Esempio n. 1
0
        private void SetupFunctionAppExpressArtifacts(DeploymentContext context)
        {
            string sitePackages    = "/home/data/SitePackages";
            string packageNameFile = Path.Combine(sitePackages, "packagename.txt");
            string packagePathFile = Path.Combine(sitePackages, "packagepath.txt");

            FileSystemHelpers.EnsureDirectory(sitePackages);

            string zipAppName = $"{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.zip";
            string createdZip = PackageArtifactFromFolder(context, OryxBuildConstants.FunctionAppBuildSettings.ExpressBuildSetup,
                                                          OryxBuildConstants.FunctionAppBuildSettings.ExpressBuildSetup, zipAppName, BuildArtifactType.Zip, numBuildArtifacts: -1);

            var copyExe    = ExternalCommandFactory.BuildExternalCommandExecutable(OryxBuildConstants.FunctionAppBuildSettings.ExpressBuildSetup, sitePackages, context.Logger);
            var copyToPath = Path.Combine(sitePackages, zipAppName);

            try
            {
                copyExe.ExecuteWithProgressWriter(context.Logger, context.Tracer, $"cp {createdZip} {copyToPath}");
            }
            catch (Exception)
            {
                context.GlobalLogger.LogError();
                throw;
            }

            // Gotta remove the old zips
            DeploymentHelper.PurgeBuildArtifactsIfNecessary(sitePackages, BuildArtifactType.Zip, context.Tracer, totalAllowedFiles: 2);

            File.WriteAllText(packageNameFile, zipAppName);
            File.WriteAllText(packagePathFile, sitePackages);
        }
Esempio n. 2
0
        private void SetupFunctionAppExpressArtifacts(DeploymentContext context)
        {
            string sitePackages    = "/home/data/SitePackages";
            string packageNameFile = Path.Combine(sitePackages, "packagename.txt");
            string packagePathFile = Path.Combine(sitePackages, "packagepath.txt");

            FileSystemHelpers.EnsureDirectory(sitePackages);

            string zipAppName = $"{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.zip";
            string zipFile    = Path.Combine(sitePackages, zipAppName);

            context.Logger.Log("Writing the artifacts to a zip file");
            var exe = ExternalCommandFactory.BuildExternalCommandExecutable(OryxBuildConstants.FunctionAppBuildSettings.ExpressBuildSetup, sitePackages, context.Logger);

            try
            {
                exe.ExecuteWithProgressWriter(context.Logger, context.Tracer, $"zip -r {zipFile} .", String.Empty);
            }
            catch (Exception)
            {
                context.GlobalLogger.LogError();
                throw;
            }

            // Just to be sure that we don't keep adding zip files here
            DeploymentHelper.PurgeZipsIfNecessary(sitePackages, context.Tracer, totalAllowedZips: 3);

            File.WriteAllText(packageNameFile, zipAppName);
            File.WriteAllText(packagePathFile, sitePackages);
        }
Esempio n. 3
0
        private void SetupAppServiceArtifacts(DeploymentContext context)
        {
            string sitePackages    = "/home/data/SitePackages";
            string deploymentsPath = $"/home/site/deployments/";
            string artifactPath    = $"/home/site/deployments/{context.CommitId}/artifact";
            string packageNameFile = Path.Combine(sitePackages, "packagename.txt");
            string packagePathFile = Path.Combine(sitePackages, "packagepath.txt");

            FileSystemHelpers.EnsureDirectory(sitePackages);
            FileSystemHelpers.EnsureDirectory(artifactPath);

            string zipAppName = $"{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.zip";

            string createdZip = PackageArtifactFromFolder(context, context.BuildTempPath,
                                                          context.BuildTempPath, zipAppName, BuildArtifactType.Zip, numBuildArtifacts: -1);
            var copyExe    = ExternalCommandFactory.BuildExternalCommandExecutable(context.BuildTempPath, artifactPath, context.Logger);
            var copyToPath = Path.Combine(artifactPath, zipAppName);

            try
            {
                copyExe.ExecuteWithProgressWriter(context.Logger, context.Tracer, $"cp {createdZip} {copyToPath}");
            }
            catch (Exception)
            {
                context.GlobalLogger.LogError();
                throw;
            }

            // Gotta remove the old zips
            DeploymentHelper.PurgeOldDeploymentsIfNecessary(deploymentsPath, context.Tracer, totalAllowedDeployments: 10);

            File.WriteAllText(packageNameFile, zipAppName);
            File.WriteAllText(packagePathFile, artifactPath);
        }
Esempio n. 4
0
        public async Task DownloadError_Md5()
        {
            // Upload file as a multi-part release, mess with a part's MD5 and
            // verify that we detect the problem when downloading.

            var tagName = Guid.NewGuid().ToString("d");
            var release = GitHub.Releases.Create(repo, tagName);

            try
            {
                var partCount = 10;
                var partSize  = 1024;
                var download  = PublishMultipartAsset(release, "test.dat", "v1.0", partCount, partSize);

                Assert.Equal("test.dat", download.Name);
                Assert.Equal("v1.0", download.Version);
                Assert.NotNull(download.Md5);
                Assert.Equal(10, download.Parts.Count);
                Assert.Equal(partCount * partSize, download.Parts.Sum(part => part.Size));
                Assert.Equal(partCount * partSize, download.Size);

                download.Parts[0].Md5 += "222";

                using (var tempFolder = new TempFolder())
                {
                    var targetPath = Path.Combine(tempFolder.Path, download.Filename);

                    await Assert.ThrowsAsync <IOException>(async() => await DeploymentHelper.DownloadMultiPartAsync(download, targetPath));
                }
            }
            finally
            {
                GitHub.Releases.Remove(repo, release);
            }
        }
