From 683696a756ebd9edd9df2eb86788d3f3818c7e18 Mon Sep 17 00:00:00 2001 From: Petar Nikolovski Date: Tue, 24 Oct 2023 19:46:11 +0000 Subject: [PATCH] Add repository webhook resource (#28) Co-authored-by: techknowlogick Reviewed-on: https://gitea.com/gitea/terraform-provider-gitea/pulls/28 Reviewed-by: techknowlogick Co-authored-by: Petar Nikolovski Co-committed-by: Petar Nikolovski --- .gitignore | 3 +- README.md | 3 +- docs/data-sources/org.md | 2 - docs/data-sources/repo.md | 2 - docs/data-sources/user.md | 2 - docs/resources/fork.md | 2 - docs/resources/git_hook.md | 2 - docs/resources/oauth2_app.md | 2 - docs/resources/org.md | 2 - docs/resources/public_key.md | 2 - docs/resources/repository.md | 2 - docs/resources/repository_key.md | 2 - docs/resources/repository_webhook.md | 36 +++ docs/resources/team.md | 2 - docs/resources/token.md | 2 - docs/resources/user.md | 2 - gitea/provider.go | 19 +- gitea/resource_gitea_repository_webhook.go | 241 +++++++++++++++++++++ 18 files changed, 290 insertions(+), 38 deletions(-) create mode 100644 docs/resources/repository_webhook.md create mode 100644 gitea/resource_gitea_repository_webhook.go diff --git a/.gitignore b/.gitignore index 8762fee..19e0518 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .vscode -dist/ \ No newline at end of file +.idea/ +dist/ diff --git a/README.md b/README.md index 34a4ec5..9d013d3 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ terraform { required_providers { gitea = { source = "go-gitea/gitea" - version = "0.2.0" + version = "0.3.0" } } } @@ -71,4 +71,3 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file ## History This codebase was created at https://gitea.com/gitea/terraform-provider-gitea, was forked by @lerentis, and then their changes were merged back into the original repo. Thank you to everyone who contributed! - diff --git a/docs/data-sources/org.md b/docs/data-sources/org.md index 2741619..298b6ff 100644 --- a/docs/data-sources/org.md +++ b/docs/data-sources/org.md @@ -28,5 +28,3 @@ description: |- - `location` (String) - `visibility` (String) - `website` (String) - - diff --git a/docs/data-sources/repo.md b/docs/data-sources/repo.md index 0bbe6c6..77b942f 100644 --- a/docs/data-sources/repo.md +++ b/docs/data-sources/repo.md @@ -43,5 +43,3 @@ description: |- - `updated` (String) - `watchers` (Number) - `website` (String) - - diff --git a/docs/data-sources/user.md b/docs/data-sources/user.md index b86c466..d2578d6 100644 --- a/docs/data-sources/user.md +++ b/docs/data-sources/user.md @@ -29,5 +29,3 @@ description: |- - `is_admin` (Boolean) - `language` (String) - `last_login` (String) - - diff --git a/docs/resources/fork.md b/docs/resources/fork.md index 6733ea7..ba10ccf 100644 --- a/docs/resources/fork.md +++ b/docs/resources/fork.md @@ -57,5 +57,3 @@ resource "gitea_fork" "org2_fork_of_repo1_in_org1" { ### Read-Only - `id` (String) The ID of this resource. - - diff --git a/docs/resources/git_hook.md b/docs/resources/git_hook.md index ba12e1e..a97f403 100644 --- a/docs/resources/git_hook.md +++ b/docs/resources/git_hook.md @@ -51,5 +51,3 @@ resource "gitea_git_hook" "org_repo_post_receive" { ### Read-Only - `id` (String) The ID of this resource. - - diff --git a/docs/resources/oauth2_app.md b/docs/resources/oauth2_app.md index 24b6d36..8bebfe7 100644 --- a/docs/resources/oauth2_app.md +++ b/docs/resources/oauth2_app.md @@ -29,5 +29,3 @@ Handling [gitea oauth application](https://docs.gitea.io/en-us/oauth2-provider/) - `client_id` (String) OAuth2 Application client id - `client_secret` (String, Sensitive) Oauth2 Application client secret - `id` (String) The ID of this resource. - - diff --git a/docs/resources/org.md b/docs/resources/org.md index f646213..02fe21c 100644 --- a/docs/resources/org.md +++ b/docs/resources/org.md @@ -47,5 +47,3 @@ resource "gitea_repository" "org_repo" { - `avatar_url` (String) - `id` (String) The ID of this resource. - `repos` (List of String) List of all Repositories that are part of this organisation - - diff --git a/docs/resources/public_key.md b/docs/resources/public_key.md index aba61fc..2839151 100644 --- a/docs/resources/public_key.md +++ b/docs/resources/public_key.md @@ -48,5 +48,3 @@ resource "gitea_public_key" "test_user_key" { - `fingerprint` (String) - `id` (String) The ID of this resource. - `type` (String) - - diff --git a/docs/resources/repository.md b/docs/resources/repository.md index 6225540..a2f99c5 100644 --- a/docs/resources/repository.md +++ b/docs/resources/repository.md @@ -111,5 +111,3 @@ Need to exist in the gitea instance - `permission_push` (Boolean) - `ssh_url` (String) - `updated` (String) - - diff --git a/docs/resources/repository_key.md b/docs/resources/repository_key.md index aef33dd..5449251 100644 --- a/docs/resources/repository_key.md +++ b/docs/resources/repository_key.md @@ -59,5 +59,3 @@ resource "gitea_repository_key" "example" { ### Read-Only - `id` (String) The ID of this resource. - - diff --git a/docs/resources/repository_webhook.md b/docs/resources/repository_webhook.md new file mode 100644 index 0000000..e165262 --- /dev/null +++ b/docs/resources/repository_webhook.md @@ -0,0 +1,36 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "gitea_repository_webhook Resource - terraform-provider-gitea" +subcategory: "" +description: |- + This resource allows you to create and manage webhooks for repositories. +--- + +# gitea_repository_webhook (Resource) + +This resource allows you to create and manage webhooks for repositories. + + + + +## Schema + +### Required + +- `active` (Boolean) Set webhook to active, e.g. `true` +- `branch_filter` (String) Set branch filter on the webhook, e.g. `"*"` +- `content_type` (String) The content type of the payload. It can be `json`, or `form` +- `events` (List of String) A list of events that will trigger the webhool, e.g. `["push"]` +- `name` (String) Repository name +- `type` (String) Webhook type, e.g. `gitea` +- `url` (String) Target URL of the webhook +- `username` (String) User name or organization name + +### Optional + +- `secret` (String) Webhook secret + +### Read-Only + +- `created_at` (String) Webhook creation timestamp +- `id` (String) The ID of this resource. diff --git a/docs/resources/team.md b/docs/resources/team.md index 9d891d2..3d1eef9 100644 --- a/docs/resources/team.md +++ b/docs/resources/team.md @@ -79,5 +79,3 @@ Can be `repo.code`, `repo.issues`, `repo.ext_issues`, `repo.wiki`, `repo.pulls`, ### Read-Only - `id` (String) The ID of this resource. - - diff --git a/docs/resources/token.md b/docs/resources/token.md index 5e9a18e..f583739 100644 --- a/docs/resources/token.md +++ b/docs/resources/token.md @@ -63,5 +63,3 @@ output "token" { - `id` (String) The ID of this resource. - `last_eight` (String) - `token` (String, Sensitive) The actual Access Token - - diff --git a/docs/resources/user.md b/docs/resources/user.md index a992c95..a3cdb88 100644 --- a/docs/resources/user.md +++ b/docs/resources/user.md @@ -56,5 +56,3 @@ resource "gitea_user" "test" { ### Read-Only - `id` (String) The ID of this resource. - - diff --git a/gitea/provider.go b/gitea/provider.go index be7b500..6a16ca6 100644 --- a/gitea/provider.go +++ b/gitea/provider.go @@ -75,15 +75,16 @@ func Provider() *schema.Provider { "gitea_org": resourceGiteaOrg(), // "gitea_team": resourceGiteaTeam(), // "gitea_repo": resourceGiteaRepo(), - "gitea_user": resourceGiteaUser(), - "gitea_oauth2_app": resourceGiteaOauthApp(), - "gitea_repository": resourceGiteaRepository(), - "gitea_fork": resourceGiteaFork(), - "gitea_public_key": resourceGiteaPublicKey(), - "gitea_team": resourceGiteaTeam(), - "gitea_git_hook": resourceGiteaGitHook(), - "gitea_token": resourceGiteaToken(), - "gitea_repository_key": resourceGiteaRepositoryKey(), + "gitea_user": resourceGiteaUser(), + "gitea_oauth2_app": resourceGiteaOauthApp(), + "gitea_repository": resourceGiteaRepository(), + "gitea_fork": resourceGiteaFork(), + "gitea_public_key": resourceGiteaPublicKey(), + "gitea_team": resourceGiteaTeam(), + "gitea_git_hook": resourceGiteaGitHook(), + "gitea_token": resourceGiteaToken(), + "gitea_repository_key": resourceGiteaRepositoryKey(), + "gitea_repository_webhook": resourceGiteaRepositoryWebhook(), }, ConfigureFunc: providerConfigure, diff --git a/gitea/resource_gitea_repository_webhook.go b/gitea/resource_gitea_repository_webhook.go new file mode 100644 index 0000000..2d16dee --- /dev/null +++ b/gitea/resource_gitea_repository_webhook.go @@ -0,0 +1,241 @@ +package gitea + +import ( + "code.gitea.io/sdk/gitea" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "strconv" +) + +const ( + repoWebhookUsername string = "username" + repoWebhookName string = "name" + repoWebhookType string = "type" + repoWebhookUrl string = "url" + repoWebhookContentType string = "content_type" + repoWebhookSecret string = "secret" + repoWebhookEvents string = "events" + repoWebhookBranchFilter string = "branch_filter" + repoWebhookActive string = "active" + repoWebhookCreatedAt string = "created_at" +) + +func resourceRepositoryWebhookRead(d *schema.ResourceData, meta interface{}) (err error) { + client := meta.(*gitea.Client) + + id, err := strconv.ParseInt(d.Id(), 10, 64) + if err != nil { + return err + } + + user := d.Get(repoWebhookUsername).(string) + repo := d.Get(repoWebhookName).(string) + + hook, resp, err := client.GetRepoHook(user, repo, id) + if err != nil { + if resp.StatusCode == 404 { + d.SetId("") + return + } else { + return err + } + } + + err = setRepositoryWebhookData(hook, d) + + return +} + +func resourceRepositoryWebhookCreate(d *schema.ResourceData, meta interface{}) (err error) { + client := meta.(*gitea.Client) + + user := d.Get(repoWebhookUsername).(string) + repo := d.Get(repoWebhookName).(string) + + config := map[string]string{ + "url": d.Get(repoWebhookUrl).(string), + "content_type": d.Get(repoWebhookContentType).(string), + } + + secret := d.Get(repoWebhookSecret).(string) + if secret != "" { + config["secret"] = secret + } + + events := make([]string, 0) + for _, element := range d.Get(repoWebhookEvents).([]interface{}) { + events = append(events, element.(string)) + } + + hookOption := gitea.CreateHookOption{ + Type: gitea.HookType(d.Get(repoWebhookType).(string)), + Config: config, + Events: events, + BranchFilter: d.Get(repoWebhookBranchFilter).(string), + Active: d.Get(repoWebhookActive).(bool), + } + + hook, _, err := client.CreateRepoHook(user, repo, hookOption) + if err != nil { + return err + } + + err = setRepositoryWebhookData(hook, d) + + return +} + +func resourceRepositoryWebhookUpdate(d *schema.ResourceData, meta interface{}) (err error) { + client := meta.(*gitea.Client) + + user := d.Get(repoWebhookUsername).(string) + repo := d.Get(repoWebhookName).(string) + id, err := strconv.ParseInt(d.Id(), 10, 64) + if err != nil { + return err + } + + config := map[string]string{ + "url": d.Get(repoWebhookUrl).(string), + "content_type": d.Get(repoWebhookContentType).(string), + } + + secret := d.Get(repoWebhookSecret).(string) + if secret != "" { + config["secret"] = secret + } + + events := make([]string, 0) + for _, element := range d.Get(repoWebhookEvents).([]interface{}) { + events = append(events, element.(string)) + } + + active := d.Get(repoWebhookActive).(bool) + + hookOption := gitea.EditHookOption{ + Config: config, + Events: events, + BranchFilter: d.Get(repoWebhookBranchFilter).(string), + Active: &active, + } + + _, err = client.EditRepoHook(user, repo, id, hookOption) + if err != nil { + return err + } + + hook, _, err := client.GetRepoHook(user, repo, id) + if err != nil { + return err + } + + err = setRepositoryWebhookData(hook, d) + + return +} + +func resourceRepositoryWebhookDelete(d *schema.ResourceData, meta interface{}) (err error) { + client := meta.(*gitea.Client) + + user := d.Get(repoWebhookUsername).(string) + repo := d.Get(repoWebhookName).(string) + id, err := strconv.ParseInt(d.Id(), 10, 64) + if err != nil { + return err + } + + _, err = client.DeleteRepoHook(user, repo, id) + if err != nil { + return err + } + + return +} + +func setRepositoryWebhookData(hook *gitea.Hook, d *schema.ResourceData) (err error) { + d.SetId(strconv.FormatInt(hook.ID, 10)) + + d.Set(repoWebhookUsername, d.Get(repoWebhookUsername).(string)) + d.Set(repoWebhookName, d.Get(repoWebhookName).(string)) + d.Set(repoWebhookType, d.Get(repoWebhookType).(string)) + d.Set(repoWebhookUrl, d.Get(repoWebhookUrl).(string)) + d.Set(repoWebhookContentType, d.Get(repoWebhookContentType).(string)) + + secret := d.Get(repoWebhookSecret).(string) + if secret != "" { + d.Set(repoWebhookSecret, secret) + } + + d.Set(repoWebhookEvents, d.Get(repoWebhookEvents)) + d.Set(repoWebhookBranchFilter, d.Get(repoWebhookBranchFilter).(string)) + d.Set(repoWebhookActive, d.Get(repoWebhookActive).(bool)) + d.Set(repoWebhookCreatedAt, hook.Created) + + return +} + +func resourceGiteaRepositoryWebhook() *schema.Resource { + return &schema.Resource{ + Read: resourceRepositoryWebhookRead, + Create: resourceRepositoryWebhookCreate, + Update: resourceRepositoryWebhookUpdate, + Delete: resourceRepositoryWebhookDelete, + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "User name or organization name", + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Repository name", + }, + "type": { + Type: schema.TypeString, + Required: true, + Description: "Webhook type, e.g. `gitea`", + }, + "url": { + Type: schema.TypeString, + Required: true, + Description: "Target URL of the webhook", + }, + "content_type": { + Type: schema.TypeString, + Required: true, + Description: "The content type of the payload. It can be `json`, or `form`", + }, + "secret": { + Type: schema.TypeString, + Optional: true, + Description: "Webhook secret", + }, + "events": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Required: true, + Description: "A list of events that will trigger the webhool, e.g. `[\"push\"]`", + }, + "branch_filter": { + Type: schema.TypeString, + Required: true, + Description: "Set branch filter on the webhook, e.g. `\"*\"`", + }, + "active": { + Type: schema.TypeBool, + Required: true, + Description: "Set webhook to active, e.g. `true`", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Webhook creation timestamp", + }, + }, + Description: "This resource allows you to create and manage webhooks for repositories.", + } +}