Example #1
0
        public void LogVariables()
        {
            string ToString(bool useRawValue)
            {
                var text = new StringBuilder();

                var namesToPrint = variables.GetNames().Where(name => !name.Contains("CustomScripts.")).OrderBy(name => name);

                foreach (var name in namesToPrint)
                {
                    var value = useRawValue ? variables.GetRaw(name) : variables.Get(name);
                    text.AppendLine($"[{name}] = '{value}'");
                }

                return(text.ToString());
            }

            if (variables.GetFlag(KnownVariables.PrintVariables))
            {
                log.Warn($"{KnownVariables.PrintVariables} is enabled. This should only be used for debugging problems with variables, and then disabled again for normal deployments.");
                log.Verbose("The following variables are available:" + Environment.NewLine + ToString(true));
            }

            if (variables.GetFlag(KnownVariables.PrintEvaluatedVariables))
            {
                log.Warn($"{KnownVariables.PrintEvaluatedVariables} is enabled. This should only be used for debugging problems with variables, and then disabled again for normal deployments.");
                log.Verbose("The following evaluated variables are available:" + Environment.NewLine + ToString(false));
            }
        }
Example #2
0
        public void DoTransforms(string currentDirectory)
        {
            var explicitTransforms  = GetExplicitTransforms();
            var automaticTransforms = GetAutomaticTransforms();
            var sourceExtensions    = GetSourceExtensions(explicitTransforms);

            var allTransforms = explicitTransforms.Concat(automaticTransforms).ToList();
            var transformDefinitionsApplied   = new List <XmlConfigTransformDefinition>();
            var duplicateTransformDefinitions = new List <XmlConfigTransformDefinition>();
            var transformFilesApplied         = new HashSet <Tuple <string, string> >();
            var diagnosticLoggingEnabled      = variables.GetFlag(KnownVariables.Package.EnableDiagnosticsConfigTransformationLogging);

            if (diagnosticLoggingEnabled)
            {
                log.Verbose($"Recursively searching for transformation files that match {string.Join(" or ", sourceExtensions)} in folder '{currentDirectory}'");
            }
            foreach (var configFile in MatchingFiles(currentDirectory, sourceExtensions))
            {
                if (diagnosticLoggingEnabled)
                {
                    log.Verbose($"Found config file '{configFile}'");
                }
                ApplyTransformations(configFile, allTransforms, transformFilesApplied,
                                     transformDefinitionsApplied, duplicateTransformDefinitions, diagnosticLoggingEnabled, currentDirectory);
            }

            LogFailedTransforms(explicitTransforms, automaticTransforms, transformDefinitionsApplied, duplicateTransformDefinitions, diagnosticLoggingEnabled);
            variables.SetStrings(KnownVariables.AppliedXmlConfigTransforms, transformFilesApplied.Select(t => t.Item1), "|");
        }
Example #3
0
        public static ConfigurationTransformer FromVariables(IVariables variables, ILog log = null)
        {
            var treatConfigTransformationWarningsAsErrors = variables.GetFlag(SpecialVariables.Package.TreatConfigTransformationWarningsAsErrors, true);
            var ignoreConfigTransformErrors    = variables.GetFlag(SpecialVariables.Package.IgnoreConfigTransformationErrors);
            var suppressConfigTransformLogging = variables.GetFlag(SpecialVariables.Package.SuppressConfigTransformationLogging);

            var transformLoggingOptions = TransformLoggingOptions.None;

            if (treatConfigTransformationWarningsAsErrors)
            {
                transformLoggingOptions |= TransformLoggingOptions.LogWarningsAsErrors;
            }

            if (ignoreConfigTransformErrors)
            {
                transformLoggingOptions |= TransformLoggingOptions.LogExceptionsAsWarnings;
                transformLoggingOptions |= TransformLoggingOptions.LogWarningsAsInfo;
                transformLoggingOptions &= ~TransformLoggingOptions.LogWarningsAsErrors;
            }

            if (suppressConfigTransformLogging)
            {
                transformLoggingOptions |= TransformLoggingOptions.DoNotLogVerbose;
            }

            return(new ConfigurationTransformer(transformLoggingOptions, log));
        }
