-
-
Notifications
You must be signed in to change notification settings - Fork 1
Grant(or remove) permission to lambda function for invoke from CloudWatch Events #4
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
Changes from all commits
9baa37f
2bc637d
de72dd6
6056865
66d9cc9
9880afa
a825822
02a3781
f24b263
9cc3c3a
520954a
ffc55e8
c2d9832
636fda2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"strings" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/lambda" | ||
) | ||
|
||
func addPermissionToLambdaFromCloudWatchEvents(lc *lambda.Lambda, rules []Rule) error { | ||
for _, rule := range rules { | ||
for _, target := range rule.Targets { | ||
if !IsLambdaFunction(target.Arn) { | ||
continue | ||
} | ||
|
||
if result, err := isAlreadyAddPermission(lc, rule, target); err != nil { | ||
return err | ||
} else if result { | ||
// do nothing (already granted permission) | ||
continue | ||
} else { | ||
_, errL := lc.AddPermission(&lambda.AddPermissionInput{ | ||
Action: aws.String("lambda:InvokeFunction"), | ||
FunctionName: aws.String(LambdaFunctionNameFromArn(target.Arn)), | ||
Principal: aws.String("events.amazonaws.com"), | ||
SourceArn: rule.ActualRule.Arn, | ||
StatementId: aws.String(target.Id), | ||
}) | ||
|
||
if errL != nil { | ||
return errL | ||
} | ||
} | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func removePermissonFromLambda(lc *lambda.Lambda, rules []Rule) error { | ||
for _, rule := range rules { | ||
for _, target := range rule.Targets { | ||
if target.NeedDelete && IsLambdaFunction(*target.ActualTarget.Arn) { | ||
_, err := lc.RemovePermission(&lambda.RemovePermissionInput{ | ||
FunctionName: target.ActualTarget.Arn, | ||
StatementId: target.ActualTarget.Id, | ||
}) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func isAlreadyAddPermission(lc *lambda.Lambda, rule Rule, target Target) (bool, error) { | ||
var policy LambdaPolicy | ||
|
||
policyOutput, err := lc.GetPolicy(&lambda.GetPolicyInput{ | ||
FunctionName: &target.Arn, | ||
}) | ||
|
||
if err != nil { | ||
return false, err | ||
} | ||
|
||
errJ := json.Unmarshal([]byte(*policyOutput.Policy), &policy) | ||
if errJ != nil { | ||
return false, errJ | ||
} | ||
|
||
for _, statement := range *policy.Statement { | ||
if (statement.Resource == target.Arn && | ||
strings.HasSuffix(statement.Condition.ArnLike.AwsSourceArn, rule.Name) && | ||
statement.Effect == "Allow" && | ||
statement.Principal.Service == "events.amazonaws.com" && | ||
statement.Action == "lambda:InvokeFunction") || | ||
statement.StatementId == target.Id { | ||
return true, nil | ||
} | ||
} | ||
|
||
return false, nil | ||
} | ||
|
||
func IsLambdaFunction(arn string) bool { | ||
return strings.HasPrefix(arn, "arn:aws:lambda") | ||
} | ||
|
||
func LambdaFunctionNameFromArn(arn string) string { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exported function LambdaFunctionNameFromArn should have comment or be unexported |
||
return strings.Split(arn, ":")[6] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package main | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestIsLambdaFunction(t *testing.T) { | ||
lambdaArn := "arn:aws:lambda:ap-northeast-1:000000000000:function:lambda-function-name:3" | ||
if IsLambdaFunction(lambdaArn) == false { | ||
t.Errorf("%s is lambda function", lambdaArn) | ||
} | ||
|
||
ec2Arn := "arn:aws:ec2:us-east-1:123456789012:instance/*" | ||
if IsLambdaFunction(ec2Arn) == true { | ||
t.Errorf("%s is not lambda function", ec2Arn) | ||
} | ||
} | ||
|
||
func TestLambdaFunctionNameFromArn(t *testing.T) { | ||
lambdaArn := "arn:aws:lambda:ap-northeast-1:000000000000:function:lambda-function-name:3" | ||
if res := LambdaFunctionNameFromArn(lambdaArn); res != "lambda-function-name" { | ||
t.Errorf("should return 'lambda-function-name', but got %s", res) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,10 +4,12 @@ import ( | |
cwe "github.com/aws/aws-sdk-go/service/cloudwatchevents" | ||
) | ||
|
||
// struct for store unmarshalized configuration yaml | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type Rules should be of the form "Rules ..." (with optional leading article) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type Rules should be of the form "Rules ..." (with optional leading article) |
||
type Rules struct { | ||
Rules []Rule | ||
} | ||
|
||
// struct for expression CloudWatch Events Rule | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type Rule should be of the form "Rule ..." (with optional leading article) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type Rule should be of the form "Rule ..." (with optional leading article) |
||
type Rule struct { | ||
Description string `yaml:"description"` | ||
EventPattern string `yaml:"event_pattern"` | ||
|
@@ -21,6 +23,7 @@ type Rule struct { | |
NeedDelete bool | ||
} | ||
|
||
// struct for expression CloudWatch Events Target | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type Target should be of the form "Target ..." (with optional leading article) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type Target should be of the form "Target ..." (with optional leading article) |
||
type Target struct { | ||
Arn string `yaml:"arn"` | ||
Id string `yaml:"id"` | ||
|
@@ -30,3 +33,35 @@ type Target struct { | |
NeedUpdate bool | ||
NeedDelete bool | ||
} | ||
|
||
// struct for JSON that return from Lambda.GetPolicy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type LambdaPolicy should be of the form "LambdaPolicy ..." (with optional leading article) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type LambdaPolicy should be of the form "LambdaPolicy ..." (with optional leading article) |
||
type LambdaPolicy struct { | ||
Version string `json:"Version"` | ||
Id string `json:"Id"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. struct field Id should be ID There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. struct field Id should be ID |
||
Statement *[]PolicyStatement `json:"Statement"` | ||
} | ||
|
||
// part of the LambdaPolicy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type PolicyStatement should be of the form "PolicyStatement ..." (with optional leading article) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type PolicyStatement should be of the form "PolicyStatement ..." (with optional leading article) |
||
type PolicyStatement struct { | ||
Resource string `json:"Resource"` | ||
Condition *PolicyCondition `json:"Condition"` | ||
StatementId string `json:"Sid"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. struct field StatementId should be StatementID There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. struct field StatementId should be StatementID |
||
Effect string `json:"Effect"` | ||
Principal *PolicyPrincipal `json:"Principal"` | ||
Action string `json:"Action"` | ||
} | ||
|
||
// part of the LambdaPolicy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type PolicyCondition should be of the form "PolicyCondition ..." (with optional leading article) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type PolicyCondition should be of the form "PolicyCondition ..." (with optional leading article) |
||
type PolicyCondition struct { | ||
ArnLike *PolicyArnLike `json:"ArnLike"` | ||
} | ||
|
||
// part of the LambdaPolicy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type PolicyArnLike should be of the form "PolicyArnLike ..." (with optional leading article) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type PolicyArnLike should be of the form "PolicyArnLike ..." (with optional leading article) |
||
type PolicyArnLike struct { | ||
AwsSourceArn string `json:"AWS:SourceArn"` | ||
} | ||
|
||
// part of the LambdaPolicy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type PolicyPrincipal should be of the form "PolicyPrincipal ..." (with optional leading article) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on exported type PolicyPrincipal should be of the form "PolicyPrincipal ..." (with optional leading article) |
||
type PolicyPrincipal struct { | ||
Service string `json:"Service"` | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exported function IsLambdaFunction should have comment or be unexported