Пример #1
0
        /// <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));
        }
Пример #2
0
        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}."
                    );
            }
        }
Пример #3
0
        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));
        }
Пример #4
0
        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}"
                );
        }
Пример #5
0
        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)
                                            );
            }
        }
Пример #6
0
        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));
        }
Пример #7
0
        private static ApplicationImage createImageFrom(Image bitmap, string imageName)
        {
            var appImage = new ApplicationImage(bitmap);

            _allImages.Add(imageName, appImage);
            return(appImage);
        }
Пример #8
0
        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);
        }
Пример #9
0
 public static int ImageIndex(ApplicationImage image)
 {
     if (_allImageList == null)
     {
         _allImageList = _allImages.ToList();
     }
     return(_allImageList.IndexOf(image));
 }
Пример #10
0
        private Application GetApplicationForApplicationImage(ApplicationImage applicationImage)
        {
            var application = _applicationService
                              .GetApplications()
                              .First(x => x.Images.Contains(applicationImage));

            return(application);
        }
Пример #11
0
        public void Add(ApplicationImage image)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            repository.Add(image);
        }
Пример #12
0
 public void Add(ApplicationImage image)
 {
     using (PhoneStoreContext context = new PhoneStoreContext())
     {
         ImageEntity imageEntity = (ImageEntity) new ImageEntity().FromApplicationModel(image);
         context.Images.Add(imageEntity);
         context.SaveChanges();
     }
 }
Пример #13
0
        public ApplicationImage ConvertToApplicationModel()
        {
            ApplicationImage appImage = new ApplicationImage
            {
                ImageId = this.ImageId,
                Image   = this.Image,
                PhoneId = this.PhoneId
            };

            return(appImage);
        }
Пример #14
0
        public IStorageModel <ApplicationImage> FromApplicationModel(ApplicationImage model)
        {
            if (model == null)
            {
                return(null);
            }

            ImageEntity imageEntity = new ImageEntity()
            {
                Image   = model.Image,
                PhoneId = model.PhoneId
            };

            return(imageEntity);
        }
Пример #15
0
        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
                       ));
        }
Пример #16
0
        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}'.");
        }
Пример #17
0
 public async Task <IEnumerable <GithubPullRequest> > GetAllPRs(ApplicationImage applicationImage)
 {
     return(await InternalGetPullRequestsWithFiltering(applicationImage, ItemStateFilter.All));
 }
Пример #18
0
        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);
        }
Пример #19
0
 private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
 {
     ApplicationImage.Focus();
 }
Пример #20
0
 public void UpdateModelImage(ApplicationImage image)
 {
     pbModel.Image = image;
 }
Пример #21
0
 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()
         }
     }
Пример #22
0
        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);
        }
Пример #23
0
        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();
        }
Пример #24
0
        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);
        }
Пример #25
0
 public Task RemovePreviewRelease(HelmDeploymentManifest manifest, ApplicationImage applicationImage, string instance)
 {
     return(Task.CompletedTask);
 }