// 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;
            }));
        }
Beispiel #5
0
        // 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;
            }));
        }
Beispiel #6
0
 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;
            }));
        }
Beispiel #9
0
        // 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;
            }));
        }
Beispiel #10
0
        // 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));
        }
Beispiel #14
0
 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;
            }));
        }
Beispiel #16
0
        // 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;
            }));
        }
Beispiel #18
0
 // 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));
        }
Beispiel #20
0
        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;
            }));
        }
Beispiel #21
0
        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;
            }));
        }