Skip to content

Commit

Permalink
feat: Add DynamoDB, S3, SQS and SNS type hints
Browse files Browse the repository at this point in the history
  • Loading branch information
normj committed Oct 22, 2021
1 parent f041b5f commit f696c3b
Show file tree
Hide file tree
Showing 12 changed files with 489 additions and 1 deletion.
52 changes: 52 additions & 0 deletions src/AWS.Deploy.CLI/Commands/TypeHints/DynamoDBTableCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AWS.Deploy.Common;
using AWS.Deploy.Common.Recipes;
using AWS.Deploy.Common.TypeHintData;
using AWS.Deploy.Orchestration.Data;

namespace AWS.Deploy.CLI.Commands.TypeHints
{
public class DynamoDBTableCommand : ITypeHintCommand
{
private readonly IAWSResourceQueryer _awsResourceQueryer;
private readonly IConsoleUtilities _consoleUtilities;

public DynamoDBTableCommand(IAWSResourceQueryer awsResourceQueryer, IConsoleUtilities consoleUtilities)
{
_awsResourceQueryer = awsResourceQueryer;
_consoleUtilities = consoleUtilities;
}

private async Task<List<string>> GetData()
{
return await _awsResourceQueryer.ListOfDyanmoDBTables();
}

public async Task<List<TypeHintResource>?> GetResources(Recommendation recommendation, OptionSettingItem optionSetting)
{
var tables = await GetData();
return tables.Select(tableName => new TypeHintResource(tableName, tableName)).ToList();
}

public async Task<object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
{
const string NO_VALUE = "*** Do not select table ***";
var currentValue = recommendation.GetOptionSettingValue(optionSetting);
var tables = await GetData();

tables.Add(NO_VALUE);
var userResponse = _consoleUtilities.AskUserToChoose(
values: tables,
title: "Select a DynamoDB table:",
defaultValue: currentValue.ToString() ?? "");

return userResponse == null || string.Equals(NO_VALUE, userResponse, StringComparison.InvariantCultureIgnoreCase) ? string.Empty : userResponse;
}
}
}
53 changes: 53 additions & 0 deletions src/AWS.Deploy.CLI/Commands/TypeHints/S3BucketNameCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AWS.Deploy.Common;
using AWS.Deploy.Common.Recipes;
using AWS.Deploy.Common.TypeHintData;
using AWS.Deploy.Orchestration.Data;
using Amazon.S3.Model;

namespace AWS.Deploy.CLI.Commands.TypeHints
{
public class S3BucketNameCommand : ITypeHintCommand
{
private readonly IAWSResourceQueryer _awsResourceQueryer;
private readonly IConsoleUtilities _consoleUtilities;

public S3BucketNameCommand(IAWSResourceQueryer awsResourceQueryer, IConsoleUtilities consoleUtilities)
{
_awsResourceQueryer = awsResourceQueryer;
_consoleUtilities = consoleUtilities;
}

private async Task<List<S3Bucket>> GetData()
{
return await _awsResourceQueryer.ListOfS3Buckets();
}

public async Task<List<TypeHintResource>?> GetResources(Recommendation recommendation, OptionSettingItem optionSetting)
{
var buckets = await GetData();
return buckets.Select(bucket => new TypeHintResource(bucket.BucketName, bucket.BucketName)).ToList();
}

public async Task<object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
{
const string NO_VALUE = "*** Do not select bucket ***";
var currentValue = recommendation.GetOptionSettingValue(optionSetting);
var buckets = (await GetData()).Select(bucket => bucket.BucketName).ToList();

buckets.Add(NO_VALUE);
var userResponse = _consoleUtilities.AskUserToChoose(
values: buckets,
title: "Select a S3 bucket:",
defaultValue: currentValue.ToString() ?? "");

return userResponse == null || string.Equals(NO_VALUE, userResponse, StringComparison.InvariantCultureIgnoreCase) ? string.Empty : userResponse;
}
}
}
56 changes: 56 additions & 0 deletions src/AWS.Deploy.CLI/Commands/TypeHints/SNSTopicArnsCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AWS.Deploy.Common;
using AWS.Deploy.Orchestration.Data;
using AWS.Deploy.Common.Recipes;
using AWS.Deploy.Common.TypeHintData;

