Skip to content

Commit

Permalink
Add support for resource gocd_environment
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhilsbhat committed Jan 4, 2023
1 parent faae241 commit 04e6ba4
Show file tree
Hide file tree
Showing 11 changed files with 298 additions and 20 deletions.
20 changes: 20 additions & 0 deletions examples/environment.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
resource "gocd_environment" "sample_environment" {
name = "sample_environment"
pipelines = [
"gocd-prometheus-exporter",
"helm-images",
"action-movies-manual",
]
environment_variables {
name = "TEST_ENV11"
value = "value_env11"
}
environment_variables {
name = "TEST_ENV12"
value = "value_env18"
}
environment_variables {
name = "TEST_ENV13"
value = "value_env13"
}
}
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/google/go-cmp v0.5.9
github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1
github.com/mitchellh/mapstructure v1.5.0
github.com/nikhilsbhat/gocd-sdk-go v0.0.5-0.20221229180705-fbb017d26f90
github.com/nikhilsbhat/gocd-sdk-go v0.0.5-0.20230104161330-13e791b1bc8c
)

require (
Expand Down Expand Up @@ -43,9 +43,9 @@ require (
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
github.com/vmihailenco/tagparser v0.1.1 // indirect
github.com/zclconf/go-cty v1.12.1 // indirect
golang.org/x/net v0.4.0 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/net v0.5.0 // indirect
golang.org/x/sys v0.4.0 // indirect
golang.org/x/text v0.6.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
google.golang.org/grpc v1.50.1 // indirect
Expand Down
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/nikhilsbhat/gocd-sdk-go v0.0.5-0.20221229180705-fbb017d26f90 h1:ft/vJOtwctnj3wkroC0TkWxrUPp4EJQmHRBPO0re9Yk=
github.com/nikhilsbhat/gocd-sdk-go v0.0.5-0.20221229180705-fbb017d26f90/go.mod h1:3XwSMe/nFH/I0Kt2+ToKKWFyD6yvJb4HaoP0dBHytY4=
github.com/nikhilsbhat/gocd-sdk-go v0.0.5-0.20230104161330-13e791b1bc8c h1:/P0QqSOA/ZjhtY7+nVkD9Vb3WprdiLOMGjoXg/QLG8A=
github.com/nikhilsbhat/gocd-sdk-go v0.0.5-0.20230104161330-13e791b1bc8c/go.mod h1:3XwSMe/nFH/I0Kt2+ToKKWFyD6yvJb4HaoP0dBHytY4=
github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758=
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
Expand Down Expand Up @@ -170,8 +170,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand All @@ -193,16 +193,16 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
Expand Down
2 changes: 1 addition & 1 deletion gocd/cluster_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func clusterProfile() *schema.Resource {
func resourceClusterProfile() *schema.Resource {
return &schema.Resource{
CreateContext: resourceClusterProfileCreate,
ReadContext: resourceClusterProfileRead,
Expand Down
2 changes: 1 addition & 1 deletion gocd/config_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/nikhilsbhat/terraform-provider-gocd/pkg/utils"
)

func configRepository() *schema.Resource {
func resourceConfigRepository() *schema.Resource {
return &schema.Resource{
CreateContext: resourceConfigRepoCreate,
ReadContext: resourceConfigRepoRead,
Expand Down
2 changes: 1 addition & 1 deletion gocd/elastic_agent_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func elasticAgentProfile() *schema.Resource {
func resourceElasticAgentProfile() *schema.Resource {
return &schema.Resource{
CreateContext: resourceElasticAgentProfileCreate,
ReadContext: resourceElasticAgentProfileRead,
Expand Down
2 changes: 1 addition & 1 deletion gocd/encrypt_value.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func encryptValue() *schema.Resource {
func resourceEncryptValue() *schema.Resource {
return &schema.Resource{
CreateContext: resourceEncryptValueCreate,
ReadContext: resourceEncryptValueRead,
Expand Down
218 changes: 218 additions & 0 deletions gocd/environments.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
package gocd

import (
"context"
"fmt"
"log"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/mitchellh/mapstructure"
"github.com/nikhilsbhat/gocd-sdk-go"
"github.com/nikhilsbhat/terraform-provider-gocd/pkg/utils"
)

func resourceEnvironment() *schema.Resource {
return &schema.Resource{
CreateContext: resourceEnvironmentCreate,
ReadContext: resourceEnvironmentRead,
DeleteContext: resourceEnvironmentDelete,
UpdateContext: resourceEnvironmentUpdate,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Computed: false,
ForceNew: true,
Description: "The name of environment.",
},
"pipelines": {
Type: schema.TypeList,
Optional: true,
Computed: false,
Description: "List of pipeline names that should be added to this environment.",
Elem: &schema.Schema{Type: schema.TypeString},
},
//"metadata": {
// Type: schema.TypeMap,
// Optional: true,
// Computed: false,
// Description: "Dummy type to handle updates",
// Elem: &schema.Schema{
// Type: schema.TypeString,
// },
//},
"environment_variables": environmentsSchema(),
"etag": {
Type: schema.TypeString,
Required: false,
Computed: true,
ForceNew: false,
Description: "etag used to track the plugin settings",
},
},
}
}

type environmentChanges struct {
envVarsChanges []gocd.EnvVars
pipelineChanges []gocd.Pipeline
equal bool
}

func resourceEnvironmentCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
defaultConfig := meta.(gocd.GoCd)

if !d.IsNewResource() {
return nil
}
id := d.Id()

if len(id) == 0 {
newID, err := utils.GetRandomID()
if err != nil {
d.SetId("")

return diag.Errorf("errored while fetching randomID %v", err)
}
id = newID
}

envVars, err := getEnvironments(d.Get(utils.TerraformEnvVar))
if err != nil {
return diag.Errorf("reading environment errored with %v", err)
}

cfg := gocd.Environment{
Name: utils.String(d.Get(utils.TerraformResourceName)),
Pipelines: getPipelines(d.Get(utils.TerraformPipelines)),
EnvVars: envVars,
}

if err = defaultConfig.CreateEnvironment(cfg); err != nil {
return diag.Errorf("creating environment %s errored with %v", cfg.Name, err)
}

d.SetId(id)

return resourceEnvironmentRead(ctx, d, meta)
}

func resourceEnvironmentRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
defaultConfig := meta.(gocd.GoCd)

envName := utils.String(d.Get(utils.TerraformResourceName))
response, err := defaultConfig.GetEnvironment(envName)
if err != nil {
return diag.Errorf("getting environment %s errored with: %v", envName, err)
}

if err = d.Set(utils.TerraformResourceEtag, response.ETAG); err != nil {
return diag.Errorf("setting etag errored with %v", err)
}

return nil
}

func resourceEnvironmentUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
defaultConfig := meta.(gocd.GoCd)

if d.HasChange(utils.TerraformPipelines) || d.HasChange(utils.TerraformEnvVar) {
changes, err := getEnvChanges(d)
if err != nil {
return diag.Errorf("fetching changes errored with %v", err)
}

if changes.equal {
return nil
}

cfg := gocd.Environment{
Name: utils.String(d.Get(utils.TerraformResourceName)),
Pipelines: changes.pipelineChanges,
EnvVars: changes.envVarsChanges,
ETAG: utils.String(d.Get(utils.TerraformResourceEtag)),
}

_, err = defaultConfig.UpdateEnvironment(cfg)
if err != nil {
return diag.Errorf("updating environment %s errored with: %v", cfg.Name, err)
}

return resourceEnvironmentRead(ctx, d, meta)
}

log.Printf("nothing to update so skipping")

return nil
}

func resourceEnvironmentDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
defaultConfig := meta.(gocd.GoCd)

if id := d.Id(); len(id) == 0 {
return diag.Errorf("resource with the ID '%s' not found", id)
}

envName := utils.String(d.Get(utils.TerraformResourceName))

err := defaultConfig.DeleteEnvironment(envName)
if err != nil {
return diag.Errorf("deleting environment %s errored with: %v", envName, err)
}

d.SetId("")

return nil
}

func getEnvironments(configs interface{}) ([]gocd.EnvVars, error) {
var envVars []gocd.EnvVars
envs := configs.(*schema.Set).List()
if err := mapstructure.Decode(envs, &envVars); err != nil {
return nil, fmt.Errorf(err.Error())
}

return envVars, nil
}

func getPipelines(configs interface{}) []gocd.Pipeline {
pipelines := make([]gocd.Pipeline, 0)
for _, pipeline := range configs.([]interface{}) {
pipelines = append(pipelines, gocd.Pipeline{Name: utils.String(pipeline)})
}

return pipelines
}

func getEnvChanges(d *schema.ResourceData) (environmentChanges, error) {
var changes environmentChanges
oldVars, newVars := d.GetChange(utils.TerraformEnvVar)
oldPipelines, newPipelines := d.GetChange(utils.TerraformPipelines)

envVars, err := getEnvironments(oldVars)
if err != nil {
return changes, fmt.Errorf("reading environment errored with %v", err)
}

changes.equal = true
changes.envVarsChanges = envVars
changes.pipelineChanges = getPipelines(oldPipelines)

if !cmp.Equal(oldVars, newVars) {
envVars, err = getEnvironments(newVars)
if err != nil {
return changes, fmt.Errorf("reading environment errored with %v", err)
}
changes.envVarsChanges = envVars
changes.equal = false
}

if !cmp.Equal(oldPipelines, newPipelines) {
changes.pipelineChanges = getPipelines(newPipelines)
changes.equal = false
}

return changes, nil
}
9 changes: 5 additions & 4 deletions gocd/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ func Provider() *schema.Provider {
ResourcesMap: map[string]*schema.Resource{
"gocd_plugin_setting": resourcePluginsSetting(),
"gocd_auth_config": resourceAuthConfig(),
"gocd_cluster_profile": clusterProfile(),
"gocd_elastic_agent_profile": elasticAgentProfile(),
"gocd_config_repository": configRepository(),
"gocd_encrypt_value": encryptValue(),
"gocd_cluster_profile": resourceClusterProfile(),
"gocd_elastic_agent_profile": resourceElasticAgentProfile(),
"gocd_config_repository": resourceConfigRepository(),
"gocd_encrypt_value": resourceEncryptValue(),
"gocd_environment": resourceEnvironment(),
},

DataSourcesMap: map[string]*schema.Resource{},
Expand Down
Loading

0 comments on commit 04e6ba4

Please sign in to comment.