示例#1
0
        public static async Task <IEnumerable <StackResourceSummary> > GetStackResourcesAsync(this IAmazonCloudFormation cfnClient, string stackName)
        {
            var result  = new List <StackResourceSummary>();
            var request = new ListStackResourcesRequest {
                StackName = stackName
            };

            do
            {
                var attempts = 0;
again:
                try {
                    var response = await cfnClient.ListStackResourcesAsync(request);

                    result.AddRange(response.StackResourceSummaries);
                    request.NextToken = response.NextToken;
                } catch (AmazonCloudFormationException e) when(
                    (e.Message == "Rate exceeded") &&
                    (++attempts < 30)
                    )
                {
                    await Task.Delay(TimeSpan.FromSeconds(attempts));

                    goto again;
                }
            } while(request.NextToken != null);
            return(result);
        }
示例#2
0
        public override void Invoke(AWSCredentials creds, RegionEndpoint region, int maxItems)
        {
            AmazonCloudFormationConfig config = new AmazonCloudFormationConfig();

            config.RegionEndpoint = region;
            ConfigureClient(config);
            AmazonCloudFormationClient client = new AmazonCloudFormationClient(creds, config);

            ListStackResourcesResponse resp = new ListStackResourcesResponse();

            do
            {
                ListStackResourcesRequest req = new ListStackResourcesRequest
                {
                    NextToken = resp.NextToken
                };

                resp = client.ListStackResources(req);
                CheckError(resp.HttpStatusCode, "200");

                foreach (var obj in resp.StackResourceSummaries)
                {
                    AddObject(obj);
                }
            }while (!string.IsNullOrEmpty(resp.NextToken));
        }
示例#3
0
        internal ListStackResourcesResponse ListStackResources(ListStackResourcesRequest request)
        {
            var marshaller   = new ListStackResourcesRequestMarshaller();
            var unmarshaller = ListStackResourcesResponseUnmarshaller.Instance;

            return(Invoke <ListStackResourcesRequest, ListStackResourcesResponse>(request, marshaller, unmarshaller));
        }
        /// <summary>
        /// <para> Returns descriptions for all resources of the specified stack. </para> <para>For deleted stacks, ListStackResources returns resource
        /// information for up to 90 days after the stack has been deleted. </para>
        /// </summary>
        ///
        /// <param name="listStackResourcesRequest">Container for the necessary parameters to execute the ListStackResources service method on
        ///           AmazonCloudFormation.</param>
        ///
        /// <returns>The response from the ListStackResources service method, as returned by AmazonCloudFormation.</returns>
        ///
        public ListStackResourcesResponse ListStackResources(ListStackResourcesRequest listStackResourcesRequest)
        {
            IRequest <ListStackResourcesRequest> request  = new ListStackResourcesRequestMarshaller().Marshall(listStackResourcesRequest);
            ListStackResourcesResponse           response = Invoke <ListStackResourcesRequest, ListStackResourcesResponse> (request, this.signer, ListStackResourcesResponseUnmarshaller.GetInstance());

            return(response);
        }
示例#5
0
        /// <summary>
        /// Initiates the asynchronous execution of the ListStackResources operation.
        /// <seealso cref="Amazon.CloudFormation.IAmazonCloudFormation.ListStackResources"/>
        /// </summary>
        ///
        /// <param name="request">Container for the necessary parameters to execute the ListStackResources operation.</param>
        /// <param name="cancellationToken">
        ///     A cancellation token that can be used by other objects or threads to receive notice of cancellation.
        /// </param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public Task <ListStackResourcesResponse> ListStackResourcesAsync(ListStackResourcesRequest request, CancellationToken cancellationToken = default(CancellationToken))
        {
            var marshaller   = new ListStackResourcesRequestMarshaller();
            var unmarshaller = ListStackResourcesResponseUnmarshaller.GetInstance();

            return(Invoke <IRequest, ListStackResourcesRequest, ListStackResourcesResponse>(request, marshaller, unmarshaller, signer, cancellationToken));
        }