namespace AWS.Deploy.CLI.Commands.TypeHints
{
public class SNSTopicArnsCommand : ITypeHintCommand
{
private readonly IAWSResourceQueryer _awsResourceQueryer;
private readonly IConsoleUtilities _consoleUtilities;

public SNSTopicArnsCommand(IAWSResourceQueryer awsResourceQueryer, IConsoleUtilities consoleUtilities)
{
_awsResourceQueryer = awsResourceQueryer;
_consoleUtilities = consoleUtilities;
}

public async Task<List<TypeHintResource>?> GetResources(Recommendation recommendation, OptionSettingItem optionSetting)
{
var topicArns = await _awsResourceQueryer.ListOfSNSTopicArns();
return topicArns.Select(topicArn => new TypeHintResource(topicArn, topicArn.Substring(topicArn.LastIndexOf(':') + 1))).ToList();
}

public async Task<object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
{
const string NO_VALUE = "*** Do not select topic ***";
var currentValue = recommendation.GetOptionSettingValue(optionSetting);
var currentValueStr = currentValue.ToString() ?? string.Empty;
var topicArns = await GetResources(recommendation, optionSetting);

var topicNames = topicArns.Select(queue => queue.DisplayName).ToList();
var currentName = string.Empty;
if (currentValue.ToString()?.LastIndexOf(':') != -1)
{
currentName = currentValueStr.Substring(currentValueStr.LastIndexOf(':') + 1);
}

topicNames.Add(NO_VALUE);
var userResponse = _consoleUtilities.AskUserToChoose(
values: topicNames,
title: "Select a SNS topic:",
defaultValue: currentName);

var selectedTopicArn = topicArns.FirstOrDefault(x => string.Equals(x.DisplayName, userResponse, StringComparison.OrdinalIgnoreCase));
return selectedTopicArn?.SystemName ?? string.Empty;
}
}
}
56 changes: 56 additions & 0 deletions src/AWS.Deploy.CLI/Commands/TypeHints/SQSQueueUrlCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AWS.Deploy.Common;
using AWS.Deploy.Common.Recipes;
using AWS.Deploy.Common.TypeHintData;
using AWS.Deploy.Orchestration.Data;

namespace AWS.Deploy.CLI.Commands.TypeHints
{
public class SQSQueueUrlCommand : ITypeHintCommand
{
private readonly IAWSResourceQueryer _awsResourceQueryer;
private readonly IConsoleUtilities _consoleUtilities;

public SQSQueueUrlCommand(IAWSResourceQueryer awsResourceQueryer, IConsoleUtilities consoleUtilities)
{
_awsResourceQueryer = awsResourceQueryer;
_consoleUtilities = consoleUtilities;
}

public async Task<List<TypeHintResource>?> GetResources(Recommendation recommendation, OptionSettingItem optionSetting)
{
var queueUrls = await _awsResourceQueryer.ListOfSQSQueuesUrls();
return queueUrls.Select(queueUrl => new TypeHintResource(queueUrl, queueUrl.Substring(queueUrl.LastIndexOf('/') + 1))).ToList();
}

public async Task<object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
{
const string NO_VALUE = "*** Do not select queue ***";
var currentValue = recommendation.GetOptionSettingValue(optionSetting);
var currentValueStr = currentValue.ToString() ?? string.Empty;
var queueUrls = await GetResources(recommendation, optionSetting);

var queueNames = queueUrls.Select(queue => queue.DisplayName).ToList();
var currentName = string.Empty;
if (currentValue.ToString()?.LastIndexOf('/') != -1)
{
currentName = currentValueStr.Substring(currentValueStr.LastIndexOf('/') + 1);
}

queueNames.Add(NO_VALUE);
var userResponse = _consoleUtilities.AskUserToChoose(
values: queueNames,
title: "Select a SQS queue:",
defaultValue: currentName);

var selectedQueueUrl = queueUrls.FirstOrDefault(x => string.Equals(x.DisplayName, userResponse, StringComparison.OrdinalIgnoreCase));
return selectedQueueUrl?.SystemName ?? string.Empty;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ public TypeHintCommandFactory(IToolInteractiveService toolInteractiveService, IA
{ OptionSettingTypeHint.DockerBuildArgs, new DockerBuildArgsCommand(consoleUtilities) },
{ OptionSettingTypeHint.ECSCluster, new ECSClusterCommand(awsResourceQueryer, consoleUtilities) },
{ OptionSettingTypeHint.ExistingApplicationLoadBalancer, new ExistingApplicationLoadBalancerCommand(awsResourceQueryer, consoleUtilities) },
{ OptionSettingTypeHint.DynamoDBTableName, new DynamoDBTableCommand(awsResourceQueryer, consoleUtilities) },
{ OptionSettingTypeHint.SQSQueueUrl, new SQSQueueUrlCommand(awsResourceQueryer, consoleUtilities) },
{ OptionSettingTypeHint.SNSTopicArn, new SNSTopicArnsCommand(awsResourceQueryer, consoleUtilities) },
{ OptionSettingTypeHint.S3BucketName, new S3BucketNameCommand(awsResourceQueryer, consoleUtilities) },
};
}

Expand Down
6 changes: 5 additions & 1 deletion src/AWS.Deploy.Common/Recipes/OptionSettingTypeHint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ public enum OptionSettingTypeHint
DotnetPublishAdditionalBuildArguments,
DockerExecutionDirectory,
DockerBuildArgs,
AppRunnerService
AppRunnerService,
DynamoDBTableName,
SQSQueueUrl,
SNSTopicArn,
S3BucketName
};
}
3 changes: 3 additions & 0 deletions src/AWS.Deploy.Orchestration/AWS.Deploy.Orchestration.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.7.0.83" />
<PackageReference Include="AWSSDK.SQS" Version="3.7.1.25" />
<PackageReference Include="AWSSDK.SimpleNotificationService" Version="3.7.2.53" />
<PackageReference Include="AWSSDK.CloudWatchEvents" Version="3.7.3.14" />
<PackageReference Include="AWSSDK.CloudFront" Version="3.7.3.10" />
<PackageReference Include="AWSSDK.EC2" Version="3.7.19.1" />
Expand Down
63 changes: 63 additions & 0 deletions src/AWS.Deploy.Orchestration/Data/AWSResourceQueryer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
using Amazon.CloudFront.Model;
using Amazon.CloudWatchEvents;
using Amazon.CloudWatchEvents.Model;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.EC2;
using Amazon.EC2.Model;
using Amazon.ECR;
Expand All @@ -27,6 +29,10 @@
using Amazon.S3;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;
using Amazon.SimpleNotificationService;
using Amazon.SimpleNotificationService.Model;
using Amazon.SQS;
using Amazon.SQS.Model;
using AWS.Deploy.Common;

