sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/services/resourceskus/sku.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 resourceskus 18 19 import ( 20 "strconv" 21 "strings" 22 23 "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5" 24 "github.com/pkg/errors" 25 "k8s.io/utils/ptr" 26 ) 27 28 // SKU is a thin layer over the Azure resource SKU API to better introspect capabilities. 29 type SKU armcompute.ResourceSKU 30 31 // ResourceType models available resource types as a set of known string constants. 32 type ResourceType string 33 34 const ( 35 // VirtualMachines is a convenience constant to filter resource SKUs to only include VMs. 36 VirtualMachines ResourceType = "virtualMachines" 37 // Disks is a convenience constant to filter resource SKUs to only include disks. 38 Disks ResourceType = "disks" 39 // AvailabilitySets is a convenience constant to filter resource SKUs to only include availability sets. 40 AvailabilitySets ResourceType = "availabilitySets" 41 ) 42 43 // Supported models an enum of possible boolean values for resource support in the Azure API. 44 type Supported string 45 46 const ( 47 // CapabilitySupported is the value returned by this API from Azure when the capability is supported. 48 CapabilitySupported Supported = "True" 49 // CapabilityUnsupported is the value returned by this API from Azure when the capability is unsupported. 50 CapabilityUnsupported Supported = "False" 51 ) 52 53 const ( 54 // EphemeralOSDisk identifies the capability for ephemeral os support. 55 EphemeralOSDisk = "EphemeralOSDiskSupported" 56 // AcceleratedNetworking identifies the capability for accelerated networking support. 57 AcceleratedNetworking = "AcceleratedNetworkingEnabled" 58 // VCPUs identifies the capability for the number of vCPUS. 59 VCPUs = "vCPUs" 60 // MemoryGB identifies the capability for memory Size. 61 MemoryGB = "MemoryGB" 62 // MinimumVCPUS is the minimum vCPUS allowed. 63 MinimumVCPUS = 2 64 // MinimumMemory is the minimum memory allowed. 65 MinimumMemory = 2 66 // EncryptionAtHost identifies the capability for encryption at host. 67 EncryptionAtHost = "EncryptionAtHostSupported" 68 // MaximumPlatformFaultDomainCount identifies the maximum fault domain count for an availability set in a region. 69 MaximumPlatformFaultDomainCount = "MaximumPlatformFaultDomainCount" 70 // UltraSSDAvailable identifies the capability for the support of UltraSSD data disks. 71 UltraSSDAvailable = "UltraSSDAvailable" 72 // TrustedLaunchDisabled identifies the absence of the trusted launch capability. 73 TrustedLaunchDisabled = "TrustedLaunchDisabled" 74 // ConfidentialComputingType identifies the capability for confidentical computing. 75 ConfidentialComputingType = "ConfidentialComputingType" 76 // CPUArchitectureType identifies the capability for cpu architecture. 77 CPUArchitectureType = "CpuArchitectureType" 78 ) 79 80 // HasCapability return true for a capability which can be either 81 // supported or not. Examples include "EphemeralOSDiskSupported", 82 // "UltraSSDAvavailable" "EncryptionAtHostSupported", 83 // "AcceleratedNetworkingEnabled", and "RdmaEnabled". 84 func (s SKU) HasCapability(name string) bool { 85 if s.Capabilities != nil { 86 for _, capability := range s.Capabilities { 87 if capability.Name != nil && *capability.Name == name { 88 if capability.Value != nil && strings.EqualFold(*capability.Value, string(CapabilitySupported)) { 89 return true 90 } 91 } 92 } 93 } 94 return false 95 } 96 97 // HasCapabilityWithCapacity returns true when the provided resource 98 // exposes a numeric capability and the maximum value exposed by that 99 // capability exceeds the value requested by the user. Examples include 100 // "MaxResourceVolumeMB", "OSVhdSizeMB", "vCPUs", 101 // "MemoryGB","MaxDataDiskCount", "CombinedTempDiskAndCachedIOPS", 102 // "CombinedTempDiskAndCachedReadBytesPerSecond", 103 // "CombinedTempDiskAndCachedWriteBytesPerSecond", "UncachedDiskIOPS", 104 // and "UncachedDiskBytesPerSecond". 105 func (s SKU) HasCapabilityWithCapacity(name string, value int64) (bool, error) { 106 if s.Capabilities == nil { 107 return false, nil 108 } 109 110 for _, capability := range s.Capabilities { 111 if capability.Name == nil || *capability.Name != name || capability.Value == nil { 112 continue 113 } 114 115 intVal, err := strconv.ParseInt(*capability.Value, 10, 64) 116 if err != nil { 117 return false, errors.Wrapf(err, "failed to parse string '%s' as int64", *capability.Value) 118 } 119 120 if intVal >= value { 121 return true, nil 122 } 123 } 124 125 return false, nil 126 } 127 128 // GetCapability gets the value assigned to the given capability. 129 // Eg. MaximumPlatformFaultDomainCount -> "3" will return "3" for the capability "MaximumPlatformFaultDomainCount". 130 func (s SKU) GetCapability(name string) (string, bool) { 131 if s.Capabilities != nil { 132 for _, capability := range s.Capabilities { 133 if capability.Name != nil && *capability.Name == name { 134 return *capability.Value, true 135 } 136 } 137 } 138 return "", false 139 } 140 141 // HasLocationCapability returns true if the provided resource supports the location capability. 142 func (s SKU) HasLocationCapability(capabilityName, location, zone string) bool { 143 if s.LocationInfo == nil { 144 return false 145 } 146 147 for _, info := range s.LocationInfo { 148 if info.Location == nil || *info.Location != location || info.ZoneDetails == nil { 149 continue 150 } 151 152 for _, zoneDetail := range info.ZoneDetails { 153 if zoneDetail.Capabilities == nil { 154 continue 155 } 156 157 for _, capability := range zoneDetail.Capabilities { 158 if capability.Name != nil && *capability.Name == capabilityName { 159 for _, name := range zoneDetail.Name { 160 if ptr.Deref(name, "") == zone { 161 return true 162 } 163 } 164 165 return false 166 } 167 } 168 } 169 } 170 return false 171 }