Ejemplo n.º 1
0
        private static void ProcessYamlServerlessTemplateFunctionBased(LambdaConfigInfo configInfo, YamlMappingNode resources)
        {
            if (resources == null)
            {
                return;
            }

            foreach (var resource in resources.Children)
            {
                var resourceBody = (YamlMappingNode)resource.Value;

                var handler = resourceBody.Children.ContainsKey("handler")
                    ? ((YamlScalarNode)resourceBody.Children["handler"])?.Value
                    : null;

                if (handler == null)
                {
                    continue;
                }
                if (string.IsNullOrEmpty(handler))
                {
                    continue;
                }


                var functionInfo = new LambdaFunctionInfo
                {
                    Name    = resource.Key.ToString(),
                    Handler = handler
                };

                configInfo.FunctionInfos.Add(functionInfo);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Find the reflection objects for the code that will be executed for the Lambda function based on the
        /// Lambda function handler.
        /// </summary>
        /// <param name="functionInfo"></param>
        /// <returns></returns>
        public LambdaFunction LoadLambdaFunction(LambdaFunctionInfo functionInfo)
        {
            var function      = new LambdaFunction(functionInfo);
            var handlerTokens = functionInfo.Handler.Split("::");

            if (handlerTokens.Length != 3)
            {
                function.ErrorMessage = $"Invalid format for function handler string {functionInfo.Handler}. Format is <assembly>::<type-name>::<method>.";
                return(function);
            }

            // Using our custom Assembly resolver load the target Assembly.
            function.LambdaAssembly = this.Resolver.LoadAssembly(handlerTokens[0]);
            if (function.LambdaAssembly == null)
            {
                function.ErrorMessage = $"Failed to find assembly {handlerTokens[0]}";
                return(function);
            }

            function.LambdaType = function.LambdaAssembly.GetType(handlerTokens[1]);
            if (function.LambdaType == null)
            {
                function.ErrorMessage = $"Failed to find type {handlerTokens[1]}";
                return(function);
            }

            var methodInfos = function.LambdaType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
                              .Where(x => string.Equals(x.Name, handlerTokens[2])).ToArray();

            if (methodInfos.Length == 1)
            {
                function.LambdaMethod = methodInfos[0];
            }
            else
            {
                // TODO: Handle method overloads
                if (methodInfos.Length > 1)
                {
                    function.ErrorMessage = $"More then one method called {handlerTokens[2]} was found. This tool does not currently support method overloading.";
                }
                else
                {
                    function.ErrorMessage = $"Failed to find method {handlerTokens[2]}";
                }
                return(function);
            }

            // Search to see if a Lambda serializer is registered.
            var attribute = function.LambdaMethod.GetCustomAttribute(typeof(LambdaSerializerAttribute)) as LambdaSerializerAttribute ??
                            function.LambdaAssembly.GetCustomAttribute(typeof(LambdaSerializerAttribute)) as LambdaSerializerAttribute;


            if (attribute != null)
            {
                function.Serializer = Activator.CreateInstance(attribute.SerializerType) as ILambdaSerializer;
            }


            return(function);
        }
Ejemplo n.º 3
0
        private static void ProcessYamlServerlessTemplateResourcesBased(LambdaConfigInfo configInfo, YamlMappingNode resources)
        {
            if (resources == null)
            {
                return;
            }

            foreach (var resource in resources.Children)
            {
                var resourceBody = (YamlMappingNode)resource.Value;
                var type         = resourceBody.Children.ContainsKey("Type")
                    ? ((YamlScalarNode)resourceBody.Children["Type"])?.Value
                    : null;


                if (!string.Equals("AWS::Serverless::Function", type, StringComparison.Ordinal) &&
                    !string.Equals("AWS::Lambda::Function", type, StringComparison.Ordinal))
                {
                    continue;
                }

                var properties = resourceBody.Children.ContainsKey("Properties")
                    ? resourceBody.Children["Properties"] as YamlMappingNode
                    : null;
                if (properties == null)
                {
                    continue;
                }

                string handler = null;
                if (properties.Children.ContainsKey("Handler"))
                {
                    handler = ((YamlScalarNode)properties.Children["Handler"])?.Value;
                }

                if (string.IsNullOrEmpty(handler) && properties.Children.ContainsKey("ImageConfig"))
                {
                    var imageConfigNode = properties.Children["ImageConfig"] as YamlMappingNode;
                    if (imageConfigNode.Children.ContainsKey("Command"))
                    {
                        var imageCommandNode = imageConfigNode.Children["Command"] as YamlSequenceNode;
                        // Grab the first element assuming that is the function handler.
                        var en = imageCommandNode.GetEnumerator();
                        en.MoveNext();
                        handler = ((YamlScalarNode)en.Current)?.Value;
                    }
                }

                if (!string.IsNullOrEmpty(handler))
                {
                    var functionInfo = new LambdaFunctionInfo
                    {
                        Name    = resource.Key.ToString(),
                        Handler = handler
                    };

                    configInfo.FunctionInfos.Add(functionInfo);
                }
            }
        }
Ejemplo n.º 4
0
        private static void ProcessJsonServerlessTemplate(LambdaConfigInfo configInfo, string content)
        {
            var rootData = JsonDocument.Parse(content);

            JsonElement resourcesNode;

            if (!rootData.RootElement.TryGetProperty("Resources", out resourcesNode))
            {
                return;
            }

            foreach (var resourceProperty in resourcesNode.EnumerateObject())
            {
                var resource = resourceProperty.Value;

                JsonElement typeProperty;
                if (!resource.TryGetProperty("Type", out typeProperty))
                {
                    continue;
                }

                var type = typeProperty.GetString();

                JsonElement propertiesProperty;
                if (!resource.TryGetProperty("Properties", out propertiesProperty))
                {
                    continue;
                }


                if (!string.Equals("AWS::Serverless::Function", type, StringComparison.Ordinal) &&
                    !string.Equals("AWS::Lambda::Function", type, StringComparison.Ordinal))
                {
                    continue;
                }

                string handler = null;
                if (propertiesProperty.TryGetProperty("Handler", out var handlerProperty))
                {
                    handler = handlerProperty.GetString();
                }
                else if (propertiesProperty.TryGetProperty("ImageConfig", out var imageConfigProperty) &&
                         imageConfigProperty.TryGetProperty("Command", out var imageCommandProperty))
                {
                    handler = imageCommandProperty.GetString();
                }

                if (!string.IsNullOrEmpty(handler))
                {
                    var functionInfo = new LambdaFunctionInfo
                    {
                        Name    = resourceProperty.Name,
                        Handler = handler
                    };

                    configInfo.FunctionInfos.Add(functionInfo);
                }
            }
        }
Ejemplo n.º 5
0
        private static void ProcessYamlServerlessTemplateResourcesBased(LambdaConfigInfo configInfo, YamlMappingNode resources)
        {
            if (resources == null)
            {
                return;
            }

            foreach (var resource in resources.Children)
            {
                var resourceBody = (YamlMappingNode)resource.Value;
                var type         = resourceBody.Children.ContainsKey("Type")
                    ? ((YamlScalarNode)resourceBody.Children["Type"])?.Value
                    : null;


                if (!string.Equals("AWS::Serverless::Function", type, StringComparison.Ordinal) &&
                    !string.Equals("AWS::Lambda::Function", type, StringComparison.Ordinal))
                {
                    continue;
                }

                var properties = resourceBody.Children.ContainsKey("Properties")
                    ? resourceBody.Children["Properties"] as YamlMappingNode
                    : null;
                if (properties == null)
                {
                    continue;
                }

                string handler = null;
                if (properties.Children.ContainsKey("Handler"))
                {
                    handler = ((YamlScalarNode)properties.Children["Handler"])?.Value;
                }

                if (string.IsNullOrEmpty(handler))
                {
                    if (properties.Children.TryGetValue("ImageConfig", out var imageConfigNode) &&
                        imageConfigNode is YamlMappingNode && ((YamlMappingNode)imageConfigNode).Children.TryGetValue("Command", out var imageCommandNode))
                    {
                        handler = (imageCommandNode as YamlScalarNode)?.Value;
                    }
                }

                if (!string.IsNullOrEmpty(handler))
                {
                    var functionInfo = new LambdaFunctionInfo
                    {
                        Name    = resource.Key.ToString(),
                        Handler = handler
                    };

                    configInfo.FunctionInfos.Add(functionInfo);
                }
            }
        }
Ejemplo n.º 6
0
        public static LambdaConfigInfo LoadFromFile(string filePath)
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException($"Lambda config file {filePath} not found");
            }

            var rootData = JsonMapper.ToObject(File.ReadAllText(filePath)) as JsonData;

            var configInfo = new LambdaConfigInfo
            {
                AWSProfile    = rootData.ContainsKey("profile") ? rootData["profile"]?.ToString() : "default",
                AWSRegion     = rootData.ContainsKey("region") ? rootData["region"]?.ToString() : null,
                FunctionInfos = new List <LambdaFunctionInfo>()
            };

            if (string.IsNullOrEmpty(configInfo.AWSProfile))
            {
                configInfo.AWSProfile = "default";
            }


            var templateFileName = rootData.ContainsKey("template") ? rootData["template"]?.ToString() : null;
            var functionHandler  = rootData.ContainsKey("function-handler") ? rootData["function-handler"]?.ToString() : null;

            if (!string.IsNullOrEmpty(templateFileName))
            {
                var templateFullPath = Path.Combine(Path.GetDirectoryName(filePath), templateFileName);
                if (!File.Exists(templateFullPath))
                {
                    throw new FileNotFoundException($"Serverless template file {templateFullPath} not found");
                }
                ProcessServerlessTemplate(configInfo, templateFullPath);
            }
            else if (!string.IsNullOrEmpty(functionHandler))
            {
                var info = new LambdaFunctionInfo
                {
                    Handler = functionHandler
                };

                info.Name = rootData.ContainsKey("function-name") ? rootData["function-name"]?.ToString() : null;
                if (string.IsNullOrEmpty(info.Name))
                {
                    info.Name = functionHandler;
                }

                configInfo.FunctionInfos.Add(info);
            }

            return(configInfo);
        }
