Skip to content

Commit 519086b

Browse files
committed
New Resource gitlab_system_hook
Closes #180
1 parent c663d29 commit 519086b

File tree

5 files changed

+378
-0
lines changed

5 files changed

+378
-0
lines changed

docs/resources/system_hook.md

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "gitlab_system_hook Resource - terraform-provider-gitlab"
4+
subcategory: ""
5+
description: |-
6+
The gitlab_system_hook resource allows to manage the lifecycle of a system hook.
7+
-> This resource requires GitLab 14.9
8+
Upstream API: GitLab REST API docs https://docs.gitlab.com/ee/api/system_hooks.html
9+
---
10+
11+
# gitlab_system_hook (Resource)
12+
13+
The `gitlab_system_hook` resource allows to manage the lifecycle of a system hook.
14+
15+
-> This resource requires GitLab 14.9
16+
17+
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/system_hooks.html)
18+
19+
## Example Usage
20+
21+
```terraform
22+
resource "gitlab_system_hook" "example" {
23+
url = "https://example.com/hook-%d"
24+
token = "secret-token"
25+
push_events = true
26+
tag_push_events = true
27+
merge_requests_events = true
28+
repository_update_events = true
29+
enable_ssl_verification = true
30+
}
31+
```
32+
33+
<!-- schema generated by tfplugindocs -->
34+
## Schema
35+
36+
### Required
37+
38+
- `url` (String) The hook URL.
39+
40+
### Optional
41+
42+
- `enable_ssl_verification` (Boolean) Do SSL verification when triggering the hook.
43+
- `id` (String) The ID of this resource.
44+
- `merge_requests_events` (Boolean) Trigger hook on merge requests events.
45+
- `push_events` (Boolean) When true, the hook fires on push events.
46+
- `repository_update_events` (Boolean) Trigger hook on repository update events.
47+
- `tag_push_events` (Boolean) When true, the hook fires on new tags being pushed.
48+
- `token` (String, Sensitive) Secret token to validate received payloads; this isn’t returned in the response. This attribute is not available for imported resources.
49+
50+
### Read-Only
51+
52+
- `created_at` (String) The date and time the hook was created in ISO8601 format.
53+
54+
## Import
55+
56+
Import is supported using the following syntax:
57+
58+
```shell
59+
# You can import a system hook using the hook id `{hook-id}`, e.g.
60+
terraform import gitlab_system_hook.example 42
61+
# NOTE: the `token` attribute won't be available for imported resources.
62+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# You can import a system hook using the hook id `{hook-id}`, e.g.
2+
terraform import gitlab_system_hook.example 42
3+
# NOTE: the `token` attribute won't be available for imported resources.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
resource "gitlab_system_hook" "example" {
2+
url = "https://example.com/hook-%d"
3+
token = "secret-token"
4+
push_events = true
5+
tag_push_events = true
6+
merge_requests_events = true
7+
repository_update_events = true
8+
enable_ssl_verification = true
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
"strconv"
8+
"time"
9+
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
gitlab "github.com/xanzy/go-gitlab"
13+
)
14+
15+
var _ = registerResource("gitlab_system_hook", func() *schema.Resource {
16+
return &schema.Resource{
17+
Description: `The ` + "`gitlab_system_hook`" + ` resource allows to manage the lifecycle of a system hook.
18+
19+
-> This resource requires GitLab 14.9
20+
21+
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/system_hooks.html)`,
22+
23+
CreateContext: resourceGitlabSystemHookCreate,
24+
ReadContext: resourceGitlabSystemHookRead,
25+
DeleteContext: resourceGitlabSystemHookDelete,
26+
Importer: &schema.ResourceImporter{
27+
StateContext: schema.ImportStatePassthroughContext,
28+
},
29+
30+
Schema: map[string]*schema.Schema{
31+
"url": {
32+
Description: "The hook URL.",
33+
Type: schema.TypeString,
34+
Required: true,
35+
ForceNew: true,
36+
},
37+
"token": {
38+
Description: "Secret token to validate received payloads; this isn’t returned in the response. This attribute is not available for imported resources.",
39+
Type: schema.TypeString,
40+
Optional: true,
41+
Sensitive: true,
42+
ForceNew: true,
43+
},
44+
"push_events": {
45+
Description: "When true, the hook fires on push events.",
46+
Type: schema.TypeBool,
47+
Optional: true,
48+
ForceNew: true,
49+
},
50+
"tag_push_events": {
51+
Description: "When true, the hook fires on new tags being pushed.",
52+
Type: schema.TypeBool,
53+
Optional: true,
54+
ForceNew: true,
55+
},
56+
"merge_requests_events": {
57+
Description: "Trigger hook on merge requests events.",
58+
Type: schema.TypeBool,
59+
Optional: true,
60+
ForceNew: true,
61+
},
62+
"repository_update_events": {
63+
Description: "Trigger hook on repository update events.",
64+
Type: schema.TypeBool,
65+
Optional: true,
66+
ForceNew: true,
67+
},
68+
"enable_ssl_verification": {
69+
Description: "Do SSL verification when triggering the hook.",
70+
Type: schema.TypeBool,
71+
Optional: true,
72+
ForceNew: true,
73+
},
74+
"created_at": {
75+
Description: "The date and time the hook was created in ISO8601 format.",
76+
Type: schema.TypeString,
77+
Computed: true,
78+
},
79+
},
80+
}
81+
})
82+
83+
func resourceGitlabSystemHookCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
84+
client := meta.(*gitlab.Client)
85+
86+
options := &gitlab.AddHookOptions{
87+
URL: gitlab.String(d.Get("url").(string)),
88+
}
89+
// NOTE: `GetOkExists()` is deprecated, but until there is a replacement we need to use it.
90+
// see https://github.com/hashicorp/terraform-plugin-sdk/pull/350#issuecomment-597888969
91+
92+
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
93+
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
94+
if v, ok := d.GetOkExists("token"); ok {
95+
options.Token = gitlab.String(v.(string))
96+
}
97+
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
98+
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
99+
if v, ok := d.GetOkExists("push_events"); ok {
100+
options.PushEvents = gitlab.Bool(v.(bool))
101+
}
102+
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
103+
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
104+
if v, ok := d.GetOkExists("tag_push_events"); ok {
105+
options.TagPushEvents = gitlab.Bool(v.(bool))
106+
}
107+
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
108+
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
109+
if v, ok := d.GetOkExists("merge_requests_events"); ok {
110+
options.MergeRequestsEvents = gitlab.Bool(v.(bool))
111+
}
112+
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
113+
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
114+
if v, ok := d.GetOkExists("repository_update_events"); ok {
115+
options.RepositoryUpdateEvents = gitlab.Bool(v.(bool))
116+
}
117+
// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
118+
// lintignore: XR001 // TODO: replace with alternative for GetOkExists
119+
if v, ok := d.GetOkExists("enable_ssl_verification"); ok {
120+
options.EnableSSLVerification = gitlab.Bool(v.(bool))
121+
}
122+
123+
log.Printf("[DEBUG] create gitlab system hook %q", *options.URL)
124+
125+
hook, _, err := client.SystemHooks.AddHook(options, gitlab.WithContext(ctx))
126+
if err != nil {
127+
return diag.FromErr(err)
128+
}
129+
130+
d.SetId(fmt.Sprintf("%d", hook.ID))
131+
d.Set("token", options.Token)
132+
return resourceGitlabSystemHookRead(ctx, d, meta)
133+
}
134+
135+
func resourceGitlabSystemHookRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
136+
client := meta.(*gitlab.Client)
137+
hookID, err := strconv.Atoi(d.Id())
138+
if err != nil {
139+
return diag.FromErr(err)
140+
}
141+
log.Printf("[DEBUG] read gitlab system hook %d", hookID)
142+
143+
hook, _, err := client.SystemHooks.GetHook(hookID, gitlab.WithContext(ctx))
144+
if err != nil {
145+
if is404(err) {
146+
log.Printf("[DEBUG] gitlab system hook not found %d, removing from state", hookID)
147+
d.SetId("")
148+
return nil
149+
}
150+
return diag.FromErr(err)
151+
}
152+
153+
d.Set("url", hook.URL)
154+
d.Set("push_events", hook.PushEvents)
155+
d.Set("tag_push_events", hook.TagPushEvents)
156+
d.Set("merge_requests_events", hook.MergeRequestsEvents)
157+
d.Set("repository_update_events", hook.RepositoryUpdateEvents)
158+
d.Set("enable_ssl_verification", hook.EnableSSLVerification)
159+
d.Set("created_at", hook.CreatedAt.Format(time.RFC3339))
160+
return nil
161+
}
162+
163+
func resourceGitlabSystemHookDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
164+
client := meta.(*gitlab.Client)
165+
hookID, err := strconv.Atoi(d.Id())
166+
if err != nil {
167+
return diag.FromErr(err)
168+
}
169+
log.Printf("[DEBUG] Delete gitlab system hook %s", d.Id())
170+
171+
_, err = client.SystemHooks.DeleteHook(hookID, gitlab.WithContext(ctx))
172+
if err != nil {
173+
return diag.FromErr(err)
174+
}
175+
176+
return nil
177+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package provider
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
11+
"github.com/xanzy/go-gitlab"
12+
)
13+
14+
func TestAccGitlabSystemHook_basic(t *testing.T) {
15+
var hook gitlab.Hook
16+
rInt := acctest.RandInt()
17+
18+
resource.Test(t, resource.TestCase{
19+
PreCheck: func() { testAccPreCheck(t) },
20+
ProviderFactories: providerFactories,
21+
CheckDestroy: testAccCheckGitlabSystemHookDestroy,
22+
Steps: []resource.TestStep{
23+
// Create a hook with all options
24+
{
25+
Config: testAccGitlabSystemHookConfig(rInt),
26+
Check: resource.ComposeTestCheckFunc(
27+
testAccCheckGitlabSystemHookExists("gitlab_system_hook.this", &hook),
28+
resource.TestCheckResourceAttrSet("gitlab_system_hook.this", "created_at"),
29+
),
30+
},
31+
// Verify import
32+
{
33+
ResourceName: "gitlab_system_hook.this",
34+
ImportState: true,
35+
ImportStateVerify: true,
36+
ImportStateVerifyIgnore: []string{"token"},
37+
},
38+
// Update the hook to toggle all the values to their inverse
39+
{
40+
Config: testAccGitlabSystemHookUpdateConfig(rInt),
41+
Check: resource.ComposeTestCheckFunc(
42+
testAccCheckGitlabSystemHookExists("gitlab_system_hook.this", &hook),
43+
),
44+
},
45+
// Verify import
46+
{
47+
ResourceName: "gitlab_system_hook.this",
48+
ImportState: true,
49+
ImportStateVerify: true,
50+
ImportStateVerifyIgnore: []string{"token"},
51+
},
52+
},
53+
})
54+
}
55+
56+
func testAccCheckGitlabSystemHookExists(n string, hook *gitlab.Hook) resource.TestCheckFunc {
57+
return func(s *terraform.State) error {
58+
rs, ok := s.RootModule().Resources[n]
59+
if !ok {
60+
return fmt.Errorf("Not Found: %s", n)
61+
}
62+
63+
hookID, err := strconv.Atoi(rs.Primary.ID)
64+
if err != nil {
65+
return err
66+
}
67+
68+
gotHook, _, err := testGitlabClient.SystemHooks.GetHook(hookID)
69+
if err != nil {
70+
return err
71+
}
72+
*hook = *gotHook
73+
return nil
74+
}
75+
}
76+
77+
func testAccCheckGitlabSystemHookDestroy(s *terraform.State) error {
78+
for _, rs := range s.RootModule().Resources {
79+
if rs.Type != "gitlab_system_hook" {
80+
continue
81+
}
82+
hookID, err := strconv.Atoi(rs.Primary.ID)
83+
if err != nil {
84+
return err
85+
}
86+
87+
gotHook, _, err := testGitlabClient.SystemHooks.GetHook(hookID, nil)
88+
if err == nil {
89+
if gotHook != nil && gotHook.ID == hookID {
90+
return fmt.Errorf("System Hook %d still exists after deletion", hookID)
91+
}
92+
}
93+
if !is404(err) {
94+
return err
95+
}
96+
return nil
97+
}
98+
return nil
99+
}
100+
101+
func testAccGitlabSystemHookConfig(rInt int) string {
102+
return fmt.Sprintf(`
103+
resource "gitlab_system_hook" "this" {
104+
url = "https://example.com/hook-%d"
105+
token = "secret-token"
106+
push_events = true
107+
tag_push_events = true
108+
merge_requests_events = true
109+
repository_update_events = true
110+
enable_ssl_verification = true
111+
}
112+
`, rInt)
113+
}
114+
115+
func testAccGitlabSystemHookUpdateConfig(rInt int) string {
116+
return fmt.Sprintf(`
117+
resource "gitlab_system_hook" "this" {
118+
url = "https://example.com/hook-%d"
119+
token = "another-secret-token"
120+
push_events = false
121+
tag_push_events = false
122+
merge_requests_events = false
123+
repository_update_events = false
124+
enable_ssl_verification = false
125+
}
126+
`, rInt)
127+
}

0 commit comments

Comments
 (0)