Esempio n. 1
0
        private static async Task <Stack> WaitForNoLongerInProgress(ILogger log, IAmazonCloudFormation cloudformation, string stackName)
        {
            try
            {
                long  start        = DateTime.Now.Ticks;
                Stack currentStack = null;
                do
                {
                    if (currentStack != null)
                    {
                        log.Information($"... Waiting for stack's state to change from {currentStack.StackStatus}: {TimeSpan.FromTicks(DateTime.Now.Ticks - start).TotalSeconds.ToString("0").PadLeft(3)} secs");
                    }
                    await Task.Delay(POLLING_PERIOD).ConfigureAwait(false);

                    currentStack = await GetExistingStackAsync(cloudformation, stackName).ConfigureAwait(false);
                } while (currentStack != null && currentStack.StackStatus.ToString().EndsWith(IN_PROGRESS_SUFFIX));

                return(currentStack);
            }
            catch (Exception e)
            {
                log.Error(e, "Error waiting for stack state change");
                throw;
            }
        }
Esempio n. 2
0
 public CloudformationStackDeployer(
     IAlarmLogger logger,
     IAmazonCloudFormation cloudformation,
     IAmazonS3 s3Client,
     S3Location s3Location) : this(logger, cloudformation, s3Client, s3Location, TimeSpan.FromSeconds(2), TimeSpan.FromMinutes(5))
 {
 }
Esempio n. 3
0
        public IAwsFactory <IAmazonCloudFormation> CreateCloudFormationFactory(IAmazonCloudFormation client)
        {
            var factory = Substitute.For <IAwsFactory <IAmazonCloudFormation> >();

            factory.Create(Arg.Any <string>()).Returns(client);
            return(factory);
        }
        internal static bool IsStackInState(IAmazonCloudFormation client, string stackName, HashSet <StackStatus> desiredStates, bool throwOnError)
        {
            try
            {
                var request = new DescribeStacksRequest {
                    StackName = stackName
                };

#if DESKTOP
                var response = client.DescribeStacks(request);
#elif CORECLR
                var response = client.DescribeStacksAsync(request).GetAwaiter().GetResult();
#else
#error "Unknown build edition"
#endif

                return(IsStackInState(response.Stacks[0].StackStatus, desiredStates));
            }
            catch (Exception exc)
            {
                var webException = exc.InnerException as System.Net.WebException;
                if (webException != null)
                {
                    throw new Exception(Utils.Common.FormatNameResolutionFailureMessage(client.Config, webException.Message), webException);
                }

                if (throwOnError)
                {
                    throw;
                }
            }

            return(false);
        }
Esempio n. 5
0
        public static async Task <(bool Success, Stack Stack)> GetStackAsync(this IAmazonCloudFormation cfnClient, string stackName, LogErrorDelegate logError)
        {
            Stack stack = null;

            try {
                var describe = await cfnClient.DescribeStacksAsync(new DescribeStacksRequest {
                    StackName = stackName
                });

                // make sure the stack is in a stable state (not updating and not failed)
                stack = describe.Stacks.FirstOrDefault();
                switch (stack?.StackStatus)
                {
                case null:
                case "CREATE_COMPLETE":
                case "ROLLBACK_COMPLETE":
                case "UPDATE_COMPLETE":
                case "UPDATE_ROLLBACK_COMPLETE":

                    // we're good to go
                    break;

                default:
                    logError?.Invoke($"{stackName} is not in a valid state; module deployment must be complete and successful (status: {stack?.StackStatus})", null);
                    return(false, null);
                }
            } catch (AmazonCloudFormationException) {
                // stack not found; nothing to do
            }
            return(true, stack);
        }
Esempio n. 6
0
        public StackEventMonitor(string stackName, IAWSClientFactory awsClientFactory, IToolInteractiveService interactiveService, OrchestratorSession session)
        {
            _stackName = stackName;

            _cloudFormationClient = awsClientFactory.GetAWSClient <IAmazonCloudFormation>(session.AWSCredentials, session.AWSRegion);
            _consoleUtilities     = new ConsoleUtilities(interactiveService);
        }
