diff --git a/mmv1/third_party/terraform/go.mod.erb b/mmv1/third_party/terraform/go.mod.erb
index b5d4fd065d93..fa30a092113d 100644
--- a/mmv1/third_party/terraform/go.mod.erb
+++ b/mmv1/third_party/terraform/go.mod.erb
@@ -5,7 +5,7 @@ go 1.20
require (
cloud.google.com/go/bigtable v1.19.0
- github.com/GoogleCloudPlatform/declarative-resource-client-library v1.62.0
+ github.com/GoogleCloudPlatform/declarative-resource-client-library v1.63.0
github.com/apparentlymart/go-cidr v1.1.0
github.com/davecgh/go-spew v1.1.1
github.com/dnaeon/go-vcr v1.0.1
diff --git a/mmv1/third_party/terraform/go.sum b/mmv1/third_party/terraform/go.sum
index 6837513a22df..63d8188cf48c 100644
--- a/mmv1/third_party/terraform/go.sum
+++ b/mmv1/third_party/terraform/go.sum
@@ -413,3 +413,5 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=
+github.com/GoogleCloudPlatform/declarative-resource-client-library v1.63.0 h1:eSOBYPZVnU2fZul9sAJFGLVCgv6stNVKkmsogKF7UeY=
+github.com/GoogleCloudPlatform/declarative-resource-client-library v1.63.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k=
diff --git a/mmv1/third_party/terraform/services/gkehub/resource_gke_hub_feature_membership_test.go.erb b/mmv1/third_party/terraform/services/gkehub/resource_gke_hub_feature_membership_test.go.erb
index d231ea19e62c..a7ab46c640a6 100644
--- a/mmv1/third_party/terraform/services/gkehub/resource_gke_hub_feature_membership_test.go.erb
+++ b/mmv1/third_party/terraform/services/gkehub/resource_gke_hub_feature_membership_test.go.erb
@@ -1008,6 +1008,17 @@ func TestAccGKEHubFeatureMembership_gkehubFeaturePolicyController(t *testing.T)
ImportState: true,
ImportStateVerify: true,
},
+ {
+ Config: testAccGKEHubFeatureMembership_policycontrollerUpdateMaps(context),
+ Check: resource.ComposeTestCheckFunc(
+ testAccCheckGkeHubFeatureMembershipPresent(t, fmt.Sprintf("tf-test-gkehub%s", context["random_suffix"]), "global", "policycontroller", fmt.Sprintf("tf-test1%s", context["random_suffix"])),
+ ),
+ },
+ {
+ ResourceName: "google_gke_hub_feature_membership.feature_member",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
},
})
}
@@ -1064,9 +1075,92 @@ resource "google_gke_hub_feature_membership" "feature_member" {
"PROMETHEUS"
]
}
+ deployment_configs {
+ component_name = "admission"
+ replica_count = 3
+ pod_affinity = "ANTI_AFFINITY"
+ container_resources {
+ limits {
+ memory = "1Gi"
+ cpu = "1.5"
+ }
+ requests {
+ memory = "500Mi"
+ cpu = "150m"
+ }
+ }
+ pod_tolerations {
+ key = "key1"
+ operator = "Equal"
+ value = "value1"
+ effect = "NoSchedule"
+ }
+ }
+ deployment_configs {
+ component_name = "mutation"
+ replica_count = 3
+ pod_affinity = "ANTI_AFFINITY"
+ }
policy_content {
template_library {
- installation = "NOT_INSTALLED"
+ installation = "ALL"
+ }
+ bundles {
+ bundle_name = "pci-dss-v3.2.1"
+ exempted_namespaces = ["sample-namespace"]
+ }
+ bundles {
+ bundle_name = "nist-sp-800-190"
+ }
+ }
+ }
+ version = "1.17.0"
+ }
+}
+`, context)
+}
+
+func testAccGKEHubFeatureMembership_policycontrollerUpdateMaps(context map[string]interface{}) string {
+ return gkeHubFeatureProjectSetup(context) + gkeHubClusterMembershipSetup(context) + acctest.Nprintf(`
+resource "google_gke_hub_feature" "feature" {
+ project = google_project.project.project_id
+ name = "policycontroller"
+ location = "global"
+ depends_on = [google_project_service.container, google_project_service.gkehub, google_project_service.poco]
+}
+
+resource "google_gke_hub_feature_membership" "feature_member" {
+ project = google_project.project.project_id
+ location = "global"
+ feature = google_gke_hub_feature.feature.name
+ membership = google_gke_hub_membership.membership.membership_id
+ policycontroller {
+ policy_controller_hub_config {
+ install_spec = "INSTALL_SPEC_SUSPENDED"
+ constraint_violation_limit = 50
+ referential_rules_enabled = true
+ log_denies_enabled = true
+ mutation_enabled = true
+ monitoring {
+ backends = [
+ "PROMETHEUS"
+ ]
+ }
+ deployment_configs {
+ component_name = "admission"
+ pod_affinity = "NO_AFFINITY"
+ }
+ deployment_configs {
+ component_name = "audit"
+ container_resources {
+ limits {
+ memory = "1Gi"
+ cpu = "1.5"
+ }
+ requests {
+ memory = "500Mi"
+ cpu = "150m"
+ }
}
}
}
diff --git a/mmv1/third_party/terraform/website/docs/r/gke_hub_feature_membership.html.markdown b/mmv1/third_party/terraform/website/docs/r/gke_hub_feature_membership.html.markdown
index ed571b6d7bdd..bd79aaa35da8 100644
--- a/mmv1/third_party/terraform/website/docs/r/gke_hub_feature_membership.html.markdown
+++ b/mmv1/third_party/terraform/website/docs/r/gke_hub_feature_membership.html.markdown
@@ -504,6 +504,10 @@ The following arguments are supported:
(Optional)
The maximum number of audit violations to be stored in a constraint. If not set, the default of 20 will be used.
+ * `deployment_configs` -
+ (Optional)
+ Map of deployment configs to deployments ("admission", "audit", "mutation").
+
* `policy_content` -
(Optional)
Specifies the desired policy content on the cluster. Structure is [documented below](#nested_policy_content).
@@ -514,12 +518,97 @@ The following arguments are supported:
(Optional)
Specifies the list of backends Policy Controller will export to. Must be one of `CLOUD_MONITORING` or `PROMETHEUS`. Defaults to [`CLOUD_MONITORING`, `PROMETHEUS`]. Specifying an empty value `[]` disables metrics export.
+The `deployment_configs` block supports:
+
+* `component_name` -
+ (Required)
+ The name of the component. One of `admission` `audit` or `mutation`
+
+* `container_resources` -
+ (Optional)
+ Container resource requirements.
+
+* `pod_affinity` -
+ (Optional)
+ Pod affinity configuration. Possible values: AFFINITY_UNSPECIFIED, NO_AFFINITY, ANTI_AFFINITY
+
+* `pod_tolerations` -
+ (Optional)
+ Pod tolerations of node taints.
+
+* `replica_count` -
+ (Optional)
+ Pod replica count.
+
+The `container_resources` block supports:
+
+* `limits` -
+ (Optional)
+ Limits describes the maximum amount of compute resources allowed for use by the running container.
+
+* `requests` -
+ (Optional)
+ Requests describes the amount of compute resources reserved for the container by the kube-scheduler.
+
+The `limits` block supports:
+
+* `cpu` -
+ (Optional)
+ CPU requirement expressed in Kubernetes resource units.
+
+* `memory` -
+ (Optional)
+ Memory requirement expressed in Kubernetes resource units.
+
+The `requests` block supports:
+
+* `cpu` -
+ (Optional)
+ CPU requirement expressed in Kubernetes resource units.
+
+* `memory` -
+ (Optional)
+ Memory requirement expressed in Kubernetes resource units.
+
+The `pod_tolerations` block supports:
+
+* `effect` -
+ (Optional)
+ Matches a taint effect.
+
+* `key` -
+ (Optional)
+ Matches a taint key (not necessarily unique).
+
+* `operator` -
+ (Optional)
+ Matches a taint operator.
+
+* `value` -
+ (Optional)
+ Matches a taint value.
+
The `policy_content` block supports:
+* `bundles` -
+ (Optional)
+ map of bundle name to BundleInstallSpec. The bundle name maps to the `bundleName` key in the `policycontroller.gke.io/constraintData` annotation on a constraint.
+
* `template_library`
(Optional)
Configures the installation of the Template Library. Structure is [documented below](#nested_template_library).
+The `template_library` block supports:
+The `bundles` block supports:
+
+* `bundle_name` -
+ (Required)
+ The name of the bundle.
+
+* `exempted_namespaces` -
+ (Optional)
+ The set of namespaces to be exempted from the bundle.
+
The `template_library` block supports:
* `installation`
diff --git a/tpgtools/go.mod b/tpgtools/go.mod
index 14c13f11e191..90f55b270e1e 100644
--- a/tpgtools/go.mod
+++ b/tpgtools/go.mod
@@ -4,7 +4,7 @@ go 1.20
require (
bitbucket.org/creachadair/stringset v0.0.11
- github.com/GoogleCloudPlatform/declarative-resource-client-library v1.62.0
+ github.com/GoogleCloudPlatform/declarative-resource-client-library v1.63.0
github.com/golang/glog v1.1.2
github.com/hashicorp/hcl v1.0.0
github.com/kylelemons/godebug v1.1.0
diff --git a/tpgtools/go.sum b/tpgtools/go.sum
index 86a5ac602ab9..30d683a7cf40 100644
--- a/tpgtools/go.sum
+++ b/tpgtools/go.sum
@@ -6,12 +6,8 @@ cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdi
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/GoogleCloudPlatform/declarative-resource-client-library v1.60.0 h1:RFZs9I3tXewC7cJf8RKbUMpQZO6jWZ9SHSnNd+auxsQ=
-github.com/GoogleCloudPlatform/declarative-resource-client-library v1.60.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k=
-github.com/GoogleCloudPlatform/declarative-resource-client-library v1.61.0 h1:IAr9UlYbxURIYABRMagXXo8pDlkFNFFXWz5J2+srrnc=
-github.com/GoogleCloudPlatform/declarative-resource-client-library v1.61.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k=
-github.com/GoogleCloudPlatform/declarative-resource-client-library v1.62.0 h1:s4Y6r6RrYLBnqosGXLwR0h1Gqr0VT3wgd6rqvHsD9OE=
-github.com/GoogleCloudPlatform/declarative-resource-client-library v1.62.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k=
+github.com/GoogleCloudPlatform/declarative-resource-client-library v1.63.0 h1:eSOBYPZVnU2fZul9sAJFGLVCgv6stNVKkmsogKF7UeY=
+github.com/GoogleCloudPlatform/declarative-resource-client-library v1.63.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
diff --git a/tpgtools/override.go b/tpgtools/override.go
index a190f8026e7e..5ce55962733c 100644
--- a/tpgtools/override.go
+++ b/tpgtools/override.go
@@ -79,6 +79,7 @@ const (
CustomListSize = "CUSTOM_LIST_SIZE_CONSTRAINT"
CustomDefault = "CUSTOM_DEFAULT"
CustomSchemaValues = "CUSTOM_SCHEMA_VALUES"
+ ComplexMapKey = "COMPLEX_MAP_KEY_NAME"
)
// Overrides represents the type a resource's override file can be marshalled
diff --git a/tpgtools/override_details.go b/tpgtools/override_details.go
index 12ee16832a59..963c23656e92 100644
--- a/tpgtools/override_details.go
+++ b/tpgtools/override_details.go
@@ -230,3 +230,8 @@ type StateUpgradeDetails struct {
// The current schema version
SchemaVersion int
}
+
+type ComplexMapKeyDetails struct {
+ // The name of the key as exposed by Terraform
+ KeyName string
+}
diff --git a/tpgtools/overrides/gkehub/beta/feature_membership.yaml b/tpgtools/overrides/gkehub/beta/feature_membership.yaml
index 3eac7364e119..8acee09e053a 100644
--- a/tpgtools/overrides/gkehub/beta/feature_membership.yaml
+++ b/tpgtools/overrides/gkehub/beta/feature_membership.yaml
@@ -29,3 +29,11 @@
details:
functions:
- tpgresource.DefaultProviderProject
+- type: COMPLEX_MAP_KEY_NAME
+ field: policycontroller.policy_controller_hub_config.policy_content.bundles
+ details:
+ keyname: bundle_name
+- type: COMPLEX_MAP_KEY_NAME
+ field: policycontroller.policy_controller_hub_config.deployment_configs
+ details:
+ keyname: component_name
\ No newline at end of file
diff --git a/tpgtools/overrides/gkehub/feature_membership.yaml b/tpgtools/overrides/gkehub/feature_membership.yaml
index 2e8b8f32503c..cd6cf1876fcc 100644
--- a/tpgtools/overrides/gkehub/feature_membership.yaml
+++ b/tpgtools/overrides/gkehub/feature_membership.yaml
@@ -24,4 +24,12 @@
field: mesh.control_plane
details:
message: >-
- Deprecated in favor of the `management` field
\ No newline at end of file
+ Deprecated in favor of the `management` field
+- type: COMPLEX_MAP_KEY_NAME
+ field: policycontroller.policy_controller_hub_config.policy_content.bundles
+ details:
+ keyname: bundle_name
+- type: COMPLEX_MAP_KEY_NAME
+ field: policycontroller.policy_controller_hub_config.deployment_configs
+ details:
+ keyname: component_name
\ No newline at end of file
diff --git a/tpgtools/property.go b/tpgtools/property.go
index f7939be2a3d9..62e5aa4fa51c 100644
--- a/tpgtools/property.go
+++ b/tpgtools/property.go
@@ -107,6 +107,10 @@ type Property struct {
// Sub-properties of nested objects or arrays with nested objects
Properties []Property
+ // If this is a complex map type, this string represents the name of the
+ // field that the key to the map can be set with
+ ComplexMapKeyName string
+
// Reference to the parent resource.
// note: "Properties" will not be available.
resource *Resource
@@ -198,13 +202,24 @@ func (p Property) ObjectType() string {
}
func (p Property) IsArray() bool {
- return (p.Type.String() == SchemaTypeList || p.Type.String() == SchemaTypeSet) && !p.Type.IsObject()
+ return (p.Type.String() == SchemaTypeList || p.Type.String() == SchemaTypeSet) && !p.Type.IsObject() && !p.IsComplexMap()
}
func (t Type) IsSet() bool {
return t.String() == SchemaTypeSet
}
+// Complex map is for maps of string --> object that are supported in DCL but
+// not in Terraform. We handle this by adding a field in the Terraform schema
+// for the key in the map. This must be added via a COMPLEX_MAP_KEY_NAME
+// override
+func (t Type) IsComplexMap() bool {
+ if t.typ.AdditionalProperties != nil {
+ return t.typ.AdditionalProperties.Type != "string"
+ }
+ return false
+}
+
// ShouldGenerateNestedSchema returns true if an object's nested schema function should be generated.
func (p Property) ShouldGenerateNestedSchema() bool {
return len(p.Properties) > 0 && !p.Collapsed
@@ -278,6 +293,9 @@ func buildGetter(p Property, rawGetter string) string {
if p.Type.IsEnumArray() {
return fmt.Sprintf("expand%s%sArray(%s)", p.resource.PathType(), p.PackagePath(), rawGetter)
}
+ if p.Type.IsComplexMap() {
+ return fmt.Sprintf("expand%s%sMap(%s)", p.resource.PathType(), p.PackagePath(), rawGetter)
+ }
if p.Type.typ.Items != nil && p.Type.typ.Items.Type == "string" {
return fmt.Sprintf("tpgdclresource.ExpandStringArray(%s)", rawGetter)
}
@@ -317,6 +335,9 @@ func (p Property) DefaultStateSetter() string {
return fmt.Sprintf("d.Set(%q, res.%s)", p.Name(), p.PackageName)
case SchemaTypeList, SchemaTypeSet:
+ if p.IsComplexMap() {
+ return fmt.Sprintf("d.Set(%q, flatten%s%sMap(res.%s))", p.Name(), p.resource.PathType(), p.PackagePath(), p.PackageName)
+ }
if p.typ.Items != nil && ((p.typ.Items.Type == "string" && len(p.typ.Items.Enum) == 0) || p.typ.Items.Type == "integer") {
return fmt.Sprintf("d.Set(%q, res.%s)", p.Name(), p.PackageName)
}
@@ -365,6 +386,9 @@ func (p Property) flattenGetterWithParent(parent string) string {
if p.Type.IsEnumArray() {
return fmt.Sprintf("flatten%s%sArray(obj.%s)", p.resource.PathType(), p.PackagePath(), p.PackageName)
}
+ if p.Type.IsComplexMap() {
+ return fmt.Sprintf("flatten%s%sMap(%s.%s)", p.resource.PathType(), p.PackagePath(), parent, p.PackageName)
+ }
if p.Type.typ.Items != nil && p.Type.typ.Items.Type == "integer" {
return fmt.Sprintf("%s.%s", parent, p.PackageName)
}
@@ -376,7 +400,6 @@ func (p Property) flattenGetterWithParent(parent string) string {
return fmt.Sprintf("flatten%s%sArray(%s.%s)", p.resource.PathType(), p.PackagePath(), parent, p.PackageName)
}
}
-
if p.typ.Type == "object" {
return fmt.Sprintf("flatten%s%s(%s.%s)", p.resource.PathType(), p.PackagePath(), parent, p.PackageName)
}
@@ -651,6 +674,38 @@ func createPropertiesFromSchema(schema *openapi.Schema, typeFetcher *TypeFetcher
p.ElemIsBasicType = true
}
}
+ // Complex maps are represented as TypeSet but don't have v.Items set.
+ // Use AdditionalProperties instead, and add an additional `name` field
+ // that represents the key in the map
+ if p.Type.IsComplexMap() {
+ props, err := createPropertiesFromSchema(p.Type.typ.AdditionalProperties, typeFetcher, overrides, resource, &p, location)
+ if err != nil {
+ return nil, err
+ }
+ cm := ComplexMapKeyDetails{}
+ cmOk, err := overrides.PropertyOverrideWithDetails(ComplexMapKey, p, &cm, location)
+ if err != nil {
+ return nil, fmt.Errorf("failed to decode complex map key name details")
+ }
+ if !cmOk {
+ return nil, fmt.Errorf("failed to find complex map key name for map named: %s", p.Name())
+ }
+ keyProp := Property{
+ title: cm.KeyName,
+ Type: Type{&openapi.Schema{Type: "string"}},
+ resource: resource,
+ parent: &p,
+ Required: true,
+ Description: "The name for the key in the map for which this object is mapped to in the API",
+ }
+ props = append([]Property{keyProp}, props...)
+
+ p.Properties = props
+ e := fmt.Sprintf("%s%sSchema()", resource.PathType(), p.PackagePath())
+ p.Elem = &e
+ p.ElemIsBasicType = false
+ p.ComplexMapKeyName = cm.KeyName
+ }
if !p.Computed {
if stringInSlice(v.Title, schema.Required) {
@@ -779,7 +834,7 @@ func createPropertiesFromSchema(schema *openapi.Schema, typeFetcher *TypeFetcher
p.ValidateFunc = &vf.Function
}
- if p.Type.String() == SchemaTypeSet {
+ if p.Type.IsSet() {
shf := SetHashFuncDetails{}
shfOk, err := overrides.PropertyOverrideWithDetails(SetHashFunc, p, &shf, location)
if err != nil {
diff --git a/tpgtools/templates/resource.go.tmpl b/tpgtools/templates/resource.go.tmpl
index 8de8fa398c60..b65085ba771f 100644
--- a/tpgtools/templates/resource.go.tmpl
+++ b/tpgtools/templates/resource.go.tmpl
@@ -661,6 +661,39 @@ func expand{{$.PathType}}{{$v.PackagePath}}Array(o interface{}) []{{$.Package}}.
items = append(items, *i)
}
+ return items
+}
+ {{- end }}
+
+ {{ if $v.IsComplexMap -}}
+func expand{{$.PathType}}{{$v.PackagePath}}Map(o interface{}) map[string]{{$.Package}}.{{$v.ObjectType}} {
+ if o == nil {
+ {{- if $v.Computed }}
+ return nil
+ {{- else }}
+ return make(map[string]{{$.Package}}.{{$v.ObjectType}})
+ {{- end }}
+ }
+
+ o = o.(*schema.Set).List()
+
+ objs := o.([]interface{})
+ if len(objs) == 0 || objs[0] == nil {
+ {{- if $v.Computed }}
+ return nil
+ {{- else }}
+ return make(map[string]{{$.Package}}.{{$v.ObjectType}})
+ {{- end }}
+ }
+
+ items := make(map[string]{{$.Package}}.{{$v.ObjectType}})
+ for _, item := range objs {
+ i := expand{{$.PathType}}{{$v.PackagePath}}(item)
+ if item != nil {
+ items[item.(map[string]interface{})["{{$v.ComplexMapKeyName}}"].(string)] = *i
+ }
+ }
+
return items
}
{{- end }}
@@ -688,7 +721,7 @@ func expand{{$.PathType}}{{$v.PackagePath}}(o interface{}) *{{$.Package}}.{{$v.O
{{- end }}
return &{{$.Package}}.{{$v.ObjectType}}{
{{- range $p := $v.Properties }}
- {{- if and ($p.Settable) ($p.ExpandGetter) }}
+ {{- if and ($p.Settable) ($p.ExpandGetter) (or (not $v.IsComplexMap) (ne $p.Name $v.ComplexMapKeyName)) }}
{{$p.PackageName}}: {{$p.ExpandGetter}},
{{- end -}}
{{ end }}
@@ -713,17 +746,36 @@ func flatten{{$.PathType}}{{$v.PackagePath}}Array(objs []{{$.Package}}.{{$v.Obje
}
{{- end }}
-func flatten{{$.PathType}}{{$v.PackagePath}}(obj *{{$.Package}}.{{$v.ObjectType}}) interface{} {
- if obj == nil || obj.Empty(){
+ {{ if $v.IsComplexMap -}}
+func flatten{{$.PathType}}{{$v.PackagePath}}Map(objs map[string]{{$.Package}}.{{$v.ObjectType}}) []interface{} {
+ if objs == nil {
+ return nil
+ }
+
+ items := []interface{}{}
+ for name, item := range objs {
+ i := flatten{{$.PathType}}{{$v.PackagePath}}(&item, name)
+ items = append(items, i)
+ }
+
+ return items
+}
+ {{- end }}
+
+func flatten{{$.PathType}}{{$v.PackagePath}}(obj *{{$.Package}}.{{$v.ObjectType}}{{- if $v.IsComplexMap -}}, name string{{- end -}}) interface{} {
+ if obj == nil {{- if not $v.IsComplexMap -}}|| obj.Empty(){{- end -}}{
return nil
}
transformed := map[string]interface{}{
{{- range $p := $v.Properties }}
- {{- if ($p.FlattenGetter) }}
+ {{- if or (not $v.IsComplexMap) (ne $p.Name $v.ComplexMapKeyName) }}
"{{$p.Name}}": {{$p.FlattenGetter}},
{{- end -}}
{{ end }}
}
+{{ if $v.IsComplexMap }}
+ transformed["{{$v.ComplexMapKeyName}}"] = name
+{{ end }}
{{ if $v.IsObject }}
return []interface{}{transformed}
{{ else }}
diff --git a/tpgtools/type.go b/tpgtools/type.go
index 47adedaa30c9..cb31f0a7c562 100644
--- a/tpgtools/type.go
+++ b/tpgtools/type.go
@@ -67,14 +67,13 @@ func (t Type) String() string {
}
return "unknown number type"
case "object":
- // assume if this is set, it's a string -> string map for now.
- // https://swagger.io/docs/specification/data-models/dictionaries/
- // describes the behaviour of AdditionalProperties for type: object
if t.typ.AdditionalProperties != nil {
if v := t.typ.AdditionalProperties.Type; v == "string" {
return SchemaTypeMap
} else {
- return fmt.Sprintf("unknown AdditionalProperties: %q", v)
+ // Complex maps are handled as sets with an extra value for the
+ // name of the object
+ return SchemaTypeSet
}
}
return SchemaTypeList