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

feat(redis): added endpoints #1263

Merged
merged 47 commits into from
Jun 14, 2022
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
69d77c8
feat(redis): cluster resource
Mia-Cross Apr 25, 2022
b72de89
Merge branch 'master' into redis_resource
Monitob Apr 25, 2022
c577339
fix(redis): wait for cluster in create and update instead of read
Codelax Apr 25, 2022
13e7e68
fix(redis): set forcenew to node_type and redis version
Codelax Apr 25, 2022
aff273f
fix(redis): remove id on read if resource does not exist
Codelax Apr 25, 2022
54fe631
fix(redis): remove unused fields
Codelax Apr 25, 2022
dbdfa30
feat(redis): add redis to github workflow
Codelax Apr 25, 2022
39737b7
update cassette
Codelax Apr 25, 2022
c4f61a5
Merge branch 'master' into redis_resource
remyleone Apr 26, 2022
ff5aa89
Update scaleway/resource_redis_cluster.go
remyleone Apr 26, 2022
dc9dd91
Update scaleway/helpers_redis.go
remyleone Apr 26, 2022
ac909ba
feat(redis): add tags to cluster
Codelax Apr 27, 2022
8119917
feat(redis): add cluster_size to cluster schema
Codelax Apr 27, 2022
e812411
feat(redis): add tls_enabled to cluster schema
Codelax Apr 27, 2022
0d0c924
feat(redis): improved tests for basic schema
Mia-Cross Apr 27, 2022
8486b90
feat(redis): added cluster migration
Mia-Cross Apr 27, 2022
4c7b522
feat(redis): update cassettes
Mia-Cross Apr 27, 2022
13958f4
Merge branch 'master' into redis_resource
Codelax Apr 27, 2022
63ab291
fix(redis): remove forcenew for fields used in migration
Codelax Apr 27, 2022
f6f0451
update cassettes
Codelax Apr 27, 2022
286d7d7
add support for created_at, updated_at and cluster_size
remyleone Apr 27, 2022
b4bacfb
fix(redis): skip tags if empty in read
Codelax Apr 27, 2022
c8d1488
doc(redis): added first draft of documentation with supported features
Mia-Cross Apr 27, 2022
b1d4054
feat(redis): added overriding of zone in the tests
Mia-Cross Apr 27, 2022
e2c6d85
feat(redis): debugging endpoints in progress
Mia-Cross May 6, 2022
83e2b7d
Merge scaleway/t/master into fork/t/redis_resource
Mia-Cross May 6, 2022
9a587f4
fixed merge errors
Mia-Cross May 6, 2022
043c2d0
feat(redis): fixed "x_network.attribute not found" error in tests
Mia-Cross May 6, 2022
3659c3c
feat(redis): fixed all tests and added some
Mia-Cross May 6, 2022
facd4af
feat(redis): private_network: can't detach pvn + added doc
Mia-Cross Jun 1, 2022
fbf49c8
Merge branch 'master' into redis_resource
remyleone Jun 1, 2022
942c093
removed unused lb cassette
Mia-Cross Jun 2, 2022
3ed1028
Merge branch 'scaleway:master' into redis_resource
Mia-Cross Jun 8, 2022
fdeb3d0
bug(redis): hasChanges bug + PN: typelist->typeset + moved PN updates…
Mia-Cross Jun 8, 2022
2e7ddf4
fix(redis): fixed tests services_ips so they all end with 0 instead o…
Mia-Cross Jun 8, 2022
f14adac
test(redis): changed back typeSet -> typeList to see if it fixes test…
Mia-Cross Jun 9, 2022
5a606d3
test(redis): added debug prints for another round of CI
Mia-Cross Jun 9, 2022
61e9dcb
test(redis): added cassette for another round of CI
Mia-Cross Jun 9, 2022
d53ff14
feat(redis): removed CI debugging prints + WIP : orderPrivateNetworks…
Mia-Cross Jun 10, 2022
3244f7a
Merge branch 'scaleway:master' into redis_resource
Mia-Cross Jun 10, 2022
e59b829
feat(redis): orderPrivateNetworks functions work (+ tests) + cluster …
Mia-Cross Jun 10, 2022
1a7f163
feat(redis): standalone mode cassette updated
Mia-Cross Jun 10, 2022
674260a
feat(redis): removed depends_on and it still works + removed debug pr…
Mia-Cross Jun 10, 2022
59a36aa
Merge branch 'master' into redis_resource
remyleone Jun 13, 2022
13af290
feat(redis): added custom test function to avoid order pbs + removed …
Mia-Cross Jun 13, 2022
daf80f1
feat(redis): update cassettes after a lot of runs
Mia-Cross Jun 13, 2022
d0c0dca
feat(redis): removed redundant return in helpers_redis
Mia-Cross Jun 14, 2022
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
66 changes: 64 additions & 2 deletions scaleway/helpers_redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,36 @@ func waitForRedisCluster(ctx context.Context, api *redis.API, zone scw.Zone, id
}, scw.WithContext(ctx))
}