Esempio n. 7
0
        public StackEventMonitor(string stackName, IAWSClientFactory awsClientFactory, IConsoleUtilities consoleUtilities)
        {
            _stackName        = stackName;
            _consoleUtilities = consoleUtilities;

            _cloudFormationClient = awsClientFactory.GetAWSClient <IAmazonCloudFormation>();
        }
Esempio n. 8
0
 public DeleteDeploymentCommand(IAWSClientFactory awsClientFactory, IToolInteractiveService interactiveService, OrchestratorSession session)
 {
     _awsClientFactory     = awsClientFactory;
     _interactiveService   = interactiveService;
     _session              = session;
     _cloudFormationClient = _awsClientFactory.GetAWSClient <IAmazonCloudFormation>(_session.AWSCredentials, _session.AWSRegion);
     _consoleUtilities     = new ConsoleUtilities(interactiveService);
 }
        //--- Constructors ---

        /// <summary>
        /// Creates new instance of <see cref="LambdaFinalizerDependencyProvider"/>, which provides the implementation for the required dependencies for <see cref="ALambdaFinalizerFunction"/>.
        /// </summary>
        /// <param name="utcNowCallback">A function that return the current <c>DateTime</c> in UTC timezone. Defaults to <see cref="DateTime.UtcNow"/> when <c>null</c>.</param>
        /// <param name="logCallback">An action that logs a string message. Defaults to <see cref="LambdaLogger.Log"/> when <c>null</c>.</param>
        /// <param name="configSource">A <see cref="ILambdaConfigSource"/> instance from which the Lambda function configuration is read. Defaults to <see cref="LambdaSystemEnvironmentSource"/> instance when <c>null</c>.</param>
        /// <param name="kmsClient">A <see cref="IAmazonKeyManagementService"/> client instance. Defaults to <see cref="AmazonKeyManagementServiceClient"/> when <c>null</c>.</param>
        /// <param name="sqsClient">A <see cref="IAmazonSQS"/> client instance. Defaults to <see cref="AmazonSQSClient"/> when <c>null</c>.</param>
        /// <param name="cloudFormationClient">A <see cref="IAmazonCloudFormation"/> client instance. Defaults to <see cref="AmazonCloudFormationClient"/> when <c>null</c>.</param>
        public LambdaFinalizerDependencyProvider(
            Func <DateTime>?utcNowCallback        = null,
            Action <string>?logCallback           = null,
            ILambdaConfigSource?configSource      = null,
            IAmazonKeyManagementService?kmsClient = null,
            IAmazonSQS?sqsClient = null,
            IAmazonCloudFormation?cloudFormationClient = null
            ) : base(utcNowCallback, logCallback, configSource, kmsClient, sqsClient)
        {
            _cloudFormationClient = cloudFormationClient ?? new AmazonCloudFormationClient();
        }
Esempio n. 10
0
        private static async Task <Stack> WaitStackToCompleteAsync(ILogger log, IAmazonCloudFormation cloudformation, string stackName, DateTime mintimeStampForEvents)
        {
            const int TIMESTAMP_WIDTH        = 20;
            const int LOGICAL_RESOURCE_WIDTH = 40;
            const int RESOURCE_STATUS        = 40;

            var mostRecentEventId = "";

            log.Information("   ");
            log.Information(
                "Timestamp".PadRight(TIMESTAMP_WIDTH) + " " +
                "Logical Resource Id".PadRight(LOGICAL_RESOURCE_WIDTH) + " " +
                "Status".PadRight(RESOURCE_STATUS) + " ");

            log.Information(
                new string('-', TIMESTAMP_WIDTH) + " " +
                new string('-', LOGICAL_RESOURCE_WIDTH) + " " +
                new string('-', RESOURCE_STATUS) + " ");

            Stack stack;

            do
            {
                await Task.Delay(POLLING_PERIOD).ConfigureAwait(false);

                stack = await GetExistingStackAsync(cloudformation, stackName).ConfigureAwait(false);

                var events = await GetLatestEventsAsync(log, cloudformation, stackName, mintimeStampForEvents, mostRecentEventId).ConfigureAwait(false);

                if (events.Count > 0)
                {
                    mostRecentEventId = events[0].EventId;
                }

                for (int i = events.Count - 1; i >= 0; i--)
                {
                    var line =
                        events[i].Timestamp.ToString("g").PadRight(TIMESTAMP_WIDTH) + " " +
                        events[i].LogicalResourceId.PadRight(LOGICAL_RESOURCE_WIDTH) + " " +
                        events[i].ResourceStatus.ToString().PadRight(RESOURCE_STATUS);

                    // To save screen space only show error messages.
                    if (!events[i].ResourceStatus.ToString().EndsWith(IN_PROGRESS_SUFFIX) && !string.IsNullOrEmpty(events[i].ResourceStatusReason))
                    {
                        line += " " + events[i].ResourceStatusReason;
                    }

                    log.Information(line);
                }
            } while (stack.StackStatus.ToString().EndsWith(IN_PROGRESS_SUFFIX));

            return(stack);
        }
