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  }