Skip to content

Commit

Permalink
Feat: add wait_for_destroy option when destroying and environment (#946)
Browse files Browse the repository at this point in the history
* Feat: add wait_for_destroy option when destroying and environment

* changes based on PR comments

* minor change

* added disclaimer

* made changes based on PR feedback
  • Loading branch information
TomerHeber authored Oct 14, 2024
1 parent 1209c07 commit af33272
Show file tree
Hide file tree
Showing 53 changed files with 408 additions and 47 deletions.
3 changes: 2 additions & 1 deletion client/api_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ type ApiClientInterface interface {
Environment(id string) (Environment, error)
EnvironmentCreate(payload EnvironmentCreate) (Environment, error)
EnvironmentCreateWithoutTemplate(payload EnvironmentCreateWithoutTemplate) (Environment, error)
EnvironmentDestroy(id string) (Environment, error)
EnvironmentDestroy(id string) (*EnvironmentDestroyResponse, error)
EnvironmentMarkAsArchived(id string) error
EnvironmentUpdate(id string, payload EnvironmentUpdate) (Environment, error)
EnvironmentDeploy(id string, payload DeployRequest) (EnvironmentDeployResponse, error)
Expand All @@ -75,6 +75,7 @@ type ApiClientInterface interface {
EnvironmentScheduling(environmentId string) (EnvironmentScheduling, error)
EnvironmentSchedulingUpdate(environmentId string, payload EnvironmentScheduling) (EnvironmentScheduling, error)
EnvironmentSchedulingDelete(environmentId string) error
EnvironmentDeploymentLog(id string) (*DeploymentLog, error)
WorkflowTrigger(environmentId string) ([]WorkflowTrigger, error)
WorkflowTriggerUpsert(environmentId string, request WorkflowTriggerUpsertPayload) ([]WorkflowTrigger, error)
EnvironmentDriftDetection(environmentId string) (EnvironmentSchedulingExpression, error)
Expand Down
19 changes: 17 additions & 2 deletions client/api_client_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 19 additions & 5 deletions client/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (c *ConfigurationVariableType) WriteResourceData(fieldName string, d *schem

switch val := *c; val {
case 0:
valStr = "environment"
valStr = ENVIRONMENT
case 1:
valStr = TERRAFORM
default:
Expand Down Expand Up @@ -93,6 +93,7 @@ type DeploymentLog struct {
Output json.RawMessage `json:"output,omitempty"`
Error json.RawMessage `json:"error,omitempty"`
Type string `json:"type"`
Status string `json:"status"`
WorkflowFile *WorkflowFile `json:"workflowFile,omitempty" tfschema:"-"`
}

Expand Down Expand Up @@ -165,6 +166,10 @@ type EnvironmentMoveRequest struct {
ProjectId string `json:"projectId"`
}

type EnvironmentDestroyResponse struct {
Id string `json:"id"`
}

func GetConfigurationVariableType(variableType string) (ConfigurationVariableType, error) {
switch variableType {
case "terraform":
Expand Down Expand Up @@ -258,6 +263,15 @@ func (client *ApiClient) Environment(id string) (Environment, error) {
return result, nil
}

func (client *ApiClient) EnvironmentDeploymentLog(id string) (*DeploymentLog, error) {
var result DeploymentLog
err := client.http.Get("/environments/deployments/"+id, nil, &result)
if err != nil {
return nil, err
}
return &result, nil
}

func (client *ApiClient) EnvironmentCreate(payload EnvironmentCreate) (Environment, error) {
var result Environment

Expand Down Expand Up @@ -285,13 +299,13 @@ func (client *ApiClient) EnvironmentCreateWithoutTemplate(payload EnvironmentCre
return result, nil
}

func (client *ApiClient) EnvironmentDestroy(id string) (Environment, error) {
var result Environment
func (client *ApiClient) EnvironmentDestroy(id string) (*EnvironmentDestroyResponse, error) {
var result EnvironmentDestroyResponse
err := client.http.Post("/environments/"+id+"/destroy", nil, &result)
if err != nil {
return Environment{}, err
return nil, err
}
return result, nil
return &result, nil
}

func (client *ApiClient) EnvironmentUpdate(id string, payload EnvironmentUpdate) (Environment, error) {
Expand Down
44 changes: 42 additions & 2 deletions client/environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,15 +280,27 @@ var _ = Describe("Environment Client", func() {

Describe("EnvironmentDelete", func() {
var err error
var res *EnvironmentDestroyResponse

mockedRes := EnvironmentDestroyResponse{
Id: "id123",
}

BeforeEach(func() {
httpCall = mockHttpClient.EXPECT().Post("/environments/"+mockEnvironment.Id+"/destroy", nil, gomock.Any()).Times(1)
_, err = apiClient.EnvironmentDestroy(mockEnvironment.Id)
httpCall = mockHttpClient.EXPECT().Post("/environments/"+mockEnvironment.Id+"/destroy", nil, gomock.Any()).Times(1).
Do((func(path string, request interface{}, response *EnvironmentDestroyResponse) {
*response = mockedRes
}))
res, err = apiClient.EnvironmentDestroy(mockEnvironment.Id)
})

It("Should not return error", func() {
Expect(err).To(BeNil())
})

It("Should return the expected response", func() {
Expect(*res).To(Equal(mockedRes))
})
})

Describe("EnvironmentMarkAsArchived", func() {
Expand Down Expand Up @@ -438,6 +450,34 @@ var _ = Describe("Environment Client", func() {
Expect(err).To(BeNil())
})
})

Describe("EnvironmentDeployment", func() {
var deployment *DeploymentLog
var err error

mockDeployment := DeploymentLog{
Id: "id12345",
Status: "IN_PROGRESS",
}

BeforeEach(func() {
httpCall = mockHttpClient.EXPECT().
Get("/environments/deployments/"+mockDeployment.Id, nil, gomock.Any()).
Do(func(path string, request interface{}, response *DeploymentLog) {
*response = mockDeployment
}).Times(1)

deployment, err = apiClient.EnvironmentDeploymentLog(mockDeployment.Id)
})

It("Should return deployment", func() {
Expect(*deployment).To(Equal(mockDeployment))
})

It("Should not return an error", func() {
Expect(err).To(BeNil())
})
})
})

func TestMarshalEnvironmentCreateWithoutTemplate(t *testing.T) {
Expand Down
1 change: 0 additions & 1 deletion env0/data_agent_values_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,4 @@ func TestAgentValues(t *testing.T) {
},
)
})

}
1 change: 1 addition & 0 deletions env0/data_cloud_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func dataCloudCredentialsRead(ctx context.Context, d *schema.ResourceData, meta
if filter && credential_type != credentials.Type {
continue
}

data = append(data, credentials.Name)
}

Expand Down
1 change: 0 additions & 1 deletion env0/data_credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,4 @@ func TestCredentialsDataSource(t *testing.T) {
)
})
}

}
2 changes: 2 additions & 0 deletions env0/data_custom_flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func dataCustomFlow() *schema.Resource {

func dataCustomFlowRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var err error

var customFlow *client.CustomFlow

id, ok := d.GetOk("id")
Expand All @@ -41,6 +42,7 @@ func dataCustomFlowRead(ctx context.Context, d *schema.ResourceData, meta interf
}
} else {
name := d.Get("name")

customFlow, err = getCustomFlowByName(name.(string), meta)
if err != nil {
return diag.Errorf("failed to get custom flow by name: %v", err)
Expand Down
1 change: 1 addition & 0 deletions env0/data_custom_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func dataCustomRole() *schema.Resource {

func dataCustomRoleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var err error

var role *client.Role

id, ok := d.GetOk("id")
Expand Down
1 change: 1 addition & 0 deletions env0/data_custom_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func dataCustomRoles() *schema.Resource {

func dataCustomRolesRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
apiClient := meta.(client.ApiClientInterface)

roles, err := apiClient.Roles()
if err != nil {
return diag.Errorf("Failed to get custom roles: %v", err)
Expand Down
2 changes: 2 additions & 0 deletions env0/data_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ func dataEnvironment() *schema.Resource {

func dataEnvironmentRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var err diag.Diagnostics

var environment client.Environment

projectId := d.Get("project_id").(string)
Expand All @@ -138,6 +139,7 @@ func dataEnvironmentRead(ctx context.Context, d *schema.ResourceData, meta inter
} else {
name := d.Get("name").(string)
excludeArchived := d.Get("exclude_archived")

environment, err = getEnvironmentByName(meta, name, projectId, excludeArchived.(bool))
if err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions env0/data_git_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func dataGitToken() *schema.Resource {

func dataGitTokenRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var gitToken *client.GitToken

var err error

id, ok := d.GetOk("id")
Expand Down
1 change: 0 additions & 1 deletion env0/data_kubernetes_credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,4 @@ func TestKubernetesCredentialsDataSource(t *testing.T) {
)
})
}

}
1 change: 0 additions & 1 deletion env0/data_module_testing_project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,4 @@ func TestModuleTestingProjectDataSource(t *testing.T) {
},
)
})

}
1 change: 1 addition & 0 deletions env0/data_notifications.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func dataNotifications() *schema.Resource {

func dataNotificationsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
apiClient := meta.(client.ApiClientInterface)

notifications, err := apiClient.Notifications()
if err != nil {
return diag.Errorf("could not get notifications: %v", err)
Expand Down
1 change: 0 additions & 1 deletion env0/data_oidc_credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,4 @@ func TestOidcCredentialDataSource(t *testing.T) {
)
})
}

}
2 changes: 2 additions & 0 deletions env0/data_project_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,11 @@ func dataPolicyRead(ctx context.Context, d *schema.ResourceData, meta interface{

func getPolicyByProjectId(projectId string, meta interface{}) (client.Policy, diag.Diagnostics) {
apiClient := meta.(client.ApiClientInterface)

policy, err := apiClient.Policy(projectId)
if err != nil {
return client.Policy{}, diag.Errorf("Could not query policy: %v", err)
}

return policy, nil
}
1 change: 1 addition & 0 deletions env0/data_projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func dataProjectsRead(ctx context.Context, d *schema.ResourceData, meta interfac
}

filteredProjects := []client.Project{}

for _, project := range projects {
if includeArchivedProjects || !project.IsArchived {
filteredProjects = append(filteredProjects, project)
Expand Down
1 change: 0 additions & 1 deletion env0/data_source_code_variables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,4 @@ func TestSourceCodeVariablesDataSource(t *testing.T) {
},
)
})

}
2 changes: 2 additions & 0 deletions env0/data_sshkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func getSshKeyByName(name interface{}, meta interface{}) (*client.SshKey, error)
if len(sshKeysByName) > 1 {
return nil, backoff.Permanent(fmt.Errorf("found multiple ssh keys with name: %s. Use id instead or make sure ssh key names are unique %v", name, sshKeysByName))
}

if len(sshKeysByName) == 0 {
return nil, fmt.Errorf("ssh key with name %v not found", name)
}
Expand All @@ -97,6 +98,7 @@ func getSshKeyById(id interface{}, meta interface{}) (*client.SshKey, error) {
}

var sshKey *client.SshKey

for _, candidate := range sshKeys {
if candidate.Id == id.(string) {
sshKey = &candidate
Expand Down
1 change: 1 addition & 0 deletions env0/data_team.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func dataTeamRead(ctx context.Context, d *schema.ResourceData, meta interface{})
if !ok {
return diag.Errorf("Either 'name' or 'id' must be specified")
}

team, err = getTeamByName(name.(string), meta)
if err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions env0/data_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,5 +205,6 @@ func getTemplateById(id interface{}, meta interface{}) (client.Template, diag.Di
if err != nil {
return client.Template{}, diag.Errorf("Could not query template: %v", err)
}

return template, nil
}
3 changes: 3 additions & 0 deletions env0/data_variable_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func dataVariableSetRead(ctx context.Context, d *schema.ResourceData, meta inter
switch resource.Scope {
case "ORGANIZATION":
var err error

scopeId, err = apiClient.OrganizationId()
if err != nil {
return diag.Errorf("could not get organization id: %v", err)
Expand All @@ -64,6 +65,7 @@ func dataVariableSetRead(ctx context.Context, d *schema.ResourceData, meta inter
if resource.ProjectId == "" {
return diag.Errorf("'project_id' is required")
}

scopeId = resource.ProjectId
}

Expand All @@ -75,6 +77,7 @@ func dataVariableSetRead(ctx context.Context, d *schema.ResourceData, meta inter
for _, variableSet := range variableSets {
if variableSet.Name == resource.Name {
d.SetId(variableSet.Id)

return nil
}
}
Expand Down
1 change: 1 addition & 0 deletions env0/data_variable_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func TestVariableSetDataSource(t *testing.T) {
if organizationId != "" {
mock.EXPECT().OrganizationId().AnyTimes().Return(organizationId, nil)
}

mock.EXPECT().ConfigurationSets(scope, scopeId).AnyTimes().Return(returnValue, nil)
}
}
Expand Down
4 changes: 3 additions & 1 deletion env0/data_workflow_triggers.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ func dataWorkflowTriggersRead(ctx context.Context, d *schema.ResourceData, meta
}

d.SetId(environmentId)
var triggerIds []string

triggerIds := []string{}

for _, value := range triggers {
triggerIds = append(triggerIds, value.Id)
}
Expand Down
1 change: 1 addition & 0 deletions env0/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func ResourceGetFailure(ctx context.Context, resourceName string, d *schema.Reso
if driftDetected(err) {
tflog.Warn(ctx, "Drift Detected: Terraform will remove id from state", map[string]interface{}{"id": d.Id()})
d.SetId("")

return nil
}

Expand Down
Loading

0 comments on commit af33272

Please sign in to comment.