Esempio n. 5
0
        private ISiteBuilder DetermineProject(string repositoryRoot, string targetPath, IDeploymentSettingsManager perDeploymentSettings, IFileFinder fileFinder)
        {
            if (!DeploymentHelper.IsDeployableProject(targetPath))
            {
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
                                                                  Resources.Error_ProjectNotDeployable,
                                                                  targetPath));
            }
            else if (File.Exists(targetPath))
            {
                var    solution     = VsHelper.FindContainingSolution(targetPath, fileFinder);
                string solutionPath = solution != null ? solution.Path : null;

                return(new WapBuilder(_environment,
                                      perDeploymentSettings,
                                      _propertyProvider,
                                      repositoryRoot,
                                      targetPath,
                                      solutionPath));
            }

            throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
                                                              Resources.Error_ProjectDoesNotExist,
                                                              targetPath));
        }
Esempio n. 6
0
        public async Task CreateDeployment_WithInvalidValidParameterFileContents_ReturnsDeploymentFailesMessage()
        {
            var template                     = @"{
  ""$schema"": ""https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"",
  ""resources"": [
    {
      ""type"": ""Microsoft.Storage/storageAccounts"",
      ""apiVersion"": ""2021-06-01"",
      ""name"": ""storageaccount"",
      ""location"": ""[resourceGroup().location]"",
      ""properties"": {}
    }
  ]
}";
            var deploymentCollection         = CreateDeploymentCollection(LanguageConstants.TargetScopeTypeSubscription);
            var deploymentCollectionProvider = StrictMock.Of <IDeploymentCollectionProvider>();

            deploymentCollectionProvider
            .Setup(m => m.GetDeploymentCollection(It.IsAny <ArmClient>(), It.IsAny <ResourceIdentifier>(), LanguageConstants.TargetScopeTypeSubscription))
            .Returns(deploymentCollection);
            string parametersFilePath = FileHelper.SaveResultFile(TestContext, "parameters.json", "invalid_parameters_file");
            var    documentPath       = "some_path";

            var result = await DeploymentHelper.CreateDeployment(
                deploymentCollectionProvider.Object,
                CreateMockArmClient(),
                documentPath,
                template,
                parametersFilePath,
                "/subscriptions/07268dd7-4c50-434b-b1ff-67b8164edb41/resourceGroups/bhavyatest",
                LanguageConstants.TargetScopeTypeSubscription,
                "eastus");

            result.Should().Be(string.Format(LangServerResources.InvalidParameterFileDeploymentFailedMessage, documentPath, @"'i' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0."));
        }
Esempio n. 7
0
        public async Task WaitForDeploymentCompletionAsync_WhenCalled_RemovesDeployIdFromDeploymentOperationsCache()
        {
            var responseMessage = "sample response";

            var armDeploymentResourceResponse = StrictMock.Of <Response <ArmDeploymentResource> >();

            armDeploymentResourceResponse.Setup(m => m.GetRawResponse().Status).Returns(It.IsAny <int>);
            armDeploymentResourceResponse.Setup(m => m.ToString()).Returns(responseMessage);

            var armDeploymentResourceOperation = StrictMock.Of <ArmOperation <ArmDeploymentResource> >();

            armDeploymentResourceOperation.Setup(m => m.WaitForCompletionAsync(CancellationToken.None)).Returns(ValueTask.FromResult(armDeploymentResourceResponse.Object));
            armDeploymentResourceOperation.Setup(m => m.HasValue).Returns(true);

            var documentPath              = "some_path";
            var deploymentId1             = "bicep_deployment_1";
            var deploymentId2             = "bicep_deployment_2";
            var deploymentOperationsCache = new DeploymentOperationsCache();

            deploymentOperationsCache.CacheDeploymentOperation(deploymentId1, armDeploymentResourceOperation.Object);
            deploymentOperationsCache.CacheDeploymentOperation(deploymentId2, armDeploymentResourceOperation.Object);

            await DeploymentHelper.WaitForDeploymentCompletionAsync(
                deploymentId1,
                documentPath,
                deploymentOperationsCache);

            deploymentOperationsCache.FindAndRemoveDeploymentOperation(deploymentId1).Should().BeNull();
            deploymentOperationsCache.FindAndRemoveDeploymentOperation(deploymentId2).Should().NotBeNull();
        }
Esempio n. 8
0
        public async Task StartDeploymentAsync_WithInvalidScope_ReturnsDeploymentFailedMessage(string scope)
        {
            var armClient = CreateMockArmClient();
            var deploymentCollectionProvider = StrictMock.Of <IDeploymentCollectionProvider>();

            deploymentCollectionProvider
            .Setup(m => m.GetDeploymentCollection(It.IsAny <ArmClient>(), It.IsAny <ResourceIdentifier>(), scope))
            .Throws(new Exception(string.Format(LangServerResources.UnsupportedTargetScopeMessage, scope)));
            var documentPath = "some_path";

            var bicepDeployStartResponse = await DeploymentHelper.StartDeploymentAsync(
                deploymentCollectionProvider.Object,
                armClient,
                documentPath,
                string.Empty,
                string.Empty,
                "/subscriptions/07268dd7-4c50-434b-b1ff-67b8164edb41",
                scope,
                string.Empty,
                string.Empty,
                string.Empty,
                ParametersFileUpdateOption.None,
                new List <BicepUpdatedDeploymentParameter>(),
                "https://portal.azure.com",
                "bicep_deployment",
                new DeploymentOperationsCache());

            var expectedDeploymentOutputMessage = string.Format(LangServerResources.DeploymentFailedWithExceptionMessage, documentPath,
                                                                string.Format(LangServerResources.UnsupportedTargetScopeMessage, scope));

            bicepDeployStartResponse.isSuccess.Should().BeFalse();
            bicepDeployStartResponse.outputMessage.Should().Be(expectedDeploymentOutputMessage);
            bicepDeployStartResponse.viewDeploymentInPortalMessage.Should().BeNull();
        }
        private async Task WriteSitePackageZip(ZipDeploymentInfo zipDeploymentInfo, ITracer tracer)
        {
            var filePath = Path.Combine(_environment.SitePackagesPath, zipDeploymentInfo.ZipName);

            // Make sure D:\home\data\SitePackages exists
            FileSystemHelpers.EnsureDirectory(_environment.SitePackagesPath);
            using (_tracer.Step("Writing zip file to {0}", filePath))
            {
                if (HttpContext.Request.ContentType.Contains("multipart/form-data",
                                                             StringComparison.OrdinalIgnoreCase))
                {
                    FormValueProvider formModel;
                    using (_tracer.Step("Writing zip file to {0}", filePath))
                    {
                        using (var file = System.IO.File.Create(filePath))
                        {
                            formModel = await Request.StreamFile(file);
                        }
                    }
                }
                else
                {
                    using (var file = System.IO.File.Create(filePath))
                    {
                        await Request.Body.CopyToAsync(file);
                    }
                }
            }

            DeploymentHelper.PurgeBuildArtifactsIfNecessary(_environment.SitePackagesPath, BuildArtifactType.Zip,
                                                            tracer, _settings.GetMaxZipPackageCount());
        }
