Skip to content

Commit

Permalink
Merge pull request #50 from Scalr/feature/SCALRCORE-15690
Browse files Browse the repository at this point in the history
SCALRCORE-15690: IACP Provider > Multiscope variables
  • Loading branch information
emocharnik committed Feb 15, 2021
2 parents 2434be7 + bd8a63b commit bc839c8
Show file tree
Hide file tree
Showing 6 changed files with 364 additions and 126 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- `scalr_variable`: new attribute `final` ([#50](https://github.com/Scalr/terraform-provider-scalr/pull/50))
- `scalr_variable`: new attribute `force` ([#50](https://github.com/Scalr/terraform-provider-scalr/pull/50))
- `scalr_variable`: new attribute `environment_id` ([#50](https://github.com/Scalr/terraform-provider-scalr/pull/50))
- `scalr_variable`: new attribute `account_id` ([#50](https://github.com/Scalr/terraform-provider-scalr/pull/50))

### Changed

- `scalr_variable`: attribute `workspace_id` is optional ([#50](https://github.com/Scalr/terraform-provider-scalr/pull/50))

### Required

- scalr server >= `8.0.1-beta.20201202`

## [1.0.0-rc13] - 2021-02-04

### Changed
Expand Down Expand Up @@ -175,6 +190,7 @@ Requires Scalr 8.0.1-beta.20200625 at least
- Initial release.

[Unreleased]: https://github.com/Scalr/terraform-provider-scalr/compare/v1.0.0-rc13...HEAD
[1.0.0-rc14]: https://github.com/Scalr/terraform-provider-scalr/releases/tag/v1.0.0-rc14
[1.0.0-rc13]: https://github.com/Scalr/terraform-provider-scalr/releases/tag/v1.0.0-rc13
[1.0.0-rc12]: https://github.com/Scalr/terraform-provider-scalr/releases/tag/v1.0.0-rc12
[1.0.0-rc11]: https://github.com/Scalr/terraform-provider-scalr/releases/tag/v1.0.0-rc11
Expand Down
7 changes: 6 additions & 1 deletion docs/resources/scalr_variable.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ resource "scalr_variable" "example" {
* `category` - (Required) Indicates if this is a Terraform or environment variable. Allowed values are `terraform` or `env`.
* `hcl` - (Optional) Set (true/false) to configure the variable as a string of HCL code. Has no effect for `category = "env"` variables. Default `false`.
* `sensitive` - (Optional) Set (true/false) to configure as sensitive. Sensitive variable values are not visible after being set. Default `false`.
* `workspace_id` - (Required) The workspace that owns the variable, specified as an ID, in the format `ws-<RANDOM STRING>`.
* `final` - (Optional) Set (true/false) to configure as final. Indicates whether the variable can be overridden on a lower scope down the Scalr organizational model. Default `false`.
* `force` - (Optional) Set (true/false) to configure as force. Allows creating final variables on higher scope, even if the same variable exists on lower scope (lower is to be deleted). Default `false`.
* `workspace_id` - (Optional) The workspace that owns the variable, specified as an ID, in the format `ws-<RANDOM STRING>`.
* `environment_id` - (Optional) The environment that owns the variable, specified as an ID, in the format `env-<RANDOM STRING>`.
* `account_id` - (Optional) The account that owns the variable, specified as an ID, in the format `acc-<RANDOM STRING>`.


## Attribute Reference

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/hashicorp/terraform v0.12.0
github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/scalr/go-scalr v0.0.0-20210119110643-9039cc40492e
github.com/scalr/go-scalr v0.0.0-20210210153908-cc4b896f1392
)

go 1.13
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,12 @@ github.com/scalr/go-scalr v0.0.0-20201202105129-922fc963a53b h1:JIXSPuMw2wdOeTnl
github.com/scalr/go-scalr v0.0.0-20201202105129-922fc963a53b/go.mod h1:eEDwNsOdDKg5TJHljpJWfb4LhobfCkUHZo/uX/rPph8=
github.com/scalr/go-scalr v0.0.0-20210119110643-9039cc40492e h1:TkyqxRvCMLhEtRl2MOp6KwDtLun9XGh6aEqErJOFv8I=
github.com/scalr/go-scalr v0.0.0-20210119110643-9039cc40492e/go.mod h1:n2HQ6QxqyTySiSFTOpAL18SjCKtP+xUskMygO0KuuQU=
github.com/scalr/go-scalr v0.0.0-20210205141334-db4e3372ed61 h1:0uDGwtHyaSe3CMKK3VjkNvfmX9mM89G1P4f5ytTO6X8=
github.com/scalr/go-scalr v0.0.0-20210205141334-db4e3372ed61/go.mod h1:n2HQ6QxqyTySiSFTOpAL18SjCKtP+xUskMygO0KuuQU=
github.com/scalr/go-scalr v0.0.0-20210210152453-7bb6d92151c1 h1:gHAzXQxf45R84FzNk/EVL9yvMiALsQF/hy881+SRkUo=
github.com/scalr/go-scalr v0.0.0-20210210152453-7bb6d92151c1/go.mod h1:n2HQ6QxqyTySiSFTOpAL18SjCKtP+xUskMygO0KuuQU=
github.com/scalr/go-scalr v0.0.0-20210210153908-cc4b896f1392 h1:5omVbEGt+45vY40jFHAxR4s+ARr/csBQfGHtxSQ1HsI=
github.com/scalr/go-scalr v0.0.0-20210210153908-cc4b896f1392/go.mod h1:n2HQ6QxqyTySiSFTOpAL18SjCKtP+xUskMygO0KuuQU=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
Expand Down
133 changes: 88 additions & 45 deletions scalr/resource_scalr_variable.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
package scalr

import (
"errors"
"fmt"
"log"
"strings"

"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
scalr "github.com/scalr/go-scalr"
)

var errVariableMultiOnlyEnv = errors.New("Only environment variables should be multi-scoped.")

func resourceScalrVariable() *schema.Resource {
return &schema.Resource{
Create: resourceScalrVariableCreate,
Read: resourceScalrVariableRead,
Update: resourceScalrVariableUpdate,
Delete: resourceScalrVariableDelete,
Importer: &schema.ResourceImporter{
State: resourceScalrVariableImporter,
State: schema.ImportStatePassthrough,
},

SchemaVersion: 1,
Expand Down Expand Up @@ -67,9 +69,33 @@ func resourceScalrVariable() *schema.Resource {
Default: false,
},

"final": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},

"force": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},

"workspace_id": {
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
},

"environment_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},

"account_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
},
Expand All @@ -81,24 +107,48 @@ func resourceScalrVariableCreate(d *schema.ResourceData, meta interface{}) error

// Get key and category.
key := d.Get("key").(string)
category := d.Get("category").(string)

// Get the workspace.
workspaceID := d.Get("workspace_id").(string)
ws, err := scalrClient.Workspaces.ReadByID(ctx, workspaceID)
if err != nil {
return fmt.Errorf(
"Error retrieving workspace %s: %v", workspaceID, err)
}
category := scalr.CategoryType(d.Get("category").(string))

// Create a new options struct.
options := scalr.VariableCreateOptions{
Key: scalr.String(key),
Value: scalr.String(d.Get("value").(string)),
Category: scalr.Category(scalr.CategoryType(category)),
HCL: scalr.Bool(d.Get("hcl").(bool)),
Sensitive: scalr.Bool(d.Get("sensitive").(bool)),
Workspace: ws,
Key: scalr.String(key),
Value: scalr.String(d.Get("value").(string)),
Category: scalr.Category(category),
HCL: scalr.Bool(d.Get("hcl").(bool)),
Sensitive: scalr.Bool(d.Get("sensitive").(bool)),
Final: scalr.Bool(d.Get("final").(bool)),
QueryOptions: &scalr.VariableWriteQueryOptions{Force: scalr.Bool(d.Get("force").(bool))},
}

// Get and check the workspace.
if workspaceID, ok := d.GetOk("workspace_id"); ok {
ws, err := scalrClient.Workspaces.ReadByID(ctx, workspaceID.(string))
if err != nil {
return fmt.Errorf(
"Error retrieving workspace %s: %v", workspaceID, err)
}
options.Workspace = ws
} else {
if category == scalr.CategoryTerraform {
return errVariableMultiOnlyEnv
}
}

// Get and check the environment
if environmentId, ok := d.GetOk("environment_id"); ok {
env, err := scalrClient.Environments.Read(ctx, environmentId.(string))
if err != nil {
return fmt.Errorf(
"Error retrieving environment %s: %v", environmentId, err)
}
options.Environment = env
}

// Get the account
if accountId, ok := d.GetOk("account_id"); ok {
options.Account = &scalr.Account{
ID: accountId.(string),
}
}

log.Printf("[DEBUG] Create %s variable: %s", category, key)
Expand Down Expand Up @@ -131,6 +181,20 @@ func resourceScalrVariableRead(d *schema.ResourceData, meta interface{}) error {
d.Set("category", string(variable.Category))
d.Set("hcl", variable.HCL)
d.Set("sensitive", variable.Sensitive)
d.Set("final", variable.Final)
_, exists := d.GetOk("force")
if !exists {
d.Set("force", false)
}
if variable.Account != nil {
d.Set("account_id", variable.Account.ID)
}
if variable.Environment != nil {
d.Set("environment_id", variable.Environment.ID)
}
if variable.Workspace != nil {
d.Set("workspace_id", variable.Workspace.ID)
}

// Only set the value if its not sensitive, as otherwise it will be empty.
if !variable.Sensitive {
Expand All @@ -145,10 +209,12 @@ func resourceScalrVariableUpdate(d *schema.ResourceData, meta interface{}) error

// Create a new options struct.
options := scalr.VariableUpdateOptions{
Key: scalr.String(d.Get("key").(string)),
Value: scalr.String(d.Get("value").(string)),
HCL: scalr.Bool(d.Get("hcl").(bool)),
Sensitive: scalr.Bool(d.Get("sensitive").(bool)),
Key: scalr.String(d.Get("key").(string)),
Value: scalr.String(d.Get("value").(string)),
HCL: scalr.Bool(d.Get("hcl").(bool)),
Sensitive: scalr.Bool(d.Get("sensitive").(bool)),
Final: scalr.Bool(d.Get("final").(bool)),
QueryOptions: &scalr.VariableWriteQueryOptions{Force: scalr.Bool(d.Get("force").(bool))},
}

log.Printf("[DEBUG] Update variable: %s", d.Id())
Expand All @@ -174,26 +240,3 @@ func resourceScalrVariableDelete(d *schema.ResourceData, meta interface{}) error

return nil
}

func resourceScalrVariableImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
scalrClient := meta.(*scalr.Client)
s := strings.SplitN(d.Id(), "/", 3)
log.Printf("[DEBUG] in resourceScalrVariableImporter: %s", s[0])
if len(s) != 3 {
return nil, fmt.Errorf(
"invalid variable import format: %s (expected <ENVIRONMENT ID>/<WORKSPACE NAME>/<VARIABLE ID>)",
d.Id(),
)
}

// Set the fields that are part of the import ID.
workspaceID, err := fetchWorkspaceID(s[0]+"/"+s[1], scalrClient)
if err != nil {
return nil, fmt.Errorf(
"error retrieving workspace %s from environment %s: %v", s[1], s[0], err)
}
d.Set("workspace_id", workspaceID)
d.SetId(s[2])

return []*schema.ResourceData{d}, nil
}

0 comments on commit bc839c8

Please sign in to comment.