diff --git a/v2/api/containerservice/v1api20210501/managed_cluster_types_gen.go b/v2/api/containerservice/v1api20210501/managed_cluster_types_gen.go index 44f7a463b7..60c8c12c74 100644 --- a/v2/api/containerservice/v1api20210501/managed_cluster_types_gen.go +++ b/v2/api/containerservice/v1api20210501/managed_cluster_types_gen.go @@ -454,7 +454,7 @@ type ManagedCluster_Spec struct { Sku *ManagedClusterSKU `json:"sku,omitempty"` // Tags: Resource tags - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` // WindowsProfile: The profile for Windows VMs in the Managed Cluster. WindowsProfile *ManagedClusterWindowsProfile `json:"windowsProfile,omitempty"` @@ -4725,14 +4725,14 @@ type ManagedClusterAgentPoolProfile struct { Name *string `json:"name,omitempty"` // NodeLabels: The node labels to be persisted across all nodes in agent pool. - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixIDReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixIDReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixIDReference,omitempty"` // NodeTaints: The taints added to new nodes during node pool create and scale. For example, key=value:NoSchedule. - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` // OrchestratorVersion: As a best practice, you should upgrade all node pools in an AKS cluster to the same Kubernetes // version. The node pool version must have the same major version as the control plane. The node pool minor version must @@ -4774,7 +4774,7 @@ type ManagedClusterAgentPoolProfile struct { SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` // Tags: The tags to be persisted on the agent pool virtual machine scale set. - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` // Type: The type of Agent Pool. Type *AgentPoolType `json:"type,omitempty"` diff --git a/v2/api/containerservice/v1api20210501/managed_clusters_agent_pool_types_gen.go b/v2/api/containerservice/v1api20210501/managed_clusters_agent_pool_types_gen.go index bf2c839655..c2ffa7d39b 100644 --- a/v2/api/containerservice/v1api20210501/managed_clusters_agent_pool_types_gen.go +++ b/v2/api/containerservice/v1api20210501/managed_clusters_agent_pool_types_gen.go @@ -389,14 +389,14 @@ type ManagedClusters_AgentPool_Spec struct { Mode *AgentPoolMode `json:"mode,omitempty"` // NodeLabels: The node labels to be persisted across all nodes in agent pool. - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixIDReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixIDReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixIDReference,omitempty"` // NodeTaints: The taints added to new nodes during node pool create and scale. For example, key=value:NoSchedule. - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` // OrchestratorVersion: As a best practice, you should upgrade all node pools in an AKS cluster to the same Kubernetes // version. The node pool version must have the same major version as the control plane. The node pool minor version must @@ -444,7 +444,7 @@ type ManagedClusters_AgentPool_Spec struct { SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` // Tags: The tags to be persisted on the agent pool virtual machine scale set. - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` // Type: The type of Agent Pool. Type *AgentPoolType `json:"type,omitempty"` diff --git a/v2/api/containerservice/v1api20210501/storage/managed_cluster_types_gen.go b/v2/api/containerservice/v1api20210501/storage/managed_cluster_types_gen.go index 8a1513e2e3..a57e65cc4a 100644 --- a/v2/api/containerservice/v1api20210501/storage/managed_cluster_types_gen.go +++ b/v2/api/containerservice/v1api20210501/storage/managed_cluster_types_gen.go @@ -293,7 +293,7 @@ type ManagedCluster_Spec struct { PropertyBag genruntime.PropertyBag `json:"$propertyBag,omitempty"` ServicePrincipalProfile *ManagedClusterServicePrincipalProfile `json:"servicePrincipalProfile,omitempty"` Sku *ManagedClusterSKU `json:"sku,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` WindowsProfile *ManagedClusterWindowsProfile `json:"windowsProfile,omitempty"` } @@ -3384,12 +3384,12 @@ type ManagedClusterAgentPoolProfile struct { MinCount *int `json:"minCount,omitempty"` Mode *string `json:"mode,omitempty"` Name *string `json:"name,omitempty"` - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixIDReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixIDReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixIDReference,omitempty"` - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` OrchestratorVersion *string `json:"orchestratorVersion,omitempty"` OsDiskSizeGB *int `json:"osDiskSizeGB,omitempty"` OsDiskType *string `json:"osDiskType,omitempty"` @@ -3405,7 +3405,7 @@ type ManagedClusterAgentPoolProfile struct { ScaleSetEvictionPolicy *string `json:"scaleSetEvictionPolicy,omitempty"` ScaleSetPriority *string `json:"scaleSetPriority,omitempty"` SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` Type *string `json:"type,omitempty"` UpgradeSettings *AgentPoolUpgradeSettings `json:"upgradeSettings,omitempty"` VmSize *string `json:"vmSize,omitempty"` diff --git a/v2/api/containerservice/v1api20210501/storage/managed_clusters_agent_pool_types_gen.go b/v2/api/containerservice/v1api20210501/storage/managed_clusters_agent_pool_types_gen.go index 1b56e315a8..ca5ad28a64 100644 --- a/v2/api/containerservice/v1api20210501/storage/managed_clusters_agent_pool_types_gen.go +++ b/v2/api/containerservice/v1api20210501/storage/managed_clusters_agent_pool_types_gen.go @@ -265,12 +265,12 @@ type ManagedClusters_AgentPool_Spec struct { MaxPods *int `json:"maxPods,omitempty"` MinCount *int `json:"minCount,omitempty"` Mode *string `json:"mode,omitempty"` - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixIDReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixIDReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixIDReference,omitempty"` - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` OrchestratorVersion *string `json:"orchestratorVersion,omitempty"` OriginalVersion string `json:"originalVersion,omitempty"` OsDiskSizeGB *int `json:"osDiskSizeGB,omitempty"` @@ -293,7 +293,7 @@ type ManagedClusters_AgentPool_Spec struct { ScaleSetEvictionPolicy *string `json:"scaleSetEvictionPolicy,omitempty"` ScaleSetPriority *string `json:"scaleSetPriority,omitempty"` SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` Type *string `json:"type,omitempty"` UpgradeSettings *AgentPoolUpgradeSettings `json:"upgradeSettings,omitempty"` VmSize *string `json:"vmSize,omitempty"` diff --git a/v2/api/containerservice/v1api20230201/managed_cluster_types_gen.go b/v2/api/containerservice/v1api20230201/managed_cluster_types_gen.go index 24d4ff41b1..dd333b04b5 100644 --- a/v2/api/containerservice/v1api20230201/managed_cluster_types_gen.go +++ b/v2/api/containerservice/v1api20230201/managed_cluster_types_gen.go @@ -514,7 +514,7 @@ type ManagedCluster_Spec struct { StorageProfile *ManagedClusterStorageProfile `json:"storageProfile,omitempty"` // Tags: Resource tags. - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` // WindowsProfile: The profile for Windows VMs in the Managed Cluster. WindowsProfile *ManagedClusterWindowsProfile `json:"windowsProfile,omitempty"` @@ -5702,14 +5702,14 @@ type ManagedClusterAgentPoolProfile struct { Name *string `json:"name,omitempty"` // NodeLabels: The node labels to be persisted across all nodes in agent pool. - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixReference,omitempty"` // NodeTaints: The taints added to new nodes during node pool create and scale. For example, key=value:NoSchedule. - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` // OrchestratorVersion: Both patch version (e.g. 1.20.13) and (e.g. 1.20) are supported. // When is specified, the latest supported GA patch version is chosen automatically. Updating the cluster @@ -5763,7 +5763,7 @@ type ManagedClusterAgentPoolProfile struct { SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` // Tags: The tags to be persisted on the agent pool virtual machine scale set. - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` // Type: The type of Agent Pool. Type *AgentPoolType `json:"type,omitempty"` diff --git a/v2/api/containerservice/v1api20230201/managed_clusters_agent_pool_types_gen.go b/v2/api/containerservice/v1api20230201/managed_clusters_agent_pool_types_gen.go index 2eed653576..4d56134ae9 100644 --- a/v2/api/containerservice/v1api20230201/managed_clusters_agent_pool_types_gen.go +++ b/v2/api/containerservice/v1api20230201/managed_clusters_agent_pool_types_gen.go @@ -398,14 +398,14 @@ type ManagedClusters_AgentPool_Spec struct { Mode *AgentPoolMode `json:"mode,omitempty"` // NodeLabels: The node labels to be persisted across all nodes in agent pool. - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixReference,omitempty"` // NodeTaints: The taints added to new nodes during node pool create and scale. For example, key=value:NoSchedule. - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` // OrchestratorVersion: Both patch version (e.g. 1.20.13) and (e.g. 1.20) are supported. // When is specified, the latest supported GA patch version is chosen automatically. Updating the cluster @@ -465,7 +465,7 @@ type ManagedClusters_AgentPool_Spec struct { SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` // Tags: The tags to be persisted on the agent pool virtual machine scale set. - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` // Type: The type of Agent Pool. Type *AgentPoolType `json:"type,omitempty"` diff --git a/v2/api/containerservice/v1api20230201/storage/managed_cluster_types_gen.go b/v2/api/containerservice/v1api20230201/storage/managed_cluster_types_gen.go index c2e2e854af..af383f8905 100644 --- a/v2/api/containerservice/v1api20230201/storage/managed_cluster_types_gen.go +++ b/v2/api/containerservice/v1api20230201/storage/managed_cluster_types_gen.go @@ -310,7 +310,7 @@ type ManagedCluster_Spec struct { ServicePrincipalProfile *ManagedClusterServicePrincipalProfile `json:"servicePrincipalProfile,omitempty"` Sku *ManagedClusterSKU `json:"sku,omitempty"` StorageProfile *ManagedClusterStorageProfile `json:"storageProfile,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` WindowsProfile *ManagedClusterWindowsProfile `json:"windowsProfile,omitempty"` WorkloadAutoScalerProfile *ManagedClusterWorkloadAutoScalerProfile `json:"workloadAutoScalerProfile,omitempty"` } @@ -3482,12 +3482,12 @@ type ManagedClusterAgentPoolProfile struct { MinCount *int `json:"minCount,omitempty"` Mode *string `json:"mode,omitempty"` Name *string `json:"name,omitempty"` - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixReference,omitempty"` - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` OrchestratorVersion *string `json:"orchestratorVersion,omitempty"` OsDiskSizeGB *int `json:"osDiskSizeGB,omitempty"` OsDiskType *string `json:"osDiskType,omitempty"` @@ -3507,7 +3507,7 @@ type ManagedClusterAgentPoolProfile struct { ScaleSetEvictionPolicy *string `json:"scaleSetEvictionPolicy,omitempty"` ScaleSetPriority *string `json:"scaleSetPriority,omitempty"` SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` Type *string `json:"type,omitempty"` UpgradeSettings *AgentPoolUpgradeSettings `json:"upgradeSettings,omitempty"` VmSize *string `json:"vmSize,omitempty"` diff --git a/v2/api/containerservice/v1api20230201/storage/managed_clusters_agent_pool_types_gen.go b/v2/api/containerservice/v1api20230201/storage/managed_clusters_agent_pool_types_gen.go index f603abb43c..86f5478dc2 100644 --- a/v2/api/containerservice/v1api20230201/storage/managed_clusters_agent_pool_types_gen.go +++ b/v2/api/containerservice/v1api20230201/storage/managed_clusters_agent_pool_types_gen.go @@ -258,12 +258,12 @@ type ManagedClusters_AgentPool_Spec struct { MaxPods *int `json:"maxPods,omitempty"` MinCount *int `json:"minCount,omitempty"` Mode *string `json:"mode,omitempty"` - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixReference,omitempty"` - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` OrchestratorVersion *string `json:"orchestratorVersion,omitempty"` OriginalVersion string `json:"originalVersion,omitempty"` OsDiskSizeGB *int `json:"osDiskSizeGB,omitempty"` @@ -290,7 +290,7 @@ type ManagedClusters_AgentPool_Spec struct { ScaleSetEvictionPolicy *string `json:"scaleSetEvictionPolicy,omitempty"` ScaleSetPriority *string `json:"scaleSetPriority,omitempty"` SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` Type *string `json:"type,omitempty"` UpgradeSettings *AgentPoolUpgradeSettings `json:"upgradeSettings,omitempty"` VmSize *string `json:"vmSize,omitempty"` diff --git a/v2/api/containerservice/v1api20230202preview/managed_cluster_types_gen.go b/v2/api/containerservice/v1api20230202preview/managed_cluster_types_gen.go index a47659e4b0..07226c9128 100644 --- a/v2/api/containerservice/v1api20230202preview/managed_cluster_types_gen.go +++ b/v2/api/containerservice/v1api20230202preview/managed_cluster_types_gen.go @@ -532,7 +532,7 @@ type ManagedCluster_Spec struct { StorageProfile *ManagedClusterStorageProfile `json:"storageProfile,omitempty"` // Tags: Resource tags. - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` // UpgradeSettings: Settings for upgrading a cluster. UpgradeSettings *ClusterUpgradeSettings `json:"upgradeSettings,omitempty"` @@ -6979,14 +6979,14 @@ type ManagedClusterAgentPoolProfile struct { NetworkProfile *AgentPoolNetworkProfile `json:"networkProfile,omitempty"` // NodeLabels: The node labels to be persisted across all nodes in agent pool. - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixReference,omitempty"` // NodeTaints: The taints added to new nodes during node pool create and scale. For example, key=value:NoSchedule. - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` // OrchestratorVersion: Both patch version and are supported. When is // specified, the latest supported patch version is chosen automatically. Updating the agent pool with the same @@ -7040,7 +7040,7 @@ type ManagedClusterAgentPoolProfile struct { SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` // Tags: The tags to be persisted on the agent pool virtual machine scale set. - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` // Type: The type of Agent Pool. Type *AgentPoolType `json:"type,omitempty"` diff --git a/v2/api/containerservice/v1api20230202preview/managed_clusters_agent_pool_types_gen.go b/v2/api/containerservice/v1api20230202preview/managed_clusters_agent_pool_types_gen.go index f191ef100c..df5c9a829c 100644 --- a/v2/api/containerservice/v1api20230202preview/managed_clusters_agent_pool_types_gen.go +++ b/v2/api/containerservice/v1api20230202preview/managed_clusters_agent_pool_types_gen.go @@ -414,14 +414,14 @@ type ManagedClusters_AgentPool_Spec struct { NetworkProfile *AgentPoolNetworkProfile `json:"networkProfile,omitempty"` // NodeLabels: The node labels to be persisted across all nodes in agent pool. - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixReference,omitempty"` // NodeTaints: The taints added to new nodes during node pool create and scale. For example, key=value:NoSchedule. - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` // OrchestratorVersion: Both patch version and are supported. When is // specified, the latest supported patch version is chosen automatically. Updating the agent pool with the same @@ -481,7 +481,7 @@ type ManagedClusters_AgentPool_Spec struct { SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` // Tags: The tags to be persisted on the agent pool virtual machine scale set. - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` // Type: The type of Agent Pool. Type *AgentPoolType `json:"type,omitempty"` diff --git a/v2/api/containerservice/v1api20230202preview/storage/managed_cluster_types_gen.go b/v2/api/containerservice/v1api20230202preview/storage/managed_cluster_types_gen.go index 3ab1f0c8fd..ecd87f7bd7 100644 --- a/v2/api/containerservice/v1api20230202preview/storage/managed_cluster_types_gen.go +++ b/v2/api/containerservice/v1api20230202preview/storage/managed_cluster_types_gen.go @@ -329,7 +329,7 @@ type ManagedCluster_Spec struct { ServicePrincipalProfile *ManagedClusterServicePrincipalProfile `json:"servicePrincipalProfile,omitempty"` Sku *ManagedClusterSKU `json:"sku,omitempty"` StorageProfile *ManagedClusterStorageProfile `json:"storageProfile,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` UpgradeSettings *ClusterUpgradeSettings `json:"upgradeSettings,omitempty"` WindowsProfile *ManagedClusterWindowsProfile `json:"windowsProfile,omitempty"` WorkloadAutoScalerProfile *ManagedClusterWorkloadAutoScalerProfile `json:"workloadAutoScalerProfile,omitempty"` @@ -3946,12 +3946,12 @@ type ManagedClusterAgentPoolProfile struct { Mode *string `json:"mode,omitempty"` Name *string `json:"name,omitempty"` NetworkProfile *AgentPoolNetworkProfile `json:"networkProfile,omitempty"` - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixReference,omitempty"` - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` OrchestratorVersion *string `json:"orchestratorVersion,omitempty"` OsDiskSizeGB *int `json:"osDiskSizeGB,omitempty"` OsDiskType *string `json:"osDiskType,omitempty"` @@ -3971,7 +3971,7 @@ type ManagedClusterAgentPoolProfile struct { ScaleSetEvictionPolicy *string `json:"scaleSetEvictionPolicy,omitempty"` ScaleSetPriority *string `json:"scaleSetPriority,omitempty"` SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` Type *string `json:"type,omitempty"` UpgradeSettings *AgentPoolUpgradeSettings `json:"upgradeSettings,omitempty"` VmSize *string `json:"vmSize,omitempty"` diff --git a/v2/api/containerservice/v1api20230202preview/storage/managed_clusters_agent_pool_types_gen.go b/v2/api/containerservice/v1api20230202preview/storage/managed_clusters_agent_pool_types_gen.go index 6b3c707de6..fd05a86835 100644 --- a/v2/api/containerservice/v1api20230202preview/storage/managed_clusters_agent_pool_types_gen.go +++ b/v2/api/containerservice/v1api20230202preview/storage/managed_clusters_agent_pool_types_gen.go @@ -276,12 +276,12 @@ type ManagedClusters_AgentPool_Spec struct { MinCount *int `json:"minCount,omitempty"` Mode *string `json:"mode,omitempty"` NetworkProfile *AgentPoolNetworkProfile `json:"networkProfile,omitempty"` - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixReference,omitempty"` - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` OrchestratorVersion *string `json:"orchestratorVersion,omitempty"` OriginalVersion string `json:"originalVersion,omitempty"` OsDiskSizeGB *int `json:"osDiskSizeGB,omitempty"` @@ -308,7 +308,7 @@ type ManagedClusters_AgentPool_Spec struct { ScaleSetEvictionPolicy *string `json:"scaleSetEvictionPolicy,omitempty"` ScaleSetPriority *string `json:"scaleSetPriority,omitempty"` SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` Type *string `json:"type,omitempty"` UpgradeSettings *AgentPoolUpgradeSettings `json:"upgradeSettings,omitempty"` VmSize *string `json:"vmSize,omitempty"` diff --git a/v2/api/containerservice/v1api20230315preview/fleet_types_gen.go b/v2/api/containerservice/v1api20230315preview/fleet_types_gen.go index d35c7c6dc8..5ffebf6edb 100644 --- a/v2/api/containerservice/v1api20230315preview/fleet_types_gen.go +++ b/v2/api/containerservice/v1api20230315preview/fleet_types_gen.go @@ -412,9 +412,6 @@ func (fleet *Fleet_Spec) ConvertToARM(resolved genruntime.ConvertToARMResolvedDe for key, value := range fleet.Tags { result.Tags[key] = value } - } else { - // Set property to empty map, as this resource is set to serialize all collections explicitly - result.Tags = make(map[string]string) } return result, nil } diff --git a/v2/api/containerservice/v1api20231001/managed_cluster_types_gen.go b/v2/api/containerservice/v1api20231001/managed_cluster_types_gen.go index f656719ab2..3f1173ec69 100644 --- a/v2/api/containerservice/v1api20231001/managed_cluster_types_gen.go +++ b/v2/api/containerservice/v1api20231001/managed_cluster_types_gen.go @@ -517,7 +517,7 @@ type ManagedCluster_Spec struct { SupportPlan *KubernetesSupportPlan `json:"supportPlan,omitempty"` // Tags: Resource tags. - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` // UpgradeSettings: Settings for upgrading a cluster. UpgradeSettings *ClusterUpgradeSettings `json:"upgradeSettings,omitempty"` @@ -6746,14 +6746,14 @@ type ManagedClusterAgentPoolProfile struct { NetworkProfile *AgentPoolNetworkProfile `json:"networkProfile,omitempty"` // NodeLabels: The node labels to be persisted across all nodes in agent pool. - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixReference,omitempty"` // NodeTaints: The taints added to new nodes during node pool create and scale. For example, key=value:NoSchedule. - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` // OrchestratorVersion: Both patch version (e.g. 1.20.13) and (e.g. 1.20) are supported. // When is specified, the latest supported GA patch version is chosen automatically. Updating the cluster @@ -6807,7 +6807,7 @@ type ManagedClusterAgentPoolProfile struct { SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` // Tags: The tags to be persisted on the agent pool virtual machine scale set. - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` // Type: The type of Agent Pool. Type *AgentPoolType `json:"type,omitempty"` diff --git a/v2/api/containerservice/v1api20231001/managed_clusters_agent_pool_types_gen.go b/v2/api/containerservice/v1api20231001/managed_clusters_agent_pool_types_gen.go index 747d3e6515..13cf180cc0 100644 --- a/v2/api/containerservice/v1api20231001/managed_clusters_agent_pool_types_gen.go +++ b/v2/api/containerservice/v1api20231001/managed_clusters_agent_pool_types_gen.go @@ -404,14 +404,14 @@ type ManagedClusters_AgentPool_Spec struct { NetworkProfile *AgentPoolNetworkProfile `json:"networkProfile,omitempty"` // NodeLabels: The node labels to be persisted across all nodes in agent pool. - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixReference,omitempty"` // NodeTaints: The taints added to new nodes during node pool create and scale. For example, key=value:NoSchedule. - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` // OrchestratorVersion: Both patch version (e.g. 1.20.13) and (e.g. 1.20) are supported. // When is specified, the latest supported GA patch version is chosen automatically. Updating the cluster @@ -471,7 +471,7 @@ type ManagedClusters_AgentPool_Spec struct { SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` // Tags: The tags to be persisted on the agent pool virtual machine scale set. - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` // Type: The type of Agent Pool. Type *AgentPoolType `json:"type,omitempty"` diff --git a/v2/api/containerservice/v1api20231001/storage/managed_cluster_types_gen.go b/v2/api/containerservice/v1api20231001/storage/managed_cluster_types_gen.go index 80fe28bec9..e1160a1d1b 100644 --- a/v2/api/containerservice/v1api20231001/storage/managed_cluster_types_gen.go +++ b/v2/api/containerservice/v1api20231001/storage/managed_cluster_types_gen.go @@ -218,7 +218,7 @@ type ManagedCluster_Spec struct { Sku *ManagedClusterSKU `json:"sku,omitempty"` StorageProfile *ManagedClusterStorageProfile `json:"storageProfile,omitempty"` SupportPlan *string `json:"supportPlan,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` UpgradeSettings *ClusterUpgradeSettings `json:"upgradeSettings,omitempty"` WindowsProfile *ManagedClusterWindowsProfile `json:"windowsProfile,omitempty"` WorkloadAutoScalerProfile *ManagedClusterWorkloadAutoScalerProfile `json:"workloadAutoScalerProfile,omitempty"` @@ -479,12 +479,12 @@ type ManagedClusterAgentPoolProfile struct { Mode *string `json:"mode,omitempty"` Name *string `json:"name,omitempty"` NetworkProfile *AgentPoolNetworkProfile `json:"networkProfile,omitempty"` - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixReference,omitempty"` - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` OrchestratorVersion *string `json:"orchestratorVersion,omitempty"` OsDiskSizeGB *int `json:"osDiskSizeGB,omitempty"` OsDiskType *string `json:"osDiskType,omitempty"` @@ -504,7 +504,7 @@ type ManagedClusterAgentPoolProfile struct { ScaleSetEvictionPolicy *string `json:"scaleSetEvictionPolicy,omitempty"` ScaleSetPriority *string `json:"scaleSetPriority,omitempty"` SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` Type *string `json:"type,omitempty"` UpgradeSettings *AgentPoolUpgradeSettings `json:"upgradeSettings,omitempty"` VmSize *string `json:"vmSize,omitempty"` diff --git a/v2/api/containerservice/v1api20231001/storage/managed_clusters_agent_pool_types_gen.go b/v2/api/containerservice/v1api20231001/storage/managed_clusters_agent_pool_types_gen.go index 8b0369eb00..2afabb8717 100644 --- a/v2/api/containerservice/v1api20231001/storage/managed_clusters_agent_pool_types_gen.go +++ b/v2/api/containerservice/v1api20231001/storage/managed_clusters_agent_pool_types_gen.go @@ -169,12 +169,12 @@ type ManagedClusters_AgentPool_Spec struct { MinCount *int `json:"minCount,omitempty"` Mode *string `json:"mode,omitempty"` NetworkProfile *AgentPoolNetworkProfile `json:"networkProfile,omitempty"` - NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" serializationType:"explicitEmptyCollection"` // NodePublicIPPrefixReference: This is of the form: // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/publicIPPrefixes/{publicIPPrefixName} NodePublicIPPrefixReference *genruntime.ResourceReference `armReference:"NodePublicIPPrefixID" json:"nodePublicIPPrefixReference,omitempty"` - NodeTaints []string `json:"nodeTaints,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" serializationType:"explicitEmptyCollection"` OrchestratorVersion *string `json:"orchestratorVersion,omitempty"` OriginalVersion string `json:"originalVersion,omitempty"` OsDiskSizeGB *int `json:"osDiskSizeGB,omitempty"` @@ -201,7 +201,7 @@ type ManagedClusters_AgentPool_Spec struct { ScaleSetEvictionPolicy *string `json:"scaleSetEvictionPolicy,omitempty"` ScaleSetPriority *string `json:"scaleSetPriority,omitempty"` SpotMaxPrice *float64 `json:"spotMaxPrice,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Tags map[string]string `json:"tags,omitempty" serializationType:"explicitEmptyCollection"` Type *string `json:"type,omitempty"` UpgradeSettings *AgentPoolUpgradeSettings `json:"upgradeSettings,omitempty"` VmSize *string `json:"vmSize,omitempty"` diff --git a/v2/azure-arm.yaml b/v2/azure-arm.yaml index 65356be82d..ca761fbc1d 100644 --- a/v2/azure-arm.yaml +++ b/v2/azure-arm.yaml @@ -1296,7 +1296,7 @@ objectModelConfiguration: PrincipalId: $armReference: false containerservice: - $payloadType: explicitEmptyCollections + $payloadType: explicitCollections 2021-05-01: ManagedCluster: $export: true @@ -1304,15 +1304,30 @@ objectModelConfiguration: $azureGeneratedSecrets: - AdminCredentials - UserCredentials + ManagedCluster_Spec: + Tags: + $payloadType: explicitEmptyCollections ManagedClusterAgentPoolProfile: ProximityPlacementGroupID: $armReference: false # This is true in the next version and we have custom conversion to make round-tripping work + NodeLabels: + $payloadType: explicitEmptyCollections + NodeTaints: + $payloadType: explicitEmptyCollections + Tags: + $payloadType: explicitEmptyCollections ManagedClusters_AgentPool: $exportAs: ManagedClustersAgentPool $supportedFrom: v2.0.0-alpha.1 ManagedClusterAgentPoolProfileProperties: ProximityPlacementGroupID: $armReference: false # This is true in the next version and we have custom conversion to make round-tripping work + NodeLabels: + $payloadType: explicitEmptyCollections + NodeTaints: + $payloadType: explicitEmptyCollections + Tags: + $payloadType: explicitEmptyCollections ManagedClusterServicePrincipalProfile: Secret: $isSecret: true @@ -1328,6 +1343,23 @@ objectModelConfiguration: - UserCredentials $generatedConfigs: OIDCIssuerProfile: $.Status.OidcIssuerProfile.IssuerURL + ManagedCluster_Spec: + Tags: + $payloadType: explicitEmptyCollections + ManagedClusterAgentPoolProfile: + NodeLabels: + $payloadType: explicitEmptyCollections + NodeTaints: + $payloadType: explicitEmptyCollections + Tags: + $payloadType: explicitEmptyCollections + ManagedClusterAgentPoolProfileProperties: + NodeLabels: + $payloadType: explicitEmptyCollections + NodeTaints: + $payloadType: explicitEmptyCollections + Tags: + $payloadType: explicitEmptyCollections ManagedClusters_AgentPool: $exportAs: ManagedClustersAgentPool $supportedFrom: v2.0.0 @@ -1346,6 +1378,23 @@ objectModelConfiguration: - UserCredentials $generatedConfigs: OIDCIssuerProfile: $.Status.OidcIssuerProfile.IssuerURL + ManagedCluster_Spec: + Tags: + $payloadType: explicitEmptyCollections + ManagedClusterAgentPoolProfile: + NodeLabels: + $payloadType: explicitEmptyCollections + NodeTaints: + $payloadType: explicitEmptyCollections + Tags: + $payloadType: explicitEmptyCollections + ManagedClusterAgentPoolProfileProperties: + NodeLabels: + $payloadType: explicitEmptyCollections + NodeTaints: + $payloadType: explicitEmptyCollections + Tags: + $payloadType: explicitEmptyCollections ManagedClusters_AgentPool: $exportAs: ManagedClustersAgentPool $supportedFrom: v2.0.0 @@ -1387,6 +1436,23 @@ objectModelConfiguration: - UserCredentials $generatedConfigs: OIDCIssuerProfile: $.Status.OidcIssuerProfile.IssuerURL + ManagedCluster_Spec: + Tags: + $payloadType: explicitEmptyCollections + ManagedClusterAgentPoolProfile: + NodeLabels: + $payloadType: explicitEmptyCollections + NodeTaints: + $payloadType: explicitEmptyCollections + Tags: + $payloadType: explicitEmptyCollections + ManagedClusterAgentPoolProfileProperties: + NodeLabels: + $payloadType: explicitEmptyCollections + NodeTaints: + $payloadType: explicitEmptyCollections + Tags: + $payloadType: explicitEmptyCollections ManagedClusters_AgentPool: $exportAs: ManagedClustersAgentPool $supportedFrom: v2.5.0 diff --git a/v2/internal/controllers/containerservice_managedcluster_crud_v1api20230102preview_test.go b/v2/internal/controllers/containerservice_managedcluster_crud_v1api20230202preview_test.go similarity index 100% rename from v2/internal/controllers/containerservice_managedcluster_crud_v1api20230102preview_test.go rename to v2/internal/controllers/containerservice_managedcluster_crud_v1api20230202preview_test.go diff --git a/v2/internal/controllers/recordings/Test_Samples_CreationAndDeletion/Test_Containerservice_v1api20230315preview_CreationAndDeletion.yaml b/v2/internal/controllers/recordings/Test_Samples_CreationAndDeletion/Test_Containerservice_v1api20230315preview_CreationAndDeletion.yaml index 483790d1bf..37cbadbcf9 100644 --- a/v2/internal/controllers/recordings/Test_Samples_CreationAndDeletion/Test_Containerservice_v1api20230315preview_CreationAndDeletion.yaml +++ b/v2/internal/controllers/recordings/Test_Samples_CreationAndDeletion/Test_Containerservice_v1api20230315preview_CreationAndDeletion.yaml @@ -810,7 +810,7 @@ interactions: code: 200 duration: "" - request: - body: '{"location":"westus3","name":"samplefleet2023315preview","properties":{"hubProfile":{"dnsPrefix":"aso"}},"tags":{}}' + body: '{"location":"westus3","name":"samplefleet2023315preview","properties":{"hubProfile":{"dnsPrefix":"aso"}},"tags":null}' form: {} headers: Accept: @@ -824,7 +824,7 @@ interactions: url: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/asotest-rg-gxhtve/providers/Microsoft.ContainerService/fleets/samplefleet2023315preview?api-version=2023-03-15-preview method: PUT response: - body: '{"eTag":"\"db010993-0000-4d00-0000-654e783d0000\"","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/asotest-rg-gxhtve/providers/Microsoft.ContainerService/fleets/samplefleet2023315preview","location":"westus3","name":"samplefleet2023315preview","properties":{"hubProfile":{"dnsPrefix":"aso"},"provisioningState":"Creating"},"systemData":{"createdAt":"2001-02-03T04:05:06Z","createdBy":"99de824c-b6d0-4769-af94-8819d4093b83","createdByType":"Application","lastModifiedAt":"2001-02-03T04:05:06Z","lastModifiedBy":"99de824c-b6d0-4769-af94-8819d4093b83","lastModifiedByType":"Application"},"tags":{},"type":"Microsoft.ContainerService/fleets"}' + body: '{"eTag":"\"db010993-0000-4d00-0000-654e783d0000\"","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/asotest-rg-gxhtve/providers/Microsoft.ContainerService/fleets/samplefleet2023315preview","location":"westus3","name":"samplefleet2023315preview","properties":{"hubProfile":{"dnsPrefix":"aso"},"provisioningState":"Creating"},"systemData":{"createdAt":"2001-02-03T04:05:06Z","createdBy":"99de824c-b6d0-4769-af94-8819d4093b83","createdByType":"Application","lastModifiedAt":"2001-02-03T04:05:06Z","lastModifiedBy":"99de824c-b6d0-4769-af94-8819d4093b83","lastModifiedByType":"Application"},"type":"Microsoft.ContainerService/fleets"}' headers: Azure-Asyncoperation: - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerService/locations/westus3/operations/74471d4b-34f4-44eb-a7b4-fc2e7afd1e26?api-version=2016-03-30&t=638352382055406872&c=MIIHADCCBeigAwIBAgITHgOPMCVriuS4-lWO9AAAA48wJTANBgkqhkiG9w0BAQsFADBEMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1FMRgwFgYDVQQDEw9BTUUgSW5mcmEgQ0EgMDYwHhcNMjMxMTAxMTk0NDE0WhcNMjQxMDI2MTk0NDE0WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOVYjGR__tDbQAkWmgTzkuhLkeLHMZF4BUrWy0rFsX2EQ-jKcnRoDb5IHA8d5kzQwRSfOsVkMYLJuxNfSVVkrT-2bRtOmLA39FjlxIxE-eeCClqoDypQUkMQFt03BhhgviChly_GAB1VdMVAtOkAqyDD7YkPdR2axUfPszW3havSW-NiPjXkJezv1WPkDjGs7VhIBdJ276lVsVC2AXVfTa_AH34QbGAVCgFq8f8RTHFAF3kuyznwrhR89pSFJZDGMu3zaigorG-qTVP15VUl0SThQRKENFzEVVIr40ndWscX0MCYmJQFpzB426gRb4aM5DABy8TfY3hU0Ma6Pqs5vu0CAwEAAaOCA-0wggPpMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwEwCgYIKwYBBQUHAwIwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIhpDjDYTVtHiE8Ys-hZvdFs6dEoFggvX2K4Py0SACAWQCAQowggHLBggrBgEFBQcBAQSCAb0wggG5MGMGCCsGAQUFBzAChldodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQkwyUEtJSU5UQ0EwMi5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwNi5jcnQwUwYIKwYBBQUHMAKGR2h0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDIuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDYuY3J0MFMGCCsGAQUFBzAChkdodHRwOi8vY3JsMi5hbWUuZ2JsL2FpYS9CTDJQS0lJTlRDQTAyLkFNRS5HQkxfQU1FJTIwSW5mcmElMjBDQSUyMDA2LmNydDBTBggrBgEFBQcwAoZHaHR0cDovL2NybDMuYW1lLmdibC9haWEvQkwyUEtJSU5UQ0EwMi5BTUUuR0JMX0FNRSUyMEluZnJhJTIwQ0ElMjAwNi5jcnQwUwYIKwYBBQUHMAKGR2h0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JMMlBLSUlOVENBMDIuQU1FLkdCTF9BTUUlMjBJbmZyYSUyMENBJTIwMDYuY3J0MB0GA1UdDgQWBBQ2lSwc1_ggaso1He0vGUt5JD_O-zAOBgNVHQ8BAf8EBAMCBaAwggEmBgNVHR8EggEdMIIBGTCCARWgggERoIIBDYY_aHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NSTC9BTUUlMjBJbmZyYSUyMENBJTIwMDYuY3JshjFodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDYuY3JshjFodHRwOi8vY3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDYuY3JshjFodHRwOi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDYuY3JshjFodHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBJbmZyYSUyMENBJTIwMDYuY3JsMBcGA1UdIAQQMA4wDAYKKwYBBAGCN3sBATAfBgNVHSMEGDAWgBTxRmjG8cPwKy19i2rhsvm-NfzRQTAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAIw8F0494wN-l6CjjUdzUshsBr2wClEmC0dDhWd1f3feZIai44cKuTS3gtIM6iwdptdi2IL_bKhFk-6Fn-JXtbxsNzIJ8XXeKHhpzJVCU9MsZAFp3UQVp3udzC1s2K_AXSg-OCDXxNEARdl-WK7qOyoEscw8w8gjgQG2Ci1QnqpZZj3XNFuKivIpxFcC8b0hYbFHXp6mX3gSSX-JIvFbcilXTjD7Akh4wCqJ0qr_UVakf6f0hcmwRwI6pxk0EVSIZDDpivRgNJousujO4E5jLDLfevJch5BD-VERxY6bIKFRBYRq5WNGU96UKZ842RWmWmjml7ckpZd5e1UD5ErqHLA&s=Rtb0P8DNE84dcfHia3Y7RuANG2p7lR6CBBAiVHMvyb3o6ZRKhP5F1xp_7cuOSwDRd1kbb8fDpFkJxgTWBhsyIJ4qqXsUzgT1tLxAnBIVkfFMTr-T_Xs-JnAOyLEREqu0IMwGEapQxNX_1fATB3ZZvBwNGnJyFYDq8ZYR9CauNvCXBy-f0HyF4PMr72_4DZLXSQbpwRLqHq8VfwYQoeZJHLHWBHb2lkCMSxTBBSRNTYlTwWZ_BVA6k1tUznsUij3I5mxaHmGKLG-K1Kl3QftGaC5zQ4l84t3OdfJHDMOFgErAnQNlknXAXdp0ci-75hx1P1aOR82Mm1q99TPDXOIsrg&h=Vb64rzKxLz9t6iZVGDjv_JubW9ItRaiCiyF2WKYbtoc diff --git a/v2/tools/generator/internal/armconversion/arm_conversion_function.go b/v2/tools/generator/internal/armconversion/arm_conversion_function.go index 5406e606e0..4b267ae89e 100644 --- a/v2/tools/generator/internal/armconversion/arm_conversion_function.go +++ b/v2/tools/generator/internal/armconversion/arm_conversion_function.go @@ -10,17 +10,16 @@ import ( "github.com/pkg/errors" "github.com/Azure/azure-service-operator/v2/tools/generator/internal/astmodel" - "github.com/Azure/azure-service-operator/v2/tools/generator/internal/config" ) // ARMConversionFunction represents an ARM conversion function for converting between a Kubernetes resource // and an ARM resource. type ARMConversionFunction struct { - armTypeName astmodel.TypeName - armType *astmodel.ObjectType - idFactory astmodel.IdentifierFactory - typeKind TypeKind - payloadType config.PayloadType + armTypeName astmodel.InternalTypeName + armType *astmodel.ObjectType + kubeTypeName astmodel.InternalTypeName + idFactory astmodel.IdentifierFactory + typeKind TypeKind } type ConvertToARMFunction struct { diff --git a/v2/tools/generator/internal/armconversion/convert_from_arm_function_builder.go b/v2/tools/generator/internal/armconversion/convert_from_arm_function_builder.go index f9d14057ec..b52dcb51e6 100644 --- a/v2/tools/generator/internal/armconversion/convert_from_arm_function_builder.go +++ b/v2/tools/generator/internal/armconversion/convert_from_arm_function_builder.go @@ -15,7 +15,6 @@ import ( "github.com/Azure/azure-service-operator/v2/tools/generator/internal/astbuilder" "github.com/Azure/azure-service-operator/v2/tools/generator/internal/astmodel" - "github.com/Azure/azure-service-operator/v2/tools/generator/internal/config" ) type convertFromARMBuilder struct { @@ -41,14 +40,14 @@ func newConvertFromARMFunctionBuilder( conversionBuilder: conversionBuilder{ methodName: methodName, - armType: c.armType, - kubeType: getReceiverObjectType(codeGenerationContext, receiver), + sourceType: c.armType, + sourceTypeName: c.armTypeName, + destinationType: getReceiverObjectType(codeGenerationContext, receiver), + destinationTypeName: c.kubeTypeName, receiverIdent: c.idFactory.CreateReceiver(receiver.Name()), receiverTypeExpr: receiver.AsType(codeGenerationContext), - armTypeIdent: c.armTypeName.Name(), idFactory: c.idFactory, typeKind: c.typeKind, - payloadType: c.payloadType, codeGenerationContext: codeGenerationContext, }, typeConversionBuilder: astmodel.NewConversionFunctionBuilder(c.idFactory, codeGenerationContext), @@ -66,11 +65,6 @@ func newConvertFromARMFunctionBuilder( // object structure or other properties. result.typeConversionBuilder.AddConversionHandlers(result.convertComplexTypeNameProperty) - // If this type requires special handling for collections, we add it here - if c.payloadType == config.ExplicitEmptyCollections { - result.typeConversionBuilder.PrependConversionHandlers(result.convertComplexTypeNameProperty) - } - result.propertyConversionHandlers = []propertyConversionHandler{ // Handlers for specific properties come first skipPropertiesFlaggedWithNoARMConversion, @@ -115,8 +109,8 @@ func (builder *convertFromARMBuilder) functionDeclaration() (*dst.FuncDecl, erro func (builder *convertFromARMBuilder) functionBodyStatements() ([]dst.Stmt, error) { conversionStmts, err := generateTypeConversionAssignments( - builder.armType, - builder.kubeType, + builder.sourceType, + builder.destinationType, builder.propertyConversionHandler) if err != nil { return nil, errors.Wrapf(err, "unable to generate conversion statements for %s", builder.methodName) @@ -149,7 +143,7 @@ func (builder *convertFromARMBuilder) assertInputTypeIsARM(needsResult bool) []d typeAssert := astbuilder.TypeAssert( dst.NewIdent(dest), dst.NewIdent(builder.inputIdent), - dst.NewIdent(builder.armTypeIdent)) + dst.NewIdent(builder.sourceTypeIdent())) // Check the result of the type assert // if !ok { @@ -160,7 +154,7 @@ func (builder *convertFromARMBuilder) assertInputTypeIsARM(needsResult bool) []d fmtPackage, fmt.Sprintf("unexpected type supplied for %s() function. Expected %s, got %%T", builder.methodName, - builder.armTypeIdent), + builder.sourceTypeIdent()), dst.NewIdent(builder.inputIdent))) return astbuilder.Statements(typeAssert, returnIfNotOk) @@ -270,10 +264,10 @@ func (builder *convertFromARMBuilder) ownerPropertyHandler( ownerNameType, ok := astmodel.AsTypeName(toProp.PropertyType()) if !ok { var kubeDescription strings.Builder - builder.kubeType.WriteDebugDescription(&kubeDescription, nil) + builder.destinationType.WriteDebugDescription(&kubeDescription, nil) var armDescription strings.Builder - builder.armType.WriteDebugDescription(&armDescription, nil) + builder.sourceType.WriteDebugDescription(&armDescription, nil) return notHandled, errors.Errorf( @@ -466,14 +460,16 @@ func (builder *convertFromARMBuilder) buildFlattenedAssignment( stmts, err := builder.typeConversionBuilder.BuildConversion( astmodel.ConversionParameters{ - Source: astbuilder.Selector(dst.NewIdent(builder.typedInputIdent), string(fromProp.PropertyName()), string(originalPropName)), - SourceType: nestedProp.PropertyType(), - Destination: astbuilder.Selector(dst.NewIdent(builder.receiverIdent), string(toProp.PropertyName())), - DestinationType: toProp.PropertyType(), - NameHint: string(toProp.PropertyName()), - ConversionContext: nil, - AssignmentHandler: nil, - Locals: locals, + Source: astbuilder.Selector(dst.NewIdent(builder.typedInputIdent), string(fromProp.PropertyName()), string(originalPropName)), + SourceType: nestedProp.PropertyType(), + Destination: astbuilder.Selector(dst.NewIdent(builder.receiverIdent), string(toProp.PropertyName())), + DestinationType: toProp.PropertyType(), + NameHint: string(toProp.PropertyName()), + ConversionContext: nil, + AssignmentHandler: nil, + Locals: locals, + SourceProperty: fromProp, + DestinationProperty: toProp, }) if err != nil { return notHandled, @@ -526,14 +522,16 @@ func (builder *convertFromARMBuilder) propertiesByNameHandler( conversion, err := builder.typeConversionBuilder.BuildConversion( astmodel.ConversionParameters{ - Source: astbuilder.Selector(dst.NewIdent(builder.typedInputIdent), string(fromProp.PropertyName())), - SourceType: fromProp.PropertyType(), - Destination: astbuilder.Selector(dst.NewIdent(builder.receiverIdent), string(toProp.PropertyName())), - DestinationType: toProp.PropertyType(), - NameHint: string(toProp.PropertyName()), - ConversionContext: nil, - AssignmentHandler: nil, - Locals: builder.locals, + Source: astbuilder.Selector(dst.NewIdent(builder.typedInputIdent), string(fromProp.PropertyName())), + SourceType: fromProp.PropertyType(), + Destination: astbuilder.Selector(dst.NewIdent(builder.receiverIdent), string(toProp.PropertyName())), + DestinationType: toProp.PropertyType(), + NameHint: string(toProp.PropertyName()), + ConversionContext: nil, + AssignmentHandler: nil, + Locals: builder.locals, + SourceProperty: fromProp, + DestinationProperty: toProp, }) if err != nil { return notHandled, diff --git a/v2/tools/generator/internal/armconversion/convert_to_arm_function_builder.go b/v2/tools/generator/internal/armconversion/convert_to_arm_function_builder.go index eb68797680..ccbcabbd97 100644 --- a/v2/tools/generator/internal/armconversion/convert_to_arm_function_builder.go +++ b/v2/tools/generator/internal/armconversion/convert_to_arm_function_builder.go @@ -12,10 +12,8 @@ import ( "github.com/dave/dst" "github.com/pkg/errors" - "github.com/Azure/azure-service-operator/v2/internal/set" "github.com/Azure/azure-service-operator/v2/tools/generator/internal/astbuilder" "github.com/Azure/azure-service-operator/v2/tools/generator/internal/astmodel" - "github.com/Azure/azure-service-operator/v2/tools/generator/internal/config" ) const ( @@ -35,31 +33,21 @@ func newConvertToARMFunctionBuilder( receiver astmodel.InternalTypeName, methodName string, ) *convertToARMBuilder { - forceEmptyCollections := c.payloadType == config.ExplicitEmptyCollections - var emptyCollectionProperties set.Set[string] - if forceEmptyCollections { - // TODO: These should not be hardcoded here, instead should be in the azure-arm.yaml config - emptyCollectionProperties = set.Make( - "Tags", - "NodeLabels", - "NodeTaints") - } - result := &convertToARMBuilder{ conversionBuilder: conversionBuilder{ methodName: methodName, - armType: c.armType, - kubeType: getReceiverObjectType(codeGenerationContext, receiver), + sourceType: getReceiverObjectType(codeGenerationContext, receiver), + sourceTypeName: c.kubeTypeName, + destinationType: c.armType, + destinationTypeName: c.armTypeName, receiverIdent: c.idFactory.CreateReceiver(receiver.Name()), receiverTypeExpr: receiver.AsType(codeGenerationContext), - armTypeIdent: c.armTypeName.Name(), idFactory: c.idFactory, typeKind: c.typeKind, - payloadType: c.payloadType, codeGenerationContext: codeGenerationContext, }, resultIdent: "result", - typeConversionBuilder: astmodel.NewConversionFunctionBuilder(c.idFactory, codeGenerationContext).WithForceEmptyCollectionProperties(emptyCollectionProperties), + typeConversionBuilder: astmodel.NewConversionFunctionBuilder(c.idFactory, codeGenerationContext), locals: astmodel.NewKnownLocalsSet(c.idFactory), } // Add the receiver ident into the known locals @@ -120,12 +108,12 @@ func (builder *convertToARMBuilder) functionBodyStatements() ([]dst.Stmt, error) decl := astbuilder.ShortDeclaration( builder.resultIdent, - astbuilder.AddrOf(astbuilder.NewCompositeLiteralBuilder(dst.NewIdent(builder.armTypeIdent)).Build())) + astbuilder.AddrOf(astbuilder.NewCompositeLiteralBuilder(dst.NewIdent(builder.destinationTypeIdent())).Build())) // Each ARM object property needs to be filled out conversions, err := generateTypeConversionAssignments( - builder.kubeType, - builder.armType, + builder.sourceType, + builder.destinationType, builder.propertyConversionHandler) if err != nil { return nil, errors.Wrapf(err, "unable to generate property conversions for %s", builder.methodName) @@ -238,13 +226,15 @@ func (builder *convertToARMBuilder) configMapReferencePropertyHandler( strStmts, err := builder.typeConversionBuilder.BuildConversion( astmodel.ConversionParameters{ - Source: strPropSource, - SourceType: strProp.PropertyType(), - Destination: destination, - DestinationType: toProp.PropertyType(), - NameHint: string(strProp.PropertyName()), - ConversionContext: nil, - Locals: builder.locals, + Source: strPropSource, + SourceType: strProp.PropertyType(), + Destination: destination, + DestinationType: toProp.PropertyType(), + NameHint: string(strProp.PropertyName()), + ConversionContext: nil, + Locals: builder.locals, + SourceProperty: strProp, + DestinationProperty: toProp, }, ) if err != nil { @@ -256,13 +246,15 @@ func (builder *convertToARMBuilder) configMapReferencePropertyHandler( refStmts, err := builder.typeConversionBuilder.BuildConversion( astmodel.ConversionParameters{ - Source: refPropSource, - SourceType: refProp.PropertyType(), - Destination: destination, - DestinationType: toProp.PropertyType(), - NameHint: string(strProp.PropertyName()), - ConversionContext: nil, - Locals: builder.locals, + Source: refPropSource, + SourceType: refProp.PropertyType(), + Destination: destination, + DestinationType: toProp.PropertyType(), + NameHint: string(strProp.PropertyName()), + ConversionContext: nil, + Locals: builder.locals, + SourceProperty: refProp, + DestinationProperty: toProp, }, ) if err != nil { @@ -304,13 +296,15 @@ func (builder *convertToARMBuilder) userAssignedIdentitiesPropertyHandler( conversion, err := builder.typeConversionBuilder.BuildConversion( astmodel.ConversionParameters{ - Source: source, - SourceType: fromProp.PropertyType(), - Destination: destination, - DestinationType: toProp.PropertyType(), - NameHint: string(fromProp.PropertyName()), - ConversionContext: nil, - Locals: builder.locals, + Source: source, + SourceType: fromProp.PropertyType(), + Destination: destination, + DestinationType: toProp.PropertyType(), + NameHint: string(fromProp.PropertyName()), + ConversionContext: nil, + Locals: builder.locals, + SourceProperty: fromProp, + DestinationProperty: toProp, }, ) if err != nil { @@ -357,13 +351,15 @@ func (builder *convertToARMBuilder) referencePropertyHandler( conversion, err := builder.typeConversionBuilder.BuildConversion( astmodel.ConversionParameters{ - Source: source, - SourceType: fromProp.PropertyType(), - Destination: destination, - DestinationType: toProp.PropertyType(), - NameHint: string(fromProp.PropertyName()), - ConversionContext: nil, - Locals: builder.locals, + Source: source, + SourceType: fromProp.PropertyType(), + Destination: destination, + DestinationType: toProp.PropertyType(), + NameHint: string(fromProp.PropertyName()), + ConversionContext: nil, + Locals: builder.locals, + SourceProperty: fromProp, + DestinationProperty: toProp, }, ) if err != nil { @@ -473,14 +469,16 @@ func (builder *convertToARMBuilder) flattenedPropertyHandler( // generate conversion conversion, err := builder.typeConversionBuilder.BuildConversion( astmodel.ConversionParameters{ - Source: astbuilder.Selector(dst.NewIdent(builder.receiverIdent), string(fromProp.PropertyName())), - SourceType: fromProp.PropertyType(), - Destination: astbuilder.Selector(dst.NewIdent(builder.resultIdent), string(toPropName), string(toSubProp.PropertyName())), - DestinationType: toSubProp.PropertyType(), - NameHint: string(toSubProp.PropertyName()), - ConversionContext: nil, - AssignmentHandler: nil, - Locals: builder.locals, + Source: astbuilder.Selector(dst.NewIdent(builder.receiverIdent), string(fromProp.PropertyName())), + SourceType: fromProp.PropertyType(), + Destination: astbuilder.Selector(dst.NewIdent(builder.resultIdent), string(toPropName), string(toSubProp.PropertyName())), + DestinationType: toSubProp.PropertyType(), + NameHint: string(toSubProp.PropertyName()), + ConversionContext: nil, + AssignmentHandler: nil, + Locals: builder.locals, + SourceProperty: fromProp, + DestinationProperty: toProp, }) if err != nil { return notHandled, @@ -563,13 +561,15 @@ func (builder *convertToARMBuilder) propertiesByNameHandler( conversion, err := builder.typeConversionBuilder.BuildConversion( astmodel.ConversionParameters{ - Source: source, - SourceType: fromProp.PropertyType(), - Destination: destination, - DestinationType: toProp.PropertyType(), - NameHint: string(toProp.PropertyName()), - ConversionContext: nil, - Locals: builder.locals, + Source: source, + SourceType: fromProp.PropertyType(), + Destination: destination, + DestinationType: toProp.PropertyType(), + NameHint: string(toProp.PropertyName()), + ConversionContext: nil, + Locals: builder.locals, + SourceProperty: fromProp, + DestinationProperty: toProp, }, ) if err != nil { @@ -651,14 +651,16 @@ func (builder *convertToARMBuilder) convertUserAssignedIdentitiesCollection( // Rely on existing conversion handler for ResourceReference type conversion, err := conversionBuilder.BuildConversion( astmodel.ConversionParameters{ - Source: refSelector, - SourceType: refProperty.PropertyType(), - Destination: dst.NewIdent(key), - DestinationType: destinationType.KeyType(), - NameHint: itemIdent, - ConversionContext: append(params.ConversionContext, destinationType), - AssignmentHandler: astmodel.AssignmentHandlerDefine, - Locals: locals, + Source: refSelector, + SourceType: refProperty.PropertyType(), + Destination: dst.NewIdent(key), + DestinationType: destinationType.KeyType(), + NameHint: itemIdent, + ConversionContext: append(params.ConversionContext, destinationType), + AssignmentHandler: astmodel.AssignmentHandlerDefine, + Locals: locals, + SourceProperty: params.SourceProperty, + DestinationProperty: params.DestinationProperty, }) if err != nil { return nil, diff --git a/v2/tools/generator/internal/armconversion/shared.go b/v2/tools/generator/internal/armconversion/shared.go index 1479ef8971..85accbffea 100644 --- a/v2/tools/generator/internal/armconversion/shared.go +++ b/v2/tools/generator/internal/armconversion/shared.go @@ -24,14 +24,15 @@ import ( type conversionBuilder struct { receiverIdent string receiverTypeExpr dst.Expr - armTypeIdent string codeGenerationContext *astmodel.CodeGenerationContext idFactory astmodel.IdentifierFactory typeKind TypeKind payloadType config.PayloadType methodName string - kubeType *astmodel.ObjectType - armType *astmodel.ObjectType + destinationType *astmodel.ObjectType + destinationTypeName astmodel.InternalTypeName + sourceType *astmodel.ObjectType + sourceTypeName astmodel.InternalTypeName propertyConversionHandlers []propertyConversionHandler } @@ -43,6 +44,14 @@ const ( TypeKindStatus ) +func (builder conversionBuilder) sourceTypeIdent() string { + return builder.sourceTypeName.Name() +} + +func (builder conversionBuilder) destinationTypeIdent() string { + return builder.destinationTypeName.Name() +} + func (builder conversionBuilder) propertyConversionHandler( toProp *astmodel.PropertyDefinition, fromType *astmodel.ObjectType, @@ -61,10 +70,10 @@ func (builder conversionBuilder) propertyConversionHandler( } var kubeDescription strings.Builder - builder.kubeType.WriteDebugDescription(&kubeDescription, nil) + builder.destinationType.WriteDebugDescription(&kubeDescription, nil) var armDescription strings.Builder - builder.armType.WriteDebugDescription(&armDescription, nil) + builder.sourceType.WriteDebugDescription(&armDescription, nil) message := fmt.Sprintf( "no property found for %q in method %s()\nFrom: %s\nTo: %s", @@ -185,32 +194,33 @@ func generateTypeConversionAssignments( // NewARMConversionImplementation creates an interface implementation with the specified ARM conversion functions func NewARMConversionImplementation( - armTypeName astmodel.TypeName, + armTypeName astmodel.InternalTypeName, armType *astmodel.ObjectType, + kubeTypeName astmodel.InternalTypeName, idFactory astmodel.IdentifierFactory, typeKind TypeKind, - payloadType config.PayloadType, ) *astmodel.InterfaceImplementation { var convertToARMFunc *ConvertToARMFunction if typeKind != TypeKindStatus { // status type should not have ConvertToARM convertToARMFunc = &ConvertToARMFunction{ ARMConversionFunction: ARMConversionFunction{ - armTypeName: armTypeName, - armType: armType, - idFactory: idFactory, - typeKind: typeKind, - payloadType: payloadType, + armTypeName: armTypeName, + armType: armType, + kubeTypeName: kubeTypeName, + idFactory: idFactory, + typeKind: typeKind, }, } } populateFromARMFunc := &PopulateFromARMFunction{ ARMConversionFunction: ARMConversionFunction{ - armTypeName: armTypeName, - armType: armType, - idFactory: idFactory, - typeKind: typeKind, + armTypeName: armTypeName, + armType: armType, + kubeTypeName: kubeTypeName, + idFactory: idFactory, + typeKind: typeKind, }, } diff --git a/v2/tools/generator/internal/astmodel/conversion_function_builder.go b/v2/tools/generator/internal/astmodel/conversion_function_builder.go index 0b1e736342..fd5aa00a2b 100644 --- a/v2/tools/generator/internal/astmodel/conversion_function_builder.go +++ b/v2/tools/generator/internal/astmodel/conversion_function_builder.go @@ -13,7 +13,6 @@ import ( "github.com/dave/dst" "github.com/pkg/errors" - "github.com/Azure/azure-service-operator/v2/internal/set" "github.com/Azure/azure-service-operator/v2/tools/generator/internal/astbuilder" ) @@ -27,6 +26,13 @@ type ConversionParameters struct { ConversionContext []Type AssignmentHandler func(destination, source dst.Expr) dst.Stmt Locals *KnownLocalsSet + + // SourceProperty is the source property for this conversion. Note that for recursive conversions this still refers + // to the source property that the conversion chain will ultimately be sourced from + SourceProperty *PropertyDefinition + // DestinationProperty is the destination property for this conversion. Note that for recursive conversions this still refers + // to the destination property that the conversion chain will ultimately be assigned to + DestinationProperty *PropertyDefinition } // GetSource gets the Source field. @@ -127,9 +133,8 @@ type ConversionFunctionBuilder struct { IDFactory IdentifierFactory CodeGenerationContext *CodeGenerationContext - // ForceEmptyCollections signals that collections should be initialized to a size 0 collection, rather than an empty collection - ForceEmptyCollections bool - EmptyCollectionProperties set.Set[string] + // SupportExplicitEmptyCollectionsSerializationMode signals that collections can be initialized to a size 0 collection, rather than an empty collection + SupportExplicitEmptyCollectionsSerializationMode bool } // NewConversionFunctionBuilder creates a new ConversionFunctionBuilder with the default conversions already added. @@ -138,9 +143,8 @@ func NewConversionFunctionBuilder( codeGenerationContext *CodeGenerationContext, ) *ConversionFunctionBuilder { return &ConversionFunctionBuilder{ - IDFactory: idFactory, - CodeGenerationContext: codeGenerationContext, - EmptyCollectionProperties: set.Make[string](), + IDFactory: idFactory, + CodeGenerationContext: codeGenerationContext, conversions: []ConversionHandler{ // Complex wrapper types checked first IdentityConvertComplexOptionalProperty, @@ -159,32 +163,13 @@ func NewConversionFunctionBuilder( } } -func (builder *ConversionFunctionBuilder) WithForceEmptyCollections() *ConversionFunctionBuilder { - builder.ForceEmptyCollections = true +func (builder *ConversionFunctionBuilder) WithSupportExplicitEmptyCollectionsSerializationMode() *ConversionFunctionBuilder { + builder.SupportExplicitEmptyCollectionsSerializationMode = true return builder } -func (builder *ConversionFunctionBuilder) WithForceEmptyCollectionProperties(properties set.Set[string]) *ConversionFunctionBuilder { - if len(properties) == 0 { - return builder - } - - builder.ForceEmptyCollections = true - builder.EmptyCollectionProperties.AddAll(properties) - return builder -} - -func (builder *ConversionFunctionBuilder) ShouldInitializeCollectionToEmpty(nameHint string) bool { - if !builder.ForceEmptyCollections { - return false - } - - // If there were no properties specified and ForceEmptyCollections is true, that means force everything - if builder.ForceEmptyCollections && len(builder.EmptyCollectionProperties) == 0 { - return true - } - - return builder.EmptyCollectionProperties.Contains(nameHint) +func (builder *ConversionFunctionBuilder) ShouldInitializeCollectionToEmpty(prop *PropertyDefinition) bool { + return prop.HasTagValue(SerializationType, SerializationTypeExplicitEmptyCollection) } // AddConversionHandlers adds the specified conversion handlers to the end of the conversion list. @@ -243,14 +228,16 @@ func IdentityConvertComplexOptionalProperty( conversion, err := builder.BuildConversion( ConversionParameters{ - Source: astbuilder.Dereference(params.GetSource()), - SourceType: sourceType.Element(), - Destination: dst.NewIdent(tempVarIdent), - DestinationType: destinationType.Element(), - NameHint: params.NameHint, - ConversionContext: append(params.ConversionContext, destinationType), - AssignmentHandler: AssignmentHandlerDefine, - Locals: locals, + Source: astbuilder.Dereference(params.GetSource()), + SourceType: sourceType.Element(), + Destination: dst.NewIdent(tempVarIdent), + DestinationType: destinationType.Element(), + NameHint: params.NameHint, + ConversionContext: append(params.ConversionContext, destinationType), + AssignmentHandler: AssignmentHandlerDefine, + Locals: locals, + SourceProperty: params.SourceProperty, + DestinationProperty: params.DestinationProperty, }) if err != nil { return nil, errors.Wrap(err, "unable to build conversion for optional element") @@ -315,14 +302,16 @@ func IdentityConvertComplexArrayProperty( conversion, err := builder.BuildConversion( ConversionParameters{ - Source: dst.NewIdent(itemIdent), - SourceType: sourceType.Element(), - Destination: dst.Clone(destination).(dst.Expr), - DestinationType: destinationType.Element(), - NameHint: itemIdent, - ConversionContext: append(params.ConversionContext, destinationType), - AssignmentHandler: astbuilder.AppendItemToSlice, - Locals: locals, + Source: dst.NewIdent(itemIdent), + SourceType: sourceType.Element(), + Destination: dst.Clone(destination).(dst.Expr), + DestinationType: destinationType.Element(), + NameHint: itemIdent, + ConversionContext: append(params.ConversionContext, destinationType), + AssignmentHandler: astbuilder.AppendItemToSlice, + Locals: locals, + SourceProperty: params.SourceProperty, + DestinationProperty: params.DestinationProperty, }) if err != nil { return nil, errors.Wrap(err, "unable to build conversion for array element") @@ -346,7 +335,7 @@ func IdentityConvertComplexArrayProperty( // If we must forcibly construct empty collections, check if the destination is nil and if so, construct an empty collection // This only applies for top-level collections (we don't forcibly construct nested collections) - if depth == 0 && builder.ShouldInitializeCollectionToEmpty(params.NameHint) { + if depth == 0 && builder.ShouldInitializeCollectionToEmpty(params.SourceProperty) { emptySlice := astbuilder.SliceLiteral(destinationType.Element().AsType(builder.CodeGenerationContext)) assignEmpty := astbuilder.SimpleAssignment(params.GetDestination(), emptySlice) astbuilder.AddComments( @@ -429,14 +418,16 @@ func IdentityConvertComplexMapProperty( conversion, err := builder.BuildConversion( ConversionParameters{ - Source: dst.NewIdent(valueIdent), - SourceType: sourceType.ValueType(), - Destination: dst.Clone(destination).(dst.Expr), - DestinationType: destinationType.ValueType(), - NameHint: nameHint, - ConversionContext: append(params.ConversionContext, destinationType), - AssignmentHandler: handler, - Locals: locals, + Source: dst.NewIdent(valueIdent), + SourceType: sourceType.ValueType(), + Destination: dst.Clone(destination).(dst.Expr), + DestinationType: destinationType.ValueType(), + NameHint: nameHint, + ConversionContext: append(params.ConversionContext, destinationType), + AssignmentHandler: handler, + Locals: locals, + SourceProperty: params.SourceProperty, + DestinationProperty: params.DestinationProperty, }) if err != nil { return nil, errors.Wrap(err, "unable to build conversion for map value") @@ -453,7 +444,7 @@ func IdentityConvertComplexMapProperty( // If we must forcibly construct empty collections, check if the destination is nil and if so, construct an empty collection // This only applies for top-level collections (we don't forcibly construct nested collections) var result *dst.IfStmt - if depth == 0 && builder.ShouldInitializeCollectionToEmpty(params.NameHint) { + if depth == 0 && builder.ShouldInitializeCollectionToEmpty(params.SourceProperty) { emptyMap := astbuilder.MakeMap(keyTypeAst, valueTypeAst) assignEmpty := astbuilder.SimpleAssignment(params.GetDestination(), emptyMap) @@ -572,14 +563,16 @@ func AssignToOptional( conversion, err := builder.BuildConversion( ConversionParameters{ - Source: params.Source, - SourceType: params.SourceType, - Destination: dst.NewIdent(tmpLocal), - DestinationType: dstType, - NameHint: tmpLocal, - ConversionContext: nil, - AssignmentHandler: nil, - Locals: params.Locals, + Source: params.Source, + SourceType: params.SourceType, + Destination: dst.NewIdent(tmpLocal), + DestinationType: dstType, + NameHint: tmpLocal, + ConversionContext: nil, + AssignmentHandler: nil, + Locals: params.Locals, + SourceProperty: params.SourceProperty, + DestinationProperty: params.DestinationProperty, }) if err != nil { return nil, errors.Wrap(err, "unable to build inner conversion to optional") @@ -633,14 +626,16 @@ func AssignFromOptional( conversion, err := builder.BuildConversion( ConversionParameters{ - Source: astbuilder.Dereference(params.GetSource()), - SourceType: srcType, - Destination: dst.NewIdent(tmpLocal), - DestinationType: params.DestinationType, - NameHint: tmpLocal, - ConversionContext: nil, - AssignmentHandler: nil, - Locals: locals, + Source: astbuilder.Dereference(params.GetSource()), + SourceType: srcType, + Destination: dst.NewIdent(tmpLocal), + DestinationType: params.DestinationType, + NameHint: tmpLocal, + ConversionContext: nil, + AssignmentHandler: nil, + Locals: locals, + SourceProperty: params.SourceProperty, + DestinationProperty: params.DestinationProperty, }) if err != nil { return nil, errors.Wrap(err, "unable to build inner conversion from optional") diff --git a/v2/tools/generator/internal/astmodel/generation_consts.go b/v2/tools/generator/internal/astmodel/generation_consts.go index 7adb313742..cc3e30ee2b 100644 --- a/v2/tools/generator/internal/astmodel/generation_consts.go +++ b/v2/tools/generator/internal/astmodel/generation_consts.go @@ -25,4 +25,8 @@ const ( // PrincipalId *string `optionalConfigMapPair:"PrincipalId"` // PrincipalIdRef *genruntime.ConfigMapReference `optionalConfigMapPair:"PrincipalId"` OptionalConfigMapPairTag = "optionalConfigMapPair" + + // SerializationType is the tag ID used for controlling if resources have special serialization rules + SerializationType = "serializationType" + SerializationTypeExplicitEmptyCollection = "explicitEmptyCollection" ) diff --git a/v2/tools/generator/internal/codegen/code_generator.go b/v2/tools/generator/internal/codegen/code_generator.go index f324e70fbd..cf00c6a348 100644 --- a/v2/tools/generator/internal/codegen/code_generator.go +++ b/v2/tools/generator/internal/codegen/code_generator.go @@ -184,6 +184,7 @@ func createAllPipelineStages( pipeline.ReportOnTypesAndVersions(configuration).UsedFor(pipeline.ARMTarget), // TODO: For now only used for ARM pipeline.CreateARMTypes(configuration.ObjectModelConfiguration, idFactory, log).UsedFor(pipeline.ARMTarget), + pipeline.AddSerializationTypeTag(configuration), pipeline.PruneResourcesWithLifecycleOwnedByParent(configuration).UsedFor(pipeline.ARMTarget), pipeline.MakeOneOfDiscriminantRequired().UsedFor(pipeline.ARMTarget), pipeline.ApplyARMConversionInterface(idFactory, configuration.ObjectModelConfiguration).UsedFor(pipeline.ARMTarget), diff --git a/v2/tools/generator/internal/codegen/pipeline/add_arm_conversion_interface.go b/v2/tools/generator/internal/codegen/pipeline/add_arm_conversion_interface.go index 2636e3200d..52299e3285 100644 --- a/v2/tools/generator/internal/codegen/pipeline/add_arm_conversion_interface.go +++ b/v2/tools/generator/internal/codegen/pipeline/add_arm_conversion_interface.go @@ -11,6 +11,7 @@ import ( "github.com/pkg/errors" + "github.com/Azure/azure-service-operator/v2/internal/set" "github.com/Azure/azure-service-operator/v2/tools/generator/internal/armconversion" "github.com/Azure/azure-service-operator/v2/tools/generator/internal/astmodel" "github.com/Azure/azure-service-operator/v2/tools/generator/internal/config" @@ -220,10 +221,15 @@ func (c *armConversionApplier) transformSpec(resourceType *astmodel.ResourceType return kubernetesDef, nil } +type PayloadTypeDetails struct { + payloadType config.PayloadType + explicitEmptyCollectionProperties set.Set[astmodel.PropertyReference] +} + func (c *armConversionApplier) addARMConversionInterface( kubeDef astmodel.TypeDefinition, armDef astmodel.TypeDefinition, - typeType armconversion.TypeKind, + typeKind armconversion.TypeKind, ) (astmodel.TypeDefinition, error) { objectType, ok := astmodel.AsObjectType(armDef.Type()) emptyDef := astmodel.TypeDefinition{} @@ -231,20 +237,13 @@ func (c *armConversionApplier) addARMConversionInterface( return emptyDef, errors.Errorf("ARM definition %q did not define an object type", armDef.Name()) } - // Determine if we need special handling for collection properties. Some RPs we need to send empty collections rather - // than nil collections, we need to determine if this def is subject to this requirement - payloadType := config.OmitEmptyProperties - if pt, ok := c.config.PayloadType.Lookup(kubeDef.Name().InternalPackageReference()); ok { - payloadType = pt - } - addInterfaceHandler := func(t *astmodel.ObjectType) (astmodel.Type, error) { result := t.WithInterface(armconversion.NewARMConversionImplementation( armDef.Name(), objectType, + kubeDef.Name(), c.idFactory, - typeType, - payloadType)) + typeKind)) return result, nil } diff --git a/v2/tools/generator/internal/codegen/pipeline/add_serialization_type_tag.go b/v2/tools/generator/internal/codegen/pipeline/add_serialization_type_tag.go new file mode 100644 index 0000000000..0bff9032b5 --- /dev/null +++ b/v2/tools/generator/internal/codegen/pipeline/add_serialization_type_tag.go @@ -0,0 +1,88 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + +package pipeline + +import ( + "context" + + "github.com/pkg/errors" + + "github.com/Azure/azure-service-operator/v2/tools/generator/internal/astmodel" + "github.com/Azure/azure-service-operator/v2/tools/generator/internal/config" +) + +const AddSerializationTypeTagStageID = "addSerializationTypeTag" + +// AddSerializationTypeTag adds a property tag to properties with special serialization instructions to initialize empty collections +// when serializing the payload to Azure. +// This uses a property tag for a few reasons: +// 1. Some types are flattened and other approaches are easily +// lost when flattening occurs. Putting the tag onto the property +// preserves it even through flattening. +// 2. In many ways this behavior is like an augmented `json:omitempty`, +// so it (IMO) makes sense to have a tag just like for JSON. It makes +// it clearer when looking at the Go object that the serialization behavior +// of these fields is special. +func AddSerializationTypeTag(configuration *config.Configuration) *Stage { + return NewStage( + AddSerializationTypeTagStageID, + "Adds a property tag to properties with special serialization instructions to initialize empty collections when serializing the payload to Azure", + func(ctx context.Context, state *State) (*State, error) { + updatedDefs := make(astmodel.TypeDefinitionSet) + + visitor := makePayloadTypeVisitor() + for _, def := range state.Definitions() { + t, err := visitor.Visit(def.Type(), &serializationVisitorContext{ + name: def.Name(), + config: configuration, + }) + if err != nil { + return nil, errors.Wrapf(err, "visiting %q", def.Name()) + } + + updatedDefs.Add(def.WithType(t)) + } + + return state.WithDefinitions(updatedDefs), nil + }) +} + +type serializationVisitorContext struct { + name astmodel.InternalTypeName + config *config.Configuration +} + +func applySerializationTypeTag(it *astmodel.TypeVisitor[*serializationVisitorContext], ot *astmodel.ObjectType, ctx *serializationVisitorContext) (astmodel.Type, error) { + var updatedProps []*astmodel.PropertyDefinition + + ot.Properties().ForEach( + func(prop *astmodel.PropertyDefinition) { + payloadType, ok := ctx.config.ObjectModelConfiguration.PayloadType.Lookup(ctx.name, prop.PropertyName()) + if !ok { + return // continue + } + + // Don't bother annotating the default behavior + if payloadType != config.ExplicitEmptyCollections { + return // continue + } + + prop = prop.WithTag(astmodel.SerializationType, astmodel.SerializationTypeExplicitEmptyCollection) + updatedProps = append(updatedProps, prop) + }) + + ot = ot.WithProperties(updatedProps...).WithProperties(updatedProps...) + + return astmodel.IdentityVisitOfObjectType(it, ot, ctx) +} + +func makePayloadTypeVisitor() astmodel.TypeVisitor[*serializationVisitorContext] { + visitor := astmodel.TypeVisitorBuilder[*serializationVisitorContext]{ + VisitObjectType: applySerializationTypeTag, + }.Build() + + return visitor +} diff --git a/v2/tools/generator/internal/codegen/pipeline/create_arm_types.go b/v2/tools/generator/internal/codegen/pipeline/create_arm_types.go index f3c79deb81..e37a5d003e 100644 --- a/v2/tools/generator/internal/codegen/pipeline/create_arm_types.go +++ b/v2/tools/generator/internal/codegen/pipeline/create_arm_types.go @@ -62,8 +62,8 @@ type armPropertyTypeConversionHandler func( ) (*astmodel.PropertyDefinition, error) type armPropertyTypeConversionContext struct { - isSpec bool - payloadType config.PayloadType + isSpec bool + typeName astmodel.InternalTypeName } type armTypeCreator struct { @@ -401,7 +401,13 @@ func (c *armTypeCreator) createARMProperty( // Return a property with (potentially) a new type result := prop.WithType(newType) - switch convContext.payloadType { + var payloadType config.PayloadType + payloadType, ok := c.configuration.PayloadType.Lookup(convContext.typeName, prop.PropertyName()) + if !ok { + payloadType = config.OmitEmptyProperties + } + + switch payloadType { case config.OmitEmptyProperties: // NOP @@ -534,12 +540,7 @@ func (c *armTypeCreator) createSpecConversionContext(name astmodel.InternalTypeN func (c *armTypeCreator) createConversionContext(name astmodel.InternalTypeName) *armPropertyTypeConversionContext { result := &armPropertyTypeConversionContext{ - // Default to 'omitempty' if not configured - payloadType: config.OmitEmptyProperties, - } - - if pt, ok := c.configuration.PayloadType.Lookup(name.InternalPackageReference()); ok { - result.payloadType = pt + typeName: name, } return result diff --git a/v2/tools/generator/internal/codegen/testdata/TestGolden_NewARMCodeGeneratorFromConfigCreatesRightPipeline.golden b/v2/tools/generator/internal/codegen/testdata/TestGolden_NewARMCodeGeneratorFromConfigCreatesRightPipeline.golden index 6dd4c20315..2b3eccc8f7 100644 --- a/v2/tools/generator/internal/codegen/testdata/TestGolden_NewARMCodeGeneratorFromConfigCreatesRightPipeline.golden +++ b/v2/tools/generator/internal/codegen/testdata/TestGolden_NewARMCodeGeneratorFromConfigCreatesRightPipeline.golden @@ -37,6 +37,7 @@ addSecrets azure Replace properties addConfigMaps azure Replace properties flagged as a configMap with genruntime.ConfigMapReference. For properties flagged as an optional configMap, add a new FromConfig property. reportTypesAndVersions azure Generate reports on types and versions in each package createArmTypes azure Create types for interaction with ARM +addSerializationTypeTag Adds a property tag to properties with special serialization instructions to initialize empty collections when serializing the payload to Azure pruneResourcesWithLifecycleOwnedByParentStage azure Prune embedded resources whose lifecycle is owned by the parent. makeOneOfDiscriminantRequired azure Fix one of types to a discriminator which is not omitempty/optional applyArmConversionInterface azure Add ARM conversion interfaces to Kubernetes types diff --git a/v2/tools/generator/internal/codegen/testdata/TestGolden_NewCrossplaneCodeGeneratorFromConfigCreatesRightPipeline.golden b/v2/tools/generator/internal/codegen/testdata/TestGolden_NewCrossplaneCodeGeneratorFromConfigCreatesRightPipeline.golden index d39d52aa7c..c4d23e3481 100644 --- a/v2/tools/generator/internal/codegen/testdata/TestGolden_NewCrossplaneCodeGeneratorFromConfigCreatesRightPipeline.golden +++ b/v2/tools/generator/internal/codegen/testdata/TestGolden_NewCrossplaneCodeGeneratorFromConfigCreatesRightPipeline.golden @@ -31,6 +31,7 @@ replaceAnyTypeWithJSON Replace properties using improvePropertyDescriptions Improve property descriptions by copying from the corresponding type fixOptionalCollectionAliases Replace types which are optional aliases to collections with just the collection alias transformCrossResourceReferencesToString crossplane Replace cross-resource references with string +addSerializationTypeTag Adds a property tag to properties with special serialization instructions to initialize empty collections when serializing the payload to Azure flattenProperties Apply flattening to properties marked for flattening stripUnreferenced Strip unreferenced types renameProperties Rename properties diff --git a/v2/tools/generator/internal/codegen/testdata/TestGolden_NewTestCodeGeneratorCreatesRightPipeline.golden b/v2/tools/generator/internal/codegen/testdata/TestGolden_NewTestCodeGeneratorCreatesRightPipeline.golden index 545ae621f8..a5d2b2e082 100644 --- a/v2/tools/generator/internal/codegen/testdata/TestGolden_NewTestCodeGeneratorCreatesRightPipeline.golden +++ b/v2/tools/generator/internal/codegen/testdata/TestGolden_NewTestCodeGeneratorCreatesRightPipeline.golden @@ -31,6 +31,7 @@ fixOptionalCollectionAliases Replace types which are op applyCrossResourceReferencesFromConfig azure Replace cross-resource references in the config with astmodel.ARMID addSecrets azure Replace properties flagged as secret with genruntime.SecretReference addConfigMaps azure Replace properties flagged as a configMap with genruntime.ConfigMapReference. For properties flagged as an optional configMap, add a new FromConfig property. +addSerializationTypeTag Adds a property tag to properties with special serialization instructions to initialize empty collections when serializing the payload to Azure makeOneOfDiscriminantRequired azure Fix one of types to a discriminator which is not omitempty/optional applyKubernetesResourceInterface azure Add the KubernetesResource interface to every resource flattenProperties Apply flattening to properties marked for flattening diff --git a/v2/tools/generator/internal/config/object_model_configuration.go b/v2/tools/generator/internal/config/object_model_configuration.go index 9754c17860..89342a2172 100644 --- a/v2/tools/generator/internal/config/object_model_configuration.go +++ b/v2/tools/generator/internal/config/object_model_configuration.go @@ -30,7 +30,7 @@ type ObjectModelConfiguration struct { typoAdvisor *typo.Advisor // Group access fields here (alphabetical, please) - PayloadType groupAccess[PayloadType] + PayloadType propertyAccess[PayloadType] // Type access fields here (alphabetical, please) AzureGeneratedSecrets typeAccess[[]string] @@ -62,8 +62,15 @@ func NewObjectModelConfiguration() *ObjectModelConfiguration { } // Initialize group access fields here (alphabetical, please) + // Initialize multi-level access fields here (alphabetical, please) result.PayloadType = makeGroupAccess[PayloadType]( - result, func(c *GroupConfiguration) *configurable[PayloadType] { return &c.PayloadType }) + result, + func(c *GroupConfiguration) *configurable[PayloadType] { return &c.PayloadType }, + ).withTypeOverride( + func(c *TypeConfiguration) *configurable[PayloadType] { return &c.PayloadType }, + ).withPropertyOverride( + func(c *PropertyConfiguration) *configurable[PayloadType] { return &c.PayloadType }, + ) // Initialize type access fields here (alphabetical, please) result.AzureGeneratedSecrets = makeTypeAccess[[]string]( diff --git a/v2/tools/generator/internal/config/object_model_configuration_test.go b/v2/tools/generator/internal/config/object_model_configuration_test.go index 25878e67a8..6340f1385c 100644 --- a/v2/tools/generator/internal/config/object_model_configuration_test.go +++ b/v2/tools/generator/internal/config/object_model_configuration_test.go @@ -572,7 +572,7 @@ func TestObjectModelConfiguration_LookupPayloadType_WhenConfigured_ReturnsExpect })). To(Succeed()) - payloadType, ok := omc.PayloadType.Lookup(name.InternalPackageReference()) + payloadType, ok := omc.PayloadType.Lookup(name, "") g.Expect(ok).To(BeTrue()) g.Expect(payloadType).To(Equal(ExplicitProperties)) } @@ -592,7 +592,7 @@ func TestObjectModelConfiguration_LookupPayloadType_WhenNotConfigured_ReturnsExp })). To(Succeed()) - _, ok := omc.PayloadType.Lookup(name.InternalPackageReference()) + _, ok := omc.PayloadType.Lookup(name, "") g.Expect(ok).To(BeFalse()) } @@ -611,7 +611,7 @@ func TestObjectModelConfiguration_VerifyPayloadTypeConsumed_WhenConsumed_Returns })). To(Succeed()) - _, ok := omc.PayloadType.Lookup(name.InternalPackageReference()) + _, ok := omc.PayloadType.Lookup(name, "") g.Expect(ok).To(BeTrue()) err := omc.PayloadType.VerifyConsumed() diff --git a/v2/tools/generator/internal/config/property_access.go b/v2/tools/generator/internal/config/property_access.go index a5287c8890..a13f6512a9 100644 --- a/v2/tools/generator/internal/config/property_access.go +++ b/v2/tools/generator/internal/config/property_access.go @@ -76,7 +76,17 @@ func (a *propertyAccess[T]) VerifyConsumed() error { c := a.accessor(configuration) return c.VerifyConsumed() }) - return visitor.visit(a.model) + + err := visitor.visit(a.model) + if err != nil { + return err + } + + if a.fallback != nil { + return a.fallback.VerifyConsumed() + } + + return nil } // MarkUnconsumed marks all configured values as unconsumed diff --git a/v2/tools/generator/internal/config/property_configuration.go b/v2/tools/generator/internal/config/property_configuration.go index d9fe57adcc..8e36389ace 100644 --- a/v2/tools/generator/internal/config/property_configuration.go +++ b/v2/tools/generator/internal/config/property_configuration.go @@ -147,6 +147,24 @@ func (pc *PropertyConfiguration) UnmarshalYAML(value *yaml.Node) error { continue } + // $payloadType: + if strings.EqualFold(lastId, payloadTypeTag) && c.Kind == yaml.ScalarNode { + switch strings.ToLower(c.Value) { + case string(OmitEmptyProperties): + pc.PayloadType.Set(OmitEmptyProperties) + case string(ExplicitCollections): + pc.PayloadType.Set(ExplicitCollections) + case string(ExplicitEmptyCollections): + pc.PayloadType.Set(ExplicitEmptyCollections) + case string(ExplicitProperties): + pc.PayloadType.Set(ExplicitProperties) + default: + return errors.Errorf("unknown %s value: %s.", payloadTypeTag, c.Value) + } + + continue + } + // No handler for this value, return an error return errors.Errorf( "property configuration, unexpected yaml value %s: %s (line %d col %d)", lastId, c.Value, c.Line, c.Column) diff --git a/v2/tools/generator/internal/config/type_access.go b/v2/tools/generator/internal/config/type_access.go index 58f5b31153..1120ffeecd 100644 --- a/v2/tools/generator/internal/config/type_access.go +++ b/v2/tools/generator/internal/config/type_access.go @@ -85,7 +85,16 @@ func (a *typeAccess[T]) VerifyConsumed() error { c := a.accessor(configuration) return c.VerifyConsumed() }) - return visitor.visit(a.model) + err := visitor.visit(a.model) + if err != nil { + return err + } + + if a.fallback != nil { + return a.fallback.VerifyConsumed() + } + + return nil } // MarkUnconsumed marks all configured values as unconsumed