Esempio n. 10
0
        public async Task WaitForDeploymentCompletionAsync_WithStatusMessage200Or201_ReturnsDeploymentSucceededMessage(int status)
        {
            var responseMessage = "sample response";

            var armDeploymentResourceResponse = StrictMock.Of <Response <ArmDeploymentResource> >();

            armDeploymentResourceResponse.Setup(m => m.GetRawResponse().Status).Returns(status);
            armDeploymentResourceResponse.Setup(m => m.ToString()).Returns(responseMessage);

            var armDeploymentResourceOperation = StrictMock.Of <ArmOperation <ArmDeploymentResource> >();

            armDeploymentResourceOperation.Setup(m => m.WaitForCompletionAsync(CancellationToken.None)).Returns(ValueTask.FromResult(armDeploymentResourceResponse.Object));
            armDeploymentResourceOperation.Setup(m => m.HasValue).Returns(true);

            var documentPath = "some_path";
            var deploymentId = "bicep_deployment";
            var deploymentOperationsCache = new DeploymentOperationsCache();

            deploymentOperationsCache.CacheDeploymentOperation(deploymentId, armDeploymentResourceOperation.Object);

            var bicepDeployWaitForCompletionResponse = await DeploymentHelper.WaitForDeploymentCompletionAsync(
                deploymentId,
                documentPath,
                deploymentOperationsCache);

            var expectedDeploymentOutputMessage = string.Format(LangServerResources.DeploymentSucceededMessage, documentPath);

            bicepDeployWaitForCompletionResponse.isSuccess.Should().BeTrue();
            bicepDeployWaitForCompletionResponse.outputMessage.Should().Be(expectedDeploymentOutputMessage);
        }
Esempio n. 11
0
        public async Task CreateDeployment_WithInvalidValidParameterFilePath_ReturnsDeploymentFailedMessage()
        {
            var template                     = @"{
  ""$schema"": ""https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"",
  ""resources"": [
    {
      ""type"": ""Microsoft.Storage/storageAccounts"",
      ""apiVersion"": ""2021-06-01"",
      ""name"": ""storageaccount"",
      ""location"": ""[resourceGroup().location]"",
      ""properties"": {}
    }
  ]
}";
            var deploymentCollection         = CreateDeploymentCollection(LanguageConstants.TargetScopeTypeSubscription);
            var deploymentCollectionProvider = StrictMock.Of <IDeploymentCollectionProvider>();

            deploymentCollectionProvider
            .Setup(m => m.GetDeploymentCollection(It.IsAny <ArmClient>(), It.IsAny <ResourceIdentifier>(), LanguageConstants.TargetScopeTypeSubscription))
            .Returns(deploymentCollection);

            var result = await DeploymentHelper.CreateDeployment(
                deploymentCollectionProvider.Object,
                CreateMockArmClient(),
                template,
                @"c:\parameter.json",
                "/subscriptions/07268dd7-4c50-434b-b1ff-67b8164edb41/resourceGroups/bhavyatest",
                LanguageConstants.TargetScopeTypeSubscription,
                "eastus");

            result.Should().Contain(string.Format(LangServerResources.InvalidParameterFileDeploymentFailedMessage, @"Could not find file"));
        }
Esempio n. 12
0
        public void DeleteDeploymentTest()
        {
            DeploymentHelper target = new DeploymentHelper();

            string subscriptionId = "e57cc5fa-5cf7-41c0-a33c-3adaf2944c4a";

            string filePath = @"C:\Development\Certificates\AzureManagementCertificate.cer";

            List <Byte> certificateBytes = CertificateUtility.GetCertificateBytes(filePath);

            string serviceName = "commandlinetest";

            string deploymentSlot = "staging";

            string expected = string.Empty;
            string actual;

            actual = target.DeleteDeployment(subscriptionId, certificateBytes, serviceName, deploymentSlot);

            string opsStatus = string.Empty;

            string status = "InProgress";

            while (status == "InProgress")
            {
                opsStatus = target.GetOperationStatus(subscriptionId, certificateBytes, actual, out status);

                Trace.WriteLine("Ops Status = " + status);

                Thread.Sleep(2000);
            }


            Assert.AreEqual(expected, actual);
        }