func expandRedisPrivateNetwork(data interface{}) ([]*redis.EndpointSpec, error) {
if data == nil {
return nil, nil
}
var epSpecs []*redis.EndpointSpec

for _, rawPN := range data.([]interface{}) {
pn := rawPN.(map[string]interface{})
id := expandID(pn["id"].(string))
rawIPs := pn["service_ips"].([]interface{})
ips := []scw.IPNet(nil)
for _, rawIP := range rawIPs {
ip, err := expandIPNet(rawIP.(string))
if err != nil {
return epSpecs, err
}
ips = append(ips, ip)
}
spec := &redis.EndpointSpecPrivateNetworkSpec{
ID: id,
ServiceIPs: ips,
}
epSpecs = append(epSpecs, &redis.EndpointSpec{PrivateNetwork: spec})
}
return epSpecs, nil
}

func expandRedisACLSpecs(i interface{}) ([]*redis.ACLRuleSpec, error) {
rules := []*redis.ACLRuleSpec(nil)

for _, aclRule := range i.([]interface{}) {
rawRule := aclRule.(map[string]interface{})
rule := &redis.ACLRuleSpec{}
Expand All @@ -71,7 +98,7 @@ func expandRedisACLSpecs(i interface{}) ([]*redis.ACLRuleSpec, error) {
rule.IP = ip
rules = append(rules, rule)
}

return rules, nil
}

Expand Down Expand Up @@ -105,4 +132,39 @@ func flattenRedisSettings(settings []*redis.ClusterSetting) interface{} {
rawSettings[setting.Name] = setting.Value
}
return rawSettings

}
func flattenRedisPrivateNetwork(endpoints []*redis.Endpoint) (interface{}, bool) {
pnFlat := []map[string]interface{}(nil)
for _, endpoint := range endpoints {
if endpoint.PrivateNetwork != nil {
pn := endpoint.PrivateNetwork
pnZonedID := newZonedIDString(pn.Zone, pn.ID)
serviceIps := []interface{}(nil)
for _, ip := range pn.ServiceIPs {
serviceIps = append(serviceIps, ip.String())
}
pnFlat = append(pnFlat, map[string]interface{}{
"id": endpoint.ID,
"zone": pn.Zone,
"private_network_id": pnZonedID,
"service_ips": serviceIps,
})
}
}
return pnFlat, len(pnFlat) != 0
}

