Skip to content

Commit 11d3567

Browse files
committed
feat: support adding ResourceManagerTags to compute instances
Signed-off-by: Carlos Salas <[email protected]>
1 parent 1fb758a commit 11d3567

25 files changed

+391
-5
lines changed

api/v1alpha3/zz_generated.conversion.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha4/gcpcluster_conversion.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ func (src *GCPCluster) ConvertTo(dstRaw conversion.Hub) error { // nolint
5252
dst.Spec.CredentialsRef = restored.Spec.CredentialsRef.DeepCopy()
5353
}
5454

55+
if restored.Spec.ResourceManagerTags != nil {
56+
dst.Spec.ResourceManagerTags = restored.Spec.ResourceManagerTags.DeepCopy()
57+
}
58+
5559
return nil
5660
}
5761

api/v1alpha4/gcpclustertemplate_conversion.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ func (src *GCPClusterTemplate) ConvertTo(dstRaw conversion.Hub) error { // nolin
5454
dst.Spec.Template.Spec.CredentialsRef = restored.Spec.Template.Spec.CredentialsRef.DeepCopy()
5555
}
5656

57+
if restored.Spec.Template.Spec.ResourceManagerTags != nil {
58+
dst.Spec.Template.Spec.ResourceManagerTags = restored.Spec.Template.Spec.ResourceManagerTags.DeepCopy()
59+
}
60+
5761
return nil
5862
}
5963

api/v1alpha4/gcpmachine_conversion.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ func (src *GCPMachine) ConvertTo(dstRaw conversion.Hub) error { // nolint
5353
dst.Spec.ConfidentialCompute = restored.Spec.ConfidentialCompute
5454
}
5555

56+
if restored.Spec.ResourceManagerTags != nil {
57+
dst.Spec.ResourceManagerTags = restored.Spec.ResourceManagerTags
58+
}
59+
5660
return nil
5761
}
5862

api/v1alpha4/gcpmachinetemplate_conversion.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ func (src *GCPMachineTemplate) ConvertTo(dstRaw conversion.Hub) error { // nolin
5454
dst.Spec.Template.Spec.ConfidentialCompute = restored.Spec.Template.Spec.ConfidentialCompute
5555
}
5656

57+
if restored.Spec.Template.Spec.ResourceManagerTags != nil {
58+
dst.Spec.Template.Spec.ResourceManagerTags = restored.Spec.Template.Spec.ResourceManagerTags
59+
}
60+
5761
return nil
5862
}
5963

api/v1alpha4/zz_generated.conversion.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1beta1/gcpcluster_types.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,56 @@ type GCPClusterSpec struct {
5454
// +optional
5555
AdditionalLabels Labels `json:"additionalLabels,omitempty"`
5656

57+
// resourceManagerTags is an optional set of tags to apply to GCP resources managed
58+
// by the GCP provider. GCP supports a maximum of 50 tags per resource.
59+
// +kubebuilder:validation:MaxItems=50
60+
// +listType=map
61+
// +listMapKey=key
62+
// +optional
63+
ResourceManagerTags ResourceManagerTags `json:"resourceManagerTags,omitempty"`
64+
5765
// CredentialsRef is a reference to a Secret that contains the credentials to use for provisioning this cluster. If not
5866
// supplied then the credentials of the controller will be used.
5967
// +optional
6068
CredentialsRef *ObjectReference `json:"credentialsRef,omitempty"`
6169
}
6270

