Пример #1
0
        public void Install(RunningDeployment deployment)
        {
            var variables         = deployment.Variables;
            var subscriptionId    = variables[SpecialVariables.Action.Azure.SubscriptionId];
            var tenantId          = variables[SpecialVariables.Action.Azure.TenantId];
            var clientId          = variables[SpecialVariables.Action.Azure.ClientId];
            var password          = variables[SpecialVariables.Action.Azure.Password];
            var resourceGroupName = variables[SpecialVariables.Action.Azure.ResourceGroupName];
            var deploymentName    = !string.IsNullOrWhiteSpace(variables[SpecialVariables.Action.Azure.ResourceGroupDeploymentName])
                    ? variables[SpecialVariables.Action.Azure.ResourceGroupDeploymentName]
                    : GenerateDeploymentNameFromStepName(variables[SpecialVariables.Action.Name]);
            var deploymentMode = (DeploymentMode)Enum.Parse(typeof(DeploymentMode),
                                                            variables[SpecialVariables.Action.Azure.ResourceGroupDeploymentMode]);
            var template   = variables.Evaluate(fileSystem.ReadFile(templateFile));
            var parameters = !string.IsNullOrWhiteSpace(templateParametersFile)
                ? parameterParser.ParseParameters(variables.Evaluate(fileSystem.ReadFile(templateParametersFile)))
                : null;

            Log.Info(
                $"Deploying Resource Group {resourceGroupName} in subscription {subscriptionId}.\nDeployment name: {deploymentName}\nDeployment mode: {deploymentMode}");

            using (var armClient = new ResourceManagementClient(
                       new TokenCloudCredentials(subscriptionId, ServicePrincipal.GetAuthorizationToken(tenantId, clientId, password))))
            {
                CreateDeployment(armClient, resourceGroupName, deploymentName, deploymentMode, template, parameters);
                PollForCompletion(armClient, resourceGroupName, deploymentName, variables);
            }
        }
Пример #2
0
        public static ICloudFormationRequestBuilder Create(ITemplateResolver templateResolver,
                                                           string templateFile,
                                                           string templateParameterFile,
                                                           bool filesInPackage,
                                                           ICalamariFileSystem fileSystem,
                                                           IVariables variables,
                                                           string stackName,
                                                           List <string> capabilities,
                                                           bool disableRollback,
                                                           string roleArn,
                                                           IEnumerable <KeyValuePair <string, string> > tags,
                                                           StackArn stack,
                                                           Func <IAmazonCloudFormation> clientFactory)
        {
            var resolvedTemplate   = templateResolver.Resolve(templateFile, filesInPackage, variables);
            var resolvedParameters = templateResolver.MaybeResolve(templateParameterFile, filesInPackage, variables);

            if (!string.IsNullOrWhiteSpace(templateParameterFile) && !resolvedParameters.Some())
            {
                throw new CommandException("Could not find template parameters file: " + templateParameterFile);
            }

            return(new CloudFormationTemplate(() => variables.Evaluate(fileSystem.ReadFile(resolvedTemplate.Value)),
                                              CloudFormationParametersFile.Create(resolvedParameters, fileSystem, variables),
                                              stackName,
                                              capabilities,
                                              disableRollback,
                                              roleArn,
                                              tags,
                                              stack,
                                              clientFactory,
                                              variables));
        }
