Esempio n. 1
0
        public async Task <string> BuildDockerImage(CloudApplication cloudApplication, Recommendation recommendation)
        {
            _interactiveService.LogMessageLine(string.Empty);
            _interactiveService.LogMessageLine("Building the docker image...");

            var dockerExecutionDirectory = GetDockerExecutionDirectory(recommendation);
            var tagSuffix  = DateTime.UtcNow.Ticks;
            var imageTag   = $"{cloudApplication.StackName.ToLower()}:{tagSuffix}";
            var dockerFile = GetDockerFilePath(recommendation);
            var buildArgs  = GetDockerBuildArgs(recommendation);

            var dockerBuildCommand = $"docker build -t {imageTag} -f \"{dockerFile}\"{buildArgs} .";

            _interactiveService.LogMessageLine($"Docker Execution Directory: {Path.GetFullPath(dockerExecutionDirectory)}");
            _interactiveService.LogMessageLine($"Docker Build Command: {dockerBuildCommand}");


            recommendation.DeploymentBundle.DockerExecutionDirectory = dockerExecutionDirectory;

            var result = await _commandLineWrapper.TryRunWithResult(dockerBuildCommand, dockerExecutionDirectory, redirectIO : false);

            if (result.ExitCode != 0)
            {
                throw new DockerBuildFailedException(result.StandardError ?? "");
            }

            return(imageTag);
        }
Esempio n. 2
0
        /// <summary>
        /// Checks if the location of the saved CDK deployment project is monitored by a source control system.
        /// </summary>
        /// <param name="saveCdkDirectoryPath">Relative or absolute path of the directory at which the CDK deployment project will be saved.</param>
        /// <returns></returns>
        private async Task <bool> IsDirectoryUnderSourceControl(string saveCdkDirectoryPath)
        {
            var gitStatusResult = await _commandLineWrapper.TryRunWithResult("git status", saveCdkDirectoryPath);

            var svnStatusResult = await _commandLineWrapper.TryRunWithResult("svn status", saveCdkDirectoryPath);

            return(gitStatusResult.Success || svnStatusResult.Success);
        }
        /// <summary>
        /// Helper method to find if the directory is monitored by a source control system.
        /// </summary>
        /// <param name="directoryPath">An absolute directory path.</param>
        /// <returns></returns>
        private async Task <bool> IsDirectoryUnderSourceControl(string?directoryPath)
        {
            if (!string.IsNullOrEmpty(directoryPath))
            {
                var gitStatusResult = await _commandLineWrapper.TryRunWithResult(GIT_STATUS_COMMAND, directoryPath);

                var svnStatusResult = await _commandLineWrapper.TryRunWithResult(SVN_STATUS_COMMAND, directoryPath);

                return(gitStatusResult.Success || svnStatusResult.Success);
            }
            return(false);
        }
Esempio n. 4
0
        /// <summary>
        /// Use the native zip utility if it exist which will maintain linux/osx file permissions.
        /// </summary>
        private async Task BuildZipForLinux(string sourceDirectoryName, string destinationArchiveFileName)
        {
            var zipCLI = FindExecutableInPath("zip");

            if (string.IsNullOrEmpty(zipCLI))
            {
                throw new FailedToCreateZipFileException("Failed to find the \"zip\" utility program in path. This program is required to maintain Linux file permissions in the zip archive.");
            }

            var args = new StringBuilder($"\"{destinationArchiveFileName}\"");

            var allFiles = GetFilesToIncludeInArchive(sourceDirectoryName);

            foreach (var kvp in allFiles)
            {
                args.AppendFormat(" \"{0}\"", kvp.Key);
            }

            var command = $"{zipCLI} {args}";
            var result  = await _commandLineWrapper.TryRunWithResult(command, sourceDirectoryName);

            if (result.ExitCode != 0)
            {
                throw new FailedToCreateZipFileException("\"zip\" utility program has failed to create a zip archive.");
            }
        }
        public async Task DeployCdkProject(OrchestratorSession session, string cdkProjectPath, Recommendation recommendation)
        {
            var recipeInfo           = $"{recommendation.Recipe.Id}_{recommendation.Recipe.Version}";
            var environmentVariables = new Dictionary <string, string>
            {
                { EnvironmentVariableKeys.AWS_EXECUTION_ENV, recipeInfo }
            };

            _interactiveService.LogMessageLine("Starting deployment of CDK Project");

            // Ensure region is bootstrapped
            await _commandLineWrapper.Run($"npx cdk bootstrap aws://{session.AWSAccountId}/{session.AWSRegion}",
                                          needAwsCredentials : true);

            var appSettingsFilePath = Path.Combine(cdkProjectPath, "appsettings.json");

            // Handover to CDK command line tool
            // Use a CDK Context parameter to specify the settings file that has been serialized.
            var cdkDeploy = await _commandLineWrapper.TryRunWithResult($"npx cdk deploy --require-approval never -c {Constants.CloudFormationIdentifier.SETTINGS_PATH_CDK_CONTEXT_PARAMETER}=\"{appSettingsFilePath}\"",
                                                                       workingDirectory : cdkProjectPath,
                                                                       environmentVariables : environmentVariables,
                                                                       needAwsCredentials : true,
                                                                       streamOutputToInteractiveService : true);

            if (cdkDeploy.ExitCode != 0)
            {
                throw new FailedToDeployCDKAppException("We had an issue deploying your application to AWS. Check the deployment output for more details.");
            }
        }
