Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New resources: azurerm_redis_cache_policy and azurerm_redis_cache_policy_assignment #25477

Merged
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
46cc1e7
WIP: redis cache policy assignment
favoretti Apr 1, 2024
5b54ec5
terrafmt
favoretti Apr 1, 2024
7aaa237
Take name from supposedly the right place
favoretti Apr 2, 2024
5fb4004
Add redis_cache_access_policy_resource, fix tests
favoretti Apr 2, 2024
0c471b8
fmt, terrafmt
favoretti Apr 2, 2024
50d6077
Add docs
favoretti Apr 2, 2024
e68d671
terrafmt again
favoretti Apr 2, 2024
1e2afe4
Fix tests
favoretti Apr 2, 2024
565812c
Update redis_cache_access_policy.html.markdown
favoretti Apr 2, 2024
a0a2439
Update redis_cache_access_policy.html.markdown
favoretti Apr 2, 2024
e9cbb89
Update redis_cache_access_policy.html.markdown
favoretti Apr 2, 2024
0d1e0cb
Update redis_cache_access_policy_assignment.html.markdown
favoretti Apr 2, 2024
4a17a5e
Update redis_cache_access_policy_assignment.html.markdown
favoretti Apr 2, 2024
52752d7
Update redis_cache_access_policy_assignment.html.markdown
favoretti Apr 2, 2024
8be728a
Update internal/services/redis/redis_cache_access_policy_assignment_r…
favoretti Apr 2, 2024
4c8d0fa
Address comments
favoretti Apr 2, 2024
a594ad8
Address comments
favoretti Apr 2, 2024
4a8756d
Fix some more docs errors
favoretti Apr 2, 2024
c054ebc
Remove update from policy assignment
favoretti Apr 3, 2024
caf3afe
Add check for requiresImport
favoretti Apr 3, 2024
ce001a8
Remove update from cache_access_policy too
favoretti Apr 3, 2024
a60e90b
Up redis_cache timeouts for create/delete/update to 180min
favoretti Apr 3, 2024
7823dd8
Update internal/services/redis/redis_cache_access_policy_assignment_r…
favoretti Apr 4, 2024
5f3bdb1
Update internal/services/redis/redis_cache_access_policy_assignment_r…
favoretti Apr 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/provider/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ func SupportedTypedServices() []sdk.TypedServiceRegistration {
policy.Registration{},
privatednsresolver.Registration{},
recoveryservices.Registration{},
redis.Registration{},
redhatopenshift.Registration{},
resource.Registration{},
sentinel.Registration{},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package redis

import (
"context"
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/resource-manager/redis/2023-08-01/redis"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
)

type RedisCacheAccessPolicyAssignmentResource struct {
}

var _ sdk.Resource = RedisCacheAccessPolicyAssignmentResource{}

type RedisCacheAccessPolicyAssignmentResourceModel struct {
Name string `tfschema:"name"`
RedisCacheID string `tfschema:"redis_cache_id"`
AccessPolicyName string `tfschema:"access_policy_name"`
ObjectID string `tfschema:"object_id"`
ObjectIDAlias string `tfschema:"object_id_alias"`
}

func (r RedisCacheAccessPolicyAssignmentResource) Arguments() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringIsNotEmpty,
},
"redis_cache_id": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: redis.ValidateRediID,
},
"access_policy_name": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
},
"object_id": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
},
"object_id_alias": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice(
[]string{
"ServicePrincipal",
"UserMSI",
}, false),
},
}
}

func (r RedisCacheAccessPolicyAssignmentResource) Attributes() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{}
}

func (r RedisCacheAccessPolicyAssignmentResource) ModelObject() interface{} {
return &RedisCacheAccessPolicyAssignmentResourceModel{}
}

func (r RedisCacheAccessPolicyAssignmentResource) ResourceType() string {
return "azurerm_redis_cache_access_policy_assignment"
}

func (r RedisCacheAccessPolicyAssignmentResource) IDValidationFunc() pluginsdk.SchemaValidateFunc {
return redis.ValidateAccessPolicyAssignmentID
}

func (r RedisCacheAccessPolicyAssignmentResource) Create() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
favoretti marked this conversation as resolved.
Show resolved Hide resolved
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
var model RedisCacheAccessPolicyAssignmentResourceModel
if err := metadata.Decode(&model); err != nil {
return fmt.Errorf("decoding %+v", err)
}
client := metadata.Client.Redis.Redis
subscriptionId := metadata.Client.Account.SubscriptionId

redisId, err := redis.ParseRediID(model.RedisCacheID)
if err != nil {
return fmt.Errorf("parsing Redis Cache ID (%s): %+v", model.RedisCacheID, err)
favoretti marked this conversation as resolved.
Show resolved Hide resolved
}
id := redis.NewAccessPolicyAssignmentID(subscriptionId, redisId.ResourceGroupName, redisId.RedisName, model.Name)

existing, err := client.AccessPolicyAssignmentGet(ctx, id)
if err != nil && !response.WasNotFound(existing.HttpResponse) {
return fmt.Errorf("checking for existing %s: %+v", id, err)
}

