зеркало из
1
0
Форкнуть 0

Stop hardcoding properties in newConvertToARMFunctionBuilder (#3685)

This fixes #3549.

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.

This also fixes an issue with the configuration where hierarchical
configurations didn't propagate the checks for usage.
This commit is contained in:
Matthew Christopher 2024-01-11 12:08:39 -08:00 коммит произвёл GitHub
Родитель 75aa751792
Коммит 43a5635a9c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
38 изменённых файлов: 492 добавлений и 285 удалений

Просмотреть файл

@ -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"`

Просмотреть файл

@ -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"`

Просмотреть файл

@ -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"`

Просмотреть файл

@ -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"`

Просмотреть файл

@ -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 <major.minor.patch> (e.g. 1.20.13) and <major.minor> (e.g. 1.20) are supported.
// When <major.minor> 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"`

Просмотреть файл

@ -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 <major.minor.patch> (e.g. 1.20.13) and <major.minor> (e.g. 1.20) are supported.
// When <major.minor> 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"`

Просмотреть файл

@ -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"`

Просмотреть файл

@ -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"`

Просмотреть файл

@ -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 <major.minor.patch> and <major.minor> are supported. When <major.minor> 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"`

Просмотреть файл

@ -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 <major.minor.patch> and <major.minor> are supported. When <major.minor> 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"`

Просмотреть файл

@ -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"`

Просмотреть файл

@ -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"`

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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 <major.minor.patch> (e.g. 1.20.13) and <major.minor> (e.g. 1.20) are supported.
// When <major.minor> 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"`

Просмотреть файл

@ -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 <major.minor.patch> (e.g. 1.20.13) and <major.minor> (e.g. 1.20) are supported.
// When <major.minor> 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"`

Просмотреть файл

@ -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"`

Просмотреть файл

@ -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"`

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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,

Просмотреть файл

@ -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,

Просмотреть файл

@ -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,
},
}

Просмотреть файл

@ -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")

Просмотреть файл

@ -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"
)

Просмотреть файл

@ -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),

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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 <property>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

Просмотреть файл

@ -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

Просмотреть файл

@ -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 <property>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

Просмотреть файл

@ -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](

Просмотреть файл

@ -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()

Просмотреть файл

@ -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

Просмотреть файл

@ -147,6 +147,24 @@ func (pc *PropertyConfiguration) UnmarshalYAML(value *yaml.Node) error {
continue
}
// $payloadType: <string>
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)

Просмотреть файл

@ -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