forked from aeirola/terraform-provider-bitbucket
-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #163 from DrFaust92/workspace-var
workspace var
- Loading branch information
Showing
4 changed files
with
388 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
package bitbucket | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"strings" | ||
|
||
"github.com/DrFaust92/bitbucket-go-client" | ||
"github.com/antihax/optional" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
func resourceWorkspaceVariable() *schema.Resource { | ||
return &schema.Resource{ | ||
CreateWithoutTimeout: resourceWorkspaceVariableCreate, | ||
UpdateWithoutTimeout: resourceWorkspaceVariableUpdate, | ||
ReadWithoutTimeout: resourceWorkspaceVariableRead, | ||
DeleteWithoutTimeout: resourceWorkspaceVariableDelete, | ||
Importer: &schema.ResourceImporter{ | ||
StateContext: schema.ImportStatePassthroughContext, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"uuid": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"key": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"value": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Sensitive: true, | ||
}, | ||
"secured": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Default: false, | ||
}, | ||
"workspace": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func newWorkspaceVariableFromResource(d *schema.ResourceData) bitbucket.PipelineVariable { | ||
dk := bitbucket.PipelineVariable{ | ||
Key: d.Get("key").(string), | ||
Value: d.Get("value").(string), | ||
Secured: d.Get("secured").(bool), | ||
} | ||
return dk | ||
} | ||
|
||
func resourceWorkspaceVariableCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
c := m.(Clients).genClient | ||
pipeApi := c.ApiClient.PipelinesApi | ||
rvcr := newWorkspaceVariableFromResource(d) | ||
|
||
workspacePipeBody := &bitbucket.PipelinesApiCreatePipelineVariableForWorkspaceOpts{ | ||
Body: optional.NewInterface(rvcr), | ||
} | ||
|
||
workspace := d.Get("workspace").(string) | ||
|
||
log.Printf("[DEBUG] Workspace Variable Request: %#v", workspacePipeBody) | ||
|
||
rvRes, res, err := pipeApi.CreatePipelineVariableForWorkspace(c.AuthContext, workspace, workspacePipeBody) | ||
|
||
log.Printf("[DEBUG] Workspace Variable Create Request Res: %#v", res) | ||
|
||
if err := handleClientError(err); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
d.SetId(fmt.Sprintf("%s/%s", workspace, rvRes.Uuid)) | ||
|
||
return resourceWorkspaceVariableRead(ctx, d, m) | ||
} | ||
|
||
func resourceWorkspaceVariableRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
c := m.(Clients).genClient | ||
pipeApi := c.ApiClient.PipelinesApi | ||
|
||
workspace, uuid, err := workspaceVarId(d.Id()) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
rvRes, res, err := pipeApi.GetPipelineVariableForWorkspace(c.AuthContext, workspace, uuid) | ||
|
||
log.Printf("[DEBUG] Workspace Variable Get Request Res: %#v", res) | ||
|
||
if res.StatusCode == http.StatusNotFound { | ||
log.Printf("[WARN] Workspace Variable (%s) not found, removing from state", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
if err := handleClientError(err); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
d.Set("uuid", rvRes.Uuid) | ||
d.Set("workspace", workspace) | ||
d.Set("key", rvRes.Key) | ||
d.Set("secured", rvRes.Secured) | ||
|
||
if !rvRes.Secured { | ||
d.Set("value", rvRes.Value) | ||
} else { | ||
d.Set("value", d.Get("value").(string)) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceWorkspaceVariableUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
c := m.(Clients).genClient | ||
pipeApi := c.ApiClient.PipelinesApi | ||
|
||
workspace, uuid, err := workspaceVarId(d.Id()) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
rvcr := newWorkspaceVariableFromResource(d) | ||
|
||
_, _, err = pipeApi.UpdatePipelineVariableForWorkspace(c.AuthContext, rvcr, workspace, uuid) | ||
if err := handleClientError(err); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
return resourceWorkspaceVariableRead(ctx, d, m) | ||
} | ||
|
||
func resourceWorkspaceVariableDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { | ||
c := m.(Clients).genClient | ||
pipeApi := c.ApiClient.PipelinesApi | ||
|
||
workspace, uuid, err := workspaceVarId(d.Id()) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
_, err = pipeApi.DeletePipelineVariableForWorkspace(c.AuthContext, workspace, uuid) | ||
if err := handleClientError(err); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func workspaceVarId(workspace string) (string, string, error) { | ||
idparts := strings.Split(workspace, "/") | ||
if len(idparts) == 2 { | ||
return idparts[0], idparts[1], nil | ||
} else { | ||
return "", "", fmt.Errorf("incorrect ID format, should match `workspace/uuid`") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
package bitbucket | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"os" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||
) | ||
|
||
func TestAccBitbucketWorkspaceVariable_basic(t *testing.T) { | ||
workspace := os.Getenv("BITBUCKET_TEAM") | ||
resourceName := "bitbucket_workspace_variable.test" | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckBitbucketWorkspaceVariableDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccBitbucketWorkspaceVariableConfig(workspace, "test", false), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckBitbucketWorkspaceVariableExists(resourceName), | ||
resource.TestCheckResourceAttr(resourceName, "workspace", workspace), | ||
resource.TestCheckResourceAttr(resourceName, "key", "test"), | ||
resource.TestCheckResourceAttr(resourceName, "value", "test"), | ||
resource.TestCheckResourceAttr(resourceName, "secured", "false"), | ||
), | ||
}, | ||
{ | ||
ResourceName: resourceName, | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
{ | ||
Config: testAccBitbucketWorkspaceVariableConfig(workspace, "test-2", false), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckBitbucketWorkspaceVariableExists(resourceName), | ||
resource.TestCheckResourceAttr(resourceName, "workspace", workspace), | ||
resource.TestCheckResourceAttr(resourceName, "key", "test"), | ||
resource.TestCheckResourceAttr(resourceName, "value", "test-2"), | ||
resource.TestCheckResourceAttr(resourceName, "secured", "false"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccBitbucketWorkspaceVariable_manyVars(t *testing.T) { | ||
workspace := os.Getenv("BITBUCKET_TEAM") | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckBitbucketWorkspaceVariableDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccBitbucketWorkspaceVariableManyConfig(workspace, "test", false), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccBitbucketWorkspaceVariable_secure(t *testing.T) { | ||
workspace := os.Getenv("BITBUCKET_TEAM") | ||
resourceName := "bitbucket_workspace_variable.test" | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckBitbucketWorkspaceVariableDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccBitbucketWorkspaceVariableConfig(workspace, "test", true), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckBitbucketWorkspaceVariableExists(resourceName), | ||
resource.TestCheckResourceAttr(resourceName, "workspace", workspace), | ||
resource.TestCheckResourceAttr(resourceName, "key", "test"), | ||
resource.TestCheckResourceAttr(resourceName, "value", "test"), | ||
resource.TestCheckResourceAttr(resourceName, "secured", "true"), | ||
), | ||
}, | ||
{ | ||
ResourceName: resourceName, | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
ImportStateVerifyIgnore: []string{"value"}, | ||
}, | ||
{ | ||
Config: testAccBitbucketWorkspaceVariableConfig(workspace, "test", false), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckBitbucketWorkspaceVariableExists(resourceName), | ||
resource.TestCheckResourceAttr(resourceName, "workspace", workspace), | ||
resource.TestCheckResourceAttr(resourceName, "key", "test"), | ||
resource.TestCheckResourceAttr(resourceName, "value", "test"), | ||
resource.TestCheckResourceAttr(resourceName, "secured", "false"), | ||
), | ||
}, | ||
{ | ||
Config: testAccBitbucketWorkspaceVariableConfig(workspace, "test", true), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckBitbucketWorkspaceVariableExists(resourceName), | ||
resource.TestCheckResourceAttr(resourceName, "workspace", workspace), | ||
resource.TestCheckResourceAttr(resourceName, "key", "test"), | ||
resource.TestCheckResourceAttr(resourceName, "value", "test"), | ||
resource.TestCheckResourceAttr(resourceName, "secured", "true"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckBitbucketWorkspaceVariableDestroy(s *terraform.State) error { | ||
client := testAccProvider.Meta().(Clients).genClient | ||
pipeApi := client.ApiClient.PipelinesApi | ||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "bitbucket_workspace_variable" { | ||
continue | ||
} | ||
|
||
workspace, uuid, err := workspaceVarId(rs.Primary.ID) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, res, err := pipeApi.GetPipelineVariableForWorkspace(client.AuthContext, workspace, uuid) | ||
|
||
if err == nil { | ||
return fmt.Errorf("The resource was found should have errored") | ||
} | ||
|
||
if res.StatusCode != http.StatusNotFound { | ||
return fmt.Errorf("Workspace Variable still exists") | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func testAccCheckBitbucketWorkspaceVariableExists(n string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
_, ok := s.RootModule().Resources[n] | ||
|
||
if !ok { | ||
return fmt.Errorf("Not found %s", n) | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccBitbucketWorkspaceVariableConfig(workspace, val string, secure bool) string { | ||
return fmt.Sprintf(` | ||
resource "bitbucket_workspace_variable" "test" { | ||
key = "test" | ||
value = %[2]q | ||
workspace = %[1]q | ||
secured = %[3]t | ||
} | ||
`, workspace, val, secure) | ||
} | ||
|
||
func testAccBitbucketWorkspaceVariableManyConfig(workspace, val string, secure bool) string { | ||
return fmt.Sprintf(` | ||
resource "bitbucket_workspace_variable" "test" { | ||
count = 50 | ||
key = "test${count.index}" | ||
value = %[2]q | ||
workspace = %[1]q | ||
secured = %[3]t | ||
} | ||
`, workspace, val, secure) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
--- | ||
layout: "bitbucket" | ||
page_title: "Bitbucket: bitbucket_workspace_variable" | ||
sidebar_current: "docs-bitbucket-resource-workspace-variable" | ||
description: |- | ||
Manage variables for your pipelines workspace environments | ||
--- | ||
|
||
|
||
# bitbucket\_workspace\_variable | ||
|
||
This resource allows you to configure workspace variables. | ||
|
||
OAuth2 Scopes: `none` | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
resource "bitbucket_workspace_variable" "country" { | ||
workspace = bitbucket_workspace.test.id | ||
key = "COUNTRY" | ||
value = "Kenya" | ||
secured = false | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
* `workspace` - (Required) The workspace ID you want to assign this variable to. | ||
* `key` - (Required) The unique name of the variable. | ||
* `value` - (Required) The value of the variable. | ||
* `secured` - (Optional) If true, this variable will be treated as secured. The value will never be exposed in the logs or the REST API. | ||
|
||
## Attributes Reference | ||
|
||
* `uuid` - (Computed) The UUID identifying the variable. | ||
|
||
## Import | ||
|
||
Workspace Variables can be imported using their `workspace-id/uuid` ID, e.g. | ||
|
||
```sh | ||
terraform import bitbucket_workspace_variable.example workspace-id/uuid | ||
``` |