func flattenRedisPublicNetwork(endpoints []*redis.Endpoint) interface{} {
pnFlat := []map[string]interface{}(nil)
for _, endpoint := range endpoints {
if endpoint.PublicNetwork != nil {
pnFlat = append(pnFlat, map[string]interface{}{
"id": endpoint.ID,
"port": endpoint.Port,
"ips": endpoint.IPs,
})
}
}
return nil
}
128 changes: 118 additions & 10 deletions scaleway/resource_redis_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
redis "github.com/scaleway/scaleway-sdk-go/api/redis/v1alpha1"
"github.com/scaleway/scaleway-sdk-go/scw"
)
Expand Down Expand Up @@ -71,16 +72,6 @@ func resourceScalewayRedisCluster() *schema.Resource {
Description: "Whether or not TLS is enabled.",
ForceNew: true,
},
"created_at": {
Type: schema.TypeString,
Computed: true,
Description: "The date and time of the creation of the Redis cluster",
},
"updated_at": {
Type: schema.TypeString,
Computed: true,
Description: "The date and time of the last update of the Redis cluster",
},
"acl": {
Type: schema.TypeList,
Description: "List of acl rules.",
Expand Down Expand Up @@ -114,6 +105,75 @@ func resourceScalewayRedisCluster() *schema.Resource {
Type: schema.TypeString,
},
},
"private_network": {
Type: schema.TypeList,
Optional: true,
//MaxItems: 1,
Description: "Private network specs details",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
Description: "UUID of the endpoint to be connected to the cluster",
},
"private_network_id": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validationUUIDorUUIDWithLocality(),
Description: "UUID of the private network to be connected to the cluster",
},
"service_ips": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.IsCIDR,
},
Description: "List of IPv4 addresses of the private network with a CIDR notation",
},
"zone": zoneSchema(),
},
},
},
//Computed
"public_network": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Description: "Public network specs details",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"port": {
Type: schema.TypeInt,
Computed: true,
Description: "TCP port of the endpoint",
},
"ips": {
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Computed: true,
},
},
},
},
"created_at": {
Type: schema.TypeString,
Computed: true,
Description: "The date and time of the creation of the Redis cluster",
},
"updated_at": {
Type: schema.TypeString,
Computed: true,
Description: "The date and time of the last update of the Redis cluster",
},
// Common
"zone": zoneSchema(),
"project_id": projectIDSchema(),
Expand Down Expand Up @@ -162,6 +222,15 @@ func resourceScalewayRedisClusterCreate(ctx context.Context, d *schema.ResourceD
createReq.ClusterSettings = expandRedisSettings(settings)
}

privN, privNExists := d.GetOk("private_network")
if privNExists {
pnSpecs, err := expandRedisPrivateNetwork(privN)
if err != nil {
return diag.FromErr(err)
}
createReq.Endpoints = pnSpecs
}

res, err := redisAPI.CreateCluster(createReq, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
Expand Down Expand Up @@ -213,6 +282,13 @@ func resourceScalewayRedisClusterRead(ctx context.Context, d *schema.ResourceDat
_ = d.Set("tags", cluster.Tags)
}

//set endpoints
pnI, pnExists := flattenRedisPrivateNetwork(cluster.Endpoints)
if pnExists {
_ = d.Set("private_network", pnI)
}
_ = d.Set("public_network", flattenRedisPublicNetwork(cluster.Endpoints))

return nil
}

