-
Notifications
You must be signed in to change notification settings - Fork 435
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Cecile Robert-Michon
committed
Nov 1, 2019
1 parent
e2f14d8
commit 7f2ec76
Showing
23 changed files
with
737 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
run: | ||
deadline: 3m | ||
skip-dirs: | ||
- mock* | ||
linters: | ||
enable: | ||
- golint | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
/* | ||
Copyright 2019 The Kubernetes Authors. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package v1alpha2 | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
) | ||
|
||
// Tags defines a map of tags. | ||
type Tags map[string]string | ||
|
||
// Equals returns true if the tags are equal. | ||
func (t Tags) Equals(other Tags) bool { | ||
return reflect.DeepEqual(t, other) | ||
} | ||
|
||
// 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. | ||
func (t Tags) HasOwned(cluster string) bool { | ||
value, ok := t[ClusterTagKey(cluster)] | ||
return ok && ResourceLifecycle(value) == ResourceLifecycleOwned | ||
} | ||
|
||
// 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. | ||
func (t Tags) HasAzureCloudProviderOwned(cluster string) bool { | ||
value, ok := t[ClusterAzureCloudProviderTagKey(cluster)] | ||
return ok && ResourceLifecycle(value) == ResourceLifecycleOwned | ||
} | ||
|
||
// GetRole returns the Cluster API role for the tagged resource | ||
func (t Tags) GetRole() string { | ||
return t[NameAzureClusterAPIRole] | ||
} | ||
|
||
// Difference returns the difference between this map of tags and the other map of tags. | ||
// Items are considered equals if key and value are equals. | ||
func (t Tags) Difference(other Tags) Tags { | ||
res := make(Tags, len(t)) | ||
|
||
for key, value := range t { | ||
if otherValue, ok := other[key]; ok && value == otherValue { | ||
continue | ||
} | ||
res[key] = value | ||
} | ||
|
||
return res | ||
} | ||
|
||
// Merge merges in tags from other. If a tag already exists, it is replaced by the tag in other. | ||
func (t Tags) Merge(other Tags) { | ||
for k, v := range other { | ||
t[k] = v | ||
} | ||
} | ||
|
||
// ResourceLifecycle configures the lifecycle of a resource | ||
type ResourceLifecycle string | ||
|
||
const ( | ||
// ResourceLifecycleOwned is the value we use when tagging resources to indicate | ||
// that the resource is considered owned and managed by the cluster, | ||
// and in particular that the lifecycle is tied to the lifecycle of the cluster. | ||
ResourceLifecycleOwned = ResourceLifecycle("owned") | ||
|
||
// ResourceLifecycleShared is the value we use when tagging resources to indicate | ||
// that the resource is shared between multiple clusters, and should not be destroyed | ||
// if the cluster is destroyed. | ||
ResourceLifecycleShared = ResourceLifecycle("shared") | ||
|
||
// NameKubernetesAzureCloudProviderPrefix is the tag name used by the cloud provider to logically | ||
// separate independent cluster resources. We use it to identify which resources we expect | ||
// to be permissive about state changes. | ||
// logically independent clusters running in the same AZ. | ||
// The tag key = NameKubernetesAzureCloudProviderPrefix + clusterID | ||
// The tag value is an ownership value | ||
NameKubernetesAzureCloudProviderPrefix = "kubernetes.io_cluster_" | ||
|
||
// NameAzureProviderPrefix is the tag prefix we use to differentiate | ||
// cluster-api-provider-azure owned components from other tooling that | ||
// uses NameKubernetesClusterPrefix | ||
NameAzureProviderPrefix = "sigs.k8s.io_cluster-api-provider-azure_" | ||
|
||
// NameAzureProviderOwned is the tag name we use to differentiate | ||
// cluster-api-provider-azure owned components from other tooling that | ||
// uses NameKubernetesClusterPrefix | ||
NameAzureProviderOwned = NameAzureProviderPrefix + "cluster_" | ||
|
||
// NameAzureClusterAPIRole is the tag name we use to mark roles for resources | ||
// dedicated to this cluster api provider implementation. | ||
NameAzureClusterAPIRole = NameAzureProviderPrefix + "role" | ||
|
||
// APIServerRoleTagValue describes the value for the apiserver role | ||
APIServerRoleTagValue = "apiserver" | ||
|
||
// BastionRoleTagValue describes the value for the bastion role | ||
BastionRoleTagValue = "bastion" | ||
|
||
// CommonRoleTagValue describes the value for the common role | ||
CommonRoleTagValue = "common" | ||
|
||
// PublicRoleTagValue describes the value for the public role | ||
PublicRoleTagValue = "public" | ||
|
||
// PrivateRoleTagValue describes the value for the private role | ||
PrivateRoleTagValue = "private" | ||
) | ||
|
||
// ClusterTagKey generates the key for resources associated with a cluster. | ||
func ClusterTagKey(name string) string { | ||
return fmt.Sprintf("%s%s", NameAzureProviderOwned, name) | ||
} | ||
|
||
// ClusterAzureCloudProviderTagKey generates the key for resources associated a cluster's Azure cloud provider. | ||
func ClusterAzureCloudProviderTagKey(name string) string { | ||
return fmt.Sprintf("%s%s", NameKubernetesAzureCloudProviderPrefix, name) | ||
} | ||
|
||
// BuildParams is used to build tags around an azure resource. | ||
type BuildParams struct { | ||
// Lifecycle determines the resource lifecycle. | ||
Lifecycle ResourceLifecycle | ||
|
||
// ClusterName is the cluster associated with the resource. | ||
ClusterName string | ||
|
||
// ResourceID is the unique identifier of the resource to be tagged. | ||
ResourceID string | ||
|
||
// Name is the name of the resource, it's applied as the tag "Name" on Azure. | ||
// +optional | ||
Name *string | ||
|
||
// Role is the role associated to the resource. | ||
// +optional | ||
Role *string | ||
|
||
// Any additional tags to be added to the resource. | ||
// +optional | ||
Additional Tags | ||
} | ||
|
||
// Build builds tags including the cluster tag and returns them in map form. | ||
func Build(params BuildParams) Tags { | ||
tags := make(Tags) | ||
for k, v := range params.Additional { | ||
tags[k] = v | ||
} | ||
|
||
tags[ClusterTagKey(params.ClusterName)] = string(params.Lifecycle) | ||
if params.Role != nil { | ||
tags[NameAzureClusterAPIRole] = *params.Role | ||
} | ||
|
||
if params.Name != nil { | ||
tags["Name"] = *params.Name | ||
} | ||
|
||
return tags | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
Copyright 2019 The Kubernetes Authors. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package v1alpha2 | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
func TestTags_Merge(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
other Tags | ||
expected Tags | ||
}{ | ||
{ | ||
name: "nil other", | ||
other: nil, | ||
expected: Tags{ | ||
"a": "b", | ||
"c": "d", | ||
}, | ||
}, | ||
{ | ||
name: "empty other", | ||
other: Tags{}, | ||
expected: Tags{ | ||
"a": "b", | ||
"c": "d", | ||
}, | ||
}, | ||
{ | ||
name: "disjoint", | ||
other: Tags{ | ||
"1": "2", | ||
"3": "4", | ||
}, | ||
expected: Tags{ | ||
"a": "b", | ||
"c": "d", | ||
"1": "2", | ||
"3": "4", | ||
}, | ||
}, | ||
{ | ||
name: "overlapping, other wins", | ||
other: Tags{ | ||
"1": "2", | ||
"3": "4", | ||
"a": "hello", | ||
}, | ||
expected: Tags{ | ||
"a": "hello", | ||
"c": "d", | ||
"1": "2", | ||
"3": "4", | ||
}, | ||
}, | ||
} | ||
for _, tc := range tests { | ||
t.Run(tc.name, func(t *testing.T) { | ||
t.Parallel() | ||
tags := Tags{ | ||
"a": "b", | ||
"c": "d", | ||
} | ||
|
||
tags.Merge(tc.other) | ||
if e, a := tc.expected, tags; !reflect.DeepEqual(e, a) { | ||
t.Errorf("expected %#v, got %#v", e, a) | ||
} | ||
}) | ||
} | ||
|
||
} |
Oops, something went wrong.