示例#6
0
        private void ProcessLiveStackResourcess(ListStackResourcesResponse liveStackResources, CFStack stack, AmazonEC2Client ec2Client, Dictionary <string, string> secGroupMap, string stackName, AmazonCloudFormationClient cfClient)
        {
            foreach (StackResourceSummary liveStackResource in liveStackResources.StackResourceSummaries)
            {
                switch (liveStackResource.ResourceType)
                {
                case "AWS::EC2::SecurityGroup":
                    AWSUtils.ProcessEC2SecurityGroupFromAWS(liveStackResource, stack, ec2Client, secGroupMap, stackName);
                    break;

                case "AWS::EC2::NetworkAcl":
                    AWSUtils.ProcessNetworkAclFromAWS(liveStackResource, stack, ec2Client, stackName);
                    break;

                default:
                    break;
                }
            }

            if (liveStackResources.NextToken != null)
            {
                ListStackResourcesRequest lr = new ListStackResourcesRequest();
                lr.StackName       = stackName;
                lr.NextToken       = liveStackResources.NextToken;
                liveStackResources = cfClient.ListStackResources(lr);
                ProcessLiveStackResourcess(liveStackResources, stack, ec2Client, secGroupMap, stackName, cfClient);
            }
        }
示例#7
0
        /// <summary>
        /// Initiates the asynchronous execution of the ListStackResources operation.
        /// </summary>
        ///
        /// <param name="request">Container for the necessary parameters to execute the ListStackResources operation.</param>
        /// <param name="cancellationToken">
        ///     A cancellation token that can be used by other objects or threads to receive notice of cancellation.
        /// </param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public Task <ListStackResourcesResponse> ListStackResourcesAsync(ListStackResourcesRequest request, System.Threading.CancellationToken cancellationToken = default(CancellationToken))
        {
            var marshaller   = new ListStackResourcesRequestMarshaller();
            var unmarshaller = ListStackResourcesResponseUnmarshaller.Instance;

            return(InvokeAsync <ListStackResourcesRequest, ListStackResourcesResponse>(request, marshaller,
                                                                                       unmarshaller, cancellationToken));
        }
示例#8
0
        /// <summary>
        /// <para>Returns descriptions of all resources of the specified stack.</para> <para>For deleted stacks, ListStackResources returns resource
        /// information for up to 90 days after the stack has been deleted.</para>
        /// </summary>
        ///
        /// <param name="request">Container for the necessary parameters to execute the ListStackResources service method on
        /// AmazonCloudFormation.</param>
        ///
        /// <returns>The response from the ListStackResources service method, as returned by AmazonCloudFormation.</returns>
        public ListStackResourcesResponse ListStackResources(ListStackResourcesRequest request)
        {
            var task = ListStackResourcesAsync(request);

            try
            {
                return(task.Result);
            }
            catch (AggregateException e)
            {
                ExceptionDispatchInfo.Capture(e.InnerException).Throw();
                return(null);
            }
        }
示例#9
0
        //private ListStackResourcesResponse ListStackResources(string stackName, AmazonCloudFormationClient cfClient, string nextToken = null)
        //{
        //    ListStackResourcesRequest lr = new ListStackResourcesRequest();
        //    lr.StackName = stackName;
        //    lr.NextToken = nextToken;
        //    ListStackResourcesResponse liveStackResources = cfClient.ListStackResources(lr);
        //    return liveStackResources;
        //}

        private void ProcessLiveStack(string stackName, AmazonCloudFormationClient cfClient, AmazonEC2Client ec2Client, RichTextBox rtb, CFStack stack)
        {
            Dictionary <string, string>   secGroupMap        = new Dictionary <string, string>();
            DescribeSecurityGroupsRequest secGroupRequestAll = new DescribeSecurityGroupsRequest();
            //Get all security group Id's and cf logicalId's (if any)
            DescribeSecurityGroupsResponse secGroupResponseAll = ec2Client.DescribeSecurityGroups(secGroupRequestAll);

            foreach (SecurityGroup sg in secGroupResponseAll.SecurityGroups)
            {
                string value = "none";
                foreach (Amazon.EC2.Model.Tag tag in sg.Tags)
                {
                    if (tag.Key.Contains("aws:cloudformation:logical-id"))
                    {
                        value = tag.Value;
                    }
                }
                secGroupMap.Add(sg.GroupId, value);
            }



            //Get Live Stack
            DescribeStacksRequest cfRequest = new DescribeStacksRequest();

            cfRequest.StackName = stackName;
            DescribeStacksResponse liveStack = cfClient.DescribeStacks(cfRequest);

            stack.Description = liveStack.Stacks[0].Description;

            //Get Stack Resouces
            //Need to use ListStackResourcesRequest to be able to get stacks with more than 100 resources
            ListStackResourcesRequest lr = new ListStackResourcesRequest();

            lr.StackName = stackName;
            ListStackResourcesResponse liveStackResources = cfClient.ListStackResources(lr);

            ProcessLiveStackResourcess(liveStackResources, stack, ec2Client, secGroupMap, stackName, cfClient);


            stack.Resources.Sort((a, b) => a.LogicalId.CompareTo(b.LogicalId));

            WriteOutput(stack, rtb, source1_CB.Text, templateOrStack1_TB.Text);
        }
        private async Task <string> GetStackResource(SnapStackRequest input, string stackName)
        {
            var cfClient = new AmazonCloudFormationClient(RegionEndpoint.EUWest1);


            //TODO: Paginate
            var request = new ListStackResourcesRequest
            {
                StackName = stackName
            };
            var json         = new JObject();
            var resourceList = await cfClient.ListStackResourcesAsync(request);

            foreach (var resource in resourceList.StackResourceSummaries)
            {
                json.Add($"{resource.ResourceType}_{resource.LogicalResourceId}", resource.PhysicalResourceId);
            }

            return(json.ToString(Formatting.Indented));
        }