Esempio n. 11
0
 public CloudformationStackDeployer(
     IAlarmLogger logger,
     IAmazonCloudFormation cloudformation,
     IAmazonS3 s3Client,
     S3Location s3Location,
     TimeSpan wait, TimeSpan timeout)
 {
     _logger                   = logger;
     _cloudformation           = cloudformation;
     _stackStatusCheckTimeout  = timeout;
     _stackStatusCheckInterval = wait;
     _s3Client                 = s3Client;
     _s3Location               = s3Location;
 }
 public DeleteDeploymentCommand(
     IAWSClientFactory awsClientFactory,
     IToolInteractiveService interactiveService,
     IConsoleUtilities consoleUtilities,
     ILocalUserSettingsEngine localUserSettingsEngine,
     OrchestratorSession?session)
 {
     _awsClientFactory        = awsClientFactory;
     _interactiveService      = interactiveService;
     _consoleUtilities        = consoleUtilities;
     _cloudFormationClient    = _awsClientFactory.GetAWSClient <IAmazonCloudFormation>();
     _localUserSettingsEngine = localUserSettingsEngine;
     _session = session;
 }
Esempio n. 13
0
        public async Task SetupCloudFormation()
        {
            cloudformation = new AmazonCloudFormationClient();

            if (await cloudformation.StackExists(stackName))
            {
                await cloudformation.DeleteStackAsync(new DeleteStackRequest
                {
                    StackName = stackName
                });

                await cloudformation.WaitUntilStackDoesNotExist(stackName);
            }
        }
Esempio n. 14
0
        public static async Task <bool> StackHasStatus(this IAmazonCloudFormation client, string stackName, string status)
        {
            try
            {
                var response = await client.DescribeStacksAsync(new DescribeStacksRequest
                {
                    StackName = stackName
                });

                return(response.Stacks.Count > 0 ? response.Stacks[0].StackStatus == status : false);
            }
            catch (Exception)
            {
                return(false);
            }
        }
Esempio n. 15
0
        public static async Task <StackSet> GetExistingStackSetAsync(IAmazonCloudFormation cloudformation, string stackSetName)
        {
            try
            {
                var request = new DescribeStackSetRequest {
                    StackSetName = stackSetName
                };
                var response = await cloudformation.DescribeStackSetAsync(request).ConfigureAwait(false);

                return(response.StackSet);
            }
            catch (AmazonCloudFormationException)
            {
                return(null);
            }
        }
Esempio n. 16
0
        public static async Task WaitUntilStackDoesNotExist(this IAmazonCloudFormation client, string stackName, int timeout = 300)
        {
            int tries = 0;

            while (await client.StackExists(stackName))
            {
                if (tries > timeout)
                {
                    throw new Exception("Timed out waiting for stack to finish deleting");
                }

                await Task.Delay(1000);

                tries++;
            }
        }
Esempio n. 17
0
        public static async Task WaitUntilStackHasStatus(this IAmazonCloudFormation client, string stackName, string status, int timeout = 300)
        {
            int tries = 0;

            while (!await client.StackHasStatus(stackName, status))
            {
                if (tries > timeout)
                {
                    throw new Exception("Timed out waiting for stack");
                }

                await Task.Delay(1000);

                tries++;
            }
        }
