From c72fcb3a49cdc2d64e17d4b1361d010efb3f9f7c Mon Sep 17 00:00:00 2001 From: Tobias Trabelsi Date: Sun, 16 Oct 2022 16:55:07 +0200 Subject: [PATCH] Added gitea_token resource --- Makefile | 2 +- README.md | 2 +- docs/index.md | 2 +- docs/resources/token.md | 67 +++++++++ examples/main.tf | 10 ++ examples/provider.tf | 6 +- examples/provider/provider.tf | 2 +- examples/resources/gitea_token/resource.tf | 25 ++++ examples/variables.tf | 4 + gitea/provider.go | 1 + gitea/resource_gitea_token.go | 151 +++++++++++++++++++++ 11 files changed, 266 insertions(+), 6 deletions(-) create mode 100644 docs/resources/token.md create mode 100644 examples/resources/gitea_token/resource.tf create mode 100644 gitea/resource_gitea_token.go diff --git a/Makefile b/Makefile index c867723..9604ce0 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor) GOFMT ?= gofmt -s -VERSION = 0.9.0 +VERSION = 0.10.0 test: fmt-check go test -i $(TEST) || exit 1 diff --git a/README.md b/README.md index 8ab4365..9b3b6eb 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ terraform { required_providers { gitea = { source = "Lerentis/gitea" - version = "0.9.0" + version = "0.10.0" } } } diff --git a/docs/index.md b/docs/index.md index a6219b6..42fe556 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,7 +17,7 @@ terraform { required_providers { gitea = { source = "Lerentis/gitea" - version = "0.9.0" + version = "0.10.0" } } } diff --git a/docs/resources/token.md b/docs/resources/token.md new file mode 100644 index 0000000..5e9a18e --- /dev/null +++ b/docs/resources/token.md @@ -0,0 +1,67 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "gitea_token Resource - terraform-provider-gitea" +subcategory: "" +description: |- + gitea_token manages gitea Access Tokens. + Due to upstream limitations (see https://gitea.com/gitea/go-sdk/issues/610) this resource + can only be used with username/password provider configuration. + WARNING: + Tokens will be stored in the terraform state! +--- + +# gitea_token (Resource) + +`gitea_token` manages gitea Access Tokens. + +Due to upstream limitations (see https://gitea.com/gitea/go-sdk/issues/610) this resource +can only be used with username/password provider configuration. + +WARNING: +Tokens will be stored in the terraform state! + +## Example Usage + +```terraform +provider "gitea" { + base_url = var.gitea_url + # Token Auth can not be used with this resource + username = var.gitea_username + password = var.gitea_password +} + +resource "gitea_user" "test" { + username = "test" + login_name = "test" + password = "Geheim1!" + email = "test@user.dev" + must_change_password = false + admin = true +} + +resource "gitea_token" "test_token" { + username = resource.gitea_user.test.username + name = "test-token" +} + +output "token" { + value = resource.gitea_token.test_token.token + sensitive = true +} +``` + + +## Schema + +### Required + +- `name` (String) The name of the Access Token +- `username` (String) The owner of the Access Token + +### Read-Only + +- `id` (String) The ID of this resource. +- `last_eight` (String) +- `token` (String, Sensitive) The actual Access Token + + diff --git a/examples/main.tf b/examples/main.tf index 2568532..2cefae2 100644 --- a/examples/main.tf +++ b/examples/main.tf @@ -94,4 +94,14 @@ resource "gitea_fork" "org2_fork_of_repo1_in_org1" { owner = gitea_org.org1.name repo = gitea_repository.repo1_in_org1.name organization = gitea_org.org2.name +} + +resource "gitea_token" "test_token" { + username = data.gitea_user.me.username + name = "test-token" +} + +output "token" { + value = resource.gitea_token.test_token.token + sensitive = true } \ No newline at end of file diff --git a/examples/provider.tf b/examples/provider.tf index 9f5f45f..85e1707 100644 --- a/examples/provider.tf +++ b/examples/provider.tf @@ -2,12 +2,14 @@ terraform { required_providers { gitea = { source = "terraform.local/lerentis/gitea" - version = "0.9.0" + version = "0.10.0" } } } provider "gitea" { base_url = var.gitea_url - token = var.gitea_token + username = "lerentis" + password = var.gitea_password + #token = var.gitea_token } \ No newline at end of file diff --git a/examples/provider/provider.tf b/examples/provider/provider.tf index 997533b..c14558b 100644 --- a/examples/provider/provider.tf +++ b/examples/provider/provider.tf @@ -2,7 +2,7 @@ terraform { required_providers { gitea = { source = "Lerentis/gitea" - version = "0.9.0" + version = "0.10.0" } } } diff --git a/examples/resources/gitea_token/resource.tf b/examples/resources/gitea_token/resource.tf new file mode 100644 index 0000000..a6707fe --- /dev/null +++ b/examples/resources/gitea_token/resource.tf @@ -0,0 +1,25 @@ +provider "gitea" { + base_url = var.gitea_url + # Token Auth can not be used with this resource + username = var.gitea_username + password = var.gitea_password +} + +resource "gitea_user" "test" { + username = "test" + login_name = "test" + password = "Geheim1!" + email = "test@user.dev" + must_change_password = false + admin = true +} + +resource "gitea_token" "test_token" { + username = resource.gitea_user.test.username + name = "test-token" +} + +output "token" { + value = resource.gitea_token.test_token.token + sensitive = true +} diff --git a/examples/variables.tf b/examples/variables.tf index dd063c7..53e6515 100644 --- a/examples/variables.tf +++ b/examples/variables.tf @@ -8,4 +8,8 @@ variable "gitea_token" { variable "gitea_mirror_token" { +} + +variable "gitea_password" { + } \ No newline at end of file diff --git a/gitea/provider.go b/gitea/provider.go index d6ec8e2..b8c59d3 100644 --- a/gitea/provider.go +++ b/gitea/provider.go @@ -82,6 +82,7 @@ func Provider() *schema.Provider { "gitea_public_key": resourceGiteaPublicKey(), "gitea_team": resourceGiteaTeam(), "gitea_git_hook": resourceGiteaGitHook(), + "gitea_token": resourceGiteaToken(), }, ConfigureFunc: providerConfigure, diff --git a/gitea/resource_gitea_token.go b/gitea/resource_gitea_token.go new file mode 100644 index 0000000..230e6dd --- /dev/null +++ b/gitea/resource_gitea_token.go @@ -0,0 +1,151 @@ +package gitea + +import ( + "fmt" + "strconv" + + "code.gitea.io/sdk/gitea" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +const ( + TokenUsername string = "username" + TokenName string = "name" + TokenHash string = "token" + TokenLastEight string = "last_eight" +) + +func searchTokenById(c *gitea.Client, id int64) (res *gitea.AccessToken, err error) { + page := 1 + + for { + tokens, _, err := c.ListAccessTokens(gitea.ListAccessTokensOptions{ + ListOptions: gitea.ListOptions{ + Page: page, + PageSize: 50, + }, + }) + if err != nil { + return nil, err + } + + if len(tokens) == 0 { + return nil, fmt.Errorf("Token with ID %d could not be found", id) + } + + for _, token := range tokens { + if token.ID == id { + return token, nil + } + } + + page += 1 + } +} + +func resourceTokenCreate(d *schema.ResourceData, meta interface{}) (err error) { + + client := meta.(*gitea.Client) + + var opt gitea.CreateAccessTokenOption + opt.Name = d.Get(TokenName).(string) + + token, _, err := client.CreateAccessToken(opt) + + if err != nil { + return err + } + + err = setTokenResourceData(token, d) + + return +} + +func resourceTokenRead(d *schema.ResourceData, meta interface{}) (err error) { + + client := meta.(*gitea.Client) + + var token *gitea.AccessToken + + id, err := strconv.ParseInt(d.Id(), 10, 64) + + token, err = searchTokenById(client, id) + + if err != nil { + return err + } + + err = setTokenResourceData(token, d) + + return +} + +func resourceTokenDelete(d *schema.ResourceData, meta interface{}) (err error) { + + client := meta.(*gitea.Client) + var resp *gitea.Response + + resp, err = client.DeleteAccessToken(d.Get(TokenName).(string)) + + if err != nil { + if resp.StatusCode == 404 { + return + } else { + return err + } + } + + return +} + +func setTokenResourceData(token *gitea.AccessToken, d *schema.ResourceData) (err error) { + + d.SetId(fmt.Sprintf("%d", token.ID)) + d.Set(TokenName, token.Name) + if token.Token != "" { + d.Set(TokenHash, token.Token) + } + d.Set(TokenLastEight, token.TokenLastEight) + + return +} + +func resourceGiteaToken() *schema.Resource { + return &schema.Resource{ + Read: resourceTokenRead, + Create: resourceTokenCreate, + Delete: resourceTokenDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The owner of the Access Token", + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The name of the Access Token", + }, + "token": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + Description: "The actual Access Token", + }, + "last_eight": { + Type: schema.TypeString, + Computed: true, + }, + }, + Description: "`gitea_token` manages gitea Access Tokens.\n\n" + + "Due to upstream limitations (see https://gitea.com/gitea/go-sdk/issues/610) this resource\n" + + "can only be used with username/password provider configuration.\n\n" + + "WARNING:\n" + + "Tokens will be stored in the terraform state!", + } +}