Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provider/heroku: Add resources for Heroku Pipelines #14078

Merged
merged 8 commits into from
May 1, 2017
16 changes: 9 additions & 7 deletions builtin/providers/heroku/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ func Provider() terraform.ResourceProvider {
},

ResourcesMap: map[string]*schema.Resource{
"heroku_addon": resourceHerokuAddon(),
"heroku_app": resourceHerokuApp(),
"heroku_app_feature": resourceHerokuAppFeature(),
"heroku_cert": resourceHerokuCert(),
"heroku_domain": resourceHerokuDomain(),
"heroku_drain": resourceHerokuDrain(),
"heroku_space": resourceHerokuSpace(),
"heroku_addon": resourceHerokuAddon(),
"heroku_app": resourceHerokuApp(),
"heroku_app_feature": resourceHerokuAppFeature(),
"heroku_cert": resourceHerokuCert(),
"heroku_domain": resourceHerokuDomain(),
"heroku_drain": resourceHerokuDrain(),
"heroku_pipeline": resourceHerokuPipeline(),
"heroku_pipeline_coupling": resourceHerokuPipelineCoupling(),
"heroku_space": resourceHerokuSpace(),
},

ConfigureFunc: providerConfigure,
Expand Down
92 changes: 92 additions & 0 deletions builtin/providers/heroku/resource_heroku_pipeline.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package heroku

import (
"context"
"fmt"
"log"

"github.com/cyberdelia/heroku-go/v3"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceHerokuPipeline() *schema.Resource {
return &schema.Resource{
Create: resourceHerokuPipelineCreate,
Update: resourceHerokuPipelineUpdate,
Read: resourceHerokuPipelineRead,
Delete: resourceHerokuPipelineDelete,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
},
}
}

func resourceHerokuPipelineCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*heroku.Service)

opts := heroku.PipelineCreateOpts{
Name: d.Get("name").(string),
}

log.Printf("[DEBUG] Pipeline create configuration: %#v", opts)

p, err := client.PipelineCreate(context.TODO(), opts)
if err != nil {
return fmt.Errorf("Error creating pipeline: %s", err)
}

d.SetId(p.ID)
d.Set("name", p.Name)

log.Printf("[INFO] Pipeline ID: %s", d.Id())

return resourceHerokuPipelineUpdate(d, meta)
}

func resourceHerokuPipelineUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*heroku.Service)

if d.HasChange("name") {
name := d.Get("name").(string)
opts := heroku.PipelineUpdateOpts{
Name: &name,
}

_, err := client.PipelineUpdate(context.TODO(), d.Id(), opts)
if err != nil {
return err
}
}

return resourceHerokuPipelineRead(d, meta)
}

func resourceHerokuPipelineDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*heroku.Service)

log.Printf("[INFO] Deleting pipeline: %s", d.Id())

_, err := client.PipelineDelete(context.TODO(), d.Id())
if err != nil {
return fmt.Errorf("Error deleting pipeline: %s", err)
}

return nil
}

func resourceHerokuPipelineRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*heroku.Service)

p, err := client.PipelineInfo(context.TODO(), d.Id())
if err != nil {
return fmt.Errorf("Error retrieving pipeline: %s", err)
}

d.Set("name", p.Name)

return nil
}
89 changes: 89 additions & 0 deletions builtin/providers/heroku/resource_heroku_pipeline_coupling.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package heroku

import (
"context"
"fmt"
"log"

"github.com/cyberdelia/heroku-go/v3"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceHerokuPipelineCoupling() *schema.Resource {
return &schema.Resource{
Create: resourceHerokuPipelineCouplingCreate,
Read: resourceHerokuPipelineCouplingRead,
Delete: resourceHerokuPipelineCouplingDelete,

Schema: map[string]*schema.Schema{
"app": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"pipeline": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateUUID,
},
"stage": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validatePipelineStageName,
},
},
}
}

func resourceHerokuPipelineCouplingCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*heroku.Service)

opts := heroku.PipelineCouplingCreateOpts{
App: d.Get("app").(string),
Pipeline: d.Get("pipeline").(string),
Stage: d.Get("stage").(string),
}

log.Printf("[DEBUG] PipelineCoupling create configuration: %#v", opts)