Example #4
0
        private static DeploymentSyncOptions DeploymentSyncOptions(IVariables variables)
        {
            var syncOptions = new DeploymentSyncOptions
            {
                WhatIf      = false,
                UseChecksum = variables.GetFlag(SpecialVariables.Action.Azure.UseChecksum),
                DoNotDelete = !variables.GetFlag(SpecialVariables.Action.Azure.RemoveAdditionalFiles),
            };

            ApplyAppOfflineDeploymentRule(syncOptions, variables);
            ApplyPreserveAppDataDeploymentRule(syncOptions, variables);
            ApplyPreservePathsDeploymentRule(syncOptions, variables);
            return(syncOptions);
        }
        static Dictionary <string, string> GoogleCloudEnvironmentVariables(IVariables variables)
        {
            // See https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#full-reference
            var googleCloudEnvironmentVariables = new Dictionary <string, string>();
            var useVmServiceAccount             = variables.GetFlag("Octopus.Action.GoogleCloud.UseVMServiceAccount");
            var account = variables.Get("Octopus.Action.GoogleCloudAccount.Variable")?.Trim();
            var keyFile = variables.Get($"{account}.JsonKey")?.Trim() ?? variables.Get("Octopus.Action.GoogleCloudAccount.JsonKey")?.Trim();

            if (!useVmServiceAccount && !string.IsNullOrEmpty(keyFile))
            {
                var bytes = Convert.FromBase64String(keyFile);
                var json  = Encoding.UTF8.GetString(bytes);
                googleCloudEnvironmentVariables.Add("GOOGLE_CLOUD_KEYFILE_JSON", json);
                Log.Verbose($"A JSON key has been set to GOOGLE_CLOUD_KEYFILE_JSON environment variable");
            }

            var impersonateServiceAccount = variables.GetFlag("Octopus.Action.GoogleCloud.ImpersonateServiceAccount");

            if (impersonateServiceAccount)
            {
                var serviceAccountEmails = variables.Get("Octopus.Action.GoogleCloud.ServiceAccountEmails") ?? string.Empty;
                googleCloudEnvironmentVariables.Add("GOOGLE_IMPERSONATE_SERVICE_ACCOUNT", serviceAccountEmails);
                Log.Verbose($"{serviceAccountEmails} has been set to GOOGLE_IMPERSONATE_SERVICE_ACCOUNT environment variable");
            }

            var project = variables.Get("Octopus.Action.GoogleCloud.Project")?.Trim();
            var region  = variables.Get("Octopus.Action.GoogleCloud.Region")?.Trim();
            var zone    = variables.Get("Octopus.Action.GoogleCloud.Zone")?.Trim();

            if (!string.IsNullOrEmpty(project))
            {
                googleCloudEnvironmentVariables.Add("GOOGLE_PROJECT", project);
                Log.Verbose($"{project} has been set to GOOGLE_PROJECT environment variable");
            }

            if (!string.IsNullOrEmpty(region))
            {
                googleCloudEnvironmentVariables.Add("GOOGLE_REGION", region);
                Log.Verbose($"{region} has been set to GOOGLE_REGION environment variable");
            }

            if (!string.IsNullOrEmpty(zone))
            {
                googleCloudEnvironmentVariables.Add("GOOGLE_ZONE", zone);
                Log.Verbose($"{zone} has been set to GOOGLE_ZONE environment variable");
            }

            return(googleCloudEnvironmentVariables);
        }
Example #6
0
        public void ReplaceVariables(string currentDirectory, List <string> targets)
        {
            var onlyPerformJsonReplacement = variables.GetFlag(ActionVariables.StructuredConfigurationFallbackFlag);

            foreach (var target in targets)
            {
                if (fileSystem.DirectoryExists(target))
                {
                    log.Warn($"Skipping structured variable replacement on '{target}' because it is a directory.");
                    continue;
                }

                var matchingFiles = MatchingFiles(currentDirectory, target);

                if (!matchingFiles.Any())
                {
                    log.Warn($"No files were found that match the replacement target pattern '{target}'");
                    continue;
                }

                foreach (var filePath in matchingFiles)
                {
                    var replacersToTry = GetReplacersToTryForFile(filePath, onlyPerformJsonReplacement).ToArray();

                    log.Verbose($"The registered replacers we will try, in order, are: " + string.Join(",", replacersToTry.Select(r => r.GetType().Name)));

                    DoReplacement(filePath, variables, replacersToTry);
                }
            }
        }
        string[] GetFilesToSubstitute(IVariables variables)
        {
            var isEnableNoMatchWarningSet   = variables.IsSet(PackageVariables.EnableNoMatchWarning);
            var additionalFileSubstitutions = GetAdditionalFileSubstitutions(variables);

            if (!isEnableNoMatchWarningSet)
            {
                var hasAdditionalSubstitutions = !string.IsNullOrEmpty(additionalFileSubstitutions);
                variables.AddFlag(PackageVariables.EnableNoMatchWarning, hasAdditionalSubstitutions);
            }

            var result = new List <string>();

            var runAutomaticFileSubstitution = variables.GetFlag(TerraformSpecialVariables.Action.Terraform.RunAutomaticFileSubstitution, true);

            if (runAutomaticFileSubstitution)
            {
                result.AddRange(new[] { "**/*.tf", "**/*.tf.json", "**/*.tfvars", "**/*.tfvars.json" });
            }

            var additionalFileSubstitution = additionalFileSubstitutions;

            if (!string.IsNullOrWhiteSpace(additionalFileSubstitution))
            {
                result.AddRange(additionalFileSubstitution.Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries));
            }

            return(result.ToArray());
        }
Example #8
0
        public override int Execute(string[] commandLineArguments)
        {
            Options.Parse(commandLineArguments);

            var configurationTransformer = ConfigurationTransformer.FromVariables(variables);
            var transformFileLocator     = new TransformFileLocator(fileSystem);
            var replacer             = new ConfigurationVariablesReplacer(variables.GetFlag(SpecialVariables.Package.IgnoreVariableReplacementErrors));
            var jsonVariableReplacer = new JsonConfigurationVariableReplacer();

            ValidateArguments();
            WriteVariableScriptToFile();

            var conventions = new List <IConvention>
            {
                new StageScriptPackagesConvention(packageFile, fileSystem, new CombinedPackageExtractor(log)),
                // Substitute the script source file
                new DelegateInstallConvention(d => substituteInFiles.Substitute(d, ScriptFileTargetFactory(d).ToList())),
                // Substitute any user-specified files
                new DelegateInstallConvention(d => substituteInFiles.SubstituteBasedSettingsInSuppliedVariables(d)),
                new ConfigurationTransformsConvention(fileSystem, configurationTransformer, transformFileLocator),
                new ConfigurationVariablesConvention(fileSystem, replacer),
                new JsonConfigurationVariablesConvention(jsonVariableReplacer, fileSystem),
                new ExecuteScriptConvention(scriptEngine, commandLineRunner)
            };

            var deployment       = new RunningDeployment(packageFile, variables);
            var conventionRunner = new ConventionProcessor(deployment, conventions);

            conventionRunner.RunConventions();
            var exitCode = variables.GetInt32(SpecialVariables.Action.Script.ExitCode);

            deploymentJournalWriter.AddJournalEntry(deployment, exitCode == 0, packageFile);
            return(exitCode.Value);
        }
