Skip to content

Commit

Permalink
Support cloud66_env_variable
Browse files Browse the repository at this point in the history
  • Loading branch information
itsmechlark committed Apr 12, 2022
1 parent 76165a7 commit 68e76e5
Show file tree
Hide file tree
Showing 8 changed files with 451 additions and 3 deletions.
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.1.8] - 2022-04-01
## [0.2.0] - 2022-04-12
### Added
- **New Resource**: `cloud66_env_variable`
- **New Data Source**: `cloud66_env_variable`

## [0.1.8] - 2022-04-01
### Fixed
- Import SSL certificate

## [0.1.0] - 2022-03-06

### Added

- **New Resource**: `cloud66_ssl_certificate`
Expand Down
38 changes: 38 additions & 0 deletions cloud66/data_source_env_variable.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package cloud66

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceCloud66EnvVariable() *schema.Resource {
return &schema.Resource{
Read: dataSourceCloud66EnvVariableRead,
Schema: map[string]*schema.Schema{
"stack_id": {
Type: schema.TypeString,
Required: true,
},
"key": {
Type: schema.TypeString,
Required: true,
},
"value": {
Type: schema.TypeString,
Optional: true,
Sensitive: true,
},
"readonly": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
},
}
}

func dataSourceCloud66EnvVariableRead(d *schema.ResourceData, meta interface{}) error {
key := d.Get("key").(string)
d.SetId(key)

return resourceCloud66EnvVariableRead(d, meta)
}
66 changes: 66 additions & 0 deletions cloud66/data_source_env_variable_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package cloud66

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestAccCloud66EnvVariableDataSource(t *testing.T) {

t.Parallel()

rnd := generateRandomResourceName()
stackID := generateRandomUid()
key := generateRandomEnvKey()
value := generateRandomEnvValue()

name := fmt.Sprintf("data.cloud66_env_variable.%s", rnd)

testAccCloud66EnvVariable(stackID, key, value)

resource.Test(t, resource.TestCase{
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCloud66EnvVariableDataSource(stackID, rnd, key),
Check: resource.ComposeTestCheckFunc(
testAccCheckCloud66EnvVariableDataSourceID(name, key),
resource.TestCheckResourceAttr(name, "stack_id", stackID),
resource.TestCheckResourceAttr(name, "key", key),
resource.TestCheckResourceAttr(name, "value", value),
),
},
},
})
}

func testAccCloud66EnvVariableDataSource(stactID string, rnd string, key string) string {
return fmt.Sprintf(`
provider "cloud66" {
access_token = "%[1]s"
}
data "cloud66_env_variable" "%[3]s" {
stack_id = "%[2]s"
key = "%[4]s"
}
`, testAccCloud66AccessToken, stactID, rnd, key)
}

func testAccCheckCloud66EnvVariableDataSourceID(n string, key string) resource.TestCheckFunc {
return func(s *terraform.State) error {
all := s.RootModule().Resources
rs, ok := all[n]
if !ok {
return fmt.Errorf("can't find env variable data source: %s", n)
}

if rs.Primary.ID != key {
return fmt.Errorf("Snapshot stacks source ID not set")
}
return nil
}
}
4 changes: 3 additions & 1 deletion cloud66/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ func Provider() *schema.Provider {
ConfigureFunc: providerConfigure,

DataSourcesMap: map[string]*schema.Resource{
"cloud66_stack": dataSourceCloud66Stack(),
"cloud66_env_variable": dataSourceCloud66EnvVariable(),
"cloud66_stack": dataSourceCloud66Stack(),
},
ResourcesMap: map[string]*schema.Resource{
"cloud66_env_variable": resourceCloud66EnvVariable(),
"cloud66_ssl_certificate": resourceCloud66SslCertificate(),
},
}
Expand Down
60 changes: 60 additions & 0 deletions cloud66/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ func generateRandomUid() string {
return acctest.RandStringFromCharSet(32, acctest.CharSetAlphaNum)
}

func generateRandomEnvKey() string {
return acctest.RandString(10)
}

func generateRandomEnvValue() string {
return acctest.RandString(10)
}

func init() {
httpmock.Activate()
}
Expand Down Expand Up @@ -253,3 +261,55 @@ func testAccCloud66SslCertificateManual(stackID string, uid string) {
httpmock.RegisterResponder("GET", "https://app.cloud66.com/api/3/stacks/"+stackID+"/ssl_certificates.json", httpmock.NewStringResponder(200, listSslResponse))
httpmock.RegisterResponder("DELETE", "https://app.cloud66.com/api/3/stacks/"+stackID+"/ssl_certificates/ssl-"+uid+".json", httpmock.NewStringResponder(200, deleteSslResponse))
}