namespace AWS.Deploy.Orchestration.Data
Expand Down Expand Up @@ -57,6 +63,10 @@ public interface IAWSResourceQueryer
Task<GetCallerIdentityResponse> GetCallerIdentity();
Task<List<Amazon.ElasticLoadBalancingV2.Model.LoadBalancer>> ListOfLoadBalancers(LoadBalancerTypeEnum loadBalancerType);
Task<Distribution> GetCloudFrontDistribution(string distributionId);
Task<List<string>> ListOfDyanmoDBTables();
Task<List<string>> ListOfSQSQueuesUrls();
Task<List<string>> ListOfSNSTopicArns();
Task<List<Amazon.S3.Model.S3Bucket>> ListOfS3Buckets();
}

public class AWSResourceQueryer : IAWSResourceQueryer
Expand Down Expand Up @@ -430,5 +440,58 @@ public async Task<Distribution> GetCloudFrontDistribution(string distributionId)

return response.Distribution;
}

public async Task<List<string>> ListOfDyanmoDBTables()
{
var client = _awsClientFactory.GetAWSClient<IAmazonDynamoDB>();

var tables = new List<string>();

await foreach(var table in client.Paginators.ListTables(new ListTablesRequest()).TableNames)
{
tables.Add(table);
}

return tables;
}

public async Task<List<string>> ListOfSQSQueuesUrls()
{
var client = _awsClientFactory.GetAWSClient<IAmazonSQS>();

var queueUrls = new List<string>();
await foreach(var queueUrl in client.Paginators.ListQueues(new ListQueuesRequest()).QueueUrls)
{
queueUrls.Add(queueUrl);
}

return queueUrls;
}

public async Task<List<string>> ListOfSNSTopicArns()
{
var client = _awsClientFactory.GetAWSClient<IAmazonSimpleNotificationService>();

var arns = new List<string>();
await foreach (var topic in client.Paginators.ListTopics(new ListTopicsRequest()).Topics)
{
arns.Add(topic.TopicArn);
}

return arns;
}

public async Task<List<Amazon.S3.Model.S3Bucket>> ListOfS3Buckets()
{
var client = _awsClientFactory.GetAWSClient<IAmazonS3>();

var buckets = new List<Amazon.S3.Model.S3Bucket>();
foreach (var bucket in (await client.ListBucketsAsync()).Buckets)
{
buckets.Add(bucket);
}

return buckets;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,9 @@ public Task<PlatformSummary> GetLatestElasticBeanstalkPlatformArn()
public Task<Amazon.AppRunner.Model.Service> DescribeAppRunnerService(string serviceArn) => throw new NotImplementedException();
public Task<List<Amazon.ElasticLoadBalancingV2.Model.LoadBalancer>> ListOfLoadBalancers(LoadBalancerTypeEnum loadBalancerType) => throw new NotImplementedException();
public Task<Distribution> GetCloudFrontDistribution(string distributionId) => throw new NotImplementedException();
public Task<List<string>> ListOfDyanmoDBTables() => throw new NotImplementedException();
public Task<List<string>> ListOfSQSQueuesUrls() => throw new NotImplementedException();
public Task<List<string>> ListOfSNSTopicArns() => throw new NotImplementedException();
public Task<List<Amazon.S3.Model.S3Bucket>> ListOfS3Buckets() => throw new NotImplementedException();
}
}
Loading

0 comments on commit f696c3b

Please sign in to comment.