Example #9
0
        public override int Execute(string[] commandLineArguments)
        {
            Options.Parse(commandLineArguments);

            Guard.NotNullOrWhiteSpace(pathToPackage, "No package file was specified. Please pass --package YourPackage.nupkg");

            if (!File.Exists(pathToPackage))
            {
                throw new CommandException("Could not find package file: " + pathToPackage);
            }

            Log.Info("Deploying package:    " + pathToPackage);

            var account = new AzureAccount(variables);

            var fileSystem                         = new WindowsPhysicalFileSystem();
            var embeddedResources                  = new AssemblyEmbeddedResources();
            var azurePackageUploader               = new AzurePackageUploader(log);
            var certificateStore                   = new CalamariCertificateStore();
            var cloudCredentialsFactory            = new SubscriptionCloudCredentialsFactory(certificateStore);
            var cloudServiceConfigurationRetriever = new AzureCloudServiceConfigurationRetriever();
            var configurationTransformer           = ConfigurationTransformer.FromVariables(variables);
            var transformFileLocator               = new TransformFileLocator(fileSystem);
            var replacer = new ConfigurationVariablesReplacer(variables.GetFlag(SpecialVariables.Package.IgnoreVariableReplacementErrors));
            var jsonVariablesReplacer = new JsonConfigurationVariableReplacer();

            var conventions = new List <IConvention>
            {
                new SwapAzureDeploymentConvention(fileSystem, embeddedResources, scriptEngine, commandLineRunner),
                new DelegateInstallConvention(d => extractPackage.ExtractToStagingDirectory(pathToPackage)),
                new FindCloudServicePackageConvention(fileSystem),
                new EnsureCloudServicePackageIsCtpFormatConvention(fileSystem),
                new ExtractAzureCloudServicePackageConvention(log, fileSystem),
                new ChooseCloudServiceConfigurationFileConvention(fileSystem),
                new ConfiguredScriptConvention(DeploymentStages.PreDeploy, fileSystem, scriptEngine, commandLineRunner),
                new PackagedScriptConvention(log, DeploymentStages.PreDeploy, fileSystem, scriptEngine, commandLineRunner),
                new ConfigureAzureCloudServiceConvention(account, fileSystem, cloudCredentialsFactory, cloudServiceConfigurationRetriever, certificateStore),
                new DelegateInstallConvention(d => substituteInFiles.SubstituteBasedSettingsInSuppliedVariables(d)),
                new ConfigurationTransformsConvention(fileSystem, configurationTransformer, transformFileLocator),
                new ConfigurationVariablesConvention(fileSystem, replacer),
                new JsonConfigurationVariablesConvention(jsonVariablesReplacer, fileSystem),
                new PackagedScriptConvention(log, DeploymentStages.Deploy, fileSystem, scriptEngine, commandLineRunner),
                new ConfiguredScriptConvention(DeploymentStages.Deploy, fileSystem, scriptEngine, commandLineRunner),
                new RePackageCloudServiceConvention(fileSystem),
                new UploadAzureCloudServicePackageConvention(fileSystem, azurePackageUploader, cloudCredentialsFactory),
                new DeployAzureCloudServicePackageConvention(fileSystem, embeddedResources, scriptEngine, commandLineRunner),
                new PackagedScriptConvention(log, DeploymentStages.PostDeploy, fileSystem, scriptEngine, commandLineRunner),
                new ConfiguredScriptConvention(DeploymentStages.PostDeploy, fileSystem, scriptEngine, commandLineRunner)
            };

            var deployment       = new RunningDeployment(pathToPackage, variables);
            var conventionRunner = new ConventionProcessor(deployment, conventions);

            conventionRunner.RunConventions();

            return(0);
        }
Example #10
0
        void ImportCertificate()
        {
            var certificateVariable  = GetMandatoryVariable(variables, SpecialVariables.Action.Certificate.CertificateVariable);
            var pfxBytes             = Convert.FromBase64String(GetMandatoryVariable(variables, $"{certificateVariable}.{CertificateVariables.Properties.Pfx}"));
            var password             = variables.Get($"{certificateVariable}.{CertificateVariables.Properties.Password}");
            var thumbprint           = variables.Get($"{certificateVariable}.{CertificateVariables.Properties.Thumbprint}");
            var storeName            = GetMandatoryVariable(variables, SpecialVariables.Action.Certificate.StoreName);
            var privateKeyExportable = variables.GetFlag(SpecialVariables.Action.Certificate.PrivateKeyExportable, false);

            // Either a store-location (LocalMachine or CurrentUser) or a user can be supplied
            StoreLocation storeLocation;
            var           locationSpecified = Enum.TryParse(variables.Get(SpecialVariables.Action.Certificate.StoreLocation), out storeLocation);

            ValidateStore(locationSpecified ? (StoreLocation?)storeLocation : null, storeName);

            try
            {
                if (locationSpecified)
                {
                    Log.Info(
                        $"Importing certificate '{variables.Get($"{certificateVariable}.{CertificateVariables.Properties.Subject}")}' with thumbprint '{thumbprint}' into store '{storeLocation}\\{storeName}'");
                    WindowsX509CertificateStore.ImportCertificateToStore(pfxBytes, password, storeLocation, storeName,
                                                                         privateKeyExportable);

                    if (storeLocation == StoreLocation.LocalMachine)
                    {
                        // Set private-key access
                        var privateKeyAccessRules = GetPrivateKeyAccessRules(variables);
                        if (privateKeyAccessRules.Any())
                        {
                            WindowsX509CertificateStore.AddPrivateKeyAccessRules(thumbprint, storeLocation, storeName,
                                                                                 privateKeyAccessRules);
                        }
                    }
                }
                else // Import into a specific user's store
                {
                    var storeUser = variables.Get(SpecialVariables.Action.Certificate.StoreUser);

                    if (string.IsNullOrWhiteSpace(storeUser))
                    {
                        throw new CommandException(
                                  $"Either '{SpecialVariables.Action.Certificate.StoreLocation}' or '{SpecialVariables.Action.Certificate.StoreUser}' must be supplied");
                    }

                    Log.Info(
                        $"Importing certificate '{variables.Get($"{certificateVariable}.{CertificateVariables.Properties.Subject}")}' with thumbprint '{thumbprint}' into store '{storeName}' for user '{storeUser}'");
                    WindowsX509CertificateStore.ImportCertificateToStore(pfxBytes, password, storeUser, storeName,
                                                                         privateKeyExportable);
                }
            }
            catch (Exception)
            {
                Log.Error("There was an error importing the certificate into the store");
                throw;
            }
        }