func testAccCloud66EnvVariable(stackID string, key string, value string) {
envVarData := fmt.Sprintf(`
{
"id": 2426460,
"key": "%[1]s",
"value": "%[2]s",
"readonly": false,
"created_at": "2019-10-23T14:15:53Z",
"updated_at": "2020-03-04T12:48:25Z",
"is_password": false,
"is_generated": false,
"history": []
}`, key, value)

listEnvVarResponse := fmt.Sprintf(`
{
"response": [%[1]s],
"count": 1,
"pagination": {
"previous": null,
"next": null,
"current": 1,
"per_page": 30,
"count": 1,
"pages": 1
}
}`, envVarData)
createEnvVarResponse := fmt.Sprint(`
{
"response": {
"id": 3360669,
"user": "[email protected]",
"resource_type": "stack",
"action": "env-var-new",
"resource_id": "66204",
"started_via": "api",
"started_at": "2022-04-12T10:12:46Z",
"finished_at": null,
"finished_success": null,
"finished_message": null,
"finished_result": null
}
}`)
updateEnvVarResponse := createEnvVarResponse
deleteEnvVarResponse := createEnvVarResponse

httpmock.RegisterResponder("POST", "https://app.cloud66.com/api/3/stacks/"+stackID+"/environments.json", httpmock.NewStringResponder(200, createEnvVarResponse))
httpmock.RegisterResponder("GET", "https://app.cloud66.com/api/3/stacks/"+stackID+"/environments.json", httpmock.NewStringResponder(200, listEnvVarResponse))
httpmock.RegisterResponder("PUT", "https://app.cloud66.com/api/3/stacks/"+stackID+"/environments/"+key+".json", httpmock.NewStringResponder(200, updateEnvVarResponse))
httpmock.RegisterResponder("DELETE", "https://app.cloud66.com/api/3/stacks/"+stackID+"/environments/"+key+".json", httpmock.NewStringResponder(200, deleteEnvVarResponse))
}
152 changes: 152 additions & 0 deletions cloud66/resource_cloud66_env_variable.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package cloud66

import (
"fmt"
"log"
"strings"
"time"

api "github.com/cloud66-oss/cloud66"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourceCloud66EnvVariable() *schema.Resource {
return &schema.Resource{
Create: resourceCloud66EnvVariableCreate,
Read: resourceCloud66EnvVariableRead,
Update: resourceCloud66EnvVariableUpdate,
Delete: resourceCloud66EnvVariableDelete,
Importer: &schema.ResourceImporter{
State: resourceCloud66EnvVariableImport,
},

SchemaVersion: 2,
Schema: resourceCloud66EnvVariableSchema(),
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(30 * time.Second),
Update: schema.DefaultTimeout(30 * time.Second),
},
}
}

func resourceCloud66EnvVariableCreate(d *schema.ResourceData, meta interface{}) error {
providerConfig := meta.(ProviderConfig)
client := providerConfig.client

stackID := d.Get("stack_id").(string)
key := d.Get("key").(string)
value := d.Get("value").(string)
applyStrategy := d.Get("apply_strategy").(string)

log.Printf("[INFO] Creating %s Env Variable for stack %s", key, stackID)

record, err := client.StackEnvVarNew(stackID, key, value, applyStrategy)

if record == nil {
return fmt.Errorf("error creating Env Variable %q: %s", stackID, err)
}

envVar := api.StackEnvVar{
Key: key,
Value: value,
Readonly: d.Get("readonly").(bool),
}

setCloud66EnvVariableData(d, &envVar)

return nil
}

func resourceCloud66EnvVariableRead(d *schema.ResourceData, meta interface{}) error {
providerConfig := meta.(ProviderConfig)
client := providerConfig.client

stackID := d.Get("stack_id").(string)
key := d.Id()

records, err := client.StackEnvVars(stackID)
if records != nil {
for _, record := range records {
if record.Key == key {
setCloud66EnvVariableData(d, &record)
break
}
}
} else {
return fmt.Errorf("error reading Env Variable %q: %s", stackID, err)
}

return nil
}

func resourceCloud66EnvVariableUpdate(d *schema.ResourceData, meta interface{}) error {
providerConfig := meta.(ProviderConfig)
client := providerConfig.client

stackID := d.Get("stack_id").(string)
key := d.Id()
value := d.Get("value").(string)
applyStrategy := d.Get("apply_strategy").(string)

log.Printf("[INFO] Updating %s Env Variable for stack %s", key, stackID)

record, err := client.StackEnvVarSet(stackID, key, value, applyStrategy)

if record == nil {
return fmt.Errorf("error updating Env Variable %q: %s", stackID, err)
}

envVar := api.StackEnvVar{
Key: key,
Value: value,
Readonly: d.Get("readonly").(bool),
}

setCloud66EnvVariableData(d, &envVar)

return nil
}

func resourceCloud66EnvVariableDelete(d *schema.ResourceData, meta interface{}) error {
providerConfig := meta.(ProviderConfig)
client := providerConfig.client

stackID := d.Get("stack_id").(string)
key := d.Id()

req, err := client.NewRequest("DELETE", "/stacks/"+stackID+"/environments/"+key+".json", nil, nil)
if req == nil {
return fmt.Errorf("error deleting Env Variable %q: %s", stackID, err)
}

return nil
}

func resourceCloud66EnvVariableImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
// split the id so we can lookup
idAttr := strings.SplitN(d.Id(), "/", 2)
if len(idAttr) != 2 {
return nil, fmt.Errorf("invalid id (\"%s\") specified, should be in format \"stackID/key\"", d.Id())
}

stackID, key := idAttr[0], idAttr[1]

log.Printf("[DEBUG] Importing %s Env Variable for stack %s", key, stackID)

d.Set("stack_id", stackID)
d.SetId(key)

resourceCloud66EnvVariableRead(d, meta)

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

func setCloud66EnvVariableData(d *schema.ResourceData, envVar *api.StackEnvVar) {
stackID := d.Get("stack_id").(string)

d.SetId(envVar.Key)
d.Set("stack_id", stackID)
d.Set("key", envVar.Key)
d.Set("value", envVar.Value)
d.Set("readonly", envVar.Readonly)
}
Loading

0 comments on commit 68e76e5

Please sign in to comment.