Skip to content

Commit 2a2a70a

Browse files
committed
Implement new resource gitlab_cluster_agent
This resource implements the API for GitLab Agents for Kubernetes: https://docs.gitlab.com/ee/api/cluster_agents.html
1 parent 36c66a1 commit 2a2a70a

File tree

7 files changed

+441
-0
lines changed

7 files changed

+441
-0
lines changed

docs/resources/cluster_agent.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "gitlab_cluster_agent Resource - terraform-provider-gitlab"
4+
subcategory: ""
5+
description: |-
6+
The gitlab_cluster_agent resource allows to manage the lifecycle of a GitLab Agent for Kubernetes.
7+
-> Note that this resource only registers the agent, but doesn't configure it.
8+
The configuration needs to be manually added as described in
9+
the docs https://docs.gitlab.com/ee/user/clusters/agent/install/index.html#create-an-agent-configuration-file.
10+
However, a gitlab_repository_file resource may be used to achieve that.
11+
-> Requires at least maintainer permissions on the project.
12+
-> Requires at least GitLab 14.10
13+
Upstream API: GitLab REST API docs https://docs.gitlab.com/ee/api/cluster_agents.html
14+
---
15+
16+
# gitlab_cluster_agent (Resource)
17+
18+
The `gitlab_cluster_agent` resource allows to manage the lifecycle of a GitLab Agent for Kubernetes.
19+
20+
-> Note that this resource only registers the agent, but doesn't configure it.
21+
The configuration needs to be manually added as described in
22+
[the docs](https://docs.gitlab.com/ee/user/clusters/agent/install/index.html#create-an-agent-configuration-file).
23+
However, a `gitlab_repository_file` resource may be used to achieve that.
24+
25+
-> Requires at least maintainer permissions on the project.
26+
27+
-> Requires at least GitLab 14.10
28+
29+
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/cluster_agents.html)
30+
31+
## Example Usage
32+
33+
```terraform
34+
resource "gitlab_cluster_agent" "example" {
35+
project = "12345"
36+
name = "agent-1"
37+
}
38+
39+
// Optionally, configure the agent as described in
40+
// https://docs.gitlab.com/ee/user/clusters/agent/install/index.html#create-an-agent-configuration-file
41+
resource "gitlab_repository_file" "example_agent_config" {
42+
project = gitlab_cluster_agent.example.project
43+
branch = "main" // or use the `default_branch` attribute from a project data source / resource
44+
file_path = ".gitlab/agents/${gitlab_cluster_agent.example.name}"
45+
content = <<CONTENT
46+
gitops:
47+
...
48+
CONTENT
49+
author_email = "[email protected]"
50+
author_name = "Terraform"
51+
commit_message = "feature: add agent config for ${gitlab_cluster_agent.example.name}"
52+
}
53+
```
54+
55+
<!-- schema generated by tfplugindocs -->
56+
## Schema
57+
58+
### Required
59+
60+
- `name` (String) The Name of the agent.
61+
- `project` (String) ID or full path of the project maintained by the authenticated user.
62+
63+
### Read-Only
64+
65+
- `agent_id` (Number) The ID of the agent.
66+
- `created_at` (String) The ISO8601 datetime when the agent was created.
67+
- `created_by_user_id` (Number) The ID of the user who created the agent.
68+
- `id` (String) The ID of this resource.
69+
70+
## Import
71+
72+
Import is supported using the following syntax:
73+
74+
```shell
75+
# GitLab Agent for Kubernetes can be imported with the following command and the id pattern `<project>:<agent-id>`
76+
terraform import gitlab_cluster_agent.example '12345:42'
77+
```
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# GitLab Agent for Kubernetes can be imported with the following command and the id pattern `<project>:<agent-id>`
2+
terraform import gitlab_cluster_agent.example '12345:42'
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
resource "gitlab_cluster_agent" "example" {
2+
project = "12345"
3+
name = "agent-1"
4+
}
5+
6+
// Optionally, configure the agent as described in
7+
// https://docs.gitlab.com/ee/user/clusters/agent/install/index.html#create-an-agent-configuration-file
8+
resource "gitlab_repository_file" "example_agent_config" {
9+
project = gitlab_cluster_agent.example.project
10+
branch = "main" // or use the `default_branch` attribute from a project data source / resource
11+
file_path = ".gitlab/agents/${gitlab_cluster_agent.example.name}"
12+
content = <<CONTENT
13+
gitops:
14+
...
15+
CONTENT
16+
author_email = "[email protected]"
17+
author_name = "Terraform"
18+
commit_message = "feature: add agent config for ${gitlab_cluster_agent.example.name}"
19+
}

internal/provider/helper_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,28 @@ func testAccAddProjectMembers(t *testing.T, pid interface{}, users []*gitlab.Use
283283
}
284284
}
285285

