Skip to content

Commit 036d078

Browse files
authored
Improve cluster metadata support (#146)
* add: version constraint for cluster metadata * tests: add acceptance test for cluster metadata * fix: cluster metadata import
1 parent 54f22a9 commit 036d078

File tree

4 files changed

+228
-0
lines changed

4 files changed

+228
-0
lines changed

argocd/features.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const (
2424
featureRepositoryGet
2525
featureTokenIDs
2626
featureProjectScopedClusters
27+
featureClusterMetadata
2728
)
2829

2930
var (
@@ -33,6 +34,7 @@ var (
3334
featureRepositoryGet: semver.MustParse("1.6.0"),
3435
featureTokenIDs: semver.MustParse("1.5.3"),
3536
featureProjectScopedClusters: semver.MustParse("2.2.0"),
37+
featureClusterMetadata: semver.MustParse("2.2.0"),
3638
}
3739
)
3840

argocd/resource_argocd_cluster.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,28 @@ func resourceArgoCDClusterCreate(ctx context.Context, d *schema.ResourceData, me
7070
}
7171
}
7272

73+
featureClusterMetadataSupported, err := server.isFeatureSupported(featureClusterMetadata)
74+
if err != nil {
75+
return []diag.Diagnostic{
76+
{
77+
Severity: diag.Error,
78+
Summary: "feature not supported",
79+
Detail: err.Error(),
80+
},
81+
}
82+
}
83+
84+
if !featureClusterMetadataSupported && (len(cluster.Annotations) != 0 || len(cluster.Labels) != 0) {
85+
return []diag.Diagnostic{
86+
{
87+
Severity: diag.Error,
88+
Summary: fmt.Sprintf(
89+
"cluster metadata is only supported from ArgoCD %s onwards",
90+
featureVersionConstraintsMap[featureClusterMetadata].String()),
91+
},
92+
}
93+
}
94+
7395
c, err := client.Create(ctx, &clusterClient.ClusterCreateRequest{
7496
Cluster: cluster, Upsert: true})
7597
if err != nil {
@@ -174,6 +196,28 @@ func resourceArgoCDClusterUpdate(ctx context.Context, d *schema.ResourceData, me
174196
}
175197
}
176198

199+
featureClusterMetadataSupported, err := server.isFeatureSupported(featureClusterMetadata)
200+
if err != nil {
201+
return []diag.Diagnostic{
202+
{
203+
Severity: diag.Error,
204+
Summary: "feature not supported",
205+
Detail: err.Error(),
206+
},
207+
}
208+
}
209+
210+
if !featureClusterMetadataSupported && (len(cluster.Annotations) != 0 || len(cluster.Labels) != 0) {
211+
return []diag.Diagnostic{
212+
{
213+
Severity: diag.Error,
214+
Summary: fmt.Sprintf(
215+
"cluster metadata is only supported from ArgoCD %s onwards",
216+
featureVersionConstraintsMap[featureClusterMetadata].String()),
217+
},
218+
}
219+
}
220+
177221
_, err = client.Update(ctx, &clusterClient.ClusterUpdateRequest{Cluster: cluster})
178222
if err != nil {
179223
if strings.Contains(err.Error(), "NotFound") {

argocd/resource_argocd_cluster_test.go

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,92 @@ func TestAccArgoCDCluster_projectScope(t *testing.T) {
100100
})
101101
}
102102

103+
func TestAccArgoCDCluster_metadata(t *testing.T) {
104+
clusterName := acctest.RandString(10)
105+
resource.Test(t, resource.TestCase{
106+
PreCheck: func() { testAccPreCheck(t); testAccPreCheckFeatureSupported(t, featureClusterMetadata) },
107+
ProviderFactories: testAccProviders,
108+
Steps: []resource.TestStep{
109+
{
110+
Config: testAccArgoCDClusterMetadata(clusterName),
111+
Check: resource.ComposeTestCheckFunc(
112+
resource.TestCheckNoResourceAttr(
113+
"argocd_cluster.cluster_metadata",
114+
"metadata",
115+
),
116+
),
117+
},
118+
{
119+
ResourceName: "argocd_cluster.cluster_metadata",
120+
ImportState: true,
121+
ImportStateVerify: true,
122+
ImportStateVerifyIgnore: []string{"config", "info"},
123+
},
124+
{
125+
Config: testAccArgoCDClusterMetadata_addLabels(clusterName),
126+
Check: resource.ComposeTestCheckFunc(
127+
resource.TestCheckResourceAttr(
128+
"argocd_cluster.cluster_metadata",
129+
"metadata.0.labels.test",
130+
"label",
131+
),
132+
resource.TestCheckNoResourceAttr(
133+
"argocd_cluster.cluster_metadata",
134+
"metadata.0.annotations",
135+
),
136+
),
137+
},
138+
{
139+
ResourceName: "argocd_cluster.cluster_metadata",
140+
ImportState: true,
141+
ImportStateVerify: true,
142+
ImportStateVerifyIgnore: []string{"config", "info"},
143+
},
144+
{
145+
Config: testAccArgoCDClusterMetadata_addAnnotations(clusterName),
146+
Check: resource.ComposeTestCheckFunc(
147+
resource.TestCheckResourceAttr(
148+
"argocd_cluster.cluster_metadata",
149+
"metadata.0.labels.test",
150+
"label",
151+
),
152+
resource.TestCheckResourceAttr(
153+
"argocd_cluster.cluster_metadata",
154+
"metadata.0.annotations.test",
155+
"annotation",
156+
),
157+
),
158+
},
159+
{
160+
ResourceName: "argocd_cluster.cluster_metadata",
161+
ImportState: true,
162+
ImportStateVerify: true,
163+
ImportStateVerifyIgnore: []string{"config", "info"},
164+
},
165+
{
166+
Config: testAccArgoCDClusterMetadata_removeLabels(clusterName),
167+
Check: resource.ComposeTestCheckFunc(
168+
resource.TestCheckNoResourceAttr(
169+
"argocd_cluster.cluster_metadata",
170+
"metadata.0.labels",
171+
),
172+
resource.TestCheckResourceAttr(
173+
"argocd_cluster.cluster_metadata",
174+
"metadata.0.annotations.test",
175+
"annotation",
176+
),
177+
),
178+
},
179+
{
180+
ResourceName: "argocd_cluster.cluster_metadata",
181+
ImportState: true,
182+
ImportStateVerify: true,
183+
ImportStateVerifyIgnore: []string{"config", "info"},
184+
},
185+
},
186+
})
187+
}
188+
103189
func testAccArgoCDClusterBearerToken(clusterName string) string {
104190
return fmt.Sprintf(`
105191
resource "argocd_cluster" "simple" {
@@ -164,6 +250,88 @@ resource "argocd_cluster" "project_scope" {
164250
`, clusterName, projectName)
165251
}
166252