Ejemplo n.º 7
0
        public static LambdaConfigInfo LoadFromFile(LambdaConfigFile configFile)
        {
            var configInfo = new LambdaConfigInfo
            {
                AWSProfile    = !string.IsNullOrEmpty(configFile.Profile) ? configFile.Profile : "default",
                AWSRegion     = !string.IsNullOrEmpty(configFile.Region) ? configFile.Region : null,
                FunctionInfos = new List <LambdaFunctionInfo>()
            };

            if (string.IsNullOrEmpty(configInfo.AWSProfile))
            {
                configInfo.AWSProfile = "default";
            }


            var templateFileName = !string.IsNullOrEmpty(configFile.Template) ? configFile.Template : null;
            var functionHandler  = !string.IsNullOrEmpty(configFile.DetermineHandler()) ? configFile.DetermineHandler() : null;

            if (!string.IsNullOrEmpty(templateFileName))
            {
                var directory        = Directory.Exists(configFile.ConfigFileLocation) ? configFile.ConfigFileLocation : Path.GetDirectoryName(configFile.ConfigFileLocation);
                var templateFullPath = Path.Combine(directory, templateFileName);
                if (!File.Exists(templateFullPath))
                {
                    throw new FileNotFoundException($"Serverless template file {templateFullPath} not found");
                }
                ProcessServerlessTemplate(configInfo, templateFullPath);
            }
            else if (!string.IsNullOrEmpty(functionHandler))
            {
                var info = new LambdaFunctionInfo
                {
                    Handler = functionHandler
                };

                info.Name = !string.IsNullOrEmpty(configFile.FunctionName) ? configFile.FunctionName : null;
                if (string.IsNullOrEmpty(info.Name))
                {
                    info.Name = functionHandler;
                }

                configInfo.FunctionInfos.Add(info);
            }

            return(configInfo);
        }