Esempio n. 18
0
        public LayerTestsFixture()
        {
            this.CFClient     = new AmazonCloudFormationClient(RegionEndpoint.USEast1);
            this.S3Client     = new AmazonS3Client(RegionEndpoint.USEast1);
            this.LambdaClient = new AmazonLambdaClient(RegionEndpoint.USEast1);

            this.Bucket = "dotnet-lambda-layer-tests-" + DateTime.Now.Ticks;

            Task.Run(async() =>
            {
                await S3Client.PutBucketAsync(this.Bucket);

                // Wait for bucket to exist
                Thread.Sleep(10000);
            }).Wait();
        }
Esempio n. 19
0
        private static async Task DeleteRollbackCompleteStackAsync(ILogger log, IAmazonCloudFormation cloudformation, Stack stack)
        {
            try
            {
                if (stack.StackStatus == StackStatus.ROLLBACK_COMPLETE)
                {
                    await cloudformation.DeleteStackAsync(new DeleteStackRequest { StackName = stack.StackName }).ConfigureAwait(false);
                }

                await WaitForNoLongerInProgress(log, cloudformation, stack.StackName).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                log.Error(ex, "Error removing previous failed stack creation {stackName}", stack.StackName);
                throw;
            }
        }
        public static async Task <string> GetOutputParameter(IAmazonCloudFormation cfClient, string stackName, string outputName)
        {
            var response = await cfClient.DescribeStacksAsync(new DescribeStacksRequest()
            {
                StackName = stackName
            });

            foreach (var output in response.Stacks[0].Outputs)
            {
                if (string.Equals(output.OutputKey, outputName, StringComparison.OrdinalIgnoreCase))
                {
                    return(output.OutputValue);
                }
            }

            return(null);
        }
        public static async Task <string> GetPhysicalCloudFormationResourceId(IAmazonCloudFormation cfClient, string stackName, string logicalId)
        {
            var response = await cfClient.DescribeStackResourcesAsync(new DescribeStackResourcesRequest()
            {
                StackName         = stackName,
                LogicalResourceId = logicalId
            });

            foreach (var resource in response.StackResources)
            {
                if (string.Equals(resource.LogicalResourceId, logicalId, StringComparison.OrdinalIgnoreCase))
                {
                    return(resource.PhysicalResourceId);
                }
            }

            return(null);
        }
Esempio n. 22
0
        public static async Task <string> GetMostRecentStackEventIdAsync(this IAmazonCloudFormation cfnClient, string stackName)
        {
            try {
                var response = await cfnClient.DescribeStackEventsAsync(new DescribeStackEventsRequest {
                    StackName = stackName
                });

                var mostRecentStackEvent = response.StackEvents.First();

                // make sure the stack is not already in an update operation
                if (!mostRecentStackEvent.IsFinalStackEvent())
                {
                    throw new System.InvalidOperationException("stack appears to be undergoing an update operation");
                }
                return(mostRecentStackEvent.EventId);
            } catch (AmazonCloudFormationException) {
                // NOTE (2018-12-11, bjorg): exception is thrown when stack doesn't exist; ignore it
            }
            return(null);
        }
Esempio n. 23
0
        private async Task <bool> DoesStackExist(DeployStackContext context, IAmazonCloudFormation cloudformationClient)
        {
            try
            { // if this throws, assume the stack does not exist.
                var describeStacksRequest = new DescribeStacksRequest {
                    StackName = context.StackName
                };
                var describeStacksResponse = await cloudformationClient.DescribeStacksAsync(describeStacksRequest);

                logger.LogInformation($"Got describe stacks response: {Serialize(describeStacksResponse)}");

                return(describeStacksResponse.Stacks.Count() != 0);
            }
            catch (Exception e)
            {
                logger.LogError($"Describe stacks failure: {e.Message}\n{e.StackTrace}");
            }

            return(false);
        }
