diff --git a/.golangci.yml b/.golangci.yml index 21d3b0b2c6c..1469f023cbe 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -18,6 +18,7 @@ linters: - durationcheck # multiplying two durations - errcheck # unchecked errors - errchkjson # invalid types passed to json encoder + - exhaustruct # checks if all structure fields are initialized - gci # ensures imports are organized - ginkgolinter # ginkgo and gomega - goconst # strings that can be replaced by constants @@ -54,6 +55,10 @@ linters: - whitespace # unnecessary newlines linters-settings: + exhaustruct: + include: + # Hub ASO agent pools should be fully defined to prevent unnecessary updates + - '.*storage\..*AgentPoolProfile$' gosec: excludes: - G307 # Deferring unsafe method "Close" on type "\*os.File" @@ -185,9 +190,9 @@ issues: - path: (^test/|_test.go$) linters: - dogsled + - exhaustruct - goconst - godot - - prealloc - path: (^test/|_test.go$) text: exported (.+) should have comment( \(or a comment on this block\))? or be unexported - source: \"github.com/onsi/(ginkgo/v2|gomega)\" diff --git a/azure/converters/managedagentpool.go b/azure/converters/managedagentpool.go index 380c8cf3085..cc29b7f29bf 100644 --- a/azure/converters/managedagentpool.go +++ b/azure/converters/managedagentpool.go @@ -17,6 +17,12 @@ limitations under the License. package converters import ( + // NOTE: when the hub API version is updated, verify the + // ManagedClusterAgentPoolProfile below has every field defined. If a field + // isn't defined, the agent pool will be created with a zero/null value, and + // then updated to the user-defined value. If the field is immutable, this + // update will fail. The linter should catch if there are missing fields, + // but verify that check is actually working. asocontainerservicev1hub "github.com/Azure/azure-service-operator/v2/api/containerservice/v1api20240901/storage" "k8s.io/utils/ptr" ) @@ -25,37 +31,50 @@ import ( func AgentPoolToManagedClusterAgentPoolProfile(pool *asocontainerservicev1hub.ManagedClustersAgentPool) asocontainerservicev1hub.ManagedClusterAgentPoolProfile { properties := pool.Spec agentPool := asocontainerservicev1hub.ManagedClusterAgentPoolProfile{ - Name: ptr.To(pool.AzureName()), - VmSize: properties.VmSize, - OsType: properties.OsType, - OsDiskSizeGB: properties.OsDiskSizeGB, - Count: properties.Count, - Type: properties.Type, - OrchestratorVersion: properties.OrchestratorVersion, - VnetSubnetReference: properties.VnetSubnetReference, - Mode: properties.Mode, - EnableAutoScaling: properties.EnableAutoScaling, - MaxCount: properties.MaxCount, - MinCount: properties.MinCount, - NodeTaints: properties.NodeTaints, - AvailabilityZones: properties.AvailabilityZones, - MaxPods: properties.MaxPods, - OsDiskType: properties.OsDiskType, - NodeLabels: properties.NodeLabels, - EnableUltraSSD: properties.EnableUltraSSD, - EnableNodePublicIP: properties.EnableNodePublicIP, - NodePublicIPPrefixReference: properties.NodePublicIPPrefixReference, - ScaleSetPriority: properties.ScaleSetPriority, - ScaleDownMode: properties.ScaleDownMode, - SpotMaxPrice: properties.SpotMaxPrice, - Tags: properties.Tags, - KubeletDiskType: properties.KubeletDiskType, - LinuxOSConfig: properties.LinuxOSConfig, - EnableFIPS: properties.EnableFIPS, - EnableEncryptionAtHost: properties.EnableEncryptionAtHost, - } - if properties.KubeletConfig != nil { - agentPool.KubeletConfig = properties.KubeletConfig + AvailabilityZones: properties.AvailabilityZones, + CapacityReservationGroupReference: properties.CapacityReservationGroupReference, + Count: properties.Count, + CreationData: properties.CreationData, + EnableAutoScaling: properties.EnableAutoScaling, + EnableEncryptionAtHost: properties.EnableEncryptionAtHost, + EnableFIPS: properties.EnableFIPS, + EnableNodePublicIP: properties.EnableNodePublicIP, + EnableUltraSSD: properties.EnableUltraSSD, + GpuInstanceProfile: properties.GpuInstanceProfile, + HostGroupReference: properties.HostGroupReference, + KubeletConfig: properties.KubeletConfig, + KubeletDiskType: properties.KubeletDiskType, + LinuxOSConfig: properties.LinuxOSConfig, + MaxCount: properties.MaxCount, + MaxPods: properties.MaxPods, + MinCount: properties.MinCount, + Mode: properties.Mode, + Name: ptr.To(pool.AzureName()), + NetworkProfile: properties.NetworkProfile, + NodeLabels: properties.NodeLabels, + NodePublicIPPrefixReference: properties.NodePublicIPPrefixReference, + NodeTaints: properties.NodeTaints, + OrchestratorVersion: properties.OrchestratorVersion, + OsDiskSizeGB: properties.OsDiskSizeGB, + OsDiskType: properties.OsDiskType, + OsSKU: properties.OsSKU, + OsType: properties.OsType, + PodSubnetReference: properties.PodSubnetReference, + PowerState: properties.PowerState, + PropertyBag: properties.PropertyBag, + ProximityPlacementGroupReference: properties.ProximityPlacementGroupReference, + ScaleDownMode: properties.ScaleDownMode, + ScaleSetEvictionPolicy: properties.ScaleSetEvictionPolicy, + ScaleSetPriority: properties.ScaleSetPriority, + SecurityProfile: properties.SecurityProfile, + SpotMaxPrice: properties.SpotMaxPrice, + Tags: properties.Tags, + Type: properties.Type, + UpgradeSettings: properties.UpgradeSettings, + VmSize: properties.VmSize, + VnetSubnetReference: properties.VnetSubnetReference, + WindowsProfile: properties.WindowsProfile, + WorkloadRuntime: properties.WorkloadRuntime, } return agentPool } diff --git a/pkg/mutators/azureasomanagedcontrolplane.go b/pkg/mutators/azureasomanagedcontrolplane.go index d0ee274428f..e208e9b888c 100644 --- a/pkg/mutators/azureasomanagedcontrolplane.go +++ b/pkg/mutators/azureasomanagedcontrolplane.go @@ -23,6 +23,12 @@ import ( "strings" asocontainerservicev1 "github.com/Azure/azure-service-operator/v2/api/containerservice/v1api20231001" + // NOTE: when the hub API version is updated, verify the + // ManagedClusterAgentPoolProfile below has every field defined. If a field + // isn't defined, the agent pool will be created with a zero/null value, and + // then updated to the user-defined value. If the field is immutable, this + // update will fail. The linter should catch if there are missing fields, + // but verify that check is actually working. asocontainerservicev1hub "github.com/Azure/azure-service-operator/v2/api/containerservice/v1api20240901/storage" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" @@ -350,12 +356,14 @@ func setAgentPoolProfilesFromAgentPools(managedCluster conversion.Convertible, a ScaleDownMode: hubPool.Spec.ScaleDownMode, ScaleSetEvictionPolicy: hubPool.Spec.ScaleSetEvictionPolicy, ScaleSetPriority: hubPool.Spec.ScaleSetPriority, + SecurityProfile: hubPool.Spec.SecurityProfile, SpotMaxPrice: hubPool.Spec.SpotMaxPrice, Tags: hubPool.Spec.Tags, Type: hubPool.Spec.Type, UpgradeSettings: hubPool.Spec.UpgradeSettings, VmSize: hubPool.Spec.VmSize, VnetSubnetReference: hubPool.Spec.VnetSubnetReference, + WindowsProfile: hubPool.Spec.WindowsProfile, WorkloadRuntime: hubPool.Spec.WorkloadRuntime, }