Esempio n. 6
0
        /// <summary>
        /// From https://docs.aws.amazon.com/cdk/latest/guide/work-with.html#work-with-prerequisites,
        /// min version is 10.3
        /// </summary>
        private async Task <bool> HasMinVersionNodeJs()
        {
            // run node --version to get the version
            var result = await _commandLineWrapper.TryRunWithResult("node --version");

            var versionString = result.StandardOut;

            if (versionString.StartsWith("v", StringComparison.OrdinalIgnoreCase))
            {
                versionString = versionString.Substring(1, versionString.Length - 1);
            }

            if (!result.Success || !Version.TryParse(versionString, out var version))
            {
                return(false);
            }

            return(version.Major > 10 || version.Major == 10 && version.Minor >= 3);
        }
Esempio n. 7
0
        private async Task <TryGetResult <Version> > GetVersion(string workingDirectory, bool checkGlobal)
        {
            var command = new StringBuilder("npm list aws-cdk");

            if (checkGlobal)
            {
                command.Append(" --global");
            }

            TryRunResult result;

            try
            {
                result = await _commandLineWrapper.TryRunWithResult(command.ToString(), workingDirectory, false);
            }
            catch (Exception exception)
            {
                throw new NPMCommandFailedException($"Failed to execute {command}", exception);
            }

            /*
             * A typical Standard out looks like with version information in line 2
             *
             * > npm list aws-cdk --global
             * C:\Users\user\AppData\Roaming\npm
             * `-- [email protected]
             */
            var standardOut = result.StandardOut ?? "";
            var lines       = standardOut.Split('\n'); // Environment.NewLine doesn't work here.

            if (lines.Length < 2)
            {
                return(TryGetResult.Failure <Version>());
            }

            var versionLine = lines[1];

            /*
             * Split line 2 in parts so that we have package name and version in separate parts
             *
             * part 0: `--
             * part 1: aws-cdk
             * part 2: 0.0.0
             *
             * It could be possible we have more than 3 parts with more information but they can be ignored.
             */
            var parts = versionLine.Split(' ', '@');

            if (parts.Length < 3)
            {
                return(TryGetResult.Failure <Version>());
            }

            /*
             * Make sure that we are checking aws-cdk only
             * If a customer has plugin which depends on aws-cdk and then customer removes aws-cdk
             * Plugin version information is shown which can lead to a false positive.
             *
             * > npm list aws-cdk --global
             * C:\Users\user\AppData\Roaming\npm
             * `-- [email protected] (git+https://github.com/aws-samples/cdk-assume-role-credential-plugin.git#5167c798a50bc9c96a9d660b28306428be4e99fb)
             */
            if (!parts[1].Equals("aws-cdk"))
            {
                return(TryGetResult.Failure <Version>());
            }

            if (Version.TryParse(parts[2], out var version))
            {
                return(TryGetResult.FromResult(version));
            }

            return(TryGetResult.Failure <Version>());
        }