71+
// ResourceManagerTag is a tag to apply to GCP resources managed by the GCP provider.
72+
type ResourceManagerTag struct {
73+
// parentID is the ID of the hierarchical resource where the tags are defined
74+
// e.g. at the Organization or the Project level. To find the Organization or Project ID ref
75+
// https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id
76+
// https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects
77+
// An OrganizationID must consist of decimal numbers, and cannot have leading zeroes.
78+
// A ProjectID must be 6 to 30 characters in length, can only contain lowercase letters,
79+
// numbers, and hyphens, and must start with a letter, and cannot end with a hyphen.
80+
// +kubebuilder:validation:Required
81+
// +kubebuilder:validation:MinLength=1
82+
// +kubebuilder:validation:MaxLength=32
83+
// +kubebuilder:validation:Pattern=`(^[1-9][0-9]{0,31}$)|(^[a-z][a-z0-9-]{4,28}[a-z0-9]$)`
84+
ParentID string `json:"parentID"`
85+
86+
// key is the key part of the tag. A tag key can have a maximum of 63 characters and cannot
87+
// be empty. Tag key must begin and end with an alphanumeric character, and must contain
88+
// only uppercase, lowercase alphanumeric characters, and the following special
89+
// characters `._-`.
90+
// +kubebuilder:validation:Required
91+
// +kubebuilder:validation:MinLength=1
92+
// +kubebuilder:validation:MaxLength=63
93+
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9]([0-9A-Za-z_.-]{0,61}[a-zA-Z0-9])?$`
94+
Key string `json:"key"`
95+
96+
// value is the value part of the tag. A tag value can have a maximum of 63 characters and
97+
// cannot be empty. Tag value must begin and end with an alphanumeric character, and must
98+
// contain only uppercase, lowercase alphanumeric characters, and the following special
99+
// characters `_-.@%=+:,*#&(){}[]` and spaces.
100+
// +kubebuilder:validation:Required
101+
// +kubebuilder:validation:MinLength=1
102+
// +kubebuilder:validation:MaxLength=63
103+
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9]([0-9A-Za-z_.@%=+:,*#&()\[\]{}\-\s]{0,61}[a-zA-Z0-9])?$`
104+
Value string `json:"value"`
105+
}
106+
63107
// GCPClusterStatus defines the observed state of GCPCluster.
64108
type GCPClusterStatus struct {
65109
FailureDomains clusterv1.FailureDomains `json:"failureDomains,omitempty"`

api/v1beta1/gcpmachine_types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,14 @@ type GCPMachineSpec struct {
197197
// +optional
198198
AdditionalNetworkTags []string `json:"additionalNetworkTags,omitempty"`
199199

200+
// resourceManagerTags is an optional set of tags to apply to GCP resources managed
201+
// by the GCP provider. GCP supports a maximum of 50 tags per resource.
202+
// +kubebuilder:validation:MaxItems=50
203+
// +listType=map
204+
// +listMapKey=key
205+
// +optional
206+
ResourceManagerTags ResourceManagerTags `json:"resourceManagerTags,omitempty"`
207+
200208
// RootDeviceSize is the size of the root volume in GB.
201209
// Defaults to 30.
202210
// +optional

api/v1beta1/tags.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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+
"context"
21+
"fmt"
22+
23+
resourcemanager "cloud.google.com/go/resourcemanager/apiv3"
24+
rmpb "cloud.google.com/go/resourcemanager/apiv3/resourcemanagerpb"
25+
"sigs.k8s.io/controller-runtime/pkg/log"
26+
)
27+
28+
// ResourceManagerTags defines a list of tags.
29+
type ResourceManagerTags []ResourceManagerTag
30+
31+
// ResourceManagerTagsMap defines a map of key value pairs as expected by compute.InstanceParams.ResourceManagerTags.
32+
type ResourceManagerTagsMap map[string]string
33+
34+
// AddResourceManagerTags binds the passed resource-manager tags to the resource. Tag keys and Tag Values
35+
// will be created by the user and only the Tag bindings to the Compute Instance will be created.
36+
// If the Tag Key/Tag Value cannot be retrieved or no tags are provided, this will be empty and no tags will be added.
37+
func AddResourceManagerTags(ctx context.Context, tagList ResourceManagerTags) ResourceManagerTagsMap {
38+
tagValueList := make(ResourceManagerTagsMap, len(tagList))
39+
log := log.FromContext(ctx)
40+
if len(tagList) == 0 {
41+
return tagValueList
42+
}
43+
44+
client, err := resourcemanager.NewTagValuesClient(ctx)
45+
if err != nil {
46+
log.Error(err, "failed to create tag values client")
47+
return tagValueList
48+
}
49+
50+
getTagValuesReq := &rmpb.GetNamespacedTagValueRequest{}
51+
for _, tag := range tagList {
52+
getTagValuesReq.Name = fmt.Sprintf("%s/%s/%s", tag.ParentID, tag.Key, tag.Value)
53+
value, err := client.GetNamespacedTagValue(ctx, getTagValuesReq)
54+
if err != nil {
55+
log.Error(err, "failed to retrieve tag value")
56+
return tagValueList
57+
}
58+
tagValueList[value.Parent] = value.Name
59+
}
60+
61+
return tagValueList
62+
}

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 65 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)