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; } }
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); }
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); }