sigs.k8s.io/cluster-api-provider-aws@v1.5.5/api/v1alpha4/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 v1alpha4
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"github.com/google/go-cmp/cmp"
    23  	"k8s.io/apimachinery/pkg/types"
    24  
    25  	clusterv1alpha4 "sigs.k8s.io/cluster-api/api/v1alpha4"
    26  )
    27  
    28  // Tags defines a map of tags.
    29  type Tags map[string]string
    30  
    31  // Equals returns true if the tags are equal.
    32  // This func is deprecated and should not be used.
    33  func (t Tags) Equals(other Tags) bool {
    34  	return cmp.Equal(t, other)
    35  }
    36  
    37  // 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.
    38  func (t Tags) HasOwned(cluster string) bool {
    39  	value, ok := t[ClusterTagKey(cluster)]
    40  	return ok && ResourceLifecycle(value) == ResourceLifecycleOwned
    41  }
    42  
    43  // HasAWSCloudProviderOwned 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.
    44  func (t Tags) HasAWSCloudProviderOwned(cluster string) bool {
    45  	value, ok := t[ClusterAWSCloudProviderTagKey(cluster)]
    46  	return ok && ResourceLifecycle(value) == ResourceLifecycleOwned
    47  }
    48  
    49  // GetRole returns the Cluster API role for the tagged resource.
    50  func (t Tags) GetRole() string {
    51  	return t[NameAWSClusterAPIRole]
    52  }
    53  
    54  // Difference returns the difference between this map of tags and the other map of tags.
    55  // Items are considered equals if key and value are equals.
    56  func (t Tags) Difference(other Tags) Tags {
    57  	res := make(Tags, len(t))
    58  
    59  	for key, value := range t {
    60  		if otherValue, ok := other[key]; ok && value == otherValue {
    61  			continue
    62  		}
    63  		res[key] = value
    64  	}
    65  
    66  	return res
    67  }
    68  
    69  // Merge merges in tags from other. If a tag already exists, it is replaced by the tag in other.
    70  func (t Tags) Merge(other Tags) {
    71  	for k, v := range other {
    72  		t[k] = v
    73  	}
    74  }
    75  
    76  // ResourceLifecycle configures the lifecycle of a resource.
    77  type ResourceLifecycle string
    78  
    79  const (
    80  	// ResourceLifecycleOwned is the value we use when tagging resources to indicate
    81  	// that the resource is considered owned and managed by the cluster,
    82  	// and in particular that the lifecycle is tied to the lifecycle of the cluster.
    83  	ResourceLifecycleOwned = ResourceLifecycle("owned")
    84  
    85  	// ResourceLifecycleShared is the value we use when tagging resources to indicate
    86  	// that the resource is shared between multiple clusters, and should not be destroyed
    87  	// if the cluster is destroyed.
    88  	ResourceLifecycleShared = ResourceLifecycle("shared")
    89  
    90  	// NameKubernetesAWSCloudProviderPrefix is the tag name used by the cloud provider to logically
    91  	// separate independent cluster resources. We use it to identify which resources we expect
    92  	// to be permissive about state changes.
    93  	// logically independent clusters running in the same AZ.
    94  	// The tag key = NameKubernetesAWSCloudProviderPrefix + clusterID
    95  	// The tag value is an ownership value.
    96  	NameKubernetesAWSCloudProviderPrefix = "kubernetes.io/cluster/"
    97  
    98  	// NameAWSProviderPrefix is the tag prefix we use to differentiate
    99  	// cluster-api-provider-aws owned components from other tooling that
   100  	// uses NameKubernetesClusterPrefix.
   101  	NameAWSProviderPrefix = "sigs.k8s.io/cluster-api-provider-aws/"
   102  
   103  	// NameAWSProviderOwned is the tag name we use to differentiate
   104  	// cluster-api-provider-aws owned components from other tooling that
   105  	// uses NameKubernetesClusterPrefix.
   106  	NameAWSProviderOwned = NameAWSProviderPrefix + "cluster/"
   107  
   108  	// NameAWSClusterAPIRole is the tag name we use to mark roles for resources
   109  	// dedicated to this cluster api provider implementation.
   110  	NameAWSClusterAPIRole = NameAWSProviderPrefix + "role"
   111  
   112  	// NameAWSSubnetAssociation is the tag name we use to mark association for resources
   113  	// dedicated to this cluster api provider implementation.
   114  	NameAWSSubnetAssociation = NameAWSProviderPrefix + "association"
   115  
   116  	// SecondarySubnetTagValue is the secondary subnet tag constant value.
   117  	SecondarySubnetTagValue = "secondary"
   118  
   119  	// APIServerRoleTagValue describes the value for the apiserver role.
   120  	APIServerRoleTagValue = "apiserver"
   121  
   122  	// BastionRoleTagValue describes the value for the bastion role.
   123  	BastionRoleTagValue = "bastion"
   124  
   125  	// CommonRoleTagValue describes the value for the common role.
   126  	CommonRoleTagValue = "common"
   127  
   128  	// PublicRoleTagValue describes the value for the public role.
   129  	PublicRoleTagValue = "public"
   130  
   131  	// PrivateRoleTagValue describes the value for the private role.
   132  	PrivateRoleTagValue = "private"
   133  
   134  	// MachineNameTagKey is the key for machine name.
   135  	MachineNameTagKey = "MachineName"
   136  )
   137  
   138  // ClusterTagKey generates the key for resources associated with a cluster.
   139  func ClusterTagKey(name string) string {
   140  	return fmt.Sprintf("%s%s", NameAWSProviderOwned, name)
   141  }
   142  
   143  // ClusterAWSCloudProviderTagKey generates the key for resources associated a cluster's AWS cloud provider.
   144  func ClusterAWSCloudProviderTagKey(name string) string {
   145  	return fmt.Sprintf("%s%s", NameKubernetesAWSCloudProviderPrefix, name)
   146  }
   147  
   148  // BuildParams is used to build tags around an aws resource.
   149  type BuildParams struct {
   150  	// Lifecycle determines the resource lifecycle.
   151  	Lifecycle ResourceLifecycle
   152  
   153  	// ClusterName is the cluster associated with the resource.
   154  	ClusterName string
   155  
   156  	// ResourceID is the unique identifier of the resource to be tagged.
   157  	ResourceID string
   158  
   159  	// Name is the name of the resource, it's applied as the tag "Name" on AWS.
   160  	// +optional
   161  	Name *string
   162  
   163  	// Role is the role associated to the resource.
   164  	// +optional
   165  	Role *string
   166  
   167  	// Any additional tags to be added to the resource.
   168  	// +optional
   169  	Additional Tags
   170  }
   171  
   172  // WithMachineName tags the namespaced machine name
   173  // The machine name will be tagged with key "MachineName".
   174  func (b BuildParams) WithMachineName(m *clusterv1alpha4.Machine) BuildParams {
   175  	machineNamespacedName := types.NamespacedName{Namespace: m.Namespace, Name: m.Name}
   176  	b.Additional[MachineNameTagKey] = machineNamespacedName.String()
   177  	return b
   178  }
   179  
   180  // WithCloudProvider tags the cluster ownership for a resource.
   181  func (b BuildParams) WithCloudProvider(name string) BuildParams {
   182  	b.Additional[ClusterAWSCloudProviderTagKey(name)] = string(ResourceLifecycleOwned)
   183  	return b
   184  }
   185  
   186  // Build builds tags including the cluster tag and returns them in map form.
   187  func Build(params BuildParams) Tags {
   188  	tags := make(Tags)
   189  	for k, v := range params.Additional {
   190  		tags[k] = v
   191  	}
   192  
   193  	if params.ClusterName != "" {
   194  		tags[ClusterTagKey(params.ClusterName)] = string(params.Lifecycle)
   195  	}
   196  	if params.Role != nil {
   197  		tags[NameAWSClusterAPIRole] = *params.Role
   198  	}
   199  
   200  	if params.Name != nil {
   201  		tags["Name"] = *params.Name
   202  	}
   203  
   204  	return tags
   205  }