/// <summary> /// Builds the deployment parameters from various data sources. /// </summary> /// <param name="deploymentType"></param> /// <param name="instanceId"></param> /// <param name="imageTagParameters">Map of parameters extracted from the image tag.</param> /// <param name="githubPrObject">The github pull request if relevant.</param> /// <param name="applicationImage"></param> /// <returns></returns> public static DeploymentParameters Build( DeploymentType deploymentType, string instanceId, IReadOnlyDictionary <string, string> imageTagParameters, PullRequest?githubPrObject, ApplicationImage applicationImage) { var dict = new Dictionary <string, string>(imageTagParameters); if (githubPrObject != null) { dict.Add(DeploymentParameterConstants.PullRequestId, githubPrObject.Id.ToString()); dict.Add(DeploymentParameterConstants.PullRequestNumber, githubPrObject.Number.ToString()); dict.Add(DeploymentParameterConstants.PullRequestCreatorEmail, githubPrObject.User.Email); // TODO: this needs to be handled in such a way that it's not Preview Release specific. dict.Add(DeploymentParameterConstants.DeploymentCreator, githubPrObject.User.Email); } if (applicationImage.Ingress.IsAvailable) { var domain = applicationImage.Ingress.Domain; // TODO we need to change this to support urls instead of domains if (deploymentType == DeploymentType.PreviewRelease) { domain = $"{instanceId}.{domain}"; } dict.Add(DeploymentParameterConstants.Hostname, domain); } return(new DeploymentParameters(dict)); }
public async Task CreatePreviewRelease(RawDeploymentManifest manifest, ApplicationImage applicationImage, string instance, string previewTag) { var manifestInfo = await _parser.BuildDeploymentManifestInfo(manifest); if (manifestInfo.Instances.ContainsKey(new DeploymentManifestInstanceKey(applicationImage, instance))) { // instance already created, GTFO return; } // clone release files var modifiedFiles = await InternalCreateRelease(manifest, instance); // refresh manifest info manifestInfo = await _parser.BuildDeploymentManifestInfo(manifest); // apply tag update var updateOpResult = await InternalUpdateApplicationImageTag(manifest, manifestInfo, applicationImage, instance, previewTag); if (updateOpResult != null && !modifiedFiles.Contains(updateOpResult)) { modifiedFiles.Add(updateOpResult); } if (modifiedFiles.Any()) { var application = GetApplicationForApplicationImage(applicationImage); await _deploymentManifestRepositoryService.StageChanges(manifest.Repository, modifiedFiles); await _deploymentManifestRepositoryService.Commit( manifest.Repository, $"[{application}] Created new Preview Release instance ({instance}) deployment for image '{applicationImage.ShortRepository}' with tag {previewTag}." ); } }
public ActionResult AdsAdditional(Phone phone, HttpPostedFileBase image = null) { if (ModelState.IsValid) { User user = userManager.GetUserByCookies(HttpContext.Request.Cookies[Constants.NameCookie].Value); phone.UserId = user.UserId; phoneManager.Add(phone); if (image != null) { string fileName = Path.GetFileName(image.FileName); var path = Path.Combine(Server.MapPath("~/Images/"), fileName); image.SaveAs(path); ApplicationImage appImage = new ApplicationImage() { Image = Url.Content("~/Images/" + fileName), PhoneId = phoneManager.GetPhoneId(phone) }; imageManager.Add(appImage); } return(RedirectToAction("AdResult", phone)); } return(View(phone)); }
public async Task UpdateApplicationImageVersion( RawDeploymentManifest manifest, ApplicationImage applicationImage, string instance, string targetTag ) { var manifestInfo = await _parser.BuildDeploymentManifestInfo(manifest); var key = new DeploymentManifestInstanceKey(applicationImage, instance); string currentImageTag = manifestInfo.ManifestTags.GetValueOrDefault(key) ?? "n/a"; var result = await InternalUpdateApplicationImageTag(manifest, manifestInfo, applicationImage, instance, targetTag); if (result == null) { return; } // this is GIT requirement: we only work with relative paths in the git repository. _log.LogTrace("Adding {Path} to repository git staging", result); // var gitFilePath = Path.Combine(relativePath, file.Name); // var gitFilePath = Path.GetRelativePath(context.GitRepositoryRoot.FullName, file.FullName); // Commands.Stage(gitRepository, gitFilePath); var application = GetApplicationForApplicationImage(applicationImage); await _deploymentManifestRepositoryService.StageChanges(manifest.Repository, new[] { result }); await _deploymentManifestRepositoryService.Commit( manifest.Repository, $"[{application}] Updated deployment for {applicationImage.ShortRepository}; {currentImageTag} to {targetTag}" ); }
public void SetCurrentImageTag(Application application, ApplicationImage image, string tag) { lock (_lock) { var ctx = _applications[application.Name]; ctx.CurrentTags.AddOrUpdate(image, (x, y) => { _log.LogInformation("Adding '{Repository}' to application {Application} with tag {Tag}", x.Repository, y.application.Name, y.tag); return(y.tag); }, (x, current, y) => { if (current == y.tag) { return(current); } _log.LogInformation( "Updating '{Repository}' with tag {Tag} for application {Application} with new tag {NewTag}", x.Repository, current, y.application.Name, y.tag); return(y.tag); }, (application, tag) ); } }
private Task <FileInfo?> InternalUpdateApplicationImageTag( RawDeploymentManifest manifest, DeploymentManifestInfo deploymentManifestInfo, ApplicationImage applicationImage, string instance, string targetTag ) { var yamlUtilities = new YamlUtilities(); var key = new DeploymentManifestInstanceKey(applicationImage, instance); string currentImageTag = deploymentManifestInfo.ManifestTags.GetValueOrDefault(key) ?? "n/a"; if (!deploymentManifestInfo.ApplicationImageToFileMapping.TryGetValue(key, out FileInfo? file)) { // TODO: warn that we have an image tag update but no corresponding file // _log.LogWarning("Update to {Repository} cannot be applied since there isn't matching file."); throw new InvalidOperationException("Update cannot be applied since there isn't matching file."); } _log.LogTrace("Upgrading {Repository} to {NewTag} from {Tag}", applicationImage.Repository, targetTag, currentImageTag ); return(yamlUtilities.UpdateValueInYamlFile(file, applicationImage.TagProperty.Path, targetTag) ? Task.FromResult((FileInfo?)file) : Task.FromResult((FileInfo?)null)); }
private static ApplicationImage createImageFrom(Image bitmap, string imageName) { var appImage = new ApplicationImage(bitmap); _allImages.Add(imageName, appImage); return(appImage); }
private static async Task <EntityEntry <Dao.Deployment> > CreateAndStoreDeploymentDao( DbSet <Dao.Deployment> deployments, Application application, ApplicationImage image, DaoDeploymentType type, string newTag, string currentTag = "", string nameSuffix = "", string instanceId = "", IReadOnlyDictionary <string, string>?parameters = null) { var entity = await deployments.AddAsync(new Dao.Deployment() { Id = Guid.NewGuid(), ApplicationId = application.Name, CreationDateTime = DateTime.Now, DeploymentDateTime = null, Status = Dao.DeploymentStatus.Pending, ImageRepository = image.Repository, UpdatePath = image.TagProperty.Path, CurrentImageTag = currentTag, TargetImageTag = newTag, IsAutomaticDeployment = true, Type = type, NameSuffix = nameSuffix, InstanceId = instanceId, Parameters = new Dictionary <string, string>(parameters ?? new Dictionary <string, string>()) }); return(entity); }
public static int ImageIndex(ApplicationImage image) { if (_allImageList == null) { _allImageList = _allImages.ToList(); } return(_allImageList.IndexOf(image)); }
private Application GetApplicationForApplicationImage(ApplicationImage applicationImage) { var application = _applicationService .GetApplications() .First(x => x.Images.Contains(applicationImage)); return(application); }
public void Add(ApplicationImage image) { if (image == null) { throw new ArgumentNullException(nameof(image)); } repository.Add(image); }
public void Add(ApplicationImage image) { using (PhoneStoreContext context = new PhoneStoreContext()) { ImageEntity imageEntity = (ImageEntity) new ImageEntity().FromApplicationModel(image); context.Images.Add(imageEntity); context.SaveChanges(); } }
public ApplicationImage ConvertToApplicationModel() { ApplicationImage appImage = new ApplicationImage { ImageId = this.ImageId, Image = this.Image, PhoneId = this.PhoneId }; return(appImage); }
public IStorageModel <ApplicationImage> FromApplicationModel(ApplicationImage model) { if (model == null) { return(null); } ImageEntity imageEntity = new ImageEntity() { Image = model.Image, PhoneId = model.PhoneId }; return(imageEntity); }
public Task <bool> IsDeploymentPresent( Application application, ApplicationImage image, string newTag, DeploymentType type = DeploymentType.ImageUpdate, string instanceId = "") { var deployments = _deploymentsDbContextConfigurator.Set <Dao.Deployment>(); return(deployments.AnyAsync( x => x.ApplicationId == application.Name && x.ImageRepository == image.Repository && x.UpdatePath == image.TagProperty.Path && x.TargetImageTag == newTag && x.Type == (type == DeploymentType.ImageUpdate ? DaoDeploymentType.ImageUpdate : DaoDeploymentType.PreviewRelease) && x.InstanceId == instanceId )); }
public async Task RemovePreviewRelease(RawDeploymentManifest manifest, ApplicationImage applicationImage, string instance) { var manifestInfo = await _parser.BuildDeploymentManifestInfo(manifest); var key = new DeploymentManifestInstanceKey(applicationImage, instance); if (!manifestInfo.Instances.ContainsKey(key)) { _log.LogError($"Cannot remove instance {key} because it doesn't exist"); return; } var instanceInfo = manifestInfo.Instances[key]; var files = instanceInfo.GetInstanceDeploymentFiles().ToList(); files.ForEach(f => f.Delete()); var application = GetApplicationForApplicationImage(applicationImage); await _deploymentManifestRepositoryService.StageChanges(manifest.Repository, files); await _deploymentManifestRepositoryService.Commit(manifest.Repository, $"[{application}] Remove preview release '{instance}'."); }
public async Task <IEnumerable <GithubPullRequest> > GetAllPRs(ApplicationImage applicationImage) { return(await InternalGetPullRequestsWithFiltering(applicationImage, ItemStateFilter.All)); }
public async Task <Deployment> AddDeployment( Application application, ApplicationImage image, string newTag, DeploymentType type = DeploymentType.ImageUpdate, string instanceId = "", IReadOnlyDictionary <string, string>?parameters = null) { var currentTagInStore = await _applicationImageInstanceService.GetCurrentTag(application, image, instanceId); var currentTag = currentTagInStore.available ? currentTagInStore.tag : ""; var deployments = _deploymentsDbContextConfigurator.Set <Dao.Deployment>(); var deploymentExists = await IsDeploymentPresent( application, image, newTag, type, instanceId ); if (deploymentExists) { _log.LogInformation( "Image tag update operation already in queue for '{Repository}' with {Tag} for application {Application} with new tag {NewTag}", image.Repository, currentTag, application.Name, newTag ); throw new Exception($"Deployment for {image} with {newTag} on application '{application.Name}' already exists."); } var entity = await CreateAndStoreDeploymentDao( deployments, application, image, type == DeploymentType.ImageUpdate?DaoDeploymentType.ImageUpdate : DaoDeploymentType.PreviewRelease, newTag, currentTag, string.Empty, instanceId, parameters ); _log.LogInformation( "Adding image tag update operation for '{Repository}' with {Tag} for application {Application} with new tag {NewTag}", image.Repository, currentTag, application.Name, newTag ); await _deploymentsDbContextConfigurator.SaveChangesAsync(); var deployment = entity.Entity.ConvertToDeploymentModel(); await _deploymentNotificationService.CreateNotification(deployment); return(deployment); }
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs) { ApplicationImage.Focus(); }
public void UpdateModelImage(ApplicationImage image) { pbModel.Image = image; }
internal static ApplicationImageDto ConvertApplicationImageToApplicationServiceDto(ApplicationImage image) { var imagePreviewReleaseConfig = image.DeploymentSettings.PreviewReleases; var previewReleaseSettingsDto = imagePreviewReleaseConfig.Enabled ? new PreviewReleaseSettingsDto() { Enabled = true, UpdatePolicy = imagePreviewReleaseConfig.Policy switch { GlobImageUpdatePolicy globImageUpdatePolicy => new ImageUpdatePolicyDto() { Glob = new GlobImageUpdatePolicyDto() { Pattern = globImageUpdatePolicy.Pattern } }, RegexImageUpdatePolicy regexImageUpdatePolicy => new ImageUpdatePolicyDto() { Regex = new RegexImageUpdatePolicyDto() { Pattern = regexImageUpdatePolicy.Pattern } }, SemverImageUpdatePolicy semverImageUpdatePolicy => new ImageUpdatePolicyDto() { Semver = new SemverImageUpdatePolicyDto() { Constraint = semverImageUpdatePolicy.Constraint } }, _ => throw new ArgumentOutOfRangeException() } }
private async Task <IEnumerable <GithubPullRequest> > InternalGetPullRequestsWithFiltering(ApplicationImage applicationImage, ItemStateFilter itemStateFilter) { if (!applicationImage.SourceCode.Enabled) { throw new InvalidOperationException($"Source code settings not available or not enabled."); } var pullRequests = await _gitHubClient.PullRequest.GetAllForRepository( applicationImage.SourceCode.Github.Owner, applicationImage.SourceCode.Github.Repository, new PullRequestRequest() { State = itemStateFilter }); var pullRequestMap = pullRequests .Select(x => new GithubPullRequest( x.Id, applicationImage.SourceCode.Github.Owner, applicationImage.SourceCode.Github.Repository, x.Head.Label, x.Number, x.State.Value == ItemState.Open, x.Title, x.User.Email ?? x.User.Name ) ) .ToList(); return(pullRequestMap); }
public async Task DetectNewTags(string imagePattern, string?currentImageTag, string?newerImageTag, int createdDeployments) { // setup UseStrictMocks(); const string imageRepository = "test-image"; const string applicationId = "test-app"; var deploymentId = Guid.NewGuid(); var containerImages = new List <ContainerImage>(); ContainerImage?currentContainerImage = null; if (currentImageTag != null) { currentContainerImage = new ContainerImage(imageRepository, currentImageTag, DateTimeOffset.Now.AddDays(-1) ); containerImages.Add(currentContainerImage); } if (newerImageTag != null) { containerImages.Add( new ContainerImage(imageRepository, newerImageTag, DateTimeOffset.Now ) ); } var registryClient = MockOf <IRegistryClient>( mock => { if (currentContainerImage != null) { mock .Setup(x => x.GetImage( It.Is <string>(s => s.Equals(imageRepository)), It.Is <string>(s => s.Equals(currentImageTag)) ) ) .Returns(Task.FromResult(currentContainerImage)); } mock.Setup( x => x.GetRepositoryTags(It.Is <string>(s => s.Equals(imageRepository))) ) .Returns(Task.FromResult(containerImages.AsEnumerable())); }); var registryClientPool = MockOf <IRegistryClientPool>( mock => mock .Setup(x => x.GetRegistryClientForRepository(It.Is <string>(s => s == imageRepository))) .Returns(Task.FromResult(registryClient)) ); var applicationImage = new ApplicationImage(imageRepository, new TagProperty("image.tag", TagPropertyValueFormat.TagOnly), new GlobImageUpdatePolicy(imagePattern), new DeploymentSettings(true, true), ApplicationImageSourceCode.Empty, ApplicationImageIngress.Empty ); var application = new Application( applicationId, new[] { applicationImage }, new NotificationSettings("#abc") ); var applicationService = MockOf <IApplicationService>( mock => { mock.Setup(x => x.GetApplication(It.Is <string>(s => s == applicationId))) .Returns(application); var currentImageTags = currentImageTag != null ? new Dictionary <ApplicationImage, string>() { { applicationImage, currentImageTag } } : new Dictionary <ApplicationImage, string>(); // mock.Setup( // x => x.GetCurrentImageTags( // It.Is<Application>(p => p.Equals(application)) // ) // ) // .Returns(currentImageTags); }); var deploymentService = MockOf <IDeploymentService>( mock => { mock.Setup( x => x.AddDeployment( It.Is <Application>(p => p.Equals(application)), It.Is <ApplicationImage>(p => p.Equals(applicationImage)), It.Is <string>(s => s.Equals(newerImageTag)), It.Is <DeploymentType>(t => t.Equals(DeploymentType.ImageUpdate)), It.Is <string>(s => s == string.Empty), It.IsAny <IReadOnlyDictionary <string, string> >() ) ) .Callback <Application, ApplicationImage, string>((application, image, newTag) => {}) .ReturnsAsync( new Deployment( deploymentId, applicationId, imageRepository, "image.tag", currentImageTag, newerImageTag, DeploymentStatus.Pending, DeploymentType.ImageUpdate, string.Empty, DateTime.Now.AddMinutes(-1), DateTime.Now, string.Empty) ); }, mock => { mock.Verify( x => x.AddDeployment( It.Is <Application>(p => p.Equals(application)), It.Is <ApplicationImage>(p => p.Equals(applicationImage)), It.Is <string>(s => s.Equals(newerImageTag)), It.Is <DeploymentType>(t => t.Equals(DeploymentType.ImageUpdate)), It.Is <string>(s => s == string.Empty), It.IsAny <IReadOnlyDictionary <string, string> >() ), Times.Exactly(createdDeployments) ); } ); var localContainerMetadataService = MockOf <IContainerImageMetadataService>( mock => { mock.Setup( x => x.AddOrUpdate(It.IsAny <ContainerImage>()) ); } ); var job = new ContainerRegistryPollingJob( GetLogger <ContainerRegistryPollingJob>(), registryClientPool, localContainerMetadataService ); // run await job.Execute(new ContainerRepositoryPollingContext(imageRepository)); // verify VerifyMocks(); }
static async Task <int> Main(string[] args) { var hostBuilder = Host.CreateDefaultBuilder() .ConfigureServices( collection => { collection.RegisterApplicationManagementComponents(); collection.RegisterDeploymentManifestSourceServices(); } ); var host = hostBuilder.Build(); using var scope = host.Services.CreateScope(); var serviceProvider = scope.ServiceProvider; // build repository and application metadta var appImage = new ApplicationImage( "511177966619.dkr.ecr.eu-west-1.amazonaws.com/odin/azurolongo.lucky8", new TagProperty("image.tag", TagPropertyValueFormat.TagOnly), new GlobImageUpdatePolicy("*-dev-*"), new DeploymentSettings( true, true, new PreviewReleaseDeploymentSettings( true, new RegexImageUpdatePolicy("^[0-9.]*-demo-(.*)-[0-9]*"), "(?<version>[\\d\\.]+)-demo-(?<branch>.*)-(?<buildNumber>\\d+)" ) ), ApplicationImageSourceCode.Empty, ApplicationImageIngress.Empty ); var application = new Application( "Test", new[] { appImage }, new NotificationSettings() ); var fs = new FileSystem(); var repo = new DeploymentManifestRepository( new Uri("https://github.com/River-iGaming/odin-deploys"), "feature/test-shipbot", new UsernamePasswordGitCredentials("rt-deploy-bot", args[0]), fs.DirectoryInfo.FromDirectoryName(Path.Combine(Path.GetTempPath(), "abc")) ); var manifest = new RawDeploymentManifest( "Test", repo, "frontend/caglisse/rig-dev-grey-eks/dev/", new[] { "lucky8.yaml" } ); // app services var appServices = serviceProvider.GetRequiredService <IApplicationService>(); appServices.AddApplication(application); // checkout var repoServices = serviceProvider.GetRequiredService <IDeploymentManifestRepositoryService>(); await repoServices.Checkout(manifest.Repository, true); // get info var management = serviceProvider.GetRequiredService <IDeploymentManifestSourceManagementFacade>(); var info = await management.GetDeploymentManifestInfo(manifest); Console.WriteLine("Before ======"); Console.WriteLine("Instances:"); foreach (var deploymentManifestInstanceInfo in info.InstanceNames) { Console.WriteLine($" {deploymentManifestInstanceInfo.Key}:"); foreach (var s in deploymentManifestInstanceInfo.Value) { Console.WriteLine($" - { (string.IsNullOrWhiteSpace(s) ? "<primary>" : s ) }"); } } // test creating a preview release await management.CreatePreviewRelease(manifest, appImage, "pr-555", "9.1.6-dev-111"); info = await management.GetDeploymentManifestInfo(manifest); Console.WriteLine("After ======"); Console.WriteLine("Instances:"); foreach (var deploymentManifestInstanceInfo in info.InstanceNames) { Console.WriteLine($" {deploymentManifestInstanceInfo.Key}:"); foreach (var s in deploymentManifestInstanceInfo.Value) { Console.WriteLine($" - { (string.IsNullOrWhiteSpace(s) ? "<primary>" : s ) }"); } } // remove await management.RemovePreviewRelease(manifest, appImage, "pr-555"); info = await management.GetDeploymentManifestInfo(manifest); Console.WriteLine("After Removal ======"); Console.WriteLine("Instances:"); foreach (var deploymentManifestInstanceInfo in info.InstanceNames) { Console.WriteLine($" {deploymentManifestInstanceInfo.Key}:"); foreach (var s in deploymentManifestInstanceInfo.Value) { Console.WriteLine($" - { (string.IsNullOrWhiteSpace(s) ? "<primary>" : s ) }"); } } return(0); }
public Task RemovePreviewRelease(HelmDeploymentManifest manifest, ApplicationImage applicationImage, string instance) { return(Task.CompletedTask); }