From 6cbc7b616bc5b74dbe9e39d02a58dc3aafc20665 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:29:28 +0000 Subject: [PATCH 1/9] maint(deps): bump github.com/hashicorp/terraform-plugin-testing from 1.10.0 to 1.11.0 in the hashicorp group (#579) --- go.mod | 12 ++++++------ go.sum | 28 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/go.mod b/go.mod index 5c895c52..a50e4ab5 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/hashicorp/terraform-plugin-go v0.25.0 github.com/hashicorp/terraform-plugin-mux v0.17.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 - github.com/hashicorp/terraform-plugin-testing v1.10.0 + github.com/hashicorp/terraform-plugin-testing v1.11.0 github.com/joho/godotenv v1.5.1 github.com/stretchr/testify v1.9.0 ) @@ -21,7 +21,7 @@ require ( github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect - golang.org/x/sync v0.8.0 // indirect + golang.org/x/sync v0.9.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect ) @@ -41,7 +41,7 @@ require ( github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/hc-install v0.9.0 // indirect - github.com/hashicorp/hcl/v2 v2.22.0 // indirect + github.com/hashicorp/hcl/v2 v2.23.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.21.0 // indirect github.com/hashicorp/terraform-json v0.23.0 // indirect @@ -63,11 +63,11 @@ require ( github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/zclconf/go-cty v1.15.0 // indirect - golang.org/x/crypto v0.28.0 // indirect + golang.org/x/crypto v0.29.0 // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.20.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.35.1 // indirect diff --git a/go.sum b/go.sum index 2e57862a..feebd85a 100644 --- a/go.sum +++ b/go.sum @@ -71,8 +71,8 @@ github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKe github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hc-install v0.9.0 h1:2dIk8LcvANwtv3QZLckxcjyF5w8KVtiMxu6G6eLhghE= github.com/hashicorp/hc-install v0.9.0/go.mod h1:+6vOP+mf3tuGgMApVYtmsnDoKWMDcFXeTxCACYZ8SFg= -github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M= -github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= +github.com/hashicorp/hcl/v2 v2.23.0 h1:Fphj1/gCylPxHutVSEOf2fBOh1VE4AuLV7+kbJf3qos= +github.com/hashicorp/hcl/v2 v2.23.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/jsonapi v1.3.2-0.20240802183744-2490a9451c3d h1:kIMRkf4AL9Zqjlc8aQD2jWBHWri88ncgERDSeln+Ya8= github.com/hashicorp/jsonapi v1.3.2-0.20240802183744-2490a9451c3d/go.mod h1:kWfdn49yCjQvbpnvY1dxxAuAFzISwrrMDQOcu6NsFoM= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= @@ -93,8 +93,8 @@ github.com/hashicorp/terraform-plugin-mux v0.17.0 h1:/J3vv3Ps2ISkbLPiZOLspFcIZ0v github.com/hashicorp/terraform-plugin-mux v0.17.0/go.mod h1:yWuM9U1Jg8DryNfvCp+lH70WcYv6D8aooQxxxIzFDsE= github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 h1:wyKCCtn6pBBL46c1uIIBNUOWlNfYXfXpVo16iDyLp8Y= github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0/go.mod h1:B0Al8NyYVr8Mp/KLwssKXG1RqnTk7FySqSn4fRuLNgw= -github.com/hashicorp/terraform-plugin-testing v1.10.0 h1:2+tmRNhvnfE4Bs8rB6v58S/VpqzGC6RCh9Y8ujdn+aw= -github.com/hashicorp/terraform-plugin-testing v1.10.0/go.mod h1:iWRW3+loP33WMch2P/TEyCxxct/ZEcCGMquSLSCVsrc= +github.com/hashicorp/terraform-plugin-testing v1.11.0 h1:MeDT5W3YHbONJt2aPQyaBsgQeAIckwPX41EUHXEn29A= +github.com/hashicorp/terraform-plugin-testing v1.11.0/go.mod h1:WNAHQ3DcgV/0J+B15WTE6hDvxcUdkPPpnB1FR3M910U= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= @@ -163,8 +163,8 @@ github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6 github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= @@ -177,8 +177,8 @@ golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -191,19 +191,19 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= +golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= From 6aa970b5d1af55acdecfdf298a58572ef49102c3 Mon Sep 17 00:00:00 2001 From: Brooke Sargent Date: Thu, 21 Nov 2024 12:31:57 -0500 Subject: [PATCH 2/9] feat: webhook payloads templates on honeycombio_webhook_recipient (#580) ## Short description of the changes Expands the honeycombio_webhook_recipient resource to be aware of custom webhook templates. Follow-up PRs will include template variables and custom headers. --------- Co-authored-by: Jason Harley --- CONTRIBUTING.md | 2 +- client/recipient.go | 16 ++ client/recipient_test.go | 51 +++++ docs/resources/webhook_recipient.md | 34 ++- internal/models/recipients.go | 20 +- .../provider/webhook_recipient_resource.go | 195 +++++++++++++++++- .../webhook_recipient_resource_test.go | 127 +++++++++++- 7 files changed, 427 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cd9012f6..7ef3bdbb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,7 +28,7 @@ Any new additions should be built with the Plugin Framework. * The Plugin SDK-based code is contained in the `honeycombio/` directory in the root of the repository. * The Plugin Framework-based code is contained in the `internal/provider` directory. -Any PRs reimplmenting Plugin SDKv2 resources or datasources in the Plugin Framework with be enthusiastically accepted. 🙏 +Any PRs reimplementing Plugin SDKv2 resources or datasources in the Plugin Framework will be enthusiastically accepted. 🙏 ### Preview document changes diff --git a/client/recipient.go b/client/recipient.go index 7d3a06c5..27ee4f4e 100644 --- a/client/recipient.go +++ b/client/recipient.go @@ -66,12 +66,28 @@ type RecipientDetails struct { WebhookURL string `json:"webhook_url,omitempty"` // webhook only WebhookSecret string `json:"webhook_secret,omitempty"` + // custom webhook + WebhookPayloads *WebhookPayloads `json:"webhook_payloads,omitempty"` } type NotificationRecipientDetails struct { PDSeverity PagerDutySeverity `json:"pagerduty_severity,omitempty"` } +type WebhookPayloads struct { + PayloadTemplates PayloadTemplates `json:"payload_templates"` +} + +type PayloadTemplates struct { + Trigger *PayloadTemplate `json:"trigger,omitempty"` + ExhaustionTime *PayloadTemplate `json:"exhaustion_time,omitempty"` + BudgetRate *PayloadTemplate `json:"budget_rate,omitempty"` +} + +type PayloadTemplate struct { + Body string `json:"body"` +} + // RecipientType holds all the possible recipient types. type RecipientType string diff --git a/client/recipient_test.go b/client/recipient_test.go index cce341e7..adde5313 100644 --- a/client/recipient_test.go +++ b/client/recipient_test.go @@ -80,6 +80,57 @@ func TestRecipientsEmail(t *testing.T) { }) } +func TestRecipientsCustomWebhook(t *testing.T) { + t.Parallel() + + ctx := context.Background() + c := newTestClient(t) + + body := `{"hello": "world"}` + + testCases := []struct { + rcpt client.Recipient + expectErr bool + }{ + { + rcpt: client.Recipient{ + Type: client.RecipientTypeWebhook, + Details: client.RecipientDetails{ + WebhookName: test.RandomStringWithPrefix("test.", 10), + WebhookURL: test.RandomURL(), + WebhookSecret: "secret", + WebhookPayloads: &client.WebhookPayloads{ + PayloadTemplates: client.PayloadTemplates{Trigger: &client.PayloadTemplate{Body: body}}}, + }, + }, + }, + } + + for _, tc := range testCases { + tr := tc.rcpt + t.Run(tr.Type.String(), func(t *testing.T) { + r, err := c.Recipients.Create(ctx, &tr) + t.Cleanup(func() { + _ = c.Recipients.Delete(ctx, r.ID) + }) + + if tc.expectErr { + require.Error(t, err, "expected error creating %s recipient", tr.Type) + return + } + require.NoError(t, err, "failed to create %s recipient", tr.Type) + r, err = c.Recipients.Get(ctx, r.ID) + require.NoError(t, err) + + assert.Equal(t, tr.Type, r.Type) + assert.Equal(t, tr.Details.WebhookName, r.Details.WebhookName) + assert.Equal(t, tr.Details.WebhookURL, r.Details.WebhookURL) + assert.Equal(t, tr.Details.WebhookSecret, r.Details.WebhookSecret) + assert.Equal(t, tr.Details.WebhookPayloads, r.Details.WebhookPayloads) + }) + } +} + func TestRecipientsWebhooksandMSTeams(t *testing.T) { t.Parallel() diff --git a/docs/resources/webhook_recipient.md b/docs/resources/webhook_recipient.md index 260c183e..5030c922 100644 --- a/docs/resources/webhook_recipient.md +++ b/docs/resources/webhook_recipient.md @@ -2,7 +2,7 @@ `honeycombio_webhook_recipient` allows you to define and manage a Webhook recipient that can be used by Triggers or BurnAlerts notifications. -## Example Usage +## Standard Webhook Example ```hcl resource "honeycombio_webhook_recipient" "prod" { @@ -12,6 +12,31 @@ resource "honeycombio_webhook_recipient" "prod" { } ``` +## Custom Webhook Example + +```hcl +resource "honeycombio_webhook_recipient" "prod" { + name = "Production Alerts" + secret = "a63dab148496ecbe04a1a802ca9b95b8" + url = "https://my.url.corp.net" + + template { + type = "trigger" + body = < Date: Thu, 21 Nov 2024 17:32:42 -0500 Subject: [PATCH 3/9] fix: webhook recipient test (#582) ## Short description of the changes We're seeing a 500 error that I believe is caused by the update in this test not actually updating the template. CI on this branch didn't cause the same 500 so I'd like to merge it in to avoid spamming ourselves with 500s when this test suite runs. I think there's still more to consider about why this is happening both on the TF side and the API side but this is a bandaid for the noise. --- internal/provider/webhook_recipient_resource_test.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/internal/provider/webhook_recipient_resource_test.go b/internal/provider/webhook_recipient_resource_test.go index 86778806..b80bcb67 100644 --- a/internal/provider/webhook_recipient_resource_test.go +++ b/internal/provider/webhook_recipient_resource_test.go @@ -65,13 +65,19 @@ resource "honeycombio_webhook_recipient" "test" { t.Run("happy path custom webhook", func(t *testing.T) { name := test.RandomStringWithPrefix("test.", 20) url := test.RandomURL() - body := `< Date: Mon, 25 Nov 2024 11:39:05 -0500 Subject: [PATCH 4/9] maint(deps): bump github.com/stretchr/testify from 1.9.0 to 1.10.0 (#584) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.9.0 to 1.10.0.
Release notes

Sourced from github.com/stretchr/testify's releases.

v1.10.0

What's Changed

Functional Changes

Fixes

Documantation, Build & CI

New Contributors

... (truncated)

Commits
  • 89cbdd9 Merge pull request #1626 from arjun-1/fix-functional-options-diff-indirect-calls
  • 07bac60 Merge pull request #1667 from sikehish/flaky
  • 716de8d Increase timeouts in Test_Mock_Called_blocks to reduce flakiness in CI
  • 118fb83 NotSame should fail if args are not pointers #1661 (#1664)
  • 7d99b2b attempt 2
  • 05f87c0 more similar
  • ea7129e better fmt
  • a1b9c9e Merge pull request #1663 from ybrustin/master
  • 8302de9 Merge branch 'master' into master
  • 89352f7 Merge pull request #1518 from hendrywiranto/adjust-readme-remove-v2
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/stretchr/testify&package-manager=go_modules&previous-version=1.9.0&new-version=1.10.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a50e4ab5..b94ecf66 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 github.com/hashicorp/terraform-plugin-testing v1.11.0 github.com/joho/godotenv v1.5.1 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 ) require ( diff --git a/go.sum b/go.sum index feebd85a..da31e18f 100644 --- a/go.sum +++ b/go.sum @@ -145,8 +145,8 @@ github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= From 13413c756949f96e1776f7b2aa8241fcd4645aa9 Mon Sep 17 00:00:00 2001 From: Ronald Date: Mon, 25 Nov 2024 13:38:02 -0500 Subject: [PATCH 5/9] feat(Board, SLO): Bump up max number of SLOs on a board to 24 (#585) ## Short description of the changes - Bump up max number of slos on a board from 6 to 24 to match new UI changes --- honeycombio/resource_board.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/honeycombio/resource_board.go b/honeycombio/resource_board.go index 8677ce25..a686b96b 100644 --- a/honeycombio/resource_board.go +++ b/honeycombio/resource_board.go @@ -148,7 +148,7 @@ See [Graph Settings](https://docs.honeycomb.io/working-with-your-data/graph-sett Type: schema.TypeSet, Optional: true, Description: "An SLO to added to the board.", - MaxItems: 6, + MaxItems: 24, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "id": { From 0266e563ad3f74720fc6190f77d1bf2dc0c248f5 Mon Sep 17 00:00:00 2001 From: Brooke Sargent Date: Tue, 26 Nov 2024 14:56:45 -0500 Subject: [PATCH 6/9] feat: template variables (#583) ## Short description of the changes Support webhook recipient template variables in Terraform --------- Co-authored-by: Jason Harley --- client/recipient.go | 8 +- client/recipient_test.go | 5 +- docs/resources/webhook_recipient.md | 13 + internal/models/recipients.go | 11 + .../provider/webhook_recipient_resource.go | 208 ++++++--- .../webhook_recipient_resource_test.go | 398 +++++++++++++++++- 6 files changed, 586 insertions(+), 57 deletions(-) diff --git a/client/recipient.go b/client/recipient.go index 27ee4f4e..eb4723ef 100644 --- a/client/recipient.go +++ b/client/recipient.go @@ -75,7 +75,8 @@ type NotificationRecipientDetails struct { } type WebhookPayloads struct { - PayloadTemplates PayloadTemplates `json:"payload_templates"` + PayloadTemplates PayloadTemplates `json:"payload_templates"` + TemplateVariables []TemplateVariable `json:"template_variables"` } type PayloadTemplates struct { @@ -88,6 +89,11 @@ type PayloadTemplate struct { Body string `json:"body"` } +type TemplateVariable struct { + Name string `json:"name"` + Default string `json:"default_value"` +} + // RecipientType holds all the possible recipient types. type RecipientType string diff --git a/client/recipient_test.go b/client/recipient_test.go index adde5313..86a5feba 100644 --- a/client/recipient_test.go +++ b/client/recipient_test.go @@ -100,7 +100,9 @@ func TestRecipientsCustomWebhook(t *testing.T) { WebhookURL: test.RandomURL(), WebhookSecret: "secret", WebhookPayloads: &client.WebhookPayloads{ - PayloadTemplates: client.PayloadTemplates{Trigger: &client.PayloadTemplate{Body: body}}}, + PayloadTemplates: client.PayloadTemplates{Trigger: &client.PayloadTemplate{Body: body}}, + TemplateVariables: []client.TemplateVariable{{Name: "severity", Default: "warning"}}, + }, }, }, }, @@ -127,6 +129,7 @@ func TestRecipientsCustomWebhook(t *testing.T) { assert.Equal(t, tr.Details.WebhookURL, r.Details.WebhookURL) assert.Equal(t, tr.Details.WebhookSecret, r.Details.WebhookSecret) assert.Equal(t, tr.Details.WebhookPayloads, r.Details.WebhookPayloads) + assert.Equal(t, tr.Details.WebhookPayloads.TemplateVariables, r.Details.WebhookPayloads.TemplateVariables) }) } } diff --git a/docs/resources/webhook_recipient.md b/docs/resources/webhook_recipient.md index 5030c922..4dda4673 100644 --- a/docs/resources/webhook_recipient.md +++ b/docs/resources/webhook_recipient.md @@ -34,6 +34,11 @@ resource "honeycombio_webhook_recipient" "prod" { } EOT } + + variable { + name = "severity" + default_value = "critical" + } } ``` @@ -45,12 +50,20 @@ The following arguments are supported: * `secret` - (Optional) The secret to include when sending the notification to the webhook. * `url` - (Required) The URL of the endpoint to send the notification to. * `template` - (Optional) Zero or more configuration blocks (described below) to customize the webhook payload if desired. +* `variable` - (Optional) Zero or m ore configuration blocks (described below) to define variables to be used in the webhook payload if desired. When configuring custom webhook payloads, use the `template` block, which accepts the following arguments: * `type` - (Required) The template type, allowed types are `trigger`, `exhaustion_time`, and `budget_rate`. Only one template block of each type is allowed on a single recipient. * `body` - (Required) A JSON formatted string to represent the webhook payload. +Optionally, when configuring custom webhooks, use the `variable` block to create custom variables that can be interpolated in a template. +To configure a variable, at least one `template` block must also be configured. +The `variable` block accepts the following arguments: + +* `name` - (Required) The name of the custom variable. Must be an alphanumeric string beginning with a lowercase letter. +* `default_value` - (Optional) The default value for the custom variable, which can be overridden at the alert level. + ## Attribute Reference diff --git a/internal/models/recipients.go b/internal/models/recipients.go index bef68596..03b06815 100644 --- a/internal/models/recipients.go +++ b/internal/models/recipients.go @@ -11,6 +11,7 @@ type WebhookRecipientModel struct { Secret types.String `tfsdk:"secret"` URL types.String `tfsdk:"url"` Templates types.Set `tfsdk:"template"` // WebhookTemplateModel + Variables types.Set `tfsdk:"variable"` // TemplateVariableModel } type WebhookTemplateModel struct { @@ -22,3 +23,13 @@ var WebhookTemplateAttrType = map[string]attr.Type{ "type": types.StringType, "body": types.StringType, } + +type TemplateVariableModel struct { + Name types.String `tfsdk:"name"` + DefaultValue types.String `tfsdk:"default_value"` +} + +var TemplateVariableAttrType = map[string]attr.Type{ + "name": types.StringType, + "default_value": types.StringType, +} diff --git a/internal/provider/webhook_recipient_resource.go b/internal/provider/webhook_recipient_resource.go index 895fd7af..d734a379 100644 --- a/internal/provider/webhook_recipient_resource.go +++ b/internal/provider/webhook_recipient_resource.go @@ -3,7 +3,9 @@ package provider import ( "context" "errors" + "regexp" + "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -11,6 +13,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" @@ -29,7 +32,8 @@ var ( _ resource.ResourceWithImportState = &webhookRecipientResource{} _ resource.ResourceWithValidateConfig = &webhookRecipientResource{} - webhookTemplateTypes = []string{"trigger", "exhaustion_time", "budget_rate"} + webhookTemplateTypes = []string{"trigger", "exhaustion_time", "budget_rate"} + webhookTemplateNameRegex = regexp.MustCompile(`^[a-z](?:[a-zA-Z0-9]+$)?$`) ) type webhookRecipientResource struct { @@ -114,6 +118,33 @@ func (*webhookRecipientResource) Schema(_ context.Context, _ resource.SchemaRequ }, }, }, + "variable": schema.SetNestedBlock{ + Description: "Variables for webhook templates", + Validators: []validator.Set{ + setvalidator.SizeAtMost(10), + }, + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Required: true, + Description: "The name of the variable", + Validators: []validator.String{ + stringvalidator.LengthBetween(1, 64), + stringvalidator.RegexMatches(webhookTemplateNameRegex, "must be an alphanumeric string beginning with a lowercase letter"), + }, + }, + "default_value": schema.StringAttribute{ + Description: "An optional default value for the variable", + Optional: true, + Computed: true, + Default: stringdefault.StaticString(""), + Validators: []validator.String{ + stringvalidator.LengthAtMost(256), + }, + }, + }, + }, + }, }, } } @@ -127,6 +158,7 @@ func (r *webhookRecipientResource) ImportState(ctx context.Context, req resource resp.Diagnostics.Append(resp.State.Set(ctx, &models.WebhookRecipientModel{ ID: types.StringValue(req.ID), Templates: types.SetUnknown(types.ObjectType{AttrTypes: models.WebhookTemplateAttrType}), + Variables: types.SetUnknown(types.ObjectType{AttrTypes: models.TemplateVariableAttrType}), })...) } @@ -139,8 +171,70 @@ func (r *webhookRecipientResource) ValidateConfig(ctx context.Context, req resou return } - // only allow one template of each type (trigger, budget_rate, exhaustion_time) - validateAttributesWhenTemplatesIncluded(ctx, data, resp) + var templates []models.WebhookTemplateModel + data.Templates.ElementsAs(ctx, &templates, false) + + var variables []models.TemplateVariableModel + data.Variables.ElementsAs(ctx, &variables, false) + + triggerTmplExists := false + budgetRateTmplExists := false + exhaustionTimeTmplExists := false + for i, t := range templates { + // only allow one template of each type (trigger, budget_rate, exhaustion_time) + switch t.Type { + case types.StringValue("trigger"): + if triggerTmplExists { + resp.Diagnostics.AddAttributeError( + path.Root("template").AtListIndex(i).AtName("type"), + "Conflicting configuration arguments", + "cannot have more than one \"template\" of type \"trigger\"", + ) + } + triggerTmplExists = true + case types.StringValue("exhaustion_time"): + if exhaustionTimeTmplExists { + resp.Diagnostics.AddAttributeError( + path.Root("template").AtListIndex(i).AtName("type"), + "Conflicting configuration arguments", + "cannot have more than one \"template\" of type \"exhaustion_time\"", + ) + } + exhaustionTimeTmplExists = true + case types.StringValue("budget_rate"): + if budgetRateTmplExists { + resp.Diagnostics.AddAttributeError( + path.Root("template").AtListIndex(i).AtName("type"), + "Conflicting configuration arguments", + "cannot have more than one \"template\" of type \"budget_rate\"", + ) + } + budgetRateTmplExists = true + } + } + + // template variables cannot be configured without a template + if len(variables) >= 1 && len(templates) == 0 { + resp.Diagnostics.AddAttributeError( + path.Root("variable").AtListIndex(0), + "Conflicting configuration arguments", + "cannot configure a \"variable\" without also configuring a \"template\"", + ) + } + + // variable names cannot be duplicated + duplicateMap := make(map[string]bool) + for i, v := range variables { + name := v.Name.ValueString() + if duplicateMap[name] { + resp.Diagnostics.AddAttributeError( + path.Root("variable").AtListIndex(i).AtName("name"), + "Conflicting configuration arguments", + "cannot have more than one \"variable\" with the same \"name\"", + ) + } + duplicateMap[name] = true + } } func (r *webhookRecipientResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { @@ -156,7 +250,7 @@ func (r *webhookRecipientResource) Create(ctx context.Context, req resource.Crea WebhookName: plan.Name.ValueString(), WebhookURL: plan.URL.ValueString(), WebhookSecret: plan.Secret.ValueString(), - WebhookPayloads: webhookTemplatesToClientPayloads(ctx, plan.Templates, &resp.Diagnostics), + WebhookPayloads: webhookTemplatesToClientPayloads(ctx, plan.Templates, plan.Variables, &resp.Diagnostics), }, }) if helper.AddDiagnosticOnError(&resp.Diagnostics, "Creating Honeycomb Webhook Recipient", err) { @@ -172,10 +266,16 @@ func (r *webhookRecipientResource) Create(ctx context.Context, req resource.Crea } else { state.Secret = types.StringNull() } + + // to prevent confusing if/else blocks, set null by default and override it if we have that detail on the recipient + state.Templates = types.SetNull(types.ObjectType{AttrTypes: models.WebhookTemplateAttrType}) + state.Variables = types.SetNull(types.ObjectType{AttrTypes: models.TemplateVariableAttrType}) + if rcpt.Details.WebhookPayloads != nil { state.Templates = plan.Templates - } else { - state.Templates = types.SetNull(types.ObjectType{AttrTypes: models.WebhookTemplateAttrType}) + if rcpt.Details.WebhookPayloads.TemplateVariables != nil { + state.Variables = plan.Variables + } } resp.Diagnostics.Append(resp.State.Set(ctx, state)...) @@ -226,10 +326,12 @@ func (r *webhookRecipientResource) Read(ctx context.Context, req resource.ReadRe } else { state.Secret = types.StringNull() } + if rcpt.Details.WebhookPayloads != nil { - state.Templates = clientPayloadsToWebhookTemplates(ctx, rcpt.Details.WebhookPayloads, &resp.Diagnostics) + state.Templates, state.Variables = clientPayloadsToWebhookTemplateSets(ctx, rcpt.Details.WebhookPayloads, &resp.Diagnostics) } else { state.Templates = types.SetNull(types.ObjectType{AttrTypes: models.WebhookTemplateAttrType}) + state.Variables = types.SetNull(types.ObjectType{AttrTypes: models.TemplateVariableAttrType}) } resp.Diagnostics.Append(resp.State.Set(ctx, state)...) @@ -249,7 +351,7 @@ func (r *webhookRecipientResource) Update(ctx context.Context, req resource.Upda WebhookName: plan.Name.ValueString(), WebhookURL: plan.URL.ValueString(), WebhookSecret: plan.Secret.ValueString(), - WebhookPayloads: webhookTemplatesToClientPayloads(ctx, plan.Templates, &resp.Diagnostics), + WebhookPayloads: webhookTemplatesToClientPayloads(ctx, plan.Templates, plan.Variables, &resp.Diagnostics), }, }) if helper.AddDiagnosticOnError(&resp.Diagnostics, "Updating Honeycomb Webhook Recipient", err) { @@ -272,8 +374,14 @@ func (r *webhookRecipientResource) Update(ctx context.Context, req resource.Upda } if rcpt.Details.WebhookPayloads != nil { state.Templates = plan.Templates + if rcpt.Details.WebhookPayloads.TemplateVariables != nil { + state.Variables = plan.Variables + } else { + state.Variables = types.SetNull(types.ObjectType{AttrTypes: models.TemplateVariableAttrType}) + } } else { state.Templates = types.SetNull(types.ObjectType{AttrTypes: models.WebhookTemplateAttrType}) + state.Variables = types.SetNull(types.ObjectType{AttrTypes: models.TemplateVariableAttrType}) } resp.Diagnostics.Append(resp.State.Set(ctx, state)...) @@ -306,9 +414,15 @@ func (r *webhookRecipientResource) Delete(ctx context.Context, req resource.Dele } } -func webhookTemplatesToClientPayloads(ctx context.Context, set types.Set, diags *diag.Diagnostics) *client.WebhookPayloads { +func webhookTemplatesToClientPayloads(ctx context.Context, templateSet types.Set, variableSet types.Set, diags *diag.Diagnostics) *client.WebhookPayloads { var templates []models.WebhookTemplateModel - diags.Append(set.ElementsAs(ctx, &templates, false)...) + diags.Append(templateSet.ElementsAs(ctx, &templates, false)...) + if diags.HasError() { + return nil + } + + var variables []models.TemplateVariableModel + diags.Append(variableSet.ElementsAs(ctx, &variables, false)...) if diags.HasError() { return nil } @@ -332,19 +446,37 @@ func webhookTemplatesToClientPayloads(ctx context.Context, set types.Set, diags } } + clientVars := make([]client.TemplateVariable, len(variables)) + for i, v := range variables { + tmplVar := client.TemplateVariable{ + Name: v.Name.ValueString(), + Default: v.DefaultValue.ValueString(), + } + + clientVars[i] = tmplVar + } + clientWebhookPayloads.TemplateVariables = clientVars + return clientWebhookPayloads } -func clientPayloadsToWebhookTemplates(ctx context.Context, p *client.WebhookPayloads, diags *diag.Diagnostics) types.Set { +func clientPayloadsToWebhookTemplateSets(ctx context.Context, p *client.WebhookPayloads, diags *diag.Diagnostics) (types.Set, types.Set) { if p == nil { - return types.SetNull(types.ObjectType{AttrTypes: models.WebhookTemplateAttrType}) + return types.SetNull(types.ObjectType{AttrTypes: models.WebhookTemplateAttrType}), types.SetNull(types.ObjectType{AttrTypes: models.TemplateVariableAttrType}) } - values := webhookTemplatesToObjectValues(p.PayloadTemplates, diags) - result, d := types.SetValueFrom(ctx, types.ObjectType{AttrTypes: models.WebhookTemplateAttrType}, values) + tmplValues := webhookTemplatesToObjectValues(p.PayloadTemplates, diags) + tmplResult, d := types.SetValueFrom(ctx, types.ObjectType{AttrTypes: models.WebhookTemplateAttrType}, tmplValues) + diags.Append(d...) + + var tmplVarValues []attr.Value + for _, v := range p.TemplateVariables { + tmplVarValues = append(tmplVarValues, webhookVariableToObjectValue(v, diags)) + } + varResult, d := types.SetValueFrom(ctx, types.ObjectType{AttrTypes: models.TemplateVariableAttrType}, tmplVarValues) diags.Append(d...) - return result + return tmplResult, varResult } func webhookTemplatesToObjectValues(templates client.PayloadTemplates, diags *diag.Diagnostics) []basetypes.ObjectValue { @@ -380,43 +512,13 @@ func webhookTemplatesToObjectValues(templates client.PayloadTemplates, diags *di return templateObjs } -func validateAttributesWhenTemplatesIncluded(ctx context.Context, data models.WebhookRecipientModel, resp *resource.ValidateConfigResponse) { - var templates []models.WebhookTemplateModel - data.Templates.ElementsAs(ctx, &templates, false) - - triggerTmplExists := false - budgetRateTmplExists := false - exhaustionTimeTmplExists := false - for i, t := range templates { - switch t.Type { - case types.StringValue("trigger"): - if triggerTmplExists { - resp.Diagnostics.AddAttributeError( - path.Root("template").AtListIndex(i).AtName("type"), - "Conflicting configuration arguments", - "cannot have more than one \"template\" of type \"trigger\"", - ) - } - triggerTmplExists = true - case types.StringValue("exhaustion_time"): - if exhaustionTimeTmplExists { - resp.Diagnostics.AddAttributeError( - path.Root("template").AtListIndex(i).AtName("type"), - "Conflicting configuration arguments", - "cannot have more than one \"template\" of type \"exhaustion_time\"", - ) - } - exhaustionTimeTmplExists = true - case types.StringValue("budget_rate"): - if budgetRateTmplExists { - resp.Diagnostics.AddAttributeError( - path.Root("template").AtListIndex(i).AtName("type"), - "Conflicting configuration arguments", - "cannot have more than one \"template\" of type \"budget_rate\"", - ) - } - budgetRateTmplExists = true - } - +func webhookVariableToObjectValue(v client.TemplateVariable, diags *diag.Diagnostics) basetypes.ObjectValue { + variableObj := map[string]attr.Value{ + "name": types.StringValue(v.Name), + "default_value": types.StringValue(v.Default), } + varObjVal, d := types.ObjectValue(models.TemplateVariableAttrType, variableObj) + diags.Append(d...) + + return varObjVal } diff --git a/internal/provider/webhook_recipient_resource_test.go b/internal/provider/webhook_recipient_resource_test.go index b80bcb67..768cc5ea 100644 --- a/internal/provider/webhook_recipient_resource_test.go +++ b/internal/provider/webhook_recipient_resource_test.go @@ -35,6 +35,7 @@ resource "honeycombio_webhook_recipient" "test" { resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "url", url), resource.TestCheckNoResourceAttr("honeycombio_webhook_recipient.test", "secret"), resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "template.#", "0"), + resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "variable.#", "0"), ), }, { @@ -90,6 +91,11 @@ resource "honeycombio_webhook_recipient" "test" { name = "%s" url = "%s" + variable { + name = "severity" + default_value = "critical" + } + template { type = "trigger" body = %s @@ -102,6 +108,9 @@ resource "honeycombio_webhook_recipient" "test" { resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "url", url), resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "template.#", "1"), resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "template.0.type", "trigger"), + resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "variable.#", "1"), + resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "variable.0.name", "severity"), + resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "variable.0.default_value", "critical"), resource.TestCheckNoResourceAttr("honeycombio_webhook_recipient.test", "secret"), ), }, @@ -113,6 +122,11 @@ resource "honeycombio_webhook_recipient" "test" { secret = "so-secret" + variable { + name = "severity" + default_value = "warning" + } + template { type = "trigger" body = %s @@ -126,6 +140,8 @@ resource "honeycombio_webhook_recipient" "test" { resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "secret", "so-secret"), resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "template.#", "1"), resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "template.0.type", "trigger"), + resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "variable.#", "1"), + resource.TestCheckResourceAttr("honeycombio_webhook_recipient.test", "variable.0.name", "severity"), ), }, { @@ -136,9 +152,15 @@ resource "honeycombio_webhook_recipient" "test" { }) }) - t.Run("custom webhook validations error when they should", func(t *testing.T) { + t.Run("custom webhook succeeds when a template is removed", func(t *testing.T) { name := test.RandomStringWithPrefix("test.", 20) url := test.RandomURL() + body := `< Date: Mon, 2 Dec 2024 10:27:15 -0500 Subject: [PATCH 7/9] feat: webhook headers (#586) ## Short description of the changes Support headers on the webhook recipient resource. --- client/recipient.go | 8 +- client/recipient_test.go | 11 +- docs/resources/webhook_recipient.md | 18 +- internal/models/recipients.go | 11 + .../provider/webhook_recipient_resource.go | 121 ++++++++++- .../webhook_recipient_resource_test.go | 188 ++++++++++++++++++ 6 files changed, 346 insertions(+), 11 deletions(-) diff --git a/client/recipient.go b/client/recipient.go index eb4723ef..e5e90e4f 100644 --- a/client/recipient.go +++ b/client/recipient.go @@ -65,7 +65,8 @@ type RecipientDetails struct { WebhookName string `json:"webhook_name,omitempty"` WebhookURL string `json:"webhook_url,omitempty"` // webhook only - WebhookSecret string `json:"webhook_secret,omitempty"` + WebhookSecret string `json:"webhook_secret,omitempty"` + WebhookHeaders []WebhookHeader `json:"webhook_headers"` // custom webhook WebhookPayloads *WebhookPayloads `json:"webhook_payloads,omitempty"` } @@ -94,6 +95,11 @@ type TemplateVariable struct { Default string `json:"default_value"` } +type WebhookHeader struct { + Key string `json:"header"` + Value string `json:"value"` +} + // RecipientType holds all the possible recipient types. type RecipientType string diff --git a/client/recipient_test.go b/client/recipient_test.go index 86a5feba..731f9a9e 100644 --- a/client/recipient_test.go +++ b/client/recipient_test.go @@ -96,9 +96,10 @@ func TestRecipientsCustomWebhook(t *testing.T) { rcpt: client.Recipient{ Type: client.RecipientTypeWebhook, Details: client.RecipientDetails{ - WebhookName: test.RandomStringWithPrefix("test.", 10), - WebhookURL: test.RandomURL(), - WebhookSecret: "secret", + WebhookName: test.RandomStringWithPrefix("test.", 10), + WebhookURL: test.RandomURL(), + WebhookSecret: "secret", + WebhookHeaders: []client.WebhookHeader{{Key: "Authorization", Value: "Bearer 123"}}, WebhookPayloads: &client.WebhookPayloads{ PayloadTemplates: client.PayloadTemplates{Trigger: &client.PayloadTemplate{Body: body}}, TemplateVariables: []client.TemplateVariable{{Name: "severity", Default: "warning"}}, @@ -130,6 +131,10 @@ func TestRecipientsCustomWebhook(t *testing.T) { assert.Equal(t, tr.Details.WebhookSecret, r.Details.WebhookSecret) assert.Equal(t, tr.Details.WebhookPayloads, r.Details.WebhookPayloads) assert.Equal(t, tr.Details.WebhookPayloads.TemplateVariables, r.Details.WebhookPayloads.TemplateVariables) + if assert.Len(t, r.Details.WebhookHeaders, 1) { + assert.Equal(t, tr.Details.WebhookHeaders[0].Key, r.Details.WebhookHeaders[0].Key) + assert.Equal(t, tr.Details.WebhookHeaders[0].Value, r.Details.WebhookHeaders[0].Value) + } }) } } diff --git a/docs/resources/webhook_recipient.md b/docs/resources/webhook_recipient.md index 4dda4673..7e68a242 100644 --- a/docs/resources/webhook_recipient.md +++ b/docs/resources/webhook_recipient.md @@ -19,7 +19,12 @@ resource "honeycombio_webhook_recipient" "prod" { name = "Production Alerts" secret = "a63dab148496ecbe04a1a802ca9b95b8" url = "https://my.url.corp.net" - + + header { + name = "Authorization" + value = "Bearer 123" + } + template { type = "trigger" body = < Date: Fri, 6 Dec 2024 09:51:34 -0500 Subject: [PATCH 8/9] chore(ci): increase integration test timeout to 20min (#587) Experienced the first timeout during integration tests during last night's scheduled CI run. This simplifies the timeout settings (one for the entire region-scoped job) and increases the limit to 20min. --- .github/workflows/ci.yaml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4373e847..d56e9801 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -34,7 +34,7 @@ jobs: name: Test US needs: build runs-on: ubuntu-latest - timeout-minutes: 15 + timeout-minutes: 20 concurrency: group: hnytf-testacc-us env: @@ -58,7 +58,6 @@ jobs: ./scripts/setup-testsuite-dataset - name: Run client acceptance tests - timeout-minutes: 10 env: HONEYCOMB_API_KEY: ${{ secrets.HONEYCOMB_API_KEY }} HONEYCOMB_KEY_ID: ${{ secrets.HONEYCOMB_KEY_ID }} @@ -79,7 +78,6 @@ jobs: terraform_wrapper: false - name: Run TF acceptance tests - timeout-minutes: 10 env: HONEYCOMB_API_KEY: ${{ secrets.HONEYCOMB_API_KEY }} HONEYCOMB_KEY_ID: ${{ secrets.HONEYCOMB_KEY_ID }} @@ -110,7 +108,6 @@ jobs: - name: Cleanup Dangling Resources if: ${{ always() }} - timeout-minutes: 5 env: HONEYCOMB_API_KEY: ${{ secrets.HONEYCOMB_API_KEY }} HONEYCOMB_KEY_ID: ${{ secrets.HONEYCOMB_KEY_ID }} @@ -134,7 +131,7 @@ jobs: name: Test EU needs: build runs-on: ubuntu-latest - timeout-minutes: 15 + timeout-minutes: 20 concurrency: group: hnytf-testacc-eu env: @@ -159,7 +156,6 @@ jobs: ./scripts/setup-testsuite-dataset - name: Run client acceptance tests - timeout-minutes: 10 env: HONEYCOMB_API_ENDPOINT: https://api.eu1.honeycomb.io HONEYCOMB_API_KEY: ${{ secrets.HONEYCOMB_API_KEY_EU }} @@ -181,7 +177,6 @@ jobs: terraform_wrapper: false - name: Run TF acceptance tests - timeout-minutes: 10 env: HONEYCOMB_API_ENDPOINT: https://api.eu1.honeycomb.io HONEYCOMB_API_KEY: ${{ secrets.HONEYCOMB_API_KEY_EU }} @@ -213,7 +208,6 @@ jobs: - name: Cleanup Dangling Resources if: ${{ always() }} - timeout-minutes: 5 env: HONEYCOMB_API_ENDPOINT: https://api.eu1.honeycomb.io HONEYCOMB_API_KEY: ${{ secrets.HONEYCOMB_API_KEY_EU }} From 29a81ed7b205e1a4be320af2dec9d34f23495244 Mon Sep 17 00:00:00 2001 From: Jason Harley Date: Fri, 6 Dec 2024 10:07:54 -0500 Subject: [PATCH 9/9] chore(ci): remove codecov (#588) We inherited codecov when we took this project over from the community, but haven't found it useful and decided to remove it from the project. As followup once this is landed I'll remove the secret from the project's secrets. --- .github/workflows/ci.yaml | 14 -------------- README.md | 1 - 2 files changed, 15 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d56e9801..3ec11485 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -65,7 +65,6 @@ jobs: HONEYCOMB_DATASET: testacc run: | go test -v ./client/... \ - -coverprofile=client-coverage.txt \ -covermode=atomic | \ go-junit-report \ -set-exit-code \ @@ -87,7 +86,6 @@ jobs: TF_ACC_TERRAFORM_VERSION: ${{ env.TERRAFORM_VERSION }} run: | go test -v ./internal/... ./honeycombio/... \ - -coverprofile=tf-coverage.txt \ -covermode=atomic | \ go-junit-report \ -set-exit-code \ @@ -122,11 +120,6 @@ jobs: paths: "*-report.xml" show: "fail, skip" - - name: Generate Coverage Report - uses: codecov/codecov-action@v4.6.0 - with: - token: ${{ secrets.CODECOV_TOKEN }} - test-eu: name: Test EU needs: build @@ -164,7 +157,6 @@ jobs: HONEYCOMB_DATASET: testacc run: | go test -v ./client/... \ - -coverprofile=client-coverage.txt \ -covermode=atomic | \ go-junit-report \ -set-exit-code \ @@ -187,7 +179,6 @@ jobs: TF_ACC_TERRAFORM_VERSION: ${{ env.TERRAFORM_VERSION }} run: | go test -v ./internal/... ./honeycombio/... \ - -coverprofile=tf-coverage.txt \ -covermode=atomic | \ go-junit-report \ -set-exit-code \ @@ -222,8 +213,3 @@ jobs: with: paths: "*-report.xml" show: "fail, skip" - - - name: Generate Coverage Report - uses: codecov/codecov-action@v4.6.0 - with: - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/README.md b/README.md index c76c620f..fefb01cc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ [![OSS Lifecycle](https://img.shields.io/osslifecycle/honeycombio/terraform-provider-honeycombio)](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md) [![CI](https://github.com/honeycombio/terraform-provider-honeycombio/workflows/CI/badge.svg)](https://github.com/honeycombio/terraform-provider-honeycombio/actions) -[![codecov](https://codecov.io/gh/honeycombio/terraform-provider-honeycombio/branch/main/graph/badge.svg)](https://codecov.io/gh/honeycombio/terraform-provider-honeycombio) [![Terraform Registry](https://img.shields.io/github/v/release/honeycombio/terraform-provider-honeycombio?color=5e4fe3&label=Terraform%20Registry&logo=terraform&sort=semver)](https://registry.terraform.io/providers/honeycombio/honeycombio/latest) A Terraform provider for Honeycomb.io.