// ARM public async Task <ResourceGroup> ActivateLogicApp(BaseTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Logic, DeploymentType.CsmDeploy, async (resourceGroup, inProgressOperation) => { SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, "Logic", template.Name, resourceGroup.ResourceUniqueId, AppService.Logic.ToString()); var logicApp = new LogicApp(resourceGroup.SubscriptionId, resourceGroup.ResourceGroupName, Guid.NewGuid().ToString().Replace("-", "")) { Location = resourceGroup.GeoRegion }; var csmTemplateString = string.Empty; using (var reader = new StreamReader(((SimpleWAWS.Models.LogicTemplate)(TemplatesManager.GetTemplates().FirstOrDefault((a) => a.AppService == AppService.Logic))).CsmTemplateFilePath)) { csmTemplateString = await reader.ReadToEndAsync(); } csmTemplateString = csmTemplateString.Replace("{{logicAppName}}", logicApp.LogicAppName); //csmTemplateString = csmTemplateString.Replace("{{gatewayName}}", Guid.NewGuid().ToString().Replace("-", "")).Replace("{{logicAppName}}", logicApp.LogicAppName); await inProgressOperation.CreateDeployment(JsonConvert.DeserializeObject <JToken>(csmTemplateString), block: true, subscriptionType: resourceGroup.SubscriptionType); // After a deployment, we have no idea what changes happened in the resource group // we should reload it. // TODO: consider reloading the resourceGroup along with the deployment itself. await resourceGroup.Load(); var rbacTask = resourceGroup.AddResourceGroupRbac(userIdentity.Puid, userIdentity.Email); resourceGroup.IsRbacEnabled = await rbacTask; return resourceGroup; })); }
// ARM public async Task <ResourceGroup> ActivateFunctionApp(BaseTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Function, DeploymentType.FunctionDeploy, async (resourceGroup, inProgressOperation) => { SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, "Function", template.Name, resourceGroup.ResourceUniqueId, AppService.Function.ToString()); //var functionApp = resourceGroup.Site; //if (template.Name.Contains(Constants.CSharpLanguage)) //{ // functionApp.AppSettings[Constants.FunctionsRuntimeAppSetting] = Constants.DotNetRuntime; //} //else if (template.Name.Contains(Constants.JavaScriptLanguage)) //{ // functionApp.AppSettings[Constants.FunctionsRuntimeAppSetting] = Constants.JavaScriptRuntime; //} //await functionApp.UpdateAppSettings(); Util.WarmUpSite(resourceGroup.Site); //resourceGroup.Tags[Constants.TemplateName] = template.Name; //await resourceGroup.Update(); return resourceGroup; }, template)); }
// 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.Site; //if (template != null && template.FileName != null) //{ // var credentials = new NetworkCredential(site.PublishingUserName, site.PublishingPassword); // var zipManager = new RemoteZipManager(site.ScmUrl + "zip/", credentials, retryCount: 3); // 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(scmRedirectUpload, deleteHostingStart); //} resourceGroup.Tags[Constants.TemplateName] = template.Name; site.SubscriptionId = resourceGroup.SubscriptionId; await site.LoadAppSettings(); 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.Name.Equals("WordPress", StringComparison.OrdinalIgnoreCase)) //{ // await site.UpdateConfig(new {properties = new {scmType = "LocalGit", httpLoggingEnabled = true, localMySqlEnabled = true} }); //} Util.WarmUpSite(site); return resourceGroup; }, template)); }
// ARM public async Task <ResourceGroup> ActivateFunctionApp(BaseTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Function, DeploymentType.FunctionDeploy, async (resourceGroup, inProgressOperation) => { SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, "Function", template.Name, resourceGroup.ResourceUniqueId, AppService.Function.ToString()); Util.WarmUpSite(resourceGroup.Sites.First(s => s.IsFunctionsContainer)); var rbacTask = resourceGroup.AddResourceGroupRbac(userIdentity.Puid, userIdentity.Email, isFunctionContainer: true); resourceGroup.Tags[Constants.TemplateName] = template.Name; await resourceGroup.Update(); resourceGroup.IsRbacEnabled = await rbacTask; return resourceGroup; })); }
// ARM public async Task <ResourceGroup> ActivateApiApp(ApiTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Api, DeploymentType.CsmDeploy, async (resourceGroup, inProgressOperation) => { SimpleTrace.Analytics.Information(AnalyticsEvents.UserCreatedSiteWithLanguageAndTemplateName, userIdentity, template, resourceGroup.CsmId); SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}; {5}; {6}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, userIdentity.Name, "Api", template.ApiTemplateName, resourceGroup.ResourceUniqueId, AppService.Api.ToString(), anonymousUserName); //SimpleTrace.UserCreatedApiApp() var apiApp = new ApiApp(resourceGroup.SubscriptionId, resourceGroup.ResourceGroupName, Guid.NewGuid().ToString().Replace("-", "")) { MicroserviceId = template.ApiTemplateName, Location = resourceGroup.GeoRegion }; var csmTemplate = await apiApp.GenerateCsmTemplate(); var templateWrapper = new CsmTemplateWrapper { properties = new CsmTemplateProperties { mode = "Incremental", parameters = apiApp.GenerateTemplateParameters(), template = csmTemplate } }; await inProgressOperation.CreateDeployment(templateWrapper, block: true); // We don't need the original site that we create for Web or Mobile apps, delete it or it'll show up in ibiza await resourceGroup.Sites.Where(s => s.IsSimpleWAWSOriginalSite).Select(s => s.Delete()).IgnoreFailures().WhenAll(); // After a deployment, we have no idea what changes happened in the resource group, we should reload it. await resourceGroup.Load(); var rbacTask = resourceGroup.AddResourceGroupRbac(userIdentity.Puid, userIdentity.Email); var publicAccessTask = resourceGroup.ApiApps.Select(a => a.SetAccessLevel("PublicAnonymous")); resourceGroup.IsRbacEnabled = await rbacTask; await publicAccessTask.WhenAll(); return resourceGroup; })); }
public static void UserCreatedApp(TryWebsitesIdentity userIdentity, BaseTemplate template, ResourceGroup resourceGroup, AppService logic) { // Get the current journey for the user and add an app and update count. }
// ARM private async Task <ResourceGroup> ActivateResourceGroup(TryWebsitesIdentity userIdentity, AppService appService, DeploymentType deploymentType, Func <ResourceGroup, InProgressOperation, Task <ResourceGroup> > func, string template = "") { ResourceGroup resourceGroup = null; if (userIdentity == null) { throw new InvalidUserIdentityException(); } var userId = userIdentity.Name; try { if (_backgroundQueueManager.ResourceGroupsInUse.TryGetValue(userId, out resourceGroup)) { throw new MoreThanOneResourceGroupException(); } bool resourceGroupFound = false; if (appService == AppService.Containers || appService == AppService.Linux) { resourceGroupFound = _backgroundQueueManager.FreeLinuxResourceGroups.TryDequeue(out resourceGroup); } else if ((appService == AppService.VSCodeLinux)) { if (_backgroundQueueManager.FreeVSCodeLinuxResourceGroups[template] != null) { resourceGroupFound = _backgroundQueueManager.FreeVSCodeLinuxResourceGroups[template].TryDequeue(out resourceGroup); } else { resourceGroupFound = false; } } else if ((appService != AppService.MonitoringTools)) { resourceGroupFound = _backgroundQueueManager.FreeResourceGroups.TryDequeue(out resourceGroup); } else if ((appService == AppService.MonitoringTools)) { resourceGroup = _backgroundQueueManager.MonitoringResourceGroup; BackgroundQueueManager.MonitoringResourceGroupCheckoutTimes.AddOrUpdate(userId, DateTime.UtcNow, (key, oldValue) => DateTime.UtcNow); SimpleTrace.Diagnostics.Information("resourceGroup {resourceGroupId} is now assigned", resourceGroup.CsmId); return(await func(resourceGroup, null)); } if (resourceGroupFound) { //mark site in use as soon as it's checked out so that if there is a reload it will be sorted out to the used queue. await resourceGroup.MarkInUse(userId, appService); //var rbacTask = Task.FromResult(false); //RbacHelper.AddRbacUser(userIdentity.Puid, userIdentity.Email, resourceGroup); var process = new InProgressOperation(resourceGroup, deploymentType); _backgroundQueueManager.ResourceGroupsInProgress.AddOrUpdate(userId, s => process, (s, task) => process); SimpleTrace.Diagnostics.Information("site {siteId} is now in use", String.Concat(resourceGroup.CsmId, "/", resourceGroup.Sites.FirstOrDefault(s => s.IsSimpleWAWSOriginalSite).SiteName)); resourceGroup = await func(resourceGroup, process); var addedResourceGroup = _backgroundQueueManager.ResourceGroupsInUse.GetOrAdd(userId, resourceGroup); if (addedResourceGroup.ResourceGroupName == resourceGroup.ResourceGroupName) { //this means we just added the resourceGroup for the user. //Removing this line since we have already marked the resourcegroup as in use by the user //await addedResourceGroup.MarkInUse(userId, appService); return(addedResourceGroup); } else { //this means the user is trying to add more than 1 site. //delete the new site that's not yet added to the used list SimpleTrace.Diagnostics.Information("User asked for more than 1 site. Replacing {resourceGroup.CsmId}", resourceGroup.CsmId); await resourceGroup.DeleteAndCreateReplacement(); throw new MoreThanOneResourceGroupException(); } } else { throw new NoFreeResourceGroupsException(); } // End site specific stuff } catch (MoreThanOneResourceGroupException) { throw; } catch (NoFreeResourceGroupsException) { throw; } catch (InvalidGithubRepoException) { throw; } catch (Exception e) { //unknown exception, log it SimpleTrace.Diagnostics.Fatal(e, "Unknown error during UserCreate, Count {Count}", Interlocked.Increment(ref _unknownErrorInCreateErrorCount)); } finally { InProgressOperation temp; if (_backgroundQueueManager.ResourceGroupsInProgress.TryRemove(userId, out temp)) { temp.Complete(); LogQueueStatistics(); } } //if we are here that means a bad exception happened above, but we might leak a site if we don't remove the site and replace it correctly. if (resourceGroup != null) { DeleteResourceGroup(resourceGroup); } throw new Exception(Resources.Server.Error_GeneralErrorMessage); }
public async Task <ResourceGroup> ActivateContainersResource(ContainersTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Containers, DeploymentType.CsmDeploy, async (resourceGroup, inProgressOperation) => { SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, "Containers", template.Name, resourceGroup.ResourceUniqueId, AppService.Containers.ToString()); var site = resourceGroup.Sites.First(s => s.IsSimpleWAWSOriginalSite); resourceGroup.Tags[Constants.TemplateName] = template.Name; resourceGroup = await resourceGroup.Update(); if (!string.IsNullOrEmpty(template.DockerContainer)) { var qualifiedContainerName = QualifyContainerName(template.DockerContainer); await site.UpdateConfig(new { properties = new { linuxFxVersion = qualifiedContainerName } }); } Util.WarmUpSite(resourceGroup.Sites.FirstOrDefault()); var rbacTask = resourceGroup.AddResourceGroupRbac(userIdentity.Puid, userIdentity.Email); resourceGroup.IsRbacEnabled = await rbacTask; return resourceGroup; })); }
// ARM public async Task <ResourceGroup> ActivateFunctionApp(FunctionTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Function, false, DeploymentType.FunctionDeploy, async (resourceGroup, inProgressOperation) => { SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, "Function", template.Name, resourceGroup.ResourceUniqueId, AppService.Function.ToString()); Util.FireAndForget(resourceGroup.Sites.First(s => s.IsFunctionsContainer).HostName); var rbacTask = resourceGroup.AddResourceGroupRbac(userIdentity.Puid, userIdentity.Email, isFunctionContainer: true); resourceGroup.Tags[Constants.TemplateName] = template.Name; await resourceGroup.Update(); await resourceGroup.Sites.First(s => s.IsFunctionsContainer).UpdateConfig(new { properties = new { cors = new { allowedOrigins = new string[] { "https://functions.azure.com", "https://functions-staging.azure.com", "https://functions-next.azure.com", "https://localhost:44300", "https://tryfunctions.com", "https://www.tryfunctions.com", "https://tryfunctions.azure.com", "https://tryfunctions-staging.azure.com", "https://www.tryfunctions-staging.azure.com" } } } }); resourceGroup.IsRbacEnabled = await rbacTask; return resourceGroup; })); }
// ARM public async Task <ResourceGroup> ActivateWebApp(WebsiteTemplate 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.Analytics.Information(AnalyticsEvents.UserCreatedSiteWithLanguageAndTemplateName, userIdentity, template, resourceGroup.CsmId); SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}; {5}; {6}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, userIdentity.Name, template.Language, template.Name, resourceGroup.ResourceUniqueId, temp.ToString(), anonymousUserName); SimpleTrace.UserCreatedApp(userIdentity, template, resourceGroup, temp); 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 vfsManager = new RemoteVfsManager(site.ScmUrl + "vfs/", credentials, retryCount: 3); Task deleteHostingStart = vfsManager.Delete("site/wwwroot/hostingstart.html"); await Task.WhenAll(zipUpload, 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); 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["SITE_LIFE_TIME_IN_MINUTES"] = SimpleSettings.SiteExpiryMinutes; site.AppSettings["MONACO_EXTENSION_VERSION"] = SimpleSettings.MonacoExtensionVersion; site.AppSettings["WEBSITE_TRY_MODE"] = "1"; 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(); } else if (template.Name.Equals("PHP Starter Site", StringComparison.OrdinalIgnoreCase)) { //Enable ZRay await site.EnableZRay(resourceGroup.GeoRegion); } 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 { await site.UpdateConfig(new { properties = new { scmType = "LocalGit", httpLoggingEnabled = true } }); } } resourceGroup.IsRbacEnabled = await rbacTask; site.FireAndForget(); return resourceGroup; })); }
// ARM private async Task <ResourceGroup> ActivateResourceGroup(TryWebsitesIdentity userIdentity, AppService appService, DeploymentType deploymentType, Func <ResourceGroup, InProgressOperation, Task <ResourceGroup> > func, BaseTemplate template = null) { ResourceGroup resourceGroup = null; if (userIdentity == null) { throw new InvalidUserIdentityException(); } var userId = userIdentity.Name; try { if (await StorageHelper.GetAssignedResourceGroup(userId) != null) { throw new MoreThanOneResourceGroupException(); } bool resourceGroupFound = false; SimpleTrace.TraceInformation($"Searching vscodequeue for template '{template.QueueName}': Count of templates:{await StorageHelper.GetQueueCount(template.QueueName)} "); if (await StorageHelper.GetQueueCount(template.QueueName) > 0) { var totalTries = 3; var tries = 0; //bool siteFound = false; while (tries++ < totalTries && !resourceGroupFound) { resourceGroup = await StorageHelper.GetQueueMessage(template.QueueName); resourceGroupFound = (resourceGroup != null); if (resourceGroupFound) { // try // { // var a = Dns.GetHostEntry(resourceGroup.Sites.FirstOrDefault().HostName); // if (a != null) // { // siteFound = true; // } // } // catch // { // resourceGroupFound = false; // SimpleTrace.TraceInformation($"Found ResourceGroup but HostName isnt active '{resourceGroup.ResourceGroupName}' with template {resourceGroup.DeployedTemplateName}"); // } SimpleTrace.TraceInformation($"Found ResourceGroup '{resourceGroup.ResourceGroupName}' with template {resourceGroup.DeployedTemplateName}"); } else { SimpleTrace.TraceInformation($"No resource found in free queue for '{template.Name}' "); } } } if (resourceGroupFound) { //mark site in use as soon as it's checked out so that if there is a reload it will be sorted out to the used queue. await resourceGroup.MarkInUse(userId, appService); //var rbacTask = Task.FromResult(false); //RbacHelper.AddRbacUser(userIdentity.Puid, userIdentity.Email, resourceGroup); var process = new InProgressOperation(resourceGroup, deploymentType); _backgroundQueueManager.ResourceGroupsInProgress.AddOrUpdate(userId, s => process, (s, task) => process); SimpleTrace.Diagnostics.Information("site {siteId} is now in use", String.Concat(resourceGroup.CsmId, "/", resourceGroup.Site.SiteName)); resourceGroup = await func(resourceGroup, process); var addedResourceGroup = await StorageHelper.AssignResourceGroup(userId, resourceGroup); if (addedResourceGroup) { //this means we just added the resourceGroup for the user. //Removing this line since we have already marked the resourcegroup as in use by the user //await addedResourceGroup.MarkInUse(userId, appService); return(resourceGroup); } else { //this means the user is trying to add more than 1 site. //delete the new site that's not yet added to the used list SimpleTrace.Diagnostics.Information("User asked for more than 1 site. Replacing {resourceGroup.CsmId}", resourceGroup.CsmId); await resourceGroup.DeleteAndCreateReplacement(); throw new MoreThanOneResourceGroupException(); } } else { SimpleTrace.Diagnostics.Information("No resource group found yet. Shouldnt be here"); throw new NoFreeResourceGroupsException(); } // End site specific stuff } catch (MoreThanOneResourceGroupException) { throw; } catch (NoFreeResourceGroupsException) { throw; } catch (InvalidGithubRepoException) { throw; } catch (Exception e) { //unknown exception, log it SimpleTrace.Diagnostics.Fatal(e, "Unknown error during UserCreate, Count {Count}", Interlocked.Increment(ref _unknownErrorInCreateErrorCount)); } finally { InProgressOperation temp; if (_backgroundQueueManager.ResourceGroupsInProgress.TryRemove(userId, out temp)) { temp.Complete(); LogQueueStatistics(); } } //if we are here that means a bad exception happened above, but we might leak a site if we don't remove the site and replace it correctly. if (resourceGroup != null) { DeleteResourceGroup(resourceGroup); } throw new Exception(Resources.Server.Error_GeneralErrorMessage); }
public async Task <ResourceGroup> ActivateContainersResource(BaseTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Containers, DeploymentType.CsmDeploy, async (resourceGroup, inProgressOperation) => { SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, "Containers", template.Name, resourceGroup.ResourceUniqueId, AppService.Containers.ToString()); var site = resourceGroup.Site; //resourceGroup.Tags[Constants.TemplateName] = template.Name; //resourceGroup = await resourceGroup.Update(); if (string.IsNullOrEmpty(template.DockerContainer)) { template.DockerContainer = "appsvc/dotnetcore"; } var qualifiedContainerName = QualifyContainerName(template.DockerContainer); site.SubscriptionId = resourceGroup.SubscriptionId; await site.UpdateConfig(new { properties = new { linuxFxVersion = qualifiedContainerName } }); Util.WarmUpSite(resourceGroup.Site); return resourceGroup; }, template)); }
// ARM public async Task <ResourceGroup> ActivateLinuxResource(BaseTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Linux, DeploymentType.CsmDeploy, async (resourceGroup, inProgressOperation) => { SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, "Linux", template.Name, resourceGroup.ResourceUniqueId, AppService.Linux.ToString()); //var site = resourceGroup.Site; //resourceGroup.Tags[Constants.TemplateName] = template.Name; //resourceGroup = await resourceGroup.Update(); //site.SubscriptionId = resourceGroup.SubscriptionId; //await Util.DeployLinuxTemplateToSite(template, site); return resourceGroup; }, template)); }
public static void AnonymousUserLoggedIn(TryWebsitesIdentity anonymousIdentity, TryWebsitesIdentity identity) { // Get the anonymous journey for the user and create a logged in user journey for it. }
public async Task <ResourceGroup> ActivateMonitoringToolsApp(BaseTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.MonitoringTools, DeploymentType.RbacOnly, async (resourceGroup, inProgressOperation) => { SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, "MonitoringTools", template.Name, resourceGroup.ResourceUniqueId, AppService.MonitoringTools.ToString()); var rbacTask = resourceGroup.AddResourceGroupRbac(userIdentity.Puid, userIdentity.Email); resourceGroup.IsRbacEnabled = await rbacTask; return resourceGroup; })); }
// ARM private async Task <ResourceGroup> ActivateResourceGroup(TryWebsitesIdentity userIdentity, AppService appService, DeploymentType deploymentType, Func <ResourceGroup, InProgressOperation, Task <ResourceGroup> > func) { ResourceGroup resourceGroup = null; if (userIdentity == null) { throw new InvalidUserIdentityException(); } var userId = userIdentity.Name; try { if (_backgroundQueueManager.ResourceGroupsInUse.TryGetValue(userId, out resourceGroup)) { throw new MoreThanOneResourceGroupException(); } if (_backgroundQueueManager.FreeResourceGroups.TryDequeue(out resourceGroup)) { //mark site in use as soon as it's checked out so that if there is a reload it will be sorted out to the used queue. await resourceGroup.MarkInUse(userId, appService); var rbacTask = Task.FromResult(false); //RbacHelper.AddRbacUser(userIdentity.Puid, userIdentity.Email, resourceGroup); var process = new InProgressOperation(resourceGroup, deploymentType); _backgroundQueueManager.ResourceGroupsInProgress.AddOrUpdate(userId, s => process, (s, task) => process); SimpleTrace.Diagnostics.Information("resourceGroup {resourceGroupId} is now in use", resourceGroup.CsmId); resourceGroup = await func(resourceGroup, process); var addedResourceGroup = _backgroundQueueManager.ResourceGroupsInUse.GetOrAdd(userId, resourceGroup); if (addedResourceGroup.ResourceGroupName == resourceGroup.ResourceGroupName) { //this means we just added the resourceGroup for the user. await addedResourceGroup.MarkInUse(userId, appService); return(addedResourceGroup); } else { //this means the user is trying to add more than 1 site. //delete the new site that's not yet added to the used list await resourceGroup.DeleteAndCreateReplacement(); throw new MoreThanOneResourceGroupException(); } } else { throw new NoFreeResourceGroupsException(); } // End site specific stuff } catch (MoreThanOneResourceGroupException) { throw; } catch (NoFreeResourceGroupsException) { throw; } catch (InvalidGithubRepoException) { throw; } catch (Exception e) { //unknown exception, log it SimpleTrace.Diagnostics.Fatal(e, "Unknown error during UserCreate, Count {Count}", Interlocked.Increment(ref _unknownErrorInCreateErrorCount)); } finally { InProgressOperation temp; if (_backgroundQueueManager.ResourceGroupsInProgress.TryRemove(userId, out temp)) { temp.Complete(); LogQueueStatistics(); } } //if we are here that means a bad exception happened above, but we might leak a site if we don't remove the site and replace it correctly. if (resourceGroup != null) { DeleteResourceGroup(resourceGroup); } throw new Exception(Resources.Server.Error_GeneralErrorMessage); }
public async Task <ResourceGroup> ActivateLinuxResource(BaseTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Linux, DeploymentType.CsmDeploy, async (resourceGroup, inProgressOperation) => { SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, "Linux", template.Name, resourceGroup.ResourceUniqueId, AppService.Linux.ToString()); var site = resourceGroup.Sites.First(s => s.IsSimpleWAWSOriginalSite); resourceGroup.Tags[Constants.TemplateName] = template.Name; resourceGroup = await resourceGroup.Update(); await Util.DeployLinuxTemplateToSite(template, site); var rbacTask = resourceGroup.AddResourceGroupRbac(userIdentity.Puid, userIdentity.Email); resourceGroup.IsRbacEnabled = await rbacTask; return resourceGroup; })); }
// ARM public async Task <ResourceGroup> ActivateMobileApp(WebsiteTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateWebApp(template, userIdentity, anonymousUserName, AppService.Mobile)); }
public async Task <ResourceGroup> ActivateVSCodeLinuxResource(BaseTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.VSCodeLinux, DeploymentType.CsmDeploy, async (resourceGroup, inProgressOperation) => { SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, "VSCodeLinux", template.Name, resourceGroup.ResourceUniqueId, AppService.VSCodeLinux.ToString()); var site = resourceGroup.Sites.First(s => s.IsSimpleWAWSOriginalSite); //if (template.Name.Equals(Constants.NodejsVSCodeWebAppLinuxTemplateName, StringComparison.OrdinalIgnoreCase)) //{ await Util.AddTimeStampFile(site); var lsm = new LinuxSiteManager.Client.LinuxSiteManager(retryCount: 2); Task checkSite = lsm.CheckTimeStampMetaDataDeploymentStatusAsync(site.Url); try { await checkSite; SimpleTrace.TraceError("Forcing retry"); } catch (Exception ex) { //TODO: Alert on this specifically after we add parsing logic SimpleTrace.TraceError("New TimeStamp wasnt deployed" + ex.Message + ex.StackTrace); } //} //else //{ // await Util.DeployVSCodeLinuxTemplateToSite(template, site, addTimeStampFile:true); //} return resourceGroup; }, template.Name)); }
public async Task <ResourceGroup> ActivateJenkinsResource(JenkinsTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Jenkins, DeploymentType.CsmDeploy, async (resourceGroup, inProgressOperation) => { SimpleTrace.Analytics.Information(AnalyticsEvents.UserCreatedSiteWithLanguageAndTemplateName, userIdentity.Name, template, resourceGroup); SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}; {5}; {6}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, userIdentity.Name, "Jenkins", template.Name, resourceGroup.ResourceUniqueId, AppService.Jenkins.ToString(), anonymousUserName); SimpleTrace.UserCreatedApp(userIdentity, template, resourceGroup, AppService.Jenkins); var csmTemplateString = string.Empty; using (var reader = new StreamReader(template.CsmTemplateFilePath)) { csmTemplateString = await reader.ReadToEndAsync(); } csmTemplateString = csmTemplateString.Replace("{{jenkinsPassword}}", SimpleSettings.TryDevOpsVMPassword); await inProgressOperation.CreateDeployment(JsonConvert.DeserializeObject <JToken>(csmTemplateString), block: true); // After a deployment, we have no idea what changes happened in the resource group // we should reload it. // TODO: consider reloading the resourceGroup along with the deployment itself. await resourceGroup.Load(loadJenkinsResources: true); resourceGroup.IsRbacEnabled = false; return resourceGroup; })); }
public async Task <ResourceGroup> ActivateLinuxResource(LinuxTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Web, true, DeploymentType.CsmDeploy, async (resourceGroup, inProgressOperation) => { SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}", AnalyticsEvents.OldUserCreatedSiteWithLanguageAndTemplateName, "Linux", template.Name, resourceGroup.ResourceUniqueId, AppService.Web.ToString()); var site = resourceGroup.Sites.First(s => s.IsSimpleWAWSOriginalSite); resourceGroup.Tags[Constants.TemplateName] = template.Name; resourceGroup = await resourceGroup.Update(); if (template?.MSDeployPackageUrl != null) { try { 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.MSDeployPackageUrl); var vfsManager = new RemoteVfsManager(site.ScmUrl + "vfs/", credentials, retryCount: 3); Task deleteHostingStart = vfsManager.Delete("site/wwwroot/hostingstart.html"); await Task.WhenAll(zipUpload, deleteHostingStart); } catch (Exception ex) { SimpleTrace.TraceError(ex.Message + ex.StackTrace); } } if (template.Name.Equals(Constants.NodeJSWebAppLinuxTemplateName, StringComparison.OrdinalIgnoreCase)) { await site.UpdateConfig(new { properties = new { linuxFxVersion = "NODE|6.10", appCommandLine = "process.json" } }); } Util.FireAndForget($"{resourceGroup.Sites.FirstOrDefault().HostName}"); Util.FireAndForget($"{resourceGroup.Sites.FirstOrDefault().ScmHostName}"); var rbacTask = resourceGroup.AddResourceGroupRbac(userIdentity.Puid, userIdentity.Email); resourceGroup.IsRbacEnabled = await rbacTask; return resourceGroup; })); }