sigs.k8s.io/cluster-api-provider-azure@v1.14.3/api/v1beta1/tags.go (about) 1 /* 2 Copyright 2021 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 v1beta1 18 19 import ( 20 "fmt" 21 "reflect" 22 ) 23 24 // Tags defines a map of tags. 25 type Tags map[string]string 26 27 // Equals returns true if the tags are equal. 28 func (t Tags) Equals(other Tags) bool { 29 return reflect.DeepEqual(t, other) 30 } 31 32 // HasMatchingSpecVersionHash returns true if the resource has been tagged with a matching resource spec hash value. 33 func (t Tags) HasMatchingSpecVersionHash(hash string) bool { 34 value, ok := t[SpecVersionHashTagKey()] 35 return ok && value == hash 36 } 37 38 // HasOwned returns true if the tags contains a tag that marks the resource as owned by the cluster from the perspective of this management tooling. 39 func (t Tags) HasOwned(cluster string) bool { 40 value, ok := t[ClusterTagKey(cluster)] 41 return ok && ResourceLifecycle(value) == ResourceLifecycleOwned 42 } 43 44 // HasAzureCloudProviderOwned returns true if the tags contains a tag that marks the resource as owned by the cluster from the perspective of the in-tree cloud provider. 45 func (t Tags) HasAzureCloudProviderOwned(cluster string) bool { 46 value, ok := t[ClusterAzureCloudProviderTagKey(cluster)] 47 return ok && ResourceLifecycle(value) == ResourceLifecycleOwned 48 } 49 50 // GetRole returns the Cluster API role for the tagged resource. 51 func (t Tags) GetRole() string { 52 return t[NameAzureClusterAPIRole] 53 } 54 55 // Difference returns the difference between this map of tags and the other map of tags. 56 // Items are considered equals if key and value are equals. 57 func (t Tags) Difference(other Tags) Tags { 58 res := make(Tags, len(t)) 59 60 for key, value := range t { 61 if otherValue, ok := other[key]; ok && value == otherValue { 62 continue 63 } 64 res[key] = value 65 } 66 67 return res 68 } 69 70 // Merge merges in tags from other. If a tag already exists, it is replaced by the tag in other. 71 func (t Tags) Merge(other Tags) { 72 for k, v := range other { 73 t[k] = v 74 } 75 } 76 77 // AddSpecVersionHashTag adds a spec version hash to the Azure resource tags to determine quickly if state has changed. 78 func (t Tags) AddSpecVersionHashTag(hash string) Tags { 79 t[SpecVersionHashTagKey()] = hash 80 return t 81 } 82 83 // ResourceLifecycle configures the lifecycle of a resource. 84 type ResourceLifecycle string 85 86 const ( 87 // ResourceLifecycleOwned is the value we use when tagging resources to indicate 88 // that the resource is considered owned and managed by the cluster, 89 // and in particular that the lifecycle is tied to the lifecycle of the cluster. 90 ResourceLifecycleOwned = ResourceLifecycle("owned") 91 92 // ResourceLifecycleShared is the value we use when tagging resources to indicate 93 // that the resource is shared between multiple clusters, and should not be destroyed 94 // if the cluster is destroyed. 95 ResourceLifecycleShared = ResourceLifecycle("shared") 96 97 // NameKubernetesAzureCloudProviderPrefix is the tag name used by the cloud provider to logically 98 // separate independent cluster resources. We use it to identify which resources we expect 99 // to be permissive about state changes. 100 // logically independent clusters running in the same AZ. 101 // The tag key = NameKubernetesAzureCloudProviderPrefix + clusterID. 102 // The tag value is an ownership value. 103 NameKubernetesAzureCloudProviderPrefix = "kubernetes.io_cluster_" 104 105 // NameAzureProviderPrefix is the tag prefix we use to differentiate 106 // cluster-api-provider-azure owned components from other tooling that 107 // uses NameKubernetesClusterPrefix. 108 NameAzureProviderPrefix = "sigs.k8s.io_cluster-api-provider-azure_" 109 110 // NameAzureProviderOwned is the tag name we use to differentiate 111 // cluster-api-provider-azure owned components from other tooling that 112 // uses NameKubernetesClusterPrefix. 113 NameAzureProviderOwned = NameAzureProviderPrefix + "cluster_" 114 115 // NameAzureClusterAPIRole is the tag name we use to mark roles for resources 116 // dedicated to this cluster api provider implementation. 117 NameAzureClusterAPIRole = NameAzureProviderPrefix + "role" 118 119 // APIServerRole describes the value for the apiserver role. 120 APIServerRole = "apiserver" 121 122 // NodeOutboundRole describes the value for the node outbound LB role. 123 NodeOutboundRole = "nodeOutbound" 124 125 // ControlPlaneOutboundRole describes the value for the control plane outbound LB role. 126 ControlPlaneOutboundRole = "controlPlaneOutbound" 127 128 // BastionRole describes the value for the bastion role. 129 BastionRole = Bastion 130 131 // CommonRole describes the value for the common role. 132 CommonRole = "common" 133 134 // VMTagsLastAppliedAnnotation is the key for the machine object annotation 135 // which tracks the AdditionalTags in the Machine Provider Config. 136 // See https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ 137 // for annotation formatting rules. 138 // Deprecated: use azure.VMTagsLastAppliedAnnotation instead. This constant will be removed in v1beta2. 139 VMTagsLastAppliedAnnotation = "sigs.k8s.io/cluster-api-provider-azure-last-applied-tags-vm" 140 141 // RGTagsLastAppliedAnnotation is the key for the Azure Cluster object annotation 142 // which tracks the AdditionalTags for Resource Group which is part in the Azure Cluster. 143 // See https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ 144 // for annotation formatting rules. 145 // Deprecated: use azure.RGTagsLastAppliedAnnotation instead. This constant will be removed in v1beta2. 146 RGTagsLastAppliedAnnotation = "sigs.k8s.io/cluster-api-provider-azure-last-applied-tags-rg" 147 ) 148 149 // SpecVersionHashTagKey is the key for the spec version hash used to enable quick spec difference comparison. 150 func SpecVersionHashTagKey() string { 151 return fmt.Sprintf("%s%s", NameAzureProviderPrefix, "spec-version-hash") 152 } 153 154 // ClusterTagKey generates the key for resources associated with a cluster. 155 func ClusterTagKey(name string) string { 156 return fmt.Sprintf("%s%s", NameAzureProviderOwned, name) 157 } 158 159 // ClusterAzureCloudProviderTagKey generates the key for resources associated a cluster's Azure cloud provider. 160 func ClusterAzureCloudProviderTagKey(name string) string { 161 return fmt.Sprintf("%s%s", NameKubernetesAzureCloudProviderPrefix, name) 162 } 163 164 // BuildParams is used to build tags around an azure resource. 165 type BuildParams struct { 166 // Lifecycle determines the resource lifecycle. 167 Lifecycle ResourceLifecycle 168 169 // ClusterName is the cluster associated with the resource. 170 ClusterName string 171 172 // ResourceID is the unique identifier of the resource to be tagged. 173 ResourceID string 174 175 // Name is the name of the resource, it's applied as the tag "Name" on Azure. 176 // +optional 177 Name *string 178 179 // Role is the role associated to the resource. 180 // +optional 181 Role *string 182 183 // Any additional tags to be added to the resource. 184 // +optional 185 Additional Tags 186 } 187 188 // Build builds tags including the cluster tag and returns them in map form. 189 func Build(params BuildParams) Tags { 190 tags := make(Tags) 191 for k, v := range params.Additional { 192 tags[k] = v 193 } 194 195 tags[ClusterTagKey(params.ClusterName)] = string(params.Lifecycle) 196 if params.Role != nil { 197 tags[NameAzureClusterAPIRole] = *params.Role 198 } 199 200 if params.Name != nil { 201 tags["Name"] = *params.Name 202 } 203 204 return tags 205 }