示例#11
0
        public async Task ListLambdasAsync(string awsProfile, string awsRegion)
        {
            Console.WriteLine();

            // initialize AWS profile
            await InitializeAwsProfile(awsProfile, awsRegion : awsRegion);

            var cfnClient    = new AmazonCloudFormationClient(AWSConfigs.RegionEndpoint);
            var lambdaClient = new AmazonLambdaClient(AWSConfigs.RegionEndpoint);
            var logsClient   = new AmazonCloudWatchLogsClient(AWSConfigs.RegionEndpoint);

            // fetch all Lambda functions on account
            var globalFunctions = (await ListLambdasAsync())
                                  .ToDictionary(function => function.FunctionName, function => function);

            // fetch all stacks on account
            var stacks = await ListStacksAsync();

            Console.WriteLine($"Analyzing {stacks.Count():N0} CloudFormation stacks and {globalFunctions.Count():N0} Lambda functions");

            // fetch most recent CloudWatch log stream for each Lambda function
            var logStreamsTask = Task.Run(async() => (await Task.WhenAll(globalFunctions.Select(async kv => {
                try {
                    var response = await logsClient.DescribeLogStreamsAsync(new DescribeLogStreamsRequest {
                        Descending = true,
                        LogGroupName = $"/aws/lambda/{kv.Value.FunctionName}",
                        OrderBy = OrderBy.LastEventTime,
                        Limit = 1
                    });
                    return(Name: kv.Value.FunctionName, Streams: response.LogStreams.FirstOrDefault());
                } catch {
                    // log group doesn't exist
                    return(Name: kv.Value.FunctionName, Streams: null);
                }
            }))).ToDictionary(tuple => tuple.Name, tuple => tuple.Streams));

            // fetch all functions belonging to a CloudFormation stack
            var stacksWithFunctionsTask = Task.Run(async() => stacks.Zip(
                                                       await Task.WhenAll(stacks.Select(stack => ListStackFunctionsAsync(stack.StackId))),
                                                       (stack, stackFunctions) => (Stack: stack, Functions: stackFunctions)
                                                       ).ToList()
                                                   );

            // wait for both fetch operations to finish
            await Task.WhenAll(logStreamsTask, stacksWithFunctionsTask);

            var logStreams          = logStreamsTask.GetAwaiter().GetResult();
            var stacksWithFunctions = stacksWithFunctionsTask.GetAwaiter().GetResult();

            // remove all the functions that were discovered inside a stack from the orphaned list of functions
            foreach (var function in stacksWithFunctions.SelectMany(stackWithFunctions => stackWithFunctions.Functions))
            {
                globalFunctions.Remove(function.Configuration.FunctionName);
            }

            // compute the max width for the function name (use logical ID if it belongs to the stack)
            var maxFunctionNameWidth = stacksWithFunctions
                                       .SelectMany(stackWithFunctions => stackWithFunctions.Functions)
                                       .Select(function => function.Name.Length)
                                       .Union(globalFunctions.Values.Select(function => function.FunctionName.Length))
                                       .Append(0)
                                       .Max();

            // compute max width for the function runtime name
            var maxRuntimeWidth = stacksWithFunctions
                                  .SelectMany(stackWithFunctions => stackWithFunctions.Functions)
                                  .Select(stackFunction => stackFunction.Configuration.Runtime.ToString().Length)
                                  .Union(globalFunctions.Values.Select(function => function.Runtime.ToString().Length))
                                  .Append(0)
                                  .Max();

            // print Lambda functions belonging to stacks
            var showAsteriskExplanation = false;

            foreach (var stackWithFunctions in stacksWithFunctions
                     .Where(stackWithFunction => stackWithFunction.Functions.Any())
                     .OrderBy(stackWithFunction => stackWithFunction.Stack.StackName)
                     )
            {
                Console.WriteLine();

                // check if CloudFormation stack was deployed by LambdaSharp
                var moduleInfoOutput = stackWithFunctions.Stack.Outputs
                                       .FirstOrDefault(output => (output.OutputKey == "ModuleInfo") || (output.OutputKey == "Module"))
                                       ?.OutputValue;
                var lambdaSharpToolOutput = stackWithFunctions.Stack.Outputs
                                            .FirstOrDefault(output => output.OutputKey == "LambdaSharpTool")
                                            ?.OutputValue;

                // NOTE (2020-05-06, bjorg): pre-0.6, the module information was emitted as two output values
                var moduleNameOutput = stackWithFunctions.Stack.Outputs
                                       .FirstOrDefault(output => output.OutputKey == "ModuleName")
                                       ?.OutputValue;
                var moduleVersionOutput = stackWithFunctions.Stack.Outputs
                                          .FirstOrDefault(output => output.OutputKey == "ModuleVersion")
                                          ?.OutputValue;

                // show CloudFormation stack name and optionally LambdaSharp module information
                Console.Write($"{Settings.OutputColor}{stackWithFunctions.Stack.StackName}{Settings.ResetColor}");
                if (ModuleInfo.TryParse(moduleInfoOutput, out var moduleInfo))
                {
                    Console.Write($" ({Settings.InfoColor}{moduleInfo.FullName}:{moduleInfo.Version}{Settings.ResetColor}) [lash {lambdaSharpToolOutput ?? "pre-0.6.1"}]");
                }
                else if ((moduleNameOutput != null) && (moduleVersionOutput != null))
                {
                    Console.Write($" ({Settings.InfoColor}{moduleNameOutput}:{moduleVersionOutput}{Settings.ResetColor}) [lash pre-0.6]");
                }
                Console.WriteLine(":");

                foreach (var function in stackWithFunctions.Functions.OrderBy(function => function.Name))
                {
                    PrintFunction(function.Name, function.Configuration);
                }
            }

            // print orphan Lambda functions
            if (globalFunctions.Any())
            {
                Console.WriteLine();
                Console.WriteLine("ORPHANS:");
                foreach (var function in globalFunctions.Values.OrderBy(function => function.FunctionName))
                {
                    PrintFunction(function.FunctionName, function);
                }
            }

            // show optional (*) explanation if it was printed
            if (showAsteriskExplanation)
            {
                Console.WriteLine();
                Console.WriteLine("(*) Showing Lambda last-modified date, because last event timestamp in CloudWatch log stream is not available");
            }

            // local functions
            async Task <IEnumerable <FunctionConfiguration> > ListLambdasAsync()
            {
                var result  = new List <FunctionConfiguration>();
                var request = new ListFunctionsRequest();

                do
                {
                    var response = await lambdaClient.ListFunctionsAsync(request);

                    result.AddRange(response.Functions);
                    request.Marker = response.NextMarker;
                } while(request.Marker != null);
                return(result);
            }

            async Task <IEnumerable <Stack> > ListStacksAsync()
            {
                var result  = new List <Stack>();
                var request = new DescribeStacksRequest();

                do
                {
                    var response = await cfnClient.DescribeStacksAsync(request);

                    result.AddRange(response.Stacks);
                    request.NextToken = response.NextToken;
                } while(request.NextToken != null);
                return(result);
            }

            async Task <IEnumerable <(string Name, FunctionConfiguration Configuration)> > ListStackFunctionsAsync(string stackName)
            {
                var result  = new List <(string, FunctionConfiguration)>();
                var request = new ListStackResourcesRequest {
                    StackName = stackName
                };

                do
                {
                    var attempts = 0;
again:
                    try {
                        var response = await cfnClient.ListStackResourcesAsync(request);

                        result.AddRange(
                            response.StackResourceSummaries
                            .Where(resourceSummary => resourceSummary.ResourceType == "AWS::Lambda::Function")
                            .Select(summary => {
                            globalFunctions.TryGetValue(summary.PhysicalResourceId, out var configuration);
                            return(Name: summary.LogicalResourceId, Configuration: configuration);
                        })
                            .Where(tuple => tuple.Configuration != null)
                            );
                        request.NextToken = response.NextToken;
                    } catch (AmazonCloudFormationException e) when(
                        (e.Message == "Rate exceeded") &&
                        (++attempts < 30)
                        )
                    {
                        await Task.Delay(TimeSpan.FromSeconds(attempts));

                        goto again;
                    }
                } while(request.NextToken != null);
                return(result);
            }

            void PrintFunction(string name, FunctionConfiguration function)
            {
                Console.Write("    ");
                Console.Write(name);
                Console.Write("".PadRight(maxFunctionNameWidth - name.Length + 4));
                Console.Write(function.Runtime);
                Console.Write("".PadRight(maxRuntimeWidth - function.Runtime.ToString().Length + 4));
                if (
                    !logStreams.TryGetValue(function.FunctionName, out var logStream) ||
                    (logStream?.LastEventTimestamp == null)
                    )
                {
                    Console.Write(DateTimeOffset.Parse(function.LastModified).ToString("yyyy-MM-dd"));
                    Console.Write("(*)");
                    showAsteriskExplanation = true;
                }
                else
                {
                    Console.Write(logStream.LastEventTimestamp.ToString("yyyy-MM-dd"));
                }
                Console.WriteLine();
            }
        }