Ejemplo n.º 8
0
        private static void ProcessJsonServerlessTemplate(LambdaConfigInfo configInfo, string content)
        {
            var rootData = JsonMapper.ToObject(content);

            var resourcesNode = rootData.ContainsKey("Resources") ? rootData["Resources"] : null as JsonData;

            if (resourcesNode == null)
            {
                return;
            }

            foreach (var key in resourcesNode.Keys)
            {
                var resource   = resourcesNode[key];
                var type       = resource.ContainsKey("Type") ? resource["Type"]?.ToString() : null;
                var properties = resource.ContainsKey("Properties") ? resource["Properties"] : null;

                if (properties == null)
                {
                    continue;
                }

                if (!string.Equals("AWS::Serverless::Function", type, StringComparison.Ordinal) &&
                    !string.Equals("AWS::Lambda::Function", type, StringComparison.Ordinal))
                {
                    continue;
                }

                var handler = properties.ContainsKey("Handler") ? properties["Handler"]?.ToString() : null;

                if (!string.IsNullOrEmpty(handler))
                {
                    var functionInfo = new LambdaFunctionInfo
                    {
                        Name    = key,
                        Handler = handler
                    };

                    configInfo.FunctionInfos.Add(functionInfo);
                }
            }
        }
Ejemplo n.º 9
0
 public LambdaFunction(LambdaFunctionInfo functionInfo)
 {
     this.FunctionInfo = functionInfo;
 }