Пример #3
0
        public override void Load()
        {
            if (File.Exists(journalPath))
            {
                var json = fileSystem.ReadFile(journalPath);

                if (TryDeserializeJournal(json, out var journalContents))
                {
                    journalEntries = journalContents
                                     ?.JournalEntries
                                     ?.ToDictionary(entry => entry.Package, entry => entry)
                                     ?? new Dictionary <PackageIdentity, JournalEntry>();
                    Cache = journalContents?.Cache ?? new PackageCache(0);
                }
                else
                {
                    var journalFileName       = Path.GetFileNameWithoutExtension(journalPath);
                    var backupJournalFileName = $"{journalFileName}_{DateTimeOffset.UtcNow:yyyyMMddTHHmmss}.json"; // eg. PackageRetentionJournal_20210101T120000.json

                    log.Warn($"The existing package retention journal file {journalPath} could not be read. The file will be renamed to {backupJournalFileName}. A new journal will be created.");

                    // NET Framework 4.0 doesn't have File.Move(source, dest, overwrite) so we use Copy and Delete to replicate this
                    File.Copy(journalPath, Path.Combine(Path.GetDirectoryName(journalPath), backupJournalFileName), true);
                    File.Delete(journalPath);

                    journalEntries = new Dictionary <PackageIdentity, JournalEntry>();
                    Cache          = new PackageCache(0);
                }
            }
            else
            {
                journalEntries = new Dictionary <PackageIdentity, JournalEntry>();
                Cache          = new PackageCache(0);
            }
        }
        public void ModifyFile(string filePath, IVariables variables)
        {
            try
            {
                var fileText = fileSystem.ReadFile(filePath, out var encoding);

                var parsed   = Parser.Parse(fileText);
                var replaced = 0;
                var updated  = parsed.Mutate(expr =>
                {
                    var newExpr = TryReplaceValue(expr, variables);
                    if (!ReferenceEquals(newExpr, expr))
                    {
                        replaced++;
                    }
                    return(newExpr);
                });
                if (replaced == 0)
                {
                    log.Info(StructuredConfigMessages.NoStructuresFound);
                }
                var serialized = updated.ToString();

                fileSystem.OverwriteFile(filePath, serialized, encoding);
            }
            catch (Sprache.ParseException e)
            {
                throw new StructuredConfigFileParseException(e.Message, e);
            }
        }
Пример #5
0
        void ArrangeOriginalConfigurationFileForSuccess(string configurationFilePath, string content, Action <string> captureResultingConfiguration)
        {
            variables.Set(SpecialVariables.Action.Azure.Output.ConfigurationFile, configurationFilePath);
            fileSystem.FileExists(configurationFilePath).Returns(true);
            fileSystem.ReadFile(configurationFilePath).Returns(content);

            fileSystem.OverwriteFile(configurationFilePath, Arg.Do <string>(captureResultingConfiguration));
        }
Пример #6
0
        public void ShouldSubstituteVariablesInRelativePathFiles()
        {
            variables.Set("foo", "bar");

            var path = Path.Combine("assets", "README.txt");

            // Enable file substitution and configure the target
            variables.Set(SpecialVariables.Package.SubstituteInFilesEnabled, true.ToString());
            variables.Set(SpecialVariables.Package.SubstituteInFilesTargets, path);

            DeployPackage();

            // The #{foo} variable in assets\README.txt should have been replaced by 'bar'
            string actual = fileSystem.ReadFile(Path.Combine(stagingDirectory, "Acme.Web", "1.0.0", "assets", "README.txt"));

            Assert.AreEqual("bar", actual);
        }
Пример #7
0
        private void AssertXmlNodeValue(string xmlFile, string nodeXPath, string value)
        {
            var configXml = new XmlDocument();

            configXml.LoadXml(fileSystem.ReadFile(xmlFile));
            var node = configXml.SelectSingleNode(nodeXPath);

            Assert.AreEqual(value, node.Value);
        }
        // The template and parameter files are relative paths, and may be located either inside or outside of the package.
        string ResolveAndSubstituteFile(string relativeFilePath, bool inPackage, VariableDictionary variables)
        {
            var absolutePath = inPackage
                ? Path.Combine(variables.Get(SpecialVariables.OriginalPackageDirectoryPath), variables.Evaluate(relativeFilePath))
                : Path.Combine(Environment.CurrentDirectory, relativeFilePath);

            if (!File.Exists(absolutePath))
            {
                throw new CommandException($"Could not resolve '{relativeFilePath}' to physical file");
            }

            return(variables.Evaluate(fileSystem.ReadFile(absolutePath)));
        }