Example #11
0
        void UpdateConfigurationWithCurrentInstanceCount(XContainer localConfigurationFile, string configurationFileName, IVariables variables)
        {
            if (!variables.GetFlag(SpecialVariables.Action.Azure.UseCurrentInstanceCount))
            {
                return;
            }

            var serviceName = variables.Get(SpecialVariables.Action.Azure.CloudServiceName);
            var slot        = (DeploymentSlot)Enum.Parse(typeof(DeploymentSlot), variables.Get(SpecialVariables.Action.Azure.Slot));

            var remoteConfigurationFile = configurationRetriever.GetConfiguration(
                certificateStore,
                account,
                serviceName,
                slot);

            if (remoteConfigurationFile == null)
            {
                Log.Info("There is no current deployment of service '{0}' in slot '{1}', so existing instance counts will not be imported.", serviceName, slot);
                return;
            }

            var rolesByCount = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            Log.Verbose("Local instance counts (from " + Path.GetFileName(configurationFileName) + "): ");
            WithInstanceCounts(localConfigurationFile, (roleName, attribute) =>
            {
                Log.Verbose(" - " + roleName + " = " + attribute.Value);

                string value;
                if (rolesByCount.TryGetValue(roleName, out value))
                {
                    attribute.SetValue(value);
                }
            });

            Log.Verbose("Remote instance counts: ");
            WithInstanceCounts(remoteConfigurationFile, (roleName, attribute) =>
            {
                rolesByCount[roleName] = attribute.Value;
                Log.Verbose(" - " + roleName + " = " + attribute.Value);
            });

            Log.Verbose("Replacing local instance count settings with remote settings: ");
            WithInstanceCounts(localConfigurationFile, (roleName, attribute) =>
            {
                string value;
                if (!rolesByCount.TryGetValue(roleName, out value))
                {
                    return;
                }

                attribute.SetValue(value);
                Log.Verbose(" - " + roleName + " = " + attribute.Value);
            });
        }
Example #12
0
        public void Dispose()
        {
            var attachLogFile = variables.GetFlag(TerraformSpecialVariables.Action.Terraform.AttachLogFile);

            if (attachLogFile)
            {
                var crashLogPath = Path.Combine(deployment.CurrentDirectory, "crash.log");

                if (fileSystem.FileExists(logPath))
                {
                    log.NewOctopusArtifact(fileSystem.GetFullPath(logPath), fileSystem.GetFileName(logPath), fileSystem.GetFileSize(logPath));
                }

                //When terraform crashes, the information would be contained in the crash.log file. We should attach this since
                //we don't want to blow that information away in case it provides something relevant https://www.terraform.io/docs/internals/debugging.html#interpreting-a-crash-log
                if (fileSystem.FileExists(crashLogPath))
                {
                    log.NewOctopusArtifact(fileSystem.GetFullPath(crashLogPath), fileSystem.GetFileName(crashLogPath), fileSystem.GetFileSize(crashLogPath));
                }
            }
        }
Example #13
0
 private static void ApplyPreserveAppDataDeploymentRule(DeploymentSyncOptions syncOptions,
                                                        IVariables variables)
 {
     // If PreserveAppData variable set, then create SkipDelete rules for App_Data directory
     // ReSharper disable once InvertIf
     if (variables.GetFlag(SpecialVariables.Action.Azure.PreserveAppData))
     {
         syncOptions.Rules.Add(new DeploymentSkipRule("SkipDeleteDataFiles", "Delete", "filePath",
                                                      "\\\\App_Data\\\\.*", null));
         syncOptions.Rules.Add(new DeploymentSkipRule("SkipDeleteDataDir", "Delete", "dirPath",
                                                      "\\\\App_Data(\\\\.*|$)", null));
     }
 }
Example #14
0
        public void SubstituteBasedSettingsInSuppliedVariables(RunningDeployment deployment)
        {
            var substituteInFilesEnabled = variables.GetFlag(PackageVariables.SubstituteInFilesEnabled);

            if (!substituteInFilesEnabled)
            {
                return;
            }

            var filesToTarget = variables.GetPaths(PackageVariables.SubstituteInFilesTargets);

            Substitute(deployment, filesToTarget);
        }
Example #15
0
        public override int Execute(string[] commandLineArguments)
        {
            Options.Parse(commandLineArguments);

            var runner = new CommandLineRunner(ConsoleLog.Instance, variables);

            Log.VerboseFormat("Executing '{0}'", scriptFile);
            var result = scriptEngine.Execute(new Script(scriptFile, ""), variables, runner);

            if (result.ExitCode == 0 && result.HasErrors && variables.GetFlag(SpecialVariables.Action.FailScriptOnErrorOutput, false))
            {
                return(-1);
            }

            return(result.ExitCode);
        }
