Exemplo n.º 1
0
        public AwsAmplifyConfig(AwsSettings awsSettings)
        {
            Auth = new auth
            {
                identityPoolId      = awsSettings["IdentityPoolId"].ToString(),
                region              = awsSettings["Region"].ToString(),
                identityPoolRegion  = awsSettings["Region"].ToString(),
                userPoolId          = awsSettings["UserPoolId"].ToString(),
                userPoolWebClientId = awsSettings["ClientId"].ToString(),
                mandatorySignIn     = false
            };

            API = new ApiSpec();
            var apiGateways = awsSettings["ApiGateways"] as Dictionary <string, AwsSettings.Api>;

            API.endpoints = new endpointSpec[apiGateways.Count];

            int i = 0;

            foreach (var kvp in apiGateways)
            {
                var api      = kvp.Value;
                var endpoint = new endpointSpec();
                endpoint.name = kvp.Key;
                var awshost = $"{api.Id}.{api.Service}.{awsSettings["Region"]}.{api.Host}";

                var uriBuilder = (api.Port == 443)
                    ? new UriBuilder(api.Scheme, awshost)
                    : new UriBuilder(api.Scheme, awshost, api.Port);

                var path = (!string.IsNullOrEmpty(api.Stage))
                    ? "/" + api.Stage
                        : "";

                endpoint.endpoint      = new Uri(uriBuilder.Uri, path).AbsoluteUri;
                endpoint.custom_header = $"#HeadersStatement-{api.SecurityLevel.ToString()}#";
                //switch(api.SecurityLevel)
                //{
                //    case AwsSettings.SecurityLevel.None:
                //        break;
                //    case AwsSettings.SecurityLevel.JWT:
                //        endpoint.custom_header = @"async () => { return { Authorization : `Bearer ${(await Auth.currentSession()).getIdToken.getJwtToken()}`}}";
                //        break;
                //    case AwsSettings.SecurityLevel.AwsSignatureVersion4:
                //        endpoint.custom_header = @"async () => { return { LzIdentity : `${(await Auth.currentSession()).getIdToken.getJwtToken()}`}}";
                //        break;
                //}

                API.endpoints[i++] = endpoint;
            }
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
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);
        }