From dca2e5643485f4afbf679293d6453de4032dfebe Mon Sep 17 00:00:00 2001 From: Salah Aldeen Al Saleh Date: Tue, 19 Dec 2023 15:49:08 +0000 Subject: [PATCH 01/14] Use rendered KOTS kinds --- pkg/apparchive/helm-v1beta2.go | 15 +--- pkg/apparchive/installation.go | 4 +- pkg/base/render.go | 27 +++---- pkg/base/replicated.go | 26 +++--- pkg/base/templates.go | 11 +-- pkg/kotsutil/kots.go | 16 ---- pkg/kotsutil/kots_test.go | 44 ---------- pkg/midstream/write.go | 123 ++++++++++++++-------------- pkg/pull/pull.go | 143 +++++++++++++++------------------ pkg/rewrite/rewrite.go | 102 +++++++++++------------ 10 files changed, 202 insertions(+), 309 deletions(-) diff --git a/pkg/apparchive/helm-v1beta2.go b/pkg/apparchive/helm-v1beta2.go index 69fa06fefc..0f7dd6879c 100644 --- a/pkg/apparchive/helm-v1beta2.go +++ b/pkg/apparchive/helm-v1beta2.go @@ -106,7 +106,7 @@ func WriteV1Beta2HelmCharts(opts WriteV1Beta2HelmChartsOptions) error { } archivePath := path.Join(chartDir, fmt.Sprintf("%s-%s.tgz", helmChart.Spec.Chart.Name, helmChart.Spec.Chart.ChartVersion)) - if err := ioutil.WriteFile(archivePath, archive, 0644); err != nil { + if err := os.WriteFile(archivePath, archive, 0644); err != nil { return errors.Wrap(err, "failed to write helm chart archive") } @@ -142,7 +142,7 @@ func WriteV1Beta2HelmCharts(opts WriteV1Beta2HelmChartsOptions) error { } valuesPath := path.Join(chartDir, "values.yaml") - if err := ioutil.WriteFile(valuesPath, []byte(valuesContent), 0644); err != nil { + if err := os.WriteFile(valuesPath, []byte(valuesContent), 0644); err != nil { return errors.Wrap(err, "failed to write values file") } @@ -159,16 +159,9 @@ func WriteV1Beta2HelmCharts(opts WriteV1Beta2HelmChartsOptions) error { return errors.Wrap(err, "failed to process online images") } - upstreamDir := opts.Upstream.GetUpstreamDir(opts.WriteUpstreamOptions) + opts.KotsKinds.Installation.Spec.KnownImages = append(opts.KotsKinds.Installation.Spec.KnownImages, result.CheckedImages...) - installation, err := kotsutil.LoadInstallationFromPath(filepath.Join(upstreamDir, "userdata", "installation.yaml")) - if err != nil { - return errors.Wrap(err, "failed to load kotskinds from new upstream") - } - - installation.Spec.KnownImages = append(installation.Spec.KnownImages, result.CheckedImages...) - - if err := SaveInstallation(installation, upstreamDir); err != nil { + if err := SaveInstallation(&opts.KotsKinds.Installation, opts.Upstream.GetUpstreamDir(opts.WriteUpstreamOptions)); err != nil { return errors.Wrap(err, "failed to save installation") } } diff --git a/pkg/apparchive/installation.go b/pkg/apparchive/installation.go index 9d4ef87e7e..d7925a5d5a 100644 --- a/pkg/apparchive/installation.go +++ b/pkg/apparchive/installation.go @@ -1,7 +1,7 @@ package apparchive import ( - "io/ioutil" + "os" "path" "github.com/pkg/errors" @@ -11,7 +11,7 @@ import ( func SaveInstallation(installation *kotsv1beta1.Installation, upstreamDir string) error { filename := path.Join(upstreamDir, "userdata", "installation.yaml") - err := ioutil.WriteFile(filename, kotsutil.MustMarshalInstallation(installation), 0644) + err := os.WriteFile(filename, kotsutil.MustMarshalInstallation(installation), 0644) if err != nil { return errors.Wrap(err, "failed to write installation") } diff --git a/pkg/base/render.go b/pkg/base/render.go index 182cdb3d8b..11ea7c9f9b 100644 --- a/pkg/base/render.go +++ b/pkg/base/render.go @@ -3,25 +3,22 @@ package base import ( "github.com/pkg/errors" "github.com/replicatedhq/kots/pkg/logger" + registrytypes "github.com/replicatedhq/kots/pkg/registry/types" upstreamtypes "github.com/replicatedhq/kots/pkg/upstream/types" ) type RenderOptions struct { - SplitMultiDocYAML bool - Namespace string - HelmVersion string - HelmValues map[string]interface{} - LocalRegistryHost string - LocalRegistryNamespace string - LocalRegistryUsername string - LocalRegistryPassword string - LocalRegistryIsReadOnly bool - ExcludeKotsKinds bool - AppSlug string - Sequence int64 - IsAirgap bool - UseHelmInstall bool - Log *logger.CLILogger + SplitMultiDocYAML bool + Namespace string + HelmVersion string + HelmValues map[string]interface{} + RegistrySettings registrytypes.RegistrySettings + ExcludeKotsKinds bool + AppSlug string + Sequence int64 + IsAirgap bool + UseHelmInstall bool + Log *logger.CLILogger } // RenderUpstream is responsible for any conversions or transpilation steps are required diff --git a/pkg/base/replicated.go b/pkg/base/replicated.go index 3e194ccda9..90a6aafd06 100644 --- a/pkg/base/replicated.go +++ b/pkg/base/replicated.go @@ -16,7 +16,6 @@ import ( kotsconfig "github.com/replicatedhq/kots/pkg/config" "github.com/replicatedhq/kots/pkg/kotsutil" "github.com/replicatedhq/kots/pkg/logger" - registrytypes "github.com/replicatedhq/kots/pkg/registry/types" "github.com/replicatedhq/kots/pkg/template" upstreamtypes "github.com/replicatedhq/kots/pkg/upstream/types" "github.com/replicatedhq/kots/pkg/util" @@ -61,18 +60,10 @@ func renderReplicated(u *upstreamtypes.Upstream, renderOptions *RenderOptions) ( return nil, nil, nil, errors.Wrap(err, "failed to find config file") } - registry := registrytypes.RegistrySettings{ - Hostname: renderOptions.LocalRegistryHost, - Namespace: renderOptions.LocalRegistryNamespace, - Username: renderOptions.LocalRegistryUsername, - Password: renderOptions.LocalRegistryPassword, - IsReadOnly: renderOptions.LocalRegistryIsReadOnly, - } - versionInfo := template.VersionInfoFromInstallationSpec(renderOptions.Sequence, renderOptions.IsAirgap, kotsKinds.Installation.Spec) appInfo := template.ApplicationInfo{Slug: renderOptions.AppSlug} - renderedConfig, err := kotsconfig.TemplateConfigObjects(kotsKinds.Config, itemValues, kotsKinds.License, &kotsKinds.KotsApplication, registry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace, true) + renderedConfig, err := kotsconfig.TemplateConfigObjects(kotsKinds.Config, itemValues, kotsKinds.License, &kotsKinds.KotsApplication, renderOptions.RegistrySettings, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace, true) if err != nil { return nil, nil, nil, errors.Wrap(err, "failed to template config objects") } @@ -181,8 +172,16 @@ func renderKotsKinds(upstreamFiles []upstreamtypes.UpstreamFile, renderedConfig switch gvkString { case "kots.io/v1beta1, Kind=Installation": - // Installation manifests are generated later and will have a different filename. - continue + // Installation manifest does not need rendering. + + case "kots.io/v1beta1, Kind=License": + // License manifest does not need rendering. + + case "kots.io/v1beta1, Kind=IdentityConfig": + // IdentityConfig manifest does not need rendering. + + case "kots.io/v1beta1, Kind=ConfigValues": + // ConfigValues manifest does not need rendering. case "kots.io/v1beta1, Kind=Config": // Use the rendered Config instead of the upstream. @@ -193,9 +192,6 @@ func renderKotsKinds(upstreamFiles []upstreamtypes.UpstreamFile, renderedConfig } doc = []byte(config) - case "kots.io/v1beta1, Kind=ConfigValues": - // ConfigValues do not need rendering since they should already be valid values. - case "kots.io/v1beta1, Kind=HelmChart", "kots.io/v1beta2, Kind=HelmChart": helmchart, err := builder.RenderTemplate(upstreamFile.Path, string(upstreamFile.Content)) if err != nil { diff --git a/pkg/base/templates.go b/pkg/base/templates.go index 8d453633cf..c89925b127 100644 --- a/pkg/base/templates.go +++ b/pkg/base/templates.go @@ -2,7 +2,6 @@ package base import ( "github.com/pkg/errors" - registrytypes "github.com/replicatedhq/kots/pkg/registry/types" "github.com/replicatedhq/kots/pkg/template" upstreamtypes "github.com/replicatedhq/kots/pkg/upstream/types" kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1" @@ -35,14 +34,6 @@ func NewConfigContextTemplateBuilder(u *upstreamtypes.Upstream, renderOptions *R configGroups = kotsKinds.Config.Spec.Groups } - localRegistry := registrytypes.RegistrySettings{ - Hostname: renderOptions.LocalRegistryHost, - Namespace: renderOptions.LocalRegistryNamespace, - Username: renderOptions.LocalRegistryUsername, - Password: renderOptions.LocalRegistryPassword, - IsReadOnly: renderOptions.LocalRegistryIsReadOnly, - } - appInfo := template.ApplicationInfo{ Slug: renderOptions.AppSlug, } @@ -62,7 +53,7 @@ func NewConfigContextTemplateBuilder(u *upstreamtypes.Upstream, renderOptions *R builderOptions := template.BuilderOptions{ ConfigGroups: configGroups, ExistingValues: templateContext, - LocalRegistry: localRegistry, + LocalRegistry: renderOptions.RegistrySettings, License: kotsKinds.License, Application: &kotsKinds.KotsApplication, VersionInfo: &versionInfo, diff --git a/pkg/kotsutil/kots.go b/pkg/kotsutil/kots.go index 3a25a7ff7f..50d711bfff 100644 --- a/pkg/kotsutil/kots.go +++ b/pkg/kotsutil/kots.go @@ -555,22 +555,6 @@ func (k *KotsKinds) addKotsKinds(content []byte) error { return nil } -func GenUniqueKotsKindFilename(renderedKotsKinds map[string][]byte, prefix string) string { - filename := fmt.Sprintf("%s.yaml", prefix) - if _, exists := renderedKotsKinds[filename]; exists { - index := 1 - for { - filename = fmt.Sprintf("%s-%d.yaml", prefix, index) - if _, exists := renderedKotsKinds[filename]; !exists { - break - } - index += 1 - } - } - - return filename -} - func GetImagesFromKotsKinds(kotsKinds *KotsKinds) []string { if kotsKinds == nil { return nil diff --git a/pkg/kotsutil/kots_test.go b/pkg/kotsutil/kots_test.go index 5747cc643e..22c5e4b048 100644 --- a/pkg/kotsutil/kots_test.go +++ b/pkg/kotsutil/kots_test.go @@ -381,50 +381,6 @@ var _ = Describe("Kots", func() { Expect(err).To(HaveOccurred()) }) }) - - Describe("GenUniqueKotsKindsFilename()", func() { - It("returns the same name when there are no file entries", func() { - filename := kotsutil.GenUniqueKotsKindFilename(nil, "unique") - Expect(filename).To(Equal("unique.yaml")) - - tmpRendered := map[string][]byte{} - filename = kotsutil.GenUniqueKotsKindFilename(tmpRendered, "unique") - Expect(filename).To(Equal("unique.yaml")) - }) - - It("returns the same name when there is no conflict", func() { - tmpRendered := map[string][]byte{ - "random.yaml": nil, - "example.yaml": nil, - } - - filename := kotsutil.GenUniqueKotsKindFilename(tmpRendered, "unique") - Expect(filename).To(Equal("unique.yaml")) - }) - - It("returns a unique name when there is a conflict", func() { - tmpRendered := map[string][]byte{ - "unique.yaml": nil, - "example.yaml": nil, - } - - filename := kotsutil.GenUniqueKotsKindFilename(tmpRendered, "unique") - Expect(filename).To(Equal("unique-1.yaml")) - }) - - It("returns a unique name when there is a conflict and the generated name creates a new conflict", func() { - tmpRendered := map[string][]byte{ - "unique.yaml": nil, - "unique-1.yaml": nil, - "unique-2.yaml": nil, - "unique-4.yaml": nil, - "example.yaml": nil, - } - - filename := kotsutil.GenUniqueKotsKindFilename(tmpRendered, "unique") - Expect(filename).To(Equal("unique-3.yaml")) - }) - }) }) func TestIsKotsKind(t *testing.T) { diff --git a/pkg/midstream/write.go b/pkg/midstream/write.go index cdee5a5c32..69ce281963 100644 --- a/pkg/midstream/write.go +++ b/pkg/midstream/write.go @@ -37,20 +37,27 @@ const ( ) type WriteOptions struct { - MidstreamDir string - BaseDir string - AppSlug string - IsGitOps bool - IsOpenShift bool - Builder template.Builder - HTTPProxyEnvValue string - HTTPSProxyEnvValue string - NoProxyEnvValue string - UseHelmInstall map[string]bool - NewHelmCharts []*kotsv1beta1.HelmChart + MidstreamDir string + Base *base.Base + BaseDir string + AppSlug string + IsGitOps bool + IsOpenShift bool + Builder template.Builder + HTTPProxyEnvValue string + HTTPSProxyEnvValue string + NoProxyEnvValue string + UseHelmInstall map[string]bool + NewHelmCharts []*kotsv1beta1.HelmChart + ProcessImageOptions image.ProcessImageOptions + License *kotsv1beta1.License + RenderedKotsKinds *kotsutil.KotsKinds + IdentityConfig *kotsv1beta1.IdentityConfig + UpstreamDir string + Log *logger.CLILogger } -func WriteMidstream(writeMidstreamOptions WriteOptions, processImageOptions image.ProcessImageOptions, b *base.Base, license *kotsv1beta1.License, identityConfig *kotsv1beta1.IdentityConfig, upstreamDir string, log *logger.CLILogger) (*Midstream, error) { +func WriteMidstream(opts WriteOptions) (*Midstream, error) { var images []kustomizetypes.Image var objects []k8sdoc.K8sDoc var pullSecretRegistries []string @@ -62,85 +69,75 @@ func WriteMidstream(writeMidstreamOptions WriteOptions, processImageOptions imag return nil, errors.Wrap(err, "failed to get k8s clientset") } - newKotsKinds, err := kotsutil.LoadKotsKindsFromPath(upstreamDir) - if err != nil { - return nil, errors.Wrap(err, "failed to load kotskinds from new upstream") - } - - identitySpec, err := upstream.LoadIdentity(upstreamDir) - if err != nil { - return nil, errors.Wrap(err, "failed to load identity") - } - // do not fail on being unable to get dockerhub credentials, since they're just used to increase the rate limit var dockerHubRegistryCreds registry.Credentials - dockerhubSecret, _ := registry.GetDockerHubPullSecret(clientset, util.PodNamespace, processImageOptions.Namespace, processImageOptions.AppSlug) + dockerhubSecret, _ := registry.GetDockerHubPullSecret(clientset, util.PodNamespace, opts.ProcessImageOptions.Namespace, opts.ProcessImageOptions.AppSlug) if dockerhubSecret != nil { dockerHubRegistryCreds, _ = registry.GetCredentialsForRegistryFromConfigJSON(dockerhubSecret.Data[".dockerconfigjson"], registry.DockerHubRegistryName) } - if processImageOptions.RewriteImages { + if opts.ProcessImageOptions.RewriteImages { // A target registry is configured. Rewrite all images and copy them (if necessary) to the configured registry. - if processImageOptions.RegistrySettings.IsReadOnly { - log.ActionWithSpinner("Rewriting images") - io.WriteString(processImageOptions.ReportWriter, "Rewriting images\n") + if opts.ProcessImageOptions.RegistrySettings.IsReadOnly { + opts.Log.ActionWithSpinner("Rewriting images") + io.WriteString(opts.ProcessImageOptions.ReportWriter, "Rewriting images\n") } else { - log.ActionWithSpinner("Copying images") - io.WriteString(processImageOptions.ReportWriter, "Copying images\n") + opts.Log.ActionWithSpinner("Copying images") + io.WriteString(opts.ProcessImageOptions.ReportWriter, "Copying images\n") } - if processImageOptions.AirgapRoot == "" { + if opts.ProcessImageOptions.AirgapRoot == "" { // This is an online installation. Pull and rewrite images from online and copy them (if necessary) to the configured registry. - rewriteResult, err := RewriteBaseImages(processImageOptions, writeMidstreamOptions.BaseDir, newKotsKinds, license, dockerHubRegistryCreds, log) + rewriteResult, err := RewriteBaseImages(opts.ProcessImageOptions, opts.BaseDir, opts.RenderedKotsKinds, opts.License, dockerHubRegistryCreds, opts.Log) if err != nil { return nil, errors.Wrap(err, "failed to rewrite base images") } images = rewriteResult.Images - newKotsKinds.Installation.Spec.KnownImages = rewriteResult.CheckedImages + opts.RenderedKotsKinds.Installation.Spec.KnownImages = rewriteResult.CheckedImages } else { // This is an airgapped installation. Copy and rewrite images from the airgap bundle to the configured registry. - result, err := ProcessAirgapImages(processImageOptions, newKotsKinds, license, log) + result, err := ProcessAirgapImages(opts.ProcessImageOptions, opts.RenderedKotsKinds, opts.License, opts.Log) if err != nil { return nil, errors.Wrap(err, "failed to process airgap images") } images = result.KustomizeImages - newKotsKinds.Installation.Spec.KnownImages = result.KnownImages + opts.RenderedKotsKinds.Installation.Spec.KnownImages = result.KnownImages } - objects = base.FindObjectsWithImages(b) + objects = base.FindObjectsWithImages(opts.Base) // Use target registry credentials to create image pull secrets for all objects that have images. - pullSecretRegistries = []string{processImageOptions.RegistrySettings.Hostname} - pullSecretUsername = processImageOptions.RegistrySettings.Username - pullSecretPassword = processImageOptions.RegistrySettings.Password + pullSecretRegistries = []string{opts.ProcessImageOptions.RegistrySettings.Hostname} + pullSecretUsername = opts.ProcessImageOptions.RegistrySettings.Username + pullSecretPassword = opts.ProcessImageOptions.RegistrySettings.Password if pullSecretUsername == "" { - pullSecretUsername, pullSecretPassword, err = registry.LoadAuthForRegistry(processImageOptions.RegistrySettings.Hostname) + pullSecretUsername, pullSecretPassword, err = registry.LoadAuthForRegistry(opts.ProcessImageOptions.RegistrySettings.Hostname) if err != nil { - return nil, errors.Wrapf(err, "failed to load registry auth for %q", processImageOptions.RegistrySettings.Hostname) + return nil, errors.Wrapf(err, "failed to load registry auth for %q", opts.ProcessImageOptions.RegistrySettings.Hostname) } } - } else if license != nil { + } else if opts.License != nil { // A target registry is NOT configured. Find and rewrite private images to be proxied through proxy.replicated.com - findResult, err := findPrivateImages(writeMidstreamOptions, b, newKotsKinds, license, dockerHubRegistryCreds) + findResult, err := findPrivateImages(opts, dockerHubRegistryCreds) if err != nil { return nil, errors.Wrap(err, "failed to find private images") } images = findResult.Images - newKotsKinds.Installation.Spec.KnownImages = findResult.CheckedImages + opts.RenderedKotsKinds.Installation.Spec.KnownImages = findResult.CheckedImages objects = findResult.Docs // Use license to create image pull secrets for all objects that have private images. - pullSecretRegistries = registry.GetRegistryProxyInfo(license, &newKotsKinds.Installation, &newKotsKinds.KotsApplication).ToSlice() - pullSecretUsername = license.Spec.LicenseID - pullSecretPassword = license.Spec.LicenseID + pullSecretRegistries = registry.GetRegistryProxyInfo(opts.License, &opts.RenderedKotsKinds.Installation, &opts.RenderedKotsKinds.KotsApplication).ToSlice() + pullSecretUsername = opts.License.Spec.LicenseID + pullSecretPassword = opts.License.Spec.LicenseID } // For the newer style charts, create a new secret per chart as helm adds chart specific // details to annotations and labels to it. - namePrefix := processImageOptions.AppSlug - for _, v := range writeMidstreamOptions.NewHelmCharts { - if v.Spec.UseHelmInstall && filepath.Base(b.Path) != "." { - namePrefix = fmt.Sprintf("%s-%s", processImageOptions.AppSlug, filepath.Base(b.Path)) + namePrefix := opts.ProcessImageOptions.AppSlug + for _, v := range opts.NewHelmCharts { + if v.Spec.UseHelmInstall && filepath.Base(opts.Base.Path) != "." { + namePrefix = fmt.Sprintf("%s-%s", opts.ProcessImageOptions.AppSlug, filepath.Base(opts.Base.Path)) break } } @@ -148,7 +145,7 @@ func WriteMidstream(writeMidstreamOptions WriteOptions, processImageOptions imag pullSecretRegistries, pullSecretUsername, pullSecretPassword, - processImageOptions.Namespace, + opts.ProcessImageOptions.Namespace, namePrefix, ) if err != nil { @@ -156,16 +153,16 @@ func WriteMidstream(writeMidstreamOptions WriteOptions, processImageOptions imag } pullSecrets.DockerHubSecret = dockerhubSecret - if err := apparchive.SaveInstallation(&newKotsKinds.Installation, upstreamDir); err != nil { + if err := apparchive.SaveInstallation(&opts.RenderedKotsKinds.Installation, opts.UpstreamDir); err != nil { return nil, errors.Wrap(err, "failed to save installation") } - m, err := CreateMidstream(b, images, objects, &pullSecrets, identitySpec, identityConfig) + m, err := CreateMidstream(opts.Base, images, objects, &pullSecrets, opts.RenderedKotsKinds.Identity, opts.IdentityConfig) if err != nil { return nil, errors.Wrap(err, "failed to create midstream") } - if err := m.Write(writeMidstreamOptions); err != nil { + if err := m.Write(opts); err != nil { return nil, errors.Wrap(err, "failed to write common midstream") } @@ -265,13 +262,13 @@ func ProcessAirgapImages(options image.ProcessImageOptions, kotsKinds *kotsutil. } // findPrivateImages Finds and rewrites private images to be proxied through proxy.replicated.com -func findPrivateImages(writeMidstreamOptions WriteOptions, b *base.Base, kotsKinds *kotsutil.KotsKinds, license *kotsv1beta1.License, dockerHubRegistryCreds registry.Credentials) (*base.FindPrivateImagesResult, error) { - replicatedRegistryInfo := registry.GetRegistryProxyInfo(license, &kotsKinds.Installation, &kotsKinds.KotsApplication) - allPrivate := kotsKinds.KotsApplication.Spec.ProxyPublicImages +func findPrivateImages(opts WriteOptions, dockerHubRegistryCreds registry.Credentials) (*base.FindPrivateImagesResult, error) { + replicatedRegistryInfo := registry.GetRegistryProxyInfo(opts.License, &opts.RenderedKotsKinds.Installation, &opts.RenderedKotsKinds.KotsApplication) + allPrivate := opts.RenderedKotsKinds.KotsApplication.Spec.ProxyPublicImages findPrivateImagesOptions := base.FindPrivateImagesOptions{ - BaseDir: writeMidstreamOptions.BaseDir, - AppSlug: license.Spec.AppSlug, + BaseDir: opts.BaseDir, + AppSlug: opts.License.Spec.AppSlug, ReplicatedRegistry: dockerregistrytypes.RegistryOptions{ Endpoint: replicatedRegistryInfo.Registry, ProxyEndpoint: replicatedRegistryInfo.Proxy, @@ -281,11 +278,11 @@ func findPrivateImages(writeMidstreamOptions WriteOptions, b *base.Base, kotsKin Username: dockerHubRegistryCreds.Username, Password: dockerHubRegistryCreds.Password, }, - Installation: &kotsKinds.Installation, + Installation: &opts.RenderedKotsKinds.Installation, AllImagesPrivate: allPrivate, - HelmChartPath: b.Path, - UseHelmInstall: writeMidstreamOptions.UseHelmInstall, - KotsKindsImages: kotsutil.GetImagesFromKotsKinds(kotsKinds), + HelmChartPath: opts.Base.Path, + UseHelmInstall: opts.UseHelmInstall, + KotsKindsImages: kotsutil.GetImagesFromKotsKinds(opts.RenderedKotsKinds), } findResult, err := base.FindPrivateImages(findPrivateImagesOptions) if err != nil { diff --git a/pkg/pull/pull.go b/pkg/pull/pull.go index 24ef5f4436..69aa1dd716 100644 --- a/pkg/pull/pull.go +++ b/pkg/pull/pull.go @@ -30,6 +30,7 @@ import ( upstreamtypes "github.com/replicatedhq/kots/pkg/upstream/types" "github.com/replicatedhq/kots/pkg/util" kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1" + kotsv1beta2 "github.com/replicatedhq/kotskinds/apis/kots/v1beta2" k8sjson "k8s.io/apimachinery/pkg/runtime/serializer/json" "k8s.io/client-go/kubernetes/scheme" ) @@ -238,7 +239,7 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { return "", errors.Wrap(err, "failed to validate app key") } - airgapAppFiles, err := ioutil.TempDir("", "airgap-kots") + airgapAppFiles, err := os.MkdirTemp("", "airgap-kots") if err != nil { return "", errors.Wrap(err, "failed to create temp airgap dir") } @@ -297,11 +298,6 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { } log.FinishSpinner() - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(u.GetUpstreamDir(writeUpstreamOptions)) - if err != nil { - return "", errors.Wrap(err, "failed to load kotskinds") - } - registrySettings := registrytypes.RegistrySettings{ Hostname: pullOptions.RewriteImageOptions.Hostname, Namespace: pullOptions.RewriteImageOptions.Namespace, @@ -310,7 +306,31 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { IsReadOnly: pullOptions.RewriteImageOptions.IsReadOnly, } - needsConfig, err := kotsadmconfig.NeedsConfiguration(pullOptions.AppSlug, pullOptions.AppSequence, pullOptions.AirgapRoot != "", kotsKinds, registrySettings) + renderOptions := base.RenderOptions{ + SplitMultiDocYAML: true, + Namespace: pullOptions.Namespace, + RegistrySettings: registrySettings, + ExcludeKotsKinds: pullOptions.ExcludeKotsKinds, + Log: log, + AppSlug: pullOptions.AppSlug, + Sequence: pullOptions.AppSequence, + IsAirgap: pullOptions.AirgapRoot != "", + } + log.ActionWithSpinner("Creating base") + io.WriteString(pullOptions.ReportWriter, "Creating base\n") + + commonBase, helmBases, renderedKotsKindsMap, err := base.RenderUpstream(u, &renderOptions) + if err != nil { + log.FinishSpinnerWithError() + return "", errors.Wrap(err, "failed to render upstream") + } + + renderedKotsKinds, err := kotsutil.KotsKindsFromMap(renderedKotsKindsMap) + if err != nil { + return "", errors.Wrap(err, "failed to load rendered kotskinds from map") + } + + needsConfig, err := kotsadmconfig.NeedsConfiguration(pullOptions.AppSlug, pullOptions.AppSequence, pullOptions.AirgapRoot != "", renderedKotsKinds, registrySettings) if err != nil { return "", errors.Wrap(err, "failed to check if version needs configuration") } @@ -333,27 +353,27 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { if needsConfig { if processImageOptions.RewriteImages && processImageOptions.AirgapRoot != "" { // if this is an airgap install, we still need to process the images - if _, err = midstream.ProcessAirgapImages(processImageOptions, kotsKinds, fetchOptions.License, log); err != nil { + if _, err = midstream.ProcessAirgapImages(processImageOptions, renderedKotsKinds, fetchOptions.License, log); err != nil { return "", errors.Wrap(err, "failed to process airgap images") } } - return "", ErrConfigNeeded } - renderDir := pullOptions.RootDir - if pullOptions.CreateAppDir { - renderDir = filepath.Join(pullOptions.RootDir, u.Name) - } - - v1Beta1HelmCharts, err := kotsutil.LoadV1Beta1HelmChartsFromPath(renderDir) - if err != nil { - return "", errors.Wrap(err, "failed to load new v1beta1 helm charts") + var v1Beta1HelmCharts []*kotsv1beta1.HelmChart + if renderedKotsKinds.V1Beta1HelmCharts != nil { + for _, v1Beta1Chart := range renderedKotsKinds.V1Beta1HelmCharts.Items { + kc := v1Beta1Chart + v1Beta1HelmCharts = append(v1Beta1HelmCharts, &kc) + } } - v1Beta2HelmCharts, err := kotsutil.LoadV1Beta2HelmChartsFromPath(renderDir) - if err != nil { - return "", errors.Wrap(err, "failed to load new v1beta2 helm charts") + var v1Beta2HelmCharts []*kotsv1beta2.HelmChart + if renderedKotsKinds.V1Beta2HelmCharts != nil { + for _, v1Beta2Chart := range renderedKotsKinds.V1Beta2HelmCharts.Items { + kc := v1Beta2Chart + v1Beta2HelmCharts = append(v1Beta2HelmCharts, &kc) + } } if !pullOptions.SkipHelmChartCheck { @@ -378,7 +398,6 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { if prevChart.GetReleaseName() != newChart.GetReleaseName() { continue } - if !prevChart.Spec.UseHelmInstall { return "", errors.Errorf("cannot upgrade chart release %s to v1beta2 because useHelmInstall is false", newChart.GetReleaseName()) } @@ -386,29 +405,6 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { } } - renderOptions := base.RenderOptions{ - SplitMultiDocYAML: true, - Namespace: pullOptions.Namespace, - LocalRegistryHost: pullOptions.RewriteImageOptions.Hostname, - LocalRegistryNamespace: pullOptions.RewriteImageOptions.Namespace, - LocalRegistryUsername: pullOptions.RewriteImageOptions.Username, - LocalRegistryPassword: pullOptions.RewriteImageOptions.Password, - LocalRegistryIsReadOnly: pullOptions.RewriteImageOptions.IsReadOnly, - ExcludeKotsKinds: pullOptions.ExcludeKotsKinds, - Log: log, - AppSlug: pullOptions.AppSlug, - Sequence: pullOptions.AppSequence, - IsAirgap: pullOptions.AirgapRoot != "", - } - log.ActionWithSpinner("Creating base") - io.WriteString(pullOptions.ReportWriter, "Creating base\n") - - commonBase, helmBases, renderedKotsKindsMap, err := base.RenderUpstream(u, &renderOptions) - if err != nil { - log.FinishSpinnerWithError() - return "", errors.Wrap(err, "failed to render upstream") - } - errorFiles := []base.BaseFile{} errorFiles = append(errorFiles, base.PrependBaseFilesPath(commonBase.ListErrorFiles(), commonBase.Path)...) for _, helmBase := range helmBases { @@ -427,14 +423,9 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { files = append(files, file) } - newKotsKinds, err := kotsutil.LoadKotsKindsFromPath(u.GetUpstreamDir(writeUpstreamOptions)) - if err != nil { - return "", errors.Wrap(err, "failed to load kotskinds") - } - newKotsKinds.Installation.Spec.YAMLErrors = files + renderedKotsKinds.Installation.Spec.YAMLErrors = files - err = apparchive.SaveInstallation(&newKotsKinds.Installation, u.GetUpstreamDir(writeUpstreamOptions)) - if err != nil { + if err := apparchive.SaveInstallation(&renderedKotsKinds.Installation, u.GetUpstreamDir(writeUpstreamOptions)); err != nil { log.FinishSpinnerWithError() return "", errors.Wrap(err, "failed to save installation") } @@ -480,14 +471,7 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { return "", errors.Wrap(err, "failed to create new config context template builder") } - newKotsKinds, err := kotsutil.LoadKotsKindsFromPath(u.GetUpstreamDir(writeUpstreamOptions)) - if err != nil { - log.FinishSpinnerWithError() - return "", errors.Wrap(err, "failed to load kotskinds") - } - - err = crypto.InitFromString(newKotsKinds.Installation.Spec.EncryptionKey) - if err != nil { + if err := crypto.InitFromString(renderedKotsKinds.Installation.Spec.EncryptionKey); err != nil { log.FinishSpinnerWithError() return "", errors.Wrap(err, "failed to load encryption cipher") } @@ -501,6 +485,11 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { HTTPSProxyEnvValue: pullOptions.HTTPSProxyEnvValue, NoProxyEnvValue: pullOptions.NoProxyEnvValue, NewHelmCharts: v1Beta1HelmCharts, + License: fetchOptions.License, + RenderedKotsKinds: renderedKotsKinds, + IdentityConfig: identityConfig, + UpstreamDir: u.GetUpstreamDir(writeUpstreamOptions), + Log: log, } // the UseHelmInstall map blocks visibility into charts and subcharts when searching for private images @@ -526,8 +515,10 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { writeMidstreamOptions := commonWriteMidstreamOptions writeMidstreamOptions.MidstreamDir = filepath.Join(u.GetOverlaysDir(writeUpstreamOptions), "midstream") writeMidstreamOptions.BaseDir = filepath.Join(u.GetBaseDir(writeUpstreamOptions), commonBase.Path) + writeMidstreamOptions.ProcessImageOptions = processImageOptions + writeMidstreamOptions.Base = commonBase - m, err := midstream.WriteMidstream(writeMidstreamOptions, processImageOptions, commonBase, fetchOptions.License, identityConfig, u.GetUpstreamDir(writeUpstreamOptions), log) + m, err := midstream.WriteMidstream(writeMidstreamOptions) if err != nil { log.FinishSpinnerWithError() return "", errors.Wrap(err, "failed to write common midstream") @@ -542,16 +533,18 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { previousUseHelmInstall := writeMidstreamOptions.UseHelmInstall[helmBase.Path] writeMidstreamOptions.UseHelmInstall[helmBase.Path] = false - writeMidstreamOptions.MidstreamDir = filepath.Join(u.GetOverlaysDir(writeUpstreamOptions), "midstream", helmBase.Path) - writeMidstreamOptions.BaseDir = filepath.Join(u.GetBaseDir(writeUpstreamOptions), helmBase.Path) - helmBaseCopy := helmBase.DeepCopy() processImageOptionsCopy := processImageOptions processImageOptionsCopy.Namespace = helmBaseCopy.Namespace processImageOptionsCopy.PushImages = false // never push images more than once - helmMidstream, err := midstream.WriteMidstream(writeMidstreamOptions, processImageOptionsCopy, helmBaseCopy, fetchOptions.License, identityConfig, u.GetUpstreamDir(writeUpstreamOptions), log) + writeMidstreamOptions.MidstreamDir = filepath.Join(u.GetOverlaysDir(writeUpstreamOptions), "midstream", helmBaseCopy.Path) + writeMidstreamOptions.BaseDir = filepath.Join(u.GetBaseDir(writeUpstreamOptions), helmBaseCopy.Path) + writeMidstreamOptions.ProcessImageOptions = processImageOptionsCopy + writeMidstreamOptions.Base = helmBaseCopy + + helmMidstream, err := midstream.WriteMidstream(writeMidstreamOptions) if err != nil { log.FinishSpinnerWithError() return "", errors.Wrapf(err, "failed to write helm midstream %s", helmBase.Path) @@ -569,12 +562,6 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { return "", errors.Wrapf(err, "failed to remove unused helm midstreams") } - renderedKotsKinds, err := kotsutil.KotsKindsFromMap(renderedKotsKindsMap) - if err != nil { - log.FinishSpinnerWithError() - return "", errors.Wrap(err, "failed to load rendered kotskinds from map") - } - writeV1Beta2HelmChartsOpts := apparchive.WriteV1Beta2HelmChartsOptions{ Upstream: u, WriteUpstreamOptions: writeUpstreamOptions, @@ -600,16 +587,14 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { } } - installationBytes, err := ioutil.ReadFile(filepath.Join(u.GetUpstreamDir(writeUpstreamOptions), "userdata", "installation.yaml")) + // installation spec gets updated during the process, ensure the map has the latest version + installationBytes, err := os.ReadFile(filepath.Join(u.GetUpstreamDir(writeUpstreamOptions), "userdata", "installation.yaml")) if err != nil { return "", errors.Wrap(err, "failed to read installation file") } + renderedKotsKindsMap["userdata/installation.yaml"] = []byte(installationBytes) - installationFilename := kotsutil.GenUniqueKotsKindFilename(renderedKotsKindsMap, "installation") - renderedKotsKindsMap[installationFilename] = []byte(installationBytes) - - err = kotsutil.WriteKotsKinds(renderedKotsKindsMap, u.GetKotsKindsDir(writeUpstreamOptions)) - if err != nil { + if err := kotsutil.WriteKotsKinds(renderedKotsKindsMap, u.GetKotsKindsDir(writeUpstreamOptions)); err != nil { return "", errors.Wrap(err, "failed to write the rendered kots kinds") } @@ -618,7 +603,7 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { OverlaysDir: u.GetOverlaysDir(writeUpstreamOptions), RenderedDir: u.GetRenderedDir(writeUpstreamOptions), Downstreams: pullOptions.Downstreams, - KustomizeBinPath: kotsKinds.GetKustomizeBinaryPath(), + KustomizeBinPath: renderedKotsKinds.GetKustomizeBinaryPath(), HelmDir: u.GetHelmDir(writeUpstreamOptions), Log: log, KotsKinds: renderedKotsKinds, @@ -726,7 +711,7 @@ func writeDownstreams(options PullOptions, overlaysDir string, m *midstream.Mids } func ParseConfigValuesFromFile(filename string) (*kotsv1beta1.ConfigValues, error) { - contents, err := ioutil.ReadFile(filename) + contents, err := os.ReadFile(filename) if err != nil { if os.IsNotExist(err) { return nil, nil @@ -750,7 +735,7 @@ func ParseConfigValuesFromFile(filename string) (*kotsv1beta1.ConfigValues, erro } func ParseIdentityConfigFromFile(filename string) (*kotsv1beta1.IdentityConfig, error) { - contents, err := ioutil.ReadFile(filename) + contents, err := os.ReadFile(filename) if err != nil { if os.IsNotExist(err) { return nil, nil diff --git a/pkg/rewrite/rewrite.go b/pkg/rewrite/rewrite.go index 3b1ba5e4ec..c689f6806c 100644 --- a/pkg/rewrite/rewrite.go +++ b/pkg/rewrite/rewrite.go @@ -115,18 +115,14 @@ func Rewrite(rewriteOptions RewriteOptions) error { log.FinishSpinner() renderOptions := base.RenderOptions{ - SplitMultiDocYAML: true, - Namespace: rewriteOptions.K8sNamespace, - LocalRegistryHost: rewriteOptions.RegistrySettings.Hostname, - LocalRegistryNamespace: rewriteOptions.RegistrySettings.Namespace, - LocalRegistryUsername: rewriteOptions.RegistrySettings.Username, - LocalRegistryPassword: rewriteOptions.RegistrySettings.Password, - LocalRegistryIsReadOnly: rewriteOptions.RegistrySettings.IsReadOnly, - ExcludeKotsKinds: rewriteOptions.ExcludeKotsKinds, - Log: log, - AppSlug: rewriteOptions.AppSlug, - Sequence: rewriteOptions.AppSequence, - IsAirgap: rewriteOptions.IsAirgap, + SplitMultiDocYAML: true, + Namespace: rewriteOptions.K8sNamespace, + RegistrySettings: rewriteOptions.RegistrySettings, + ExcludeKotsKinds: rewriteOptions.ExcludeKotsKinds, + Log: log, + AppSlug: rewriteOptions.AppSlug, + Sequence: rewriteOptions.AppSequence, + IsAirgap: rewriteOptions.IsAirgap, } log.ActionWithSpinner("Creating base") io.WriteString(rewriteOptions.ReportWriter, "Creating base\n") @@ -136,6 +132,11 @@ func Rewrite(rewriteOptions RewriteOptions) error { return errors.Wrap(err, "failed to render upstream") } + renderedKotsKinds, err := kotsutil.KotsKindsFromMap(renderedKotsKindsMap) + if err != nil { + return errors.Wrap(err, "failed to load rendered kotskinds from map") + } + errorFiles := []base.BaseFile{} errorFiles = append(errorFiles, base.PrependBaseFilesPath(commonBase.ListErrorFiles(), commonBase.Path)...) for _, helmBase := range helmBases { @@ -154,14 +155,9 @@ func Rewrite(rewriteOptions RewriteOptions) error { files = append(files, file) } - newKotsKinds, err := kotsutil.LoadKotsKindsFromPath(u.GetUpstreamDir(writeUpstreamOptions)) - if err != nil { - return errors.Wrap(err, "failed to load installation") - } - newKotsKinds.Installation.Spec.YAMLErrors = files + renderedKotsKinds.Installation.Spec.YAMLErrors = files - err = apparchive.SaveInstallation(&newKotsKinds.Installation, u.GetUpstreamDir(writeUpstreamOptions)) - if err != nil { + if err := apparchive.SaveInstallation(&renderedKotsKinds.Installation, u.GetUpstreamDir(writeUpstreamOptions)); err != nil { return errors.Wrap(err, "failed to save installation") } } @@ -203,14 +199,21 @@ func Rewrite(rewriteOptions RewriteOptions) error { return errors.Wrap(err, "failed to create new config context template builder") } - err = crypto.InitFromString(rewriteOptions.Installation.Spec.EncryptionKey) - if err != nil { + if err := crypto.InitFromString(rewriteOptions.Installation.Spec.EncryptionKey); err != nil { return errors.Wrap(err, "failed to create cipher from installation spec") } - v1Beta1HelmCharts, err := kotsutil.LoadV1Beta1HelmChartsFromPath(rewriteOptions.UpstreamPath) + identityConfig, err := upstream.LoadIdentityConfig(u.GetUpstreamDir(writeUpstreamOptions)) if err != nil { - return errors.Wrap(err, "failed to load v1beta1 helm charts") + return errors.Wrap(err, "failed to load identity config") + } + + var v1Beta1HelmCharts []*kotsv1beta1.HelmChart + if renderedKotsKinds.V1Beta1HelmCharts != nil { + for _, v1Beta1Chart := range renderedKotsKinds.V1Beta1HelmCharts.Items { + kc := v1Beta1Chart + v1Beta1HelmCharts = append(v1Beta1HelmCharts, &kc) + } } commonWriteMidstreamOptions := midstream.WriteOptions{ @@ -222,6 +225,11 @@ func Rewrite(rewriteOptions RewriteOptions) error { HTTPSProxyEnvValue: rewriteOptions.HTTPSProxyEnvValue, NoProxyEnvValue: rewriteOptions.NoProxyEnvValue, NewHelmCharts: v1Beta1HelmCharts, + License: rewriteOptions.License, + RenderedKotsKinds: renderedKotsKinds, + IdentityConfig: identityConfig, + UpstreamDir: u.GetUpstreamDir(writeUpstreamOptions), + Log: log, } // the UseHelmInstall map blocks visibility into charts and subcharts when searching for private images @@ -243,10 +251,6 @@ func Rewrite(rewriteOptions RewriteOptions) error { } } - writeMidstreamOptions := commonWriteMidstreamOptions - writeMidstreamOptions.MidstreamDir = filepath.Join(u.GetOverlaysDir(writeUpstreamOptions), "midstream") - writeMidstreamOptions.BaseDir = filepath.Join(u.GetBaseDir(writeUpstreamOptions), commonBase.Path) - processImageOptions := image.ProcessImageOptions{ AppSlug: rewriteOptions.AppSlug, Namespace: rewriteOptions.K8sNamespace, @@ -262,13 +266,13 @@ func Rewrite(rewriteOptions RewriteOptions) error { ReportWriter: rewriteOptions.ReportWriter, } - upstreamDir := u.GetUpstreamDir(writeUpstreamOptions) - identityConfig, err := upstream.LoadIdentityConfig(upstreamDir) - if err != nil { - return errors.Wrap(err, "failed to load identity config") - } + writeMidstreamOptions := commonWriteMidstreamOptions + writeMidstreamOptions.MidstreamDir = filepath.Join(u.GetOverlaysDir(writeUpstreamOptions), "midstream") + writeMidstreamOptions.BaseDir = filepath.Join(u.GetBaseDir(writeUpstreamOptions), commonBase.Path) + writeMidstreamOptions.ProcessImageOptions = processImageOptions + writeMidstreamOptions.Base = commonBase - m, err := midstream.WriteMidstream(writeMidstreamOptions, processImageOptions, commonBase, rewriteOptions.License, identityConfig, upstreamDir, log) + m, err := midstream.WriteMidstream(writeMidstreamOptions) if err != nil { return errors.Wrap(err, "failed to write common midstream") } @@ -283,16 +287,18 @@ func Rewrite(rewriteOptions RewriteOptions) error { previousUseHelmInstall := writeMidstreamOptions.UseHelmInstall[helmBase.Path] writeMidstreamOptions.UseHelmInstall[helmBase.Path] = false - writeMidstreamOptions.MidstreamDir = filepath.Join(u.GetOverlaysDir(writeUpstreamOptions), "midstream", helmBase.Path) - writeMidstreamOptions.BaseDir = filepath.Join(u.GetBaseDir(writeUpstreamOptions), helmBase.Path) - helmBaseCopy := helmBase.DeepCopy() processImageOptionsCopy := processImageOptions processImageOptionsCopy.Namespace = helmBaseCopy.Namespace processImageOptionsCopy.CopyImages = false // don't copy images more than once - helmMidstream, err := midstream.WriteMidstream(writeMidstreamOptions, processImageOptionsCopy, helmBaseCopy, rewriteOptions.License, identityConfig, upstreamDir, log) + writeMidstreamOptions.MidstreamDir = filepath.Join(u.GetOverlaysDir(writeUpstreamOptions), "midstream", helmBaseCopy.Path) + writeMidstreamOptions.BaseDir = filepath.Join(u.GetBaseDir(writeUpstreamOptions), helmBaseCopy.Path) + writeMidstreamOptions.ProcessImageOptions = processImageOptionsCopy + writeMidstreamOptions.Base = helmBaseCopy + + helmMidstream, err := midstream.WriteMidstream(writeMidstreamOptions) if err != nil { return errors.Wrapf(err, "failed to write helm midstream %s", helmBase.Path) } @@ -303,11 +309,6 @@ func Rewrite(rewriteOptions RewriteOptions) error { helmMidstreams = append(helmMidstreams, *helmMidstream) } - renderedKotsKinds, err := kotsutil.KotsKindsFromMap(renderedKotsKindsMap) - if err != nil { - return errors.Wrap(err, "failed to load rendered kotskinds from map") - } - writeV1Beta2HelmChartsOpts := apparchive.WriteV1Beta2HelmChartsOptions{ Upstream: u, WriteUpstreamOptions: writeUpstreamOptions, @@ -325,23 +326,16 @@ func Rewrite(rewriteOptions RewriteOptions) error { return errors.Wrap(err, "failed to write downstreams") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(rewriteOptions.UpstreamPath) - if err != nil { - return errors.Wrap(err, "failed to load kotskinds") - } - - err = store.GetStore().UpdateAppVersionInstallationSpec(rewriteOptions.AppID, rewriteOptions.AppSequence, kotsKinds.Installation) - if err != nil { + if err := store.GetStore().UpdateAppVersionInstallationSpec(rewriteOptions.AppID, rewriteOptions.AppSequence, renderedKotsKinds.Installation); err != nil { return errors.Wrap(err, "failed to update installation spec") } - installationBytes, err := ioutil.ReadFile(filepath.Join(u.GetUpstreamDir(writeUpstreamOptions), "userdata", "installation.yaml")) + // installation spec gets updated during the process, ensure the map has the latest version + installationBytes, err := os.ReadFile(filepath.Join(u.GetUpstreamDir(writeUpstreamOptions), "userdata", "installation.yaml")) if err != nil { return errors.Wrap(err, "failed to read installation file") } - - installationFilename := kotsutil.GenUniqueKotsKindFilename(renderedKotsKindsMap, "installation") - renderedKotsKindsMap[installationFilename] = []byte(installationBytes) + renderedKotsKindsMap["userdata/installation.yaml"] = installationBytes if err := kotsutil.WriteKotsKinds(renderedKotsKindsMap, u.GetKotsKindsDir(writeUpstreamOptions)); err != nil { return errors.Wrap(err, "failed to write kots base") @@ -352,7 +346,7 @@ func Rewrite(rewriteOptions RewriteOptions) error { OverlaysDir: u.GetOverlaysDir(writeUpstreamOptions), RenderedDir: u.GetRenderedDir(writeUpstreamOptions), Downstreams: rewriteOptions.Downstreams, - KustomizeBinPath: kotsKinds.GetKustomizeBinaryPath(), + KustomizeBinPath: renderedKotsKinds.GetKustomizeBinaryPath(), HelmDir: u.GetHelmDir(writeUpstreamOptions), Log: log, KotsKinds: renderedKotsKinds, From 9da248c31b86d3e00ec68d3d585ff0e36ecbeaf7 Mon Sep 17 00:00:00 2001 From: Salah Aldeen Al Saleh Date: Tue, 19 Dec 2023 17:25:15 +0000 Subject: [PATCH 02/14] always load rendered kots kinds when possible --- pkg/airgap/airgap.go | 2 +- pkg/airgap/update.go | 4 ++-- pkg/base/helm.go | 2 +- pkg/gitops/gitops.go | 2 +- pkg/handlers/config.go | 10 +++++----- pkg/handlers/download.go | 2 +- pkg/handlers/identity.go | 4 ++-- pkg/handlers/preflight.go | 3 +-- pkg/handlers/rendered_contents.go | 3 +-- pkg/handlers/upload.go | 2 +- pkg/kotsadmlicense/license.go | 3 +-- pkg/kotsadmsnapshot/backup.go | 5 ++--- pkg/kotsadmupstream/upstream.go | 4 ++-- pkg/kotsutil/kots.go | 13 +++++++++++-- pkg/online/online.go | 3 +-- pkg/operator/operator.go | 9 ++++----- pkg/preflight/preflight.go | 2 +- pkg/registry/registry.go | 2 +- pkg/render/render.go | 2 +- pkg/reporting/app.go | 3 +-- pkg/store/kotsstore/migrations.go | 13 ++++++------- pkg/store/kotsstore/version_store.go | 6 +++--- pkg/supportbundle/supportbundle.go | 4 ++-- pkg/tests/base/render_test.go | 2 +- .../kotsKinds/{ => userdata}/installation.yaml | 0 .../kotsKinds/{ => userdata}/installation.yaml | 0 .../kotsKinds/{ => userdata}/installation.yaml | 0 .../kotsKinds/{ => userdata}/installation.yaml | 0 .../kotsKinds/{ => userdata}/installation.yaml | 0 .../kotsKinds/{ => userdata}/installation.yaml | 0 .../kotsKinds/{ => userdata}/installation.yaml | 0 .../kotsKinds/{ => userdata}/installation.yaml | 0 .../kotsKinds/{ => userdata}/installation.yaml | 0 .../kotsKinds/{ => userdata}/installation.yaml | 0 .../kotsKinds/{ => userdata}/installation.yaml | 0 pkg/upstream/write.go | 9 +++++++-- pkg/version/metrics.go | 3 +-- 37 files changed, 61 insertions(+), 56 deletions(-) rename pkg/tests/pull/cases/configcontext/wantResults/kotsKinds/{ => userdata}/installation.yaml (100%) rename pkg/tests/pull/cases/customhostnames/wantResults/kotsKinds/{ => userdata}/installation.yaml (100%) rename pkg/tests/pull/cases/multidoc/wantResults/kotsKinds/{ => userdata}/installation.yaml (100%) rename pkg/tests/pull/cases/samechartvariations/wantResults/kotsKinds/{ => userdata}/installation.yaml (100%) rename pkg/tests/pull/cases/simple/wantResults/kotsKinds/{ => userdata}/installation.yaml (100%) rename pkg/tests/pull/cases/subchart-alias/wantResults/kotsKinds/{ => userdata}/installation.yaml (100%) rename pkg/tests/pull/cases/subchart-crds/wantResults/kotsKinds/{ => userdata}/installation.yaml (100%) rename pkg/tests/pull/cases/subcharts/wantResults/kotsKinds/{ => userdata}/installation.yaml (100%) rename pkg/tests/pull/cases/taganddigest-norewrite/wantResults/kotsKinds/{ => userdata}/installation.yaml (100%) rename pkg/tests/pull/cases/taganddigest-rewrite/wantResults/kotsKinds/{ => userdata}/installation.yaml (100%) rename pkg/tests/pull/cases/v1beta2-charts/wantResults/kotsKinds/{ => userdata}/installation.yaml (100%) diff --git a/pkg/airgap/airgap.go b/pkg/airgap/airgap.go index 083baa5217..37ec89ec65 100644 --- a/pkg/airgap/airgap.go +++ b/pkg/airgap/airgap.go @@ -271,7 +271,7 @@ func CreateAppFromAirgap(opts CreateAirgapAppOpts) (finalError error) { return errors.Wrap(err, "failed to create support bundle dependencies") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(tmpRoot, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(tmpRoot) if err != nil { return errors.Wrap(err, "failed to load kotskinds from path") } diff --git a/pkg/airgap/update.go b/pkg/airgap/update.go index 945dd9cac7..f754d84fa5 100644 --- a/pkg/airgap/update.go +++ b/pkg/airgap/update.go @@ -87,7 +87,7 @@ func UpdateAppFromPath(a *apptypes.App, airgapRoot string, airgapBundlePath stri } defer os.RemoveAll(archiveDir) - beforeKotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + beforeKotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return errors.Wrap(err, "failed to load current kotskinds") } @@ -185,7 +185,7 @@ func UpdateAppFromPath(a *apptypes.App, airgapRoot string, airgapBundlePath stri } } - afterKotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + afterKotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return errors.Wrap(err, "failed to read after kotskinds") } diff --git a/pkg/base/helm.go b/pkg/base/helm.go index d74a865e24..0f15ff8229 100644 --- a/pkg/base/helm.go +++ b/pkg/base/helm.go @@ -39,7 +39,7 @@ func RenderHelm(u *upstreamtypes.Upstream, renderOptions *RenderOptions) (*Base, } } - if err := ioutil.WriteFile(p, file.Content, 0644); err != nil { + if err := os.WriteFile(p, file.Content, 0644); err != nil { return nil, errors.Wrap(err, "failed to write chart file") } } diff --git a/pkg/gitops/gitops.go b/pkg/gitops/gitops.go index 4157d6c5dd..20c0c77e4d 100644 --- a/pkg/gitops/gitops.go +++ b/pkg/gitops/gitops.go @@ -713,7 +713,7 @@ func getAuth(privateKey string) (transport.AuthMethod, error) { } func CreateGitOpsCommit(gitOpsConfig *GitOpsConfig, appSlug string, appName string, newSequence int, archiveDir string, downstreamName string) (string, error) { - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return "", errors.Wrap(err, "failed to load kots kinds") } diff --git a/pkg/handlers/config.go b/pkg/handlers/config.go index 814a7ef151..3ec03f7ae7 100644 --- a/pkg/handlers/config.go +++ b/pkg/handlers/config.go @@ -358,7 +358,7 @@ func (h *Handler) LiveAppConfig(w http.ResponseWriter, r *http.Request) { return } - kotsKinds, err = kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err = kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { liveAppConfigResponse.Error = "failed to load kots kinds from path" logger.Error(errors.Wrap(err, liveAppConfigResponse.Error)) @@ -607,7 +607,7 @@ func (h *Handler) CurrentAppConfig(w http.ResponseWriter, r *http.Request) { return } - kotsKinds, err = kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err = kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { currentAppConfigResponse.Error = "failed to load kots kinds from path" logger.Error(errors.Wrap(err, currentAppConfigResponse.Error)) @@ -749,7 +749,7 @@ func getAppConfigValueForFile(downloadApp *apptypes.App, sequence int64, filenam return "", errors.Wrap(err, "failed to get app version archive") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return "", errors.Wrap(err, "failed to load kots kinds from archive") } @@ -783,7 +783,7 @@ func updateAppConfig(updateApp *apptypes.App, sequence int64, configGroups []kot return updateAppConfigResponse, err } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { updateAppConfigResponse.Error = "failed to load kots kinds from path" return updateAppConfigResponse, err @@ -1079,7 +1079,7 @@ func (h *Handler) SetAppConfigValues(w http.ResponseWriter, r *http.Request) { return } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { setAppConfigValuesResponse.Error = "failed to load kots kinds from path" logger.Error(errors.Wrap(err, setAppConfigValuesResponse.Error)) diff --git a/pkg/handlers/download.go b/pkg/handlers/download.go index 4f6e01f56a..39baa7082d 100644 --- a/pkg/handlers/download.go +++ b/pkg/handlers/download.go @@ -73,7 +73,7 @@ func (h *Handler) DownloadApp(w http.ResponseWriter, r *http.Request) { } if decryptPasswordValues { - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archivePath, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archivePath) if err != nil { logger.Error(err) w.WriteHeader(500) diff --git a/pkg/handlers/identity.go b/pkg/handlers/identity.go index 598fa71248..c22ca668f4 100644 --- a/pkg/handlers/identity.go +++ b/pkg/handlers/identity.go @@ -279,7 +279,7 @@ func (h *Handler) ConfigureAppIdentityService(w http.ResponseWriter, r *http.Req return } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { err = errors.Wrap(err, "failed to load kots kinds from path") logger.Error(err) @@ -680,7 +680,7 @@ func (h *Handler) GetAppIdentityServiceConfig(w http.ResponseWriter, r *http.Req return } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { err = errors.Wrap(err, "failed to load kotskinds from path") logger.Error(err) diff --git a/pkg/handlers/preflight.go b/pkg/handlers/preflight.go index 550545d4a3..b19eb5e38f 100644 --- a/pkg/handlers/preflight.go +++ b/pkg/handlers/preflight.go @@ -5,7 +5,6 @@ import ( "io/ioutil" "net/http" "os" - "path/filepath" "strconv" "github.com/gorilla/mux" @@ -274,7 +273,7 @@ func (h *Handler) GetPreflightCommand(w http.ResponseWriter, r *http.Request) { return } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archivePath, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archivePath) if err != nil { logger.Error(errors.Wrap(err, "failed to load kots kinds")) w.WriteHeader(http.StatusInternalServerError) diff --git a/pkg/handlers/rendered_contents.go b/pkg/handlers/rendered_contents.go index 1b99ad3460..1d79391e61 100644 --- a/pkg/handlers/rendered_contents.go +++ b/pkg/handlers/rendered_contents.go @@ -4,7 +4,6 @@ import ( "io/ioutil" "net/http" "os" - "path/filepath" "strconv" "github.com/gorilla/mux" @@ -67,7 +66,7 @@ func (h *Handler) GetAppRenderedContents(w http.ResponseWriter, r *http.Request) return } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archivePath, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archivePath) if err != nil { logger.Error(errors.Wrap(err, "failed to load kots kinds from path")) w.WriteHeader(http.StatusInternalServerError) diff --git a/pkg/handlers/upload.go b/pkg/handlers/upload.go index c481683f36..76fc60e0bb 100644 --- a/pkg/handlers/upload.go +++ b/pkg/handlers/upload.go @@ -89,7 +89,7 @@ func (h *Handler) UploadExistingApp(w http.ResponseWriter, r *http.Request) { defer os.RemoveAll(archiveDir) // encrypt any plain text values - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { uploadResponse.Error = util.StrPointer("failed to load kotskinds") logger.Error(errors.Wrap(err, *uploadResponse.Error)) diff --git a/pkg/kotsadmlicense/license.go b/pkg/kotsadmlicense/license.go index 79be707e32..308e1d5fcf 100644 --- a/pkg/kotsadmlicense/license.go +++ b/pkg/kotsadmlicense/license.go @@ -3,7 +3,6 @@ package license import ( "io/ioutil" "os" - "path/filepath" "github.com/pkg/errors" apptypes "github.com/replicatedhq/kots/pkg/app/types" @@ -72,7 +71,7 @@ func Sync(a *apptypes.App, licenseString string, failOnVersionCreate bool) (*kot return nil, false, errors.Wrap(err, "failed to get latest app sequence") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return nil, false, errors.Wrap(err, "failed to load kotskinds from path") } diff --git a/pkg/kotsadmsnapshot/backup.go b/pkg/kotsadmsnapshot/backup.go index 779661c7c9..3b78c4216b 100644 --- a/pkg/kotsadmsnapshot/backup.go +++ b/pkg/kotsadmsnapshot/backup.go @@ -7,7 +7,6 @@ import ( "io/ioutil" "math" "os" - "path/filepath" "strconv" "time" @@ -94,7 +93,7 @@ func CreateApplicationBackup(ctx context.Context, a *apptypes.App, isScheduled b return nil, errors.New("no backup store location found") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return nil, errors.Wrap(err, "failed to load kots kinds from path") } @@ -268,7 +267,7 @@ func CreateInstanceBackup(ctx context.Context, cluster *downstreamtypes.Downstre return nil, errors.Wrapf(err, "failed to get app version archive for app %s", a.Slug) } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return nil, errors.Wrap(err, "failed to load kots kinds from path") } diff --git a/pkg/kotsadmupstream/upstream.go b/pkg/kotsadmupstream/upstream.go index 1e2e77e5fd..277f125bd5 100644 --- a/pkg/kotsadmupstream/upstream.go +++ b/pkg/kotsadmupstream/upstream.go @@ -128,7 +128,7 @@ func DownloadUpdate(appID string, update types.Update, skipPreflights bool, skip } defer os.RemoveAll(archiveDir) - beforeKotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + beforeKotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { finalError = errors.Wrap(err, "failed to read kots kinds before update") return @@ -241,7 +241,7 @@ func DownloadUpdate(appID string, update types.Update, skipPreflights bool, skip } if update.AppSequence == nil { - afterKotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + afterKotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { finalError = errors.Wrap(err, "failed to read kots kinds after update") return diff --git a/pkg/kotsutil/kots.go b/pkg/kotsutil/kots.go index 50d711bfff..16c8adb6a9 100644 --- a/pkg/kotsutil/kots.go +++ b/pkg/kotsutil/kots.go @@ -630,13 +630,22 @@ func EmptyKotsKinds() KotsKinds { return kotsKinds } -func LoadKotsKindsFromPath(fromDir string) (*KotsKinds, error) { +func LoadKotsKindsFromPath(rootDir string) (*KotsKinds, error) { kotsKinds := EmptyKotsKinds() - if fromDir == "" { + if rootDir == "" { return &kotsKinds, nil } + fromDir := rootDir + if _, err := os.Stat(filepath.Join(rootDir, "kotsKinds")); err == nil { + // contains the rendered kots kinds if exists, prioritize it over upstream. only newer versions of kots create this directory. + fromDir = filepath.Join(rootDir, "kotsKinds") + } else if _, err := os.Stat(filepath.Join(rootDir, "upstream")); err == nil { + // contains the non-rendered kots kinds, fallback to it if kotsKinds directory doesn't exist. this directory should always exist. + fromDir = filepath.Join(rootDir, "upstream") + } + err := filepath.Walk(fromDir, func(path string, info os.FileInfo, err error) error { if err != nil { diff --git a/pkg/online/online.go b/pkg/online/online.go index 2d91e585e4..a97cec30fd 100644 --- a/pkg/online/online.go +++ b/pkg/online/online.go @@ -5,7 +5,6 @@ import ( "io" "io/ioutil" "os" - "path/filepath" "time" "github.com/pkg/errors" @@ -194,7 +193,7 @@ func CreateAppFromOnline(opts CreateOnlineAppOpts) (_ *kotsutil.KotsKinds, final return nil, errors.Wrap(err, "failed to create rendered support bundle spec") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(tmpRoot, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(tmpRoot) if err != nil { return nil, errors.Wrap(err, "failed to load kotskinds from path") } diff --git a/pkg/operator/operator.go b/pkg/operator/operator.go index 9409ca25d2..c68ab55bc8 100644 --- a/pkg/operator/operator.go +++ b/pkg/operator/operator.go @@ -7,7 +7,6 @@ import ( "encoding/json" "fmt" "os" - "path/filepath" "strconv" "sync" "time" @@ -235,7 +234,7 @@ func (o *Operator) DeployApp(appID string, sequence int64) (deployed bool, deplo return false, errors.Wrap(err, "failed to ensure disaster recovery label transformer") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(deployedVersionArchive, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(deployedVersionArchive) if err != nil { return false, errors.Wrap(err, "failed to load kotskinds") } @@ -356,7 +355,7 @@ func (o *Operator) DeployApp(appID string, sequence int64) (deployed bool, deplo return false, errors.Wrap(err, "failed to get previously deployed app version archive") } - previousKotsKinds, err = kotsutil.LoadKotsKindsFromPath(filepath.Join(previouslyDeployedVersionArchive, "upstream")) + previousKotsKinds, err = kotsutil.LoadKotsKindsFromPath(previouslyDeployedVersionArchive) if err != nil { return false, errors.Wrap(err, "failed to load kotskinds for previously deployed app version") } @@ -533,7 +532,7 @@ func (o *Operator) resumeInformersForApp(app *apptypes.App) error { return errors.Wrap(err, "failed to get image pull secrets") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(deployedVersionArchive, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(deployedVersionArchive) if err != nil { return errors.Wrap(err, "failed to load kotskinds") } @@ -750,7 +749,7 @@ func (o *Operator) UndeployApp(a *apptypes.App, d *downstreamtypes.Downstream, i return errors.Wrap(err, "failed to get app version archive") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(deployedVersionArchive, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(deployedVersionArchive) if err != nil { return errors.Wrap(err, "failed to load kotskinds") } diff --git a/pkg/preflight/preflight.go b/pkg/preflight/preflight.go index 88aea32c97..dc35e6ccfc 100644 --- a/pkg/preflight/preflight.go +++ b/pkg/preflight/preflight.go @@ -45,7 +45,7 @@ const ( ) func Run(appID string, appSlug string, sequence int64, isAirgap bool, archiveDir string) error { - upstreamKotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + upstreamKotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return errors.Wrap(err, "failed to load rendered kots kinds") } diff --git a/pkg/registry/registry.go b/pkg/registry/registry.go index a9d0cf0fa8..14f78c9172 100644 --- a/pkg/registry/registry.go +++ b/pkg/registry/registry.go @@ -77,7 +77,7 @@ func RewriteImages(appID string, sequence int64, hostname string, username strin return "", errors.Wrap(err, "failed to get app version archive") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(appDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(appDir) if err != nil { return "", errors.Wrap(err, "failed to load kotskinds from path") } diff --git a/pkg/render/render.go b/pkg/render/render.go index 8b09f05c17..55b505681c 100644 --- a/pkg/render/render.go +++ b/pkg/render/render.go @@ -102,7 +102,7 @@ func (r Renderer) RenderDir(archiveDir string, a *apptypes.App, downstreams []do } func RenderDir(archiveDir string, a *apptypes.App, downstreams []downstreamtypes.Downstream, registrySettings registrytypes.RegistrySettings, sequence int64) error { - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return errors.Wrap(err, "failed to load kotskinds from path") } diff --git a/pkg/reporting/app.go b/pkg/reporting/app.go index 96d4b3cacc..f11a34328c 100644 --- a/pkg/reporting/app.go +++ b/pkg/reporting/app.go @@ -9,7 +9,6 @@ import ( "fmt" "io/ioutil" "os" - "path/filepath" "github.com/pkg/errors" downstreamtypes "github.com/replicatedhq/kots/pkg/api/downstream/types" @@ -322,7 +321,7 @@ func getDownstreamInfo(appID string) (*types.DownstreamInfo, error) { return nil, errors.Wrap(err, "failed to get app version archive") } - deployedKotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(deployedArchiveDir, "upstream")) + deployedKotsKinds, err := kotsutil.LoadKotsKindsFromPath(deployedArchiveDir) if err != nil { return nil, errors.Wrap(err, "failed to load kotskinds from path") } diff --git a/pkg/store/kotsstore/migrations.go b/pkg/store/kotsstore/migrations.go index 73d482a40c..7413cb0ceb 100644 --- a/pkg/store/kotsstore/migrations.go +++ b/pkg/store/kotsstore/migrations.go @@ -4,7 +4,6 @@ import ( "fmt" "io/ioutil" "os" - "path/filepath" "github.com/pkg/errors" "github.com/replicatedhq/kots/pkg/kotsutil" @@ -97,7 +96,7 @@ func (s *KOTSStore) migrateKotsAppSpec() error { return errors.Wrap(err, "failed to get app version archive") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return errors.Wrap(err, "failed to load kots kinds from path") } @@ -169,7 +168,7 @@ func (s *KOTSStore) migrateKotsInstallationSpec() error { return errors.Wrap(err, "failed to get app version archive") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return errors.Wrap(err, "failed to load kots kinds from path") } @@ -241,7 +240,7 @@ func (s *KOTSStore) migrateSupportBundleSpec() error { return errors.Wrap(err, "failed to get app version archive") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return errors.Wrap(err, "failed to load kots kinds from path") } @@ -313,7 +312,7 @@ func (s *KOTSStore) migratePreflightSpec() error { return errors.Wrap(err, "failed to get app version archive") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return errors.Wrap(err, "failed to load kots kinds from path") } @@ -385,7 +384,7 @@ func (s *KOTSStore) migrateAnalyzerSpec() error { return errors.Wrap(err, "failed to get app version archive") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return errors.Wrap(err, "failed to load kots kinds from path") } @@ -457,7 +456,7 @@ func (s *KOTSStore) migrateAppSpec() error { return errors.Wrap(err, "failed to get app version archive") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return errors.Wrap(err, "failed to load kots kinds from path") } diff --git a/pkg/store/kotsstore/version_store.go b/pkg/store/kotsstore/version_store.go index 27ed91aa4d..bff46496a7 100644 --- a/pkg/store/kotsstore/version_store.go +++ b/pkg/store/kotsstore/version_store.go @@ -128,7 +128,7 @@ func (s *KOTSStore) IsSnapshotsSupportedForVersion(a *apptypes.App, sequence int return false, errors.Wrap(err, "failed to get app version archive") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return false, errors.Wrap(err, "failed to load kots kinds from path") } @@ -498,7 +498,7 @@ func (s *KOTSStore) createAppVersionStatements(appID string, baseSequence *int64 func (s *KOTSStore) upsertAppVersionStatements(appID string, sequence int64, baseSequence *int64, filesInDir string, source string, skipPreflights bool, gitops gitopstypes.DownstreamGitOps, renderer rendertypes.Renderer) ([]gorqlite.ParameterizedStatement, error) { statements := []gorqlite.ParameterizedStatement{} - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(filesInDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filesInDir) if err != nil { return nil, errors.Wrap(err, "failed to read kots kinds") } @@ -904,7 +904,7 @@ func (s *KOTSStore) UpdateNextAppVersionDiffSummary(appID string, baseSequence i return errors.Wrap(err, "failed to get next archive dir") } - nextKotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(nextArchiveDir, "upstream")) + nextKotsKinds, err := kotsutil.LoadKotsKindsFromPath(nextArchiveDir) if err != nil { return errors.Wrap(err, "failed to read kots kinds") } diff --git a/pkg/supportbundle/supportbundle.go b/pkg/supportbundle/supportbundle.go index ba68edf0b5..92fff336d5 100644 --- a/pkg/supportbundle/supportbundle.go +++ b/pkg/supportbundle/supportbundle.go @@ -211,7 +211,7 @@ func getKotsKindsForApp(app *apptypes.App, sequence int64) (*kotsutil.KotsKinds, return nil, errors.Wrap(err, "failed to get current archive") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archivePath, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archivePath) if err != nil { return nil, errors.Wrap(err, "failed to load current kotskinds") } @@ -341,7 +341,7 @@ func CreateSupportBundleAnalysis(appID string, archivePath string, bundle *types return err } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { err = errors.Wrap(err, "failed to load kots kinds from archive") logger.Error(err) diff --git a/pkg/tests/base/render_test.go b/pkg/tests/base/render_test.go index 9772a48bc2..4aaa2579f0 100644 --- a/pkg/tests/base/render_test.go +++ b/pkg/tests/base/render_test.go @@ -78,7 +78,7 @@ func TestRenderUpstream(t *testing.T) { test.WantBase = baseFromDir(t, filepath.Join(path, "base"), false) - test.WantKotsKinds, err = kotsutil.LoadKotsKindsFromPath(filepath.Join(path, "kotsKinds")) + test.WantKotsKinds, err = kotsutil.LoadKotsKindsFromPath(path) require.NoError(t, err, "kotsKinds") chartsPath := filepath.Join(path, "base", "charts") diff --git a/pkg/tests/pull/cases/configcontext/wantResults/kotsKinds/installation.yaml b/pkg/tests/pull/cases/configcontext/wantResults/kotsKinds/userdata/installation.yaml similarity index 100% rename from pkg/tests/pull/cases/configcontext/wantResults/kotsKinds/installation.yaml rename to pkg/tests/pull/cases/configcontext/wantResults/kotsKinds/userdata/installation.yaml diff --git a/pkg/tests/pull/cases/customhostnames/wantResults/kotsKinds/installation.yaml b/pkg/tests/pull/cases/customhostnames/wantResults/kotsKinds/userdata/installation.yaml similarity index 100% rename from pkg/tests/pull/cases/customhostnames/wantResults/kotsKinds/installation.yaml rename to pkg/tests/pull/cases/customhostnames/wantResults/kotsKinds/userdata/installation.yaml diff --git a/pkg/tests/pull/cases/multidoc/wantResults/kotsKinds/installation.yaml b/pkg/tests/pull/cases/multidoc/wantResults/kotsKinds/userdata/installation.yaml similarity index 100% rename from pkg/tests/pull/cases/multidoc/wantResults/kotsKinds/installation.yaml rename to pkg/tests/pull/cases/multidoc/wantResults/kotsKinds/userdata/installation.yaml diff --git a/pkg/tests/pull/cases/samechartvariations/wantResults/kotsKinds/installation.yaml b/pkg/tests/pull/cases/samechartvariations/wantResults/kotsKinds/userdata/installation.yaml similarity index 100% rename from pkg/tests/pull/cases/samechartvariations/wantResults/kotsKinds/installation.yaml rename to pkg/tests/pull/cases/samechartvariations/wantResults/kotsKinds/userdata/installation.yaml diff --git a/pkg/tests/pull/cases/simple/wantResults/kotsKinds/installation.yaml b/pkg/tests/pull/cases/simple/wantResults/kotsKinds/userdata/installation.yaml similarity index 100% rename from pkg/tests/pull/cases/simple/wantResults/kotsKinds/installation.yaml rename to pkg/tests/pull/cases/simple/wantResults/kotsKinds/userdata/installation.yaml diff --git a/pkg/tests/pull/cases/subchart-alias/wantResults/kotsKinds/installation.yaml b/pkg/tests/pull/cases/subchart-alias/wantResults/kotsKinds/userdata/installation.yaml similarity index 100% rename from pkg/tests/pull/cases/subchart-alias/wantResults/kotsKinds/installation.yaml rename to pkg/tests/pull/cases/subchart-alias/wantResults/kotsKinds/userdata/installation.yaml diff --git a/pkg/tests/pull/cases/subchart-crds/wantResults/kotsKinds/installation.yaml b/pkg/tests/pull/cases/subchart-crds/wantResults/kotsKinds/userdata/installation.yaml similarity index 100% rename from pkg/tests/pull/cases/subchart-crds/wantResults/kotsKinds/installation.yaml rename to pkg/tests/pull/cases/subchart-crds/wantResults/kotsKinds/userdata/installation.yaml diff --git a/pkg/tests/pull/cases/subcharts/wantResults/kotsKinds/installation.yaml b/pkg/tests/pull/cases/subcharts/wantResults/kotsKinds/userdata/installation.yaml similarity index 100% rename from pkg/tests/pull/cases/subcharts/wantResults/kotsKinds/installation.yaml rename to pkg/tests/pull/cases/subcharts/wantResults/kotsKinds/userdata/installation.yaml diff --git a/pkg/tests/pull/cases/taganddigest-norewrite/wantResults/kotsKinds/installation.yaml b/pkg/tests/pull/cases/taganddigest-norewrite/wantResults/kotsKinds/userdata/installation.yaml similarity index 100% rename from pkg/tests/pull/cases/taganddigest-norewrite/wantResults/kotsKinds/installation.yaml rename to pkg/tests/pull/cases/taganddigest-norewrite/wantResults/kotsKinds/userdata/installation.yaml diff --git a/pkg/tests/pull/cases/taganddigest-rewrite/wantResults/kotsKinds/installation.yaml b/pkg/tests/pull/cases/taganddigest-rewrite/wantResults/kotsKinds/userdata/installation.yaml similarity index 100% rename from pkg/tests/pull/cases/taganddigest-rewrite/wantResults/kotsKinds/installation.yaml rename to pkg/tests/pull/cases/taganddigest-rewrite/wantResults/kotsKinds/userdata/installation.yaml diff --git a/pkg/tests/pull/cases/v1beta2-charts/wantResults/kotsKinds/installation.yaml b/pkg/tests/pull/cases/v1beta2-charts/wantResults/kotsKinds/userdata/installation.yaml similarity index 100% rename from pkg/tests/pull/cases/v1beta2-charts/wantResults/kotsKinds/installation.yaml rename to pkg/tests/pull/cases/v1beta2-charts/wantResults/kotsKinds/userdata/installation.yaml diff --git a/pkg/upstream/write.go b/pkg/upstream/write.go index 2c8d8f8fb9..8481ad946d 100644 --- a/pkg/upstream/write.go +++ b/pkg/upstream/write.go @@ -157,8 +157,13 @@ func WriteUpstream(u *types.Upstream, options types.WriteOptions) error { } installationBytes := kotsutil.MustMarshalInstallation(&installation) - err = os.WriteFile(path.Join(renderDir, "userdata", "installation.yaml"), installationBytes, 0644) - if err != nil { + + u.Files = append(u.Files, types.UpstreamFile{ + Path: "userdata/installation.yaml", + Content: installationBytes, + }) + + if err := os.WriteFile(path.Join(renderDir, "userdata", "installation.yaml"), installationBytes, 0644); err != nil { return errors.Wrap(err, "failed to write installation") } diff --git a/pkg/version/metrics.go b/pkg/version/metrics.go index 5c91727673..30fd681db4 100644 --- a/pkg/version/metrics.go +++ b/pkg/version/metrics.go @@ -7,7 +7,6 @@ import ( "net/http" "net/url" "os" - "path/filepath" "strconv" "time" @@ -98,7 +97,7 @@ func GetGraphs(app *types.App, sequence int64, kotsStore store.Store) ([]kotsv1b return graphs, errors.Wrap(err, "failed to get app version archive") } - kotsKinds, err := kotsutil.LoadKotsKindsFromPath(filepath.Join(archiveDir, "upstream")) + kotsKinds, err := kotsutil.LoadKotsKindsFromPath(archiveDir) if err != nil { return graphs, errors.Wrap(err, "failed to load kots kinds from path") } From d31677d8795ad1808a2e0f4986846fa10d73d80d Mon Sep 17 00:00:00 2001 From: Salah Aldeen Al Saleh Date: Tue, 19 Dec 2023 17:51:50 +0000 Subject: [PATCH 03/14] fix checked images in helm v1beta2 --- pkg/apparchive/helm-v1beta2.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pkg/apparchive/helm-v1beta2.go b/pkg/apparchive/helm-v1beta2.go index 0f7dd6879c..fb43f1cce9 100644 --- a/pkg/apparchive/helm-v1beta2.go +++ b/pkg/apparchive/helm-v1beta2.go @@ -18,6 +18,7 @@ import ( "github.com/replicatedhq/kots/pkg/logger" upstreamtypes "github.com/replicatedhq/kots/pkg/upstream/types" "github.com/replicatedhq/kots/pkg/util" + kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1" kotsv1beta2 "github.com/replicatedhq/kotskinds/apis/kots/v1beta2" "gopkg.in/yaml.v2" "helm.sh/helm/v3/pkg/action" @@ -81,6 +82,8 @@ func WriteV1Beta2HelmCharts(opts WriteV1Beta2HelmChartsOptions) error { return nil } + checkedImages := []kotsv1beta1.InstallationImage{} + for _, v1Beta2Chart := range opts.KotsKinds.V1Beta2HelmCharts.Items { helmChart := v1Beta2Chart @@ -159,7 +162,11 @@ func WriteV1Beta2HelmCharts(opts WriteV1Beta2HelmChartsOptions) error { return errors.Wrap(err, "failed to process online images") } - opts.KotsKinds.Installation.Spec.KnownImages = append(opts.KotsKinds.Installation.Spec.KnownImages, result.CheckedImages...) + checkedImages = append(checkedImages, result.CheckedImages...) + } + + if len(checkedImages) > 0 { + opts.KotsKinds.Installation.Spec.KnownImages = append(opts.KotsKinds.Installation.Spec.KnownImages, checkedImages...) if err := SaveInstallation(&opts.KotsKinds.Installation, opts.Upstream.GetUpstreamDir(opts.WriteUpstreamOptions)); err != nil { return errors.Wrap(err, "failed to save installation") From f9c9c06059ee279f68af1e737d7c5555f20d7979 Mon Sep 17 00:00:00 2001 From: Salah Aldeen Al Saleh Date: Tue, 19 Dec 2023 22:00:11 +0000 Subject: [PATCH 04/14] addkotskinds pull test --- pkg/kotsutil/kots.go | 8 +- pkg/pull/pull.go | 10 +- pkg/tests/pull/cases/kotskinds/testcase.yaml | 13 + .../kotskinds/upstream/app/configmap.yaml | 6 + .../cases/kotskinds/upstream/kots-app.yaml | 51 ++ .../cases/kotskinds/upstream/kots-config.yaml | 406 +++++++++++++++ .../kotskinds/upstream/kots-preflight.yaml | 30 ++ .../upstream/kots-supportbundle.yaml | 55 ++ .../kotskinds/upstream/my-chart-0.1.0.tgz | Bin 0 -> 407 bytes .../upstream/my-excluded-chart-v1beta1.yaml | 24 + .../upstream/my-excluded-chart-v1beta2.yaml | 22 + .../kotskinds/upstream/userdata/config.yaml | 210 ++++++++ .../upstream/userdata/installation.yaml | 14 + .../kotskinds/upstream/userdata/license.yaml | 49 ++ .../wantResults/base/app/configmap.yaml | 6 + .../wantResults/base/kustomization.yaml | 7 + .../wantResults/kotsKinds/kots-app.yaml | 51 ++ .../wantResults/kotsKinds/kots-config.yaml | 493 ++++++++++++++++++ .../wantResults/kotsKinds/kots-preflight.yaml | 30 ++ .../kotsKinds/kots-supportbundle.yaml | 55 ++ .../kotsKinds/my-excluded-chart-v1beta1.yaml | 33 ++ .../kotsKinds/my-excluded-chart-v1beta2.yaml | 31 ++ .../kotsKinds/userdata/config.yaml | 210 ++++++++ .../kotsKinds/userdata/installation.yaml | 14 + .../kotsKinds/userdata/license.yaml | 49 ++ .../this-cluster/kustomization.yaml | 4 + .../midstream/backup-label-transformer.yaml | 39 ++ .../overlays/midstream/kustomization.yaml | 10 + .../overlays/midstream/secret.yaml | 28 + .../kotsadm-replicated-registry-secret.yaml | 17 + .../this-cluster/my-app-registry-secret.yaml | 17 + .../this-cluster/test-config-configmap.yaml | 11 + .../wantResults/upstream/app/configmap.yaml | 6 + .../wantResults/upstream/kots-app.yaml | 51 ++ .../wantResults/upstream/kots-config.yaml | 406 +++++++++++++++ .../wantResults/upstream/kots-preflight.yaml | 30 ++ .../upstream/kots-supportbundle.yaml | 55 ++ .../wantResults/upstream/my-chart-0.1.0.tgz | Bin 0 -> 407 bytes .../upstream/my-excluded-chart-v1beta1.yaml | 24 + .../upstream/my-excluded-chart-v1beta2.yaml | 22 + .../wantResults/upstream/userdata/config.yaml | 210 ++++++++ .../upstream/userdata/installation.yaml | 14 + .../upstream/userdata/license.yaml | 49 ++ 43 files changed, 2863 insertions(+), 7 deletions(-) create mode 100644 pkg/tests/pull/cases/kotskinds/testcase.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/upstream/app/configmap.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/upstream/kots-app.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/upstream/kots-config.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/upstream/kots-preflight.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/upstream/kots-supportbundle.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/upstream/my-chart-0.1.0.tgz create mode 100644 pkg/tests/pull/cases/kotskinds/upstream/my-excluded-chart-v1beta1.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/upstream/my-excluded-chart-v1beta2.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/upstream/userdata/config.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/upstream/userdata/installation.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/upstream/userdata/license.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/base/app/configmap.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/base/kustomization.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/kotsKinds/kots-app.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/kotsKinds/kots-config.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/kotsKinds/kots-preflight.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/kotsKinds/kots-supportbundle.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/kotsKinds/my-excluded-chart-v1beta1.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/kotsKinds/my-excluded-chart-v1beta2.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/kotsKinds/userdata/config.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/kotsKinds/userdata/installation.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/kotsKinds/userdata/license.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/overlays/downstreams/this-cluster/kustomization.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/overlays/midstream/backup-label-transformer.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/overlays/midstream/kustomization.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/overlays/midstream/secret.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/rendered/this-cluster/kotsadm-replicated-registry-secret.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/rendered/this-cluster/my-app-registry-secret.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/rendered/this-cluster/test-config-configmap.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/upstream/app/configmap.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/upstream/kots-app.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/upstream/kots-config.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/upstream/kots-preflight.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/upstream/kots-supportbundle.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/upstream/my-chart-0.1.0.tgz create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/upstream/my-excluded-chart-v1beta1.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/upstream/my-excluded-chart-v1beta2.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/upstream/userdata/config.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/upstream/userdata/installation.yaml create mode 100644 pkg/tests/pull/cases/kotskinds/wantResults/upstream/userdata/license.yaml diff --git a/pkg/kotsutil/kots.go b/pkg/kotsutil/kots.go index 16c8adb6a9..2140d4b6d9 100644 --- a/pkg/kotsutil/kots.go +++ b/pkg/kotsutil/kots.go @@ -743,7 +743,7 @@ func loadRuntimeObjectsFromPath(apiVersion, kind, fromDir string) ([]runtime.Obj return nil } - contents, err := ioutil.ReadFile(path) + contents, err := os.ReadFile(path) if err != nil { return errors.Wrap(err, "failed to read file") } @@ -754,7 +754,7 @@ func loadRuntimeObjectsFromPath(apiVersion, kind, fromDir string) ([]runtime.Obj decoded, gvk, err := decode(contents, nil, nil) if err != nil { - return errors.Wrap(err, "failed to decode") + return errors.Wrapf(err, "failed to decode: %v", contents) } if gvk.String() == fmt.Sprintf("%s, Kind=%s", apiVersion, kind) { @@ -866,7 +866,7 @@ func LoadV1Beta1HelmChartFromContents(content []byte) (*kotsv1beta1.HelmChart, e decode := scheme.Codecs.UniversalDeserializer().Decode obj, gvk, err := decode(content, nil, nil) if err != nil { - return nil, errors.Wrap(err, "failed to decode chart") + return nil, errors.Wrapf(err, "failed to decode chart: %v", string(content)) } if gvk.Group != "kots.io" || gvk.Version != "v1beta1" || gvk.Kind != "HelmChart" { @@ -880,7 +880,7 @@ func LoadV1Beta2HelmChartFromContents(content []byte) (*kotsv1beta2.HelmChart, e decode := scheme.Codecs.UniversalDeserializer().Decode obj, gvk, err := decode(content, nil, nil) if err != nil { - return nil, errors.Wrap(err, "failed to decode chart") + return nil, errors.Wrapf(err, "failed to decode chart: %v", string(content)) } if gvk.Group != "kots.io" || gvk.Version != "v1beta2" || gvk.Kind != "HelmChart" { diff --git a/pkg/pull/pull.go b/pkg/pull/pull.go index 69aa1dd716..8766692989 100644 --- a/pkg/pull/pull.go +++ b/pkg/pull/pull.go @@ -255,9 +255,13 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) { } // the root directory contains the manifests of the previous version and gets rewritten when fetching the upstream, so we load previous charts before fetching the upstream. - prevHelmCharts, err := kotsutil.LoadV1Beta1HelmChartsFromPath(pullOptions.RootDir) - if err != nil { - return "", errors.Wrap(err, "failed to load previous helm charts") + prevHelmCharts := []*kotsv1beta1.HelmChart{} + if !pullOptions.SkipHelmChartCheck { + phc, err := kotsutil.LoadV1Beta1HelmChartsFromPath(pullOptions.RootDir) + if err != nil { + return "", errors.Wrap(err, "failed to load previous helm charts") + } + prevHelmCharts = phc } log.ActionWithSpinner("Pulling upstream") diff --git a/pkg/tests/pull/cases/kotskinds/testcase.yaml b/pkg/tests/pull/cases/kotskinds/testcase.yaml new file mode 100644 index 0000000000..5b0fcd75a1 --- /dev/null +++ b/pkg/tests/pull/cases/kotskinds/testcase.yaml @@ -0,0 +1,13 @@ +Name: test templating kots kinds +PullOptions: + Namespace: app-namespace + ExcludeAdminConsole: true + IsAirgap: true + Silent: true + LocalPath: cases/kotskinds/upstream + RootDir: cases/kotskinds/results + SharedPassword: dummy-pass + RewriteImages: false + Downstreams: + - this-cluster + SkipHelmChartCheck: true \ No newline at end of file diff --git a/pkg/tests/pull/cases/kotskinds/upstream/app/configmap.yaml b/pkg/tests/pull/cases/kotskinds/upstream/app/configmap.yaml new file mode 100644 index 0000000000..51ade02102 --- /dev/null +++ b/pkg/tests/pull/cases/kotskinds/upstream/app/configmap.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: test-config +data: + key: value diff --git a/pkg/tests/pull/cases/kotskinds/upstream/kots-app.yaml b/pkg/tests/pull/cases/kotskinds/upstream/kots-app.yaml new file mode 100644 index 0000000000..cc58d192c8 --- /dev/null +++ b/pkg/tests/pull/cases/kotskinds/upstream/kots-app.yaml @@ -0,0 +1,51 @@ +apiVersion: kots.io/v1beta1 +kind: Application +metadata: + name: my-app + annotations: + kots.io/exclude: "true" +spec: + title: repl{{ ConfigOption "kots_app_app_title" }} + icon: repl{{ ConfigOption "kots_app_app_icon" }} + branding: + css: + - repl{{ ConfigOption "kots_app_branding_css_1" }} + fonts: + - fontFamily: repl{{ ConfigOption "kots_app_branding_fonts_1_font_family" }} + sources: + - repl{{ ConfigOption "kots_app_branding_fonts_1_font_sources_1" }} + applicationPorts: + - serviceName: repl{{ ConfigOption "kots_app_application_ports_1_service_name" }} + servicePort: repl{{ ConfigOption "kots_app_application_ports_1_service_port" }} + localPort: repl{{ ConfigOption "kots_app_application_ports_1_local_port" }} + applicationUrl: repl{{ ConfigOption "kots_app_application_ports_1_application_url" }} + releaseNotes: repl{{ ConfigOption "kots_app_release_notes" }} + allowRollback: repl{{ ConfigOptionEquals "kots_app_allow_rollback" "1" }} + statusInformers: + - repl{{ ConfigOption "kots_app_status_informers_1" }} + graphs: + - title: repl{{ ConfigOption "kots_app_graphs_1_title" }} + query: repl{{ ConfigOption "kots_app_graphs_1_query" }} + legend: repl{{ ConfigOption "kots_app_graphs_1_legend" }} + queries: + - query: repl{{ ConfigOption "kots_app_graphs_1_queries_1_query" }} + legend: repl{{ ConfigOption "kots_app_graphs_1_queries_1_legend" }} + - query: repl{{ ConfigOption "kots_app_graphs_1_queries_2_query" }} + legend: repl{{ ConfigOption "kots_app_graphs_1_queries_2_legend" }} + durationSeconds: repl{{ ConfigOption "kots_app_graphs_1_duration_seconds" }} + yAxisFormat: repl{{ ConfigOption "kots_app_graphs_1_y_axis_format" }} + yAxisTemplate: repl{{ ConfigOption "kots_app_graphs_1_y_axis_template" }} + minKotsVersion: repl{{ ConfigOption "kots_app_min_kots_version" }} + targetKotsVersion: repl{{ ConfigOption "kots_app_target_kots_version" }} + kubectlVersion: repl{{ ConfigOption "kots_app_kubectl_version" }} + kustomizeVersion: repl{{ ConfigOption "kots_app_kustomize_version" }} + additionalImages: + - repl{{ ConfigOption "kots_app_additional_images_1" }} + additionalNamespaces: + - repl{{ ConfigOption "kots_app_additional_namespacse_1" }} + requireMinimalRBACPrivileges: repl{{ ConfigOptionEquals "kots_app_require_minimal_rbac_privileges" "1" }} + supportMinimalRBACPrivileges: repl{{ ConfigOptionEquals "kots_app_support_minimal_rbac_privileges" "1" }} + consoleFeatureFlags: + - repl{{ ConfigOption "kots_app_console_feature_flags_1" }} + replicatedRegistryDomain: repl{{ ConfigOption "kots_app_replicated_registry_domain" }} + proxyRegistryDomain: repl{{ ConfigOption "kots_app_proxy_registry_domain" }} diff --git a/pkg/tests/pull/cases/kotskinds/upstream/kots-config.yaml b/pkg/tests/pull/cases/kotskinds/upstream/kots-config.yaml new file mode 100644 index 0000000000..f400bb4761 --- /dev/null +++ b/pkg/tests/pull/cases/kotskinds/upstream/kots-config.yaml @@ -0,0 +1,406 @@ +apiVersion: kots.io/v1beta1 +kind: Config +metadata: + name: my-app +spec: + groups: + - name: setup + title: Setup + items: + # ---- KOTS APP ---- # + - name: kots_app_app_title + title: My Application + type: text + default: "My Application" + - name: kots_app_app_icon + title: Application Icon + type: text + default: "https://cdn.example.com/my-app-icon.png" + - name: kots_app_branding_css_1 + title: Branding CSS 1 + type: text + default: "https://cdn.example.com/my-app.css" + - name: kots_app_branding_fonts_1_font_family + title: Branding Fonts 1 Font Family + type: text + default: "Arial" + - name: kots_app_branding_fonts_1_font_sources_1 + title: Branding Fonts 1 Font Sources 1 + type: text + default: "https://cdn.example.com/my-app-font.woff" + - name: kots_app_application_ports_1_service_name + title: Application Ports 1 Service Name + type: text + default: "my-app" + - name: kots_app_application_ports_1_service_port + title: Application Ports 1 Service Port + type: text + default: "80" + - name: kots_app_application_ports_1_local_port + title: Application Ports 1 Local Port + type: text + default: "80" + - name: kots_app_application_ports_1_application_url + title: Application Ports 1 Application URL + type: text + default: "http://localhost:80" + - name: kots_app_release_notes + title: Release Notes + type: text + default: "my release notes" + - name: kots_app_allow_rollback + title: Allow Rollback + type: bool + default: "0" + - name: kots_app_status_informers_1 + title: Status Informers 1 + type: text + default: "deployment/my-app" + - name: kots_app_graphs_1_title + title: Graphs 1 Title + type: text + default: "My Graph" + - name: kots_app_graphs_1_query + title: Graphs 1 Query + type: text + default: "sum(kube_pod_container_resource_requests_cpu_cores)" + - name: kots_app_graphs_1_legend + title: Graphs 1 Legend + type: text + default: "CPU" + - name: kots_app_graphs_1_queries_1_query + title: Graphs 1 Queries 1 Query + type: text + default: "sum(kube_pod_container_resource_requests_memory_bytes)" + - name: kots_app_graphs_1_queries_1_legend + title: Graphs 1 Queries 1 Legend + type: text + default: "Memory" + - name: kots_app_graphs_1_queries_2_query + title: Graphs 1 Queries 2 Query + type: text + default: "sum(kube_pod_container_resource_requests_storage_bytes)" + - name: kots_app_graphs_1_queries_2_legend + title: Graphs 1 Queries 2 Legend + type: text + default: "Storage" + - name: kots_app_graphs_1_duration_seconds + title: Graphs 1 Duration Seconds + type: text + default: "3600" + - name: kots_app_graphs_1_y_axis_format + title: Graphs 1 Y Axis Format + type: text + default: "bytes" + - name: kots_app_graphs_1_y_axis_template + title: Graphs 1 Y Axis Template + type: text + default: "y-axis-template" + - name: kots_app_min_kots_version + title: Min Kots Version + type: text + default: "1.0.0" + - name: kots_app_target_kots_version + title: Target Kots Version + type: text + default: "2.0.0" + - name: kots_app_kubectl_version + title: Kubectl Version + type: text + default: "1.25.0" + - name: kots_app_kustomize_version + title: Kustomize Version + type: text + default: "4.7.0" + - name: kots_app_additional_images_1 + title: Additional Images 1 + type: text + default: "my-app-image:1.0.0" + - name: kots_app_additional_namespacse_1 + title: Additional Namespaces 1 + type: text + default: "my-app-namespace" + - name: kots_app_require_minimal_rbac_privileges + title: Require Minimal RBAC Privileges + type: bool + default: "0" + - name: kots_app_support_minimal_rbac_privileges + title: Support Minimal RBAC Privileges + type: bool + default: "0" + - name: kots_app_console_feature_flags_1 + title: Console Feature Flags 1 + type: text + default: "my-app-feature" + - name: kots_app_replicated_registry_domain + title: Replicated Registry Domain + type: text + default: "registry.example.com" + - name: kots_app_proxy_registry_domain + title: Proxy Registry Domain + type: text + default: "proxy.example.com" + + # ---- HelmChart v1beta1 ---- # + - name: v1beta1_helmchart_chart_release_name + title: v1beta1 Chart Release Name + type: text + default: "my-chart-release-name" + - name: v1beta1_helmchart_use_helm_install + title: v1beta1 Use Helm Install + type: bool + default: "1" + - name: v1beta1_helmchart_values + title: v1beta1 Values + type: textarea + default: | + foo: bar + bar: baz + - name: v1beta1_helmchart_exclude + title: v1beta1 Exclude + type: bool + default: "1" + - name: v1beta1_helmchart_helm_version + title: v1beta1 Helm Version + type: text + default: "v3" + - name: v1beta1_helmchart_namespace + title: v1beta1 Namespace + type: text + default: "my-namespace" + - name: v1beta1_helmchart_optional_values_1_when + title: v1beta1 Optional Values 1 When + type: bool + default: "1" + - name: v1beta1_helmchart_optional_values_1_recursive_merge + title: v1beta1 Optional Values 1 Recursive Merge + type: bool + default: "1" + - name: v1beta1_helmchart_optional_values_1_values + title: v1beta1 Optional Values 1 Values + type: textarea + default: | + foo: bar + bar: baz + - name: v1beta1_helmchart_builder + title: v1beta1 Builder + type: textarea + default: | + foo: bar + bar: baz + - name: v1beta1_helmchart_weight + title: v1beta1 Weight + type: text + default: "1" + - name: v1beta1_helmchart_helm_upgrade_flags_1 + title: v1beta1 Helm Upgrade Flags 1 + type: text + default: "--timeout 60s" + + # ---- HelmChart v1beta2 ---- # + - name: v1beta2_helmchart_release_name + title: v1beta2 Release Name + type: text + default: "my-chart-release-name" + - name: v1beta2_helmchart_values + title: v1beta2 Values + type: textarea + default: | + foo: bar + bar: baz + - name: v1beta2_helmchart_exclude + title: v1beta2 Exclude + type: bool + default: "1" + - name: v1beta2_helmchart_namespace + title: v1beta2 Namespace + type: text + default: "my-namespace" + - name: v1beta2_helmchart_optional_values_1_when + title: v1beta2 Optional Values 1 When + type: bool + default: "1" + - name: v1beta2_helmchart_optional_values_1_recursive_merge + title: v1beta2 Optional Values 1 Recursive Merge + type: bool + default: "1" + - name: v1beta2_helmchart_optional_values_1_values + title: v1beta2 Optional Values 1 Values + type: textarea + default: | + foo: bar + bar: baz + - name: v1beta2_helmchart_builder + title: v1beta2 Builder + type: textarea + default: | + foo: bar + bar: baz + - name: v1beta2_helmchart_weight + title: v1beta2 Weight + type: text + default: "1" + - name: v1beta2_helmchart_helm_upgrade_flags_1 + title: v1beta2 Helm Upgrade Flags 1 + type: text + default: "--timeout 70s" + + # ---- SupportBundle v1beta2 ---- # + - name: v1beta2_supportbundle_collectors_exec_collector_name + title: v1beta2 Exec Collector Name + type: text + default: "my-exec-collector-name" + - name: v1beta2_supportbundle_collectors_exec_name + title: v1beta2 Exec Name + type: text + default: "my-exec-name" + - name: v1beta2_supportbundle_collectors_exec_selector_0 + title: v1beta2 Exec Selector 0 + type: text + default: "my-exec-selector-0" + - name: v1beta2_supportbundle_collectors_exec_command_0 + title: v1beta2 Exec Command 0 + type: text + default: "my-exec-command-0" + - name: v1beta2_supportbundle_collectors_exec_timeout + title: v1beta2 Exec Timeout + type: text + default: "70s" + - name: v1beta2_supportbundle_collectors_logs_collector_name + title: v1beta2 Logs Collector Name + type: text + default: "my-logs-collector-name" + - name: v1beta2_supportbundle_collectors_logs_name + title: v1beta2 Logs Name + type: text + default: "my-logs-name" + - name: v1beta2_supportbundle_collectors_logs_selector_0 + title: v1beta2 Logs Selector 0 + type: text + default: "my-logs-selector-0" + - name: v1beta2_supportbundle_analyzers_cluster_version_outcomes_fail_when + title: v1beta2 Cluster Version Outcomes Fail When + type: text + default: "< 1.16.0" + - name: v1beta2_supportbundle_analyzers_cluster_version_outcomes_fail_message + title: v1beta2 Cluster Version Outcomes Fail Message + type: text + default: "Cluster version is too old" + - name: v1beta2_supportbundle_analyzers_cluster_version_outcomes_pass_message + title: v1beta2 Cluster Version Outcomes Pass Message + type: text + default: "Cluster version is new enough" + - name: v1beta2_supportbundle_analyzers_container_runtime_outcomes_fail_when + title: v1beta2 Container Runtime Outcomes Fail When + type: text + default: "== gvisor" + - name: v1beta2_supportbundle_analyzers_container_runtime_outcomes_fail_message + title: v1beta2 Container Runtime Outcomes Fail Message + type: text + default: "Container runtime is gvisor" + - name: v1beta2_supportbundle_analyzers_container_runtime_outcomes_pass_message + title: v1beta2 Container Runtime Outcomes Pass Message + type: text + default: "Container runtime is not gvisor" + - name: v1beta2_supportbundle_analyzers_text_analyze_check_name + title: v1beta2 Text Analyze Check Name + type: text + default: "my-text-analyze-check-name" + - name: v1beta2_supportbundle_analyzers_text_analyze_exclude + title: v1beta2 Text Analyze Exclude + type: bool + default: "0" + - name: v1beta2_supportbundle_analyzers_text_analyze_ignore_if_no_files + title: v1beta2 Text Analyze Ignore If No Files + type: bool + default: "0" + - name: v1beta2_supportbundle_analyzers_text_analyze_file_name + title: v1beta2 Text Analyze File Name + type: text + default: "my-text-analyze-file-name" + - name: v1beta2_supportbundle_analyzers_text_analyze_outcomes_fail_when + title: v1beta2 Text Analyze Outcomes Fail When + type: text + default: "contains" + - name: v1beta2_supportbundle_analyzers_text_analyze_outcomes_fail_message + title: v1beta2 Text Analyze Outcomes Fail Message + type: text + default: "Text analyze failed" + - name: v1beta2_supportbundle_analyzers_text_analyze_outcomes_pass_message + title: v1beta2 Text Analyze Outcomes Pass Message + type: text + default: "Text analyze passed" + - name: v1beta2_supportbundle_analyzers_text_analyze_regex_groups + title: v1beta2 Text Analyze Regex Groups + type: text + default: "my-text-analyze-regex-groups" + - name: v1beta2_supportbundle_analyzers_node_resources_check_name + title: v1beta2 Node Resources Check Name + type: text + default: "my-node-resources-check-name" + - name: v1beta2_supportbundle_analyzers_node_resources_outcomes_fail_when + title: v1beta2 Node Resources Outcomes Fail When + type: text + default: "< 1" + - name: v1beta2_supportbundle_analyzers_node_resources_outcomes_fail_message + title: v1beta2 Node Resources Outcomes Fail Message + type: text + default: "Node resources are too low" + - name: v1beta2_supportbundle_analyzers_node_resources_outcomes_pass_message + title: v1beta2 Node Resources Outcomes Pass Message + type: text + default: "Node resources are high enough" + + # ---- Preflight v1beta2 ---- # + - name: v1beta2_preflight_collectors_run_pod_name + title: v1beta2 Run Pod Name + type: text + default: "my-run-pod-name" + - name: v1beta2_preflight_collectors_run_pod_namespace + title: v1beta2 Run Pod Namespace + type: text + default: "my-run-pod-namespace" + - name: v1beta2_preflight_collectors_run_pod_pod_spec_containers_0_name + title: v1beta2 Pod Spec Containers 0 Name + type: text + default: "my-pod-spec-containers-0-name" + - name: v1beta2_preflight_collectors_run_pod_pod_spec_containers_0_image + title: v1beta2 Pod Spec Containers 0 Image + type: text + default: "my-pod-spec-containers-0-image" + - name: v1beta2_preflight_collectors_run_pod_pod_spec_containers_0_security_context_allow_privilege_escalation + title: v1beta2 Pod Spec Containers 0 Security Context Allow Privilege Escalation + type: bool + default: "1" + - name: v1beta2_preflight_collectors_run_pod_pod_spec_containers_0_command_0 + title: v1beta2 Pod Spec Containers 0 Command 0 + type: text + default: "my-pod-spec-containers-0-command-0" + - name: v1beta2_preflight_collectors_run_pod_pod_spec_containers_0_args_0 + title: v1beta2 Pod Spec Containers 0 Args 0 + type: text + default: "my-pod-spec-containers-0-args-0" + - name: v1beta2_preflight_analyzers_text_analyze_check_name + title: v1beta2 Text Analyze Check Name + type: text + default: "my-text-analyze-check-name" + - name: v1beta2_preflight_analyzers_text_analyze_file_name + title: v1beta2 Text Analyze File Name + type: text + default: "my-text-analyze-file-name" + - name: v1beta2_preflight_analyzers_text_analyze_regex_groups + title: v1beta2 Text Analyze Regex Groups + type: text + default: "my-text-analyze-regex-groups" + - name: v1beta2_preflight_analyzers_text_analyze_outcomes_pass_when + title: v1beta2 Text Analyze Outcomes Pass When + type: text + default: "Loss < 5" + - name: v1beta2_preflight_analyzers_text_analyze_outcomes_pass_message + title: v1beta2 Text Analyze Outcomes Pass Message + type: text + default: "my-text-analyze-outcomes-pass-message" + - name: v1beta2_preflight_analyzers_text_analyze_outcomes_fail_message + title: v1beta2 Text Analyze Outcomes Fail Message + type: text + default: "my-text-analyze-outcomes-fail-message" diff --git a/pkg/tests/pull/cases/kotskinds/upstream/kots-preflight.yaml b/pkg/tests/pull/cases/kotskinds/upstream/kots-preflight.yaml new file mode 100644 index 0000000000..dcd23f54da --- /dev/null +++ b/pkg/tests/pull/cases/kotskinds/upstream/kots-preflight.yaml @@ -0,0 +1,30 @@ +apiVersion: troubleshoot.sh/v1beta2 +kind: Preflight +metadata: + name: my-app +spec: + collectors: + - runPod: + name: repl{{ ConfigOption "v1beta2_preflight_collectors_run_pod_name" }} + namespace: repl{{ ConfigOption "v1beta2_preflight_collectors_run_pod_namespace" }} + podSpec: + containers: + - name: repl{{ ConfigOption "v1beta2_preflight_collectors_run_pod_pod_spec_containers_0_name" }} + image: repl{{ ConfigOption "v1beta2_preflight_collectors_run_pod_pod_spec_containers_0_image" }} + securityContext: + allowPrivilegeEscalation: repl{{ ConfigOptionEquals "v1beta2_preflight_collectors_run_pod_pod_spec_containers_0_security_context_allow_privilege_escalation" "1" }} + command: + - repl{{ ConfigOption "v1beta2_preflight_collectors_run_pod_pod_spec_containers_0_command_0" }} + args: + - repl{{ ConfigOption "v1beta2_preflight_collectors_run_pod_pod_spec_containers_0_args_0" }} + analyzers: + - textAnalyze: + checkName: repl{{ ConfigOption "v1beta2_preflight_analyzers_text_analyze_check_name" }} + fileName: repl{{ ConfigOption "v1beta2_preflight_analyzers_text_analyze_file_name" }} + regexGroups: repl{{ ConfigOption "v1beta2_preflight_analyzers_text_analyze_regex_groups" }} + outcomes: + - pass: + when: repl{{ ConfigOption "v1beta2_preflight_analyzers_text_analyze_outcomes_pass_when" }} + message: repl{{ ConfigOption "v1beta2_preflight_analyzers_text_analyze_outcomes_pass_message" }} + - fail: + message: repl{{ ConfigOption "v1beta2_preflight_analyzers_text_analyze_outcomes_fail_message" }} \ No newline at end of file diff --git a/pkg/tests/pull/cases/kotskinds/upstream/kots-supportbundle.yaml b/pkg/tests/pull/cases/kotskinds/upstream/kots-supportbundle.yaml new file mode 100644 index 0000000000..bc3e1147b4 --- /dev/null +++ b/pkg/tests/pull/cases/kotskinds/upstream/kots-supportbundle.yaml @@ -0,0 +1,55 @@ +apiVersion: troubleshoot.sh/v1beta2 +kind: SupportBundle +metadata: + name: my-app +spec: + collectors: + - exec: + collectorName: repl{{ ConfigOption "v1beta2_supportbundle_collectors_exec_collector_name" }} + name: repl{{ ConfigOption "v1beta2_supportbundle_collectors_exec_name" }} + selector: + - repl{{ ConfigOption "v1beta2_supportbundle_collectors_exec_selector_0" }} + command: + - repl{{ ConfigOption "v1beta2_supportbundle_collectors_exec_command_0" }} + timeout: repl{{ ConfigOption "v1beta2_supportbundle_collectors_exec_timeout" }} + - logs: + collectorName: repl{{ ConfigOption "v1beta2_supportbundle_collectors_logs_collector_name" }} + name: repl{{ ConfigOption "v1beta2_supportbundle_collectors_logs_name" }} + selector: + - repl{{ ConfigOption "v1beta2_supportbundle_collectors_logs_selector_0" }} + + analyzers: + - clusterVersion: + outcomes: + - fail: + when: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_cluster_version_outcomes_fail_when" }} + message: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_cluster_version_outcomes_fail_message" }} + - pass: + message: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_cluster_version_outcomes_pass_message" }} + - containerRuntime: + outcomes: + - fail: + when: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_container_runtime_outcomes_fail_when" }} + message: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_container_runtime_outcomes_fail_message" }} + - pass: + message: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_container_runtime_outcomes_pass_message" }} + - textAnalyze: + checkName: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_text_analyze_check_name" }} + exclude: repl{{ ConfigOptionEquals "v1beta2_supportbundle_analyzers_text_analyze_exclude" "1" }} + ignoreIfNoFiles: repl{{ ConfigOptionEquals "v1beta2_supportbundle_analyzers_text_analyze_ignore_if_no_files" "1" }} + fileName: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_text_analyze_file_name" }} + outcomes: + - fail: + when: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_text_analyze_outcomes_fail_when" }} + message: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_text_analyze_outcomes_fail_message" }} + - pass: + message: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_text_analyze_outcomes_pass_message" }} + regexGroups: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_text_analyze_regex_groups" }} + - nodeResources: + checkName: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_node_resources_check_name" }} + outcomes: + - fail: + when: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_node_resources_outcomes_fail_when" }} + message: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_node_resources_outcomes_fail_message" }} + - pass: + message: repl{{ ConfigOption "v1beta2_supportbundle_analyzers_node_resources_outcomes_pass_message" }} diff --git a/pkg/tests/pull/cases/kotskinds/upstream/my-chart-0.1.0.tgz b/pkg/tests/pull/cases/kotskinds/upstream/my-chart-0.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..dd79ddc8a78391a7e96ba81e4696f8382c47b46d GIT binary patch literal 407 zcmV;I0cidoiwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PL2{YU3~vfPL0e%nQUB$;Mf9TXI=g3OV&YwUt!V`axDgL+QI0 zyCfwhB$T8H1$~DIjWV_e&nL@lC-pOhIGy*u`IbzZT^mHisw{^Q5yvC)naFrq7NV+n zfmMcF%!J4Qul^)QSa*>^h8N#!T-+~#yna-n)6PoR2u9xTr{71``3tv&v;OmPC8j2(tz@gw@-NA-Gz}x%1 zYe{^cQ~rC`T;)J;&VNykzyB4lc=G=i9QA+Unp5U`*Ram3x?ifDjijv#T|b)~*(5%f z832Gbv{Dl6O50b-b5RUY??N21`}}>v!i6Z|PdX