diff --git a/examples/playground/key.tf b/examples/playground/key.tf index bea82e7..27cb22b 100644 --- a/examples/playground/key.tf +++ b/examples/playground/key.tf @@ -1,6 +1,7 @@ resource "ably_api_key" "api_key_0" { - app_id = ably_app.app0.id - name = "key-0000" + app_id = ably_app.app0.id + name = "key-0000" + revocable_tokens = true capabilities = { "channel2" = ["publish"], "channel3" = ["subscribe"], @@ -9,8 +10,9 @@ resource "ably_api_key" "api_key_0" { } resource "ably_api_key" "api_key_1" { - app_id = ably_app.app0.id - name = "key-0001" + app_id = ably_app.app0.id + name = "key-0001" + revocable_tokens = false capabilities = { "channel1" = ["subscribe"], "channel2" = ["publish"], diff --git a/go.mod b/go.mod index 588e9cc..ca2348a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/ably/terraform-provider-ably go 1.19 require ( - github.com/ably/ably-control-go v0.2.0 + github.com/ably/ably-control-go v0.3.0 github.com/hashicorp/terraform-plugin-docs v0.13.0 github.com/hashicorp/terraform-plugin-framework v0.16.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.21.0 diff --git a/go.sum b/go.sum index 23f4fc2..08569e9 100644 --- a/go.sum +++ b/go.sum @@ -12,14 +12,8 @@ github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= -github.com/ably/ably-control-go v0.1.0 h1:flhd5ZiJZyWs+RxOK//ozsev6VpmRrqOmvXhVvgon3I= -github.com/ably/ably-control-go v0.1.0/go.mod h1:TP7gWAy+ga++gX6OZ0DtjwH8oVKKdiaIGQvZvxDKNdk= -github.com/ably/ably-control-go v0.1.1-0.20231211162000-164517f286eb h1:WVq8ysFKqCc8OtM77GnWF7s+cyEcRBT5+i2iirOZeoQ= -github.com/ably/ably-control-go v0.1.1-0.20231211162000-164517f286eb/go.mod h1:TP7gWAy+ga++gX6OZ0DtjwH8oVKKdiaIGQvZvxDKNdk= -github.com/ably/ably-control-go v0.1.1-0.20231213094545-a41bf3d025ef h1:tJthta4QnJVvbH/gR1G8hkdHQi/djOd8fkU8QS7IXx0= -github.com/ably/ably-control-go v0.1.1-0.20231213094545-a41bf3d025ef/go.mod h1:TP7gWAy+ga++gX6OZ0DtjwH8oVKKdiaIGQvZvxDKNdk= -github.com/ably/ably-control-go v0.2.0 h1:a6fOGtEAzGYYWL/k7tNHHc2WHur3mm7ZPuU7n/RsayU= -github.com/ably/ably-control-go v0.2.0/go.mod h1:TP7gWAy+ga++gX6OZ0DtjwH8oVKKdiaIGQvZvxDKNdk= +github.com/ably/ably-control-go v0.3.0 h1:m5Y2SHE69Mwg8iDASZxqmlHFSwpejN4s2TgZi3EIVMQ= +github.com/ably/ably-control-go v0.3.0/go.mod h1:TP7gWAy+ga++gX6OZ0DtjwH8oVKKdiaIGQvZvxDKNdk= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= diff --git a/internal/provider/models.go b/internal/provider/models.go index 055c0e5..df3d720 100644 --- a/internal/provider/models.go +++ b/internal/provider/models.go @@ -32,14 +32,15 @@ type AblyNamespace struct { // Ably Key type AblyKey struct { - ID types.String `tfsdk:"id"` - AppID types.String `tfsdk:"app_id"` - Name types.String `tfsdk:"name"` - Capability map[string][]string `tfsdk:"capabilities"` - Status types.Int64 `tfsdk:"status"` - Key types.String `tfsdk:"key"` - Created types.Int64 `tfsdk:"created"` - Modified types.Int64 `tfsdk:"modified"` + ID types.String `tfsdk:"id"` + AppID types.String `tfsdk:"app_id"` + Name types.String `tfsdk:"name"` + RevocableTokens types.Bool `tfsdk:"revocable_tokens"` + Capability map[string][]string `tfsdk:"capabilities"` + Status types.Int64 `tfsdk:"status"` + Key types.String `tfsdk:"key"` + Created types.Int64 `tfsdk:"created"` + Modified types.Int64 `tfsdk:"modified"` } // Ably Queue diff --git a/internal/provider/resource_ably_key.go b/internal/provider/resource_ably_key.go index e6c95dc..09da6db 100644 --- a/internal/provider/resource_ably_key.go +++ b/internal/provider/resource_ably_key.go @@ -48,6 +48,15 @@ func (r resourceKey) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostic Required: true, Description: "The capabilities that this key has. More information on capabilities can be found in the [Ably documentation](https://ably.com/docs/core-features/authentication#capabilities-explained)", }, + "revocable_tokens": { + Type: types.BoolType, + Optional: true, + Computed: true, + Description: "Allow tokens issued by this key to be revoked. More information on Token Revocation can be found in the [Ably documentation](https://ably.com/docs/auth/revocation)", + PlanModifiers: []tfsdk.AttributePlanModifier{ + DefaultAttribute(types.BoolValue(false)), + }, + }, "status": { Type: types.Int64Type, Computed: true, @@ -106,8 +115,9 @@ func (r resourceKey) Create(ctx context.Context, req tfsdk_resource.CreateReques } new_key := ably_control_go.NewKey{ - Name: plan.Name.ValueString(), - Capability: plan.Capability, + Name: plan.Name.ValueString(), + Capability: plan.Capability, + RevocableTokens: plan.RevocableTokens.ValueBool(), } // Creates a new Ably Key by invoking the CreateKey function from the Client Library @@ -122,14 +132,15 @@ func (r resourceKey) Create(ctx context.Context, req tfsdk_resource.CreateReques // Maps response body to resource schema attributes. resp_key := AblyKey{ - ID: types.StringValue(ably_key.ID), - AppID: types.StringValue(ably_key.AppID), - Name: types.StringValue(ably_key.Name), - Key: types.StringValue(ably_key.Key), - Capability: ably_key.Capability, - Status: types.Int64Value(int64(ably_key.Status)), - Created: types.Int64Value(int64(ably_key.Created)), - Modified: types.Int64Value(int64(ably_key.Modified)), + ID: types.StringValue(ably_key.ID), + AppID: types.StringValue(ably_key.AppID), + Name: types.StringValue(ably_key.Name), + Key: types.StringValue(ably_key.Key), + RevocableTokens: types.BoolValue(ably_key.RevocableTokens), + Capability: ably_key.Capability, + Status: types.Int64Value(int64(ably_key.Status)), + Created: types.Int64Value(int64(ably_key.Created)), + Modified: types.Int64Value(int64(ably_key.Modified)), } // Sets state for the new Ably App. @@ -175,14 +186,15 @@ func (r resourceKey) Read(ctx context.Context, req tfsdk_resource.ReadRequest, r for _, v := range keys { if v.AppID == app_id && v.ID == key_id && v.Status == 0 { resp_key := AblyKey{ - ID: types.StringValue(v.ID), - AppID: types.StringValue(v.AppID), - Name: types.StringValue(v.Name), - Capability: v.Capability, - Status: types.Int64Value(int64(v.Status)), - Key: types.StringValue(v.Key), - Created: types.Int64Value(int64(v.Created)), - Modified: types.Int64Value(int64(v.Modified)), + ID: types.StringValue(v.ID), + AppID: types.StringValue(v.AppID), + Name: types.StringValue(v.Name), + RevocableTokens: types.BoolValue(v.RevocableTokens), + Capability: v.Capability, + Status: types.Int64Value(int64(v.Status)), + Key: types.StringValue(v.Key), + Created: types.Int64Value(int64(v.Created)), + Modified: types.Int64Value(int64(v.Modified)), } // Sets state to app values. diags = resp.State.Set(ctx, &resp_key) @@ -225,8 +237,9 @@ func (r resourceKey) Update(ctx context.Context, req tfsdk_resource.UpdateReques // Instantiates struct of type ably_control_go.NewKey and sets values to output of plan key_values := ably_control_go.NewKey{ - Name: plan.Name.ValueString(), - Capability: plan.Capability, + Name: plan.Name.ValueString(), + Capability: plan.Capability, + RevocableTokens: plan.RevocableTokens.ValueBool(), } // Updates an Ably API Key. The function invokes the Client Library UpdateKey method. @@ -240,14 +253,15 @@ func (r resourceKey) Update(ctx context.Context, req tfsdk_resource.UpdateReques } resp_key := AblyKey{ - ID: types.StringValue(ably_key.ID), - AppID: types.StringValue(ably_key.AppID), - Name: types.StringValue(ably_key.Name), - Capability: ably_key.Capability, - Status: types.Int64Value(int64(ably_key.Status)), - Key: types.StringValue(ably_key.Key), - Created: types.Int64Value(int64(ably_key.Created)), - Modified: types.Int64Value(int64(ably_key.Modified)), + ID: types.StringValue(ably_key.ID), + AppID: types.StringValue(ably_key.AppID), + Name: types.StringValue(ably_key.Name), + RevocableTokens: types.BoolValue(ably_key.RevocableTokens), + Capability: ably_key.Capability, + Status: types.Int64Value(int64(ably_key.Status)), + Key: types.StringValue(ably_key.Key), + Created: types.Int64Value(int64(ably_key.Created)), + Modified: types.Int64Value(int64(ably_key.Modified)), } // Sets state. diff --git a/internal/provider/resource_ably_key_test.go b/internal/provider/resource_ably_key_test.go index c6c3118..f622f6c 100644 --- a/internal/provider/resource_ably_key_test.go +++ b/internal/provider/resource_ably_key_test.go @@ -2,9 +2,10 @@ package ably_control import ( "fmt" + "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "testing" ) // Test Create and Update of an Ably Key with: @@ -21,10 +22,11 @@ func TestAccAblyKey(t *testing.T) { Steps: []resource.TestStep{ // Create and Read testing of ably_app.app0 { - Config: testAccAblyKeyConfig(app_name, key_name, "channel100", `["publish", "subscribe"]`), + Config: testAccAblyKeyConfig(app_name, key_name, "channel100", `["publish", "subscribe"]`, true), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("ably_app.app0", "name", app_name), resource.TestCheckResourceAttr("ably_api_key.key0", "name", key_name), + resource.TestCheckResourceAttr("ably_api_key.key0", "revocable_tokens", "true"), resource.TestCheckResourceAttr("ably_api_key.key0", "capabilities.channel100.0", "publish"), resource.TestCheckResourceAttr("ably_api_key.key0", "capabilities.channel100.1", "subscribe"), resource.TestCheckResourceAttrWith("ably_api_key.key0", "key", func(value string) error { @@ -37,10 +39,11 @@ func TestAccAblyKey(t *testing.T) { }, // Update and Read testing of ably_app.app0 { - Config: testAccAblyKeyConfig(update_app_name, update_key_name, "channel100", `["history"]`), + Config: testAccAblyKeyConfig(update_app_name, update_key_name, "channel100", `["history"]`, false), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("ably_app.app0", "name", update_app_name), resource.TestCheckResourceAttr("ably_api_key.key0", "name", update_key_name), + resource.TestCheckResourceAttr("ably_api_key.key0", "revocable_tokens", "false"), resource.TestCheckResourceAttr("ably_api_key.key0", "capabilities.channel100.0", "history"), resource.TestCheckResourceAttrWith("ably_api_key.key0", "key", func(value string) error { if value == "" { @@ -57,7 +60,7 @@ func TestAccAblyKey(t *testing.T) { // Function with inline HCL to provision an ably_app resource // Takes App name, Key Name, Capability Name and Capability List as function params. -func testAccAblyKeyConfig(appName string, keyName string, keyCapabilityName0 string, keyCapabilityCap0 string) string { +func testAccAblyKeyConfig(appName string, keyName string, keyCapabilityName0 string, keyCapabilityCap0 string, revocableTokens bool) string { return fmt.Sprintf(` terraform { required_providers { @@ -82,6 +85,7 @@ resource "ably_api_key" "key0" { capabilities = { %[3]q = %[4]s } + revocable_tokens = %[5]t } -`, appName, keyName, keyCapabilityName0, keyCapabilityCap0) +`, appName, keyName, keyCapabilityName0, keyCapabilityCap0, revocableTokens) } diff --git a/internal/provider/resource_ably_rule_azure_function_test.go b/internal/provider/resource_ably_rule_azure_function_test.go index 9380c72..c15c668 100644 --- a/internal/provider/resource_ably_rule_azure_function_test.go +++ b/internal/provider/resource_ably_rule_azure_function_test.go @@ -2,9 +2,10 @@ package ably_control import ( "fmt" + "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "testing" ) func TestAccAblyRuleAzureFunction(t *testing.T) { @@ -122,6 +123,7 @@ resource "ably_api_key" "api_key_0" { "channel3" = ["subscribe"], "channel33" = ["subscribe"], } + revocable_tokens = true } resource "ably_api_key" "api_key_1" { @@ -130,6 +132,7 @@ resource "ably_api_key" "api_key_0" { capabilities = { "channel2" = ["publish"], } + revocable_tokens = false } resource "ably_rule_azure_function" "rule0" { diff --git a/internal/provider/resource_ably_rule_http_cloudflare_worker_test.go b/internal/provider/resource_ably_rule_http_cloudflare_worker_test.go index c1e0bc9..5a9e471 100644 --- a/internal/provider/resource_ably_rule_http_cloudflare_worker_test.go +++ b/internal/provider/resource_ably_rule_http_cloudflare_worker_test.go @@ -116,6 +116,7 @@ resource "ably_api_key" "api_key_0" { "channel3" = ["subscribe"], "channel33" = ["subscribe"], } + revocable_tokens = true } resource "ably_api_key" "api_key_1" { @@ -124,6 +125,7 @@ resource "ably_api_key" "api_key_0" { capabilities = { "channel2" = ["publish"], } + revocable_tokens = false } resource "ably_rule_cloudflare_worker" "rule0" { diff --git a/internal/provider/resource_ably_rule_http_google_cloud_function_test.go b/internal/provider/resource_ably_rule_http_google_cloud_function_test.go index 33fc25d..50f96eb 100644 --- a/internal/provider/resource_ably_rule_http_google_cloud_function_test.go +++ b/internal/provider/resource_ably_rule_http_google_cloud_function_test.go @@ -123,6 +123,7 @@ resource "ably_api_key" "api_key_0" { "channel3" = ["subscribe"], "channel33" = ["subscribe"], } + revocable_tokens = true } resource "ably_api_key" "api_key_1" { @@ -131,6 +132,7 @@ resource "ably_api_key" "api_key_1" { capabilities = { "channel2" = ["publish"], } + revocable_tokens = false } resource "ably_rule_google_function" "rule0" { diff --git a/internal/provider/resource_ably_rule_http_test.go b/internal/provider/resource_ably_rule_http_test.go index 8e0590a..2bca17d 100644 --- a/internal/provider/resource_ably_rule_http_test.go +++ b/internal/provider/resource_ably_rule_http_test.go @@ -122,6 +122,7 @@ resource "ably_api_key" "api_key_0" { "channel3" = ["subscribe"], "channel33" = ["subscribe"], } + revocable_tokens = true } resource "ably_api_key" "api_key_1" { @@ -130,6 +131,7 @@ resource "ably_api_key" "api_key_1" { capabilities = { "channel2" = ["publish"], } + revocable_tokens = false } resource "ably_rule_http" "rule0" { diff --git a/internal/provider/resource_ably_rule_ifttt_test.go b/internal/provider/resource_ably_rule_ifttt_test.go index 61dabe1..23325ed 100644 --- a/internal/provider/resource_ably_rule_ifttt_test.go +++ b/internal/provider/resource_ably_rule_ifttt_test.go @@ -99,6 +99,7 @@ resource "ably_api_key" "api_key_0" { "channel3" = ["subscribe"], "channel33" = ["subscribe"], } + revocable_tokens = true } resource "ably_api_key" "api_key_1" { @@ -107,6 +108,7 @@ resource "ably_api_key" "api_key_0" { capabilities = { "channel2" = ["publish"], } + revocable_tokens = false } resource "ably_rule_ifttt" "rule0" { diff --git a/internal/provider/resource_ably_rule_zapier_test.go b/internal/provider/resource_ably_rule_zapier_test.go index 499c6e3..16dc7d4 100644 --- a/internal/provider/resource_ably_rule_zapier_test.go +++ b/internal/provider/resource_ably_rule_zapier_test.go @@ -116,6 +116,7 @@ resource "ably_api_key" "api_key_0" { "channel3" = ["subscribe"], "channel33" = ["subscribe"], } + revocable_tokens = true } resource "ably_api_key" "api_key_1" { @@ -124,6 +125,7 @@ resource "ably_api_key" "api_key_0" { capabilities = { "channel2" = ["publish"], } + revocable_tokens = false } resource "ably_rule_zapier" "rule0" {