Skip to content

Commit

Permalink
Merge pull request #72 from zambien/v0.0.24
Browse files Browse the repository at this point in the history
V0.0.24
  • Loading branch information
zambien authored Apr 28, 2021
2 parents 6b8e367 + 307352c commit 8e6ea81
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 91 deletions.
65 changes: 38 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,17 @@ Allows Terraform deployments and management of Apigee API proxies, deployments,

https://registry.terraform.io/providers/zambien/apigee/

## Installation

Download the appropriate release for your system: https://github.com/zambien/terraform-provider-apigee/releases

See here for info on how to install the plugin:

https://www.terraform.io/docs/plugins/basics.html

An example of how to do this would be:

1. Make a terraform providers folder in home
`mkdir -p ~/terraform-providers`

2. Download plugin for linux into your home directory
`curl -L https://github.com/zambien/terraform-provider-apigee/releases/download/v0.0.22/terraform-provider-apigee_0.0.22_linux_amd64.tar.gz -o ~/terraform-providers/terraform-provider-apigee_0.0.22_linux_amd64.tar.gz && cd ~/terraform-providers/ && tar xzf terraform-provider-apigee_0.0.22_linux_amd64.tar.gz`

3. Add the providers clause if you don't already have one. Warning, this command will overwrite your .terraformrc!
```
cat << EOF > ~/.terraformrc
providers {
apigee = "$HOME/terraform-providers/terraform-provider-apigee_v0.0.22"
}
EOF
```