Example #16
0
 private static void ApplyAppOfflineDeploymentRule(DeploymentSyncOptions syncOptions,
                                                   IVariables variables)
 {
     // ReSharper disable once InvertIf
     if (variables.GetFlag(SpecialVariables.Action.Azure.AppOffline))
     {
         var rules = Microsoft.Web.Deployment.DeploymentSyncOptions.GetAvailableRules();
         if (rules.TryGetValue("AppOffline", out var rule))
         {
             syncOptions.Rules.Add(rule);
         }
         else
         {
             Log.Verbose("Azure Deployment API does not support `AppOffline` deployment rule.");
         }
     }
 }
Example #17
0
        public override int Execute(string[] commandLineArguments)
        {
            Options.Parse(commandLineArguments);

            Guard.NotNullOrWhiteSpace(pathToPackage,
                                      "No package file was specified. Please pass --package YourPackage.nupkg");

            if (!File.Exists(pathToPackage))
            {
                throw new CommandException("Could not find package file: " + pathToPackage);
            }

            Log.Info("Deploying package:    " + pathToPackage);

            var fileSystem               = new WindowsPhysicalFileSystem();
            var replacer                 = new ConfigurationVariablesReplacer(variables.GetFlag(SpecialVariables.Package.IgnoreVariableReplacementErrors));
            var jsonReplacer             = new JsonConfigurationVariableReplacer();
            var configurationTransformer = ConfigurationTransformer.FromVariables(variables);
            var transformFileLocator     = new TransformFileLocator(fileSystem);

            var conventions = new List <IConvention>
            {
                new DelegateInstallConvention(d => extractPackage.ExtractToStagingDirectory(pathToPackage)),
                new ConfiguredScriptConvention(DeploymentStages.PreDeploy, fileSystem, scriptEngine, commandLineRunner),
                new PackagedScriptConvention(log, DeploymentStages.PreDeploy, fileSystem, scriptEngine, commandLineRunner),
                new DelegateInstallConvention(d => substituteInFiles.SubstituteBasedSettingsInSuppliedVariables(d)),
                new ConfigurationTransformsConvention(fileSystem, configurationTransformer, transformFileLocator),
                new ConfigurationVariablesConvention(fileSystem, replacer),
                new JsonConfigurationVariablesConvention(jsonReplacer, fileSystem),
                new PackagedScriptConvention(log, DeploymentStages.Deploy, fileSystem, scriptEngine, commandLineRunner),
                new ConfiguredScriptConvention(DeploymentStages.Deploy, fileSystem, scriptEngine, commandLineRunner),
                new AzureWebAppConvention(log),
                new LogAzureWebAppDetails(log),
                new PackagedScriptConvention(log, DeploymentStages.PostDeploy, fileSystem, scriptEngine, commandLineRunner),
                new ConfiguredScriptConvention(DeploymentStages.PostDeploy, fileSystem, scriptEngine, commandLineRunner),
            };

            var deployment       = new RunningDeployment(pathToPackage, variables);
            var conventionRunner = new ConventionProcessor(deployment, conventions);

            conventionRunner.RunConventions();

            return(0);
        }
Example #18
0
        string[] GetFilesToSubstitute()
        {
            var result = new List <string>();

            var runAutomaticFileSubstitution = variables.GetFlag(TerraformSpecialVariables.Action.Terraform.RunAutomaticFileSubstitution, true);

            if (runAutomaticFileSubstitution)
            {
                result.AddRange(new[] { "**/*.tf", "**/*.tf.json", "**/*.tfvars", "**/*.tfvars.json" });
            }

            var additionalFileSubstitution = GetAdditionalFileSubstitutions();

            if (!string.IsNullOrWhiteSpace(additionalFileSubstitution))
            {
                result.AddRange(additionalFileSubstitution.Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries));
            }

            return(result.ToArray());
        }
Example #19
0
        public void EnsureDiskHasEnoughFreeSpace(string directoryPath)
        {
            if (CalamariEnvironment.IsRunningOnMono && CalamariEnvironment.IsRunningOnMac)
            {
                //After upgrading to macOS 10.15.2, and mono 5.14.0, drive.TotalFreeSpace and drive.AvailableFreeSpace both started returning 0.
                //see https://github.com/mono/mono/issues/17151, which was fixed in mono 6.4.xx
                //If we upgrade mono past 5.14.x, scriptcs stops working.
                //Rock and a hard place.
                Log.Verbose("Unable to determine disk free space under Mono on macOS. Assuming there's enough.");
                return;
            }

            if (variables.GetFlag(skipFreeDiskSpaceCheckVariable))
            {
                Log.Verbose($"{skipFreeDiskSpaceCheckVariable} is enabled. The check to ensure that the drive containing the directory '{directoryPath}' on machine '{Environment.MachineName}' has enough free space will be skipped.");
                return;
            }

            ulong requiredSpaceInBytes         = 500L * 1024 * 1024;
            var   freeSpaceOverrideInMegaBytes = variables.GetInt32(freeDiskSpaceOverrideInMegaBytesVariable);

            if (freeSpaceOverrideInMegaBytes.HasValue)
            {
                requiredSpaceInBytes = (ulong)freeSpaceOverrideInMegaBytes * 1024 * 1024;
                Log.Verbose($"{freeDiskSpaceOverrideInMegaBytesVariable} has been specified. We will check and ensure that the drive containing the directory '{directoryPath}' on machine '{Environment.MachineName}' has {((ulong) requiredSpaceInBytes).ToFileSizeString()} free disk space.");
            }

            var success = fileSystem.GetDiskFreeSpace(directoryPath, out ulong totalNumberOfFreeBytes);

            if (!success)
            {
                return;
            }

            if (totalNumberOfFreeBytes < requiredSpaceInBytes)
            {
                throw new CommandException($"The drive containing the directory '{directoryPath}' on machine '{Environment.MachineName}' does not have enough free disk space available for this operation to proceed. The disk only has {totalNumberOfFreeBytes.ToFileSizeString()} available; please free up at least {requiredSpaceInBytes.ToFileSizeString()}.");
            }
        }
