Example #1
0
 public Deployment(Application application, DeployCommand command)
 {
     ApplicationId      = application.ApplicationId;
     Version            = command.Version;
     CommitHash         = command.CommitHash;
     ApplicationConfig  = command.ConfigurationYaml;
     DeploymentDateTime = DateTimeOffset.UtcNow;
 }
        public void ExpectedBehavior()
        {
            var command = new DeployCommand();
            var args    = new DeployArgs();

            var result = command.Execute(args);

            StringAssert.AreEqualIgnoringCase(" ", result);
        }
Example #3
0
        private async Task <IngressV1Beta1> CreateEntryPointIngress(DeployCommand deployCommand, string kubeNamespace)
        {
            if (string.IsNullOrWhiteSpace(deployCommand.EntryPoint))
            {
                await DeleteExistingIngress();

                return(null);
            }
            else
            {
                return(await CreateIngress());
            }

            async Task DeleteExistingIngress()
            {
                await kubeApiClient.IngressesV1Beta1().Delete(KubeNaming.EntryPointIngressName, kubeNamespace);
            }

            async Task <IngressV1Beta1> CreateIngress()
            {
                var ingress = new IngressV1Beta1
                {
                    Metadata = new ObjectMetaV1
                    {
                        Name      = KubeNaming.EntryPointIngressName,
                        Namespace = kubeNamespace,
                    },
                    Spec = new IngressSpecV1Beta1
                    {
                        Rules =
                        {
                            new IngressRuleV1Beta1
                            {
                                Host = $"{deployCommand.Name}.{cludOptions.BaseHostname}",
                                Http = new HTTPIngressRuleValueV1Beta1
                                {
                                    Paths =
                                    {
                                        new HTTPIngressPathV1Beta1
                                        {
                                            Path    = "/",
                                            Backend = new IngressBackendV1Beta1
                                            {
                                                ServiceName = deployCommand.EntryPoint,
                                                ServicePort = KubeNaming.HttpPortName,
                                            }
                                        }
                                    }
                                }
                            }
                        },
                    },
                };

                return(await kubeApiClient.Dynamic().Apply(ingress, fieldManager: "clud", force: true));
            }
        }
Example #4
0
        public override async Task <DeploymentResponse> DeployApplication(DeployCommand command, ServerCallContext context)
        {
            var kubeNamespace = command.Name;

            await CreateNamespace(kubeNamespace);

            var serviceResources = await DeployServices(command, kubeNamespace);

            var entryPointIngress = await CreateEntryPointIngress(command, kubeNamespace);

            await CleanUpResources(serviceResources, kubeNamespace);

            var application = await dataContext.Applications.SingleOrDefaultAsync(a => a.Name == command.Name);

            if (application != null)
            {
                application.Update(command);
            }
            else
            {
                application = new Application(command);
                dataContext.Applications.Add(application);
                await dataContext.SaveChangesAsync();
            }

            dataContext.Deployments.Add(new Deployment(application, command));
            await dataContext.SaveChangesAsync();

            return(new DeploymentResponse
            {
                ManagementUrl = $"https://{cludOptions.BaseHostname}/applications/{command.Name}",
                IngressUrl = entryPointIngress != null ? "https://" + entryPointIngress.Spec.Rules.Single().Host : null,
                Services =
                {
                    serviceResources.Select(service => new DeploymentResponse.Types.Service
                    {
                        Name = service.Service.Metadata.Name,
                        InternalHostname = $"{service.Service.Metadata.Name}.{command.Name}",
                        IngressUrl = service.Ingress != null
                            ? "https://" + service.Ingress.Spec.Rules.Single().Host
                            : null,
                        Ports =
                        {
                            service.Service.Spec.Ports
                            .Where(port => port.Name != KubeNaming.HttpPortName)
                            .Select(port => new DeploymentResponse.Types.Port
                            {
                                TargetPort = port.TargetPort.Int32Value,
                                ExposedPort = port.NodePort,
                                HostName = $"{command.Name}.{cludOptions.BaseHostname}",
                                Type = port.Protocol,
                            })
                        }
                    })
                }
            });
        }
Example #5
0
 public void Update(DeployCommand deployment)
 {
     Name            = deployment.Name;
     Description     = deployment.Description;
     Owner           = deployment.Owner;
     Repository      = deployment.Repository;
     HasEntryPoint   = !string.IsNullOrWhiteSpace(deployment.EntryPoint);
     UpdatedDateTime = DateTimeOffset.UtcNow;
 }