Esempio n. 13
0
        public async Task CreateDeployment_WithInvalidScope_ReturnsDeploymentFailedMessage(string scope)
        {
            var armClient = CreateMockArmClient();
            var deploymentCollectionProvider = StrictMock.Of <IDeploymentCollectionProvider>();

            deploymentCollectionProvider
            .Setup(m => m.GetDeploymentCollection(It.IsAny <ArmClient>(), It.IsAny <ResourceIdentifier>(), scope))
            .Throws(new Exception(string.Format(LangServerResources.UnsupportedTargetScopeMessage, scope)));
            var documentPath = "some_path";

            var result = await DeploymentHelper.CreateDeployment(
                deploymentCollectionProvider.Object,
                armClient,
                documentPath,
                string.Empty,
                string.Empty,
                "/subscriptions/07268dd7-4c50-434b-b1ff-67b8164edb41",
                scope,
                string.Empty);

            var expectedDeploymentOutputMessage = string.Format(LangServerResources.DeploymentFailedWithExceptionMessage, documentPath,
                                                                string.Format(LangServerResources.UnsupportedTargetScopeMessage, scope));

            result.Should().Be(expectedDeploymentOutputMessage);
        }
Esempio n. 14
0
        public async Task CreateDeployment_WithExceptionWhileFetchingDeploymentCollection_ReturnsDeploymentFailedMessage()
        {
            var template = @"{
  ""$schema"": ""https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"",
  ""resources"": [
    {
      ""type"": ""Microsoft.Storage/storageAccounts"",
      ""apiVersion"": ""2021-06-01"",
      ""name"": ""storageaccount"",
      ""location"": ""[resourceGroup().location]"",
      ""properties"": {}
    }
  ]
}";
            var deploymentCollectionProvider = StrictMock.Of <IDeploymentCollectionProvider>();
            var errorMessage = "Encountered error while fetching deployments";

            deploymentCollectionProvider
            .Setup(m => m.GetDeploymentCollection(It.IsAny <ArmClient>(), It.IsAny <ResourceIdentifier>(), LanguageConstants.TargetScopeTypeResourceGroup))
            .Throws(new Exception(errorMessage));
            var documentPath = "some_path";

            var result = await DeploymentHelper.CreateDeployment(
                deploymentCollectionProvider.Object,
                CreateMockArmClient(),
                documentPath,
                template,
                string.Empty,
                "/subscriptions/07268dd7-4c50-434b-b1ff-67b8164edb41/resourceGroups/bhavyatest",
                LanguageConstants.TargetScopeTypeResourceGroup,
                "");

            result.Should().Be(string.Format(LangServerResources.DeploymentFailedWithExceptionMessage, documentPath, errorMessage));
        }
Esempio n. 15
0
        public async Task StartDeploymentAsync_WithSubscriptionScopeAndInvalidLocation_ReturnsDeploymentFailedMessage(string location)
        {
            var armClient    = CreateMockArmClient();
            var documentPath = "some_path";

            var bicepDeployStartResponse = await DeploymentHelper.StartDeploymentAsync(
                CreateDeploymentCollectionProvider(),
                armClient,
                documentPath,
                string.Empty,
                string.Empty,
                "/subscriptions/07268dd7-4c50-434b-b1ff-67b8164edb41",
                LanguageConstants.TargetScopeTypeSubscription,
                location,
                string.Empty,
                string.Empty,
                ParametersFileUpdateOption.None,
                new List <BicepUpdatedDeploymentParameter>(),
                "https://portal.azure.com",
                "bicep_deployment",
                new DeploymentOperationsCache());

            var expectedDeploymentOutputMessage = string.Format(LangServerResources.MissingLocationDeploymentFailedMessage, documentPath);

            bicepDeployStartResponse.isSuccess.Should().BeFalse();
            bicepDeployStartResponse.outputMessage.Should().Be(expectedDeploymentOutputMessage);
            bicepDeployStartResponse.viewDeploymentInPortalMessage.Should().BeNull();
        }
Esempio n. 16
0
        public async Task CreateDeployment_WithValidScopeAndInput_ReturnsDeploymentSucceededMessage(string scope, string location)
        {
            var template                     = @"{
  ""$schema"": ""https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"",
  ""resources"": [
    {
      ""type"": ""Microsoft.Storage/storageAccounts"",
      ""apiVersion"": ""2021-06-01"",
      ""name"": ""storageaccount"",
      ""location"": ""[resourceGroup().location]"",
      ""properties"": {}
    }
  ]
}";
            var deploymentCollection         = CreateDeploymentCollection(scope);
            var deploymentCollectionProvider = StrictMock.Of <IDeploymentCollectionProvider>();

            deploymentCollectionProvider
            .Setup(m => m.GetDeploymentCollection(It.IsAny <ArmClient>(), It.IsAny <ResourceIdentifier>(), scope))
            .Returns(deploymentCollection);
            var documentPath = "some_path";

            var result = await DeploymentHelper.CreateDeployment(
                deploymentCollectionProvider.Object,
                CreateMockArmClient(),
                documentPath,
                template,
                string.Empty,
                "/subscriptions/07268dd7-4c50-434b-b1ff-67b8164edb41/resourceGroups/bhavyatest",
                scope,
                location);

            result.Should().Be(string.Format(LangServerResources.DeploymentSucceededMessage, documentPath));
        }
Esempio n. 17
0
        static OperationStatus GetOperationStatus(OperationStatus operationStatus)
        {
            try
            {
                DeploymentHelper deploymentHelper = new DeploymentHelper();

                string status = string.Empty;

                string responseString = deploymentHelper.GetOperationStatus(operationStatus.SubscriptionId,
                                                                            operationStatus.CertificateBytes,
                                                                            operationStatus.RequestId, out status);

                operationStatus.ResponseString = responseString;
                operationStatus.Status         = status;
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Error: {0}\n{1}", ex.Message,
                                                ex.InnerException != null ? ex.InnerException.Message : string.Empty));

                operationStatus = null;
            }

            return(operationStatus);
        }