示例#12
0
        public static async Task <AwsSettings> GetAwsSettings(string profileName, string stackName)
        {
            if (string.IsNullOrEmpty(profileName))
            {
                throw new Exception($"Error: No ProfileName provided");
            }

            if (string.IsNullOrEmpty(stackName))
            {
                throw new Exception($"Error: No StackName provided");
            }

            var sharedCredentialsFile = new SharedCredentialsFile(); // AWS finds the shared credentials store for us
            CredentialProfile profile = null;

            if (!sharedCredentialsFile.TryGetProfile(profileName, out profile))
            {
                throw new Exception($"Error: Aws Profile \"{profileName}\" not found in shared credentials store.");
            }

            AWSCredentials creds = null;

            if (!AWSCredentialsFactory.TryGetAWSCredentials(profile, sharedCredentialsFile, out creds))
            {
                throw new Exception($"Error: Could not get AWS Credentials using specified profile \"{profileName}\".");
            }

            var awsSettings = new AwsSettings();

            awsSettings["StackName"] = stackName;

            // Get Original Template
            AmazonCloudFormationClient cfClient = null;
            GetTemplateRequest         getTemplateRequestOriginal = null;

            try
            {
                // Note the need to extract region from the profile!
                cfClient = new AmazonCloudFormationClient(creds, profile.Region);
                getTemplateRequestOriginal = new GetTemplateRequest()
                {
                    StackName     = stackName,
                    TemplateStage = Amazon.CloudFormation.TemplateStage.Original
                };
            }
            catch (Exception ex)
            {
                throw new Exception($"Could not create AmazonCloudFormationClient");
            }

            var templateReponse = cfClient.GetTemplateAsync(getTemplateRequestOriginal).GetAwaiter().GetResult();
            //var templateBodyIndex = templateReponse.StagesAvailable.IndexOf("Original");
            var templateBody = templateReponse.TemplateBody; // Original is in yaml form
            //var tmplYaml = new StringReader(new YamlDotNet.Serialization.SerializerBuilder().Build().Serialize(templateBody));
            var tmplYaml     = new StringReader(templateBody);
            var templYamlObj = new YamlDotNet.Serialization.DeserializerBuilder().Build().Deserialize(tmplYaml);

            templateBody = new YamlDotNet.Serialization.SerializerBuilder().JsonCompatible().Build().Serialize(templYamlObj);
            var jTemplateObjOriginal = JObject.Parse(templateBody);


            // Get Processed Template
            var getTemplateRequestProcessed = new GetTemplateRequest()
            {
                StackName     = stackName,
                TemplateStage = Amazon.CloudFormation.TemplateStage.Processed
            };

            templateReponse = cfClient.GetTemplateAsync(getTemplateRequestProcessed).GetAwaiter().GetResult();
            //var templateBodyIndex = templateReponse.StagesAvailable.IndexOf("Original");
            templateBody = templateReponse.TemplateBody;
            var jTemplateObjProcessed = JObject.Parse(templateBody);

            // Get Stack Resources - note: this call only returns the first 100 resources.
            // We are calling it to get the StackId
            var describeStackResourcesRequest = new DescribeStackResourcesRequest()
            {
                StackName = stackName
            };
            var describeStackResourcesResponse = await cfClient.DescribeStackResourcesAsync(describeStackResourcesRequest);

            if (describeStackResourcesResponse.StackResources.Count == 0)
            {
                throw new Exception($"Error: No resources found for specified stack.");
            }

            // Extract region from StackId ARN -- "arn:aws:cloudformation:us-east-1:..."
            var stackIdParts = describeStackResourcesResponse.StackResources[0].StackId.Split(':');


            var region = stackIdParts[3];

            awsSettings["Region"] = region;

            // Get all stack resources - paginated
            // The the ListStackResourcesResponse does not contain the StackId.
            string nextToken     = null;
            string apiName       = null;
            int    resourceCount = 0;
            var    apiGateways   = new Dictionary <string, AwsSettings.Api>();

            awsSettings["ApiGateways"] = apiGateways;
            do
            {
                var listStackResourcesRequest = new ListStackResourcesRequest()
                {
                    StackName = stackName, NextToken = nextToken
                };
                var listStackResourcesResponse = await cfClient.ListStackResourcesAsync(listStackResourcesRequest);

                nextToken = listStackResourcesResponse.NextToken;

                foreach (var resource in listStackResourcesResponse.StackResourceSummaries)
                {
                    resourceCount++;
                    switch (resource.ResourceType)
                    {
                    case "AWS::Cognito::UserPool":
                    case "AWS::Cognito::IdentityPool":
                    case "AWS::Cognito::UserPoolClient":
                        awsSettings[resource.LogicalResourceId] = resource.PhysicalResourceId;
                        break;

                    case "AWS::ApiGatewayV2::Api":
                        var httpApi = new AwsSettings.Api();
                        apiGateways.Add(resource.LogicalResourceId, httpApi);
                        httpApi.Id   = resource.PhysicalResourceId;
                        httpApi.Type = "HttpApi";
                        apiName      = resource.LogicalResourceId;
                        try
                        {
                            var HttpApiSecureAuthType = (string)jTemplateObjProcessed["Resources"][apiName]["Properties"]["Body"]["components"]["securitySchemes"]["OpenIdAuthorizer"]["type"];
                            if (HttpApiSecureAuthType.Equals("oauth2"))
                            {
                                httpApi.SecurityLevel = AwsSettings.SecurityLevel.JWT;
                            }
                            else
                            {
                                httpApi.SecurityLevel = AwsSettings.SecurityLevel.None;
                            }
                        }
                        catch
                        {
                            httpApi.SecurityLevel = AwsSettings.SecurityLevel.None;
                        }
                        httpApi.Stage = (string)jTemplateObjOriginal["Resources"][apiName]["Properties"]["StageName"];
                        break;

                    case "AWS::ApiGateway::RestApi":
                        var restApi = new AwsSettings.Api();
                        apiGateways.Add(resource.LogicalResourceId, restApi);
                        restApi.Id   = resource.PhysicalResourceId;
                        restApi.Type = "Api";
                        apiName      = resource.LogicalResourceId;
                        try
                        {
                            var apiAuthSecurityType = (string)jTemplateObjProcessed["Resources"][apiName]["Properties"]["Body"]["securityDefinitions"]["AWS_IAM"]["x-amazon-apigateway-authtype"];
                            if (apiAuthSecurityType.Equals("awsSigv4"))
                            {
                                restApi.SecurityLevel = AwsSettings.SecurityLevel.AwsSignatureVersion4;
                            }
                            else
                            {
                                restApi.SecurityLevel = AwsSettings.SecurityLevel.None;
                            }
                        }
                        catch
                        {
                            restApi.SecurityLevel = AwsSettings.SecurityLevel.None;
                        }
                        restApi.Stage = (string)jTemplateObjOriginal["Resources"][apiName]["Properties"]["StageName"];
                        break;
                    }
                }
            } while (nextToken != null);

            if (resourceCount == 0)
            {
                throw new Exception($"Error: No resources found for specified stack.");
            }

            return(awsSettings);
        }
