/// <summary> /// Packs the specified template and its referenced artifacts for use /// in a Template Spec. /// </summary> /// <param name="rootTemplateFilePath"> /// The path to the ARM Template .json file to pack /// </param> /// <param name="uiFormDefinitionFilePath"> /// The path to the UI Form Definition .json to pack (if any) /// </param> public static PackagedTemplate Pack(string rootTemplateFilePath, string uiFormDefinitionFilePath) { rootTemplateFilePath = Path.GetFullPath(rootTemplateFilePath); PackingContext context = new PackingContext( Path.GetDirectoryName(rootTemplateFilePath) ); PackArtifacts(rootTemplateFilePath, context, out JObject templateObj); var packagedTemplate = new PackagedTemplate { RootTemplate = templateObj, Artifacts = context.Artifacts.ToArray() }; // If a UI Form Definition file path was provided to us, make sure we package the // UI Form Definition as well: if (!string.IsNullOrWhiteSpace(uiFormDefinitionFilePath)) { string uiFormDefinitionJson = FileUtilities.DataStore.ReadFileAsText(uiFormDefinitionFilePath); packagedTemplate.UIFormDefinition = JObject.Parse(uiFormDefinitionJson); } return(packagedTemplate); }
/// <summary> /// Unpacks the specified packaged template to the local filesystem. /// </summary> /// <param name="packagedTemplate">The packaged template to be unpacked</param> /// <param name="targetDirectory"> /// The root directory to unpack the template and its artifacts to /// </param> /// <param name="templateFileName"> /// The name of the file to use for the root template json /// </param> public static void Unpack( PackagedTemplate packagedTemplate, string targetDirectory, string templateFileName) { // Ensure paths are normalized: templateFileName = Path.GetFileName(templateFileName); targetDirectory = Path.GetFullPath(targetDirectory) .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); string rootTemplateFilePath = Path.Combine(targetDirectory, templateFileName); // TODO: Directory/file existence checks.. // Go through each artifact and make sure it's not going to place artifacts // outside of the target directory: foreach (var artifact in packagedTemplate.Artifacts) { string absoluteLocalPath = Path.GetFullPath( Path.Combine( targetDirectory, NormalizeDirectorySeparatorsForLocalFS(artifact.Path) ) ); if (!absoluteLocalPath.StartsWith( targetDirectory + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException( $"Unable to unpack artifact '{artifact.Path}' because it would create a file " + $"outside of the target directory heirarchy of '{targetDirectory}'"); } } // Now that the artifact paths checkout...let's begin by writing our main template // file and then processing each artifact: FileUtilities.DataStore.CreateDirectory(targetDirectory); FileUtilities.DataStore.WriteFile(rootTemplateFilePath, packagedTemplate.RootTemplate.ToString()); foreach (var artifact in packagedTemplate.Artifacts) { if (!(artifact is TemplateSpecTemplateArtifact templateArtifact)) { throw new NotSupportedException("Unknown artifact type encountered..."); } string absoluteLocalPath = Path.GetFullPath( Path.Combine( targetDirectory, NormalizeDirectorySeparatorsForLocalFS(artifact.Path) ) ); FileUtilities.DataStore.CreateDirectory(Path.GetDirectoryName(absoluteLocalPath)); FileUtilities.DataStore.WriteFile(absoluteLocalPath, ((JObject)templateArtifact.Template).ToString()); } }