diff --git a/v2/api/containerservice/v1api20210501/managed_cluster_types_gen.go b/v2/api/containerservice/v1api20210501/managed_cluster_types_gen.go index 44f7a463b7f..60c8c12c74d 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 bf2c839655e..c2ffa7d39bf 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 8a1513e2e3b..a57e65cc4af 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 1b56e315a8e..ca5ad28a649 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 24d4ff41b14..dd333b04b54 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 2eed653576f..4d56134ae9e 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 c2e2e854af3..af383f8905c 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 f603abb43cd..86f5478dc23 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 a47659e4b08..07226c91281 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 f191ef100cc..df5c9a829c3 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 3ab1f0c8fd2..ecd87f7bd75 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 6b3c707de6b..fd05a868352 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 d35c7c6dc8a..5ffebf6edb0 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 f656719ab21..3f1173ec69d 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 747d3e65159..13cf180cc0f 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 80fe28bec97..e1160a1d1bc 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 8b0369eb009..2afabb8717c 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 65356be82d2..ca761fbc1d5 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 483790d1bff..37cbadbcf99 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 5406e606e07..4b267ae89e3 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 f9d14057ec1..b52dcb51e63 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 eb68797680a..ccbcabbd97b 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 1479ef89715..85accbffeaf 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 0b1e736342c..fd5aa00a2bf 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 - return builder -} - -func (builder *ConversionFunctionBuilder) WithForceEmptyCollectionProperties(properties set.Set[string]) *ConversionFunctionBuilder { - if len(properties) == 0 { - return builder - } - - builder.ForceEmptyCollections = true - builder.EmptyCollectionProperties.AddAll(properties) +func (builder *ConversionFunctionBuilder) WithSupportExplicitEmptyCollectionsSerializationMode() *ConversionFunctionBuilder { + builder.SupportExplicitEmptyCollectionsSerializationMode = true 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 7adb3137423..cc3e30ee2bb 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 f324e70fbdb..cf00c6a3489 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 2636e3200d8..52299e3285c 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 00000000000..0bff9032b54 --- /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 f3c79deb814..e37a5d003e3 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 6dd4c20315b..2b3eccc8f7e 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 d39d52aa7c9..c4d23e34817 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 545ae621f8b..a5d2b2e0829 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 9754c178604..89342a21728 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 25878e67a8e..6340f1385c8 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 a5287c8890f..a13f6512a9d 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 d9fe57adcc5..8e36389acee 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 58f5b311531..1120ffeecdb 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