Skip to content

Commit

Permalink
feat: added data source for Stacks (#87)
Browse files Browse the repository at this point in the history
* feat: added data source for Stacks

* Update docs/data-sources/stacks.md

Co-authored-by: Josh Raker <48493233+joshraker@users.noreply.github.com>

* Update docs/data-sources/stacks.md

Co-authored-by: Josh Raker <48493233+joshraker@users.noreply.github.com>

* chore: added unit tests for validation on stacks, and unit tests + integration tests for environments data sources

* chore: updated var name of docs to reflect truth

* chore: added unit test with client for stack data

* chore: moved stack test setup as it required remote retrieval

* chore: another attempt to prevent integration tests from running in travis

* chore: unit test corrections

* chore: trying rename to see if test suite picks it up

* chore: reverted naming, using hack to allow test suite to skip on non tfacc

* chore: wrapped client-based data call in TF_ACC guard

* chore: left comment on stack data source test

* chore: renamed func to be consistent

Co-authored-by: Josh Raker <48493233+joshraker@users.noreply.github.com>
  • Loading branch information
madhuravius and joshraker committed Oct 26, 2022
1 parent a60aca8 commit eadcd90
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 6 deletions.
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
**/.terraform/*
*.terraform
*tfstate*
**/.terraform.lock.hcl
*.terraform.lock.hcl
*.auto.tfvars
!example.auto.tfvars
.vscode
.DS_Store
terraform-provider-aptible
Expand Down
70 changes: 70 additions & 0 deletions aptible/data_source_environment_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package aptible

import (
"fmt"
"regexp"
"strconv"
"testing"

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

func TestAccDataSourceEnvironment_validation(t *testing.T) {
requiredAttrs := []string{"handle"}
var testSteps []resource.TestStep

for _, attr := range requiredAttrs {
testSteps = append(testSteps, resource.TestStep{
PlanOnly: true,
Config: `data "aptible_environment" "test" {}`,
ExpectError: regexp.MustCompile(fmt.Sprintf("%q is required", attr)),
})
}

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviderFactories,
Steps: testSteps,
})
}

func TestAccDataSourceEnvironment_basic(t *testing.T) {
rHandle := acctest.RandString(10)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviderFactories,
Providers: testAccProviders,
CheckDestroy: testAccCheckEnvironmentDestroy,
Steps: []resource.TestStep{
{
Config: testAccAptibleEnvironment(rHandle),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("aptible_environment.test", "handle", rHandle),
resource.TestCheckResourceAttr("aptible_environment.test", "org_id", testOrganizationId),
resource.TestCheckResourceAttr("aptible_environment.test", "stack_id", strconv.Itoa(testStackId)),
),
}, {
ResourceName: "aptible_environment.test",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testDataAccAptibleEnvironment(rHandle),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.aptible_environment.test", "handle", rHandle),
),
},
},
})
}

func testDataAccAptibleEnvironment(handle string) string {
// also include the past environment state to prevent deletion
return fmt.Sprintf(`
%s
data "aptible_environment" "test" {
handle = "%s"
}`, testAccAptibleEnvironment(handle), handle)
}
40 changes: 40 additions & 0 deletions aptible/data_source_stack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package aptible

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

func dataSourceStack() *schema.Resource {
return &schema.Resource{
Read: dataSourceStackRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"stack_id": {
Type: schema.TypeInt,
Computed: true,
},
"org_id": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceStackRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*aptible.Client)
handle := d.Get("name").(string)
stack, err := client.GetStackByName(handle)
if err != nil {
return generateErrorFromClientError(err)
}

_ = d.Set("stack_id", stack.ID)
_ = d.Set("org_id", stack.OrganizationID)
d.SetId(handle)
return nil
}
81 changes: 81 additions & 0 deletions aptible/data_source_stack_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package aptible

import (
"fmt"
"os"
"regexp"
"strconv"
"testing"

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

"github.com/aptible/go-deploy/aptible"
)

func TestAccStackDataSource_validation(t *testing.T) {
requiredAttrs := []string{"name"}
var testSteps []resource.TestStep

for _, attr := range requiredAttrs {
testSteps = append(testSteps, resource.TestStep{
PlanOnly: true,
Config: `data "aptible_stack" "test" {}`,
ExpectError: regexp.MustCompile(fmt.Sprintf("%q is required", attr)),
})
}

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviderFactories,
Steps: testSteps,
})
}

