PageRenderTime 40ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/src/ServiceManagement/Services/Commands/Websites/PublishAzureWebsiteProject.cs

https://gitlab.com/jslee1/azure-powershell
C# | 200 lines | 154 code | 26 blank | 20 comment | 19 complexity | 249ffaa203085230f11c1d45494be245 MD5 | raw file
  1. using System;
  2. using System.Collections;
  3. using System.IO;
  4. using System.Management.Automation;
  5. using Microsoft.WindowsAzure.Commands.Properties;
  6. using Microsoft.WindowsAzure.Commands.Utilities.Common;
  7. using Microsoft.WindowsAzure.Commands.Utilities.Websites.Common;
  8. using Microsoft.Web.Deployment;
  9. namespace Microsoft.WindowsAzure.Commands.Websites
  10. {
  11. [Cmdlet(VerbsData.Publish, "AzureWebsiteProject")]
  12. public class PublishAzureWebsiteProject : WebsiteContextBaseCmdlet, IDynamicParameters
  13. {
  14. [Parameter(ParameterSetName = "ProjectFile", Position = 1, Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The Visual Studio web application project to be published.")]
  15. [ValidateNotNullOrEmpty]
  16. public string ProjectFile { get; set; }
  17. [Parameter(ParameterSetName = "ProjectFile", Position = 2, Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The configuration used to build the Visual Studio web application project.")]
  18. [ValidateNotNullOrEmpty]
  19. public string Configuration { get; set; }
  20. [Parameter(ParameterSetName = "Package", Position = 1, Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The WebDeploy package folder for zip file of the Visual Studio web application project to be published.")]
  21. [ValidateNotNullOrEmpty]
  22. public string Package { get; set; }
  23. [Parameter(ParameterSetName = "ProjectFile", Position = 3, Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The connection strings to use for the deployment.")]
  24. [Parameter(ParameterSetName = "Package", Position = 2, Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The connection strings to use for the deployment.")]
  25. [ValidateNotNullOrEmpty]
  26. public Hashtable ConnectionString { get; set; }
  27. [Parameter(ParameterSetName = "Package", Position = 3, Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The configuration tokens to use for the deployment.")]
  28. [ValidateNotNullOrEmpty]
  29. public string Tokens { get; set; }
  30. [Parameter(Mandatory = false, ParameterSetName = "Package", HelpMessage = "The WebDeploy SetParameters.xml file to transform configuration within the package.")]
  31. public string SetParametersFile { get; set; }
  32. [Parameter(Mandatory = false, ParameterSetName = "ProjectFile")]
  33. [Parameter(Mandatory = false, ParameterSetName = "Package")]
  34. public SwitchParameter SkipAppData { get; set; }
  35. [Parameter(Mandatory = false, ParameterSetName = "ProjectFile")]
  36. [Parameter(Mandatory = false, ParameterSetName = "Package")]
  37. public SwitchParameter DoNotDelete { get; set; }
  38. private string fullProjectFile;
  39. private string fullWebConfigFileWithConfiguration;
  40. private string fullWebConfigFile;
  41. private string fullPackage;
  42. private string fullSetParametersFile;
  43. private string configuration;
  44. private RuntimeDefinedParameterDictionary dynamicParameters;
  45. public override void ExecuteCmdlet()
  46. {
  47. PrepareFileFullPaths();
  48. // If a project file is specified, use MSBuild to build the package zip file.
  49. if (!string.IsNullOrEmpty(ProjectFile))
  50. {
  51. WriteVerbose(string.Format(Resources.StartBuildingProjectTemplate, fullProjectFile));
  52. fullPackage = WebsitesClient.BuildWebProject(fullProjectFile, configuration, Path.Combine(CurrentPath(), "build.log"));
  53. WriteVerbose(string.Format(Resources.CompleteBuildingProjectTemplate, fullProjectFile));
  54. }
  55. // Resolve the full path of the package file or folder when the "Package" parameter set is used.
  56. fullPackage = string.IsNullOrEmpty(fullPackage) ? this.TryResolvePath(Package) : fullPackage;
  57. WriteVerbose(string.Format(Resources.StartPublishingProjectTemplate, fullPackage));
  58. fullSetParametersFile = string.IsNullOrEmpty(fullSetParametersFile) ? this.TryResolvePath(SetParametersFile) : fullSetParametersFile;
  59. // Convert dynamic parameters to a connection string hash table.
  60. var connectionStrings = ConnectionString;
  61. if (connectionStrings == null)
  62. {
  63. connectionStrings = new Hashtable();
  64. if (dynamicParameters != null)
  65. {
  66. foreach (var dp in dynamicParameters)
  67. {
  68. if (MyInvocation.BoundParameters.ContainsKey(dp.Key))
  69. {
  70. connectionStrings[dp.Value.Name.ToString()] = dp.Value.Value.ToString();
  71. }
  72. }
  73. }
  74. }
  75. if (!string.IsNullOrEmpty(fullSetParametersFile) && !File.Exists(fullSetParametersFile))
  76. {
  77. if (File.Exists(Path.Combine(Path.GetDirectoryName(fullPackage), fullSetParametersFile)))
  78. {
  79. WriteVerbose("Setting path for Parameters file to local one to package: " + Path.Combine(Path.GetDirectoryName(fullPackage), fullSetParametersFile));
  80. fullSetParametersFile = Path.Combine(Path.GetDirectoryName(fullPackage),fullSetParametersFile);
  81. }
  82. }
  83. // If tokens are passed in, update the parameters file if there is one
  84. if (!string.IsNullOrEmpty(Tokens) && !string.IsNullOrEmpty(fullSetParametersFile))
  85. {
  86. // Convert tokens string to hashtable
  87. string[] tokenSplit = Tokens.Split(';');
  88. WriteVerbose(string.Format("Replacing tokens in {0}", fullSetParametersFile));
  89. var fileContents = File.ReadAllText(fullSetParametersFile);
  90. foreach (string pair in tokenSplit)
  91. {
  92. string[] data = pair.Split('=');
  93. fileContents = fileContents.Replace(string.Format("__{0}__", data[0].Replace("\"", "")), data[1].Replace("\"", ""));
  94. }
  95. File.WriteAllText(fullSetParametersFile, fileContents);
  96. }
  97. try
  98. {
  99. // Publish the package.
  100. DeploymentChangeSummary changeSummary = WebsitesClient.PublishWebProject(Name, Slot, fullPackage, fullSetParametersFile, connectionStrings, SkipAppData.IsPresent, DoNotDelete.IsPresent);
  101. WriteVerbose(string.Format(Resources.CompletePublishingProjectTemplate, fullPackage));
  102. if (changeSummary != null)
  103. {
  104. WriteObject("Change Summary:");
  105. WriteObject(string.Format("Bytes Copied: {0}", changeSummary.BytesCopied.ToString()));
  106. WriteObject(string.Format("Files Added: {0}", changeSummary.ObjectsAdded.ToString()));
  107. WriteObject(string.Format("Files Updated: {0}", changeSummary.ObjectsUpdated.ToString()));
  108. WriteObject(string.Format("Files Deleted: {0}", changeSummary.ObjectsDeleted.ToString()));
  109. WriteObject(string.Format("Errors: {0}", changeSummary.Errors.ToString()));
  110. WriteObject(string.Format("Warnings: {0}", changeSummary.Warnings.ToString()));
  111. WriteObject(string.Format("Parameters Changed: {0}", changeSummary.ParameterChanges.ToString()));
  112. WriteObject(string.Format("Total No of Changes: {0}", changeSummary.TotalChanges.ToString()));
  113. }
  114. }
  115. catch (Exception)
  116. {
  117. WriteVerbose(string.Format(Resources.FailPublishingProjectTemplate, fullPackage));
  118. throw;
  119. }
  120. }
  121. /// <summary>
  122. /// Generate dynamic parameters based on the connection strings in the Web.config.
  123. /// It will look at 2 Web.config files:
  124. /// 1. Web.config
  125. /// 2. Web.&lt;configuration&gt;.config (like Web.Release.config)
  126. /// This only works when -ProjectFile is used and -ConnectionString is not used.
  127. /// </summary>
  128. /// <returns>The dynamic parameters.</returns>
  129. public object GetDynamicParameters()
  130. {
  131. if (!string.IsNullOrEmpty(ProjectFile) && ConnectionString == null)
  132. {
  133. // Get the 2 Web.config files.
  134. PrepareFileFullPaths();
  135. dynamicParameters = new RuntimeDefinedParameterDictionary();
  136. if (string.Compare("ProjectFile", ParameterSetName) == 0)
  137. {
  138. // Parse the connection strings from the Web.config files.
  139. var names = WebsitesClient.ParseConnectionStringNamesFromWebConfig(fullWebConfigFile, fullWebConfigFileWithConfiguration);
  140. // Create a dynmaic parameter for each connection string using the same name.
  141. foreach (var name in names)
  142. {
  143. var parameter = new RuntimeDefinedParameter();
  144. parameter.Name = name;
  145. parameter.ParameterType = typeof(string);
  146. parameter.Attributes.Add(new ParameterAttribute()
  147. {
  148. ParameterSetName = "ProjectFile",
  149. Mandatory = false,
  150. ValueFromPipelineByPropertyName = true,
  151. HelpMessage = "Connection string from Web.config."
  152. }
  153. );
  154. dynamicParameters.Add(name, parameter);
  155. }
  156. }
  157. }
  158. return dynamicParameters;
  159. }
  160. /// <summary>
  161. /// Prepare the full path of the project file and Web.config files.
  162. /// </summary>
  163. private void PrepareFileFullPaths()
  164. {
  165. if (!string.IsNullOrEmpty(ProjectFile))
  166. {
  167. fullProjectFile = this.TryResolvePath(ProjectFile).Trim(new char[] { '"' });
  168. fullWebConfigFile = Path.Combine(Path.GetDirectoryName(fullProjectFile), "Web.config");
  169. configuration = string.IsNullOrEmpty(Configuration) ? "Release" : Configuration;
  170. fullWebConfigFileWithConfiguration = Path.Combine(Path.GetDirectoryName(fullProjectFile), string.Format("Web.{0}.config", configuration));
  171. }
  172. }
  173. }
  174. }