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  }