Пример #9
0
        void ReadEncryptedVariablesFromFile(CommonOptions options, CalamariVariables variables)
        {
            foreach (var sensitiveFilePath in options.InputVariables.SensitiveVariablesFiles.Where(f => !string.IsNullOrEmpty(f)))
            {
                var sensitiveFilePassword = options.InputVariables.SensitiveVariablesPassword;
                var rawVariables          = string.IsNullOrWhiteSpace(sensitiveFilePassword)
                    ? fileSystem.ReadFile(sensitiveFilePath)
                    : Decrypt(fileSystem.ReadAllBytes(sensitiveFilePath), sensitiveFilePassword);

                try
                {
                    var sensitiveVariables = JsonConvert.DeserializeObject <Dictionary <string, string> >(rawVariables);
                    foreach (var variable in sensitiveVariables)
                    {
                        variables.Set(variable.Key, variable.Value);
                    }
                }
                catch (JsonReaderException)
                {
                    throw new CommandException("Unable to parse sensitive-variables as valid JSON.");
                }
            }
        }
Пример #10
0
        public void PerformSubstitution(string sourceFile, VariableDictionary variables, string targetFile)
        {
            var source   = fileSystem.ReadFile(sourceFile);
            var encoding = GetEncoding(sourceFile, variables);

            string error;
            var    result = variables.Evaluate(source, out error);

            if (!string.IsNullOrEmpty(error))
            {
                Log.VerboseFormat("Parsing file '{0}' with Octostache returned the following error: `{1}`", sourceFile, error);
            }

            fileSystem.OverwriteFile(targetFile, result, encoding);
        }
        /// <summary>
        /// Look at the template file and see if there were any outputs.
        /// </summary>
        /// <param name="template">The template file</param>
        /// <param name="deployment">The current deployment</param>
        /// <returns>true if the Outputs marker was found, and false otherwise</returns>
        private bool TemplateFileContainsOutputs(string template, RunningDeployment deployment)
        {
            Guard.NotNullOrWhiteSpace(template, "template can not be null or empty");
            Guard.NotNull(deployment, "deployment can not be null");

            return(TemplateReplacement.GetAbsolutePath(
                       fileSystem,
                       template,
                       filesInPackage,
                       deployment.Variables)
                   // The path is transformed to the string contents
                   .Map(path => fileSystem.ReadFile(path))
                   // The contents becomes true or false based on the regex match
                   .Map(contents => OutputsRe.IsMatch(contents)));
        }
Пример #12
0
        public void Install(RunningDeployment deployment)
        {
            // Validate we actually have a real path to the real config file since this value is potentially passed via variable or a previous convention
            var configurationFilePath = deployment.Variables.Get(SpecialVariables.Action.Azure.Output.ConfigurationFile);

            if (!fileSystem.FileExists(configurationFilePath))
            {
                throw new CommandException("Could not find the Azure Cloud Service Configuration file: " + configurationFilePath);
            }

            var configuration = XDocument.Parse(fileSystem.ReadFile(configurationFilePath));

            UpdateConfigurationWithCurrentInstanceCount(configuration, configurationFilePath, deployment.Variables);
            UpdateConfigurationSettings(configuration, deployment.Variables);
            SaveConfigurationFile(configuration, configurationFilePath);
        }
Пример #13
0
        public void PerformSubstitution(string sourceFile, IVariables variables, string targetFile)
        {
            log.Verbose($"Performing variable substitution on '{sourceFile}'");

            var source   = fileSystem.ReadFile(sourceFile, out var sourceFileEncoding);
            var encoding = GetEncoding(variables, sourceFileEncoding);

            var result = variables.Evaluate(source, out var error, false);

            if (!string.IsNullOrEmpty(error))
            {
                log.VerboseFormat("Parsing file '{0}' with Octostache returned the following error: `{1}`", sourceFile, error);
            }

            fileSystem.OverwriteFile(targetFile, result, encoding);
        }