286+
func testAccCreateClusterAgents(t *testing.T, pid interface{}, n int) []*gitlab.Agent {
287+
t.Helper()
288+
289+
var clusterAgents []*gitlab.Agent
290+
for i := 0; i < n; i++ {
291+
clusterAgent, _, err := testGitlabClient.ClusterAgents.RegisterAgent(pid, &gitlab.RegisterAgentOptions{
292+
Name: gitlab.String(fmt.Sprintf("agent-%d", i)),
293+
})
294+
if err != nil {
295+
t.Fatalf("could not create test cluster agent: %v", err)
296+
}
297+
t.Cleanup(func() {
298+
_, err := testGitlabClient.ClusterAgents.DeleteAgent(pid, clusterAgent.ID)
299+
if err != nil {
300+
t.Fatalf("could not cleanup test cluster agent: %v", err)
301+
}
302+
})
303+
clusterAgents = append(clusterAgents, clusterAgent)
304+
}
305+
return clusterAgents
306+
}
307+
286308
func testAccCreateProjectIssues(t *testing.T, pid interface{}, n int) []*gitlab.Issue {
287309
t.Helper()
288310

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
"strconv"
8+
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
11+
gitlab "github.com/xanzy/go-gitlab"
12+
)
13+
14+
var _ = registerResource("gitlab_cluster_agent", func() *schema.Resource {
15+
return &schema.Resource{
16+
Description: `The ` + "`" + `gitlab_cluster_agent` + "`" + ` resource allows to manage the lifecycle of a GitLab Agent for Kubernetes.
17+
18+
-> Note that this resource only registers the agent, but doesn't configure it.
19+
The configuration needs to be manually added as described in
20+
[the docs](https://docs.gitlab.com/ee/user/clusters/agent/install/index.html#create-an-agent-configuration-file).
21+
However, a ` + "`gitlab_repository_file`" + ` resource may be used to achieve that.
22+
23+
-> Requires at least maintainer permissions on the project.
24+
25+
-> Requires at least GitLab 14.10
26+
27+
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/cluster_agents.html)`,
28+
29+
CreateContext: resourceGitlabClusterAgentCreate,
30+
ReadContext: resourceGitlabClusterAgentRead,
31+
DeleteContext: resourceGitlabClusterAgentDelete,
32+
Importer: &schema.ResourceImporter{
33+
StateContext: schema.ImportStatePassthroughContext,
34+
},
35+
36+
Schema: gitlabClusterAgentSchema(),
37+
}
38+
})
39+
40+
func resourceGitlabClusterAgentCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
41+
client := meta.(*gitlab.Client)
42+
43+
project := d.Get("project").(string)
44+
options := gitlab.RegisterAgentOptions{
45+
Name: gitlab.String(d.Get("name").(string)),
46+
}
47+
48+
log.Printf("[DEBUG] create GitLab Agent for Kubernetes in project %s with name '%v'", project, options.Name)
49+
clusterAgent, _, err := client.ClusterAgents.RegisterAgent(project, &options, gitlab.WithContext(ctx))
50+
if err != nil {
51+
return diag.FromErr(err)
52+
}
53+
54+
d.SetId(resourceGitlabClusterAgentBuildID(project, clusterAgent.ID))
55+
return resourceGitlabClusterAgentRead(ctx, d, meta)
56+
}
57+
58+
func resourceGitlabClusterAgentRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
59+
client := meta.(*gitlab.Client)
60+
project, agentID, err := resourceGitlabClusterAgentParseID(d.Id())
61+
if err != nil {
62+
return diag.FromErr(err)
63+
}
64+
65+
log.Printf("[DEBUG] read GitLab Agent for Kubernetes in project %s with id %d", project, agentID)
66+
clusterAgent, _, err := client.ClusterAgents.GetAgent(project, agentID, gitlab.WithContext(ctx))
67+
if err != nil {
68+
if is404(err) {
69+
log.Printf("[DEBUG] read GitLab Agent for Kubernetes in project %s with id %d not found, removing from state", project, agentID)
70+
d.SetId("")
71+
return nil
72+
}
73+
return diag.FromErr(err)
74+
}
75+
76+
stateMap := gitlabClusterAgentToStateMap(project, clusterAgent)
77+
if err = setStateMapInResourceData(stateMap, d); err != nil {
78+
return diag.FromErr(err)
79+
}
80+
return nil
81+
}
82+
83+
func resourceGitlabClusterAgentDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
84+
client := meta.(*gitlab.Client)
85+
project, agentID, err := resourceGitlabClusterAgentParseID(d.Id())
86+
if err != nil {
87+
return diag.FromErr(err)
88+
}
89+
90+
log.Printf("[DEBUG] delete GitLab Agent for Kubernetes in project %s with id %d", project, agentID)
91+
if _, err := client.ClusterAgents.DeleteAgent(project, agentID, gitlab.WithContext(ctx)); err != nil {
92+
return diag.FromErr(err)
93+
}
94+
95+
return nil
96+
}
97+
98+
func resourceGitlabClusterAgentBuildID(project string, agentID int) string {
99+
return fmt.Sprintf("%s:%d", project, agentID)
100+
}
101+
102+
func resourceGitlabClusterAgentParseID(id string) (string, int, error) {
103+
project, rawAgentID, err := parseTwoPartID(id)
104+
if err != nil {
105+
return "", 0, err
106+
}
107+
108+
agentID, err := strconv.Atoi(rawAgentID)
109+
if err != nil {
110+
return "", 0, err
111+
}
112+
113+
return project, agentID, nil
114+
}

0 commit comments

Comments
 (0)