public static void SetOutputVariable(this IVariables variables, string name, string?value) { variables.Set(name, value); // And set the output-variables. // Assuming we are running in a step named 'DeployWeb' and are setting a variable named 'Foo' // then we will set Octopus.Action[DeployWeb].Output.Foo var actionName = variables.Get(ActionVariables.Name); if (string.IsNullOrWhiteSpace(actionName)) { return; } var actionScopedVariable = ActionVariables.GetOutputVariableName(actionName, name); variables.Set(actionScopedVariable, value); // And if we are on a machine named 'Web01' // Then we will set Octopus.Action[DeployWeb].Output[Web01].Foo var machineName = variables.Get(MachineVariables.Name); if (string.IsNullOrWhiteSpace(machineName)) { return; } var machineIndexedVariableName = ActionVariables.GetMachineIndexedOutputVariableName(actionName, machineName, name); variables.Set(machineIndexedVariableName, value); }
static void UpdateConfigurationSettings(XContainer configurationFile, IVariables variables) { Log.Verbose("Updating configuration settings..."); var foundSettings = false; WithConfigurationSettings(configurationFile, (roleName, settingName, settingValueAttribute) => { var setting = variables.Get(roleName + "/" + settingName) ?? variables.Get(roleName + "\\" + settingName) ?? variables.Get(settingName) ?? (variables.GetNames().Contains(settingName) ? "" : null); if (setting != null) { foundSettings = true; Log.Info("Updating setting for role {0}: {1} = {2}", roleName, settingName, setting); settingValueAttribute.Value = setting; } }); if (!foundSettings) { Log.Info("No settings that match provided variables were found."); } }
void WriteVariableScriptToFile() { if (!TryGetScriptFromVariables(out var scriptBody, out var relativeScriptFile, out var scriptSyntax) && !WasProvided(variables.Get(ScriptVariables.ScriptFileName))) { throw new CommandException($"Could not determine script to run. Please provide either a `{ScriptVariables.ScriptBody}` variable, " + $"or a `{ScriptVariables.ScriptFileName}` variable."); } if (WasProvided(scriptBody)) { var scriptFile = Path.GetFullPath(relativeScriptFile); //Set the name of the script we are about to create to the variables collection for replacement later on variables.Set(ScriptVariables.ScriptFileName, relativeScriptFile); // If the script body was supplied via a variable, then we write it out to a file. // This will be deleted with the working directory. // Bash files need SheBang as first few characters. This does not play well with BOM characters var scriptBytes = scriptSyntax == ScriptSyntax.Bash ? scriptBody.EncodeInUtf8NoBom() : scriptBody.EncodeInUtf8Bom(); File.WriteAllBytes(scriptFile, scriptBytes); } }
CommandResult ExecuteCommandInternal(string[] arguments, out string result, bool outputToCalamariConsole) { var environmentVar = defaultEnvironmentVariables; if (environmentVariables != null) { environmentVar.AddRange(environmentVariables); } var terraformExecutable = variables.Get(TerraformSpecialVariables.Action.Terraform.CustomTerraformExecutable) ?? $"terraform{(CalamariEnvironment.IsRunningOnWindows ? ".exe" : String.Empty)}"; var captureOutput = new CaptureInvocationOutputSink(); var commandLineInvocation = new CommandLineInvocation(terraformExecutable, arguments) { WorkingDirectory = templateDirectory, EnvironmentVars = environmentVar, OutputToLog = outputToCalamariConsole, AdditionalInvocationOutputSink = captureOutput }; log.Info(commandLineInvocation.ToString()); var commandResult = commandLineRunner.Execute(commandLineInvocation); result = String.Join("\n", captureOutput.Infos); return(commandResult); }
public X509Certificate2 GetOrAdd(IVariables variables, string certificateVariable, StoreName storeName, StoreLocation storeLocation = StoreLocation.CurrentUser) { var pfxBytes = Convert.FromBase64String(variables.Get($"{certificateVariable}.{CertificateVariables.Properties.Pfx}")); var thumbprint = variables.Get($"{certificateVariable}.{CertificateVariables.Properties.Thumbprint}"); var password = variables.Get($"{certificateVariable}.{CertificateVariables.Properties.Password}"); return(GetOrAdd(thumbprint, pfxBytes, password, new X509Store(storeName, storeLocation))); }
public static bool IsPackageRetentionEnabled(this IVariables variables) { bool.TryParse(variables.Get(KnownVariables.Calamari.EnablePackageRetention, bool.FalseString), out var retentionEnabled); var tentacleHome = variables.Get(TentacleVariables.Agent.TentacleHome); var packageRetentionJournalPath = variables.Get(KnownVariables.Calamari.PackageRetentionJournalPath); return(retentionEnabled && (!string.IsNullOrWhiteSpace(packageRetentionJournalPath) || !string.IsNullOrWhiteSpace(tentacleHome))); }
public void ShouldAddVariablesIfPreviousInstallation() { previous = new JournalEntry("123", "tenant", "env", "proj", "rp01", DateTime.Now, "C:\\App", "C:\\MyApp", false, new List <DeployedPackage> { new DeployedPackage("pkg", "0.0.9", "C:\\PackageOld.nupkg") }); DeploymentJournalVariableContributor.Previous(variables, journal, "123"); Assert.That(variables.Get(TentacleVariables.PreviousInstallation.OriginalInstalledPath), Is.EqualTo("C:\\App")); }
public bool IsEnabled(ScriptSyntax syntax) { if (String.IsNullOrEmpty(variables.Get(ScriptFunctionsVariables.Registration))) { return(false); } return(codeGenFunctionsRegistry.SupportedScriptSyntax.Contains(syntax)); }
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); }); }
public SubscriptionCloudCredentials GetCredentials(IVariables variables) { var subscriptionId = variables.Get(SpecialVariables.Action.Azure.SubscriptionId); var certificateThumbprint = variables.Get(SpecialVariables.Action.Azure.CertificateThumbprint); var certificateBytes = Convert.FromBase64String(variables.Get(SpecialVariables.Action.Azure.CertificateBytes)); var certificate = certificateStore.GetOrAdd(certificateThumbprint, certificateBytes); return(new CertificateCloudCredentials(subscriptionId, certificate)); }
public int ExecuteHealthCheck() { var account = new AzureServicePrincipalAccount(variables); var resourceGroupName = variables.Get(SpecialVariables.Action.Azure.ResourceGroupName); var webAppName = variables.Get(SpecialVariables.Action.Azure.WebAppName); ConfirmWebAppExists(account, resourceGroupName, webAppName); return(0); }
Task <WebDeployPublishSettings> GetPublishProfile(IVariables variables) { var account = new AzureServicePrincipalAccount(variables); var siteAndSlotName = variables.Get(SpecialVariables.Action.Azure.WebAppName); var slotName = variables.Get(SpecialVariables.Action.Azure.WebAppSlot); var targetSite = AzureWebAppHelper.GetAzureTargetSite(siteAndSlotName, slotName); return(resourceManagerPublishProfileProvider.GetPublishProperties(account, variables.Get(SpecialVariables.Action.Azure.ResourceGroupName, string.Empty), targetSite)); }
public void ShouldSkipIfInstalled() { variables.Set(SpecialVariables.Package.SkipIfAlreadyInstalled, true.ToString()); previous = new JournalEntry("123", "tenant", "env", "proj", "rp01", DateTime.Now, "C:\\App", "C:\\MyApp", true, new List <DeployedPackage> { new DeployedPackage("pkg", "0.0.9", "C:\\PackageOld.nupkg") }); RunConvention(); Assert.That(variables.Get(KnownVariables.Action.SkipJournal), Is.EqualTo("true")); }
public X509Certificate2 GetOrAdd(IVariables variables, string certificateVariable, StoreName storeName, StoreLocation storeLocation = StoreLocation.CurrentUser) { var pfxBytes = Convert.FromBase64String(variables.Get($"{certificateVariable}.{CertificateVariables.Properties.Pfx}")); var thumbprint = variables.Get($"{certificateVariable}.{CertificateVariables.Properties.Thumbprint}"); if (string.IsNullOrWhiteSpace(thumbprint)) { throw new InvalidOperationException("Certificate thumbprint was not found in variables"); } var password = variables.Get($"{certificateVariable}.{CertificateVariables.Properties.Password}"); return(GetOrAdd(thumbprint, pfxBytes, password, new X509Store(storeName, storeLocation))); }
public string GetJournalPath() { var packageRetentionJournalPath = variables.Get(KnownVariables.Calamari.PackageRetentionJournalPath); if (packageRetentionJournalPath != null) { return(packageRetentionJournalPath); } var tentacleHome = variables.Get(TentacleVariables.Agent.TentacleHome) ?? string.Empty; return(Path.Combine(tentacleHome, DefaultJournalName)); }
private string CreateAzureCertificate(string workingDirectory, IVariables variables) { var certificateFilePath = Path.Combine(workingDirectory, CertificateFileName); var certificatePassword = GenerateCertificatePassword(); var azureCertificate = certificateStore.GetOrAdd( variables.Get(SpecialVariables.Action.Azure.CertificateThumbprint), Convert.FromBase64String(variables.Get(SpecialVariables.Action.Azure.CertificateBytes)), StoreName.My); variables.Set("OctopusAzureCertificateFileName", certificateFilePath); variables.Set("OctopusAzureCertificatePassword", certificatePassword); fileSystem.WriteAllBytes(certificateFilePath, azureCertificate.Export(X509ContentType.Pfx, certificatePassword)); return(certificateFilePath); }
string GetReleaseName(IVariables variables) { var validChars = new Regex("[^a-zA-Z0-9-]"); var releaseName = variables.Get(SpecialVariables.Helm.ReleaseName)?.ToLower(); if (string.IsNullOrWhiteSpace(releaseName)) { releaseName = $"{variables.Get(ActionVariables.Name)}-{variables.Get(DeploymentEnvironment.Name)}"; releaseName = validChars.Replace(releaseName, "").ToLowerInvariant(); } log.SetOutputVariable("ReleaseName", releaseName, variables); log.Info($"Using Release Name {releaseName}"); return(releaseName); }
static string WritePatternMatching(IVariables variables) { var builder = new StringBuilder(); foreach (var variableName in variables.GetNames()) { var variableValue = variables.Get(variableName); if (variableValue == null) { builder.AppendFormat(" | \"{0}\" -> Some null", EncodeValue(variableName)); } else { builder.AppendFormat(" | \"{0}\" -> {1} |> Some", EncodeValue(variableName), EncryptVariable(variableValue)); } builder.Append(Environment.NewLine); } builder.Append(" | _ -> None"); return(builder.ToString()); }
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)); } }
protected override IEnumerable <ScriptExecution> PrepareExecution(Script script, IVariables variables, Dictionary <string, string> environmentVars = null) { var powerShellBootstrapper = GetPowerShellBootstrapper(variables); var(bootstrapFile, otherTemporaryFiles) = powerShellBootstrapper.PrepareBootstrapFile(script, variables); var debuggingBootstrapFile = powerShellBootstrapper.PrepareDebuggingBootstrapFile(script); var executable = powerShellBootstrapper.PathToPowerShellExecutable(variables); var arguments = powerShellBootstrapper.FormatCommandArguments(bootstrapFile, debuggingBootstrapFile, variables); var invocation = new CommandLineInvocation(executable, arguments) { EnvironmentVars = environmentVars, WorkingDirectory = Path.GetDirectoryName(script.File), UserName = powerShellBootstrapper.AllowImpersonation() ? variables.Get(PowerShellVariables.UserName) : null, Password = powerShellBootstrapper.AllowImpersonation() ? ToSecureString(variables.Get(PowerShellVariables.Password)) : null }; return(new[] { new ScriptExecution( invocation, otherTemporaryFiles.Concat(new[] { bootstrapFile, debuggingBootstrapFile }) ) }); }
string GetTomcatVersion(IVariables variables) { var catalinaHome = variables.Get(SpecialVariables.Action.Java.TomcatDeployCertificate.CatalinaHome) ?? Environment.GetEnvironmentVariable("CATALINA_HOME");; var catalinaPath = Path.Combine(catalinaHome, "lib", "catalina.jar"); if (!File.Exists(catalinaPath)) { throw new CommandException("TOMCAT-HTTPS-ERROR-0018: " + $"Failed to find the file {catalinaPath} " + "http://g.octopushq.com/JavaAppDeploy#tomcat-https-error-0018"); } var version = new StringBuilder(); var versionCheck = SilentProcessRunner.ExecuteCommand(JavaRuntime.CmdPath, $"-cp \"{catalinaPath}\" org.apache.catalina.util.ServerInfo", ".", (stdOut) => { Log.Verbose(stdOut); version.AppendLine(stdOut); }, Console.Error.WriteLine); if (versionCheck.ExitCode != 0) { throw new CommandException($"Attempt to obtain tomcat version failed with exit code {versionCheck.ExitCode}."); } return(version.ToString()); }
static IEnumerable<string> ReplaceStronglyTypeApplicationSetting(XNode document, string xpath, string keyAttributeName, string keyAttributeValue, IVariables variables) { var changes = new List<string>(); var settings = ( from element in document.XPathSelectElements(xpath) let keyAttribute = element.Attribute(keyAttributeName) where keyAttribute != null where string.Equals(keyAttribute.Value, keyAttributeValue, StringComparison.OrdinalIgnoreCase) select element).ToList(); if (settings.Count == 0) return changes; var value = variables.Get(keyAttributeValue) ?? string.Empty; foreach (var setting in settings) { changes.Add($"Setting '{keyAttributeValue}' = '{value}'"); var valueElement = setting.Elements().FirstOrDefault(e => e.Name.LocalName == "value"); if (valueElement == null) { setting.Add(new XElement("value", value)); } else { valueElement.SetValue(value); } } return changes; }
public void Update(IVariables variables) { bool VariableNameIsNotASystemVariable(string v) { if (v.StartsWith("Octopus", StringComparison.OrdinalIgnoreCase)) { // Only include variables starting with 'Octopus' // if it also has a colon (:) if (v.StartsWith("Octopus:", StringComparison.OrdinalIgnoreCase)) { return(map.ContainsKey(v)); } else { return(false); } } return(map.ContainsKey(v)); } foreach (var name in variables.GetNames().Where(VariableNameIsNotASystemVariable)) { try { map[name](variables.Get(name)); } catch (Exception e) { Log.WarnFormat("Unable to set value for {0}. The following error occurred: {1}", name, e.Message); } } }
static void SetOutputVariable(string name, string value, IVariables variables) { if (variables.Get(name) != value) { Log.SetOutputVariable(name, value, variables); } }
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, commandLineArguments.Skip(1).ToArray()); if (result != 0) { return(result); } } return(0); }
public void Update(IVariables variables) { bool VariableNameIsMappedPath(string v) { if (v.StartsWith("Octopus", StringComparison.OrdinalIgnoreCase) && !v.StartsWith("Octopus:", StringComparison.OrdinalIgnoreCase)) { // Only include variables starting with 'Octopus' // if it also has a colon (:) return(false); } return(map.ContainsKey(v)); } var replaced = 0; foreach (var name in variables.GetNames().Where(VariableNameIsMappedPath)) { try { log.Verbose(StructuredConfigMessages.StructureFound(name)); replaced++; map[name](variables.Get(name)); } catch (Exception e) { log.WarnFormat("Unable to set value for {0}. The following error occurred: {1}", name, e.Message); } } if (replaced == 0) { log.Info(StructuredConfigMessages.NoStructuresFound); } }
static IEnumerable <string> ReplaceAppSettingOrConnectionString(XNode document, string xpath, string keyAttributeName, string keyAttributeValue, string valueAttributeName, IVariables variables) { var changes = new List <string>(); var settings = ( from element in document.XPathSelectElements(xpath) let keyAttribute = element.Attribute(keyAttributeName) where keyAttribute != null where string.Equals(keyAttribute.Value, keyAttributeValue, StringComparison.OrdinalIgnoreCase) select element).ToList(); if (settings.Count == 0) { return(changes); } var value = variables.Get(keyAttributeValue) ?? string.Empty; foreach (var setting in settings) { changes.Add(string.Format("Setting '{0}' = '{1}'", keyAttributeValue, value)); var valueAttribute = setting.Attribute(valueAttributeName); if (valueAttribute == null) { setting.Add(new XAttribute(valueAttributeName, value)); } else { valueAttribute.SetValue(value); } } return(changes); }
ITopLevelExpression TryReplaceValue(ITopLevelExpression expr, IVariables variables) { switch (expr) { case KeyValuePairExpression pair: var logicalName = pair.Key?.Text?.LogicalValue ?? ""; if (!IsOctopusVariableName(logicalName) && variables.IsSet(logicalName)) { log.Verbose(StructuredConfigMessages.StructureFound(logicalName)); var logicalValue = variables.Get(logicalName); var encodedValue = Encode.Value(logicalValue); var newValueExpr = new ValueExpression(new StringValue(logicalValue, encodedValue)); // In cases where a key was specified with neither separator nor value // we have to add a separator, otherwise the value becomes part of the key. var separator = pair.Separator ?? new SeparatorExpression(":"); return(new KeyValuePairExpression(pair.Key, separator, newValueExpr)); } else { return(expr); } default: return(expr); } }
static string[] WriteScriptModules(IVariables variables, string parentDirectory, StringBuilder output) { var scriptModules = new List <string>(); foreach (var variableName in variables.GetNames().Where(ScriptVariables.IsLibraryScriptModule)) { if (ScriptVariables.GetLibraryScriptModuleLanguage(variables, variableName) == ScriptSyntax.PowerShell) { var libraryScriptModuleName = ScriptVariables.GetLibraryScriptModuleName(variableName); var name = "Library_" + new string(libraryScriptModuleName.Where(char.IsLetterOrDigit).ToArray()) + "_" + DateTime.Now.Ticks; var moduleFileName = $"{name}.psm1"; var moduleFilePath = Path.Combine(parentDirectory, moduleFileName); Log.VerboseFormat("Writing script module '{0}' as PowerShell module {1}. This module will be automatically imported - functions will automatically be in scope.", libraryScriptModuleName, moduleFileName, name); var contents = variables.Get(variableName); if (contents == null) { throw new InvalidOperationException($"Value for variable {variableName} could not be found."); } CalamariFileSystem.OverwriteFile(moduleFilePath, contents, Encoding.UTF8); output.AppendLine($"Import-ScriptModule '{libraryScriptModuleName.EscapeSingleQuotedString()}' '{moduleFilePath.EscapeSingleQuotedString()}'"); output.AppendLine(); scriptModules.Add(moduleFilePath); } } return(scriptModules.ToArray()); }
TimeSpan GetHttpTimeout() { const string expectedTimespanFormat = "c"; // Equal to Timeout.InfiniteTimeSpan, which isn't available in net40 var defaultTimeout = new TimeSpan(0, 0, 0, 0, -1); var rawTimeout = variables.Get(KnownVariables.NugetHttpTimeout); if (string.IsNullOrWhiteSpace(rawTimeout)) { return(defaultTimeout); } if (TimeSpan.TryParseExact(rawTimeout, expectedTimespanFormat, null, out var parsedTimeout)) { return(parsedTimeout); } var exampleTimespan = new TimeSpan(0, 0, 1, 0).ToString(expectedTimespanFormat); var message = $"The variable {KnownVariables.NugetHttpTimeout} couldn't be parsed as a timespan. " + $"Expected a value like '{exampleTimespan}' but received '{rawTimeout}'. " + $"Defaulting to '{defaultTimeout.ToString(expectedTimespanFormat)}'."; Log.Warn(message); return(defaultTimeout); }