Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New Resource
gitlab_cluster_agent_token
This change set adds support for the `gitlab_cluster_agent_token` resource, representing the [Agents Token API](https://docs.gitlab.com/ee/api/cluster_agents.html#create-an-agent-token). Closes: #1141
- Loading branch information
1 parent
334b041
commit e937938
Showing
6 changed files
with
515 additions
and
0 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 |
---|---|---|
@@ -0,0 +1,99 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "gitlab_cluster_agent_token Resource - terraform-provider-gitlab" | ||
subcategory: "" | ||
description: |- | ||
The gitlab_cluster_agent_token resource allows to manage the lifecycle of a token for a GitLab Agent for Kubernetes. | ||
-> Requires at least maintainer permissions on the project. | ||
-> Requires at least GitLab 15.0 | ||
Upstream API: GitLab REST API docs https://docs.gitlab.com/ee/api/cluster_agents.html#create-an-agent-token | ||
--- | ||
|
||
# gitlab_cluster_agent_token (Resource) | ||
|
||
The `gitlab_cluster_agent_token` resource allows to manage the lifecycle of a token for a GitLab Agent for Kubernetes. | ||
|
||
-> Requires at least maintainer permissions on the project. | ||
|
||
-> Requires at least GitLab 15.0 | ||
|
||
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/cluster_agents.html#create-an-agent-token) | ||
|
||
## Example Usage | ||
|
||
```terraform | ||
// Create token for an agent | ||
resource "gitlab_cluster_agent_token" "example" { | ||
project = "12345" | ||
agent_id = 42 | ||
name = "some-token" | ||
description = "some token" | ||
} | ||
// The following example creates a GitLab Agent for Kubernetes in a given project, | ||
// creates a token and install the `gitlab-agent` Helm Chart. | ||
// (see https://gitlab.com/gitlab-org/charts/gitlab-agent) | ||
data "gitlab_project" "this" { | ||
path_with_namespace = "my-org/example" | ||
} | ||
resource "gitlab_cluster_agent" "this" { | ||
project = data.gitlab_project.this | ||
name = "my-agent" | ||
} | ||
resource "gitlab_cluster_agent_token" "this" { | ||
project = data.gitlab_project.this | ||
agent_id = gitlab_cluster_agent.this.id | ||
name = "my-agent-token" | ||
description = "Token for the my-agent used with `gitlab-agent` Helm Chart" | ||
} | ||
resource "helm_release" "gitlab_agent" { | ||
name = "gitlab-agent" | ||
namespace = "gitlab-agent" | ||
create_namespace = true | ||
repository = "https://charts.gitlab.io" | ||
chart = "gitlab-agent" | ||
version = "1.2.0" | ||
set { | ||
name = "config.token" | ||
value = gitlab_cluster_agent_token.this.token | ||
} | ||
} | ||
``` | ||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Required | ||
|
||
- `agent_id` (Number) The ID of the agent. | ||
- `name` (String) The Name of the agent. | ||
- `project` (String) ID or full path of the project maintained by the authenticated user. | ||
|
||
### Optional | ||
|
||
- `description` (String) The Description for the agent. | ||
|
||
### Read-Only | ||
|
||
- `created_at` (String) The ISO8601 datetime when the agent was created. | ||
- `created_by_user_id` (Number) The ID of the user who created the agent. | ||
- `id` (String) The ID of this resource. | ||
- `last_used_at` (String) The ISO8601 datetime when the token was last used. | ||
- `status` (String) The status of the token. Valid values are `active`, `revoked`. | ||
- `token` (String) The secret token for the agent. The `token` is not available in imported resources. | ||
- `token_id` (Number) The ID of the token. | ||
|
||
## Import | ||
|
||
Import is supported using the following syntax: | ||
|
||
```shell | ||
# A token for a GitLab Agent for Kubernetes can be imported with the following command and the id pattern `<project>:<agent-id>:<token-id>`: | ||
terraform import gitlab_cluster_agent_token.example '12345:42:1' | ||
|
||
# ATTENTION: the `token` resource attribute is not available for imported resources as this information cannot be read from the GitLab API. | ||
``` |
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,4 @@ | ||
# A token for a GitLab Agent for Kubernetes can be imported with the following command and the id pattern `<project>:<agent-id>:<token-id>`: | ||
terraform import gitlab_cluster_agent_token.example '12345:42:1' | ||
|
||
# ATTENTION: the `token` resource attribute is not available for imported resources as this information cannot be read from the GitLab API. |
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,40 @@ | ||
// Create token for an agent | ||
resource "gitlab_cluster_agent_token" "example" { | ||
project = "12345" | ||
agent_id = 42 | ||
name = "some-token" | ||
description = "some token" | ||
} | ||
|
||
// The following example creates a GitLab Agent for Kubernetes in a given project, | ||
// creates a token and install the `gitlab-agent` Helm Chart. | ||
// (see https://gitlab.com/gitlab-org/charts/gitlab-agent) | ||
data "gitlab_project" "this" { | ||
path_with_namespace = "my-org/example" | ||
} | ||
|
||
resource "gitlab_cluster_agent" "this" { | ||
project = data.gitlab_project.this | ||
name = "my-agent" | ||
} | ||
|
||
resource "gitlab_cluster_agent_token" "this" { | ||
project = data.gitlab_project.this | ||
agent_id = gitlab_cluster_agent.this.id | ||
name = "my-agent-token" | ||
description = "Token for the my-agent used with `gitlab-agent` Helm Chart" | ||
} | ||
|
||
resource "helm_release" "gitlab_agent" { | ||
name = "gitlab-agent" | ||
namespace = "gitlab-agent" | ||
create_namespace = true | ||
repository = "https://charts.gitlab.io" | ||
chart = "gitlab-agent" | ||
version = "1.2.0" | ||
|
||
set { | ||
name = "config.token" | ||
value = gitlab_cluster_agent_token.this.token | ||
} | ||
} |
121 changes: 121 additions & 0 deletions
121
internal/provider/resource_gitlab_cluster_agent_token.go
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,121 @@ | ||
package provider | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
gitlab "github.com/xanzy/go-gitlab" | ||
) | ||
|
||
var _ = registerResource("gitlab_cluster_agent_token", func() *schema.Resource { | ||
return &schema.Resource{ | ||
Description: `The ` + "`" + `gitlab_cluster_agent_token` + "`" + ` resource allows to manage the lifecycle of a token for a GitLab Agent for Kubernetes. | ||
-> Requires at least maintainer permissions on the project. | ||
-> Requires at least GitLab 15.0 | ||
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/cluster_agents.html#create-an-agent-token)`, | ||
|
||
CreateContext: resourceGitlabClusterAgentTokenCreate, | ||
ReadContext: resourceGitlabClusterAgentTokenRead, | ||
DeleteContext: resourceGitlabClusterAgentTokenDelete, | ||
Importer: &schema.ResourceImporter{ | ||
StateContext: schema.ImportStatePassthroughContext, | ||
}, | ||
|
||
Schema: gitlabClusterAgentTokenSchema(), | ||
} | ||
}) | ||
|
||
func resourceGitlabClusterAgentTokenCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
client := meta.(*gitlab.Client) | ||
|
||
project := d.Get("project").(string) | ||
agentID := d.Get("agent_id").(int) | ||
options := gitlab.CreateAgentTokenOptions{ | ||
Name: gitlab.String(d.Get("name").(string)), | ||
} | ||
|
||
if v, ok := d.GetOk("description"); ok { | ||
options.Description = gitlab.String(v.(string)) | ||
} | ||
|
||
log.Printf("[DEBUG] create token for GitLab Agent for Kubernetes %d in project %s with name '%v'", agentID, project, options.Name) | ||
clusterAgentToken, _, err := client.ClusterAgents.CreateAgentToken(project, agentID, &options, gitlab.WithContext(ctx)) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
d.SetId(resourceGitlabClusterAgentTokenBuildID(project, agentID, clusterAgentToken.ID)) | ||
// NOTE: the token is only returned with the direct response from the create API. | ||
d.Set("token", clusterAgentToken.Token) | ||
return resourceGitlabClusterAgentTokenRead(ctx, d, meta) | ||
} | ||
|
||
func resourceGitlabClusterAgentTokenRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
client := meta.(*gitlab.Client) | ||
project, agentID, tokenID, err := resourceGitlabClusterAgentTokenParseID(d.Id()) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
log.Printf("[DEBUG] read token for GitLab Agent for Kubernetes %d in project %s with id %d", agentID, project, tokenID) | ||
clusterAgentToken, _, err := client.ClusterAgents.GetAgentToken(project, agentID, tokenID, gitlab.WithContext(ctx)) | ||
if err != nil { | ||
if is404(err) { | ||
log.Printf("[DEBUG] read token for GitLab Agent for Kubernetes %d in project %s with id %d not found, removing from state", agentID, project, tokenID) | ||
d.SetId("") | ||
return nil | ||
} | ||
return diag.FromErr(err) | ||
} | ||
|
||
stateMap := gitlabClusterAgentTokenToStateMap(project, clusterAgentToken) | ||
if err = setStateMapInResourceData(stateMap, d); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
return nil | ||
} | ||
|
||
func resourceGitlabClusterAgentTokenDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
client := meta.(*gitlab.Client) | ||
project, agentID, tokenID, err := resourceGitlabClusterAgentTokenParseID(d.Id()) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
log.Printf("[DEBUG] delete token for GitLab Agent for Kubernetes %d in project %s with id %d", agentID, project, tokenID) | ||
if _, err := client.ClusterAgents.RevokeAgentToken(project, agentID, tokenID, gitlab.WithContext(ctx)); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceGitlabClusterAgentTokenBuildID(project string, agentID int, tokenID int) string { | ||
return fmt.Sprintf("%s:%d:%d", project, agentID, tokenID) | ||
} | ||
|
||
func resourceGitlabClusterAgentTokenParseID(id string) (string, int, int, error) { | ||
parts := strings.Split(id, ":") | ||
if len(parts) != 3 { | ||
return "", 0, 0, fmt.Errorf("invalid cluster agent token id %q, expected format '{project}:{agent_id}:{token_id}", id) | ||
} | ||
project, rawAgentID, rawTokenID := parts[0], parts[1], parts[2] | ||
agentID, err := strconv.Atoi(rawAgentID) | ||
if err != nil { | ||
return "", 0, 0, fmt.Errorf("invalid cluster agent token id %q with 'agent_id' %q, expected integer", id, rawAgentID) | ||
} | ||
tokenID, err := strconv.Atoi(rawTokenID) | ||
if err != nil { | ||
return "", 0, 0, fmt.Errorf("invalid cluster agent token id %q with 'token_id' %q, expected integer", id, rawTokenID) | ||
} | ||
|
||
return project, agentID, tokenID, nil | ||
} |
Oops, something went wrong.