Esempio n. 24
0
        public static async Task <bool> DeleteStackAsync(ILogger log, IAmazonCloudFormation cloudformation, string stackName, string roleArn)
        {
            var request = new DeleteStackRequest
            {
                StackName = stackName,
                RoleARN   = roleArn
            };

            try
            {
                await cloudformation.DeleteStackAsync(request).ConfigureAwait(false);

                log.Information("CloudFormation stack {stackName} deleted", request.StackName);
                return(true);
            }
            catch (Exception ex)
            {
                log.Error(ex, "Error deleting Cloudformation stack {stackName}", request.StackName);
                return(false);
            }
        }
Esempio n. 25
0
        public static async Task <(bool Success, Stack Stack)> GetStackAsync(this IAmazonCloudFormation cfnClient, string stackName, LogErrorDelegate logError)
        {
            Stack stack    = null;
            var   attempts = 0;

            try {
                var describe = await cfnClient.DescribeStacksAsync(new DescribeStacksRequest {
                    StackName = stackName
                });

                // make sure the stack is in a stable state (not updating and not failed)
                stack = describe.Stacks.FirstOrDefault();
                switch (stack?.StackStatus)
                {
                case null:
                case "CREATE_COMPLETE":
                case "ROLLBACK_COMPLETE":
                case "UPDATE_COMPLETE":
                case "UPDATE_ROLLBACK_COMPLETE":

                    // we're good to go
                    break;

                default:
                    logError?.Invoke($"{stackName} is not in a valid state; CloudFormation stack must be complete and successful (status: {stack?.StackStatus})", null);
                    return(false, null);
                }
            } catch (AmazonCloudFormationException) {
                // stack not found; nothing to do
            } catch (HttpRequestException e) when(e.Message == "The requested name is valid, but no data of the requested type was found")
            {
                // NOTE (2020-03-31, bjorg): avoid sporadic DNS issues by waiting an trying again
                if (++attempts < 3)
                {
                    await Task.Delay(TimeSpan.FromSeconds(attempts));
                }
            }
            return(true, stack);
        }
 private Amazon.CloudFormation.Model.TestTypeResponse CallAWSServiceOperation(IAmazonCloudFormation client, Amazon.CloudFormation.Model.TestTypeRequest request)
 {
     Utils.Common.WriteVerboseEndpointMessage(this, client.Config, "AWS CloudFormation", "TestType");
     try
     {
         #if DESKTOP
         return(client.TestType(request));
         #elif CORECLR
         return(client.TestTypeAsync(request).GetAwaiter().GetResult());
         #else
                 #error "Unknown build edition"
         #endif
     }
     catch (AmazonServiceException exc)
     {
         var webException = exc.InnerException as System.Net.WebException;
         if (webException != null)
         {
             throw new Exception(Utils.Common.FormatNameResolutionFailureMessage(client.Config, webException.Message), webException);
         }
         throw;
     }
 }
Esempio n. 27
0
 internal ListStackSetOperationResultsPaginator(IAmazonCloudFormation client, ListStackSetOperationResultsRequest request)
 {
     this._client  = client;
     this._request = request;
 }
 internal ListTypesPaginator(IAmazonCloudFormation client, ListTypesRequest request)
 {
     this._client  = client;
     this._request = request;
 }
