private static async Task CreateHostJson(Site site) { var credentials = new NetworkCredential(site.PublishingUserName, site.PublishingPassword); var vfsManager = new RemoteVfsManager($"{site.ScmUrl}vfs/", credentials, retryCount: 3); var hostId = new { id = Guid.NewGuid().ToString().Replace("-", "") }; var putTask = vfsManager.Put("site/wwwroot/host.json", new StringContent(JsonConvert.SerializeObject(hostId))); var deleteTask = vfsManager.Delete("site/wwwroot/hostingstart.html"); await Task.WhenAll(putTask, deleteTask); }
public static async Task AddTimeStampFile(Site site) { var credentials = new NetworkCredential(site.PublishingUserName, site.PublishingPassword); var vfsManager = new RemoteVfsManager(site.ScmUrl + "vfs/", credentials, retryCount: 3); var json = JsonConvert.SerializeObject(new { expiryTime = DateTime.UtcNow.AddMinutes(Double.Parse(SimpleSettings.VSCodeLinuxExpiryMinutes)).ToString() }); HttpContent content = new StringContent(json, Encoding.UTF8, "application/json"); Task addTimeStampFile = vfsManager.Put("site/wwwroot/metadata.json", content); await addTimeStampFile; }
private static async Task CreateSecretsForFunctionsContainer(Site site) { var credentials = new NetworkCredential(site.PublishingUserName, site.PublishingPassword); var vfsManager = new RemoteVfsManager($"{site.ScmUrl}vfs/", credentials, retryCount: 3); var secrets = new { masterKey = Util.GetRandomHexNumber(40), functionKey = Util.GetRandomHexNumber(40) }; await vfsManager.Put("data/functions/secrets/host.json", new StringContent(JsonConvert.SerializeObject(secrets))); }
public static async Task DeployVSCodeLinuxTemplateToSite(BaseTemplate template, Site site, bool addTimeStampFile = false) { SimpleTrace.TraceInformation($"Site ZipDeploy started: for {template?.MSDeployPackageUrl} on {site.SiteName}->{site.ResourceGroupName}->{site.SubscriptionId}"); if (template?.MSDeployPackageUrl != null) { try { var credentials = new NetworkCredential(site.PublishingUserName, site.PublishingPassword); var zipManager = new RemoteZipManager(site.ScmUrl + "api/zipdeploy?isAsync=true", credentials, retryCount: 3); Task <Uri> zipUpload = zipManager.PostZipFileAsync("", template.MSDeployPackageUrl); var deploystatusurl = await zipUpload; SimpleTrace.TraceInformation($"Site ZipDeployed: StatusUrl: {deploystatusurl} for {template?.MSDeployPackageUrl} on {site.SiteName}->{site.ResourceGroupName}->{site.SubscriptionId}"); var deploycheck = 0; var deploycheckTimes = 150; while (deploycheck++ < deploycheckTimes) { try { await Task.Delay(10 * 1000); var url = site.MonacoUrl.Replace(@"/basicauth", deploystatusurl.PathAndQuery); var httpClient = (HttpWebRequest)WebRequest.Create(url); { var creds = $"{site.PublishingUserName }:{ site.PublishingPassword}"; var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(creds); var credsbase64 = System.Convert.ToBase64String(plainTextBytes); httpClient.Headers.Add($"Authorization: Basic {credsbase64}"); using (var response = await httpClient.GetResponseAsync()) { using (var content = new StreamReader(response.GetResponseStream())) { var message = Newtonsoft.Json.Linq.JObject.Parse(content.ReadToEnd()); if ((bool)message["complete"] == false) { SimpleTrace.TraceInformation($"Zip Deployment going on: StatusUrl: {deploystatusurl} -{JsonConvert.SerializeObject(message)} for {template?.MSDeployPackageUrl} on {site.SiteName}->{site.ResourceGroupName}->{site.SubscriptionId}"); } else { SimpleTrace.TraceInformation($"Zip Deployment completed: StatusUrl: {deploystatusurl} -{JsonConvert.SerializeObject(message)} for {template?.MSDeployPackageUrl} on {site.SiteName}->{site.ResourceGroupName}->{site.SubscriptionId}"); break; } } } } } catch { SimpleTrace.TraceError($"Ping post ZipDeployed: StatusUrl: {deploystatusurl} for {template?.MSDeployPackageUrl} on {site.SiteName}->{site.ResourceGroupName}->{site.SubscriptionId}"); } } var vfsManager = new RemoteVfsManager(site.ScmUrl + "vfs/", credentials, retryCount: 3); Task deleteHostingStart = vfsManager.Delete("site/wwwroot/hostingstart.html"); List <Task> taskList = new List <Task>(); //taskList.Add(zipUpload); taskList.Add(deleteHostingStart); if (template.Name == Constants.ReactVSCodeWebAppLinuxTemplateName) { Task uploaddeploymentfile = vfsManager.Put("site/wwwroot/deploy.sh", (template?.MSDeployPackageUrl.Replace("ReactVSCodeWebApp.zip", "deploy.sh"))); Task uploaddeploysh = vfsManager.Put("site/wwwroot/.deployment", (template?.MSDeployPackageUrl.Replace("ReactVSCodeWebApp.zip", ".deployment"))); taskList.Add(uploaddeploymentfile); taskList.Add(uploaddeploysh); } if (addTimeStampFile) { SimpleTrace.TraceInformation($"Adding TimeStamp File started: for {site.SiteName}->{site.ResourceGroupName}->{site.SubscriptionId}"); Task timeStampAdd = AddTimeStampFile(site); taskList.Add(timeStampAdd); } await Task.WhenAll(taskList.ToArray()); SimpleTrace.TraceInformation($"Site ZipDeploy and Delete HostingStart completed: for {site.SiteName}->{site.ResourceGroupName}->{site.SubscriptionId}"); await Task.Delay(10 * 1000); } catch (Exception ex) { var message = "New Site wasnt deployed: " + ex.Message + ex.StackTrace; SimpleTrace.TraceError(message); throw new ZipDeploymentFailedException(message); } } else { SimpleTrace.TraceError("New Site wasnt deployed: MsDeployPackageUrl wasnt set"); } }
private static async Task <Site> CreateVSCodeLinuxSite(ResourceGroup resourceGroup, Func <string> nameGenerator, string siteKind = null) { var jsonSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; var site = new Site(resourceGroup.SubscriptionId, resourceGroup.ResourceGroupName, nameGenerator(), siteKind); var csmTemplateString = string.Empty; var template = TemplatesManager.GetTemplates().FirstOrDefault(t => t.Name == resourceGroup.TemplateName); SimpleTrace.TraceInformation($"Deploying {template.Name} to {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}"); csmTemplateString = await GetConfig(template.ARMTemplateLink); csmTemplateString = csmTemplateString .Replace("{{appServiceName}}", site.SiteName) .Replace("{{msdeployPackageUrl}}", template.MSDeployPackageUrl) .Replace("{{serverFarmType}}", SimpleSettings.ServerFarmTypeContent) .Replace("{{tryAppserviceUrl}}", SimpleSettings.TryAppServiceSite); var inProgressOperation = new InProgressOperation(resourceGroup, DeploymentType.CsmDeploy); var token = await inProgressOperation.CreateDeployment(JsonConvert.DeserializeObject <JToken>(csmTemplateString), block : true, subscriptionType : resourceGroup.SubscriptionType); SimpleTrace.TraceInformation($"ARM Deployment result: {JsonConvert.SerializeObject(token)} to {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}"); var csmSiteResponse = await GetClient(resourceGroup.SubscriptionType).HttpInvoke(HttpMethod.Get, ArmUriTemplates.SiteCreate.Bind(site)); await csmSiteResponse.EnsureSuccessStatusCodeWithFullError(); var csmSite = await csmSiteResponse.Content.ReadAsAsync <CsmWrapper <CsmSite> >(); await Load(site, csmSite); SimpleTrace.TraceInformation($"Site Loaded from ARM : {JsonConvert.SerializeObject(site)} to {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}"); var siteguid = await Util.UpdatePostDeployAppSettings(site); SimpleTrace.TraceInformation($"Site AppSettings Updated: for {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}"); if (resourceGroup.AppService == AppService.VSCodeLinux) { await Task.Delay(30 * 1000); try { var lsm = new LinuxSiteManager.Client.LinuxSiteManager(retryCount: 30); await lsm.CheckSiteDeploymentStatusAsync(site.HttpUrl); } catch (Exception ex) { SimpleTrace.TraceError($"Unable to ping deployed site {site.HostName}. Continuing regardless {ex.Message}->{ex.StackTrace} "); } } if (!resourceGroup.Tags.ContainsKey(Constants.TemplateName)) { resourceGroup.Tags.Add(Constants.TemplateName, resourceGroup.TemplateName); } if (resourceGroup.SubscriptionType == SubscriptionType.AppService) { if (template != null && template.FileName != null) { var credentials = new NetworkCredential(site.PublishingUserName, site.PublishingPassword); var vfsSCMManager = new RemoteVfsManager(site.ScmUrl + "vfs/", credentials, retryCount: 3); Task scmRedirectUpload = vfsSCMManager.Put("site/applicationHost.xdt", Path.Combine(HostingEnvironment.MapPath(@"~/App_Data"), "applicationHost.xdt")); var vfsManager = new RemoteVfsManager(site.ScmUrl + "vfs/", credentials, retryCount: 3); await Task.WhenAll(scmRedirectUpload); } } if (template.Name.Equals("WordPress", StringComparison.OrdinalIgnoreCase)) { await site.UpdateConfig(new { properties = new { scmType = "LocalGit", httpLoggingEnabled = true, localMySqlEnabled = true } }); } resourceGroup.Tags[Constants.TemplateName] = template.Name; site.SubscriptionId = resourceGroup.SubscriptionId; //site.AppSettings = new Dictionary<string, string>(); resourceGroup.Tags.Add(Constants.SiteGuid, siteguid); await Task.WhenAll(resourceGroup.Update()); SimpleTrace.TraceInformation($"ResourceGroup Templates Tag Updated: with SiteGuid: {siteguid} for {site.SiteName} ->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}"); return(site); }
// ARM public async Task <ResourceGroup> ActivateWebApp(BaseTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName, AppService temp = AppService.Web) { // Start site specific stuff var deploymentType = template != null && template.GithubRepo != null ? DeploymentType.GitWithCsmDeploy : DeploymentType.ZipDeploy; return(await ActivateResourceGroup(userIdentity, temp, deploymentType, async (resourceGroup, inProgressOperation) => { SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}; ", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, "NA", template.Name, resourceGroup.ResourceUniqueId, temp.ToString()); var site = resourceGroup.Sites.First(s => s.IsSimpleWAWSOriginalSite); var rbacTask = resourceGroup.AddResourceGroupRbac(userIdentity.Puid, userIdentity.Email); if (template != null && template.FileName != null) { var credentials = new NetworkCredential(site.PublishingUserName, site.PublishingPassword); var zipManager = new RemoteZipManager(site.ScmUrl + "zip/", credentials, retryCount: 3); Task zipUpload = zipManager.PutZipFileAsync("site/wwwroot", template.GetFullPath()); var vfsSCMManager = new RemoteVfsManager(site.ScmUrl + "vfs/", credentials, retryCount: 3); Task scmRedirectUpload = vfsSCMManager.Put("site/applicationHost.xdt", Path.Combine(HostingEnvironment.MapPath(@"~/App_Data"), "applicationHost.xdt")); var vfsManager = new RemoteVfsManager(site.ScmUrl + "vfs/", credentials, retryCount: 3); Task deleteHostingStart = vfsManager.Delete("site/wwwroot/hostingstart.html"); await Task.WhenAll(zipUpload, scmRedirectUpload, deleteHostingStart); } else if (template != null && template.GithubRepo != null) { Uri githubRepo; var validUri = Uri.TryCreate(template.GithubRepo, UriKind.Absolute, out githubRepo); if (validUri && (githubRepo.AbsoluteUri.StartsWith("https://github.com/davidebbo-test/") || githubRepo.AbsoluteUri.StartsWith("https://github.com/ahmelsayed-test"))) { //Do CSM template deployment var csmTemplate = new CsmTemplateWrapper { properties = new CsmTemplateProperties { mode = "Incremental", parameters = new { siteName = new CsmTemplateParameter(site.SiteName), hostingPlanName = new CsmTemplateParameter(resourceGroup.ServerFarms.Select(sf => sf.ServerFarmName).FirstOrDefault()), repoUrl = new CsmTemplateParameter(githubRepo.AbsoluteUri) }, templateLink = new CsmTemplateLink { contentVersion = "1.0.0.0", uri = new Uri("https://raw.githubusercontent.com/" + githubRepo.AbsolutePath.Trim('/') + "/master/azuredeploy.json") } } }; await inProgressOperation.CreateDeployment(csmTemplate, block: true, subscriptionType: resourceGroup.SubscriptionType); await site.GetKuduDeploymentStatus(block: true); await resourceGroup.Load(); } else if (validUri && githubRepo.AbsoluteUri.StartsWith("https://github.com/")) { //Do Kudu deployment throw new InvalidGithubRepoException(); } else { throw new InvalidGithubRepoException(); } } resourceGroup.Tags[Constants.TemplateName] = template.Name; site.AppSettings["LAST_MODIFIED_TIME_UTC"] = DateTime.UtcNow.ToString(CultureInfo.InvariantCulture); site.AppSettings["WEBSITE_TRY_MODE"] = "1"; if (site.SubscriptionType != SubscriptionType.VSCodeLinux) { site.AppSettings["SITE_LIFE_TIME_IN_MINUTES"] = SimpleSettings.SiteExpiryMinutes; } if (site.AppSettings.ContainsKey("FUNCTIONS_EXTENSION_VERSION")) { site.AppSettings.Remove("FUNCTIONS_EXTENSION_VERSION"); } if (template.Name.Equals("ASP.NET with Azure Search Site", StringComparison.OrdinalIgnoreCase)) { site.AppSettings["SearchServiceName"] = SimpleSettings.SearchServiceName; site.AppSettings["SearchServiceApiKey"] = AzureSearchHelper.GetApiKey(); } await Task.WhenAll(site.UpdateAppSettings(), resourceGroup.Update()); if (template.GithubRepo == null) { if (site.IsFunctionsContainer) { await site.UpdateConfig(new { properties = new { scmType = "None", httpLoggingEnabled = true } }); } else if (template.Name.Equals("WordPress", StringComparison.OrdinalIgnoreCase)) { await site.UpdateConfig(new { properties = new { scmType = "LocalGit", httpLoggingEnabled = true, localMySqlEnabled = true } }); } else { await site.UpdateConfig(new { properties = new { scmType = "LocalGit", httpLoggingEnabled = true } }); } } resourceGroup.IsRbacEnabled = await rbacTask; Util.WarmUpSite(site); return resourceGroup; })); }