public override void ExecuteCmdlet() { try { ResourceIdentifier resourceIdentifier = (ResourceId != null) ? new ResourceIdentifier(ResourceId) : null; ResourceGroupName = ResourceGroupName ?? resourceIdentifier.ResourceGroupName; Name = Name ?? ResourceIdUtility.GetResourceName(ResourceId); // Get the template spec version model from the SDK: TemplateSpecVersion specificVersion = TemplateSpecsSdkClient.TemplateSpecsClient.TemplateSpecVersions.Get( ResourceGroupName, Name, Version ); // Get the parent template spec from the SDK. We do this because we want to retrieve the // template spec name with its proper casing for naming our main template output file (the // Name parameter may have mismatched casing): TemplateSpec parentTemplateSpec = TemplateSpecsSdkClient.TemplateSpecsClient.TemplateSpecs.Get(ResourceGroupName, Name); PackagedTemplate packagedTemplate = new PackagedTemplate(specificVersion); // TODO: Handle overwriting prompts... // Ensure our output path is resolved based on the current powershell working // directory instead of the current process directory: OutputFolder = ResolveUserPath(OutputFolder); string mainTemplateFileName = $"{parentTemplateSpec.Name}.{specificVersion.Name}.json"; string uiFormDefinitionFileName = $"{parentTemplateSpec.Name}.{specificVersion.Name}.uiformdefinition.json"; string fullRootTemplateFilePath = Path.GetFullPath( Path.Combine(OutputFolder, mainTemplateFileName) ); if (ShouldProcess(specificVersion.Id, $"Export to '{fullRootTemplateFilePath}'")) { TemplateSpecPackagingEngine.Unpack( packagedTemplate, OutputFolder, mainTemplateFileName, uiFormDefinitionFileName); } WriteObject(PowerShellUtilities.ConstructPSObject(null, "Path", fullRootTemplateFilePath)); } catch (Exception ex) { WriteExceptionError(ex); } }
public PSTemplateSpec CreateOrUpdateTemplateSpecVersion( string resourceGroupName, string templateSpecName, string templateSpecVersion, string location, PackagedTemplate packagedTemplate, string templateSpecDisplayName = null, string templateSpecDescription = null, string versionDescription = null) { var templateSpecModel = this.CreateOrUpdateTemplateSpecInternal( resourceGroupName, templateSpecName, location, templateSpecDisplayName, templateSpecDescription ); var existingTemplateSpecVersion = this.GetAzureSdkTemplateSpecVersion( resourceGroupName, templateSpecName, templateSpecVersion, throwIfNotExists: false ); var templateSpecVersionModel = new TemplateSpecVersion { Location = templateSpecModel.Location, Template = packagedTemplate.RootTemplate, Artifacts = packagedTemplate.Artifacts?.ToList(), Description = versionDescription ?? existingTemplateSpecVersion?.Description }; templateSpecVersionModel = TemplateSpecsClient.TemplateSpecVersions.CreateOrUpdate( resourceGroupName, templateSpecName, templateSpecVersion, templateSpecVersionModel ); return(new PSTemplateSpec(templateSpecModel, new[] { templateSpecVersionModel })); }
public PSTemplateSpec CreateOrUpdateTemplateSpecVersion( string resourceGroupName, string templateSpecName, string templateSpecVersion, string location, PackagedTemplate packagedTemplate, object UIFormDefinition, string templateSpecDisplayName = null, string templateSpecDescription = null, string versionDescription = null, Hashtable templateSpecTags = null, Hashtable versionTags = null) { var templateSpecModel = this.CreateOrUpdateTemplateSpecInternal( resourceGroupName, templateSpecName, location, templateSpecDisplayName, templateSpecDescription, tags: templateSpecTags, onlyApplyTagsOnCreate: true // Don't update tags if the template spec already exists ); var existingTemplateSpecVersion = this.GetAzureSdkTemplateSpecVersion( resourceGroupName, templateSpecName, templateSpecVersion, throwIfNotExists: false ); var templateSpecVersionModel = new TemplateSpecVersion { Location = templateSpecModel.Location, MainTemplate = packagedTemplate.RootTemplate, LinkedTemplates = packagedTemplate.Artifacts?.ToList(), Description = versionDescription ?? existingTemplateSpecVersion?.Description, UiFormDefinition = UIFormDefinition }; // Handle our conditional tagging: // ------------------------------------------ if (versionTags != null) { // Explicit version tags provided. Use them: templateSpecVersionModel.Tags = TagsConversionHelper.CreateTagDictionary(versionTags, true); } else if (existingTemplateSpecVersion != null) { // No tags were provided. The template spec version already exists // ... keep the existing version's tags: templateSpecVersionModel.Tags = existingTemplateSpecVersion.Tags; } else { // No tags were provided. The template spec version does not already exist // ... inherit the tags present on the underlying template spec: templateSpecVersionModel.Tags = templateSpecModel.Tags; } // Perform the actual version create/update: // ------------------------------------------ templateSpecVersionModel = TemplateSpecsClient.TemplateSpecVersions.CreateOrUpdate( resourceGroupName, templateSpecName, templateSpecVersion, templateSpecVersionModel ); return(new PSTemplateSpec(templateSpecModel, new[] { templateSpecVersionModel })); }
public override void ExecuteCmdlet() { try { PackagedTemplate packagedTemplate; switch (ParameterSetName) { case FromJsonFileParameterSet: string filePath = this.TryResolvePath(TemplateFile); if (!File.Exists(filePath)) { throw new PSInvalidOperationException( string.Format(ProjectResources.InvalidFilePath, TemplateFile) ); } if (BicepUtility.IsBicepFile(TemplateFile)) { filePath = BicepUtility.BuildFile(this.ResolvePath(TemplateFile), this.WriteVerbose); } packagedTemplate = TemplateSpecPackagingEngine.Pack(filePath); break; case FromJsonStringParameterSet: JObject parsedTemplate; try { parsedTemplate = JObject.Parse(TemplateJson); } catch { // Check if the user may have inadvertantly passed a file path using "-TemplateJson" // instead of using "-TemplateFile". If they did, display a warning message. Note we // do not currently automatically switch to using a file in this case because if the // JSON string is coming from an external script/source not authored directly by the // caller it could result in a sensitive template being PUT unintentionally: try { string asFilePath = this.TryResolvePath(TemplateJson); if (File.Exists(asFilePath)) { WriteWarning( $"'{TemplateJson}' was found to exist as a file. Did you mean to use '-TemplateFile' instead?" ); } } catch { // Subsequent failure in the file existence check... Ignore it } throw; } // When we're provided with a raw JSON string for the template we don't // do any special packaging... (ie: we don't pack artifacts because there // is no well known root path): packagedTemplate = new PackagedTemplate { RootTemplate = parsedTemplate, Artifacts = new LinkedTemplateArtifact[0] }; break; default: throw new PSNotSupportedException(); } JObject UIFormDefinition = new JObject(); if (UIFormDefinitionFile == null && UIFormDefinitionString == null) { UIFormDefinition = null; } else if (!String.IsNullOrEmpty(UIFormDefinitionFile)) { string UIFormFilePath = this.TryResolvePath(UIFormDefinitionFile); if (!File.Exists(UIFormFilePath)) { throw new PSInvalidOperationException( string.Format(ProjectResources.InvalidFilePath, UIFormDefinitionFile) ); } string UIFormJson = FileUtilities.DataStore.ReadFileAsText(UIFormDefinitionFile); UIFormDefinition = JObject.Parse(UIFormJson); } else if (!String.IsNullOrEmpty(UIFormDefinitionString)) { UIFormDefinition = JObject.Parse(UIFormDefinitionString); } Action createOrUpdateAction = () => { var templateSpecVersion = TemplateSpecsSdkClient.CreateOrUpdateTemplateSpecVersion( ResourceGroupName, Name, Version, Location, packagedTemplate, UIFormDefinition, templateSpecDescription: Description, templateSpecDisplayName: DisplayName, versionDescription: VersionDescription, templateSpecTags: Tag, // Note: Only applied if template spec doesn't exist versionTags: Tag ); WriteObject(templateSpecVersion); }; if (!Force.IsPresent && TemplateSpecsSdkClient.GetAzureSdkTemplateSpecVersion( ResourceGroupName, Name, Version, throwIfNotExists: false) != null) { // The template spec version already exists and force is not present, so // let's confirm with the user that he/she wishes to overwrite (update) it: string confirmationMessage = $"Template Spec version '{Version}' already exists and this action will overwrite existing " + "data for this version. Are you sure you'd like to overwrite existing " + $"Template Spec version data for Template Spec '{Name}' version '{Version}'?"; ConfirmAction( Force.IsPresent, confirmationMessage, "Update", $"{Name}/versions/{Version}", createOrUpdateAction ); } else { if (!ShouldProcess($"{Name}/versions/{Version}", "Create")) { return; // Don't perform the actual creation/update action } createOrUpdateAction(); } } catch (Exception ex) { WriteExceptionError(ex); } }
public override void ExecuteCmdlet() { try { // TODO: Update the following to use ??= when we upgrade to C# 8.0 if (ResourceGroupName == null) { ResourceGroupName = ResourceIdUtility.GetResourceGroupName(this.ResourceId); } if (Name == null) { Name = ResourceIdUtility.GetResourceName(this.ResourceId); } if (Version != null) { // This is a version specific update... PackagedTemplate packagedTemplate; switch (ParameterSetName) { case UpdateVersionByIdFromJsonFileParameterSet: case UpdateVersionByNameFromJsonFileParameterSet: string filePath = this.TryResolvePath(TemplateFile); if (!File.Exists(filePath)) { throw new PSInvalidOperationException( string.Format(ProjectResources.InvalidFilePath, TemplateFile) ); } packagedTemplate = TemplateSpecPackagingEngine.Pack(filePath); break; case UpdateVersionByIdFromJsonParameterSet: case UpdateVersionByNameFromJsonParameterSet: JObject parsedTemplate; try { parsedTemplate = JObject.Parse(TemplateJson); } catch { // Check if the user may have inadvertantly passed a file path using "-TemplateJson" // instead of using "-TemplateFile". If they did, display a warning message. Note we // do not currently automatically switch to using a file in this case because if the // JSON string is coming from an external script/source not authored directly by the // caller it could result in a sensitive template being PUT unintentionally: try { string asFilePath = this.TryResolvePath(TemplateJson); if (File.Exists(asFilePath)) { WriteWarning( $"'{TemplateJson}' was found to exist as a file. Did you mean to use '-TemplateFile' instead?" ); } } catch { // Subsequent failure in the file existence check... Ignore it } throw; } // When we're provided with a raw JSON string for the template we don't // do any special packaging... (ie: we don't pack artifacts because there // is no well known root path): packagedTemplate = new PackagedTemplate { RootTemplate = JObject.Parse(TemplateJson), Artifacts = new TemplateSpecArtifact[0] }; break; default: throw new PSNotSupportedException(); } if (!ShouldProcess($"{Name}/versions/{Version}", "Create or Update")) { return; } var templateSpecVersion = TemplateSpecsSdkClient.CreateOrUpdateTemplateSpecVersion( ResourceGroupName, Name, Version, Location, packagedTemplate, templateSpecDescription: Description, templateSpecDisplayName: DisplayName, versionDescription: VersionDescription, templateSpecTags: Tag, // Note: Only applied if template spec doesn't exist versionTags: Tag ); WriteObject(templateSpecVersion); } else { // This is an update to the root template spec only: if (!ShouldProcess(Name, "Create or Update")) { return; } var templateSpec = TemplateSpecsSdkClient.CreateOrUpdateTemplateSpec( ResourceGroupName, Name, Location, templateSpecDescription: Description, templateSpecDisplayName: DisplayName, tags: Tag ); // As the root template spec is a seperate resource type, it won't contain version // details. To provide more information to the user, let's get the template spec // with all of its version details: var templateSpecWithVersions = TemplateSpecsSdkClient.GetTemplateSpec(templateSpec.Name, templateSpec.ResourceGroupName); WriteObject(templateSpecWithVersions); } } catch (Exception ex) { WriteExceptionError(ex); } }