diff --git a/v2/azure-arm.yaml b/v2/azure-arm.yaml index c2fcb111361..645d720381a 100644 --- a/v2/azure-arm.yaml +++ b/v2/azure-arm.yaml @@ -1109,6 +1109,8 @@ objectModelConfiguration: $supportedFrom: v2.0.0-alpha.2 $defaultAzureName: false RoleAssignmentProperties: + DelegatedManagedIdentityResourceId: + $armReference: false # Actually, this *IS* a resource id, but we want to avoid breaking changes so we're fibbing here RoleDefinitionId: $armReference: true PrincipalId: @@ -1119,6 +1121,8 @@ objectModelConfiguration: $supportedFrom: v2.4.0 $defaultAzureName: false RoleAssignmentProperties: + DelegatedManagedIdentityResourceId: + $armReference: false # Actually, this *IS* a resource id, but we want to avoid breaking changes so we're fibbing here RoleDefinitionId: $armReference: true PrincipalId: @@ -1728,6 +1732,9 @@ objectModelConfiguration: FlexibleServers_FirewallRule: $exportAs: FlexibleServersFirewallRule $supportedFrom: v2.0.0-alpha.2 + ServerProperties: + SourceServerResourceId: + $armReference: false # Actually, this *IS* a resource id, but we want to avoid breaking changes so we're fibbing here 2022-01-01: FlexibleServers_Administrator: $exportAs: FlexibleServersAdministrator @@ -2152,6 +2159,12 @@ objectModelConfiguration: AksNetworkingConfiguration: SubnetId: $armReference: true + IdentityForCmk: + UserAssignedIdentity: + $armReference: false # Actually, this *IS* a resource id, but we want to avoid breaking changes so we're fibbing here + KeyVaultProperties: + KeyVaultArmId: + $armReference: false # Actually, this *IS* a resource id, but we want to avoid breaking changes so we're fibbing here Kubernetes: ResourceId: $armReference: true diff --git a/v2/tools/generator/internal/codegen/pipeline/add_cross_resource_references.go b/v2/tools/generator/internal/codegen/pipeline/add_cross_resource_references.go index fb5fda93bd0..d2c78b96647 100644 --- a/v2/tools/generator/internal/codegen/pipeline/add_cross_resource_references.go +++ b/v2/tools/generator/internal/codegen/pipeline/add_cross_resource_references.go @@ -20,10 +20,7 @@ import ( // TransformCrossResourceReferencesStageID is the unique identifier for this pipeline stage const TransformCrossResourceReferencesStageID = "transformCrossResourceReferences" -var ( - armIDDescriptionRegex = regexp.MustCompile("(?i)(.*/subscriptions/.*?/resourceGroups/.*|ARM ID|Resource ID|resourceId)") - idRegex = regexp.MustCompile("^(.*)I[d|D]s?$") -) +var idRegex = regexp.MustCompile("^(.*)I[d|D]s?$") // TransformCrossResourceReferences replaces cross resource references with genruntime.ResourceReference. func TransformCrossResourceReferences(configuration *config.Configuration, idFactory astmodel.IdentifierFactory) *Stage { diff --git a/v2/tools/generator/internal/codegen/pipeline/apply_cross_resource_references_from_config.go b/v2/tools/generator/internal/codegen/pipeline/apply_cross_resource_references_from_config.go index 9aa6c86894b..fe7d8bb4f1e 100644 --- a/v2/tools/generator/internal/codegen/pipeline/apply_cross_resource_references_from_config.go +++ b/v2/tools/generator/internal/codegen/pipeline/apply_cross_resource_references_from_config.go @@ -7,9 +7,11 @@ package pipeline import ( "context" + "regexp" "github.com/go-logr/logr" "github.com/pkg/errors" + kerrors "k8s.io/apimachinery/pkg/util/errors" "github.com/Azure/azure-service-operator/v2/tools/generator/internal/astmodel" @@ -174,22 +176,40 @@ func MakeARMIDPropertyTypeVisitor( return visitor } +var ( + armIDNameRegex = regexp.MustCompile("(?i)(^Id$|ResourceID|ARMID)") + armIDDescriptionRegex = regexp.MustCompile("(?i)(.*/subscriptions/.*?/resourceGroups/.*|ARMID|ARM ID|Resource ID|resourceId)") +) + // DoesPropertyLookLikeARMReference uses a simple heuristic to determine if a property looks like it might be an ARM reference. // This can be used for logging/reporting purposes to discover references which we missed. func DoesPropertyLookLikeARMReference(prop *astmodel.PropertyDefinition) bool { // The property must be a string, optional string, list of strings, or map[string]string - isString := astmodel.TypeEquals(prop.PropertyType(), astmodel.StringType) - isOptionalString := astmodel.TypeEquals(prop.PropertyType(), astmodel.OptionalStringType) - isStringSlice := astmodel.TypeEquals(prop.PropertyType(), astmodel.NewArrayType(astmodel.StringType)) - isStringMap := astmodel.TypeEquals(prop.PropertyType(), astmodel.MapOfStringStringType) + mightBeReference := false + if pt, ok := astmodel.AsPrimitiveType(prop.PropertyType()); ok { + // Might be a reference if we have a primitive type that's a string + mightBeReference = pt == astmodel.StringType + } - if !isString && !isOptionalString && !isStringSlice && !isStringMap { - return false + if at, ok := astmodel.AsArrayType(prop.PropertyType()); ok { + // Might be references if we have an array of strings + elementType, elementTypeIsPrimitive := astmodel.AsPrimitiveType(at.Element()) + mightBeReference = elementTypeIsPrimitive && + elementType == astmodel.StringType } + if mt, ok := astmodel.AsMapType(prop.PropertyType()); ok { + // Might be references if we have a map of strings to strings + keyType, keyTypeIsPrimitive := astmodel.AsPrimitiveType(mt.KeyType()) + valueType, valueTypeIsPrimitive := astmodel.AsPrimitiveType(mt.ValueType()) + mightBeReference = keyTypeIsPrimitive && valueTypeIsPrimitive && + keyType == astmodel.StringType && valueType == astmodel.StringType + } + + hasMatchingName := armIDNameRegex.MatchString(prop.PropertyName().String()) hasMatchingDescription := armIDDescriptionRegex.MatchString(prop.Description()) - namedID := prop.HasName("Id") - if hasMatchingDescription || namedID { + + if mightBeReference && (hasMatchingName || hasMatchingDescription) { return true }