- [terraform-provider-apigee](#terraform-provider-apigee)
* [TFVARS for provider](#tfvars-for-provider)
* [Simple Example](#simple-example)
* [Contributions](#contributions)
* [Building](#building)
* [Testing](#testing)
- [Set env vars for test using username/password:](#set-env-vars-for-test-using-username-password-)
- [Set env vars for test using access token:](#set-env-vars-for-test-using-access-token-)
* [Releasing](#releasing)
* [Known issues](#known-issues)

## TFVARS for provider

```
Expand All @@ -49,6 +35,25 @@ APIGEE_ACCESS_TOKEN="my-access-token"

```
# note, to test and build the plugin locally uncomment the lines below or do something like it
# provider_version=0.0.x
# mkdir -p ~/.terraform.d/plugins/local/zambien/apigee/${provider_version}/linux_amd64/
# mv terraform-provider-apigee-v${provider_version}-linux64 ~/.terraform.d/plugins/local/zambien/apigee/${provider_version}/linux_amd64/terraform-provider-apigee_v${provider_version}
terraform {
required_version = ">= 0.14"
required_providers {
apigee = {
# pull from registry
source = "zambien/apigee"
# test locally built plugin
# source = "local/zambien/apigee"
version = "~> 0.0.23"
}
}
}
variable "org" { default = "my-really-cool-apigee-org-name" }
variable "env" { default = "test" }
Expand Down Expand Up @@ -109,7 +114,8 @@ resource "apigee_api_proxy_deployment" "helloworld_proxy_deployment" {
# NOTE: revision = "latest"
# will deploy the latest revision of the api proxy
revision = "${apigee_api_proxy.helloworld_proxy.revision}"
revision = "latest"
# OR revision = "1" # for specific revision
}
# A target server
Expand Down Expand Up @@ -206,7 +212,8 @@ resource "apigee_shared_flow_deployment" "helloworld_shared_flow_deployment" {
# NOTE: revision = "latest"
# will deploy the latest revision of the shared flow
revision = "${apigee_shared_flow.helloworld_shared_flow.revision}"
revision = "latest"
# OR revision = "1" # for specific revision
}
```

Expand Down Expand Up @@ -264,3 +271,7 @@ goreleaser # actually create the release
You can read more about goreleaser here:

https://goreleaser.com/

## Known issues

* You will often find the need to run apply twice when updating a proxy. This has to do with how terraform handles state. This plugin will be rewritten to combine proxies and proxy deployments to resolve this issue in the future.
31 changes: 24 additions & 7 deletions apigee/helpers.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package apigee

import (
"github.com/17media/structs"
"github.com/hashicorp/terraform/helper/schema"
"github.com/zambien/go-apigee-edge"
"reflect"
Expand Down Expand Up @@ -60,16 +59,34 @@ func attributesFromMap(attributes map[string]interface{}) []apigee.Attribute {
return result
}

func mapFromCredentials(credentials []apigee.Credential) []interface{} {
func flattenCredentials(in []apigee.Credential) []interface{} {

result := make([]interface{}, 0, len(credentials))
if in != nil {

for _, elem := range credentials {
credentialMap := structs.Map(elem)
result = append(result, credentialMap)
out := make([]interface{}, len(in), len(in))

for i, elem := range in {

m := make(map[string]interface{})

m["consumer_key"] = elem.ConsumerKey
m["consumer_secret"] = elem.ConsumerSecret
m["issued_at"] = elem.IssuedAt
m["expired_at"] = elem.ExpiresAt


/*
if len(elem.ApiProducts) > 0 {
m["port_mapping"] = flattenDockerPortMappings(elem.PortMappings)
}*/

out[i] = m
}

return out
}

return result
return make([]interface{}, 0)
}

func arraySortedEqual(a, b []string) bool {
Expand Down
30 changes: 25 additions & 5 deletions apigee/resource_api_proxy_deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,25 @@ func resourceApiProxyDeploymentRead(d *schema.ResourceData, meta interface{}) (e

if found {
if d.Get("revision").(string) == "latest" {
d.SetId(matchedRevision)

log.Printf("[DEBUG] resourceApiProxyDeploymentRead doing latest check")

// Get the latest revision and make sure we show it as different if it is
rev_int := 0
rev := apigee.Revision(rev_int)

rev_int, err := getLatestRevision(client, d.Get("proxy_name").(string))
rev = apigee.Revision(rev_int)
if err != nil {
return fmt.Errorf("[ERROR] resourceApiProxyDeploymentUpdate error getting latest revision: %v", err)
}

log.Printf("[DEBUG] resourceApiProxyDeploymentRead found latest revision: %#v\n", rev)

if matchedRevision != strconv.Itoa(rev_int) {
log.Printf("[DEBUG] resourceApiProxyDeploymentRead latest deployed revision: %#v did not match actual latest revision: %#v. Updating revision to latest available. \n", matchedRevision, strconv.Itoa(rev_int))
d.Set("revision", strconv.Itoa(rev_int))
}
} else {
d.Set("revision", matchedRevision)
}
Expand Down Expand Up @@ -149,15 +167,17 @@ func resourceApiProxyDeploymentCreate(d *schema.ResourceData, meta interface{})
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)
return fmt.Errorf("[ERROR] resourceApiProxyDeploymentCreate error getting latest revision: %v", err)
}
}

proxyDep, _, err := client.Proxies.Deploy(proxy_name, env, rev, delay, override)

if err != nil {

if strings.Contains(err.Error(), "conflicts with existing deployment path") {
if strings.Contains(err.Error(), " is already deployed ") {
log.Printf("[ERROR] resourceApiProxyDeploymentCreate error deploying. We will read into state: %s", err.Error())
resourceApiProxyDeploymentUpdate(d, meta)
} else if strings.Contains(err.Error(), "conflicts with existing deployment path") {
//create, fail, update
log.Printf("[ERROR] resourceApiProxyDeploymentCreate error deploying: %s", err.Error())
log.Print("[DEBUG] resourceApiProxyDeploymentCreate something got out of sync... maybe someone messing around in apigee directly. Terraform OVERRIDE!!!")
Expand Down Expand Up @@ -210,7 +230,7 @@ func resourceApiProxyDeploymentUpdate(d *schema.ResourceData, meta interface{})

if err != nil {
log.Printf("[ERROR] resourceApiProxyDeploymentUpdate error redeploying: %s", err.Error())
if strings.Contains(err.Error(), " is already deployed into environment ") {
if strings.Contains(err.Error(), " is already deployed ") {
return resourceApiProxyDeploymentRead(d, meta)
}
return fmt.Errorf("[ERROR] resourceApiProxyDeploymentUpdate error redeploying: %s", err.Error())
Expand Down
62 changes: 18 additions & 44 deletions apigee/resource_company_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ func resourceCompanyApp() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
/*
"credentials": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeMap},
},*/
"credentials": {
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -104,7 +98,7 @@ func resourceCompanyApp() *schema.Resource {
},
"scopes": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"callback_url": {
Expand All @@ -119,6 +113,14 @@ func resourceCompanyApp() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"consumer_key": {
Type: schema.TypeString,
Computed: true,
},
"consumer_secret": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -170,28 +172,17 @@ func resourceCompanyAppRead(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] resourceCompanyAppRead CompanyAppData: %+v\n", CompanyAppData)

//Scopes and apiProducts are tricky. These actually result in an array which will always have
//one element unless an outside API is called. Since using terraform we assume you do everything there
//you might only ever have one credential... we'll see.
scopes := flattenStringList(CompanyAppData.Credentials[0].Scopes)

credentials := mapFromCredentials(CompanyAppData.Credentials)

//credentials_again
if CompanyAppData.Credentials != nil {
//one element unless an outside API is called.
//Get the most recent scopes from the last credentials set
scopes := flattenStringList(CompanyAppData.Credentials[len(CompanyAppData.Credentials)-1].Scopes)

log.Print("[DEBUG] resourceCompanyAppRead credentials ConsumerKey: ", CompanyAppData.Credentials[0].ConsumerKey)
log.Print("[DEBUG] resourceCompanyAppRead credentials ConsumerSecret: ", CompanyAppData.Credentials[0].ConsumerSecret)

d.Set("credentials.0.consumer_key", CompanyAppData.Credentials[0].ConsumerKey)
d.Set("credentials.0.consumer_secret", CompanyAppData.Credentials[0].ConsumerSecret)

log.Print("[DEBUG] resourceCompanyAppRead credentials: ", d.Get("credentials.0"))
log.Print("[DEBUG] resourceCompanyAppRead credentials consumer key: ", d.Get("credentials.0.consumer_key"))
}
//TBD: credentials complex list. See comments in resource_developer_app.go
d.Set("credentials", make([]interface{}, 0))

//Apigee does not return products in the order you send them
//Get the most recent api products from the last credentials set
oldApiProducts := getStringList("api_products", d)
newApiProducts := apiProductsListFromCredentials(CompanyAppData.Credentials[0].ApiProducts)
newApiProducts := apiProductsListFromCredentials(CompanyAppData.Credentials[len(CompanyAppData.Credentials)-1].ApiProducts)

if !arraySortedEqual(oldApiProducts, newApiProducts) {
d.Set("api_products", newApiProducts)
Expand All @@ -202,14 +193,13 @@ func resourceCompanyAppRead(d *schema.ResourceData, meta interface{}) error {
d.Set("test","tester")
d.Set("name", CompanyAppData.Name)
d.Set("attributes", CompanyAppData.Attributes)
d.Set("credentials", CompanyAppData.Credentials)
d.Set("scopes", scopes)
d.Set("callback_url", CompanyAppData.CallbackUrl)
d.Set("app_id", CompanyAppData.AppId)
d.Set("company_name", CompanyAppData.CompanyName)
d.Set("status", CompanyAppData.Status)

log.Print("[DEBUG] resourceCompanyAppRead credentials: ", credentials)
d.Set("consumer_key", CompanyAppData.Credentials[len(CompanyAppData.Credentials)-1].ConsumerKey)
d.Set("consumer_secret", CompanyAppData.Credentials[len(CompanyAppData.Credentials)-1].ConsumerSecret)

return nil
}
Expand Down Expand Up @@ -259,21 +249,6 @@ func setCompanyAppData(d *schema.ResourceData) (apigee.CompanyApp, error) {
apiProducts = getStringList("api_products", d)
}

log.Print("[DEBUG] setCompanyAppData credentials: ", d.Get("credentials"))
var credentials []apigee.Credential
if d.Get("credentials") != nil {

credentialsMap := d.Get("credentials").([]interface{})

for elem := range credentialsMap {


log.Printf("[DEBUG] setCompanyAppData credentialsMap element: %v", elem)

//credentials = append(result, t)
}
}

scopes := []string{""}
if d.Get("scopes") != nil {
scopes = getStringList("scopes", d)
Expand All @@ -290,7 +265,6 @@ func setCompanyAppData(d *schema.ResourceData) (apigee.CompanyApp, error) {
Attributes: attributes,
ApiProducts: apiProducts,
Scopes: scopes,
Credentials: credentials,
CallbackUrl: d.Get("callback_url").(string),
}

Expand Down
Loading

0 comments on commit 8e6ea81

Please sign in to comment.