Пример #14
0
 public static CloudFormationParametersFile Create(Maybe <ResolvedTemplatePath> path, ICalamariFileSystem fileSystem, CalamariVariableDictionary variables)
 {
     return(new CloudFormationParametersFile(() => path.Select(x => variables.Evaluate(fileSystem.ReadFile(x.Value))), JsonConvert.DeserializeObject <List <Parameter> >));
 }
Пример #15
0
 public static CloudFormationTemplate Create(ResolvedTemplatePath path, ITemplateInputs <Parameter> parameters, ICalamariFileSystem filesSystem, IVariables variables)
 {
     Guard.NotNull(path, "Path must not be null");
     return(new CloudFormationTemplate(() => variables.Evaluate(filesSystem.ReadFile(path.Value)), parameters, JsonConvert.DeserializeObject <List <StackFormationNamedOutput> >));
 }
        public void ModifyFile(string filePath, IVariables variables)
        {
            try
            {
                void LogReplacement(string key)
                => log.Verbose(StructuredConfigMessages.StructureFound(key));

                var replaced       = 0;
                var variablesByKey = variables
                                     .Where(v => !OctopusReservedVariablePattern.IsMatch(v.Key))
                                     .DistinctBy(v => v.Key)
                                     .ToDictionary <KeyValuePair <string, string>, string, Func <string?> >(v => v.Key,
                                                                                                            v => () =>
                {
                    LogReplacement(v.Key);
                    replaced++;
                    return(variables.Get(v.Key));
                },
                                                                                                            StringComparer.OrdinalIgnoreCase);

                // Read and transform the input file
                var fileText   = fileSystem.ReadFile(filePath, out var encoding);
                var lineEnding = fileText.GetMostCommonLineEnding();

                var outputEvents   = new List <ParsingEvent>();
                var indentDetector = new YamlIndentDetector();

                using (var reader = new StringReader(fileText))
                {
                    var scanner    = new Scanner(reader, false);
                    var parser     = new Parser(scanner);
                    var classifier = new YamlEventStreamClassifier();
                    (IYamlNode startEvent, string?replacementValue)? structureWeAreReplacing = null;
                    while (parser.MoveNext())
                    {
                        var ev = parser.Current;
                        if (ev == null)
                        {
                            continue;
                        }

                        indentDetector.Process(ev);

                        if (ev is Comment c)
                        {
                            ev = c.RestoreLeadingSpaces();
                        }

                        var node = classifier.Process(ev);

                        if (structureWeAreReplacing == null)
                        {
                            // Not replacing: searching for things to replace, copying events to output.

                            if (node is YamlNode <Scalar> scalar &&
                                variablesByKey.TryGetValue(scalar.Path, out var newValue))
                            {
                                outputEvents.Add(scalar.Event.ReplaceValue(newValue()));
                            }
                            else if (node is YamlNode <MappingStart> mappingStart &&
                                     variablesByKey.TryGetValue(mappingStart.Path, out var mappingReplacement))
                            {
                                structureWeAreReplacing = (mappingStart, mappingReplacement());
                            }
                            else if (node is YamlNode <SequenceStart> sequenceStart &&
                                     variablesByKey.TryGetValue(sequenceStart.Path, out var sequenceReplacement))
                            {
                                structureWeAreReplacing = (sequenceStart, sequenceReplacement());
                            }
Пример #17
0
 public string ResolveAndSubstituteFile(ICalamariFileSystem fileSystem, string relativeFilePath, bool inPackage, VariableDictionary variables)
 {
     return(GetAbsolutePath(fileSystem, relativeFilePath, inPackage, variables)
            .Map(path => variables.Evaluate(fileSystem.ReadFile(path))));
 }