Example #20
0
        public override int Execute(string[] commandLineArguments)
        {
            Options.Parse(commandLineArguments);

            var contents = variables.Get(SpecialVariables.Execution.Manifest);

            if (contents == null)
            {
                throw new CommandException("Execution manifest not found in variables.");
            }

            var instructions =
                JsonConvert.DeserializeObject <Instruction[]>(contents,
                                                              JsonSerialization.GetDefaultSerializerSettings());

            if (instructions.Length == 0)
            {
                throw new CommandException("The execution manifest must have at least one instruction.");
            }

            foreach (var instruction in instructions)
            {
                var tool = executionTools.First(x => x.Metadata.Tool == instruction.Launcher);

                var result = tool.Value.Execute(instruction.LauncherInstructionsRaw);

                if (result != 0)
                {
                    return(result);
                }

                if (variables.GetFlag(KnownVariables.Action.SkipRemainingConventions))
                {
                    break;
                }
            }

            return(0);
        }
Example #21
0
        public void DoTransforms(string currentDirectory)
        {
            var appliedAsTransforms = variables.GetStrings(KnownVariables.AppliedXmlConfigTransforms, '|');

            log.Verbose("Looking for appSettings, applicationSettings, and connectionStrings in any .config files");

            if (variables.GetFlag(KnownVariables.Package.IgnoreVariableReplacementErrors))
            {
                log.Info("Variable replacement errors are suppressed because the variable Octopus.Action.Package.IgnoreVariableReplacementErrors has been set.");
            }

            foreach (var configurationFile in MatchingFiles(currentDirectory))
            {
                if (appliedAsTransforms.Contains(configurationFile))
                {
                    log.VerboseFormat("File '{0}' was interpreted as an XML configuration transform; variable substitution won't be attempted.", configurationFile);
                    continue;
                }

                replacer.ModifyConfigurationFile(configurationFile, variables);
            }
        }
Example #22
0
        public void Substitute(string currentDirectory, IList <string> filesToTarget, bool warnIfFileNotFound = true)
        {
            foreach (var target in filesToTarget)
            {
                var matchingFiles = MatchingFiles(currentDirectory, target);

                if (!matchingFiles.Any())
                {
                    if (warnIfFileNotFound && variables.GetFlag(PackageVariables.EnableNoMatchWarning, true))
                    {
                        log.WarnFormat("No files were found in {0} that match the substitution target pattern '{1}'", currentDirectory, target);
                    }

                    continue;
                }

                foreach (var file in matchingFiles)
                {
                    substituter.PerformSubstitution(file, variables);
                }
            }
        }
