@@ -2,6 +2,7 @@ package ecrm
22
33import (
44 "context"
5+ "fmt"
56 "log"
67 "math"
78 "sort"
@@ -33,6 +34,10 @@ func (s *Scanner) scanLambdaFunctions(ctx context.Context, lcs []*LambdaConfig)
3334 continue
3435 }
3536 log .Printf ("[debug] Checking Lambda function %s latest %d versions" , name , keepCount )
37+ aliases , err := s .getLambdaAliases (ctx , name )
38+ if err != nil {
39+ return fmt .Errorf ("failed to get lambda aliases: %w" , err )
40+ }
3641 p := lambda .NewListVersionsByFunctionPaginator (
3742 s .lambda ,
3843 & lambda.ListVersionsByFunctionInput {
@@ -51,9 +56,7 @@ func (s *Scanner) scanLambdaFunctions(ctx context.Context, lcs []*LambdaConfig)
5156 sort .SliceStable (versions , func (i , j int ) bool {
5257 return lambdaVersionInt64 (* versions [j ].Version ) < lambdaVersionInt64 (* versions [i ].Version )
5358 })
54- if len (versions ) > int (keepCount ) {
55- versions = versions [:int (keepCount )]
56- }
59+ var kept int64
5760 for _ , v := range versions {
5861 log .Println ("[debug] Getting Lambda function " , * v .FunctionArn )
5962 f , err := s .lambda .GetFunction (ctx , & lambda.GetFunctionInput {
@@ -67,20 +70,61 @@ func (s *Scanner) scanLambdaFunctions(ctx context.Context, lcs []*LambdaConfig)
6770 continue
6871 }
6972 log .Println ("[debug] ImageUri" , u )
73+ if a , ok := aliases [* v .Version ]; ok { // check if the version is aliased
74+ if s .Images .Add (u , aws .ToString (v .FunctionArn )) {
75+ log .Printf ("[info] %s is in use by Lambda function %s:%s (alias=%v)" , u .String (), * v .FunctionName , * v .Version , a )
76+ }
77+ continue
78+ }
79+ if kept >= keepCount {
80+ continue
81+ }
7082 if s .Images .Add (u , aws .ToString (v .FunctionArn )) {
7183 log .Printf ("[info] %s is in use by Lambda function %s:%s" , u .String (), * v .FunctionName , * v .Version )
84+ kept ++
7285 }
7386 }
7487 }
7588 return nil
7689}
7790
91+ func (s * Scanner ) getLambdaAliases (ctx context.Context , name string ) (map [string ][]string , error ) {
92+ aliases := make (map [string ][]string )
93+ var nextAliasMarker * string
94+ for {
95+ res , err := s .lambda .ListAliases (ctx , & lambda.ListAliasesInput {
96+ FunctionName : & name ,
97+ Marker : nextAliasMarker ,
98+ })
99+ if err != nil {
100+ return nil , fmt .Errorf ("failed to list aliases: %w" , err )
101+ }
102+ for _ , alias := range res .Aliases {
103+ aliases [* alias .FunctionVersion ] = append (aliases [* alias .FunctionVersion ], * alias .Name )
104+ if alias .RoutingConfig == nil || alias .RoutingConfig .AdditionalVersionWeights == nil {
105+ continue
106+ }
107+ for v := range alias .RoutingConfig .AdditionalVersionWeights {
108+ aliases [v ] = append (aliases [v ], * alias .Name )
109+ }
110+ }
111+ if nextAliasMarker = res .NextMarker ; nextAliasMarker == nil {
112+ break
113+ }
114+ }
115+ return aliases , nil
116+ }
117+
78118func lambdaVersionInt64 (v string ) int64 {
79119 var vi int64
80120 if v == "$LATEST" {
81121 vi = math .MaxInt64
82122 } else {
83- vi , _ = strconv .ParseInt (v , 10 , 64 )
123+ var err error
124+ vi , err = strconv .ParseInt (v , 10 , 64 )
125+ if err != nil {
126+ panic (fmt .Sprintf ("invalid version number:%s %s" , v , err .Error ()))
127+ }
84128 }
85129 return vi
86130}
0 commit comments