public HttpResponseMessage LogEvent(string telemetryEvent, JObject properties) { var context = new HttpContextWrapper(HttpContext.Current); if (context.IsBrowserRequest()) { var userName = User != null && User.Identity != null && !string.IsNullOrEmpty(User.Identity.Name) ? User.Identity.Name : "-"; var anonymousUserName = SecurityManager.GetAnonymousUserName(context); if (telemetryEvent.Equals("INIT_USER", StringComparison.OrdinalIgnoreCase)) { var dic = properties != null ? properties.ToObject <Dictionary <string, string> >() : new Dictionary <string, string>(); Func <string, string> cleanUp = (s) => string.IsNullOrEmpty(s) ? "-" : s; var referer = cleanUp(dic.Where(p => p.Key == "origin").Select(p => p.Value).FirstOrDefault()); var cid = cleanUp(dic.Where(p => p.Key == "cid").Select(p => p.Value).FirstOrDefault()); var sv = cleanUp(dic.Where(p => p.Key == "sv").Select(p => p.Value).FirstOrDefault()); SimpleTrace.TraceInformation("{0}; {1}; {2}; {3}; {4}", AnalyticsEvents.AnonymousUserInit, "", referer, cid, sv ); SimpleTrace.InitializeAnonymousUser(userName, "", referer, cid, sv); } else { SimpleTrace.Analytics.Information(AnalyticsEvents.UiEvent, telemetryEvent, properties); var eventProperties = properties != null ? properties.ToObject <Dictionary <string, string> >().Select(e => e.Value).Aggregate((a, b) => string.Join(",", a, b)) : string.Empty; SimpleTrace.TraceInformation("{0}; {1}; {2};", AnalyticsEvents.OldUiEvent, telemetryEvent, eventProperties); } } return(Request.CreateResponse(HttpStatusCode.Accepted)); }
// ARM public async Task <ResourceGroup> ActivateFunctionApp(FunctionTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Function, DeploymentType.FunctionDeploy, 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, "Function", template.Name, resourceGroup.ResourceUniqueId, AppService.Function.ToString(), anonymousUserName); SimpleTrace.UserCreatedApp(userIdentity, template, resourceGroup, AppService.Function); resourceGroup.Sites.First(s => s.IsFunctionsContainer).FireAndForget(); 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; })); }
static ServiceContext CreateServiceContext(IOptions <SimpleServerOptions> options, ILoggerFactory loggerFactory) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (loggerFactory == null) { throw new ArgumentNullException(nameof(loggerFactory)); } var serverOptions = options.Value ?? new SimpleServerOptions(); var logger = loggerFactory.CreateLogger("Contoso.GameNetCore.Server.Simple"); var trace = new SimpleTrace(logger); return(new ServiceContext { Log = trace, ServerOptions = serverOptions, }); }
private void AsyncCommitDeviceState() { try { if (Devices.NetworkSpine.State == SpineClientWrap.States.DISCONNECTED) { // silenciosamente, ignoro el commit pues no tengo spine a la vista. return; } var asyncCallback = new AsyncCallback(LoadDeviceStateAsyncCallbackHandler); // preparo el cliente. var remoteAsyncDelegate = new LoadDeviceStateHandler(Devices.NetworkSpine.GetDeviceState); // lanzamos el evento. remoteAsyncDelegate.BeginInvoke(id, asyncCallback, remoteAsyncDelegate); } catch (Exception e) { SimpleTrace.Exception(typeof(DeviceStateWrap).FullName, e); } }
public HttpCookie CreateSessionCookie(IPrincipal user) { var identity = user.Identity as TryWebsitesIdentity; SimpleTrace.TraceInformation("{0}", AnalyticsEvents.OldUserLoggedIn); try { var anonymousUser = HttpContext.Current.Request.Cookies[AuthConstants.AnonymousUser]; if (anonymousUser != null) { SimpleTrace.TraceInformation("{0}", AnalyticsEvents.AnonymousUserLogedIn); } } catch { } return(new HttpCookie(AuthConstants.LoginSessionCookie, GetSessionCookieString(user)) { Path = "/", Expires = DateTime.UtcNow.AddHours(1) }); }
public static async Task StartSite(this Site site) { var csmResponse = await GetClient(site.SubscriptionType).HttpInvoke(HttpMethod.Post, ArmUriTemplates.SiteStart.Bind(site), new { }); try { await csmResponse.EnsureSuccessStatusCodeWithFullError(); } catch (Exception ex) { var message = $"Error Starting site via ARM {site.SiteName} -> {site.ResourceGroupName} -> {site.SubscriptionId} : {ex.Message} -> {ex.StackTrace}"; SimpleTrace.TraceError(message); throw new SiteStartStopFailedException(message); } if (!await Util.PingTillStatusCode(site.HostName, HttpStatusCode.OK, 35, 5)) { var message = $"Error Pinging site after start {site.SiteName} -> {site.ResourceGroupName} -> {site.SubscriptionId}"; SimpleTrace.TraceError(message); throw new SiteStartStopFailedException(message); } }
// ARM public async Task <ResourceGroup> ActivateLogicApp(LogicTemplate template, TryWebsitesIdentity userIdentity, string anonymousUserName) { return(await ActivateResourceGroup(userIdentity, AppService.Logic, 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, "Logic", template.Name, resourceGroup.ResourceUniqueId, AppService.Logic.ToString(), anonymousUserName); SimpleTrace.UserCreatedApp(userIdentity, template, resourceGroup, AppService.Logic); //await resourceGroup.InitApiApps(); var logicApp = new LogicApp(resourceGroup.SubscriptionId, resourceGroup.ResourceGroupName, Guid.NewGuid().ToString().Replace("-", "")) { Location = resourceGroup.GeoRegion }; var csmTemplateString = string.Empty; using (var reader = new StreamReader(template.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); // 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; })); }
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; })); }
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)); }
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; })); }
internal async Task CleanupSubscriptions() { try { _cleanupOperationsTriggered++; var subscriptions = await CsmManager.GetSubscriptions(); Stopwatch sw = new Stopwatch(); sw.Start(); //Delete any duplicate resourcegroups in same subscription loaded in the same region //or create any missing resourcegroups in a region List <ResourceGroup> toDelete = new List <ResourceGroup>(); List <ResourceGroup> ready = new List <ResourceGroup>(); var deletedDuplicateRGs = 0; var createdMissingRGs = 0; var createdMissingTemplates = 0; foreach (var subscription in subscriptions) { var sub = new Subscription(subscription); await sub.Load(); //sub.ResourceGroups = (await LoadedResourceGroups()).Where(r => r.SubscriptionId == sub.SubscriptionId); var trialsubresult = sub.GetSubscriptionStats(); toDelete.AddRange(trialsubresult.ToDelete); ready.AddRange(trialsubresult.Ready); } var rand = new Random(); foreach (var resourceGroup in toDelete) { //RemoveFromFreeResourcesQueue(resourceGroup); DeleteResourceGroupOperation(resourceGroup); deletedDuplicateRGs++; } foreach (var template in TemplatesManager.GetTemplates().Where(a => a.QueueSizeToMaintain > 0)) { var deployedTemplates = ready.Count(a => a.DeployedTemplateName == template.Name); var delta = template.QueueSizeToMaintain - deployedTemplates; SimpleTrace.TraceInformation($"Template {template.Name} has {deployedTemplates} RGs deployed and requires {template.QueueSizeToMaintain}"); for (int i = 1; i <= delta; i++) { SimpleTrace.TraceInformation($"Template {template.Name} creating {i} of {delta}"); CreateResourceGroupOperation(template.Config.Subscriptions.OrderBy(a => Guid.NewGuid()).First(), template.Config.Regions.OrderBy(a => Guid.NewGuid()).First(), template.Name); createdMissingTemplates++; } for (int i = 1; i <= -delta; i++) { var resourceGroup = await StorageHelper.GetQueueMessage(template.QueueName); if (resourceGroup != null) { SimpleTrace.TraceInformation($"Template {template.Name} deleting {i} of {-delta}->{resourceGroup.CsmId}"); //RemoveFromFreeResourcesQueue(resourceGroup); DeleteResourceGroupOperation(resourceGroup); } } } AppInsights.TelemetryClient.TrackMetric("createdMissingTemplates", createdMissingTemplates); AppInsights.TelemetryClient.TrackMetric("createdMissingRGs", createdMissingRGs); AppInsights.TelemetryClient.TrackMetric("deletedDuplicateRGs", deletedDuplicateRGs); AppInsights.TelemetryClient.TrackMetric("fullCleanupTime", sw.Elapsed.TotalSeconds); sw.Stop(); } catch (Exception e) { SimpleTrace.Diagnostics.Fatal(e, "CleanupSubscriptions error, Count {Count}", Interlocked.Increment(ref _maintainResourceGroupListErrorCount)); } }
// 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; })); }
public static MakeSubscriptionFreeTrialResult MakeTrialSubscription(this Subscription subscription) { var result = new MakeSubscriptionFreeTrialResult(); if (subscription.Type != SubscriptionType.VSCodeLinux) { result.ToCreateTemplates = new List <TemplateStats>(); result.ToCreateInRegions = subscription.GeoRegions .Where(g => !subscription.ResourceGroups .Any(rg => rg.ResourceGroupName.StartsWith(string.Format(CultureInfo.InvariantCulture, "{0}_{1}", Constants.TryResourceGroupPrefix, g.Replace(" ", Constants.TryResourceGroupSeparator)), StringComparison.OrdinalIgnoreCase))) .Concat(subscription.ResourceGroups .GroupBy(s => s.GeoRegion) .Select(g => new { Region = g.Key, ResourceGroups = g.Select(r => r), RemainingCount = (subscription.ResourceGroupsPerGeoRegion) - g.Count() }) .Where(g => g.RemainingCount > 0) .Select(g => Enumerable.Repeat(g.Region, g.RemainingCount)) .Select(i => i) .SelectMany(i => i) ); result.ToDelete = subscription.ResourceGroups .GroupBy(s => s.GeoRegion) .Select(g => new { Region = g.Key, ResourceGroups = g.Select(r => r), Count = g.Count() }) .Where(g => g.Count > subscription.ResourceGroupsPerGeoRegion) .Select(g => g.ResourceGroups.Where(rg => string.IsNullOrEmpty(rg.UserId)).Skip((subscription.ResourceGroupsPerGeoRegion))) .SelectMany(i => i); } else if (subscription.Type == SubscriptionType.VSCodeLinux) { result.ToCreateInRegions = new List <string>(); var vscodeTemplates = TemplatesManager.GetTemplates().Where(a => a.AppService == AppService.VSCodeLinux); var temp = subscription.ResourceGroups.GroupBy(a => a.TemplateName) .Select(g => new TemplateStats { TemplateName = g.Key, RemainingCount = (subscription.ResourceGroupsPerTemplate) - g.Count() }) .Where(g => g.RemainingCount > 0); var temp2 = new List <TemplateStats>(); foreach (var remaining in vscodeTemplates) { if (!temp.Any(a => a.TemplateName == remaining.Name)) { temp = temp.Union(new List <TemplateStats> { new TemplateStats { TemplateName = remaining.Name, RemainingCount = subscription.ResourceGroupsPerTemplate } }); } var count = temp.First(a => a.TemplateName == remaining.Name).RemainingCount; temp2.Add(new TemplateStats { TemplateName = remaining.Name, RemainingCount = count }); } result.ToCreateTemplates = temp2; result.ToDelete = subscription.ResourceGroups .GroupBy(s => s.DeployedTemplateName) .Select(g => new { TemplateName = g.Key, ResourceGroups = g.Select(r => r), ExtraCount = g.Count() - (subscription.ResourceGroupsPerTemplate) }) .Where(g => g.ExtraCount > 0) .Select(g => g.ResourceGroups.Where(rg => string.IsNullOrEmpty(rg.UserId)).Skip((subscription.ResourceGroupsPerGeoRegion))) .SelectMany(i => i); } //TODO:Also delete RGs that are not in subscription.GeoRegions result.Ready = subscription.ResourceGroups.Where(rg => !result.ToDelete.Any(drg => drg.ResourceGroupName == rg.ResourceGroupName)); SimpleTrace.TraceInformation($"MakeTrialSubscription for: {subscription.SubscriptionId} -> Ready:{result.Ready.Count()} -> ToCreate:{result.ToCreateInRegions.Count()} -> ToDelete:{result.ToDelete.Count()} -> result:{JsonConvert.SerializeObject(result)}"); return(result); }
public static void WarmUpSite(Site site) { SimpleTrace.TraceInformation($"Warming up hostnames: {site.HostName},{site.ScmHostName}->{site.ResourceGroupName}->{site.SubscriptionId}"); FireAndForget(site.HostName); FireAndForget(site.ScmHostName); }
public static async Task DeployVSCodeLinuxTemplateToSite(BaseTemplate template, Site site) { 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) { var failed = $"Zip Deployment going on: StatusUrl: {deploystatusurl} -{JsonConvert.SerializeObject(message)} for {template?.MSDeployPackageUrl} on {site.SiteName}->{site.ResourceGroupName}->{site.SubscriptionId}"; SimpleTrace.TraceInformation(failed); File.AppendAllLines(HostingEnvironment.MapPath(string.Format(CultureInfo.InvariantCulture, "~/App_data/filestatus.txt")), new string [] { failed }); } else { var success = ($"Zip Deployment completed: StatusUrl: {deploystatusurl} -{JsonConvert.SerializeObject(message)} for {template?.MSDeployPackageUrl} on {site.SiteName}->{site.ResourceGroupName}->{site.SubscriptionId}"); SimpleTrace.TraceInformation(success); File.AppendAllLines(HostingEnvironment.MapPath(string.Format(CultureInfo.InvariantCulture, "~/App_data/filestatus.txt")), new string[] { success }); break; } } } } } catch (Exception ex) { var exception = ($"Ping post ZipDeployed: StatusUrl: {deploystatusurl} for {template?.MSDeployPackageUrl} on {site.SiteName}->{site.ResourceGroupName}->{site.SubscriptionId} -> {ex.Message}->{ex.StackTrace}s"); SimpleTrace.TraceError(exception); File.AppendAllLines(HostingEnvironment.MapPath(string.Format(CultureInfo.InvariantCulture, "~/App_data/filestatus.txt")), new string[] { exception }); } } File.AppendAllLines(HostingEnvironment.MapPath(string.Format(CultureInfo.InvariantCulture, "~/App_data/filestatus.txt")), new string[] { "Starting hostingstart file delete" }); 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}"); File.AppendAllLines(HostingEnvironment.MapPath(string.Format(CultureInfo.InvariantCulture, "~/App_data/filestatus.txt")), new string[] { "Starting hostingstart file delete" }); 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"); } }
public static async Task DeployLinuxTemplateToSite(BaseTemplate template, Site site) { 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); if (template.Name.Equals(Constants.PHPWebAppLinuxTemplateName, StringComparison.OrdinalIgnoreCase)) { await site.UpdateConfig( new { properties = new { linuxFxVersion = "PHP|7.2", appCommandLine = "process.json", alwaysOn = true, httpLoggingEnabled = true } }); } else { await site.UpdateConfig( new { properties = new { linuxFxVersion = "NODE|9.4", appCommandLine = "process.json", alwaysOn = true, httpLoggingEnabled = true } }); } await Task.Delay(5 * 1000); var lsm = new LinuxSiteManager.Client.LinuxSiteManager(retryCount: 2); Task checkSite = lsm.CheckSiteDeploymentStatusAsync(site.HttpUrl); try { await checkSite; } catch (Exception ex) { SimpleTrace.TraceError("New Site wasnt deployed" + ex.Message + ex.StackTrace); } } catch (Exception ex) { SimpleTrace.TraceError(ex.Message + ex.StackTrace); } WarmUpSite(site); } }
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); }
public static void RECORD(this object obj, string type, string inp, string outp, params object[] args) { SimpleTrace.Trace(typeof(ExtensionMethods).FullName, "{0}:{1,10} '{2}' '{3}' context: {4}", obj.NODE(), type, inp, outp, obj.CONTEXT(args)); }
// 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); }
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) as VSCodeLinuxTemplate; SimpleTrace.TraceInformation($"Deploying {template.Name} to {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}"); using (var reader = new StreamReader(template.CsmTemplateFilePath)) { csmTemplateString = await reader.ReadToEndAsync(); } csmTemplateString = csmTemplateString .Replace("{{siteName}}", site.SiteName) .Replace("{{aspName}}", site.SiteName + "-plan") .Replace("{{vmLocation}}", resourceGroup.GeoRegion); 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}"); await Load(site, null); SimpleTrace.TraceInformation($"Site Loaded from ARM : {JsonConvert.SerializeObject(site)} to {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}"); await Util.UpdateVSCodeLinuxAppSettings(site); SimpleTrace.TraceInformation($"Site AppSettings Updated: for {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}"); //await site.StopSite(); await Util.DeployVSCodeLinuxTemplateToSite(template, site, false); //await site.StartSite(); var lsm = new LinuxSiteManager.Client.LinuxSiteManager(retryCount: 6); Task checkSite = lsm.CheckSiteDeploymentStatusAsync(site.HttpUrl); try { await checkSite; } catch (Exception ex) { //TODO: Alert on this specifically var message = "New Site didnt come up after zip deploy: " + ex.Message + ex.StackTrace; SimpleTrace.TraceError(message); throw new ZipDeploymentFailedException(message); } SimpleTrace.TraceInformation($"Site Code Zip PUT and restart complete: {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}"); if (!resourceGroup.Tags.ContainsKey(Constants.TemplateName)) { resourceGroup.Tags.Add(Constants.TemplateName, resourceGroup.TemplateName); await resourceGroup.Update(); SimpleTrace.TraceInformation($"ResourceGroup Templates Tag Updated: for {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}"); } return(site); }
public async Task <HttpResponseMessage> CreateResource(BaseTemplate template) { try { var payload = JsonConvert.SerializeObject(template); SimpleTrace.TraceInformation($"CREATE {template?.AppService} : {payload}. Request Received"); } catch (Exception ex) { SimpleTrace.TraceError($"Error Logging Create Start Information: {ex.Message} -> {ex.StackTrace}"); } var tempTemplate = WebsiteTemplate.EmptySiteTemplate; if (template == null) { template = WebsiteTemplate.EmptySiteTemplate; } else if (template.AppService.Equals(AppService.Function)) { tempTemplate = FunctionTemplate.DefaultFunctionTemplate(template.Name); } else if (template.AppService.Equals(AppService.Containers)) { var containersTemplate = ContainersTemplate.DefaultContainersTemplate(template.Name); containersTemplate.DockerContainer = template.DockerContainer; tempTemplate = containersTemplate; } else if (template.Name != null && !template.Name.Equals("GitHub Repo") && !template.AppService.Equals(AppService.Function)) { var temp = TemplatesManager.GetTemplates() .FirstOrDefault(t => t.Name == template.Name); tempTemplate = WebsiteTemplate.DefaultTemplate(temp.Name, temp.AppService, temp.Language, temp.FileName, template.DockerContainer, temp.MSDeployPackageUrl); } else if (template.Name != null && template.Name.Equals("GitHub Repo")) { tempTemplate = new WebsiteTemplate { AppService = AppService.Web, GithubRepo = template.GithubRepo, Name = template.Name, Language = "GitHub" }; } var identity = HttpContext.Current.User.Identity as TryWebsitesIdentity; var anonymousUserName = SecurityManager.GetAnonymousUserName(new HttpContextWrapper(HttpContext.Current)); try { var resourceManager = await ResourcesManager.GetInstanceAsync(); if ((await resourceManager.GetResourceGroup(identity.Name)) != null) { SimpleTrace.Diagnostics.Fatal(AnalyticsEvents.MoreThanOneError, 1); //This should use the server version of the error, but due to a string bug they are not the same. return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, Resources.Client.Information_YouCantHaveMoreThanOne)); } ResourceGroup resourceGroup = null; SimpleTrace.TraceInformation($"Searching for {tempTemplate?.AppService} {tempTemplate?.Name}."); switch (tempTemplate.AppService) { case AppService.Linux: resourceGroup = await resourceManager.ActivateLinuxResource(tempTemplate, identity, anonymousUserName); break; case AppService.VSCodeLinux: resourceGroup = await resourceManager.ActivateVSCodeLinuxResource(tempTemplate, identity, anonymousUserName); break; case AppService.Web: resourceGroup = await resourceManager.ActivateWebApp(tempTemplate, identity, anonymousUserName); break; case AppService.Api: resourceGroup = await resourceManager.ActivateApiApp(tempTemplate, identity, anonymousUserName); break; case AppService.Function: resourceGroup = await resourceManager.ActivateFunctionApp(tempTemplate, identity, anonymousUserName); break; case AppService.Containers: resourceGroup = await resourceManager.ActivateContainersResource(tempTemplate, identity, anonymousUserName); break; } try { SimpleTrace.TraceInformation($"CREATE {template?.AppService}. Returning { GetUIResource(resourceGroup).SiteName } with template { GetUIResource(resourceGroup).TemplateName } for user {identity.FilteredName}"); } catch (Exception ex) { SimpleTrace.TraceError($"Error Logging Create End Information: {ex.Message} -> {ex.StackTrace}"); } return(Request.CreateResponse(HttpStatusCode.OK, resourceGroup == null ? null : GetUIResource(resourceGroup))); } catch (Exception ex) { var message = ex is NullReferenceException ? Resources.Server.Error_GeneralErrorMessage : ex.Message; SimpleTrace.Diagnostics.Fatal(ex, AnalyticsEvents.UserGotError, message, Interlocked.Increment(ref _userGotErrorErrorCount)); return(Request.CreateErrorResponse(HttpStatusCode.ServiceUnavailable, message)); } }