if !response.WasNotFound(existing.HttpResponse) {
return metadata.ResourceRequiresImport(r.ResourceType(), id)
}

createInput := redis.RedisCacheAccessPolicyAssignment{
Name: &model.Name,
Properties: &redis.RedisCacheAccessPolicyAssignmentProperties{
AccessPolicyName: model.AccessPolicyName,
ObjectId: model.ObjectID,
ObjectIdAlias: model.ObjectIDAlias,
},
}
if err := client.AccessPolicyAssignmentCreateUpdateThenPoll(ctx, id, createInput); err != nil {
return fmt.Errorf("failed to create Redis Cache Access Policy Assignment %s in Redis Cache %s in resource group %s: %s", model.Name, redisId.RedisName, redisId.ResourceGroupName, err)
}

metadata.SetID(id)
return nil
},
}
}

func (r RedisCacheAccessPolicyAssignmentResource) Read() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
id, err := redis.ParseAccessPolicyAssignmentID(metadata.ResourceData.Id())
if err != nil {
return err
}

client := metadata.Client.Redis.Redis

resp, err := client.AccessPolicyAssignmentGet(ctx, *id)
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
return metadata.MarkAsGone(id)
}
return fmt.Errorf("retrieving Redis Cache Access Policy Assignment %s: %+v", *id, err)
}

state := RedisCacheAccessPolicyAssignmentResourceModel{}

if model := resp.Model; model != nil {
if model.Name != nil {
state.Name = *model.Name
}
state.RedisCacheID = redis.NewRediID(id.SubscriptionId, id.ResourceGroupName, id.RedisName).ID()
if model.Properties != nil {
state.AccessPolicyName = model.Properties.AccessPolicyName
state.ObjectID = model.Properties.ObjectId
state.ObjectIDAlias = model.Properties.ObjectIdAlias
}
}

return metadata.Encode(&state)
},
}
}

func (r RedisCacheAccessPolicyAssignmentResource) Delete() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
var model RedisCacheAccessPolicyAssignmentResourceModel
if err := metadata.Decode(&model); err != nil {
return fmt.Errorf("decoding %+v", err)
}
client := metadata.Client.Redis.Redis
id, err := redis.ParseAccessPolicyAssignmentID(metadata.ResourceData.Id())
if err != nil {
return fmt.Errorf("while parsing resource ID: %+v", err)
favoretti marked this conversation as resolved.
Show resolved Hide resolved
}

if _, err := client.AccessPolicyAssignmentDelete(ctx, *id); err != nil {
return fmt.Errorf("deleting Redis Cache Access Policy Assignment %s in Redis Cache %s in resource group %s: %s", id.AccessPolicyAssignmentName, id.RedisName, id.ResourceGroupName, err)
}

return nil
},
}
}
favoretti marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package redis_test

import (
"context"
"fmt"
"testing"

"github.com/hashicorp/go-azure-sdk/resource-manager/redis/2023-08-01/redis"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

type RedisCacheAccessPolicyAssignmentResource struct{}

func TestAccRedisCacheAccessPolicyAssignment_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_redis_cache_access_policy_assignment", "test")
r := RedisCacheAccessPolicyAssignmentResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccRedisCacheAccessPolicyAssignment_requiresImport(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_redis_cache_access_policy_assignment", "test")
r := RedisCacheAccessPolicyAssignmentResource{}
data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.RequiresImportErrorStep(r.requiresImport),
})
}

func (t RedisCacheAccessPolicyAssignmentResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := redis.ParseAccessPolicyAssignmentID(state.ID)
if err != nil {
return nil, err
}

resp, err := clients.Redis.Redis.AccessPolicyAssignmentGet(ctx, *id)
if err != nil {
return nil, fmt.Errorf("reading %s: %+v", *id, err)
}

return utils.Bool(resp.Model != nil), nil
}

func (RedisCacheAccessPolicyAssignmentResource) basic(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

data "azurerm_client_config" "test" {
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_redis_cache" "test" {
name = "acctestRedis-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
capacity = 1
family = "C"
sku_name = "Basic"
enable_non_ssl_port = true
minimum_tls_version = "1.2"

redis_configuration {
}
}

resource "azurerm_redis_cache_access_policy_assignment" "test" {
name = "acctestRedisAccessPolicyAssignmentTest"
redis_cache_id = azurerm_redis_cache.test.id
access_policy_name = "Data Contributor"
object_id = data.azurerm_client_config.test.object_id
object_id_alias = "ServicePrincipal"
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func (r RedisCacheAccessPolicyAssignmentResource) requiresImport(data acceptance.TestData) string {
return fmt.Sprintf(`
%s

resource "azurerm_redis_cache_access_policy_assignment" "import" {
name = azurerm_redis_cache_access_policy_assignment.test.name
redis_cache_id = azurerm_redis_cache_access_policy_assignment.test.redis_cache_id
access_policy_name = azurerm_redis_cache_access_policy_assignment.test.access_policy_name
object_id = azurerm_redis_cache_access_policy_assignment.test.object_id
object_id_alias = azurerm_redis_cache_access_policy_assignment.test.object_id_alias
}
`, r.basic(data))
}
Loading
Loading