Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func TestAccCloudbuildWorkerPool_basic(t *testing.T) {
{
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"annotations"},
ResourceName: "google_cloudbuild_worker_pool.pool",
},
{
Expand Down Expand Up @@ -79,6 +80,11 @@ resource "google_cloudbuild_worker_pool" "pool" {
machine_type = "e2-standard-4"
no_external_ip = false
}

annotations = {
env = "foo"
default_expiration_ms = 3600000
}
}
`, context)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ func TestAccDataprocWorkflowTemplate_basic(t *testing.T) {
{
ImportState: true,
ImportStateVerify: true,
// The "labels" field in the state are decided by the configuration.
// During importing, as the configuration is unavailableafter, the "labels" field in the state will be empty.
// So add the "labels" to the ImportStateVerifyIgnore list.
ImportStateVerifyIgnore: []string{"labels"},
ResourceName: "google_dataproc_workflow_template.template",
},
},
Expand Down Expand Up @@ -124,6 +128,11 @@ resource "google_dataproc_workflow_template" "template" {
query_file_uri = "someuri"
}
}

labels = {
env = "foo"
somekey = "somevalue"
}
}
`, context)
}
Expand Down
6 changes: 6 additions & 0 deletions tpgtools/overrides/dataplex/samples/asset/basic_asset.tf.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ resource "google_dataplex_asset" "primary" {
name = "projects/{{project}}/buckets/{{bucket}}"
type = "STORAGE_BUCKET"
}

labels = {
env = "foo"
my-asset = "exists"
}


