Skip to content

Commit

Permalink
adding #10706
Browse files Browse the repository at this point in the history
* Pull Main and add RedisEnterprise API

* Complete cluster resource

* Added test cases and documentation

* Minor fix to documentation

* Remove HR from docs

* Fix missed quotation mark in documentation sample

* Add database resource and more test cases

* Add tests, update validation, mostly working now

* Add validation and more test cases

* Fix lint errors

* terrafmt tests

* Address RP comments
  • Loading branch information
WodansSon authored Feb 26, 2021
1 parent 46da3d1 commit fa64273
Show file tree
Hide file tree
Showing 48 changed files with 6,975 additions and 0 deletions.
1 change: 1 addition & 0 deletions .teamcity/components/generated/services.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ var services = mapOf(
"privatedns" to "Private DNS",
"recoveryservices" to "Recovery Services",
"redis" to "Redis",
"redisenterprise" to "Redis Enterprise",
"relay" to "Relay",
"resource" to "Resources",
"sql" to "SQL",
Expand Down
29 changes: 29 additions & 0 deletions azurerm/helpers/azure/error_output.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package azure

import (
"fmt"
"strings"
)

// QuotedStringSlice formats a string slice into a quoted string containing all segments passed in a slice (e.g. string[]{"one", "two", "three"} will return {"one", "two" or "three"}). Useful for error messages with multiple possible values.
func QuotedStringSlice(strs []string) string {
if len(strs) == 1 {
return fmt.Sprint(`"`, strs[0], `"`)
}

var sb strings.Builder

for i, str := range strs {
if i < (len(strs) - 1) {
if i == (len(strs) - 2) {
sb.WriteString(fmt.Sprint(`"`, str, `"`))
} else {
sb.WriteString(fmt.Sprint(`"`, str, `", `))
}
} else {
sb.WriteString(fmt.Sprint(` or "`, str, `"`))
}
}

return sb.String()
}
36 changes: 36 additions & 0 deletions azurerm/helpers/azure/error_output_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package azure

import "testing"

func TestQuotedStringSlice(t *testing.T) {
testData := []struct {
input []string
expected string
}{
{
input: []string{""},
expected: `""`,
},
{
input: []string{"Din Djarin"},
expected: `"Din Djarin"`,
},
{
input: []string{"Baby Yoda", "Grogu"},
expected: `"Baby Yoda" or "Grogu"`,
},
{
input: []string{"This", "is", "the", "way"},
expected: `"This", "is", "the" or "way"`,
},
}

for _, v := range testData {
t.Logf("[DEBUG] Testing %q..", v.input)

actual := QuotedStringSlice(v.input)
if v.expected != actual {
t.Fatalf("Expected %s but got %s", v.expected, actual)
}
}
}
3 changes: 3 additions & 0 deletions azurerm/internal/clients/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ import (
privatedns "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/privatedns/client"
recoveryServices "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/recoveryservices/client"
redis "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/redis/client"
redisenterprise "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/redisenterprise/client"
relay "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/relay/client"
resource "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/resource/client"
search "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/search/client"
Expand Down Expand Up @@ -172,6 +173,7 @@ type Client struct {
PrivateDns *privatedns.Client
RecoveryServices *recoveryServices.Client
Redis *redis.Client
RedisEnterprise *redisenterprise.Client
Relay *relay.Client
Resource *resource.Client
Search *search.Client
Expand Down Expand Up @@ -270,6 +272,7 @@ func (client *Client) Build(ctx context.Context, o *common.ClientOptions) error
client.PrivateDns = privatedns.NewClient(o)
client.RecoveryServices = recoveryServices.NewClient(o)
client.Redis = redis.NewClient(o)
client.RedisEnterprise = redisenterprise.NewClient(o)
client.Relay = relay.NewClient(o)
client.Resource = resource.NewClient(o)
client.Search = search.NewClient(o)
Expand Down
2 changes: 2 additions & 0 deletions azurerm/internal/provider/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/privatedns"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/recoveryservices"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/redis"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/redisenterprise"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/relay"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/resource"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/search"
Expand Down Expand Up @@ -171,6 +172,7 @@ func SupportedUntypedServices() []sdk.UntypedServiceRegistration {
privatedns.Registration{},
recoveryservices.Registration{},
redis.Registration{},
redisenterprise.Registration{},
relay.Registration{},
resource.Registration{},
search.Registration{},
Expand Down
29 changes: 29 additions & 0 deletions azurerm/internal/services/redisenterprise/client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package client

import (
"github.com/Azure/azure-sdk-for-go/services/redisenterprise/mgmt/2021-03-01/redisenterprise"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common"
)

type Client struct {
Client *redisenterprise.Client
DatabaseClient *redisenterprise.DatabasesClient
OperationsClient *redisenterprise.OperationsClient
}

func NewClient(o *common.ClientOptions) *Client {
client := redisenterprise.NewClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&client.Client, o.ResourceManagerAuthorizer)

databaseClient := redisenterprise.NewDatabasesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&databaseClient.Client, o.ResourceManagerAuthorizer)

operationsClient := redisenterprise.NewOperationsClient(o.ResourceManagerEndpoint)
o.ConfigureClient(&client.Client, o.ResourceManagerAuthorizer)

return &Client{
Client: &client,
DatabaseClient: &databaseClient,
OperationsClient: &operationsClient,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"fmt"
"strings"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
)

type RedisEnterpriseClusterId struct {
SubscriptionId string
ResourceGroup string
RedisEnterpriseName string
}

func NewRedisEnterpriseClusterID(subscriptionId, resourceGroup, redisEnterpriseName string) RedisEnterpriseClusterId {
return RedisEnterpriseClusterId{
SubscriptionId: subscriptionId,
ResourceGroup: resourceGroup,
RedisEnterpriseName: redisEnterpriseName,
}
}

func (id RedisEnterpriseClusterId) String() string {
segments := []string{
fmt.Sprintf("Redis Enterprise Name %q", id.RedisEnterpriseName),
fmt.Sprintf("Resource Group %q", id.ResourceGroup),
}
segmentsStr := strings.Join(segments, " / ")
return fmt.Sprintf("%s: (%s)", "Redis Enterprise Cluster", segmentsStr)
}

func (id RedisEnterpriseClusterId) ID() string {
fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Cache/redisEnterprise/%s"
return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.RedisEnterpriseName)
}

// RedisEnterpriseClusterID parses a RedisEnterpriseCluster ID into an RedisEnterpriseClusterId struct
func RedisEnterpriseClusterID(input string) (*RedisEnterpriseClusterId, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
return nil, err
}

resourceId := RedisEnterpriseClusterId{
SubscriptionId: id.SubscriptionID,
ResourceGroup: id.ResourceGroup,
}

if resourceId.SubscriptionId == "" {
return nil, fmt.Errorf("ID was missing the 'subscriptions' element")
}

if resourceId.ResourceGroup == "" {
return nil, fmt.Errorf("ID was missing the 'resourceGroups' element")
}

if resourceId.RedisEnterpriseName, err = id.PopSegment("redisEnterprise"); err != nil {
return nil, err
}

if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &resourceId, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package parse

import (
"fmt"
"strconv"
"strings"
)

// RedisEnterpriseCacheSku type
type RedisEnterpriseCacheSku struct {
Name string
Capacity string
}

// RedisEnterpriseCacheSkuName parses the input string into a RedisEnterpriseCacheSku type
func RedisEnterpriseCacheSkuName(input string) (*RedisEnterpriseCacheSku, error) {
if len(strings.TrimSpace(input)) == 0 {
return nil, fmt.Errorf("unable to parse Redis Enterprise Cluster 'sku_name' %q", input)
}

skuParts := strings.Split(input, "-")

if len(skuParts) < 2 {
return nil, fmt.Errorf("invalid Redis Enterprise Cluster 'sku_name', got %q", input)
}

if strings.TrimSpace(skuParts[0]) == "" {
return nil, fmt.Errorf("invalid Redis Enterprise Cluster 'sku_name' missing 'name' segment, got %q", input)
}

if strings.TrimSpace(skuParts[1]) == "" {
return nil, fmt.Errorf("invalid Redis Enterprise Cluster 'sku_name' missing 'capacity' segment, got %q", input)
}

_, err := strconv.ParseInt(skuParts[1], 10, 32)
if err != nil {
return nil, fmt.Errorf("invalid Redis Enterprise Cluster 'sku_name', 'capacity' segment must be of type int32 and be a valid int32 value, got %q", skuParts[1])
}

redisEnterpriseCacheSku := RedisEnterpriseCacheSku{
Name: skuParts[0],
Capacity: skuParts[1],
}

return &redisEnterpriseCacheSku, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package parse

import (
"testing"
)

func TestRedisenterpriseSkuName(t *testing.T) {
testData := []struct {
Input string
Error bool
Expected *RedisEnterpriseCacheSku
}{
{
// empty
Input: "",
Error: true,
},
{
// missing sku name and capacity
Input: "-",
Error: true,
},
{
// missing sku name and capacity with multi delimiter
Input: "--",
Error: true,
},
{
// missing sku name
Input: "-1",
Error: true,
},
{
// missing capacity
Input: "Sku1-",
Error: true,
},
{
// invalid capacity type
Input: "Sku1-A",
Error: true,
},
{
// invalid capacity above int32 type
Input: "Sku1-2147483648",
Error: true,
},
{
// valid with ignored extra delimiter
Input: "skuName-1-",
Expected: &RedisEnterpriseCacheSku{
Name: "skuName",
Capacity: "1",
},
},
{
// valid
Input: "skuName-1",
Expected: &RedisEnterpriseCacheSku{
Name: "skuName",
Capacity: "1",
},
},
{
// upper-cased
Input: "SKUNAME-1",
Expected: &RedisEnterpriseCacheSku{
Name: "SKUNAME",
Capacity: "1",
},
},
}

for _, v := range testData {
t.Logf("[DEBUG] Testing %q", v.Input)

actual, err := RedisEnterpriseCacheSkuName(v.Input)
if err != nil {
if v.Error {
continue
}
t.Fatalf("Expected a value but got an error: %s", err)
}

if actual.Name != v.Expected.Name {
t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name)
}

if actual.Capacity != v.Expected.Capacity {
t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name)
}
}
}
Loading

0 comments on commit fa64273

Please sign in to comment.