Esempio n. 18
0
        static string CreateDeployment(string subscriptionId, string serviceName,
                                       string label, string deploymentName,
                                       string deploymentSlot, string certificateFilePath,
                                       int instanceCount)
        {
            string responseString = string.Empty;

            try
            {
                DeploymentHelper deploymentHelper = new DeploymentHelper();

                List <Byte> certificateBytes = GetCertificateBytes(certificateFilePath);

                responseString = deploymentHelper.CreateDeployment(subscriptionId, certificateBytes,
                                                                   serviceName, deploymentName,
                                                                   deploymentSlot, label, instanceCount);

                Console.WriteLine();

                Console.WriteLine("Response String: {0}", responseString);

                Console.WriteLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Error: {0}\n{1}", ex.Message,
                                                ex.InnerException != null ? ex.InnerException.Message : string.Empty));

                responseString = string.Empty;
            }

            return(responseString);
        }
Esempio n. 19
0
        // POST /api/deployment/subscriptionId/serviceName/deploymentName/deploymentSlot/label/instanceCount
        // CreateDeployment
        public string Post(AzureDeployment azureDeployment)
        {
            string requestId = string.Empty;

            try
            {
                Logger.Write("In the DeploymentController.Post method...");

                DeploymentHelper deploymentHelper = new DeploymentHelper();

                Logger.Write(string.Format("SubscriptionId: {0}\tService Name: {1}\tCertificate Byte Length: {2}\tDeployment Name: {3}",
                                           azureDeployment.SubscriptionId, azureDeployment.ServiceName,
                                           azureDeployment.CertificateBytes.ToArray().Length, azureDeployment.DeploymentName));

                requestId = deploymentHelper.CreateDeployment(azureDeployment.SubscriptionId,
                                                              azureDeployment.CertificateBytes,
                                                              azureDeployment.ServiceName,
                                                              azureDeployment.DeploymentName,
                                                              azureDeployment.DeploymentSlot,
                                                              azureDeployment.Label,
                                                              azureDeployment.InstanceCount);

                Logger.Write("Returned RequestId: " + requestId);
            }
            catch (WebException wex)
            {
                string responseString = string.Empty;

                using (StreamReader responseReader = new StreamReader(wex.Response.GetResponseStream()))
                {
                    responseString = responseReader.ReadToEnd();

                    if (string.IsNullOrWhiteSpace(responseString) != true)
                    {
                        Logger.Write("DeploymentController.Post() WebException Response: " + responseString);
                    }

                    responseReader.Close();
                }

                Logger.Write(string.Format("Error in DeploymentController.Post()  Error: {0}\n{1}", wex.Message,
                                           wex.InnerException != null ? wex.InnerException.Message : string.Empty));

                requestId = string.Empty;

                throw new HttpResponseException(HttpStatusCode.BadRequest);
            }
            catch (Exception ex)
            {
                Logger.Write(string.Format("Error in DeploymentController.Post()  Error: {0}\n{1}", ex.Message,
                                           ex.InnerException != null ? ex.InnerException.Message : string.Empty));

                requestId = string.Empty;

                throw new HttpResponseException(HttpStatusCode.BadRequest);
            }

            return(requestId);
        }
Esempio n. 20
0
        public void PurgeZipsIfNecessaryTest()
        {
            // Setup
            var tracer        = new Mock <ITracer>();
            var fileSystem    = new Mock <IFileSystem>();
            var fileBase      = new Mock <FileBase>();
            var directoryBase = new Mock <DirectoryBase>();

            Dictionary <string, DateTime> testFiles = new Dictionary <string, DateTime>()
            {
                { "testFile1.zip", new DateTime(year: 2018, month: 08, day: 21, hour: 12, minute: 31, second: 34) },
                { "testFile2.zip", new DateTime(year: 2018, month: 08, day: 21, hour: 12, minute: 31, second: 20) },
                { "testFile3.zip", new DateTime(year: 2018, month: 07, day: 30, hour: 7, minute: 21, second: 22) },
                { "testFile4.zip", new DateTime(year: 2018, month: 08, day: 25, hour: 0, minute: 0, second: 0) }
            };

            List <string> deletedFiles = new List <string>();

            directoryBase
            .Setup(d => d.GetFiles(It.IsAny <string>(), It.IsAny <string>()))
            .Returns(testFiles.Keys.ToArray());

            fileBase
            .Setup(f => f.GetLastWriteTimeUtc(It.IsAny <string>()))
            .Returns((string fileName) => testFiles[fileName]);

            fileBase
            .Setup(f => f.Delete(It.IsAny <string>()))
            .Callback((string path) => deletedFiles.Add(Path.GetFileName(path)));

            fileSystem.SetupGet(f => f.File).Returns(fileBase.Object);
            fileSystem.SetupGet(f => f.Directory).Returns(directoryBase.Object);

            // Act
            FileSystemHelpers.Instance = fileSystem.Object;
            DeploymentHelper.PurgeZipsIfNecessary("testLocation", tracer.Object, 2);

            // Assert Set 1
            Assert.Contains("testFile3.zip", deletedFiles);
            Assert.Contains("testFile2.zip", deletedFiles);
            Assert.Equal(deletedFiles.Count, 2);

            // Reset and Act
            deletedFiles = new List <string>();
            DeploymentHelper.PurgeZipsIfNecessary("testLocation", tracer.Object, 5);

            // Assert Set 2
            Assert.Equal(deletedFiles.Count, 0);

            // Reset and Act
            deletedFiles = new List <string>();
            DeploymentHelper.PurgeZipsIfNecessary("testLocation", tracer.Object, 1);

            // Assert Set 3
            Assert.Contains("testFile3.zip", deletedFiles);
            Assert.Contains("testFile2.zip", deletedFiles);
            Assert.Contains("testFile1.zip", deletedFiles);
            Assert.Equal(deletedFiles.Count, 3);
        }
        /// <summary>
        ///
        /// </summary>
        public void InitialCommitIfNecessary()
        {
            var settings = GetInstance <IDeploymentSettingsManager>();

            // only support if LocalGit
            if (settings.GetValue(SettingsKeys.ScmType) != ScmType.LocalGit)
            {
                return;
            }

            // get repository for the WebRoot
            var initLock = GetInstance <IDictionary <string, IOperationLock> >();

            initLock["deployment"].LockOperation(() =>
            {
                IRepository repository = _repositoryFactory.GetRepository();

                // if repository exists, no need to do anything
                if (repository != null)
                {
                    return;
                }

                var repositoryPath = settings.GetValue(SettingsKeys.RepositoryPath);

                // if repository settings is defined, it's already been taken care.
                if (!String.IsNullOrEmpty(repositoryPath))
                {
                    return;
                }

                var env = GetInstance <IEnvironment>();
                // it is default webroot content, do nothing
                if (DeploymentHelper.IsDefaultWebRootContent(env.WebRootPath))
                {
                    return;
                }

                // Set repo path to WebRoot
                var previous       = env.RepositoryPath;
                env.RepositoryPath = Path.Combine(env.SiteRootPath, Constants.WebRoot);

                repository = _repositoryFactory.GetRepository();
                if (repository != null)
                {
                    env.RepositoryPath = previous;
                    return;
                }

                // do initial commit
                repository = _repositoryFactory.EnsureRepository(RepositoryType.Git);

                // Once repo is init, persist the new repo path
                settings.SetValue(SettingsKeys.RepositoryPath, Constants.WebRoot);

                repository.Commit("Initial Commit", authorName: null, emailAddress: null);
            }, "Cloning repository", GitExeServer.InitTimeout);
        }