p, err := client.PipelineCouplingCreate(context.TODO(), opts)
if err != nil {
return fmt.Errorf("Error creating pipeline: %s", err)
}

d.SetId(p.ID)

log.Printf("[INFO] PipelineCoupling ID: %s", d.Id())

return resourceHerokuPipelineCouplingRead(d, meta)
}

func resourceHerokuPipelineCouplingDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*heroku.Service)

log.Printf("[INFO] Deleting pipeline: %s", d.Id())

_, err := client.PipelineCouplingDelete(context.TODO(), d.Id())
if err != nil {
return fmt.Errorf("Error deleting pipeline: %s", err)
}

return nil
}

func resourceHerokuPipelineCouplingRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*heroku.Service)

p, err := client.PipelineCouplingInfo(context.TODO(), d.Id())
if err != nil {
return fmt.Errorf("Error retrieving pipeline: %s", err)
}

d.Set("app", p.App)
d.Set("pipeline", p.Pipeline)
d.Set("stage", p.Stage)

return nil
}
123 changes: 123 additions & 0 deletions builtin/providers/heroku/resource_heroku_pipeline_coupling_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package heroku

import (
"context"
"fmt"
"testing"

heroku "github.com/cyberdelia/heroku-go/v3"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccHerokuPipelineCoupling_Basic(t *testing.T) {
var coupling heroku.PipelineCouplingInfoResult

appName := fmt.Sprintf("tftest-%s", acctest.RandString(10))
pipelineName := fmt.Sprintf("tftest-%s", acctest.RandString(10))
stageName := "development"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckHerokuPipelineCouplingDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckHerokuPipelineCouplingConfig_basic(appName, pipelineName, stageName),
Check: resource.ComposeTestCheckFunc(
testAccCheckHerokuPipelineCouplingExists("heroku_pipeline_coupling.default", &coupling),
testAccCheckHerokuPipelineCouplingAttributes(
&coupling,
"heroku_pipeline.default",
stageName,
),
),
},
},
})
}

func testAccCheckHerokuPipelineCouplingConfig_basic(appName, pipelineName, stageName string) string {
return fmt.Sprintf(`
resource "heroku_app" "default" {
name = "%s"
region = "us"
}

resource "heroku_pipeline" "default" {
name = "%s"
}

resource "heroku_pipeline_coupling" "default" {
app = "${heroku_app.default.id}"
pipeline = "${heroku_pipeline.default.id}"
stage = "%s"
}
`, appName, pipelineName, stageName)
}

func testAccCheckHerokuPipelineCouplingExists(n string, pipeline *heroku.PipelineCouplingInfoResult) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]

if !ok {
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No coupling ID set")
}

client := testAccProvider.Meta().(*heroku.Service)

foundPipelineCoupling, err := client.PipelineCouplingInfo(context.TODO(), rs.Primary.ID)
if err != nil {
return err
}

if foundPipelineCoupling.ID != rs.Primary.ID {
return fmt.Errorf("PipelineCoupling not found: %s != %s", foundPipelineCoupling.ID, rs.Primary.ID)
}

*pipeline = *foundPipelineCoupling

return nil
}
}

func testAccCheckHerokuPipelineCouplingAttributes(coupling *heroku.PipelineCouplingInfoResult, pipelineResource, stageName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
pipeline, ok := s.RootModule().Resources[pipelineResource]
if !ok {
return fmt.Errorf("Pipeline not found: %s", pipelineResource)
}

if coupling.Pipeline.ID != pipeline.Primary.ID {
return fmt.Errorf("Bad pipeline ID: %v != %v", coupling.Pipeline.ID, pipeline.Primary.ID)
}
if coupling.Stage != stageName {
return fmt.Errorf("Bad stage: %s", coupling.Stage)
}

return nil
}
}

func testAccCheckHerokuPipelineCouplingDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*heroku.Service)

for _, rs := range s.RootModule().Resources {
if rs.Type != "heroku_pipeline_coupling" {
continue
}

_, err := client.PipelineCouplingInfo(context.TODO(), rs.Primary.ID)

if err == nil {
return fmt.Errorf("PipelineCoupling still exists")
}
}

return nil
}
Loading