Example #23
0
        string BuildParams(NodeInstructions instructions, string sensitiveVariablesFilePath)
        {
            var parameters = new List <string>();
            var debugMode  = variables.GetFlag(DebugVariableName, false);

            if (debugMode)
            {
                parameters.Add("--inspect-brk");
            }

            var pathToBootstrapperFolder = variables.Get(instructions.BootstrapperPathVariable);
            var pathToBootstrapper       = Path.Combine(pathToBootstrapperFolder, "bootstrapper.js");

            parameters.Add(pathToBootstrapper);
            parameters.Add(instructions.BootstrapperInvocationCommand);
            var pathToStepPackage = variables.Get(instructions.TargetPathVariable);

            parameters.Add(pathToStepPackage);
            parameters.Add(sensitiveVariablesFilePath);
            parameters.Add(options.InputVariables.SensitiveVariablesPassword);
            parameters.Add(AesEncryption.SaltRaw);
            if (string.Equals(instructions.BootstrapperInvocationCommand, "Execute", StringComparison.OrdinalIgnoreCase))
            {
                parameters.Add(instructions.InputsVariable);
                parameters.Add(instructions.DeploymentTargetInputsVariable);
            }
            else if (string.Equals(instructions.BootstrapperInvocationCommand, "Discover", StringComparison.OrdinalIgnoreCase))
            {
                parameters.Add(instructions.TargetDiscoveryContextVariable);
            }
            else
            {
                throw new CommandException($"Unknown bootstrapper invocation command: '{instructions.BootstrapperInvocationCommand}'");
            }

            return(string.Join(" ", parameters.Select(p => $"\"{p}\"")));
        }
        public override int Execute(string[] commandLineArguments)
        {
            Options.Parse(commandLineArguments);

            Guard.NotNullOrWhiteSpace(archiveFile, "No archive file was specified. Please pass --archive YourPackage.jar");
            JavaRuntime.VerifyExists();

            if (!File.Exists(archiveFile))
            {
                throw new CommandException("Could not find archive file: " + archiveFile);
            }

            Log.Info("Deploying:    " + archiveFile);

            var semaphore = SemaphoreFactory.Get();
            var journal   = new DeploymentJournal(fileSystem, semaphore, variables);
            var allFileFormatReplacers           = FileFormatVariableReplacers.BuildAllReplacers(fileSystem, log);
            var structuredConfigVariablesService = new StructuredConfigVariablesService(allFileFormatReplacers, fileSystem, log);
            var jarTools          = new JarTool(commandLineRunner, log, variables);
            var packageExtractor  = new JarPackageExtractor(jarTools);
            var embeddedResources = new AssemblyEmbeddedResources();
            var javaRunner        = new JavaRunner(commandLineRunner, variables);


            var featureClasses = new List <IFeature>
            {
                new TomcatFeature(javaRunner),
                new WildflyFeature(javaRunner)
            };

            var deployExploded = variables.GetFlag(SpecialVariables.Action.Java.DeployExploded);

            var conventions = new List <IConvention>
            {
                new AlreadyInstalledConvention(log, journal),
                // If we are deploying the package exploded then extract directly to the application directory.
                // Else, if we are going to re-pack, then we extract initially to a temporary directory
                deployExploded
                    ? (IInstallConvention) new DelegateInstallConvention(d => extractPackage.ExtractToApplicationDirectory(archiveFile, packageExtractor))
                    : new DelegateInstallConvention(d => extractPackage.ExtractToStagingDirectory(archiveFile, packageExtractor)),
                new FeatureConvention(DeploymentStages.BeforePreDeploy, featureClasses, fileSystem, scriptEngine, commandLineRunner, embeddedResources),
                new ConfiguredScriptConvention(new PreDeployConfiguredScriptBehaviour(log, fileSystem, scriptEngine, commandLineRunner)),
                new PackagedScriptConvention(new PreDeployPackagedScriptBehaviour(log, fileSystem, scriptEngine, commandLineRunner)),
                new FeatureConvention(DeploymentStages.AfterPreDeploy, featureClasses, fileSystem, scriptEngine, commandLineRunner, embeddedResources),
                new SubstituteInFilesConvention(new SubstituteInFilesBehaviour(substituteInFiles)),
                new StructuredConfigurationVariablesConvention(new StructuredConfigurationVariablesBehaviour(structuredConfigVariablesService)),
                new RePackArchiveConvention(log, fileSystem, jarTools),
                new CopyPackageToCustomInstallationDirectoryConvention(fileSystem),
                new FeatureConvention(DeploymentStages.BeforeDeploy, featureClasses, fileSystem, scriptEngine, commandLineRunner, embeddedResources),
                new PackagedScriptConvention(new DeployPackagedScriptBehaviour(log, fileSystem, scriptEngine, commandLineRunner)),
                new ConfiguredScriptConvention(new DeployConfiguredScriptBehaviour(log, fileSystem, scriptEngine, commandLineRunner)),
                new FeatureConvention(DeploymentStages.AfterDeploy, featureClasses, fileSystem, scriptEngine, commandLineRunner, embeddedResources),
                new FeatureConvention(DeploymentStages.BeforePostDeploy, featureClasses, fileSystem, scriptEngine, commandLineRunner, embeddedResources),
                new PackagedScriptConvention(new PostDeployPackagedScriptBehaviour(log, fileSystem, scriptEngine, commandLineRunner)),
                new ConfiguredScriptConvention(new PostDeployConfiguredScriptBehaviour(log, fileSystem, scriptEngine, commandLineRunner)),
                new FeatureConvention(DeploymentStages.AfterPostDeploy, featureClasses, fileSystem, scriptEngine, commandLineRunner, embeddedResources),
                new RollbackScriptConvention(log, DeploymentStages.DeployFailed, fileSystem, scriptEngine, commandLineRunner),
                new FeatureRollbackConvention(DeploymentStages.DeployFailed, fileSystem, scriptEngine, commandLineRunner, embeddedResources)
            };

            var deployment       = new RunningDeployment(archiveFile, variables);
            var conventionRunner = new ConventionProcessor(deployment, conventions, log);

            try
            {
                conventionRunner.RunConventions();
                if (!deployment.SkipJournal)
                {
                    journal.AddJournalEntry(new JournalEntry(deployment, true));
                }
            }
            catch (Exception)
            {
                if (!deployment.SkipJournal)
                {
                    journal.AddJournalEntry(new JournalEntry(deployment, false));
                }
                throw;
            }

            return(0);
        }
Example #25
0
        public override int Execute(string[] commandLineArguments)
        {
            Options.Parse(commandLineArguments);

            Guard.NotNullOrWhiteSpace(pathToPackage, "No package file was specified. Please pass --package YourPackage.nupkg");

            if (!File.Exists(pathToPackage))
            {
                throw new CommandException("Could not find package file: " + pathToPackage);
            }

            Log.Info("Deploying package:    " + pathToPackage);

            var featureClasses = new List <IFeature>();

            var replacer  = new ConfigurationVariablesReplacer(variables.GetFlag(SpecialVariables.Package.IgnoreVariableReplacementErrors));
            var generator = new JsonConfigurationVariableReplacer();
            var configurationTransformer = ConfigurationTransformer.FromVariables(variables);
            var transformFileLocator     = new TransformFileLocator(fileSystem);
            var embeddedResources        = new AssemblyEmbeddedResources();

#if IIS_SUPPORT
            var iis = new InternetInformationServer();
            featureClasses.AddRange(new IFeature[] { new IisWebSiteBeforeDeployFeature(), new IisWebSiteAfterPostDeployFeature() });
#endif
            if (!CalamariEnvironment.IsRunningOnWindows)
            {
                featureClasses.Add(new NginxFeature(NginxServer.AutoDetect(), fileSystem));
            }

            var semaphore = SemaphoreFactory.Get();
            var journal   = new DeploymentJournal(fileSystem, semaphore, variables);

            var conventions = new List <IConvention>
            {
                new AlreadyInstalledConvention(log, journal),
                new DelegateInstallConvention(d => extractPackage.ExtractToApplicationDirectory(pathToPackage)),
                new FeatureConvention(DeploymentStages.BeforePreDeploy, featureClasses, fileSystem, scriptEngine, commandLineRunner, embeddedResources),
                new ConfiguredScriptConvention(DeploymentStages.PreDeploy, fileSystem, scriptEngine, commandLineRunner),
                new PackagedScriptConvention(log, DeploymentStages.PreDeploy, fileSystem, scriptEngine, commandLineRunner),
                new FeatureConvention(DeploymentStages.AfterPreDeploy, featureClasses, fileSystem, scriptEngine, commandLineRunner, embeddedResources),
                new DelegateInstallConvention(d => substituteInFiles.SubstituteBasedSettingsInSuppliedVariables(d)),
                new ConfigurationTransformsConvention(fileSystem, configurationTransformer, transformFileLocator),
                new ConfigurationVariablesConvention(fileSystem, replacer),
                new JsonConfigurationVariablesConvention(generator, fileSystem),
                new CopyPackageToCustomInstallationDirectoryConvention(fileSystem),
                new FeatureConvention(DeploymentStages.BeforeDeploy, featureClasses, fileSystem, scriptEngine, commandLineRunner, embeddedResources),
                new PackagedScriptConvention(log, DeploymentStages.Deploy, fileSystem, scriptEngine, commandLineRunner),
                new ConfiguredScriptConvention(DeploymentStages.Deploy, fileSystem, scriptEngine, commandLineRunner),
                new FeatureConvention(DeploymentStages.AfterDeploy, featureClasses, fileSystem, scriptEngine, commandLineRunner, embeddedResources),
#if IIS_SUPPORT
                new LegacyIisWebSiteConvention(fileSystem, iis),
#endif
                new FeatureConvention(DeploymentStages.BeforePostDeploy, featureClasses, fileSystem, scriptEngine, commandLineRunner, embeddedResources),
                new PackagedScriptConvention(log, DeploymentStages.PostDeploy, fileSystem, scriptEngine, commandLineRunner),
                new ConfiguredScriptConvention(DeploymentStages.PostDeploy, fileSystem, scriptEngine, commandLineRunner),
                new FeatureConvention(DeploymentStages.AfterPostDeploy, featureClasses, fileSystem, scriptEngine, commandLineRunner, embeddedResources),
                new RollbackScriptConvention(log, DeploymentStages.DeployFailed, fileSystem, scriptEngine, commandLineRunner),
                new FeatureRollbackConvention(DeploymentStages.DeployFailed, fileSystem, scriptEngine, commandLineRunner, embeddedResources)
            };

            var deployment       = new RunningDeployment(pathToPackage, variables);
            var conventionRunner = new ConventionProcessor(deployment, conventions);

            try
            {
                conventionRunner.RunConventions();
                if (!deployment.SkipJournal)
                {
                    journal.AddJournalEntry(new JournalEntry(deployment, true));
                }
            }
            catch (Exception)
            {
                if (!deployment.SkipJournal)
                {
                    journal.AddJournalEntry(new JournalEntry(deployment, false));
                }
                throw;
            }

            return(0);
        }
        public ConfigurationVariablesReplacer(IVariables variables, ILog log)
        {
            this.log = log;

            ignoreVariableReplacementErrors = variables.GetFlag(KnownVariables.Package.IgnoreVariableReplacementErrors);
        }