Esempio n. 22
0
 public static void AssemblyInitialize(TestContext testContext)
 {
     //Todo: This will fail if local cluster is not setup, currently the test code does not automatically
     //start a local cluster and that's a manual pre-req step.
     //Todo: Also this will assume that latest SF test application and service code is packaged, if that's not true
     //the issue might be hard to detect :-(
     DeploymentHelper.CleanAsync().Wait();
     DeploymentHelper.DeployAsync(TestApplicationRootPath).Wait();
 }
Esempio n. 23
0
        private ISiteBuilder ResolveProject(string repositoryRoot, string targetPath, IDeploymentSettingsManager perDeploymentSettings, IFileFinder fileFinder, bool tryWebSiteProject, SearchOption searchOption = SearchOption.AllDirectories, bool specificConfiguration = true)
        {
            if (DeploymentHelper.IsProject(targetPath))
            {
                return(DetermineProject(repositoryRoot, targetPath, perDeploymentSettings, fileFinder));
            }

            // Check for loose projects
            var projects = DeploymentHelper.GetProjects(targetPath, fileFinder, searchOption);

            if (projects.Count > 1)
            {
                // Can't determine which project to build
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
                                                                  Resources.Error_AmbiguousProjects,
                                                                  String.Join(", ", projects)));
            }
            else if (projects.Count == 1)
            {
                return(DetermineProject(repositoryRoot, projects[0], perDeploymentSettings, fileFinder));
            }

            if (tryWebSiteProject)
            {
                // Website projects need a solution to build so look for one in the repository path
                // that has this website in it.
                var solutions = VsHelper.FindContainingSolutions(targetPath, fileFinder);

                // More than one solution is ambiguous
                if (solutions.Count > 1)
                {
                    ThrowAmbiguousSolutionsError(solutions);
                }
                else if (solutions.Count == 1)
                {
                    // Unambiguously pick the root
                    return(new WebSiteBuilder(_environment,
                                              perDeploymentSettings,
                                              _propertyProvider,
                                              repositoryRoot,
                                              targetPath,
                                              solutions[0].Path));
                }
            }

            // This should only ever happen if the user specifies an invalid directory.
            // The other case where the method is called we always resolve the path so it's a non issue there.
            if (specificConfiguration && !Directory.Exists(targetPath))
            {
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
                                                                  Resources.Error_ProjectDoesNotExist,
                                                                  targetPath));
            }

            // If there's none then use the basic builder (the site is xcopy deployable)
            return(ResolveNonAspProject(repositoryRoot, targetPath, perDeploymentSettings));
        }
Esempio n. 24
0
        // OneDeploy Fetch handler for non-zip artifacts.
        // For zip files, OneDeploy uses the LocalZipHandler Fetch handler
        // NOTE: Do not access the request stream as it may have been closed during asynchronous scenarios
        private async Task OneDeployFetch(IRepository repository, DeploymentInfoBase deploymentInfo, string targetBranch, ILogger logger, ITracer tracer)
        {
            var artifactDeploymentInfo = (ArtifactDeploymentInfo)deploymentInfo;

            // This is the path where the artifact being deployed is staged, before it is copied to the final target location
            var artifactDirectoryStagingPath = repository.RepositoryPath;

            var targetInfo = FileSystemHelpers.DirectoryInfoFromDirectoryName(artifactDirectoryStagingPath);

            if (targetInfo.Exists)
            {
                // If tempDirPath already exists, rename it so we can delete it later
                var moveTarget = Path.Combine(targetInfo.Parent.FullName, Path.GetRandomFileName());
                using (tracer.Step(string.Format("Renaming ({0}) to ({1})", targetInfo.FullName, moveTarget)))
                {
                    targetInfo.MoveTo(moveTarget);
                }
            }

            // Create artifact staging directory before later use
            Directory.CreateDirectory(artifactDirectoryStagingPath);
            var artifactFileStagingPath = Path.Combine(artifactDirectoryStagingPath, deploymentInfo.TargetFileName);

            // If RemoteUrl is non-null, it means the content needs to be downloaded from the Url source to the staging location
            // Else, it had been downloaded already so we just move the downloaded file to the staging location
            if (!string.IsNullOrWhiteSpace(artifactDeploymentInfo.RemoteURL))
            {
                using (tracer.Step("Saving request content to {0}", artifactFileStagingPath))
                {
                    var content = await DeploymentHelper.GetArtifactContentFromURL(artifactDeploymentInfo, tracer);

                    var copyTask = content.CopyToAsync(artifactFileStagingPath, tracer);

                    // Deletes all files and directories except for artifactFileStagingPath and artifactDirectoryStagingPath
                    var cleanTask = Task.Run(() => DeleteFilesAndDirsExcept(artifactFileStagingPath, artifactDirectoryStagingPath, tracer));

                    // Lets the copy and cleanup tasks to run in parallel and wait for them to finish
                    await Task.WhenAll(copyTask, cleanTask);
                }
            }
            else
            {
                var srcInfo = FileSystemHelpers.DirectoryInfoFromDirectoryName(deploymentInfo.RepositoryUrl);
                using (tracer.Step(string.Format("Moving {0} to {1}", targetInfo.FullName, artifactFileStagingPath)))
                {
                    srcInfo.MoveTo(artifactFileStagingPath);
                }

                // Deletes all files and directories except for artifactFileStagingPath and artifactDirectoryStagingPath
                DeleteFilesAndDirsExcept(artifactFileStagingPath, artifactDirectoryStagingPath, tracer);
            }

            // The deployment flow expects at least 1 commit in the IRepository commit, refer to CommitRepo() for more info
            CommitRepo(repository, artifactDeploymentInfo);
        }
