sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/types.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package azure 18 19 import ( 20 "reflect" 21 "strings" 22 23 "github.com/google/go-cmp/cmp" 24 infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1" 25 azureutil "sigs.k8s.io/cluster-api-provider-azure/util/azure" 26 ) 27 28 // RoleAssignmentSpec defines the specification for a Role Assignment. 29 type RoleAssignmentSpec struct { 30 MachineName string 31 Name string 32 ResourceType string 33 } 34 35 // ResourceType defines the type azure resource being reconciled. 36 // Eg. Virtual Machine, Virtual Machine Scale Sets. 37 type ResourceType string 38 39 const ( 40 41 // VirtualMachine ... 42 VirtualMachine = "VirtualMachine" 43 44 // VirtualMachineScaleSet ... 45 VirtualMachineScaleSet = "VirtualMachineScaleSet" 46 ) 47 48 // ScaleSetSpec defines the specification for a Scale Set. 49 type ScaleSetSpec struct { 50 Name string 51 Size string 52 Capacity int64 53 SSHKeyData string 54 OSDisk infrav1.OSDisk 55 DataDisks []infrav1.DataDisk 56 SubnetName string 57 VNetName string 58 VNetResourceGroup string 59 PublicLBName string 60 PublicLBAddressPoolName string 61 AcceleratedNetworking *bool 62 TerminateNotificationTimeout *int 63 Identity infrav1.VMIdentity 64 UserAssignedIdentities []infrav1.UserAssignedIdentity 65 SecurityProfile *infrav1.SecurityProfile 66 SpotVMOptions *infrav1.SpotVMOptions 67 AdditionalCapabilities *infrav1.AdditionalCapabilities 68 DiagnosticsProfile *infrav1.Diagnostics 69 FailureDomains []string 70 VMExtensions []infrav1.VMExtension 71 NetworkInterfaces []infrav1.NetworkInterface 72 IPv6Enabled bool 73 OrchestrationMode infrav1.OrchestrationModeType 74 } 75 76 // TagsSpec defines the specification for a set of tags. 77 type TagsSpec struct { 78 Scope string 79 Tags infrav1.Tags 80 // Annotation is the key which stores the last applied tags as value in JSON format. 81 // The last applied tags are used to find out which tags are being managed by CAPZ 82 // and if any has to be deleted by comparing it with the new desired tags 83 Annotation string 84 } 85 86 // ExtensionSpec defines the specification for a VM or VMSS extension. 87 type ExtensionSpec struct { 88 Name string 89 VMName string 90 Publisher string 91 Version string 92 Settings map[string]string 93 ProtectedSettings map[string]string 94 } 95 96 type ( 97 // VMSSVM defines a VM in a virtual machine scale set. 98 VMSSVM struct { 99 ID string `json:"id,omitempty"` 100 InstanceID string `json:"instanceID,omitempty"` 101 Image infrav1.Image `json:"image,omitempty"` 102 Name string `json:"name,omitempty"` 103 AvailabilityZone string `json:"availabilityZone,omitempty"` 104 State infrav1.ProvisioningState `json:"vmState,omitempty"` 105 BootstrappingState infrav1.ProvisioningState `json:"bootstrappingState,omitempty"` 106 OrchestrationMode infrav1.OrchestrationModeType `json:"orchestrationMode,omitempty"` 107 } 108 109 // VMSS defines a virtual machine scale set. 110 VMSS struct { 111 ID string `json:"id,omitempty"` 112 Name string `json:"name,omitempty"` 113 Sku string `json:"sku,omitempty"` 114 Capacity int64 `json:"capacity,omitempty"` 115 Zones []string `json:"zones,omitempty"` 116 Image infrav1.Image `json:"image,omitempty"` 117 State infrav1.ProvisioningState `json:"vmState,omitempty"` 118 Identity infrav1.VMIdentity `json:"identity,omitempty"` 119 Tags infrav1.Tags `json:"tags,omitempty"` 120 Instances []VMSSVM `json:"instances,omitempty"` 121 } 122 ) 123 124 // HasModelChanges returns true if the spec fields which will mutate the Azure VMSS model are different. 125 func (vmss VMSS) HasModelChanges(other VMSS) bool { 126 equal := cmp.Equal(vmss.Image, other.Image) && 127 cmp.Equal(vmss.Identity, other.Identity) && 128 cmp.Equal(vmss.Zones, other.Zones) && 129 cmp.Equal(vmss.Tags, other.Tags) && 130 cmp.Equal(vmss.Sku, other.Sku) 131 return !equal 132 } 133 134 // InstancesByProviderID returns VMSSVMs by ID. 135 func (vmss VMSS) InstancesByProviderID(mode infrav1.OrchestrationModeType) map[string]VMSSVM { 136 instancesByProviderID := make(map[string]VMSSVM, len(vmss.Instances)) 137 for _, instance := range vmss.Instances { 138 instance.OrchestrationMode = mode 139 instancesByProviderID[instance.ProviderID()] = instance 140 } 141 142 return instancesByProviderID 143 } 144 145 // ProviderID returns the K8s provider ID for the VMSS instance. 146 func (vm VMSSVM) ProviderID() string { 147 if vm.OrchestrationMode == infrav1.FlexibleOrchestrationMode { 148 // ProviderID for Flex scaleset VMs looks like this: 149 // azure:///subscriptions/<sub_id>/resourceGroups/my-cluster/providers/Microsoft.Compute/virtualMachines/my-cluster_1234abcd 150 splitOnSlash := strings.Split(vm.ID, "/") 151 elems := splitOnSlash[:len(splitOnSlash)-4] 152 elems = append(elems, splitOnSlash[len(splitOnSlash)-2:]...) 153 return azureutil.ProviderIDPrefix + strings.Join(elems, "/") 154 } 155 // ProviderID for Uniform scaleset VMs looks like this: 156 // azure:///subscriptions/<sub_id>/resourceGroups/my-cluster/providers/Microsoft.Compute/virtualMachineScaleSets/my-cluster-mp-0/virtualMachines/0 157 return azureutil.ProviderIDPrefix + vm.ID 158 } 159 160 // HasLatestModelAppliedToAll returns true if all VMSS instance have the latest model applied. 161 func (vmss VMSS) HasLatestModelAppliedToAll() bool { 162 for _, instance := range vmss.Instances { 163 if !vmss.HasLatestModelApplied(instance) { 164 return false 165 } 166 } 167 168 return true 169 } 170 171 // HasEnoughLatestModelOrNotMixedModel returns true if VMSS instance have the latest model applied to all or equal to the capacity. 172 func (vmss VMSS) HasEnoughLatestModelOrNotMixedModel() bool { 173 if vmss.HasLatestModelAppliedToAll() { 174 return true 175 } 176 177 counter := int64(0) 178 for _, instance := range vmss.Instances { 179 if vmss.HasLatestModelApplied(instance) { 180 counter++ 181 } 182 } 183 184 return counter == vmss.Capacity 185 } 186 187 // HasLatestModelApplied returns true if the VMSS instance matches the VMSS image reference. 188 func (vmss VMSS) HasLatestModelApplied(vm VMSSVM) bool { 189 // if the images match, then the VM is of the same model 190 return reflect.DeepEqual(vm.Image, vmss.Image) 191 }