sigs.k8s.io/cluster-api-provider-azure@v1.17.0/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.Sku, other.Sku) 130 return !equal 131 } 132 133 // InstancesByProviderID returns VMSSVMs by ID. 134 func (vmss VMSS) InstancesByProviderID(mode infrav1.OrchestrationModeType) map[string]VMSSVM { 135 instancesByProviderID := make(map[string]VMSSVM, len(vmss.Instances)) 136 for _, instance := range vmss.Instances { 137 instance.OrchestrationMode = mode 138 instancesByProviderID[instance.ProviderID()] = instance 139 } 140 141 return instancesByProviderID 142 } 143 144 // ProviderID returns the K8s provider ID for the VMSS instance. 145 func (vm VMSSVM) ProviderID() string { 146 if vm.OrchestrationMode == infrav1.FlexibleOrchestrationMode { 147 // ProviderID for Flex scaleset VMs looks like this: 148 // azure:///subscriptions/<sub_id>/resourceGroups/my-cluster/providers/Microsoft.Compute/virtualMachines/my-cluster_1234abcd 149 splitOnSlash := strings.Split(vm.ID, "/") 150 elems := splitOnSlash[:len(splitOnSlash)-4] 151 elems = append(elems, splitOnSlash[len(splitOnSlash)-2:]...) 152 return azureutil.ProviderIDPrefix + strings.Join(elems, "/") 153 } 154 // ProviderID for Uniform scaleset VMs looks like this: 155 // azure:///subscriptions/<sub_id>/resourceGroups/my-cluster/providers/Microsoft.Compute/virtualMachineScaleSets/my-cluster-mp-0/virtualMachines/0 156 return azureutil.ProviderIDPrefix + vm.ID 157 } 158 159 // HasLatestModelAppliedToAll returns true if all VMSS instance have the latest model applied. 160 func (vmss VMSS) HasLatestModelAppliedToAll() bool { 161 for _, instance := range vmss.Instances { 162 if !vmss.HasLatestModelApplied(instance) { 163 return false 164 } 165 } 166 167 return true 168 } 169 170 // HasEnoughLatestModelOrNotMixedModel returns true if VMSS instance have the latest model applied to all or equal to the capacity. 171 func (vmss VMSS) HasEnoughLatestModelOrNotMixedModel() bool { 172 if vmss.HasLatestModelAppliedToAll() { 173 return true 174 } 175 176 counter := int64(0) 177 for _, instance := range vmss.Instances { 178 if vmss.HasLatestModelApplied(instance) { 179 counter++ 180 } 181 } 182 183 return counter == vmss.Capacity 184 } 185 186 // HasLatestModelApplied returns true if the VMSS instance matches the VMSS image reference. 187 func (vmss VMSS) HasLatestModelApplied(vm VMSSVM) bool { 188 // if the images match, then the VM is of the same model 189 return reflect.DeepEqual(vm.Image, vmss.Image) 190 }