GetDeploymentSetup(DeploymentTarget deploymentTarget) { var app = await _applicationService.Get(deploymentTarget.ApplicationName); if (app == null) { throw new Exception($"Can't find application [{deploymentTarget.ApplicationName}]. Check the correctness of the manifest."); } var env = await _environmentService.Get(app.Id, deploymentTarget.EnvironmentName); if (env == null) { throw new Exception($"Can't find environment [{deploymentTarget.EnvironmentName}] for application [{deploymentTarget.ApplicationName}]. Check the correctness of the manifest."); } var deploymentStrategies = await _client.ListDeploymentStrategiesAsync(new ListDeploymentStrategiesRequest()); var deploymentStrategy = deploymentStrategies.Items.FirstOrDefault(x => x.Name == deploymentTarget.DeploymentStrategy); if (deploymentStrategy == null) { throw new Exception($"Can't find deployment strategy [{deploymentTarget.DeploymentStrategy}]. Check the correctness of the manifest."); } return(app, env, deploymentStrategy); }
/// <summary> /// Deploys a registered model /// </summary> /// <param name="deploymentTarget"></param> /// <param name="registeredModel"></param> /// <param name="deployedBy"></param> /// <returns>A deployment</returns> /// <returns></returns> public async Task <Deployment> DeployModelAsync(DeploymentTarget deploymentTarget, RegisteredModel registeredModel, string deployedBy) { var experiment = this.experimentRepository.GetExperiment(registeredModel.ExperimentId); var deploymentUri = await this.modelRepository.DeployModelAsync(deploymentTarget, registeredModel, experiment); return(await this.deploymentRepository.CreateDeploymentAsync(deploymentTarget, registeredModel, deployedBy, deploymentUri)); }
public async Task DeployModelAsync_GivenADeployedModelAlreadyExists_ShouldOverwriteExistingModel() { //Arrange var client = new HttpClient(); var deploymentTarget = new DeploymentTarget("Test"); var firstModelUri = await DeployModelAsync(deploymentTarget); var model1 = await client.GetAsync(firstModelUri); var firstModelUpdateTime = model1.Content.Headers.LastModified; Thread.Sleep(60000); //Act var uri = await DeployModelAsync(deploymentTarget); //Assert var model2 = await client.GetAsync(uri); var secondModelUpdateTime = model2.Content.Headers.LastModified; firstModelUpdateTime.Value.Ticks.Should().BeLessThan(secondModelUpdateTime.Value.Ticks); }
public async Task SeedAsync(CancellationToken cancellationToken) { var testTarget = new DeploymentTarget("TestTarget", "Test target", "MilouDeployerWebTest", allowExplicitPreRelease: false, autoDeployEnabled: true, targetDirectory: Environment.GetEnvironmentVariable("TestDeploymentTargetPath"), uri: Environment.GetEnvironmentVariable("TestDeploymentUri"), emailNotificationAddresses: new StringValues("*****@*****.**"), enabled: true); var createTarget = new CreateTarget(testTarget.Id, testTarget.Name); await _mediator.Send(createTarget, cancellationToken); var updateDeploymentTarget = new UpdateDeploymentTarget(testTarget.Id, testTarget.AllowPreRelease, testTarget.Url, testTarget.PackageId, autoDeployEnabled: testTarget.AutoDeployEnabled, targetDirectory: testTarget.TargetDirectory, enabled: true); await _mediator.Send(updateDeploymentTarget, cancellationToken); }
public DeploymentTargetViewOutputModel( [NotNull] DeploymentTarget target, [NotNull] IReadOnlyCollection <StringPair> configurationPairs) { Target = target ?? throw new ArgumentNullException(nameof(target)); ConfigurationPairs = configurationPairs ?? throw new ArgumentNullException(nameof(configurationPairs)); }
private static DeploymentTarget MapDataToTarget(DeploymentTargetData deploymentTargetData) { if (deploymentTargetData is null) { return(null); } var deploymentTargetAsync = new DeploymentTarget( deploymentTargetData.Id, deploymentTargetData.Name, deploymentTargetData.PackageId ?? Core.Constants.NotAvailable, deploymentTargetData.PublishSettingsXml, deploymentTargetData.AllowExplicitPreRelease, uri: deploymentTargetData.Url?.ToString(), nuGetConfigFile: deploymentTargetData.NuGetConfigFile, nuGetPackageSource: deploymentTargetData.NuGetPackageSource, iisSiteName: deploymentTargetData.IisSiteName, autoDeployEnabled: deploymentTargetData.AutoDeployEnabled, targetDirectory: deploymentTargetData.TargetDirectory, webConfigTransform: deploymentTargetData.WebConfigTransform, excludedFilePatterns: deploymentTargetData.ExcludedFilePatterns, enabled: deploymentTargetData.Enabled); return(deploymentTargetAsync); }
public async Task <DeploymentTarget> GetDeploymentTargetAsync( [NotNull] string deploymentTargetId, CancellationToken cancellationToken = default) { if (string.IsNullOrWhiteSpace(deploymentTargetId)) { throw new ArgumentException("Value cannot be null or whitespace.", nameof(deploymentTargetId)); } using (IQuerySession session = _documentStore.QuerySession()) { try { DeploymentTargetData deploymentTargetData = await session.Query <DeploymentTargetData>() .SingleOrDefaultAsync(target => target.Id.Equals(deploymentTargetId, StringComparison.OrdinalIgnoreCase), cancellationToken); DeploymentTarget deploymentTarget = MapDataToTarget(deploymentTargetData); return(deploymentTarget); } catch (Exception ex) when(!ex.IsFatal()) { _logger.Warning(ex, "Could not get deployment target with id {Id}", deploymentTargetId); return(DeploymentTarget.None); } } }
///<inheritdoc cref="IDeploymentRepository"/> public async Task <DeploymentTarget> CreateDeploymentTargetAsync(string deploymentTargetName, bool isProduction = false) { if (string.IsNullOrEmpty(deploymentTargetName)) { throw new ArgumentNullException("Deployment target name was not specified"); } using var db = this.contextFactory.CreateDbContext(); var existingDeploymentTarget = db.DeploymentTargets.FirstOrDefault(x => x.Name == deploymentTargetName); if (existingDeploymentTarget != null) { return(this.deploymentTargetResolver.BuildEntity(db, existingDeploymentTarget)); } var deploymentTarget = new DeploymentTarget(deploymentTargetName) { CreatedDate = clock.UtcNow, IsProduction = isProduction }; db.DeploymentTargets.Add(deploymentTarget); await db.SaveChangesAsync(); return(deploymentTarget); }
private async Task <AppVersion> GetAppVersionAsync( HttpResponseMessage response, DeploymentTarget target, IReadOnlyCollection <PackageVersion> filtered, CancellationToken cancellationToken) { if (response.Content.Headers.ContentType?.MediaType.Equals("application/json", StringComparison.OrdinalIgnoreCase) != true) { return(new AppVersion(target, "Response not JSON", filtered)); } string json = await response.Content.ReadAsStringAsync(); if (cancellationToken.IsCancellationRequested) { return(new AppVersion(target, "Timeout", filtered)); } ConfigurationItems configuration = new JsonConfigurationSerializer().Deserialize(json); var nameValueCollection = new NameValueCollection(); foreach (KeyValue configurationItem in configuration.Keys) { nameValueCollection.Add(configurationItem.Key, configurationItem.Value); } var appVersion = new AppVersion(target, new InMemoryKeyValueConfiguration(nameValueCollection), filtered); return(appVersion); }
public async Task GetDeploymentUri_GivenADeployedModel_ShouldReturnAValidUri() { //Arrange var runId = Guid.NewGuid(); var experiment = new Experiment("ExperimentName"); await sut.UploadModelAsync(runId, @"Data/model.txt"); var registeredModel = new RegisteredModel { RunId = runId, ExperimentId = experiment.ExperimentId }; var deploymentTarget = new DeploymentTarget("Test"); await sut.DeployModelAsync(deploymentTarget, registeredModel, experiment); //Act var uri = sut.GetDeploymentUri(experiment, deploymentTarget); //Assert var client = new HttpClient(); var response = await client.GetAsync(uri); response.StatusCode.Should().Be(HttpStatusCode.OK); response.Content.Headers.ContentLength.Should().BeGreaterThan(0); }
private static string LogJobMetadata( DeploymentTask deploymentTask, DateTime start, DateTime end, Stopwatch stopwatch, ExitCode exitCode, DirectoryInfo deploymentJobsDirectory, DeploymentTarget deploymentTarget) { var metadata = new StringBuilder(); metadata .Append("Started job ") .Append(deploymentTask.DeploymentTaskId) .Append(" at ") .AppendFormat("{0:O}", start) .Append(" and finished at ") .AppendFormat("{0:O}", end).AppendLine(); metadata .Append("Total time ") .AppendFormat("{0:f}", stopwatch.Elapsed.TotalSeconds) .AppendLine(" seconds"); metadata .Append("Package version: ") .Append(deploymentTask.SemanticVersion) .AppendLine(); metadata .Append("Package id: ") .AppendLine(deploymentTask.PackageId); metadata .Append("Target id: ") .AppendLine(deploymentTask.DeploymentTargetId); if (deploymentTarget is null) { metadata.AppendLine("Deployment target not found"); } else { metadata.Append("Publish settings file: ").AppendLine(deploymentTarget.PublishSettingFile); metadata.Append("Target directory: ").AppendLine(deploymentTarget.TargetDirectory); metadata.Append("Target URI: ").Append(deploymentTarget.Url).AppendLine(); } metadata.Append("Exit code ").Append(exitCode).AppendLine(); string metadataContent = metadata.ToString(); string metadataFilePath = Path.Combine(deploymentJobsDirectory.FullName, $"{deploymentTask.DeploymentTaskId}.metadata.txt"); File.WriteAllText(metadataFilePath, metadataContent, Encoding.UTF8); return(metadataContent); }
public void GetConfigFromTargetWithoutEnvironment() { var target = new DeploymentTarget(new DeploymentTargetId("123"), "123", "abc"); string?environmentConfig = target.GetEnvironmentConfiguration(); Assert.Null(environmentConfig); }
private async Task <(ExitCode, DateTime)> RunDeploymentToolAsync( DeploymentTask deploymentTask, DirectoryInfo deploymentJobsDirectory, DeploymentTarget deploymentTarget, ILogger logger, CancellationToken cancellationToken = default) { string contentFilePath = GetMainLogFilePath(deploymentTask, deploymentJobsDirectory); ExitCode exitCode; var logBuilder = new StringBuilder(); LoggerConfiguration loggerConfiguration = new LoggerConfiguration() .WriteTo.File(contentFilePath) .WriteTo.DelegateSink(deploymentTask.Log) .WriteTo.DelegateSink(message => logBuilder.AppendLine(message)) .WriteTo.Logger(logger); if (Debugger.IsAttached) { loggerConfiguration = loggerConfiguration.WriteTo.Debug(LogEventLevel.Verbose); } loggerConfiguration = loggerConfiguration.MinimumLevel.ControlledBy(_loggingLevelSwitch); using (Logger log = loggerConfiguration.CreateLogger()) { if (logger.IsEnabled(LogEventLevel.Debug)) { logger.Debug( "Running tool '{Deployer}' for deployment target '{DeploymentTarget}', package '{PackageId}' version {Version}", _deployer, deploymentTarget, deploymentTask.PackageId, deploymentTask.SemanticVersion.ToNormalizedString()); } try { exitCode = await _deployer.ExecuteAsync(deploymentTask, log, cancellationToken); } catch (Exception ex) when(!ex.IsFatal()) { _logger.Error(ex, "Failed to deploy task {DeploymentTask}", deploymentTask); exitCode = ExitCode.Failure; } } DateTime finishedAtUtc = _customClock.UtcNow().UtcDateTime; await _mediator.Publish( new DeploymentFinishedNotification(deploymentTask, logBuilder.ToString(), finishedAtUtc), cancellationToken); return(exitCode, finishedAtUtc); }
public void GetConfigFromTargetWithOldEnvironment() { var target = new DeploymentTarget(new DeploymentTargetId("123"), "123", "abc", environmentConfiguration: "test"); string?environmentConfig = target.GetEnvironmentConfiguration(); Assert.Equal("test", environmentConfig); }
public void GetConfigFromTargetWithOtherEnvironment() { var target = new DeploymentTarget(new DeploymentTargetId("123"), "123", "abc", environmentType: new EnvironmentType("", "", PreReleaseBehavior.Allow)); string?environmentConfig = target.GetEnvironmentConfiguration(); Assert.Null(environmentConfig); }
public async Task <AppVersion> GetAppMetadataAsync( [NotNull] DeploymentTarget target, CancellationToken cancellationToken = default) { if (target == null) { throw new ArgumentNullException(nameof(target)); } AppVersion appMetadata; using (var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(_monitorConfiguration.DefaultTimeoutInSeconds))) { if (_logger.IsEnabled(LogEventLevel.Verbose)) { cancellationTokenSource.Token.Register(() => { _logger.Verbose("{Method} for {Target}, cancellation token invoked out after {Seconds} seconds", nameof(GetAppMetadataAsync), target.Id, _monitorConfiguration.DefaultTimeoutInSeconds); }); } using (CancellationTokenSource linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cancellationTokenSource.Token)) { (HttpResponseMessage response, string message) = await GetApplicationMetadataTask(target, linkedTokenSource.Token); using (HttpResponseMessage httpResponseMessage = response) { IReadOnlyCollection <PackageVersion> packages = await GetAllowedPackagesAsync(target, linkedTokenSource.Token); if (httpResponseMessage == null) { return(new AppVersion(target, message ?? $"Could not get application metadata from target {target.Url}, no response", packages)); } if (!httpResponseMessage.IsSuccessStatusCode) { return(new AppVersion(target, message ?? $"Could not get application metadata from target {target.Url}, status code not successful {httpResponseMessage.StatusCode}", packages)); } appMetadata = await GetAppVersionAsync(httpResponseMessage, target, packages, linkedTokenSource.Token); } } } return(appMetadata); }
public void GetConfigFromTargetWithEmptyOldEnvironment() { var target = new DeploymentTarget(new DeploymentTargetId("123"), "123", "abc", environmentConfiguration: ""); string?environmentConfig = target.GetEnvironmentConfiguration(); Assert.True(string.IsNullOrWhiteSpace(environmentConfig)); }
public AppVersion( [NotNull] DeploymentTarget target, [NotNull] IKeyValueConfiguration manifestProperties, IReadOnlyCollection <PackageVersion> availablePackageVersions) { Properties = manifestProperties ?? throw new ArgumentNullException(nameof(manifestProperties)); AvailablePackageVersions = availablePackageVersions.SafeToImmutableArray(); Target = target ?? throw new ArgumentNullException(nameof(target)); Status = GetStatus(); }
public AppVersion( [NotNull] DeploymentTarget target, string message, IReadOnlyCollection <PackageVersion> availablePackages) { Properties = new InMemoryKeyValueConfiguration(new NameValueCollection()); Target = target; Message = message; AvailablePackageVersions = availablePackages.SafeToImmutableArray(); Status = GetStatus(); }
public void GetDeploymentPath_ShouldReturnCorrectDeploymentPath() { var deploymentTarget = new DeploymentTarget("Test"); var expectedPath = Path.Combine("ExperimentName", "Test", $"ExperimentName.zip"); // Act var deploymentPath = sut.GetDeploymentPath(deploymentTarget, "ExperimentName"); // Assert deploymentPath.Should().Be(expectedPath); }
private static void CheckPackageMatchingTarget(DeploymentTarget deploymentTarget, string packageId) { if ( !deploymentTarget.PackageId.Equals(packageId, StringComparison.InvariantCultureIgnoreCase)) { string allPackageIds = string.Join(", ", deploymentTarget.PackageId.Select(name => $"'{name}'")); throw new DeployerAppException( $"The package id '{packageId}' is not in the list of allowed package ids: {allPackageIds}"); } }
public async Task <DeploymentTarget> GetDeploymentTargetAsync( string deploymentTargetId, CancellationToken cancellationToken = default) { ImmutableArray <OrganizationInfo> organizations = await GetOrganizationsAsync(cancellationToken); DeploymentTarget foundDeploymentTarget = organizations .SelectMany(organizationInfo => organizationInfo.Projects) .SelectMany(projectInfo => projectInfo.DeploymentTargets) .SingleOrDefault(deploymentTarget => deploymentTarget.Id == deploymentTargetId); return(foundDeploymentTarget); }
public async Task <IActionResult> Edit( [FromRoute] string targetId, [FromServices] IDeploymentTargetReadService deploymentTargetReadService) { DeploymentTarget deploymentTarget = await deploymentTargetReadService.GetDeploymentTargetAsync(targetId); if (deploymentTarget is null) { return(RedirectToAction(nameof(Index))); } return(View(new EditTargetViewOutputModel(deploymentTarget))); }
public string GetDeploymentUri(Experiment experiment, DeploymentTarget deploymentTarget) { var deploymentPath = this.modelPathGenerator.GetDeploymentPath(deploymentTarget, experiment.ExperimentName); var request = new GetPreSignedUrlRequest { BucketName = deploymentRepositoryBucket, Key = deploymentPath, Expires = DateTime.Now.AddYears(5), Protocol = Protocol.HTTP }; return(this.s3Client.GetPreSignedURL(request)); }
public async Task DeployModel_NoSourceFileExists_ShouldThrowException() { var experiment = new Experiment("ExperimentName"); var registeredModel = new RegisteredModel { RunId = Guid.NewGuid(), }; var deploymentTarget = new DeploymentTarget("Test"); // Act await sut.DeployModelAsync(deploymentTarget, registeredModel, experiment); }
private async Task <string> DeployModelAsync(DeploymentTarget deploymentTarget) { var runId = Guid.NewGuid(); var experiment = new Experiment("ExperimentName"); await sut.UploadModelAsync(runId, @"Data/model.txt"); var registeredModel = new RegisteredModel { RunId = runId, ExperimentId = experiment.ExperimentId }; return(await sut.DeployModelAsync(deploymentTarget, registeredModel, experiment)); }
public async Task DeployModel_NoSourceFileExist_ShouldThrowException() { var experiment = new Experiment("ExperimentName"); var registeredModel = new RegisteredModel { RunId = Guid.NewGuid(), ExperimentId = experiment.ExperimentId }; var deploymentTarget = new DeploymentTarget("Test"); var blobClientMock = new Mock <BlobClient>(); var responseMock = new Mock <Response <bool> >(); blobClientMock.Setup(x => x.Exists(default)).Returns(responseMock.Object);
public async Task <string> DeployModelAsync(DeploymentTarget deploymentTarget, RegisteredModel registeredModel, Experiment experiment) { var deploymentPath = this.modelPathGenerator.GetDeploymentPath(deploymentTarget, experiment.ExperimentName); var sourceModelBlob = this.modelRepositoryClient.GetBlobClient(this.modelPathGenerator.GetModelName(registeredModel.RunId)); var deployedModelBlob = this.deploymentClient.GetBlobClient(deploymentPath); if (!sourceModelBlob.Exists()) { throw new InvalidOperationException("The model to be deployed does not exist"); } await deployedModelBlob.StartCopyFromUriAsync(sourceModelBlob.Uri); return(deployedModelBlob.Uri.ToString()); }
private async Task UpdateTarget(CancellationToken cancellationToken, DeploymentTarget deploymentTarget, ImmutableArray <EnvironmentType> environmentTypes) { string?typeId = default; string?environmentConfiguration = deploymentTarget.EnvironmentConfiguration; if (string.IsNullOrWhiteSpace(deploymentTarget.EnvironmentTypeId) && !string.IsNullOrWhiteSpace(environmentConfiguration)) { string configuration = environmentConfiguration.Trim(); EnvironmentType?foundType = environmentTypes.SingleOrDefault(type => type.Name.Trim().Equals(configuration, StringComparison.OrdinalIgnoreCase)); if (foundType is { })
///<inheritdoc cref="IDeploymentRepository"/> public async Task <Deployment> CreateDeploymentAsync(DeploymentTarget deploymentTarget, RegisteredModel registeredModel, string deployedBy, string deploymentUri) { using var db = this.contextFactory.CreateDbContext(); var deployment = new Deployment() { DeploymentDate = this.clock.UtcNow, DeployedBy = deployedBy, DeploymentTargetId = deploymentTarget.DeploymentTargetId, RegisteredModelId = registeredModel.RegisteredModelId, DeploymentUri = deploymentUri }; db.Deployments.Add(deployment); await db.SaveChangesAsync(); return(deployment); }
/// <summary> /// Configures the deployment /// </summary> /// <param name="deployment"></param> /// <param name="portalInstanceId"></param> private void InitializeDeployment(Sage.Platform.Deployment.Deployment deployment, string portalInstanceId) { // Configure the portal var portal = new DeploymentTargetPortal { PortalName = Manifest.PortalName, IsActive = true, InstanceId = portalInstanceId }; // Configure the target var target = new DeploymentTarget("FS") { IsActive = true }; target.ExtendedProperties.SetValue(DeploymentTargetConstants.DeploymentPath, Manifest.DeploymentPath); target.Portals.Add(portal); deployment.Targets.Add(target); }
public TargetPortalInfo(DeploymentTarget target, DeploymentTargetPortal targetPortal) { Target = target; TargetPortal = targetPortal; }