View Javadoc
1   /*
2    * Copyright (c) 2016 ingenieux Labs
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   */
17  
18  package br.com.ingenieux.mojo.lambda;
19  
20  import com.google.common.collect.Lists;
21  
22  import com.amazonaws.services.lambda.AWSLambdaClient;
23  import com.amazonaws.services.lambda.model.FunctionConfiguration;
24  import com.amazonaws.services.lambda.model.ListAliasesRequest;
25  import com.amazonaws.services.lambda.model.ListFunctionsRequest;
26  import com.amazonaws.services.lambda.model.ListFunctionsResult;
27  
28  import org.apache.maven.plugin.MojoExecutionException;
29  import org.apache.maven.plugins.annotations.Mojo;
30  import org.apache.maven.plugins.annotations.Parameter;
31  
32  import java.util.LinkedHashMap;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.Set;
36  import java.util.regex.Pattern;
37  import java.util.stream.Collectors;
38  
39  import br.com.ingenieux.mojo.aws.util.GlobUtil;
40  
41  import static org.apache.commons.lang.StringUtils.isNotEmpty;
42  
43  /**
44   * List Function Aliases
45   */
46  @Mojo(name = "list-aliases")
47  public class ListAliasesMojo extends AbstractLambdaMojo {
48    public static final Pattern PATTERN_ALIAS = Pattern.compile("(?!^[0-9]+$)([a-zA-Z0-9-_]+)");
49    public static final String PATTERN_ALIAS_ARN = "arn:aws:lambda:[a-z]{2}-[a-z]+-\\d{1}:\\d{12}:function:[a-zA-Z0-9-_]+:(\\$LATEST|[a-zA-Z0-9-_]+)";
50  
51    private AWSLambdaClient lambdaClient;
52  
53    /**
54     * Glob of Functions to Include (default: all)
55     */
56    @Parameter(property = "lambda.function.includes", defaultValue = "*")
57    List<String> includes;
58  
59    List<Pattern> globIncludes;
60  
61    @Override
62    protected void configure() {
63      super.configure();
64  
65      try {
66        configureInternal();
67      } catch (Exception exc) {
68        throw new RuntimeException(exc);
69      }
70    }
71  
72    private void configureInternal() throws MojoExecutionException {
73      lambdaClient = this.getService();
74  
75      globIncludes = Lists.transform(includes, GlobUtil::globify);
76    }
77  
78    @Override
79    protected Object executeInternal() throws Exception {
80      Map<String, Set<String>> aliasMap = fetchAliases();
81  
82      return aliasMap;
83    }
84  
85    private Map<String, Set<String>> fetchAliases() {
86      Map<String, Set<String>> aliases = new LinkedHashMap<String, Set<String>>();
87  
88      String marker = null;
89  
90      do {
91        final ListFunctionsResult listFunctionsResult = lambdaClient.listFunctions(new ListFunctionsRequest().withMarker(marker));
92  
93        listFunctionsResult
94            .getFunctions()
95            .stream()
96            .map(FunctionConfiguration::getFunctionName)
97            .filter(this::isItIncluded)
98            .forEach(
99                func -> {
100                 Set<String> aliasesSet =
101                     lambdaClient
102                         .listAliases(new ListAliasesRequest().withFunctionName(func))
103                         .getAliases()
104                         .stream()
105                         .map(x -> x.getAliasArn().replaceAll(PATTERN_ALIAS_ARN, "$1"))
106                         .collect(Collectors.toSet());
107 
108                 aliases.put(func, aliasesSet);
109               });
110 
111       marker = listFunctionsResult.getNextMarker();
112 
113     } while (isNotEmpty(marker));
114 
115     return aliases;
116   }
117 
118   public boolean isItIncluded(String functionArn) {
119     for (Pattern p : globIncludes) {
120       if (p.matcher(functionArn).matches()) {
121         return true;
122       }
123     }
124 
125     return false;
126   }
127 }