project = "{{project}}"
depends_on = [
Expand Down
39 changes: 39 additions & 0 deletions tpgtools/property.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,10 @@ func (p Property) DefaultStateSetter() string {
case SchemaTypeFloat:
fallthrough
case SchemaTypeMap:
if p.IsResourceLabels() || p.IsResourceAnnotations() {
return fmt.Sprintf("d.Set(%q, flatten%s%s(res.%s, d))", p.Name(), p.resource.PathType(), p.PackagePath(), p.PackageName)
}

return fmt.Sprintf("d.Set(%q, res.%s)", p.Name(), p.PackageName)
case SchemaTypeList, SchemaTypeSet:
if p.typ.Items != nil && ((p.typ.Items.Type == "string" && len(p.typ.Items.Enum) == 0) || p.typ.Items.Type == "integer") {
Expand Down Expand Up @@ -440,6 +444,14 @@ func (p Property) Objects() (props []Property) {
return props
}

func (p Property) IsResourceLabels() bool {
return p.Name() == "labels" && p.parent == nil
}

func (p Property) IsResourceAnnotations() bool {
return p.Name() == "annotations" && p.parent == nil
}

// collapsedProperties returns the input list of properties with nested objects collapsed if needed.
func collapsedProperties(props []Property) (collapsed []Property) {
for _, v := range props {
Expand Down Expand Up @@ -878,6 +890,16 @@ func createPropertiesFromSchema(schema *openapi.Schema, typeFetcher *TypeFetcher
resource.ReusedTypes = resource.RegisterReusedType(p)
}

// Add the "effective_labels" property when the current property is top level "labels" or
// add the "effective_annotations" property when the current property is top level "annotations"

if p.IsResourceLabels() || p.IsResourceAnnotations() {
note := "**Note**: This field is non-authoritative, and will only manage the labels present in your configuration. " +
"Please refer to the field `effective_labels` for all of the labels present on the resource."
p.Description = fmt.Sprintf("%s\n\n%s", p.Description, note)
props = append(props, build_effective_labels_field(p, resource, parent))
}

props = append(props, p)
}

Expand All @@ -901,3 +923,20 @@ func createPropertiesFromSchema(schema *openapi.Schema, typeFetcher *TypeFetcher

return props, nil
}

func build_effective_labels_field(p Property, resource *Resource, parent *Property) Property {
title := fmt.Sprintf("effective_%s", p.title)
description := fmt.Sprintf("All of %s (key/value pairs) present on the resource in GCP, including the %s configured through Terraform, other clients and services.", p.title, p.title)
stateSetter := fmt.Sprintf("d.Set(%q, res.%s)", title, p.PackageName)

return Property{
title: title,
Type: p.Type,
Description: description,
resource: resource,
parent: parent,
Optional: false,
Computed: true,
StateSetter: &stateSetter,
}
}
44 changes: 44 additions & 0 deletions tpgtools/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,26 @@ func (r Resource) IDFunction() string {
return "tpgresource.ReplaceVarsForId"
}

// Check if the resource has the lables field for the resource
func (r Resource) HasLabels() bool {
for _, p := range r.Properties {
if p.IsResourceLabels() {
return true
}
}
return false
}

// Check if the resource has the annotations field for the resource
func (r Resource) HasAnnotations() bool {
for _, p := range r.Properties {
if p.IsResourceAnnotations() {
return true
}
}
return false
}

// ResourceInput is a Resource along with additional generation metadata.
type ResourceInput struct {
Resource
Expand Down Expand Up @@ -810,6 +830,18 @@ func (r *Resource) loadHandWrittenSamples() []Sample {
sample.Name = &sampleName
}
sample.TestSlug = RenderedString(snakeToTitleCase(miscellaneousNameSnakeCase(sampleName)).titlecase() + "HandWritten")

// The "labels" and "annotations" fields in the state are decided by the configuration.
// During importing, as the configuration is unavailableafter, the "labels" and "annotations" fields in the state will be empty.
// So add the "labels" and the "annotations" fields to the ImportStateVerifyIgnore list.
if r.HasLabels() {
sample.IgnoreRead = append(sample.IgnoreRead, "labels")
}

if r.HasAnnotations() {
sample.IgnoreRead = append(sample.IgnoreRead, "annotations")
}

samples = append(samples, sample)
}

Expand Down Expand Up @@ -896,6 +928,18 @@ func (r *Resource) loadDCLSamples() []Sample {
}
sample.DependencyList = dependencies
sample.TestSlug = RenderedString(sampleNameToTitleCase(*sample.Name).titlecase())

// The "labels" and "annotations" fields in the state are decided by the configuration.
// During importing, as the configuration is unavailableafter, the "labels" and "annotations" fields in the state will be empty.
// So add the "labels" and the "annotations" fields to the ImportStateVerifyIgnore list.
if r.HasLabels() {
sample.IgnoreRead = append(sample.IgnoreRead, "labels")
}

if r.HasAnnotations() {
sample.IgnoreRead = append(sample.IgnoreRead, "annotations")
}

samples = append(samples, sample)
}

Expand Down
34 changes: 34 additions & 0 deletions tpgtools/templates/resource.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,40 @@ func flatten{{$.PathType}}{{$v.PackagePath}}(obj *{{$.Package}}.{{$v.ObjectType}
}
{{ end -}}

{{ if $.HasLabels }}
func flatten{{$.PathType}}Labels(v map[string]string, d *schema.ResourceData) interface{} {
if v == nil {
return nil
}

transformed := make(map[string]interface{})
if l, ok := d.Get("labels").(map[string]interface{}); ok {
for k, _ := range l {
transformed[k] = l[k]
}
}

return transformed
}
{{ end }}

{{ if $.HasAnnotations }}
func flatten{{$.PathType}}Annotations(v map[string]string, d *schema.ResourceData) interface{} {
if v == nil {
return nil
}

transformed := make(map[string]interface{})
if l, ok := d.Get("annotations").(map[string]interface{}); ok {
for k, _ := range l {
transformed[k] = l[k]
}
}

return transformed
}
{{ end }}

{{ range $v := .EnumArrays -}}
func flatten{{$.PathType}}{{$v.PackagePath}}Array(obj []{{$.Package}}.{{$v.ObjectType}}Enum) interface{} {
if obj == nil {
Expand Down