Skip to content

Commit

Permalink
Make cluster_id understand id as well (#205)
Browse files Browse the repository at this point in the history
Fixes #170. The underlying problem is that anything else but `id` (like `cluster_id`) will not recreate the child resource if the parent resource is changed.
Previously the root token wouldn't be updated when the consul cluster changes, because `cluster.cluster_id` was used instead of `cluster.id`.

Now a root token can be created like this:

```
resource "hcp_consul_cluster_root_token" "token" {
  cluster_id = hcp_consul_cluster.example.id
}
```

and because `id` is used, it will recreate the token when the cluster is updated. Relevant terraform-core issue: hashicorp/terraform#8099.

`cluster_id` now understand both formats. When we release the next major version of this provider, we should only allow `id` going forward.
  • Loading branch information
hanshasselberg authored Oct 18, 2021
1 parent 7ed7142 commit e68bd42
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 5 deletions.
2 changes: 1 addition & 1 deletion docs/guides/consul-root-token.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ resource "hcp_consul_cluster" "example" {
// Create a new ACL root token
resource "hcp_consul_cluster_root_token" "example" {
cluster_id = hcp_consul_cluster.example.cluster_id
cluster_id = hcp_consul_cluster.example.id
}
```

Expand Down
4 changes: 2 additions & 2 deletions examples/guides/consul_cluster_root_token/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ resource "hcp_consul_cluster" "example" {

// Create a new ACL root token
resource "hcp_consul_cluster_root_token" "example" {
cluster_id = hcp_consul_cluster.example.cluster_id
}
cluster_id = hcp_consul_cluster.example.id
}
12 changes: 11 additions & 1 deletion internal/provider/resource_consul_cluster_root_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/base64"
"fmt"
"log"
"path/filepath"
"strings"
"time"

Expand Down Expand Up @@ -47,7 +48,7 @@ func resourceConsulClusterRootToken() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateDiagFunc: validateSlugID,
ValidateDiagFunc: validateSlugIDOrID,
},
// Computed outputs
"accessor_id": {
Expand Down Expand Up @@ -76,6 +77,9 @@ func resourceConsulClusterRootTokenCreate(ctx context.Context, d *schema.Resourc
client := meta.(*clients.Client)

clusterID := d.Get("cluster_id").(string)
if matchesID(clusterID) {
clusterID = filepath.Base(clusterID)
}

// fetch organizationID by project ID
organizationID := client.Config.OrganizationID
Expand Down Expand Up @@ -140,6 +144,9 @@ func resourceConsulClusterRootTokenRead(ctx context.Context, d *schema.ResourceD
client := meta.(*clients.Client)

clusterID := d.Get("cluster_id").(string)
if matchesID(clusterID) {
clusterID = filepath.Base(clusterID)
}
organizationID := client.Config.OrganizationID
projectID := client.Config.ProjectID

Expand Down Expand Up @@ -178,6 +185,9 @@ func resourceConsulClusterRootTokenDelete(ctx context.Context, d *schema.Resourc
client := meta.(*clients.Client)

clusterID := d.Get("cluster_id").(string)
if matchesID(clusterID) {
clusterID = filepath.Base(clusterID)
}
organizationID := client.Config.OrganizationID
projectID := client.Config.ProjectID

Expand Down
29 changes: 28 additions & 1 deletion internal/provider/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,39 @@ func validateSemVer(v interface{}, path cty.Path) diag.Diagnostics {
return diagnostics
}

// matchesID matches /project/11eabb9f-d2ee-9c80-9483-0242ac110013/hashicorp.consul.cluster/example
func matchesID(id string) bool {
return regexp.MustCompile(`/project/\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/hashicorp\.consul\.cluster/.*`).MatchString(id)
}

func matchesSlugID(slugID string) bool {
return regexp.MustCompile(`^[-\da-zA-Z]{3,36}$`).MatchString(slugID)
}

// validateSlugIDOrID validates that the string value matches the HCP requirements for
// an id or slug id.
func validateSlugIDOrID(v interface{}, path cty.Path) diag.Diagnostics {
var diagnostics diag.Diagnostics

if !matchesID(v.(string)) && !matchesSlugID(v.(string)) {
msg := "must be between 3 and 36 characters in length and contains only letters, numbers or hyphens OR must match /project/uuid/hashicorp.consul.cluster/id format"
diagnostics = append(diagnostics, diag.Diagnostic{
Severity: diag.Error,
Summary: msg,
Detail: msg,
AttributePath: path,
})
}

return diagnostics
}

// validateSlugID validates that the string value matches the HCP requirements for
// a user-settable slug.
func validateSlugID(v interface{}, path cty.Path) diag.Diagnostics {
var diagnostics diag.Diagnostics

if !regexp.MustCompile(`^[-\da-zA-Z]{3,36}$`).MatchString(v.(string)) {
if !matchesSlugID(v.(string)) {
msg := "must be between 3 and 36 characters in length and contains only letters, numbers or hyphens"
diagnostics = append(diagnostics, diag.Diagnostic{
Severity: diag.Error,
Expand Down

0 comments on commit e68bd42

Please sign in to comment.