Example #27
0
        public override int Execute(string[] commandLineArguments)
        {
            Options.Parse(commandLineArguments);

            if (!ServiceFabricHelper.IsServiceFabricSdkKeyInRegistry())
            {
                throw new CommandException("Could not find the Azure Service Fabric SDK on this server. This SDK is required before running Service Fabric commands.");
            }

            Guard.NotNullOrWhiteSpace(pathToPackage,
                                      "No package file was specified. Please pass --package YourPackage.nupkg");

            if (!File.Exists(pathToPackage))
            {
                throw new CommandException("Could not find package file: " + pathToPackage);
            }

            Log.Info("Deploying package:    " + pathToPackage);

            var fileSystem               = new WindowsPhysicalFileSystem();
            var embeddedResources        = new AssemblyEmbeddedResources();
            var replacer                 = new ConfigurationVariablesReplacer(variables.GetFlag(SpecialVariables.Package.IgnoreVariableReplacementErrors));
            var jsonReplacer             = new JsonConfigurationVariableReplacer();
            var configurationTransformer = ConfigurationTransformer.FromVariables(variables);
            var transformFileLocator     = new TransformFileLocator(fileSystem);

            var conventions = new List <IConvention>
            {
                new DelegateInstallConvention(d => extractPackage.ExtractToStagingDirectory(pathToPackage)),

                // PreDeploy stage
                new ConfiguredScriptConvention(DeploymentStages.PreDeploy, fileSystem, scriptEngine, commandLineRunner),
                new PackagedScriptConvention(log, DeploymentStages.PreDeploy, fileSystem, scriptEngine, commandLineRunner),

                // Standard variable and transform replacements
                new DelegateInstallConvention(d => substituteInFiles.SubstituteBasedSettingsInSuppliedVariables(d)),
                new ConfigurationTransformsConvention(fileSystem, configurationTransformer, transformFileLocator),
                new ConfigurationVariablesConvention(fileSystem, replacer),
                new JsonConfigurationVariablesConvention(jsonReplacer, fileSystem),

                // Deploy stage
                new PackagedScriptConvention(log, DeploymentStages.Deploy, fileSystem, scriptEngine, commandLineRunner),
                new ConfiguredScriptConvention(DeploymentStages.Deploy, fileSystem, scriptEngine, commandLineRunner),

                // Variable replacement
                new SubstituteVariablesInAzureServiceFabricPackageConvention(fileSystem, fileSubstituter),

                // Main Service Fabric deployment script execution
                new EnsureCertificateInstalledInStoreConvention(certificateStore, SpecialVariables.Action.ServiceFabric.ClientCertVariable, SpecialVariables.Action.ServiceFabric.CertificateStoreLocation, SpecialVariables.Action.ServiceFabric.CertificateStoreName),
                new DeployAzureServiceFabricAppConvention(log, fileSystem, embeddedResources, scriptEngine, commandLineRunner),

                // PostDeploy stage
                new PackagedScriptConvention(log, DeploymentStages.PostDeploy, fileSystem, scriptEngine, commandLineRunner),
                new ConfiguredScriptConvention(DeploymentStages.PostDeploy, fileSystem, scriptEngine, commandLineRunner),
            };

            var deployment       = new RunningDeployment(pathToPackage, variables);
            var conventionRunner = new ConventionProcessor(deployment, conventions);

            conventionRunner.RunConventions();

            return(0);
        }