sigs.k8s.io/cluster-api-provider-aws@v1.5.5/api/v1alpha3/tags.go (about)

     1  /*
     2  Copyright 2019 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 v1alpha3
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"github.com/google/go-cmp/cmp"
    23  	"k8s.io/apimachinery/pkg/types"
    24  
    25  	clusterv1alpha3 "sigs.k8s.io/cluster-api/api/v1alpha3"
    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 subnet associations.
   113  	NameAWSSubnetAssociation = NameAWSProviderPrefix + "association"
   114  
   115  	// SecondarySubnetTagValue describes the value for the secondary subnet.
   116  	SecondarySubnetTagValue = "secondary"
   117  
   118  	// APIServerRoleTagValue describes the value for the apiserver role.
   119  	APIServerRoleTagValue = "apiserver"
   120  
   121  	// BastionRoleTagValue describes the value for the bastion role.
   122  	BastionRoleTagValue = "bastion"
   123  
   124  	// CommonRoleTagValue describes the value for the common role.
   125  	CommonRoleTagValue = "common"
   126  
   127  	// PublicRoleTagValue describes the value for the public role.
   128  	PublicRoleTagValue = "public"
   129  
   130  	// PrivateRoleTagValue describes the value for the private role.
   131  	PrivateRoleTagValue = "private"
   132  
   133  	// MachineNameTagKey is the key for machine name.
   134  	MachineNameTagKey = "MachineName"
   135  )
   136  
   137  // ClusterTagKey generates the key for resources associated with a cluster.
   138  func ClusterTagKey(name string) string {
   139  	return fmt.Sprintf("%s%s", NameAWSProviderOwned, name)
   140  }
   141  
   142  // ClusterAWSCloudProviderTagKey generates the key for resources associated a cluster's AWS cloud provider.
   143  func ClusterAWSCloudProviderTagKey(name string) string {
   144  	return fmt.Sprintf("%s%s", NameKubernetesAWSCloudProviderPrefix, name)
   145  }
   146  
   147  // BuildParams is used to build tags around an aws resource.
   148  type BuildParams struct {
   149  	// Lifecycle determines the resource lifecycle.
   150  	Lifecycle ResourceLifecycle
   151  
   152  	// ClusterName is the cluster associated with the resource.
   153  	ClusterName string
   154  
   155  	// ResourceID is the unique identifier of the resource to be tagged.
   156  	ResourceID string
   157  
   158  	// Name is the name of the resource, it's applied as the tag "Name" on AWS.
   159  	// +optional
   160  	Name *string
   161  
   162  	// Role is the role associated to the resource.
   163  	// +optional
   164  	Role *string
   165  
   166  	// Any additional tags to be added to the resource.
   167  	// +optional
   168  	Additional Tags
   169  }
   170  
   171  // WithMachineName tags the namespaced machine name
   172  // The machine name will be tagged with key "MachineName".
   173  func (b BuildParams) WithMachineName(m *clusterv1alpha3.Machine) BuildParams {
   174  	machineNamespacedName := types.NamespacedName{Namespace: m.Namespace, Name: m.Name}
   175  	b.Additional[MachineNameTagKey] = machineNamespacedName.String()
   176  	return b
   177  }
   178  
   179  // WithCloudProvider tags the cluster ownership for a resource.
   180  func (b BuildParams) WithCloudProvider(name string) BuildParams {
   181  	b.Additional[ClusterAWSCloudProviderTagKey(name)] = string(ResourceLifecycleOwned)
   182  	return b
   183  }
   184  
   185  // Build builds tags including the cluster tag and returns them in map form.
   186  func Build(params BuildParams) Tags {
   187  	tags := make(Tags)
   188  	for k, v := range params.Additional {
   189  		tags[k] = v
   190  	}
   191  
   192  	tags[ClusterTagKey(params.ClusterName)] = string(params.Lifecycle)
   193  	if params.Role != nil {
   194  		tags[NameAWSClusterAPIRole] = *params.Role
   195  	}
   196  
   197  	if params.Name != nil {
   198  		tags["Name"] = *params.Name
   199  	}
   200  
   201  	return tags
   202  }