github.com/argoproj/argo-events@v1.9.1/sensors/triggers/aws-lambda/aws-lambda.go (about) 1 /* 2 Copyright 2020 BlackRock, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 package aws_lambda 17 18 import ( 19 "context" 20 "encoding/json" 21 "fmt" 22 23 "github.com/aws/aws-sdk-go/aws" 24 "github.com/aws/aws-sdk-go/service/lambda" 25 "go.uber.org/zap" 26 27 "github.com/argoproj/argo-events/common" 28 "github.com/argoproj/argo-events/common/logging" 29 commonaws "github.com/argoproj/argo-events/eventsources/common/aws" 30 apicommon "github.com/argoproj/argo-events/pkg/apis/common" 31 "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1" 32 "github.com/argoproj/argo-events/sensors/policy" 33 "github.com/argoproj/argo-events/sensors/triggers" 34 ) 35 36 // AWSLambdaTrigger refers to trigger that invokes AWS Lambda functions 37 type AWSLambdaTrigger struct { 38 // LambdaClient is AWS Lambda client 39 LambdaClient *lambda.Lambda 40 // Sensor object 41 Sensor *v1alpha1.Sensor 42 // Trigger definition 43 Trigger *v1alpha1.Trigger 44 // logger to log stuff 45 Logger *zap.SugaredLogger 46 } 47 48 // NewAWSLambdaTrigger returns a new AWS Lambda context 49 func NewAWSLambdaTrigger(lambdaClients common.StringKeyedMap[*lambda.Lambda], sensor *v1alpha1.Sensor, trigger *v1alpha1.Trigger, logger *zap.SugaredLogger) (*AWSLambdaTrigger, error) { 50 lambdatrigger := trigger.Template.AWSLambda 51 52 lambdaClient, ok := lambdaClients.Load(trigger.Template.Name) 53 if !ok { 54 awsSession, err := commonaws.CreateAWSSessionWithCredsInVolume(lambdatrigger.Region, lambdatrigger.RoleARN, lambdatrigger.AccessKey, lambdatrigger.SecretKey, nil) 55 if err != nil { 56 return nil, fmt.Errorf("failed to create a AWS session, %w", err) 57 } 58 lambdaClient = lambda.New(awsSession, &aws.Config{Region: &lambdatrigger.Region}) 59 lambdaClients.Store(trigger.Template.Name, lambdaClient) 60 } 61 62 return &AWSLambdaTrigger{ 63 LambdaClient: lambdaClient, 64 Sensor: sensor, 65 Trigger: trigger, 66 Logger: logger.With(logging.LabelTriggerType, apicommon.LambdaTrigger), 67 }, nil 68 } 69 70 // GetTriggerType returns the type of the trigger 71 func (t *AWSLambdaTrigger) GetTriggerType() apicommon.TriggerType { 72 return apicommon.LambdaTrigger 73 } 74 75 // FetchResource fetches the trigger resource 76 func (t *AWSLambdaTrigger) FetchResource(ctx context.Context) (interface{}, error) { 77 return t.Trigger.Template.AWSLambda, nil 78 } 79 80 // ApplyResourceParameters applies parameters to the trigger resource 81 func (t *AWSLambdaTrigger) ApplyResourceParameters(events map[string]*v1alpha1.Event, resource interface{}) (interface{}, error) { 82 resourceBytes, err := json.Marshal(resource) 83 if err != nil { 84 return nil, fmt.Errorf("failed to marshal the aws lamda trigger resource, %w", err) 85 } 86 parameters := t.Trigger.Template.AWSLambda.Parameters 87 if parameters != nil { 88 updatedResourceBytes, err := triggers.ApplyParams(resourceBytes, t.Trigger.Template.AWSLambda.Parameters, events) 89 if err != nil { 90 return nil, err 91 } 92 var ht *v1alpha1.AWSLambdaTrigger 93 if err := json.Unmarshal(updatedResourceBytes, &ht); err != nil { 94 return nil, fmt.Errorf("failed to unmarshal the updated aws lambda trigger resource after applying resource parameters, %w", err) 95 } 96 return ht, nil 97 } 98 return resource, nil 99 } 100 101 // Execute executes the trigger 102 func (t *AWSLambdaTrigger) Execute(ctx context.Context, events map[string]*v1alpha1.Event, resource interface{}) (interface{}, error) { 103 trigger, ok := resource.(*v1alpha1.AWSLambdaTrigger) 104 if !ok { 105 return nil, fmt.Errorf("failed to interpret the trigger resource") 106 } 107 108 if trigger.Payload == nil { 109 return nil, fmt.Errorf("payload parameters are not specified") 110 } 111 112 payload, err := triggers.ConstructPayload(events, trigger.Payload) 113 if err != nil { 114 return nil, err 115 } 116 117 response, err := t.LambdaClient.Invoke(&lambda.InvokeInput{ 118 FunctionName: &trigger.FunctionName, 119 Payload: payload, 120 InvocationType: trigger.InvocationType, 121 }) 122 if err != nil { 123 return nil, err 124 } 125 126 return response, nil 127 } 128 129 // ApplyPolicy applies the policy on the trigger execution response 130 func (t *AWSLambdaTrigger) ApplyPolicy(ctx context.Context, resource interface{}) error { 131 if t.Trigger.Policy == nil || t.Trigger.Policy.Status == nil || t.Trigger.Policy.Status.Allow == nil { 132 return nil 133 } 134 135 obj, ok := resource.(*lambda.InvokeOutput) 136 if !ok { 137 return fmt.Errorf("failed to interpret the trigger resource") 138 } 139 140 p := policy.NewStatusPolicy(int(*obj.StatusCode), t.Trigger.Policy.Status.GetAllow()) 141 return p.ApplyPolicy(ctx) 142 }