253+
func testAccArgoCDClusterMetadata(clusterName string) string {
254+
return fmt.Sprintf(`
255+
resource "argocd_cluster" "cluster_metadata" {
256+
server = "https://kubernetes.default.svc.cluster.local"
257+
name = "%s"
258+
config {
259+
# Uses Kind's bootstrap token whose ttl is 24 hours after cluster bootstrap.
260+
bearer_token = "abcdef.0123456789abcdef"
261+
tls_client_config {
262+
insecure = true
263+
}
264+
}
265+
}
266+
`, clusterName)
267+
}
268+
269+
func testAccArgoCDClusterMetadata_addLabels(clusterName string) string {
270+
return fmt.Sprintf(`
271+
resource "argocd_cluster" "cluster_metadata" {
272+
server = "https://kubernetes.default.svc.cluster.local"
273+
name = "%s"
274+
metadata {
275+
labels = {
276+
test = "label"
277+
}
278+
}
279+
config {
280+
# Uses Kind's bootstrap token whose ttl is 24 hours after cluster bootstrap.
281+
bearer_token = "abcdef.0123456789abcdef"
282+
tls_client_config {
283+
insecure = true
284+
}
285+
}
286+
}
287+
`, clusterName)
288+
}
289+
290+
func testAccArgoCDClusterMetadata_addAnnotations(clusterName string) string {
291+
return fmt.Sprintf(`
292+
resource "argocd_cluster" "cluster_metadata" {
293+
server = "https://kubernetes.default.svc.cluster.local"
294+
name = "%s"
295+
metadata {
296+
labels = {
297+
test = "label"
298+
}
299+
annotations = {
300+
test = "annotation"
301+
}
302+
}
303+
config {
304+
# Uses Kind's bootstrap token whose ttl is 24 hours after cluster bootstrap.
305+
bearer_token = "abcdef.0123456789abcdef"
306+
tls_client_config {
307+
insecure = true
308+
}
309+
}
310+
}
311+
`, clusterName)
312+
}
313+
314+
func testAccArgoCDClusterMetadata_removeLabels(clusterName string) string {
315+
return fmt.Sprintf(`
316+
resource "argocd_cluster" "cluster_metadata" {
317+
server = "https://kubernetes.default.svc.cluster.local"
318+
name = "%s"
319+
metadata {
320+
annotations = {
321+
test = "annotation"
322+
}
323+
}
324+
config {
325+
# Uses Kind's bootstrap token whose ttl is 24 hours after cluster bootstrap.
326+
bearer_token = "abcdef.0123456789abcdef"
327+
tls_client_config {
328+
insecure = true
329+
}
330+
}
331+
}
332+
`, clusterName)
333+
}
334+
167335
// getInternalRestConfig returns the internal Kubernetes cluster REST config.
168336
func getInternalRestConfig() (*rest.Config, error) {
169337
rc := &rest.Config{}

argocd/structure_cluster.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ func flattenCluster(cluster *application.Cluster, d *schema.ResourceData) error
126126
"config": flattenClusterConfig(cluster.Config, d),
127127
"project": cluster.Project,
128128
}
129+
if len(cluster.Annotations) != 0 || len(cluster.Labels) != 0 {
130+
// The generic flattenMetadata function can not be used since the Cluster
131+
// object does not actually have ObjectMeta, just label and annotation maps
132+
r["metadata"] = flattenClusterMetadata(cluster.Annotations, cluster.Labels)
133+
}
129134
if cluster.Shard != nil {
130135
r["shard"] = convertInt64PointerToString(cluster.Shard)
131136
}
@@ -202,3 +207,12 @@ func flattenClusterConfigExecProviderConfig(epc *application.ExecProviderConfig)
202207
}
203208
return
204209
}
210+
211+
func flattenClusterMetadata(annotations, labels map[string]string) []map[string]interface{} {
212+
return []map[string]interface{}{
213+
{
214+
"annotations": annotations,
215+
"labels": labels,
216+
},
217+
}
218+
}

0 commit comments

Comments
 (0)