Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provider/aws: API Gateway resources #4295

Merged
merged 10 commits into from
Mar 6, 2016
9 changes: 6 additions & 3 deletions builtin/providers/aws/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/apigateway"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/aws/aws-sdk-go/service/cloudtrail"
Expand Down Expand Up @@ -84,6 +85,7 @@ type AWSClient struct {
efsconn *efs.EFS
elbconn *elb.ELB
esconn *elasticsearch.ElasticsearchService
apigateway *apigateway.APIGateway
autoscalingconn *autoscaling.AutoScaling
s3conn *s3.S3
sqsconn *sqs.SQS
Expand All @@ -105,8 +107,6 @@ type AWSClient struct {

// Client configures and returns a fully initialized AWSClient
func (c *Config) Client() (interface{}, error) {
var client AWSClient

// Get the auth and region. This can fail if keys/regions were not
// specified and we're attempting to use the environment.
var errs []error
Expand All @@ -117,6 +117,7 @@ func (c *Config) Client() (interface{}, error) {
errs = append(errs, err)
}

var client AWSClient
if len(errs) == 0 {
// store AWS region in client struct, for region specific operations such as
// bucket storage in S3
Expand Down Expand Up @@ -234,6 +235,9 @@ func (c *Config) Client() (interface{}, error) {
log.Println("[INFO] Initializing ECR Connection")
client.ecrconn = ecr.New(sess)

log.Println("[INFO] Initializing API Gateway")
client.apigateway = apigateway.New(sess)

log.Println("[INFO] Initializing ECS Connection")
client.ecsconn = ecs.New(sess)

Expand Down Expand Up @@ -316,7 +320,6 @@ func (c *Config) ValidateCredentials(iamconn *iam.IAM) error {
_, err := iamconn.GetUser(nil)

if awsErr, ok := err.(awserr.Error); ok {

if awsErr.Code() == "AccessDenied" || awsErr.Code() == "ValidationError" {
log.Printf("[WARN] AccessDenied Error with iam.GetUser, assuming IAM profile")
// User may be an IAM instance profile, or otherwise IAM role without the
Expand Down
9 changes: 9 additions & 0 deletions builtin/providers/aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,15 @@ func Provider() terraform.ResourceProvider {
"aws_ami": resourceAwsAmi(),
"aws_ami_copy": resourceAwsAmiCopy(),
"aws_ami_from_instance": resourceAwsAmiFromInstance(),
"aws_api_gateway_rest_api": resourceAwsApiGatewayRestApi(),
"aws_api_gateway_api_key": resourceAwsApiGatewayApiKey(),
"aws_api_gateway_model": resourceAwsApiGatewayModel(),
"aws_api_gateway_resource": resourceAwsApiGatewayResource(),
"aws_api_gateway_method": resourceAwsApiGatewayMethod(),
"aws_api_gateway_method_response": resourceAwsApiGatewayMethodResponse(),
"aws_api_gateway_integration": resourceAwsApiGatewayIntegration(),
"aws_api_gateway_integration_response": resourceAwsApiGatewayIntegrationResponse(),
"aws_api_gateway_deployment": resourceAwsApiGatewayDeployment(),
"aws_app_cookie_stickiness_policy": resourceAwsAppCookieStickinessPolicy(),
"aws_autoscaling_group": resourceAwsAutoscalingGroup(),
"aws_autoscaling_notification": resourceAwsAutoscalingNotification(),
Expand Down
166 changes: 166 additions & 0 deletions builtin/providers/aws/resource_aws_api_gateway_api_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package aws

import (
"fmt"
"log"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/apigateway"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsApiGatewayApiKey() *schema.Resource {
return &schema.Resource{
Create: resourceAwsApiGatewayApiKeyCreate,
Read: resourceAwsApiGatewayApiKeyRead,
Update: resourceAwsApiGatewayApiKeyUpdate,
Delete: resourceAwsApiGatewayApiKeyDelete,

Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"description": &schema.Schema{
Type: schema.TypeString,
Required: true,
},

"enabled": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: true,
},

"stage_key": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"rest_api_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
},

"stage_name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
},
},
},
},
}
}

func resourceAwsApiGatewayApiKeyCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway
log.Printf("[DEBUG] Creating API Gateway API Key")

apiKey, err := conn.CreateApiKey(&apigateway.CreateApiKeyInput{
Name: aws.String(d.Get("name").(string)),
Description: aws.String(d.Get("description").(string)),
Enabled: aws.Bool(d.Get("enabled").(bool)),
StageKeys: expandApiGatewayStageKeys(d),
})
if err != nil {
return fmt.Errorf("Error creating API Gateway: %s", err)
}

d.SetId(*apiKey.Id)

return resourceAwsApiGatewayApiKeyRead(d, meta)
}

func resourceAwsApiGatewayApiKeyRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway
log.Printf("[DEBUG] Reading API Gateway API Key: %s", d.Id())

apiKey, err := conn.GetApiKey(&apigateway.GetApiKeyInput{
ApiKey: aws.String(d.Id()),
})
if err != nil {
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NotFoundException" {
d.SetId("")
return nil
}

return err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add guarding against deletion outside of Terraform here, like you did nicely for many other resources.

}

d.Set("name", apiKey.Name)
d.Set("description", apiKey.Description)
d.Set("enabled", apiKey.Enabled)

return nil
}

func resourceAwsApiGatewayApiKeyUpdateOperations(d *schema.ResourceData) []*apigateway.PatchOperation {
operations := make([]*apigateway.PatchOperation, 0)
if d.HasChange("enabled") {
isEnabled := "false"
if d.Get("enabled").(bool) {
isEnabled = "true"
}
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String("replace"),
Path: aws.String("/enabled"),
Value: aws.String(isEnabled),
})
}

if d.HasChange("description") {
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String("replace"),
Path: aws.String("/description"),
Value: aws.String(d.Get("description").(string)),
})
}

if d.HasChange("stage_key") {
operations = append(operations, expandApiGatewayStageKeyOperations(d)...)
}
return operations
}

func resourceAwsApiGatewayApiKeyUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway

log.Printf("[DEBUG] Updating API Gateway API Key: %s", d.Id())

_, err := conn.UpdateApiKey(&apigateway.UpdateApiKeyInput{
ApiKey: aws.String(d.Id()),
PatchOperations: resourceAwsApiGatewayApiKeyUpdateOperations(d),
})
if err != nil {
return err
}

return resourceAwsApiGatewayApiKeyRead(d, meta)
}

func resourceAwsApiGatewayApiKeyDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway
log.Printf("[DEBUG] Deleting API Gateway API Key: %s", d.Id())

return resource.Retry(5*time.Minute, func() error {
_, err := conn.DeleteApiKey(&apigateway.DeleteApiKeyInput{
ApiKey: aws.String(d.Id()),
})

if err == nil {
return nil
}

if apigatewayErr, ok := err.(awserr.Error); ok && apigatewayErr.Code() == "NotFoundException" {
return nil
}

return resource.RetryError{Err: err}
})
}
Loading