Skip to content
Draft
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
61 changes: 61 additions & 0 deletions mmv1/api/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,67 @@ func TestResourceAddExtraFields(t *testing.T) {
}
})

t.Run("WriteOnly property inside FlattenObject has correct ConflictsWith and RequiredWith paths", func(t *testing.T) {
t.Parallel()

product := &api.Product{Name: "testproduct"}
product.SetCompiler("terraform")
r := &api.Resource{
Name: "testresource",
ProductMetadata: product,
}

writeOnlyProp := createTestType("secretData", "String",
withWriteOnly(true),
withDescription("The secret data"),
)

flattenedParent := &api.Type{
Name: "payload",
Type: "NestedObject",
FlattenObject: true,
Properties: []*api.Type{writeOnlyProp},
}

r.Properties = []*api.Type{flattenedParent}
// Mirror loader: SetDefault before AddExtraFields, then SetDefault again after.
r.SetDefault(product)
r.Properties = r.AddExtraFields(r.Properties, nil)
r.SetDefault(product)

// After AddExtraFields + SetDefault, secretDataWo and secretDataWoVersion are
// inside payload.Properties but appear as top-level schema fields (due to FlattenObject).
// GetPropertySchemaPath must find them when resolving ConflictsWith/RequiredWith.
var woField *api.Type
for _, p := range r.Properties {
if p.Name == "payload" {
for _, child := range p.Properties {
if child.Name == "secretDataWo" {
woField = child
}
}
}
}

if woField == nil {
t.Fatal("Expected to find secretDataWo field inside payload")
}

conflicts := woField.GetPropertySchemaPathList(woField.Conflicting())
if len(conflicts) == 0 {
t.Error("secretDataWo ConflictsWith should not be empty; expected [\"secret_data\"]")
} else if conflicts[0] != "secret_data" {
t.Errorf("secretDataWo ConflictsWith[0] = %q, want \"secret_data\"", conflicts[0])
}

requiredWith := woField.GetPropertySchemaPathList(woField.RequiredWithList())
if len(requiredWith) == 0 {
t.Error("secretDataWo RequiredWith should not be empty; expected [\"secret_data_wo_version\"]")
} else if requiredWith[0] != "secret_data_wo_version" {
t.Errorf("secretDataWo RequiredWith[0] = %q, want \"secret_data_wo_version\"", requiredWith[0])
}
})

t.Run("WriteOnly property doesn't add companion fields for tgc", func(t *testing.T) {
t.Parallel()

Expand Down
33 changes: 23 additions & 10 deletions mmv1/api/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -1483,23 +1483,17 @@ func (t *Type) GetPropertySchemaPath(schemaPath string) string {
var pathTkns []string
for _, pname := range strings.Split(schemaPath, ".0.") {
camelPname := google.Camelize(pname, "lower")
index := slices.IndexFunc(nestedProps, func(p *Type) bool {
return p.Name == camelPname
})
prop := findPropByNameInFlattenedList(nestedProps, camelPname)

// if we couldn't find it, see if it was renamed at the top level
if index == -1 {
index = slices.IndexFunc(nestedProps, func(p *Type) bool {
return p.Name == schemaPath
})
if prop == nil {
prop = findPropByNameInFlattenedList(nestedProps, schemaPath)
}

if index == -1 {
if prop == nil {
return ""
}

prop := nestedProps[index]

nestedProps = prop.NestedProperties()
if !prop.FlattenObject {
pathTkns = append(pathTkns, google.Underscore(pname))
Expand All @@ -1513,6 +1507,25 @@ func (t *Type) GetPropertySchemaPath(schemaPath string) string {
return strings.Join(pathTkns[:], ".0.")
}

// findPropByNameInFlattenedList searches for a property by name in a list of properties,
// also searching recursively inside any FlattenObject nested objects (since those appear
// as top-level fields in the schema).
func findPropByNameInFlattenedList(props []*Type, name string) *Type {
for _, p := range props {
if p.Name == name {
return p
}
}
for _, p := range props {
if p.FlattenObject {
if found := findPropByNameInFlattenedList(p.UserProperties(), name); found != nil {
return found
}
}
}
return nil
}

func (t Type) GetPropertySchemaPathList(propertyList []string) []string {
var list []string
for _, path := range propertyList {
Expand Down
24 changes: 2 additions & 22 deletions mmv1/products/bigquerydatatransfer/Config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -227,30 +227,10 @@ properties:
to a different credential configuration in the config will require an apply to update state.
url_param_only: true
properties:
- name: 'secretAccessKeyWoVersion'
type: Integer
url_param_only: true
required_with:
- 'sensitive_params.0.secretAccessKeyWo'
description: |
The version of the sensitive params - used to trigger updates of the write-only params. For more info see [updating write-only arguments](/docs/providers/google/guides/using_write_only_arguments.html#updating-write-only-arguments)
- name: 'secretAccessKey'
type: String
description: |
The Secret Access Key of the AWS account transferring data from.
sensitive: true
at_least_one_of:
- 'sensitive_params.0.secretAccessKey'
- 'sensitive_params.0.secretAccessKeyWo'
conflicts:
- 'sensitive_params.0.secretAccessKeyWo'
- name: 'secretAccessKeyWo' # Wo is convention for write-only properties
type: String
description: |
The Secret Access Key of the AWS account transferring data from.
write_only_legacy: true
at_least_one_of:
- 'sensitive_params.0.secretAccessKeyWo'
- 'sensitive_params.0.secretAccessKey'
conflicts:
- 'sensitive_params.0.secretAccessKey'
required: true
write_only: true
21 changes: 2 additions & 19 deletions mmv1/products/monitoring/UptimeCheckConfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -203,28 +203,11 @@ properties:
- name: password
type: String
description: The password to authenticate.
exactly_one_of:
- password
- password_wo
required: true
sensitive: true
write_only: true
custom_flatten: templates/terraform/custom_flatten/uptime_check_http_password.tmpl
is_missing_in_cai: true
- name: passwordWo
type: String
description: The password to authenticate.
exactly_one_of:
- passwordWo
- password
required_with:
- http_check.0.auth_info.0.password_wo_version
write_only_legacy: true
- name: passwordWoVersion
type: String
description: The password write-only version.
immutable: true
required_with:
- http_check.0.auth_info.0.password_wo
ignore_read: true
- name: username
type: String
required: true
Expand Down
18 changes: 1 addition & 17 deletions mmv1/products/secretmanager/SecretVersion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -202,23 +202,7 @@ properties:
type: String
description: The secret data. Must be no larger than 64KiB.
api_name: data
conflicts:
- 'secretDataWo'
immutable: true
sensitive: true
write_only: true
is_missing_in_cai: true
- name: 'secretDataWo'
type: String
description: The secret data. Must be no larger than 64KiB. For more info see [updating write-only arguments](/docs/providers/google/guides/using_write_only_arguments.html#updating-write-only-arguments)
api_name: data
required_with:
- 'SecretDataWoVersion'
conflicts:
- 'payload.0.secretData'
write_only_legacy: true
- name: 'SecretDataWoVersion'
type: Integer
default_value: 0
url_param_only: true
description: Triggers update of secret data write-only. For more info see [updating write-only arguments](/docs/providers/google/guides/using_write_only_arguments.html#updating-write-only-arguments)
immutable: true
Loading