示例#13
0
        public static async Task <string> GenerateMethodMapJsonAsync(
            string profileName,
            string stackName)
        {
            if (string.IsNullOrEmpty(profileName))
            {
                throw new Exception($"Error: No ProfileName provided");
            }

            if (string.IsNullOrEmpty(stackName))
            {
                throw new Exception($"Error: No StackName provided");
            }

            var sharedCredentialsFile = new SharedCredentialsFile(); // AWS finds the shared credentials store for us
            CredentialProfile profile = null;

            if (!sharedCredentialsFile.TryGetProfile(profileName, out profile))
            {
                throw new Exception($"Error: Aws Profile \"{profileName}\" not found in shared credentials store.");
            }

            AWSCredentials creds = null;

            if (!AWSCredentialsFactory.TryGetAWSCredentials(profile, sharedCredentialsFile, out creds))
            {
                throw new Exception($"Error: Could not get AWS Credentials using specified profile \"{profileName}\".");
            }

            var awsSettings = new AwsSettings();

            if (!awsSettings.ContainsKey("StackName"))
            {
                awsSettings.Add("StackName", stackName);
            }
            else
            {
                awsSettings["StackName"] = stackName;
            }

            // Get Original Template
            var cfClient = new AmazonCloudFormationClient(creds);
            var getTemplateRequestOriginal = new GetTemplateRequest()
            {
                StackName     = stackName,
                TemplateStage = Amazon.CloudFormation.TemplateStage.Original
            };

            var templateReponse = cfClient.GetTemplateAsync(getTemplateRequestOriginal).GetAwaiter().GetResult();
            //var templateBodyIndex = templateReponse.StagesAvailable.IndexOf("Original");
            var templateBody = templateReponse.TemplateBody; // Original is in yaml form
            //var tmplYaml = new StringReader(new YamlDotNet.Serialization.SerializerBuilder().Build().Serialize(templateBody));
            var tmplYaml     = new StringReader(templateBody);
            var templYamlObj = new YamlDotNet.Serialization.DeserializerBuilder().Build().Deserialize(tmplYaml);

            templateBody = new YamlDotNet.Serialization.SerializerBuilder().JsonCompatible().Build().Serialize(templYamlObj);
            var jTemplateObjOriginal = JObject.Parse(templateBody);

            // Get all Stack Resources
            string nextToken      = null;
            bool   foundResources = false;
            var    methodMap      = new Dictionary <string, string>();

            do
            {
                var listStackResourcesRequest = new ListStackResourcesRequest()
                {
                    StackName = stackName, NextToken = nextToken
                };
                var listStackResourcesResponse = await cfClient.ListStackResourcesAsync(listStackResourcesRequest);

                nextToken = listStackResourcesResponse.NextToken;

                foreach (var resource in listStackResourcesResponse.StackResourceSummaries)
                {
                    switch (resource.ResourceType)
                    {
                    case "AWS::Lambda::Function":
                        foundResources = true;
                        var funcName     = resource.LogicalResourceId;
                        var lambdaEvents = jTemplateObjOriginal["Resources"][funcName]["Properties"]["Events"].Children();
                        foreach (JToken le in lambdaEvents)
                        {
                            var jObject = new JObject(le);
                            var name    = jObject.First.First.Path;
                            var type    = jObject[name]["Type"].ToString();
                            var apiId   = string.Empty;

                            if (type.Equals("HttpApi"))
                            {
                                apiId = jObject[name]["Properties"]["ApiId"]["Ref"].ToString();
                            }

                            else if (type.Equals("Api"))
                            {
                                apiId = jObject[name]["Properties"]["RestApiId"]["Ref"].ToString();
                            }

                            if (!string.IsNullOrEmpty(apiId))
                            {
                                methodMap.Add(name + "Async", apiId);
                            }
                        }
                        break;
                    }
                }
            } while (nextToken != null);

            if (!foundResources)
            {
                throw new Exception($"Error: No Lambda resources found for specified stack.");
            }

            var result = $"{{\"MethodMap\": {Newtonsoft.Json.JsonConvert.SerializeObject(methodMap, Newtonsoft.Json.Formatting.Indented)}}}";

            return(result);
        }