Example #6
0
        public void Setup()
        {
            projectBuilder    = MockRepository.GenerateStub <IProjectBuilder>();
            ftpSessionFactory = MockRepository.GenerateMock <IFtpSessionFactory>();

            consoleEnv = new ConsoleShell("x");

            cmd = new DeployCommand(projectBuilder, ftpSessionFactory);
        }
    public static Command GetCommand(IServiceProvider serviceProvider)
    {
        var command = new Command("infra", "Infra commands")
        {
            DeployCommand.GetCommand(serviceProvider),
            GenHttpsCertCommand.GetCommand(serviceProvider),
        };

        command.Handler = ActivatorUtilities.CreateInstance <InfraCommand>(serviceProvider);
        return(command);
    }
Example #8
0
        private async Task <IReadOnlyCollection <ServiceResources> > DeployServices(DeployCommand command, string kubeNamespace)
        {
            var resources = new List <ServiceResources>();

            foreach (var serviceCommand in command.Services)
            {
                resources.Add(await DeployService(serviceCommand, kubeNamespace));
            }

            return(resources);
        }
Example #9
0
 void RaiseDeployCommandCanExecuteChanged()
 {
     if (Application.Current != null)
     {
         if (Application.Current.Dispatcher != null)
         {
             Application.Current.Dispatcher.Invoke(() =>
             {
                 DeployCommand.RaiseCanExecuteChanged();
             });
         }
     }
 }