Esempio n. 29
0
        public static async Task <(Stack Stack, bool Success)> TrackStackUpdateAsync(
            this IAmazonCloudFormation cfnClient,
            string stackName,
            string stackId,
            string mostRecentStackEventId,
            ModuleNameMappings nameMappings = null,
            LogErrorDelegate logError       = null
            )
        {
            var seenEventIds = new HashSet <string>();
            var foundMostRecentStackEvent = (mostRecentStackEventId == null);
            var request = new DescribeStackEventsRequest {
                StackName = stackId ?? stackName
            };
            var eventList        = new List <StackEvent>();
            var ansiLinesPrinted = 0;

            // iterate as long as the stack is being created/updated
            var active  = true;
            var success = false;

            while (active)
            {
                await Task.Delay(TimeSpan.FromSeconds(3));

                // fetch as many events as possible for the current stack
                var events = new List <StackEvent>();
                try {
                    var response = await cfnClient.DescribeStackEventsAsync(request);

                    events.AddRange(response.StackEvents);
                } catch (System.Net.Http.HttpRequestException e) when((e.InnerException is System.Net.Sockets.SocketException) && (e.InnerException.Message == "No such host is known"))
                {
                    // ignore network issues and just try again
                    continue;
                }
                events.Reverse();

                // skip any events that preceded the most recent event before the stack update operation
                while (!foundMostRecentStackEvent && events.Any())
                {
                    var evt = events.First();
                    if (evt.EventId == mostRecentStackEventId)
                    {
                        foundMostRecentStackEvent = true;
                    }
                    seenEventIds.Add(evt.EventId);
                    events.RemoveAt(0);
                }
                if (!foundMostRecentStackEvent)
                {
                    throw new ApplicationException($"unable to find starting event for stack: {stackName}");
                }

                // report only on new events
                foreach (var evt in events.Where(evt => !seenEventIds.Contains(evt.EventId)))
                {
                    UpdateEvent(evt);
                    if (!seenEventIds.Add(evt.EventId))
                    {
                        // we found an event we already saw in the past, no point in looking at more events
                        break;
                    }
                    if (IsFinalStackEvent(evt) && (evt.LogicalResourceId == stackName))
                    {
                        // event signals stack creation/update completion; time to stop
                        active  = false;
                        success = IsSuccessfulFinalStackEvent(evt);
                        break;
                    }
                }
                RenderEvents();
            }
            if (!success)
            {
                return(Stack : null, Success : false);
            }

            // describe stack and report any output values
            var description = await cfnClient.DescribeStacksAsync(new DescribeStacksRequest {
                StackName = stackName
            });

            return(Stack : description.Stacks.FirstOrDefault(), Success : success);

            // local function
            string TranslateLogicalIdToFullName(string logicalId)
            {
                var fullName = logicalId;

                nameMappings?.ResourceNameMappings?.TryGetValue(logicalId, out fullName);
                return(fullName ?? logicalId);
            }

            string TranslateResourceTypeToFullName(string awsType)
            {
                var fullName = awsType;

                nameMappings?.TypeNameMappings?.TryGetValue(awsType, out fullName);
                return(fullName ?? awsType);
            }

            void RenderEvents()
            {
                if (Settings.UseAnsiConsole)
                {
                    if (ansiLinesPrinted > 0)
                    {
                        Console.Write(AnsiTerminal.MoveLineUp(ansiLinesPrinted));
                    }
                    var maxResourceStatusLength   = eventList.Any() ? eventList.Max(evt => evt.ResourceStatus.ToString().Length) : 0;
                    var maxResourceTypeNameLength = eventList.Any() ? eventList.Max(evt => TranslateResourceTypeToFullName(evt.ResourceType).Length) : 0;
                    foreach (var evt in eventList)
                    {
                        var resourceStatus = evt.ResourceStatus.ToString();
                        var resourceType   = TranslateResourceTypeToFullName(evt.ResourceType);
                        if (_ansiStatusColorCodes.TryGetValue(evt.ResourceStatus, out var ansiColor))
                        {
                            // print resource status
                            Console.Write(ansiColor);
                            Console.Write(resourceStatus);
                            Console.Write(AnsiTerminal.Reset);
                            Console.Write("".PadRight(maxResourceStatusLength - resourceStatus.Length + 4));

                            // print resource type
                            Console.Write(resourceType);
                            Console.Write("".PadRight(maxResourceTypeNameLength - resourceType.Length + 4));

                            // print resource name
                            Console.Write(TranslateLogicalIdToFullName(evt.LogicalResourceId));

                            // print status reason
                            if ((logError == null) && (evt.ResourceStatusReason != null))
                            {
                                Console.Write($" ({evt.ResourceStatusReason})");
                            }
                        }
                        else
                        {
                            Console.Write($"{resourceStatus}    {resourceType}    {TranslateLogicalIdToFullName(evt.LogicalResourceId)}{(evt.ResourceStatusReason != null ? $" ({evt.ResourceStatusReason})" : "")}");
                        }
                        Console.Write(AnsiTerminal.ClearEndOfLine);
                        Console.WriteLine();
                    }
                    ansiLinesPrinted = eventList.Count;
                }
            }

            void UpdateEvent(StackEvent evt)
            {
                if (Settings.UseAnsiConsole)
                {
                    var index = eventList.FindIndex(e => e.LogicalResourceId == evt.LogicalResourceId);
                    if (index < 0)
                    {
                        eventList.Add(evt);
                    }
                    else
                    {
                        eventList[index] = evt;
                    }
                }
                else
                {
                    Console.WriteLine($"{evt.ResourceStatus,-35} {TranslateResourceTypeToFullName(evt.ResourceType),-55} {TranslateLogicalIdToFullName(evt.LogicalResourceId)}{(evt.ResourceStatusReason != null ? $" ({evt.ResourceStatusReason})" : "")}");
                }

                // capture failed operation as an error
                switch (evt.ResourceStatus)
                {
                case "CREATE_FAILED":
                case "ROLLBACK_FAILED":
                case "UPDATE_FAILED":
                case "DELETE_FAILED":
                case "UPDATE_ROLLBACK_FAILED":
                case "UPDATE_ROLLBACK_IN_PROGRESS":
                    if (evt.ResourceStatusReason != "Resource creation cancelled")
                    {
                        logError?.Invoke($"{evt.ResourceStatus} {TranslateLogicalIdToFullName(evt.LogicalResourceId)} [{TranslateResourceTypeToFullName(evt.ResourceType)}]: {evt.ResourceStatusReason}", /*Exception*/ null);
                    }
                    break;
                }
            }
        }
