Skip to content

Commit

Permalink
Merge pull request #5239 from TimeIncOSS/f-aws-lambda-func-updates
Browse files Browse the repository at this point in the history
provider/aws: Add support for updating Lambda function
  • Loading branch information
radeksimko committed Mar 11, 2016
2 parents 065fb8a + 9f6b487 commit d8b3653
Show file tree
Hide file tree
Showing 5 changed files with 356 additions and 15 deletions.
113 changes: 98 additions & 15 deletions builtin/providers/aws/resource_aws_lambda_function.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package aws

import (
"crypto/sha256"
"fmt"
"io/ioutil"
"log"
Expand Down Expand Up @@ -58,18 +57,15 @@ func resourceAwsLambdaFunction() *schema.Resource {
"handler": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true, // TODO make this editable
},
"memory_size": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 128,
ForceNew: true, // TODO make this editable
},
"role": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true, // TODO make this editable
},
"runtime": &schema.Schema{
Type: schema.TypeString,
Expand All @@ -81,7 +77,6 @@ func resourceAwsLambdaFunction() *schema.Resource {
Type: schema.TypeInt,
Optional: true,
Default: 3,
ForceNew: true, // TODO make this editable
},
"vpc_config": &schema.Schema{
Type: schema.TypeList,
Expand Down Expand Up @@ -116,8 +111,8 @@ func resourceAwsLambdaFunction() *schema.Resource {
},
"source_code_hash": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
},
}
Expand All @@ -135,17 +130,12 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e

var functionCode *lambda.FunctionCode
if v, ok := d.GetOk("filename"); ok {
filename, err := homedir.Expand(v.(string))
if err != nil {
return err
}
zipfile, err := ioutil.ReadFile(filename)
file, err := loadFileContent(v.(string))
if err != nil {
return err
return fmt.Errorf("Unable to load %q: %s", v.(string), err)
}
d.Set("source_code_hash", sha256.Sum256(zipfile))
functionCode = &lambda.FunctionCode{
ZipFile: zipfile,
ZipFile: file,
}
} else {
s3Bucket, bucketOk := d.GetOk("s3_bucket")
Expand Down Expand Up @@ -202,6 +192,7 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e
err := resource.Retry(1*time.Minute, func() *resource.RetryError {
_, err := conn.CreateFunction(params)
if err != nil {
log.Printf("[ERROR] Received %q, retrying CreateFunction", err)
if awserr, ok := err.(awserr.Error); ok {
if awserr.Code() == "InvalidParameterValueException" {
log.Printf("[DEBUG] InvalidParameterValueException creating Lambda Function: %s", awserr)
Expand Down Expand Up @@ -256,6 +247,7 @@ func resourceAwsLambdaFunctionRead(d *schema.ResourceData, meta interface{}) err
if config := flattenLambdaVpcConfigResponse(function.VpcConfig); len(config) > 0 {
d.Set("vpc_config", config)
}
d.Set("source_code_hash", function.CodeSha256)

return nil
}
Expand Down Expand Up @@ -284,7 +276,98 @@ func resourceAwsLambdaFunctionDelete(d *schema.ResourceData, meta interface{}) e
// resourceAwsLambdaFunctionUpdate maps to:
// UpdateFunctionCode in the API / SDK
func resourceAwsLambdaFunctionUpdate(d *schema.ResourceData, meta interface{}) error {
return nil
conn := meta.(*AWSClient).lambdaconn

d.Partial(true)

codeReq := &lambda.UpdateFunctionCodeInput{
FunctionName: aws.String(d.Id()),
}

codeUpdate := false
if v, ok := d.GetOk("filename"); ok && d.HasChange("source_code_hash") {
file, err := loadFileContent(v.(string))
if err != nil {
return fmt.Errorf("Unable to load %q: %s", v.(string), err)
}
codeReq.ZipFile = file
codeUpdate = true
}
if d.HasChange("s3_bucket") || d.HasChange("s3_key") || d.HasChange("s3_object_version") {
codeReq.S3Bucket = aws.String(d.Get("s3_bucket").(string))
codeReq.S3Key = aws.String(d.Get("s3_key").(string))
codeReq.S3ObjectVersion = aws.String(d.Get("s3_object_version").(string))
codeUpdate = true
}

log.Printf("[DEBUG] Send Update Lambda Function Code request: %#v", codeReq)
if codeUpdate {
_, err := conn.UpdateFunctionCode(codeReq)
if err != nil {
return fmt.Errorf("Error modifying Lambda Function Code %s: %s", d.Id(), err)
}

d.SetPartial("filename")
d.SetPartial("source_code_hash")
d.SetPartial("s3_bucket")
d.SetPartial("s3_key")
d.SetPartial("s3_object_version")
}

configReq := &lambda.UpdateFunctionConfigurationInput{
FunctionName: aws.String(d.Id()),
}

configUpdate := false
if d.HasChange("description") {
configReq.Description = aws.String(d.Get("description").(string))
configUpdate = true
}
if d.HasChange("handler") {
configReq.Handler = aws.String(d.Get("handler").(string))
configUpdate = true
}
if d.HasChange("memory_size") {
configReq.MemorySize = aws.Int64(int64(d.Get("memory_size").(int)))
configUpdate = true
}
if d.HasChange("role") {
configReq.Role = aws.String(d.Get("role").(string))
configUpdate = true
}
if d.HasChange("timeout") {
configReq.Timeout = aws.Int64(int64(d.Get("timeout").(int)))
configUpdate = true
}

log.Printf("[DEBUG] Send Update Lambda Function Configuration request: %#v", configReq)
if configUpdate {
_, err := conn.UpdateFunctionConfiguration(configReq)
if err != nil {
return fmt.Errorf("Error modifying Lambda Function Configuration %s: %s", d.Id(), err)
}
d.SetPartial("description")
d.SetPartial("handler")
d.SetPartial("memory_size")
d.SetPartial("role")
d.SetPartial("timeout")
}
d.Partial(false)

return resourceAwsLambdaFunctionRead(d, meta)
}

// loadFileContent returns contents of a file in a given path
func loadFileContent(v string) ([]byte, error) {
filename, err := homedir.Expand(v)
if err != nil {
return nil, err
}
fileContent, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return fileContent, nil
}

func validateVPCConfig(v interface{}) (map[string]interface{}, error) {
Expand Down
Loading

0 comments on commit d8b3653

Please sign in to comment.