diff --git a/builtin/providers/heroku/provider.go b/builtin/providers/heroku/provider.go index 08432ac98..8afbc80eb 100644 --- a/builtin/providers/heroku/provider.go +++ b/builtin/providers/heroku/provider.go @@ -33,6 +33,7 @@ func Provider() terraform.ResourceProvider { "heroku_cert": resourceHerokuCert(), "heroku_domain": resourceHerokuDomain(), "heroku_drain": resourceHerokuDrain(), + "heroku_pipeline": resourceHerokuPipeline(), "heroku_space": resourceHerokuSpace(), }, diff --git a/builtin/providers/heroku/resource_heroku_pipeline.go b/builtin/providers/heroku/resource_heroku_pipeline.go new file mode 100644 index 000000000..8b23dd7d3 --- /dev/null +++ b/builtin/providers/heroku/resource_heroku_pipeline.go @@ -0,0 +1,73 @@ +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, + Read: resourceHerokuPipelineRead, + Delete: resourceHerokuPipelineDelete, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, // TODO does it? + }, + }, + } +} + +func resourceHerokuPipelineCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*heroku.Service) + + opts := heroku.PipelineCreateOpts{} + opts.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 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 +} diff --git a/builtin/providers/heroku/resource_heroku_pipeline_test.go b/builtin/providers/heroku/resource_heroku_pipeline_test.go new file mode 100644 index 000000000..7ce7f0707 --- /dev/null +++ b/builtin/providers/heroku/resource_heroku_pipeline_test.go @@ -0,0 +1,97 @@ +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 TestAccHerokuPipeline_Basic(t *testing.T) { + var pipeline heroku.PipelineInfoResult + pipelineName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckHerokuPipelineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckHerokuPipelineConfig_basic(pipelineName), + Check: resource.ComposeTestCheckFunc( + testAccCheckHerokuPipelineExists("heroku_pipeline.foobar", &pipeline), + testAccCheckHerokuPipelineAttributes(&pipeline, pipelineName), + ), + }, + }, + }) +} + +func testAccCheckHerokuPipelineConfig_basic(pipelineName string) string { + return fmt.Sprintf(` +resource "heroku_pipeline" "foobar" { + name = "%s" +} +`, pipelineName) +} + +func testAccCheckHerokuPipelineExists(n string, pipeline *heroku.PipelineInfoResult) 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 pipeline name set") + } + + client := testAccProvider.Meta().(*heroku.Service) + + foundPipeline, err := client.PipelineInfo(context.TODO(), rs.Primary.ID) + if err != nil { + return err + } + + if foundPipeline.ID != rs.Primary.ID { + return fmt.Errorf("Pipeline not found") + } + + *pipeline = *foundPipeline + + return nil + } +} + +func testAccCheckHerokuPipelineAttributes(pipeline *heroku.PipelineInfoResult, pipelineName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + if pipeline.Name != pipelineName { + return fmt.Errorf("Bad name: %s", pipeline.Name) + } + + return nil + } +} + +func testAccCheckHerokuPipelineDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*heroku.Service) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "heroku_pipeline" { + continue + } + + _, err := client.PipelineInfo(context.TODO(), rs.Primary.ID) + + if err == nil { + return fmt.Errorf("Pipeline still exists") + } + } + + return nil +}