Expand Down Expand Up @@ -289,6 +365,7 @@ func resourceScalewayRedisClusterUpdate(ctx context.Context, d *schema.ResourceD
if err != nil && !is404Error(err) {
return diag.FromErr(err)
}

_, err = redisAPI.MigrateCluster(&request, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
Expand All @@ -300,6 +377,37 @@ func resourceScalewayRedisClusterUpdate(ctx context.Context, d *schema.ResourceD
}
}

if d.HasChanges("private_network") {
//retrieve state
cluster, err := waitForRedisCluster(ctx, redisAPI, zone, ID, d.Timeout(schema.TimeoutUpdate))
if err != nil {
return diag.FromErr(err)
}

// get new desired state of endpoints
rawNewEndpoints := d.Get("private_network")
newEndpoints, epErr := expandRedisPrivateNetwork(rawNewEndpoints)
if epErr != nil {
return diag.FromErr(epErr)
}

//send request
_, err = redisAPI.SetEndpoints(&redis.SetEndpointsRequest{
Zone: cluster.Zone,
ClusterID: cluster.ID,
Endpoints: newEndpoints,
})
//TODO: jeter un oeil aux requests options
if err != nil {
return diag.FromErr(err)
}

_, err = waitForRedisCluster(ctx, redisAPI, zone, ID, d.Timeout(schema.TimeoutUpdate))
if err != nil {
return diag.FromErr(err)
}
}

_, err = waitForRedisCluster(ctx, redisAPI, zone, ID, d.Timeout(schema.TimeoutUpdate))
if err != nil {
return diag.FromErr(err)
Expand Down
80 changes: 80 additions & 0 deletions scaleway/resource_redis_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ func TestAccScalewayRedisCluster_Basic(t *testing.T) {
Steps: []resource.TestStep{
{
Config: `
provider "scaleway" {
zone = "fr-par-1"
}
resource "scaleway_redis_cluster" "main" {
name = "test_redis_basic"
version = "6.2.6"
Expand All @@ -61,6 +64,7 @@ func TestAccScalewayRedisCluster_Basic(t *testing.T) {
tags = [ "test1" ]
cluster_size = 1
tls_enabled = "true"
zone = "fr-par-2"
}
`,
Check: resource.ComposeTestCheckFunc(
Expand All @@ -73,10 +77,14 @@ func TestAccScalewayRedisCluster_Basic(t *testing.T) {
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "tags.0", "test1"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "cluster_size", "1"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "tls_enabled", "true"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "zone", "fr-par-2"),
),
},
{
Config: `
provider "scaleway" {
zone = "fr-par-1"
}
resource "scaleway_redis_cluster" "main" {
name = "test_redis_basic_edit"
version = "6.2.6"
Expand All @@ -86,6 +94,7 @@ func TestAccScalewayRedisCluster_Basic(t *testing.T) {
tags = [ "test1", "other_tag" ]
cluster_size = 1
tls_enabled = "true"
zone = "fr-par-2"
}
`,
Check: resource.ComposeTestCheckFunc(
Expand All @@ -99,6 +108,7 @@ func TestAccScalewayRedisCluster_Basic(t *testing.T) {
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "tags.1", "other_tag"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "cluster_size", "1"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "tls_enabled", "true"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "zone", "fr-par-2"),
),
},
},
Expand Down Expand Up @@ -298,6 +308,76 @@ func TestAccScalewayRedisCluster_Settings(t *testing.T) {
})
}

func TestAccScalewayRedisCluster_Endpoints(t *testing.T) {
tt := NewTestTools(t)
defer tt.Cleanup()
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: testAccCheckScalewayRedisClusterDestroy(tt),
Steps: []resource.TestStep{
{
Config: `
resource "scaleway_redis_cluster" "main" {
name = "test_redis_endpoints"
version = "6.2.6"
node_type = "MDB-BETA-M"
user_name = "my_initial_user"
password = "thiZ_is_v&ry_s3cret"
cluster_size = 1
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayRedisExists(tt, "scaleway_redis_cluster.main"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "name", "test_redis_endpoints"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "version", "6.2.6"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "node_type", "MDB-BETA-M"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "user_name", "my_initial_user"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "password", "thiZ_is_v&ry_s3cret"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "cluster_size", "1"),
resource.TestCheckResourceAttrSet("scaleway_redis_cluster.main", "public_network.id"),
resource.TestCheckResourceAttrSet("scaleway_redis_cluster.main", "public_network.ips"),
resource.TestCheckResourceAttrSet("scaleway_redis_cluster.main", "public_network.port"),
),
},
{
Config: `
resource "scaleway_vpc_private_network" "pn" {
name = "privateN"
}
resource "scaleway_redis_cluster" "main" {
name = "test_redis_endpoints"
version = "6.2.6"
node_type = "MDB-BETA-M"
user_name = "my_initial_user"
password = "thiZ_is_v&ry_s3cret"
cluster_size = 1
private_network {
private_network_id = "${scaleway_vpc_private_network.pn.id}"
service_ips = [
"10.12.1.0/20",
]
}
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayRedisExists(tt, "scaleway_redis_cluster.main"),
testAccCheckScalewayRedisExists(tt, "scaleway_vpc_private_network.pn"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "name", "test_redis_endpoints"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "version", "6.2.6"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "node_type", "MDB-BETA-M"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "user_name", "my_initial_user"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "password", "thiZ_is_v&ry_s3cret"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "cluster_size", "1"),
resource.TestCheckResourceAttrSet("scaleway_redis_cluster.main", "private_network.id"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "private_network.id", "${scaleway_vpc_private_network.pn.id}"),
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "private_network.service_ips.0", "10.12.1.0/20"),
),
},
},
})
}

func testAccCheckScalewayRedisClusterDestroy(tt *TestTools) resource.TestCheckFunc {
return func(state *terraform.State) error {
for _, rs := range state.RootModule().Resources {
Expand Down
Loading