Example #10
0
        private static void Deploy(string[] args)
        {
            DeployCommand deployCommand = ParseDeployCommand(args[0]);
            string        scriptText    = string.Empty;

            string connectionString = args
                                      .Skip(1)
                                      .Take(args.Length - 2)
                                      .FirstOrDefault(t => t.ToLower().StartsWith(key_Connection))
                                      .With(t => t == null ? null : t.Substring(key_Connection.Length));

            string scriptPath = args
                                .Skip(1)
                                .Take(args.Length - (deployCommand == DeployCommand.Manage ? 1 : 2))
                                .FirstOrDefault(t => t.ToLower().StartsWith(key_Script))
                                .With(t => t == null ? null : t.Substring(key_Script.Length));

            if (deployCommand == DeployCommand.Manage)
            {
                ManageParams manageParams = new ManageParams();

                manageParams.EnableClr = args
                                         .Skip(1)
                                         .Take(args.Length - 2)
                                         .Any(t => t.ToLower().Equals(key_EnableClr));

                manageParams.TrustworthyOn = args
                                             .Skip(1)
                                             .Take(args.Length - 2)
                                             .Any(t => t.ToLower().Equals(key_Trustworthy));

                scriptText = GetManageScript(manageParams);
            }
            else
            {
                DeployParams deployParams = new DeployParams();

                deployParams.PermissionSet = args
                                             .Skip(1)
                                             .Take(args.Length - 2)
                                             .FirstOrDefault(t => t.ToLower().StartsWith(key_Permission))
                                             .With(t => t == null ? default(PermissionSet?) : ParsePermissionSet(t.Substring(key_Permission.Length)));

                deployParams.Owner = args
                                     .Skip(1)
                                     .Take(args.Length - 2)
                                     .FirstOrDefault(t => t.ToLower().StartsWith(key_Owner))
                                     .With(t => t == null ? null : t.Substring(key_Owner.Length));

                deployParams.Schema = args
                                      .Skip(1)
                                      .Take(args.Length - 2)
                                      .FirstOrDefault(t => t.ToLower().StartsWith(key_Schema))
                                      .With(t => t == null ? null : t.Substring(key_Schema.Length));

                deployParams.UncheckedData = args
                                             .Skip(1)
                                             .Take(args.Length - 2)
                                             .Any(t => t.ToLower().Equals(key_Unchecked));

                deployParams.Assembly = args
                                        .Skip(1)
                                        .Take(args.Length - 2)
                                        .FirstOrDefault(t => t.ToLower().StartsWith(key_Assembly))
                                        .With(t => t == null ? null : t.Substring(key_Assembly.Length));

                deployParams.Reference = args
                                         .Skip(1)
                                         .Take(args.Length - 2)
                                         .Any(t => t.ToLower().Equals(key_Invisible));

                deployParams.Strong = args
                                      .Skip(1)
                                      .Take(args.Length - 2)
                                      .Any(t => t.ToLower().Equals(key_Strong));

                string mapPath = args
                                 .Skip(1)
                                 .Take(args.Length - 2)
                                 .FirstOrDefault(t => t.ToLower().StartsWith(map_Script))
                                 .With(t => t == null ? null : t.Substring(map_Script.Length));

                deployParams.Map = string.IsNullOrEmpty(mapPath) ? new Dictionary <string, string>() :
                                   File.ReadAllLines(mapPath)
                                   .Select(s => s.Split(';'))
                                   .Where(t => t.Length == 2 && !string.IsNullOrWhiteSpace(t[0]) && !string.IsNullOrWhiteSpace(t[1]))
                                   .ToDictionary(t => t[0], t => t[1]);

                Assembly assembly = deployParams.Strong ? Assembly.Load(args[args.Length - 1]) : Assembly.LoadFrom(args[args.Length - 1]);

                switch (deployCommand)
                {
                case DeployCommand.Register:
                    scriptText = GetCreateScript(assembly, deployParams);
                    break;

                case DeployCommand.Unregister:
                    scriptText = GetDropScript(assembly, deployParams);
                    break;

                case DeployCommand.Modify:
                    scriptText = GetAlterScript(assembly, deployParams);
                    break;
                }
            }

            if (!string.IsNullOrWhiteSpace(scriptPath))
            {
                bool append = args
                              .Skip(1)
                              .Take(args.Length - 2)
                              .Any(t => t.ToLower().Equals(key_Append));

                string encoding = args
                                  .Skip(1)
                                  .Take(args.Length - 2)
                                  .FirstOrDefault(t => t.ToLower().StartsWith(key_Encoding))
                                  .With(t => t == null ? null : t.Substring(key_Encoding.Length));

                SaveScript(scriptPath, scriptText, encoding, append);
            }

            if (!string.IsNullOrWhiteSpace(connectionString))
            {
                ExecuteScript(connectionString, scriptText);
            }
        }
        private static async Task <int> Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;

            SetExecutionEnvironment();

            var preambleWriter = new ConsoleInteractiveServiceImpl(diagnosticLoggingEnabled: false);

            preambleWriter.WriteLine("AWS .NET deployment tool for deploying .NET Core applications to AWS.");
            preambleWriter.WriteLine("Project Home: https://github.com/aws/aws-dotnet-deploy");
            preambleWriter.WriteLine(string.Empty);

            // Name is important to set here to show correctly in the CLI usage help.
            // Either dotnet-aws or dotnet aws works from the CLI. System.Commandline's help system does not like having a space with dotnet aws.
            var rootCommand = new RootCommand {
                Name = "dotnet-aws", Description = "The AWS .NET deployment tool for deploying .NET applications on AWS."
            };

            var deployCommand = new Command(
                "deploy",
                "Inspect, build, and deploy the .NET project to AWS using the recommended AWS service.")
            {
                _optionProfile,
                _optionRegion,
                _optionProjectPath,
                _optionDiagnosticLogging
            };

            deployCommand.Handler = CommandHandler.Create <string, string, string, bool, bool>(async(profile, region, projectPath, saveCdkProject, diagnostics) =>
            {
                var toolInteractiveService = new ConsoleInteractiveServiceImpl(diagnostics);

                try
                {
                    var orchestratorInteractiveService = new ConsoleOrchestratorLogger(toolInteractiveService);

                    var previousSettings = PreviousDeploymentSettings.ReadSettings(projectPath, null);

                    var awsUtilities   = new AWSUtilities(toolInteractiveService);
                    var awsCredentials = await awsUtilities.ResolveAWSCredentials(profile, previousSettings.Profile);
                    var awsRegion      = awsUtilities.ResolveAWSRegion(region, previousSettings.Region);

                    var commandLineWrapper =
                        new CommandLineWrapper(
                            orchestratorInteractiveService,
                            awsCredentials,
                            awsRegion);

                    var directoryManager     = new DirectoryManager();
                    var fileManager          = new FileManager();
                    var packageJsonGenerator = new PackageJsonGenerator(
                        typeof(PackageJsonGenerator).Assembly
                        .ReadEmbeddedFile(PackageJsonGenerator.TemplateIdentifier));
                    var npmPackageInitializer = new NPMPackageInitializer(commandLineWrapper, packageJsonGenerator, fileManager, directoryManager);
                    var cdkInstaller          = new CDKInstaller(commandLineWrapper);
                    var cdkManager            = new CDKManager(cdkInstaller, npmPackageInitializer);

                    var systemCapabilityEvaluator = new SystemCapabilityEvaluator(commandLineWrapper, cdkManager);
                    var systemCapabilities        = systemCapabilityEvaluator.Evaluate();

                    var stsClient      = new AmazonSecurityTokenServiceClient(awsCredentials);
                    var callerIdentity = await stsClient.GetCallerIdentityAsync(new GetCallerIdentityRequest());

                    var session = new OrchestratorSession
                    {
                        AWSProfileName     = profile,
                        AWSCredentials     = awsCredentials,
                        AWSRegion          = awsRegion,
                        AWSAccountId       = callerIdentity.Account,
                        ProjectPath        = projectPath,
                        ProjectDirectory   = projectPath,
                        SystemCapabilities = systemCapabilities,
                        CdkManager         = cdkManager
                    };

                    var awsResourceQueryer = new AWSResourceQueryer(new DefaultAWSClientFactory());
                    var zipFileManager     = new ZipFileManager(commandLineWrapper);

                    var deploy = new DeployCommand(
                        toolInteractiveService,
                        orchestratorInteractiveService,
                        new CdkProjectHandler(orchestratorInteractiveService, commandLineWrapper),
                        new DeploymentBundleHandler(session, commandLineWrapper, awsResourceQueryer, orchestratorInteractiveService, directoryManager, zipFileManager),
                        awsResourceQueryer,
                        session);

                    await deploy.ExecuteAsync(saveCdkProject);

                    return(CommandReturnCodes.SUCCESS);
                }
                catch (Exception e) when(e.IsAWSDeploymentExpectedException())
                {
                    // helpful error message should have already been presented to the user,
                    // bail out with an non-zero return code.
                    return(CommandReturnCodes.USER_ERROR);
                }
                catch (Exception e)
                {
                    // This is a bug
                    toolInteractiveService.WriteErrorLine(
                        "Unhandled exception.  This is a bug.  Please copy the stack trace below and file a bug at https://github.com/aws/aws-dotnet-deploy. " +
                        e.PrettyPrint());

                    return(CommandReturnCodes.UNHANDLED_EXCEPTION);
                }
            });
            rootCommand.Add(deployCommand);

            var listCommand = new Command("list-deployments", "List existing deployments.")
            {
                _optionProfile,
                _optionRegion,
                _optionProjectPath,
                _optionDiagnosticLogging
            };

            listCommand.Handler = CommandHandler.Create <string, string, string, bool>(async(profile, region, projectPath, diagnostics) =>
            {
                var toolInteractiveService         = new ConsoleInteractiveServiceImpl(diagnostics);
                var orchestratorInteractiveService = new ConsoleOrchestratorLogger(toolInteractiveService);

                var awsUtilities = new AWSUtilities(toolInteractiveService);

                var previousSettings = PreviousDeploymentSettings.ReadSettings(projectPath, null);

                var awsCredentials = await awsUtilities.ResolveAWSCredentials(profile, previousSettings.Profile);
                var awsRegion      = awsUtilities.ResolveAWSRegion(region, previousSettings.Region);

                var stsClient      = new AmazonSecurityTokenServiceClient(awsCredentials);
                var callerIdentity = await stsClient.GetCallerIdentityAsync(new GetCallerIdentityRequest());

                var session = new OrchestratorSession
                {
                    AWSProfileName   = profile,
                    AWSCredentials   = awsCredentials,
                    AWSRegion        = awsRegion,
                    AWSAccountId     = callerIdentity.Account,
                    ProjectPath      = projectPath,
                    ProjectDirectory = projectPath
                };

                var commandLineWrapper =
                    new CommandLineWrapper(
                        orchestratorInteractiveService,
                        awsCredentials,
                        awsRegion);

                var awsResourceQueryer = new AWSResourceQueryer(new DefaultAWSClientFactory());
                var directoryManager   = new DirectoryManager();
                var zipFileManager     = new ZipFileManager(commandLineWrapper);

                await new ListDeploymentsCommand(toolInteractiveService,
                                                 new ConsoleOrchestratorLogger(toolInteractiveService),
                                                 new CdkProjectHandler(orchestratorInteractiveService, commandLineWrapper),
                                                 new DeploymentBundleHandler(session, commandLineWrapper, awsResourceQueryer, orchestratorInteractiveService, directoryManager, zipFileManager),
                                                 awsResourceQueryer,
                                                 session).ExecuteAsync();
            });
            rootCommand.Add(listCommand);

            var deleteCommand = new Command("delete-deployment", "Delete an existing deployment.")
            {
                _optionProfile,
                _optionRegion,
                _optionProjectPath,
                _optionDiagnosticLogging,
                new Argument("deployment-name")
            };

            deleteCommand.Handler = CommandHandler.Create <string, string, string, string, bool>(async(profile, region, projectPath, deploymentName, diagnostics) =>
            {
                var toolInteractiveService = new ConsoleInteractiveServiceImpl(diagnostics);
                var awsUtilities           = new AWSUtilities(toolInteractiveService);

                var previousSettings = PreviousDeploymentSettings.ReadSettings(projectPath, null);

                var awsCredentials = await awsUtilities.ResolveAWSCredentials(profile, previousSettings.Profile);
                var awsRegion      = awsUtilities.ResolveAWSRegion(region, previousSettings.Region);

                var session = new OrchestratorSession
                {
                    AWSProfileName = profile,
                    AWSCredentials = awsCredentials,
                    AWSRegion      = awsRegion,
                };

                await new DeleteDeploymentCommand(new DefaultAWSClientFactory(), toolInteractiveService, session).ExecuteAsync(deploymentName);

                return(CommandReturnCodes.SUCCESS);
            });
            rootCommand.Add(deleteCommand);

            // if user didn't specify a command, default to help
            if (args.Length == 0)
            {
                args = new string[] { "-h" };
            }

            return(await rootCommand.InvokeAsync(args));
        }