forked from armory-io/terraform-provider-spinnaker
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add spinnaker_pipeline_template_v2 resource
Notable changes: - add `ResponseError` to make working with API errors easier - add validation to the `template` field of the new `spinnaker_pipeline_template_v2` resource to catch common issues on `terraform plan` - tests for error impl and parsing/validation logic More tests require general changes to the way the API client is instantiated and passed around. This is out of scope here and will be addressed in a separate change.
- Loading branch information
1 parent
3195eaa
commit 976a924
Showing
10 changed files
with
547 additions
and
3 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "spinnaker_pipeline_template_v2 Resource - terraform-provider-spinnaker" | ||
subcategory: "" | ||
description: |- | ||
Provides a V2 pipeline template. See https://spinnaker.io/reference/pipeline/templates/ for more details. | ||
--- | ||
|
||
# spinnaker_pipeline_template_v2 (Resource) | ||
|
||
Provides a V2 pipeline template. See https://spinnaker.io/reference/pipeline/templates/ for more details. | ||
|
||
|
||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Required | ||
|
||
- **template** (String) JSON schema of the V2 pipeline template. | ||
- **template_id** (String) ID of the template. | ||
|
||
### Optional | ||
|
||
- **id** (String) The ID of this resource. | ||
|
||
### Read-Only | ||
|
||
- **reference** (String) The URL for referencing the template in a pipeline instance. | ||
|
||
|
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
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,27 @@ | ||
package errors | ||
|
||
import ( | ||
"errors" | ||
"net/http" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestResponseError(t *testing.T) { | ||
err := errors.New("the-error") | ||
notFoundResp := &http.Response{StatusCode: http.StatusNotFound} | ||
|
||
require.EqualError(t, NewResponseError(nil, err), "the-error") | ||
require.EqualError(t, NewResponseError(notFoundResp, err), "the-error, Code: 404") | ||
} | ||
|
||
func TestIsNotFound(t *testing.T) { | ||
err := errors.New("the-error") | ||
respErr := NewResponseError(nil, err) | ||
notFoundErr := NewResponseError(&http.Response{StatusCode: http.StatusNotFound}, err) | ||
|
||
require.False(t, IsNotFound(err)) | ||
require.False(t, IsNotFound(respErr)) | ||
require.True(t, IsNotFound(notFoundErr)) | ||
} |
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,33 @@ | ||
package api | ||
|
||
// PipelineTemplateV2 defines the schema of the pipeline template JSON. | ||
type PipelineTemplateV2 struct { | ||
ID string `json:"id,omitempty"` | ||
Metadata PipelineTemplateV2Metadata `json:"metadata"` | ||
Pipeline interface{} `json:"pipeline"` | ||
Protect *bool `json:"protect,omitempty"` | ||
Schema string `json:"schema"` | ||
Variables []PipelineTemplateV2Variable `json:"variables,omitempty"` | ||
} | ||
|
||
type PipelineTemplateV2Metadata struct { | ||
Name string `json:"name"` | ||
Description string `json:"description"` | ||
Owner *string `json:"owner,omitempty"` | ||
Scopes []string `json:"scopes,omitempty"` | ||
} | ||
|
||
type PipelineTemplateV2Variable struct { | ||
Name string `json:"name"` | ||
Description *string `json:"description,omitempty"` | ||
DefaultValue interface{} `json:"defaultValue,omitempty"` | ||
Type string `json:"type"` | ||
Group *string `json:"group,omitempty"` | ||
Example *string `json:"example,omitempty"` | ||
} | ||
|
||
type PipelineTemplateV2Version struct { | ||
ID string `json:"id"` | ||
Digest string `json:"digest"` | ||
Tag string `json:"tag"` | ||
} |
File renamed without changes.
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,97 @@ | ||
package api | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/Bonial-International-GmbH/terraform-provider-spinnaker/spinnaker/api/errors" | ||
"github.com/antihax/optional" | ||
"github.com/mitchellh/mapstructure" | ||
gate "github.com/spinnaker/spin/cmd/gateclient" | ||
gateapi "github.com/spinnaker/spin/gateapi" | ||
) | ||
|
||
// CreatePipelineTemplateV2 creates a pipeline template. | ||
func CreatePipelineTemplateV2(client *gate.GatewayClient, template *PipelineTemplateV2) error { | ||
_, resp, err := retry(func() (map[string]interface{}, *http.Response, error) { | ||
return client.V2PipelineTemplatesControllerApi.CreateUsingPOST1(client.Context, template, nil) | ||
}) | ||
if err != nil || (resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated) { | ||
return errors.NewResponseError(resp, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// GetPipelineTemplateV2 fetches the pipeline template with templateID. | ||
func GetPipelineTemplateV2(client *gate.GatewayClient, templateID string) (*PipelineTemplateV2, error) { | ||
payload, resp, err := retry(func() (map[string]interface{}, *http.Response, error) { | ||
return client.V2PipelineTemplatesControllerApi.GetUsingGET2(client.Context, templateID, nil) | ||
}) | ||
if err != nil || resp.StatusCode != http.StatusOK { | ||
return nil, errors.NewResponseError(resp, err) | ||
} | ||
|
||
var template PipelineTemplateV2 | ||
|
||
if err := mapstructure.Decode(payload, &template); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &template, nil | ||
} | ||
|
||
// DeletePipelineTemplateV2 deletes the pipeline template with templateID. | ||
// Either digest or tag can be set on a delete request, but not both. | ||
func DeletePipelineTemplateV2(client *gate.GatewayClient, templateID, tag, digest string) error { | ||
opts := &gateapi.V2PipelineTemplatesControllerApiDeleteUsingDELETE1Opts{} | ||
if digest != "" { | ||
opts.Digest = optional.NewString(digest) | ||
} else if tag != "" { | ||
opts.Tag = optional.NewString(tag) | ||
} | ||
|
||
_, resp, err := retry(func() (map[string]interface{}, *http.Response, error) { | ||
return client.V2PipelineTemplatesControllerApi.DeleteUsingDELETE1(client.Context, templateID, opts) | ||
}) | ||
if err != nil || (resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent) { | ||
return errors.NewResponseError(resp, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// UpdatePipelineTemplateV2 updates the pipeline template with templateID with | ||
// the data in template. | ||
func UpdatePipelineTemplateV2(client *gate.GatewayClient, template *PipelineTemplateV2) error { | ||
_, resp, err := retry(func() (map[string]interface{}, *http.Response, error) { | ||
return client.V2PipelineTemplatesControllerApi.UpdateUsingPOST1(client.Context, template.ID, template, nil) | ||
}) | ||
if err != nil || (resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated) { | ||
return errors.NewResponseError(resp, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// ListPipelineTemplateV2Versions lists versions of all availabe pipeline | ||
// templates. The resulting map is keyed by template ID. | ||
func ListPipelineTemplateV2Versions(client *gate.GatewayClient) (map[string][]*PipelineTemplateV2Version, error) { | ||
var payload interface{} | ||
|
||
_, resp, err := retry(func() (map[string]interface{}, *http.Response, error) { | ||
v, resp, err := client.V2PipelineTemplatesControllerApi.ListVersionsUsingGET(client.Context, nil) | ||
payload = v | ||
return nil, resp, err | ||
}) | ||
if err != nil || resp.StatusCode != http.StatusOK { | ||
return nil, errors.NewResponseError(resp, err) | ||
} | ||
|
||
var versionMap map[string][]*PipelineTemplateV2Version | ||
|
||
if err = mapstructure.Decode(payload, &versionMap); err != nil { | ||
return nil, err | ||
} | ||
|
||
return versionMap, nil | ||
} |
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
Oops, something went wrong.