From 57c553f00a6a64a91d8ef4a973aee5cb3fe27fd6 Mon Sep 17 00:00:00 2001 From: zambien Date: Thu, 26 Mar 2020 16:07:44 -0400 Subject: [PATCH 1/3] resolves #40, starting on #32 --- README.md | 22 ----------- apigee/helpers.go | 18 +++++++-- apigee/resource_api_proxy_deployment.go | 50 +++++++++++++------------ apigee/resource_company_app.go | 8 ++++ apigee/resource_developer_app.go | 8 ++++ go.mod | 2 + go.sum | 4 ++ 7 files changed, 63 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 8d7de86..c930245 100644 --- a/README.md +++ b/README.md @@ -260,25 +260,3 @@ goreleaser # actually create the release You can read more about goreleaser here: https://goreleaser.com/ - -## Important Known Issues - -Right now if you rev your proxy bundle then apply your deployment will not update automatically if you reference that proxy rev (as in the example above). - -To work around the issue you can apply twice: -``` -terraform apply && terraform apply -``` - -Or manually change the revision number in a variable or in the script... -``` -resource "apigee_api_proxy_deployment" "helloworld_proxy_deployment" { - proxy_name = "${apigee_api_proxy.helloworld_proxy.name}" - org = "${var.org}" - env = "${var.env}" - revision = 4 # the known next revision number -} -``` - -This is happening due to a known issue in Terraform that should be fixed soon: -https://github.com/hashicorp/terraform/issues/15857 \ No newline at end of file diff --git a/apigee/helpers.go b/apigee/helpers.go index 7e69037..e1a4f21 100644 --- a/apigee/helpers.go +++ b/apigee/helpers.go @@ -1,11 +1,11 @@ package apigee import ( - "reflect" - "sort" - + "github.com/17media/structs" "github.com/hashicorp/terraform/helper/schema" "github.com/zambien/go-apigee-edge" + "reflect" + "sort" ) func flattenStringList(list []string) []interface{} { @@ -60,6 +60,18 @@ func attributesFromMap(attributes map[string]interface{}) []apigee.Attribute { return result } +func mapFromCredentials(credentials []apigee.Credential) []interface{} { + + result := make([]interface{}, 0, len(credentials)) + + for _, elem := range credentials { + credentialMap := structs.Map(elem) + result = append(result, credentialMap) + } + + return result +} + func arraySortedEqual(a, b []string) bool { if len(a) != len(b) { return false diff --git a/apigee/resource_api_proxy_deployment.go b/apigee/resource_api_proxy_deployment.go index b97b441..c21dc91 100644 --- a/apigee/resource_api_proxy_deployment.go +++ b/apigee/resource_api_proxy_deployment.go @@ -104,23 +104,26 @@ func resourceApiProxyDeploymentRead(d *schema.ResourceData, meta interface{}) (e if environment.Name == d.Get("env").(string) { //We don't break. Always get the last one if there are multiple deployments. for _, revision := range environment.Revision { + found = true log.Printf("[DEBUG] resourceApiProxyDeploymentRead checking deployed revision: %#v for expected revision: %#v\n", revision.Number.String(), d.Get("revision").(string)) if d.Get("revision").(string) != "latest" && d.Get("revision").(string) == revision.Number.String() { matchedRevision = revision.Number.String() - found = true break } else { matchedRevision = revision.Number.String() } - found = true } } } } if found { - log.Printf("[DEBUG] resourceApiProxyDeploymentRead - deployment found. Revision is: %#v", matchedRevision) - d.Set("revision", matchedRevision) + if d.Get("revision").(string) == "latest" { + d.SetId(matchedRevision) + } else { + d.Set("revision", matchedRevision) + } + log.Printf("[DEBUG] resourceApiProxyDeploymentRead - deployment found. Revision is: %#v", d.Get("revision").(string)) } else { log.Print("[DEBUG] resourceApiProxyDeploymentRead - no deployment found") d.SetId("") @@ -143,16 +146,11 @@ func resourceApiProxyDeploymentCreate(d *schema.ResourceData, meta interface{}) if d.Get("revision").(string) == "latest" { // deploy latest - rev, err := getLatestRevision(client, proxy_name) + rev_int, err := getLatestRevision(client, proxy_name) + rev = apigee.Revision(rev_int) if err != nil { return fmt.Errorf("[ERROR] resourceApiProxyDeploymentUpdate error getting latest revision: %v", err) } - _, _, err = client.Proxies.Deploy(proxy_name, env, apigee.Revision(rev), delay, override) - if err != nil { - return fmt.Errorf("[ERROR] resourceApiProxyDeploymentUpdate error deploying: %v", err) - } - log.Printf("[DEBUG] resourceApiProxyDeploymentUpdate Deployed revision %d of %s", rev, proxy_name) - return resourceApiProxyDeploymentRead(d, meta) } proxyDep, _, err := client.Proxies.Deploy(proxy_name, env, rev, delay, override) @@ -174,6 +172,7 @@ func resourceApiProxyDeploymentCreate(d *schema.ResourceData, meta interface{}) d.SetId(id.String()) d.Set("revision", proxyDep.Revision.String()) + log.Printf("[DEBUG] resourceApiProxyDeploymentUpdate Deployed revision %d of %s", rev, proxy_name) return resourceApiProxyDeploymentRead(d, meta) } @@ -196,25 +195,17 @@ func resourceApiProxyDeploymentUpdate(d *schema.ResourceData, meta interface{}) override = true } + rev_int, _ := strconv.Atoi(d.Get("revision").(string)) + rev := apigee.Revision(rev_int) if d.Get("revision").(string) == "latest" { // deploy latest - rev, err := getLatestRevision(client, proxy_name) + rev_int, err := getLatestRevision(client, proxy_name) + rev = apigee.Revision(rev_int) if err != nil { return fmt.Errorf("[ERROR] resourceApiProxyDeploymentUpdate error getting latest revision: %v", err) } - _, _, err = client.Proxies.ReDeploy(proxy_name, env, apigee.Revision(rev), delay, override) - if err != nil { - if strings.Contains(err.Error(), " is already deployed ") { - return resourceApiProxyDeploymentRead(d, meta) - } - return fmt.Errorf("[ERROR] resourceApiProxyDeploymentUpdate error deploying: %v", err) - } - log.Printf("[DEBUG] resourceApiProxyDeploymentUpdate Deployed revision %d of %s", rev, proxy_name) - return resourceApiProxyDeploymentRead(d, meta) } - rev_int, _ := strconv.Atoi(d.Get("revision").(string)) - rev := apigee.Revision(rev_int) _, _, err := client.Proxies.ReDeploy(proxy_name, env, rev, delay, override) if err != nil { @@ -225,6 +216,7 @@ func resourceApiProxyDeploymentUpdate(d *schema.ResourceData, meta interface{}) return fmt.Errorf("[ERROR] resourceApiProxyDeploymentUpdate error redeploying: %s", err.Error()) } + log.Printf("[DEBUG] resourceApiProxyDeploymentUpdate Deployed revision %d of %s", rev, proxy_name) return resourceApiProxyDeploymentRead(d, meta) } @@ -236,16 +228,26 @@ func resourceApiProxyDeploymentDelete(d *schema.ResourceData, meta interface{}) proxy_name := d.Get("proxy_name").(string) env := d.Get("env").(string) + rev_int, _ := strconv.Atoi(d.Get("revision").(string)) rev := apigee.Revision(rev_int) + if d.Get("revision").(string) == "latest" { + // deploy latest + rev_int, err := getLatestRevision(client, proxy_name) + rev = apigee.Revision(rev_int) + if err != nil { + return fmt.Errorf("[ERROR] resourceApiProxyDeploymentDelete error getting latest revision: %v", err) + } + } _, _, err := client.Proxies.Undeploy(proxy_name, env, rev) if err != nil { log.Printf("[ERROR] resourceApiProxyDeploymentDelete error undeploying: %s", err.Error()) return fmt.Errorf("[ERROR] resourceApiProxyDeploymentDelete error undeploying: %s", err.Error()) } + log.Printf("[DEBUG] resourceApiProxyDeploymentDelete Deleted revision %d of %s", rev, proxy_name) - return nil + return resourceApiProxyDeploymentRead(d, meta) } func getLatestRevision(client *apigee.EdgeClient, proxyName string) (int, error) { diff --git a/apigee/resource_company_app.go b/apigee/resource_company_app.go index 5fdda40..652435b 100644 --- a/apigee/resource_company_app.go +++ b/apigee/resource_company_app.go @@ -36,6 +36,11 @@ func resourceCompanyApp() *schema.Resource { Type: schema.TypeMap, Optional: true, }, + "credentials": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeMap}, + }, "scopes": { Type: schema.TypeList, Optional: true, @@ -108,6 +113,8 @@ func resourceCompanyAppRead(d *schema.ResourceData, meta interface{}) error { //you might only ever have one credential... we'll see. scopes := flattenStringList(CompanyAppData.Credentials[0].Scopes) + credentials := mapFromCredentials(CompanyAppData.Credentials) + //Apigee does not return products in the order you send them oldApiProducts := getStringList("api_products", d) newApiProducts := apiProductsListFromCredentials(CompanyAppData.Credentials[0].ApiProducts) @@ -120,6 +127,7 @@ func resourceCompanyAppRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", CompanyAppData.Name) d.Set("attributes", CompanyAppData.Attributes) + d.Set("credentials", credentials) d.Set("scopes", scopes) d.Set("callback_url", CompanyAppData.CallbackUrl) d.Set("app_id", CompanyAppData.AppId) diff --git a/apigee/resource_developer_app.go b/apigee/resource_developer_app.go index edaa4e5..19e5fb1 100644 --- a/apigee/resource_developer_app.go +++ b/apigee/resource_developer_app.go @@ -40,6 +40,11 @@ func resourceDeveloperApp() *schema.Resource { Type: schema.TypeMap, Optional: true, }, + "credentials": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeMap}, + }, "scopes": { Type: schema.TypeList, Optional: true, @@ -116,6 +121,8 @@ func resourceDeveloperAppRead(d *schema.ResourceData, meta interface{}) error { //you might only ever have one credential... we'll see. scopes := flattenStringList(DeveloperAppData.Credentials[0].Scopes) + credentials := mapFromCredentials(DeveloperAppData.Credentials) + //Apigee does not return products in the order you send them oldApiProducts := getStringList("api_products", d) newApiProducts := apiProductsListFromCredentials(DeveloperAppData.Credentials[0].ApiProducts) @@ -128,6 +135,7 @@ func resourceDeveloperAppRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", DeveloperAppData.Name) d.Set("attributes", DeveloperAppData.Attributes) + d.Set("credentials", credentials) d.Set("scopes", scopes) d.Set("callback_url", DeveloperAppData.CallbackUrl) d.Set("app_id", DeveloperAppData.AppId) diff --git a/go.mod b/go.mod index 24a56ed..a32c6b4 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module github.com/zambien/terraform-provider-apigee go 1.13 require ( + github.com/17media/structs v0.0.0-20200317074636-7872972ebe57 + github.com/fatih/structs v1.1.0 // indirect github.com/gofrs/uuid v3.2.0+incompatible github.com/hashicorp/terraform v0.12.13 github.com/sethgrid/pester v0.0.0-20190127155807-68a33a018ad0 // indirect diff --git a/go.sum b/go.sum index 3b4a75a..7dd42c9 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,8 @@ dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= +github.com/17media/structs v0.0.0-20200317074636-7872972ebe57 h1:37pgIfOnYep7tssdIxFq51FH9DwETjTcYH8bkAm2Y8U= +github.com/17media/structs v0.0.0-20200317074636-7872972ebe57/go.mod h1:OYgQ/75ljAEp1bzyw70wLZ7QC6H3Hm2Li941u3rSXG0= github.com/Azure/azure-sdk-for-go v21.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-autorest v10.15.4+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= @@ -96,6 +98,8 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= From 00cfe14b71d56cbd07c926e7d9e67545f0cff9b3 Mon Sep 17 00:00:00 2001 From: zambien Date: Fri, 3 Apr 2020 08:37:22 -0400 Subject: [PATCH 2/3] resolves #40 --- apigee/resource_company_app.go | 8 -------- apigee/resource_developer_app.go | 8 -------- 2 files changed, 16 deletions(-) diff --git a/apigee/resource_company_app.go b/apigee/resource_company_app.go index 652435b..5fdda40 100644 --- a/apigee/resource_company_app.go +++ b/apigee/resource_company_app.go @@ -36,11 +36,6 @@ func resourceCompanyApp() *schema.Resource { Type: schema.TypeMap, Optional: true, }, - "credentials": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeMap}, - }, "scopes": { Type: schema.TypeList, Optional: true, @@ -113,8 +108,6 @@ func resourceCompanyAppRead(d *schema.ResourceData, meta interface{}) error { //you might only ever have one credential... we'll see. scopes := flattenStringList(CompanyAppData.Credentials[0].Scopes) - credentials := mapFromCredentials(CompanyAppData.Credentials) - //Apigee does not return products in the order you send them oldApiProducts := getStringList("api_products", d) newApiProducts := apiProductsListFromCredentials(CompanyAppData.Credentials[0].ApiProducts) @@ -127,7 +120,6 @@ func resourceCompanyAppRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", CompanyAppData.Name) d.Set("attributes", CompanyAppData.Attributes) - d.Set("credentials", credentials) d.Set("scopes", scopes) d.Set("callback_url", CompanyAppData.CallbackUrl) d.Set("app_id", CompanyAppData.AppId) diff --git a/apigee/resource_developer_app.go b/apigee/resource_developer_app.go index 19e5fb1..edaa4e5 100644 --- a/apigee/resource_developer_app.go +++ b/apigee/resource_developer_app.go @@ -40,11 +40,6 @@ func resourceDeveloperApp() *schema.Resource { Type: schema.TypeMap, Optional: true, }, - "credentials": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeMap}, - }, "scopes": { Type: schema.TypeList, Optional: true, @@ -121,8 +116,6 @@ func resourceDeveloperAppRead(d *schema.ResourceData, meta interface{}) error { //you might only ever have one credential... we'll see. scopes := flattenStringList(DeveloperAppData.Credentials[0].Scopes) - credentials := mapFromCredentials(DeveloperAppData.Credentials) - //Apigee does not return products in the order you send them oldApiProducts := getStringList("api_products", d) newApiProducts := apiProductsListFromCredentials(DeveloperAppData.Credentials[0].ApiProducts) @@ -135,7 +128,6 @@ func resourceDeveloperAppRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", DeveloperAppData.Name) d.Set("attributes", DeveloperAppData.Attributes) - d.Set("credentials", credentials) d.Set("scopes", scopes) d.Set("callback_url", DeveloperAppData.CallbackUrl) d.Set("app_id", DeveloperAppData.AppId) From d811245a3eb1d5b9bb4e5c3c75c74c7ab4d77284 Mon Sep 17 00:00:00 2001 From: zambien Date: Fri, 3 Apr 2020 08:40:45 -0400 Subject: [PATCH 3/3] remove cred map code --- apigee/helpers.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/apigee/helpers.go b/apigee/helpers.go index e1a4f21..3313665 100644 --- a/apigee/helpers.go +++ b/apigee/helpers.go @@ -1,7 +1,6 @@ package apigee import ( - "github.com/17media/structs" "github.com/hashicorp/terraform/helper/schema" "github.com/zambien/go-apigee-edge" "reflect" @@ -60,18 +59,6 @@ func attributesFromMap(attributes map[string]interface{}) []apigee.Attribute { return result } -func mapFromCredentials(credentials []apigee.Credential) []interface{} { - - result := make([]interface{}, 0, len(credentials)) - - for _, elem := range credentials { - credentialMap := structs.Map(elem) - result = append(result, credentialMap) - } - - return result -} - func arraySortedEqual(a, b []string) bool { if len(a) != len(b) { return false