예제 #1
0
 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);
 }
예제 #2
0
 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;
 }
예제 #3
0
 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)));
 }
예제 #4
0
        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;
            }));
        }