Skip to content

Commit

Permalink
Merge branch 'master' into sc-80955/terraform-provider-database-resou…
Browse files Browse the repository at this point in the history
…rce-a-change
  • Loading branch information
jessicatoscani authored Jan 26, 2024
2 parents 00a55e9 + 7b632df commit 9e3a4cf
Show file tree
Hide file tree
Showing 22 changed files with 836 additions and 363 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
IMPROVEMENTS:

- Bump golang.org/x/crypto from 0.14.0 to 0.17.0 (#323)
- sks_nodepool: add an example for taints #324
- sks_nodepool: add an example for taints #324
- SKS tests: renable cluster update test as upstream bug is fixed (#309)
- Make `iam_role.name` attribute require replace as per API behaviour (#330)


BUG FIXES:
Expand All @@ -14,6 +16,7 @@ BUG FIXES:
- Bump dependencies (#329)
- database: change of plan should not recreate resource (#327)
- database: UseStateForUnknown for state and maintenance (#331)
- iam: fix bug in `iam_role` and `iam_org_policy` rules update (#330)

## 0.54.1 (December 6, 2023)

Expand Down
2 changes: 1 addition & 1 deletion docs/resources/iam_role.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Manage Exoscale [IAM](https://community.exoscale.com/documentation/iam/) Role.

### Required

- `name` (String) Name of IAM Role.
- `name` (String) Name of IAM Role.

### Optional

Expand Down
54 changes: 53 additions & 1 deletion exoscale/resource_exoscale_sks_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import (
"encoding/base64"
"errors"
"fmt"
"time"

"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

egoscale "github.com/exoscale/egoscale/v2"
exov2 "github.com/exoscale/egoscale/v2"
exoapi "github.com/exoscale/egoscale/v2/api"
"github.com/exoscale/terraform-provider-exoscale/pkg/config"
"github.com/exoscale/terraform-provider-exoscale/pkg/general"
Expand Down Expand Up @@ -404,6 +406,35 @@ func resourceSKSClusterRead(ctx context.Context, d *schema.ResourceData, meta in
return diag.FromErr(resourceSKSClusterApply(ctx, d, sksCluster, certificates))
}

func waitForClusterUpdateToSucceed(ctx context.Context, client *exov2.Client, zone, clusterID string) error {
ticker := time.NewTicker(3 * time.Second)
defer ticker.Stop()

hasStartedUpdate := false
for {
select {
case <-ticker.C:
cluster, err := client.GetSKSCluster(ctx, zone, clusterID)
if err != nil {
return err
}

if hasStartedUpdate && *cluster.State != "updating" {
return nil
} else if *cluster.State == "updating" {
hasStartedUpdate = true
}
case <-ctx.Done():
err := ctx.Err()
if err != nil {
return err
}

return nil
}
}
}

func resourceSKSClusterUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
tflog.Debug(ctx, "beginning update", map[string]interface{}{
"id": resourceSKSClusterIDString(d),
Expand Down Expand Up @@ -460,7 +491,28 @@ func resourceSKSClusterUpdate(ctx context.Context, d *schema.ResourceData, meta
}

if updated {
if err = client.UpdateSKSCluster(ctx, zone, sksCluster); err != nil {
// due to a bug it's possible for the update operation
// to remain in pending state forever
// we work around this by checking the cluster state
updateErrChan := make(chan error)
getErrChan := make(chan error)

go func() {
updateErrChan <- client.UpdateSKSCluster(ctx, zone, sksCluster)
}()

go func() {
getErrChan <- waitForClusterUpdateToSucceed(ctx, client, zone, *sksCluster.ID)
}()

var err error

select {
case err = <-updateErrChan:
case err = <-getErrChan:
}

if err != nil {
return diag.FromErr(err)
}
}
Expand Down
165 changes: 70 additions & 95 deletions exoscale/resource_exoscale_sks_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import (
)

var (
testAccResourceSKSClusterLabelValue = acctest.RandomWithPrefix(testPrefix)
// testAccResourceSKSClusterLabelValueUpdated = testAccResourceSKSClusterLabelValue + "-updated"
testAccResourceSKSClusterName = acctest.RandomWithPrefix(testPrefix)
// testAccResourceSKSClusterNameUpdated = testAccResourceSKSClusterName + "-updated"
testAccResourceSKSClusterLabelValue = acctest.RandomWithPrefix(testPrefix)
testAccResourceSKSClusterLabelValueUpdated = testAccResourceSKSClusterLabelValue + "-updated"
testAccResourceSKSClusterName = acctest.RandomWithPrefix(testPrefix)
testAccResourceSKSClusterNameUpdated = testAccResourceSKSClusterName + "-updated"
testAccResourceSKSClusterOIDCClientID = acctest.RandString(10)
testAccResourceSKSClusterOIDCGroupsClaim = acctest.RandString(10)
testAccResourceSKSClusterOIDCGroupsPrefix = acctest.RandString(10)
Expand All @@ -30,7 +30,7 @@ var (
testAccResourceSKSClusterOIDCUsernameClaim = acctest.RandString(10)
testAccResourceSKSClusterOIDCUsernamePrefix = acctest.RandString(10)
testAccResourceSKSClusterDescription = acctest.RandString(10)
// testAccResourceSKSClusterDescriptionUpdated = testAccResourceSKSClusterDescription + "-updated"
testAccResourceSKSClusterDescriptionUpdated = testAccResourceSKSClusterDescription + "-updated"

testAccResourceSKSClusterConfigCreate = fmt.Sprintf(`
locals {
Expand Down Expand Up @@ -89,45 +89,45 @@ resource "exoscale_sks_nodepool" "test" {
testAccResourceSKSClusterOIDCUsernamePrefix,
)

// testAccResourceSKSClusterConfigUpdate = fmt.Sprintf(`
// locals {
// zone = "%s"
// }
//
// resource "exoscale_sks_cluster" "test" {
// zone = local.zone
// name = "%s"
// description = "%s"
// exoscale_ccm = true
// metrics_server = false
// auto_upgrade = true
// labels = {
// test = "%s"
// }
//
// timeouts {
// create = "10m"
// }
// }
//
// resource "exoscale_sks_nodepool" "test" {
// zone = local.zone
// cluster_id = exoscale_sks_cluster.test.id
// name = "test"
// instance_type = "standard.small"
// disk_size = 20
// size = 1
//
// timeouts {
// create = "10m"
// }
// }
// `,
// testZoneName,
// testAccResourceSKSClusterNameUpdated,
// testAccResourceSKSClusterDescriptionUpdated,
// testAccResourceSKSClusterLabelValueUpdated,
// )
testAccResourceSKSClusterConfigUpdate = fmt.Sprintf(`
locals {
zone = "%s"
}
resource "exoscale_sks_cluster" "test" {
zone = local.zone
name = "%s"
description = "%s"
exoscale_ccm = true
metrics_server = false
auto_upgrade = true
labels = {
test = "%s"
}
timeouts {
create = "10m"
}
}
resource "exoscale_sks_nodepool" "test" {
zone = local.zone
cluster_id = exoscale_sks_cluster.test.id
name = "test"
instance_type = "standard.small"
disk_size = 20
size = 1
timeouts {
create = "10m"
}
}
`,
testZoneName,
testAccResourceSKSClusterNameUpdated,
testAccResourceSKSClusterDescriptionUpdated,
testAccResourceSKSClusterLabelValueUpdated,
)

testAccResourceSKSClusterConfig2Format = `
locals {
Expand Down Expand Up @@ -223,54 +223,29 @@ func TestAccResourceSKSCluster(t *testing.T) {
})),
),
},
// NOTE: Temporarily disabled Update test until upstream fix lands:
// https://app.shortcut.com/exoscale/story/77029/tf-provider-sks-acc-test-times-out-after-a-cluster-update
// {
// // Update
// Config: testAccResourceSKSClusterConfigUpdate,
// Check: resource.ComposeTestCheckFunc(
// testAccCheckResourceSKSClusterExists(r, &sksCluster),
// func(s *terraform.State) error {
// a := assert.New(t)
//
// a.True(defaultBool(sksCluster.AutoUpgrade, false))
// a.Equal(testAccResourceSKSClusterDescriptionUpdated, *sksCluster.Description)
// a.Equal(testAccResourceSKSClusterLabelValueUpdated, (*sksCluster.Labels)["test"])
// a.Equal(testAccResourceSKSClusterNameUpdated, *sksCluster.Name)
//
// // Wait for the cluster to be in the Running state
// for i := 0; i < 60; i++ {
// c, err := client.GetSKSCluster(clientctx, testZoneName, *sksCluster.ID)
// if err != nil {
// return fmt.Errorf("failed to fetch sks cluster: %s", err)
// }
// if *c.State == "running" {
// return nil
// }
// t.Logf("waiting for cluster to be Running, current state: %s", *c.State)
// time.Sleep(10 * time.Second)
// }
//
// return fmt.Errorf("timeout waiting for the cluster to be Running: current state")
// },
// checkResourceState(r, checkResourceStateValidateAttributes(testAttrs{
// resSKSClusterAttrAggregationLayerCA: validation.ToDiagFunc(validation.StringMatch(testPemCertificateFormatRegex, "Aggregation CA must be a PEM certificate")),
// resSKSClusterAttrAutoUpgrade: validateString("true"),
// resSKSClusterAttrCNI: validateString(defaultSKSClusterCNI),
// resSKSClusterAttrControlPlaneCA: validation.ToDiagFunc(validation.StringMatch(testPemCertificateFormatRegex, "Control-plane CA must be a PEM certificate")),
// resSKSClusterAttrCreatedAt: validation.ToDiagFunc(validation.NoZeroValues),
// resSKSClusterAttrDescription: validateString(testAccResourceSKSClusterDescriptionUpdated),
// resSKSClusterAttrEndpoint: validation.ToDiagFunc(validation.IsURLWithHTTPS),
// resSKSClusterAttrExoscaleCCM: validateString("true"),
// resSKSClusterAttrKubeletCA: validation.ToDiagFunc(validation.StringMatch(testPemCertificateFormatRegex, "Kubelet CA must be a PEM certificate")),
// resSKSClusterAttrMetricsServer: validateString("false"),
// resSKSClusterAttrLabels + ".test": validateString(testAccResourceSKSClusterLabelValueUpdated),
// resSKSClusterAttrName: validateString(testAccResourceSKSClusterNameUpdated),
// resSKSClusterAttrServiceLevel: validateString(defaultSKSClusterServiceLevel),
// resSKSClusterAttrState: validation.ToDiagFunc(validation.NoZeroValues),
// })),
// ),
// },
{
// Update
Config: testAccResourceSKSClusterConfigUpdate,
Check: resource.ComposeTestCheckFunc(
testAccCheckResourceSKSClusterExists(r, &sksCluster),
checkResourceState(r, checkResourceStateValidateAttributes(testAttrs{
resSKSClusterAttrAggregationLayerCA: validation.ToDiagFunc(validation.StringMatch(testPemCertificateFormatRegex, "Aggregation CA must be a PEM certificate")),
resSKSClusterAttrAutoUpgrade: validateString("true"),
resSKSClusterAttrCNI: validateString(defaultSKSClusterCNI),
resSKSClusterAttrControlPlaneCA: validation.ToDiagFunc(validation.StringMatch(testPemCertificateFormatRegex, "Control-plane CA must be a PEM certificate")),
resSKSClusterAttrCreatedAt: validation.ToDiagFunc(validation.NoZeroValues),
resSKSClusterAttrDescription: validateString(testAccResourceSKSClusterDescriptionUpdated),
resSKSClusterAttrEndpoint: validation.ToDiagFunc(validation.IsURLWithHTTPS),
resSKSClusterAttrExoscaleCCM: validateString("true"),
resSKSClusterAttrKubeletCA: validation.ToDiagFunc(validation.StringMatch(testPemCertificateFormatRegex, "Kubelet CA must be a PEM certificate")),
resSKSClusterAttrMetricsServer: validateString("false"),
resSKSClusterAttrLabels + ".test": validateString(testAccResourceSKSClusterLabelValueUpdated),
resSKSClusterAttrName: validateString(testAccResourceSKSClusterNameUpdated),
resSKSClusterAttrServiceLevel: validateString(defaultSKSClusterServiceLevel),
resSKSClusterAttrState: validation.ToDiagFunc(validation.NoZeroValues),
})),
),
},
{
// Import
ResourceName: r,
Expand Down Expand Up @@ -300,13 +275,13 @@ func TestAccResourceSKSCluster(t *testing.T) {
resSKSClusterAttrCNI: validateString(defaultSKSClusterCNI),
resSKSClusterAttrControlPlaneCA: validation.ToDiagFunc(validation.StringMatch(testPemCertificateFormatRegex, "Control-plane CA must be a PEM certificate")),
resSKSClusterAttrCreatedAt: validation.ToDiagFunc(validation.NoZeroValues),
resSKSClusterAttrDescription: validateString(testAccResourceSKSClusterDescription),
resSKSClusterAttrDescription: validateString(testAccResourceSKSClusterDescriptionUpdated),
resSKSClusterAttrEndpoint: validation.ToDiagFunc(validation.IsURLWithHTTPS),
resSKSClusterAttrExoscaleCCM: validateString("true"),
resSKSClusterAttrKubeletCA: validation.ToDiagFunc(validation.StringMatch(testPemCertificateFormatRegex, "Kubelet CA must be a PEM certificate")),
resSKSClusterAttrMetricsServer: validateString("false"),
resSKSClusterAttrLabels + ".test": validateString(testAccResourceSKSClusterLabelValue),
resSKSClusterAttrName: validateString(testAccResourceSKSClusterName),
resSKSClusterAttrLabels + ".test": validateString(testAccResourceSKSClusterLabelValueUpdated),
resSKSClusterAttrName: validateString(testAccResourceSKSClusterNameUpdated),
resSKSClusterAttrServiceLevel: validateString(defaultSKSClusterServiceLevel),
resSKSClusterAttrState: validation.ToDiagFunc(validation.NoZeroValues),
resSKSClusterAttrVersion: validation.ToDiagFunc(validation.NoZeroValues),
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module github.com/exoscale/terraform-provider-exoscale

require (
github.com/exoscale/egoscale v0.102.1
github.com/exoscale/egoscale v0.102.3
github.com/google/go-cmp v0.6.0
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
Expand Down Expand Up @@ -76,7 +76,7 @@ require (
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/zclconf/go-cty v1.14.1 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.18.0 // indirect
golang.org/x/sys v0.15.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.
github.com/deepmap/oapi-codegen v1.9.1 h1:yHmEnA7jSTUMQgV+uN02WpZtwHnz2CBW3mZRIxr1vtI=
github.com/deepmap/oapi-codegen v1.9.1/go.mod h1:PLqNAhdedP8ttRpBBkzLKU3bp+Fpy+tTgeAMlztR2cw=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/exoscale/egoscale v0.102.1 h1:Wc5ogjhl+ws5kElDg9+AKU4QVXPsXBweFCmnhn1FMOc=
github.com/exoscale/egoscale v0.102.1/go.mod h1:szh4hWSVh+ylgfti4AFR4mkRaCfUyUXSKS3PihlcOco=
github.com/exoscale/egoscale v0.102.3 h1:DYqN2ipoLKpiFoprRGQkp2av/Ze7sUYYlGhi1N62tfY=
github.com/exoscale/egoscale v0.102.3/go.mod h1:RPf2Gah6up+6kAEayHTQwqapzXlm93f0VQas/UEGU5c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
Expand Down Expand Up @@ -281,8 +281,8 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb h1:mIKbk8weKhSeLH2GmUTrvx8CjkyJmnU1wFmg59CUjFA=
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
Expand Down
6 changes: 3 additions & 3 deletions pkg/resources/iam/resource_api_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func (r *ResourceAPIKey) Create(ctx context.Context, req resource.CreateRequest,
data.Secret = types.StringValue(secret)

// Read created policy
r.read(ctx, resp.Diagnostics, &data)
r.read(ctx, &resp.Diagnostics, &data)
if resp.Diagnostics.HasError() {
return
}
Expand Down Expand Up @@ -173,7 +173,7 @@ func (r *ResourceAPIKey) Read(ctx context.Context, req resource.ReadRequest, res

ctx = exoapi.WithEndpoint(ctx, exoapi.NewReqEndpoint(r.env, config.DefaultZone))

r.read(ctx, resp.Diagnostics, &data)
r.read(ctx, &resp.Diagnostics, &data)
if resp.Diagnostics.HasError() {
return
}
Expand Down Expand Up @@ -251,7 +251,7 @@ func (r *ResourceAPIKey) ImportState(ctx context.Context, req resource.ImportSta

func (r *ResourceAPIKey) read(
ctx context.Context,
d diag.Diagnostics,
d *diag.Diagnostics,
data *ResourceAPIKeyModel,
) {
apiKey, err := r.client.GetAPIKey(
Expand Down
2 changes: 1 addition & 1 deletion pkg/resources/iam/resource_api_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package iam_test

import (
"bytes"
"html/template"
"testing"
"text/template"

"github.com/exoscale/terraform-provider-exoscale/pkg/testutils"

Expand Down
Loading

0 comments on commit 9e3a4cf

Please sign in to comment.