Skip to content

Commit

Permalink
Fix: template retry attributes (#117)
Browse files Browse the repository at this point in the history
* fix template retry field

* add validation to retries fields

* go fmt changes

* fix ondeploy/ondestroy fields reference

* fix tests after model change

* add unit tests for invalid retry fields
  • Loading branch information
yaronya committed Jun 14, 2021
1 parent d0ff9f0 commit 44c1ab9
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 32 deletions.
8 changes: 4 additions & 4 deletions client/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ const (

type TemplateRetryOn struct {
Times int `json:"times,omitempty"`
ErrorRegex string `json:"errorRegex,omitempty"`
ErrorRegex string `json:"errorRegex"`
}

type TemplateRetry struct {
OnDeploy TemplateRetryOn `json:"onDeploy,omitempty"`
OnDestroy TemplateRetryOn `json:"onDestroy,omitempty"`
OnDeploy *TemplateRetryOn `json:"onDeploy"`
OnDestroy *TemplateRetryOn `json:"onDestroy"`
}

type TemplateType string
Expand All @@ -97,7 +97,7 @@ type TemplateSshKey struct {
}

type TemplateCreatePayload struct {
Retry TemplateRetry `json:"retry,omitempty"`
Retry TemplateRetry `json:"retry"`
SshKeys []TemplateSshKey `json:"sshKeys,omitempty"`
Type TemplateType `json:"type"`
Description string `json:"description"`
Expand Down
6 changes: 3 additions & 3 deletions env0/data_configuration_variable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ func TestUnitConfigurationVariableData(t *testing.T) {
Steps: []resource.TestStep{
{
Config: dataSourceConfigCreate(resourceType, resourceName, map[string]interface{}{"id": configurationVariable.Id}),
Check: checkResources,
Check: checkResources,
},
{
Config: dataSourceConfigCreate(resourceType, resourceName, map[string]interface{}{"name": configurationVariable.Name}),
Check: checkResources,
Check: checkResources,
},
},
},
Expand All @@ -62,7 +62,7 @@ func TestUnitConfigurationVariableData(t *testing.T) {
Steps: []resource.TestStep{
{
Config: dataSourceConfigCreate(resourceType, resourceName, map[string]interface{}{"id": configurationVariable.Id, "template_id": "template_id"}),
Check: checkResources,
Check: checkResources,
},
},
},
Expand Down
4 changes: 2 additions & 2 deletions env0/data_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,14 @@ func dataTemplateRead(ctx context.Context, d *schema.ResourceData, meta interfac
d.Set("type", template.Type)
d.Set("project_ids", template.ProjectIds)
d.Set("terraform_version", template.TerraformVersion)
if (template.Retry.OnDeploy != client.TemplateRetryOn{}) {
if template.Retry.OnDeploy != nil {
d.Set("retries_on_deploy", template.Retry.OnDeploy.Times)
d.Set("retry_on_deploy_only_when_matches_regex", template.Retry.OnDeploy.ErrorRegex)
} else {
d.Set("retries_on_deploy", 0)
d.Set("retry_on_deploy_only_when_matches_regex", "")
}
if (template.Retry.OnDestroy != client.TemplateRetryOn{}) {
if template.Retry.OnDestroy != nil {
d.Set("retries_on_destroy", template.Retry.OnDestroy.Times)
d.Set("retry_on_destroy_only_when_matches_regex", template.Retry.OnDestroy.ErrorRegex)
} else {
Expand Down
4 changes: 2 additions & 2 deletions env0/data_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ func TestUnitTemplateData(t *testing.T) {
ErrorRegex: "error retry on destroy",
}
templateRetry := client.TemplateRetry{
OnDeploy: onDeploy,
OnDestroy: onDestroy,
OnDeploy: &onDeploy,
OnDestroy: &onDestroy,
}

template := client.Template{
Expand Down
46 changes: 30 additions & 16 deletions env0/resource_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,22 @@ import (
"errors"
"github.com/env0/terraform-provider-env0/client"
"github.com/google/uuid"
"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"log"
)

func resourceTemplate() *schema.Resource {
validateRetries := func(i interface{}, path cty.Path) diag.Diagnostics {
retries := i.(int)
if retries < 1 || retries > 3 {
return diag.Errorf("Retries amount must be between 1 and 3")
}

return nil
}

return &schema.Resource{
CreateContext: resourceTemplateCreate,
ReadContext: resourceTemplateRead,
Expand Down Expand Up @@ -61,24 +71,28 @@ func resourceTemplate() *schema.Resource {
},
},
"retries_on_deploy": {
Type: schema.TypeInt,
Description: "number of times to retry when deploying an environment based on this template",
Optional: true,
Type: schema.TypeInt,
Description: "number of times to retry when deploying an environment based on this template",
Optional: true,
ValidateDiagFunc: validateRetries,
},
"retry_on_deploy_only_when_matches_regex": {
Type: schema.TypeString,
Description: "if specified, will only retry (on deploy) if error matches specified regex",
Optional: true,
Type: schema.TypeString,
Description: "if specified, will only retry (on deploy) if error matches specified regex",
Optional: true,
RequiredWith: []string{"retries_on_deploy"},
},
"retries_on_destroy": {
Type: schema.TypeInt,
Description: "number of times to retry when destroying an environment based on this template",
Optional: true,
Type: schema.TypeInt,
Description: "number of times to retry when destroying an environment based on this template",
Optional: true,
ValidateDiagFunc: validateRetries,
},
"retry_on_destroy_only_when_matches_regex": {
Type: schema.TypeString,
Description: "if specified, will only retry (on destroy) if error matches specified regex",
Optional: true,
Type: schema.TypeString,
Description: "if specified, will only retry (on destroy) if error matches specified regex",
Optional: true,
RequiredWith: []string{"retries_on_destroy"},
},
"github_installation_id": {
Type: schema.TypeInt,
Expand Down Expand Up @@ -160,10 +174,10 @@ func templateCreatePayloadFromParameters(d *schema.ResourceData) (client.Templat
if onDeploy != nil || onDestroy != nil {
result.Retry = client.TemplateRetry{}
if onDeploy != nil {
result.Retry.OnDeploy = *onDeploy
result.Retry.OnDeploy = onDeploy
}
if onDestroy != nil {
result.Retry.OnDestroy = *onDestroy
result.Retry.OnDestroy = onDestroy
}
}

Expand Down Expand Up @@ -213,14 +227,14 @@ func resourceTemplateRead(ctx context.Context, d *schema.ResourceData, meta inte
}
d.Set("ssh_keys", rawSshKeys)

if (template.Retry.OnDeploy != client.TemplateRetryOn{}) {
if template.Retry.OnDeploy != nil {
d.Set("retries_on_deploy", template.Retry.OnDeploy.Times)
d.Set("retry_on_deploy_only_when_matches_regex", template.Retry.OnDeploy.ErrorRegex)
} else {
d.Set("retries_on_deploy", 0)
d.Set("retry_on_deploy_only_when_matches_regex", "")
}
if (template.Retry.OnDestroy != client.TemplateRetryOn{}) {
if template.Retry.OnDestroy != nil {
d.Set("retries_on_destroy", template.Retry.OnDestroy.Times)
d.Set("retry_on_destroy_only_when_matches_regex", template.Retry.OnDestroy.ErrorRegex)
} else {
Expand Down
55 changes: 50 additions & 5 deletions env0/resource_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"testing"
)

func TestUnitTeplateResource(t *testing.T) {
func TestUnitTemplateResource(t *testing.T) {
const resourceType = "env0_template"
const resourceName = "test"
const defaultVersion = "0.15.1"
Expand All @@ -27,11 +27,11 @@ func TestUnitTeplateResource(t *testing.T) {
Path: "path/zero",
Revision: "branch-zero",
Retry: client.TemplateRetry{
OnDeploy: client.TemplateRetryOn{
OnDeploy: &client.TemplateRetryOn{
Times: 2,
ErrorRegex: "RetryMeForDeploy.*",
},
OnDestroy: client.TemplateRetryOn{
OnDestroy: &client.TemplateRetryOn{
Times: 1,
ErrorRegex: "RetryMeForDestroy.*",
},
Expand All @@ -49,11 +49,11 @@ func TestUnitTeplateResource(t *testing.T) {
Path: "path/zero/new",
Revision: "branch-zero-new",
Retry: client.TemplateRetry{
OnDeploy: client.TemplateRetryOn{
OnDeploy: &client.TemplateRetryOn{
Times: 1,
ErrorRegex: "NewForDeploy.*",
},
OnDestroy: client.TemplateRetryOn{
OnDestroy: &client.TemplateRetryOn{
Times: 2,
ErrorRegex: "NewForDestroy.*",
},
Expand Down Expand Up @@ -312,4 +312,49 @@ func TestUnitTeplateResource(t *testing.T) {
mock.EXPECT().TemplateDelete(template.Id).Times(1).Return(nil)
})
})

t.Run("Invalid retry times field", func(t *testing.T) {
testMatrix := map[string][]int{
"retries_on_deploy": {-1, 0, 4, 5},
"retries_on_destroy": {-1, 0, 4, 5},
}

var testCases []resource.TestCase
for attribute, amounts := range testMatrix {
for _, amount := range amounts {
testCases = append(testCases, resource.TestCase{
Steps: []resource.TestStep{
{
Config: resourceConfigCreate(resourceType, resourceName, map[string]interface{}{"name": "test", "repository": "env0/test", attribute: amount}),
ExpectError: regexp.MustCompile("Retries amount must be between 1 and 3"),
},
},
})
}
}

for _, testCase := range testCases {
runUnitTest(t, testCase, func(mockFunc *client.MockApiClientInterface) {})
}
})

t.Run("Invalid retry regex field", func(t *testing.T) {
testMatrix := map[string]string{
"retries_on_deploy": "retry_on_deploy_only_when_matches_regex",
"retries_on_destroy": "retry_on_destroy_only_when_matches_regex",
}

var testCases []resource.TestCase
for timesAttribute, regexAttribute := range testMatrix {
testCases = append(testCases, resource.TestCase{
Steps: []resource.TestStep{
{
Config: resourceConfigCreate(resourceType, resourceName, map[string]interface{}{"name": "test", "repository": "env0/test", regexAttribute: "bla"}),
ExpectError: regexp.MustCompile(fmt.Sprintf("`%s,%s` must be specified", timesAttribute, regexAttribute)),
},
},
})
}

})
}

0 comments on commit 44c1ab9

Please sign in to comment.