func TestAccStackDataSource_basic(t *testing.T) {
if os.Getenv("TF_ACC") == "1" {
// This guard is set because the below code should only evaluate if running in an integration test
// setting. Typically this is honored by Terraform, but this occurs outside the context of the resource.Test
// which must be done as values set in PreCheck are discarded and/or run in an entirely different context
var stacks []aptible.Stack
client, err := aptible.SetUpClient()
if err != nil {
t.Fatalf("Unable to generate and setup client for stacks test - %s", err.Error())
return
}
stacks, err = client.GetStacks()
if err != nil {
t.Fatalf("Unable to retrieve stacks for test - %s", err.Error())
return
}
if len(stacks) == 0 {
t.Fatal("Unable to find stacks with a zero length")
return
}

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
ProviderFactories: testAccProviderFactories,
Steps: []resource.TestStep{
{
Config: testDataAccAptibleStack(stacks[0].Name),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.aptible_stack.test", "name", stacks[0].Name),
resource.TestCheckResourceAttr("data.aptible_stack.test", "stack_id", strconv.Itoa(int(stacks[0].ID))),
resource.TestCheckResourceAttr("data.aptible_stack.test", "org_id", stacks[0].OrganizationID),
),
},
},
})
}
}

func testDataAccAptibleStack(name string) string {
return fmt.Sprintf(`
data "aptible_stack" "test" {
name = "%s"
}`,
name)
}
1 change: 1 addition & 0 deletions aptible/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func Provider() *schema.Provider {
},
DataSourcesMap: map[string]*schema.Resource{
"aptible_environment": dataSourceEnvironment(),
"aptible_stack": dataSourceStack(),
},
ConfigureContextFunc: providerConfigureWithContext,
}
Expand Down
2 changes: 1 addition & 1 deletion docs/data-sources/environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ resource "aptible_app" "techo-app" {

In addition to all arguments above, the following attributes are exported:

- `id` - The unique ID for an Environment suitable for use in `env_id` attributes
- `env_id` - The unique ID for an Environment suitable for use in `env_id` attributes
41 changes: 41 additions & 0 deletions docs/data-sources/stacks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Stack Data Source

[Stacks](https://deploy-docs.aptible.com/docs/stacks)
are the underlying virtualized infrastructure (EC2 instances, private network, etc.) your resources
are deployed on.

## Example Usage

### Determining the Stack ID

If you have an Stack with the name "test-stack" you can
create the data source:

```hcl
data "aptible_stack" "test-stack" {
name = "test-stack"
}
```

Once defined, you can use this data source in your resource definitions.
For example, when defining an environment:

```hcl
resource "aptible_environment" "test-env" {
stack_id = data.aptible_stack.test-stack.stack_id
org_id = data.aptible_stack.test-stack.org_id
name = "test-env"
}
```

## Argument Reference

- `name` - The name of the Stack

## Attribute Reference

In addition to all arguments above, the following attributes are exported:

- `stack_id` - The unique ID for an Stack suitable for use in `stack_id` attributes
- `org_id` - If the stack is a [dedicated stack](https://deploy-docs.aptible.com/docs/shared-dedicated#dedicated-stacks),
you will also receive an id that corresponds to that organization. If it is a shared stack, this value will be empty.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
cloud.google.com/go/storage v1.15.0 // indirect
github.com/Djarvur/go-err113 v0.1.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/aptible/go-deploy v0.3.1
github.com/aptible/go-deploy v0.3.2
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
github.com/aws/aws-sdk-go v1.38.67 // indirect
github.com/bflad/tfproviderdocs v0.9.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/aptible/go-deploy v0.3.1 h1:P3nk41tRimKgeDipRYmGucayS9bCtWsE40q9WsBqX9E=
github.com/aptible/go-deploy v0.3.1/go.mod h1:h0Zt8I+pV3aqvPo+rA1hIeQjT/13RzFPYuTmg4+SyPQ=
github.com/aptible/go-deploy v0.3.2 h1:CPmmcatX0dwtWn95lP3MDIHXRq65KJgaGxnptm+ijK4=
github.com/aptible/go-deploy v0.3.2/go.mod h1:h0Zt8I+pV3aqvPo+rA1hIeQjT/13RzFPYuTmg4+SyPQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
Expand Down

0 comments on commit eadcd90

Please sign in to comment.