Esempio n. 25
0
        public void SmartCopyDeletesFilesThatDontExistInSourceIfNoPrevious()
        {
            DirectoryWrapper sourceDirectory      = GetDirectory(@"a:\test\", filePaths: new[] { @"a.txt", "b.txt" });
            DirectoryWrapper destinationDirectory = GetDirectory(@"b:\foo\", filePaths: new[] { "c.txt" });

            DeploymentHelper.SmartCopy(@"a:\test\", @"b:\foo\", null, sourceDirectory.Directory, destinationDirectory.Directory, path => GetDirectory(path, exists: false).Directory);

            sourceDirectory.VerifyCopied("a.txt", @"b:\foo\a.txt");
            sourceDirectory.VerifyCopied("b.txt", @"b:\foo\b.txt");
            destinationDirectory.VerifyDeleted("c.txt");
        }
 /// <summary>
 /// Returns the server link to the deployment.
 /// </summary>
 /// <returns>Returns the server link to the deployment.</returns>
 public string GetDeploymentLink()
 {
     if (taskToManage != null)
     {
         return(DeploymentHelper.GetDeploymentLinkForWeb(deploymentToManage));
     }
     else
     {
         return(string.Empty);
     }
 }
Esempio n. 27
0
        public async Task CreateDeployment_WithStatusMessageOtherThan200Or201_ReturnsDeploymentFailedMessage()
        {
            var template = @"{
  ""$schema"": ""https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"",
  ""resources"": [
    {
      ""type"": ""Microsoft.Storage/storageAccounts"",
      ""apiVersion"": ""2021-06-01"",
      ""name"": ""storageaccount"",
      ""location"": ""[resourceGroup().location]"",
      ""properties"": {}
    }
  ]
}";
            var response = StrictMock.Of <Response>();

            response.Setup(m => m.Status).Returns(502);
            var responseMessage = "sample response";

            response.Setup(m => m.ToString()).Returns(responseMessage);

            var deploymentCreateOrUpdateOperation = StrictMock.Of <DeploymentCreateOrUpdateOperation>();

            deploymentCreateOrUpdateOperation.Setup(m => m.HasValue).Returns(true);
            deploymentCreateOrUpdateOperation.Setup(m => m.GetRawResponse()).Returns(response.Object);

            var deploymentCollection = StrictMock.Of <DeploymentCollection>();

            deploymentCollection
            .Setup(m => m.CreateOrUpdateAsync(
                       It.IsAny <bool>(),
                       It.IsAny <string>(),
                       It.IsAny <DeploymentInput>(),
                       It.IsAny <CancellationToken>())).Returns(Task.FromResult(deploymentCreateOrUpdateOperation.Object));

            var deploymentCollectionProvider = StrictMock.Of <IDeploymentCollectionProvider>();

            deploymentCollectionProvider
            .Setup(m => m.GetDeploymentCollection(It.IsAny <ArmClient>(), It.IsAny <ResourceIdentifier>(), LanguageConstants.TargetScopeTypeResourceGroup))
            .Returns(deploymentCollection.Object);
            var documentPath = "some_path";

            var result = await DeploymentHelper.CreateDeployment(
                deploymentCollectionProvider.Object,
                CreateMockArmClient(),
                documentPath,
                template,
                string.Empty,
                "/subscriptions/07268dd7-4c50-434b-b1ff-67b8164edb41/resourceGroups/bhavyatest",
                LanguageConstants.TargetScopeTypeResourceGroup,
                "");

            result.Should().Be(string.Format(LangServerResources.DeploymentFailedWithExceptionMessage, documentPath, responseMessage));
        }
Esempio n. 28
0
        public async Task StartDeploymentAsync_WithExceptionWhileCreatingDeployment_ReturnsDeploymentFailedMessage()
        {
            var template             = @"{
  ""$schema"": ""https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"",
  ""resources"": [
    {
      ""type"": ""Microsoft.Storage/storageAccounts"",
      ""apiVersion"": ""2021-06-01"",
      ""name"": ""storageaccount"",
      ""location"": ""[resourceGroup().location]"",
      ""properties"": {}
    }
  ]
}";
            var deploymentCollection = StrictMock.Of <ArmDeploymentCollection>();
            var errorMessage         = "Encountered error while creating deployment";

            deploymentCollection
            .Setup(m => m.CreateOrUpdateAsync(
                       It.IsAny <WaitUntil>(),
                       It.IsAny <string>(),
                       It.IsAny <ArmDeploymentContent>(),
                       It.IsAny <CancellationToken>()))
            .Throws(new Exception(errorMessage));
            var deploymentCollectionProvider = StrictMock.Of <IDeploymentCollectionProvider>();

            deploymentCollectionProvider
            .Setup(m => m.GetDeploymentCollection(It.IsAny <ArmClient>(), It.IsAny <ResourceIdentifier>(), LanguageConstants.TargetScopeTypeResourceGroup))
            .Returns(deploymentCollection.Object);
            var documentPath = "some_path";

            var bicepDeployStartResponse = await DeploymentHelper.StartDeploymentAsync(
                deploymentCollectionProvider.Object,
                CreateMockArmClient(),
                documentPath,
                template,
                string.Empty,
                "/subscriptions/07268dd7-4c50-434b-b1ff-67b8164edb41/resourceGroups/bhavyatest",
                LanguageConstants.TargetScopeTypeResourceGroup,
                "",
                string.Empty,
                string.Empty,
                ParametersFileUpdateOption.None,
                new List <BicepUpdatedDeploymentParameter>(),
                "https://portal.azure.com",
                "bicep_deployment",
                new DeploymentOperationsCache());

            var expectedDeploymentOutputMessage = string.Format(LangServerResources.DeploymentFailedWithExceptionMessage, documentPath, errorMessage);

            bicepDeployStartResponse.isSuccess.Should().BeFalse();
            bicepDeployStartResponse.outputMessage.Should().Be(expectedDeploymentOutputMessage);
            bicepDeployStartResponse.viewDeploymentInPortalMessage.Should().BeNull();
        }
Esempio n. 29
0
        private void EnsureProperties()
        {
            if (_initialized)
            {
                return;
            }

            _projectName = _projectNameProperty.GetValue <string>(_projectInstance);
            var projectType  = _projectTypeProperty.GetValue <SolutionProjectType>(_projectInstance);
            var relativePath = _relativePathProperty.GetValue <string>(_projectInstance);

            _isWebSite = projectType == SolutionProjectType.WebProject;

            // When using websites with IISExpress, the relative path property becomes a URL.
            // When that happens we're going to grab the path from the Release.AspNetCompiler.PhysicalPath
            // property in the solution.

            Uri uri;

            if (_isWebSite && Uri.TryCreate(relativePath, UriKind.Absolute, out uri))
            {
                var aspNetConfigurations = _aspNetConfigurationsProperty.GetValue <Hashtable>(_projectInstance);

                // Use the release configuration and debug if it isn't available
                object configurationObject = aspNetConfigurations["Release"] ?? aspNetConfigurations["Debug"];

                // REVIEW: Is there always a configuration object (i.e. can this ever be null?)

                // The aspNetPhysicalPath contains the relative to the website
                FieldInfo aspNetPhysicalPathField = configurationObject.GetType().GetField("aspNetPhysicalPath", BindingFlags.NonPublic | BindingFlags.Instance);

                relativePath = (string)aspNetPhysicalPathField.GetValue(configurationObject);
            }

            _absolutePath = Path.Combine(Path.GetDirectoryName(_solutionPath), relativePath);
            if (FileSystemHelpers.FileExists(_absolutePath) && DeploymentHelper.IsMsBuildProject(_absolutePath))
            {
                // used to determine project type from project file
                _projectTypeGuids = VsHelper.GetProjectTypeGuids(_absolutePath);

                _isAspNetCore    = AspNetCoreHelper.IsDotnetCoreFromProjectFile(_absolutePath, _projectTypeGuids);
                _isWap           = VsHelper.IsWap(_projectTypeGuids);
                _isExecutable    = VsHelper.IsExecutableProject(_absolutePath);
                _isFunctionApp   = FunctionAppHelper.LooksLikeFunctionApp();
                _targetFramework = VsHelper.GetTargetFramework(_absolutePath);
            }
            else
            {
                _projectTypeGuids = Enumerable.Empty <Guid>();
            }

            _initialized = true;
        }
Esempio n. 30
0
        public async Task StartDeploymentAsync_WithValidScopeAndInput_ShouldUpdateDeploymentOperationsCache()
        {
            var template = @"{
  ""$schema"": ""https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"",
  ""resources"": [
    {
      ""type"": ""Microsoft.Storage/storageAccounts"",
      ""apiVersion"": ""2021-06-01"",
      ""name"": ""storageaccount"",
      ""location"": ""[resourceGroup().location]"",
      ""properties"": {}
    }
  ]
}";

            var armDeploymentResourceOperation = StrictMock.Of <ArmOperation <ArmDeploymentResource> >().Object;
            var deploymentCollection           = StrictMock.Of <ArmDeploymentCollection>();

            deploymentCollection
            .Setup(m => m.CreateOrUpdateAsync(
                       It.IsAny <WaitUntil>(),
                       It.IsAny <string>(),
                       It.IsAny <ArmDeploymentContent>(),
                       It.IsAny <CancellationToken>())).Returns(Task.FromResult(armDeploymentResourceOperation));

            var deploymentCollectionProvider = StrictMock.Of <IDeploymentCollectionProvider>();

            deploymentCollectionProvider
            .Setup(m => m.GetDeploymentCollection(It.IsAny <ArmClient>(), It.IsAny <ResourceIdentifier>(), LanguageConstants.TargetScopeTypeSubscription))
            .Returns(deploymentCollection.Object);

            var deploymentOperationsCache = new DeploymentOperationsCache();
            var deployId = "bicep_deployment1";

            var bicepDeployStartResponse = await DeploymentHelper.StartDeploymentAsync(
                deploymentCollectionProvider.Object,
                CreateMockArmClient(),
                "some_path",
                template,
                string.Empty,
                "/subscriptions/07268dd7-4c50-434b-b1ff-67b8164edb41/resourceGroups/bhavyatest",
                LanguageConstants.TargetScopeTypeSubscription,
                "eastus",
                deployId,
                string.Empty,
                ParametersFileUpdateOption.None,
                new List <BicepUpdatedDeploymentParameter>(),
                "https://portal.azure.com",
                "deployment_name",
                deploymentOperationsCache);

            deploymentOperationsCache.FindAndRemoveDeploymentOperation(deployId).Should().NotBeNull();
        }