Esempio n. 30
0
        protected Func <Task <Settings> > CreateSettingsInitializer(
            CommandLineApplication cmd,
            bool requireAwsProfile     = true,
            bool requireDeploymentTier = true
            )
        {
            CommandOption tierOption       = null;
            CommandOption awsProfileOption = null;

            // add misc options
            if (requireDeploymentTier)
            {
                tierOption = AddTierOption(cmd);
            }
            var toolProfileOption = cmd.Option("--cli-profile|-C <NAME>", "(optional) Use a specific LambdaSharp CLI profile (default: Default)", CommandOptionType.SingleValue);

            if (requireAwsProfile)
            {
                awsProfileOption = cmd.Option("--aws-profile|-P <NAME>", "(optional) Use a specific AWS profile from the AWS credentials file", CommandOptionType.SingleValue);
            }
            var verboseLevelOption = cmd.Option("--verbose|-V:<LEVEL>", "(optional) Show verbose output (0=quiet, 1=normal, 2=detailed, 3=exceptions)", CommandOptionType.SingleOrNoValue);

            // add hidden testing options
            var awsRegionOption                   = cmd.Option("--aws-region <NAME>", "(test only) Override AWS region (default: read from AWS profile)", CommandOptionType.SingleValue);
            var awsAccountIdOption                = cmd.Option("--aws-account-id <VALUE>", "(test only) Override AWS account Id (default: read from AWS profile)", CommandOptionType.SingleValue);
            var awsUserArnOption                  = cmd.Option("--aws-user-arn <ARN>", "(test only) Override AWS user ARN (default: read from AWS profile)", CommandOptionType.SingleValue);
            var toolVersionOption                 = cmd.Option("--cli-version <VALUE>", "(test only) LambdaSharp CLI version for profile", CommandOptionType.SingleValue);
            var deploymentBucketNameOption        = cmd.Option("--deployment-bucket-name <NAME>", "(test only) S3 Bucket name used to deploy modules (default: read from LambdaSharp CLI configuration)", CommandOptionType.SingleValue);
            var deploymentNotificationTopicOption = cmd.Option("--deployment-notifications-topic <ARN>", "(test only) SNS Topic for CloudFormation deployment notifications (default: read from LambdaSharp CLI configuration)", CommandOptionType.SingleValue);
            var moduleBucketNamesOption           = cmd.Option("--module-bucket-names <NAMES>", "(test only) Comma-separated list of S3 Bucket names used to find modules (default: read from LambdaSharp CLI configuration)", CommandOptionType.SingleValue);
            var tierVersionOption                 = cmd.Option("--tier-version <VERSION>", "(test only) LambdaSharp tier version (default: read from deployment tier)", CommandOptionType.SingleValue);

            awsAccountIdOption.ShowInHelpText                = false;
            awsRegionOption.ShowInHelpText                   = false;
            toolVersionOption.ShowInHelpText                 = false;
            deploymentBucketNameOption.ShowInHelpText        = false;
            deploymentNotificationTopicOption.ShowInHelpText = false;
            moduleBucketNamesOption.ShowInHelpText           = false;
            tierVersionOption.ShowInHelpText                 = false;
            return(async() => {
                // initialize logging level
                if (!TryParseEnumOption(verboseLevelOption, Tool.VerboseLevel.Normal, VerboseLevel.Detailed, out Settings.VerboseLevel))
                {
                    // NOTE (2018-08-04, bjorg): no need to add an error message since it's already added by 'TryParseEnumOption'
                    return null;
                }

                // initialize CLI profile
                var toolProfile = toolProfileOption.Value() ?? Environment.GetEnvironmentVariable("LAMBDASHARP_PROFILE") ?? "Default";

                // initialize deployment tier
                string tier = null;
                if (requireDeploymentTier)
                {
                    tier = tierOption.Value() ?? Environment.GetEnvironmentVariable("LAMBDASHARP_TIER");
                    if (string.IsNullOrEmpty(tier))
                    {
                        LogError("missing deployment tier name");
                    }
                    else if (tier == "Default")
                    {
                        LogError("deployment tier cannot be 'Default' because it is a reserved name");
                    }
                }

                // initialize AWS profile
                try {
                    AwsAccountInfo awsAccount = null;
                    IAmazonSimpleSystemsManagement ssmClient = null;
                    IAmazonCloudFormation cfClient = null;
                    IAmazonKeyManagementService kmsClient = null;
                    IAmazonS3 s3Client = null;
                    if (requireAwsProfile)
                    {
                        awsAccount = await InitializeAwsProfile(
                            awsProfileOption.Value(),
                            awsAccountIdOption.Value(),
                            awsRegionOption.Value(),
                            awsUserArnOption.Value()
                            );

                        // create AWS clients
                        ssmClient = new AmazonSimpleSystemsManagementClient();
                        cfClient = new AmazonCloudFormationClient();
                        kmsClient = new AmazonKeyManagementServiceClient();
                        s3Client = new AmazonS3Client();
                    }
                    if (HasErrors)
                    {
                        return null;
                    }

                    // initialize LambdaSharp deployment values
                    var tierVersion = tierVersionOption.Value();
                    var deploymentBucketName = deploymentBucketNameOption.Value();
                    var deploymentNotificationTopic = deploymentNotificationTopicOption.Value();
                    var moduleBucketNames = moduleBucketNamesOption.Value()?.Split(',');

                    // create a settings instance for each module filename
                    return new Settings {
                        ToolVersion = Version,
                        ToolProfile = toolProfile,
                        ToolProfileExplicitlyProvided = toolProfileOption.HasValue(),
                        TierVersion = (tierVersion != null) ? VersionInfo.Parse(tierVersion) : null,
                        Tier = tier,
                        AwsRegion = awsAccount?.Region,
                        AwsAccountId = awsAccount?.AccountId,
                        AwsUserArn = awsAccount?.UserArn,
                        DeploymentBucketName = deploymentBucketName,
                        DeploymentNotificationsTopic = deploymentNotificationTopic,
                        ModuleBucketNames = moduleBucketNames,
                        SsmClient = ssmClient,
                        CfnClient = cfClient,
                        KmsClient = kmsClient,
                        S3Client = s3Client
                    };
                } catch (AmazonClientException e) when(e.Message == "No RegionEndpoint or ServiceURL configured")
                {
                    LogError("AWS profile configuration is missing a region specifier");
                    return null;
                }
            });
        }
Esempio n. 31
0
 public StackService(IAmazonCloudFormation cloudFormationClient, IStorageService storageService, string bucket)
 {
     _cloudFormationClient = cloudFormationClient;
     _storageService = storageService;
     _bucket = bucket;
 }