private async static Task CreateAzureStorageAccount(SetupInformation info) { var key = await AzureManagementUtility.CreateStorageAccount(info.AzureAccessToken, info.AzureTargetSubscriptionId, info.AzureResourceGroupName, info.AzureServicePlanName, info.AzureBlobStorageName, info.AzureLocationDisplayName); info.AzureStorageKey = key; }
private async static Task BuildAndDeployJob(SetupInformation info, String jobName, String jobPath, String basePath, JobType jobType) { // Run PowerShell script to build and deploy Hashtable packageBuildParameters = new Hashtable(); packageBuildParameters.Add("ProjectPath", jobPath); var powerShellScriptPath = (new System.IO.FileInfo($@"{basePath}\OfficeDevPnP.PartnerPack.Setup\Scripts\MsBuildWebJob.ps1")).FullName; string packageBuildResult = Run.RunScript(powerShellScriptPath, packageBuildParameters); if (packageBuildResult.Contains("Build FAILED")) { // TODO: Handle exception } // Create the WebJob ZIP file var binPath = Path.Combine(jobPath, @"bin\Release"); var zipPath = $@"{basePath}\OfficeDevPnP.PartnerPack.Setup\{jobName}.zip"; // Remove any already existing file if (System.IO.File.Exists(zipPath)) { System.IO.File.Delete(zipPath); } System.IO.Compression.ZipFile.CreateFromDirectory(binPath, zipPath); // Get the Azure App Service Publishing Credentials var xmlPublishingSettings = XElement.Parse(info.AzureAppPublishingSettings); if (xmlPublishingSettings != null) { var xmlPublishProfile = xmlPublishingSettings.Element("publishProfile"); if (xmlPublishProfile != null) { var username = xmlPublishProfile.Attribute("userName").Value; var password = xmlPublishProfile.Attribute("userPWD").Value; // Upload the WebJobB await AzureManagementUtility.UploadWebJob(info.AzureAppServiceName, username, password, jobName, zipPath, jobType); } } // Remove the ZIP file after having created the job if (System.IO.File.Exists(zipPath)) { System.IO.File.Delete(zipPath); } }
private async static Task CreateAzureAppService(SetupInformation info) { var appSettings = new AzureAppServiceSetting[3]; appSettings[0] = new AzureAppServiceSetting { Name = "WEBSITE_LOAD_CERTIFICATES", Value = "*" }; appSettings[1] = new AzureAppServiceSetting { Name = "WEBJOBS_IDLE_TIMEOUT", Value = "10000" }; appSettings[2] = new AzureAppServiceSetting { Name = "SCM_COMMAND_IDLE_TIMEOUT", Value = "10000" }; await AzureManagementUtility.CreateAppServiceWebSite(info.AzureAccessToken, info.AzureTargetSubscriptionId, info.AzureResourceGroupName, info.AzureServicePlanName, info.AzureAppServiceName, info.AzureLocationDisplayName, appSettings); var certificate = info.AuthenticationCertificate; var pfxBlob = certificate.Export(X509ContentType.Pfx, info.SslCertificatePassword); await AzureManagementUtility.UploadCertificateToAzureAppService(info.AzureAccessToken, info.AzureTargetSubscriptionId, info.AzureResourceGroupName, info.AzureAppServiceName, info.AzureLocationDisplayName, pfxBlob, info.SslCertificatePassword); info.AzureAppPublishingSettings = await AzureManagementUtility.GetAppServiceWebSitePublishingSettings( info.AzureAccessToken, info.AzureTargetSubscriptionId, info.AzureResourceGroupName, info.AzureAppServiceName); }
private async static Task CreateAzureResourceGroup(SetupInformation info) { await AzureManagementUtility.RegisterAzureProvider(info.AzureAccessToken, info.AzureTargetSubscriptionId, "Microsoft.Storage"); await AzureManagementUtility.RegisterAzureProvider(info.AzureAccessToken, info.AzureTargetSubscriptionId, "Microsoft.Web"); info.AzureResourceGroupName = $"{info.AzureAppServiceName}-resource-group"; info.AzureServicePlanName = $"{info.AzureAppServiceName}-plan"; await AzureManagementUtility.CreateResourceGroup(info.AzureAccessToken, info.AzureTargetSubscriptionId, info.AzureResourceGroupName, info.AzureLocationId); await AzureManagementUtility.CreateServicePlan(info.AzureAccessToken, info.AzureTargetSubscriptionId, info.AzureResourceGroupName, info.AzureServicePlanName, info.AzureLocationDisplayName); }
private async static Task RegisterAzureADApplication(SetupInformation info) { // Fix the App URL if (!info.AzureWebAppUrl.EndsWith("/")) { info.AzureWebAppUrl = info.AzureWebAppUrl + "/"; } // Load the App Manifest template Stream stream = typeof(SetupManager) .Assembly .GetManifestResourceStream("OfficeDevPnP.PartnerPack.Setup.Resources.azure-ad-app-manifest.json"); using (StreamReader sr = new StreamReader(stream)) { // Get the JSON manifest var jsonApplication = sr.ReadToEnd(); var application = JsonConvert.DeserializeObject <AzureAdApplication>(jsonApplication); var keyCredential = JsonConvert.DeserializeObject <KeyCredential>(info.AzureAppKeyCredential); application.displayName = info.ApplicationName; application.homepage = info.AzureWebAppUrl; application.identifierUris = new List <String>(); application.identifierUris.Add(info.ApplicationUniqueUri); application.keyCredentials = new List <KeyCredential>(); application.keyCredentials.Add(keyCredential); application.replyUrls = new List <String>(); application.replyUrls.Add(info.AzureWebAppUrl); // Generate the Application Shared Secret var startDate = DateTime.Now; Byte[] bytes = new Byte[32]; using (var rand = System.Security.Cryptography.RandomNumberGenerator.Create()) { rand.GetBytes(bytes); } info.AzureAppSharedSecret = System.Convert.ToBase64String(bytes); application.passwordCredentials = new List <object>(); application.passwordCredentials.Add(new AzureAdApplicationPasswordCredential { CustomKeyIdentifier = null, StartDate = startDate.ToString("o"), EndDate = startDate.AddYears(2).ToString("o"), KeyId = Guid.NewGuid().ToString(), Value = info.AzureAppSharedSecret, }); // Get an Access Token to create the application via Microsoft Graph var office365AzureADAccessToken = await AzureManagementUtility.GetAccessTokenSilentAsync( AzureManagementUtility.MicrosoftGraphResourceId, ConfigurationManager.AppSettings["O365:ClientId"]); var azureAdApplicationCreated = false; // Create the Azure AD Application try { await CreateAzureADApplication(info, application, office365AzureADAccessToken); azureAdApplicationCreated = true; } catch (ApplicationException ex) { var graphError = JsonConvert.DeserializeObject <GraphError>(((HttpException)ex.InnerException).Message); if (graphError != null && graphError.error.code == "Request_BadRequest" && graphError.error.message.Contains("identifierUris already exists")) { // We need to remove the existing application // Thus, retrieve it String jsonApplications = await HttpHelper.MakeGetRequestForStringAsync( String.Format("{0}applications?$filter=identifierUris/any(c:c+eq+'{1}')", AzureManagementUtility.MicrosoftGraphBetaBaseUri, HttpUtility.UrlEncode(info.ApplicationUniqueUri)), office365AzureADAccessToken); var applications = JsonConvert.DeserializeObject <AzureAdApplications>(jsonApplications); var applicationToUpdate = applications.Applications.FirstOrDefault(); if (applicationToUpdate != null) { // Remove it await HttpHelper.MakeDeleteRequestAsync( String.Format("{0}applications/{1}", AzureManagementUtility.MicrosoftGraphBetaBaseUri, applicationToUpdate.Id), office365AzureADAccessToken); // And add it again await CreateAzureADApplication(info, application, office365AzureADAccessToken); azureAdApplicationCreated = true; } } } if (azureAdApplicationCreated) { // TODO: We should upload the logo // property mainLogo: stream of the application via PATCH } } }
private async static Task CreateInfrastructuralSiteCollectionAsync(SetupInformation info) { Uri infrastructureSiteUri = new Uri(info.InfrastructuralSiteUrl); Uri tenantAdminUri = new Uri(infrastructureSiteUri.Scheme + "://" + infrastructureSiteUri.Host.Replace(".sharepoint.com", "-admin.sharepoint.com")); Uri sharepointUri = new Uri(infrastructureSiteUri.Scheme + "://" + infrastructureSiteUri.Host + "/"); var siteUrl = info.InfrastructuralSiteUrl.Substring(info.InfrastructuralSiteUrl.IndexOf("sharepoint.com/") + 14); var siteCreated = false; var siteAlreadyExists = false; var accessToken = await AzureManagementUtility.GetAccessTokenSilentAsync( tenantAdminUri.ToString(), ConfigurationManager.AppSettings["O365:ClientId"]); AuthenticationManager am = new AuthenticationManager(); using (var adminContext = am.GetAzureADAccessTokenAuthenticatedContext( tenantAdminUri.ToString(), accessToken)) { adminContext.RequestTimeout = Timeout.Infinite; var tenant = new Tenant(adminContext); // Check if the site already exists, and eventually removes it from the Recycle Bin if (tenant.CheckIfSiteExists(info.InfrastructuralSiteUrl, "Recycled")) { tenant.DeleteSiteCollectionFromRecycleBin(info.InfrastructuralSiteUrl); } siteAlreadyExists = tenant.SiteExists(info.InfrastructuralSiteUrl); if (!siteAlreadyExists) { // Configure the Site Collection properties SiteEntity newSite = new SiteEntity(); newSite.Description = "PnP Partner Pack - Infrastructural Site Collection"; newSite.Lcid = (uint)info.InfrastructuralSiteLCID; newSite.Title = newSite.Description; newSite.Url = info.InfrastructuralSiteUrl; newSite.SiteOwnerLogin = info.InfrastructuralSitePrimaryAdmin; newSite.StorageMaximumLevel = 1000; newSite.StorageWarningLevel = 900; newSite.Template = "STS#0"; newSite.TimeZoneId = info.InfrastructuralSiteTimeZone; newSite.UserCodeMaximumLevel = 0; newSite.UserCodeWarningLevel = 0; // Create the Site Collection and wait for its creation (we're asynchronous) tenant.CreateSiteCollection(newSite, true, true, (top) => { if (top == TenantOperationMessage.CreatingSiteCollection) { var maxProgress = (100 / (Int32)SetupStep.Completed); info.ViewModel.SetupProgress += 1; if (info.ViewModel.SetupProgress >= maxProgress) { info.ViewModel.SetupProgress = maxProgress; } } return(false); }); } } await Task.Delay(5000); using (var adminContext = am.GetAzureADAccessTokenAuthenticatedContext( tenantAdminUri.ToString(), accessToken)) { adminContext.RequestTimeout = Timeout.Infinite; var tenant = new Tenant(adminContext); Site site = tenant.GetSiteByUrl(info.InfrastructuralSiteUrl); Web web = site.RootWeb; adminContext.Load(site, s => s.Url); adminContext.Load(web, w => w.Url); adminContext.ExecuteQueryRetry(); // Enable Secondary Site Collection Administrator if (!String.IsNullOrEmpty(info.InfrastructuralSiteSecondaryAdmin)) { Microsoft.SharePoint.Client.User secondaryOwner = web.EnsureUser(info.InfrastructuralSiteSecondaryAdmin); secondaryOwner.IsSiteAdmin = true; secondaryOwner.Update(); web.SiteUsers.AddUser(secondaryOwner); adminContext.ExecuteQueryRetry(); } siteCreated = true; } if (siteAlreadyExists || siteCreated) { accessToken = await AzureManagementUtility.GetAccessTokenSilentAsync( sharepointUri.ToString(), ConfigurationManager.AppSettings["O365:ClientId"]); using (ClientContext clientContext = am.GetAzureADAccessTokenAuthenticatedContext( info.InfrastructuralSiteUrl, accessToken)) { clientContext.RequestTimeout = Timeout.Infinite; Site site = clientContext.Site; Web web = site.RootWeb; clientContext.Load(site, s => s.Url); clientContext.Load(web, w => w.Url); clientContext.ExecuteQueryRetry(); // Override settings within templates, before uploading them UpdateProvisioningTemplateParameter("Responsive", "SPO-Responsive.xml", "AzureWebSiteUrl", info.AzureWebAppUrl); UpdateProvisioningTemplateParameter("Overrides", "PnP-Partner-Pack-Overrides.xml", "AzureWebSiteUrl", info.AzureWebAppUrl); // Apply the templates to the target site ApplyProvisioningTemplate(web, "Infrastructure", "PnP-Partner-Pack-Infrastructure-Jobs.xml"); ApplyProvisioningTemplate(web, "Infrastructure", "PnP-Partner-Pack-Infrastructure-Templates.xml"); ApplyProvisioningTemplate(web, "", "PnP-Partner-Pack-Infrastructure-Contents.xml"); // We to it twice to force the content types, due to a small bug in the provisioning engine ApplyProvisioningTemplate(web, "", "PnP-Partner-Pack-Infrastructure-Contents.xml"); } } else { // TODO: Handle some kind of exception ... } }