Skip to content

Commit

Permalink
separate rendering kots kinds and upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
sgalsaleh committed Dec 20, 2023
1 parent b0b5860 commit a7f6c61
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 99 deletions.
17 changes: 14 additions & 3 deletions pkg/base/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package base

import (
"github.com/pkg/errors"
"github.com/replicatedhq/kots/pkg/kotsutil"
"github.com/replicatedhq/kots/pkg/logger"
registrytypes "github.com/replicatedhq/kots/pkg/registry/types"
upstreamtypes "github.com/replicatedhq/kots/pkg/upstream/types"
Expand All @@ -21,18 +22,28 @@ type RenderOptions struct {
Log *logger.CLILogger
}

// RenderKotsKinds is responsible for rendering KOTS custom resources
func RenderKotsKinds(u *upstreamtypes.Upstream, renderOptions *RenderOptions) (map[string][]byte, error) {
renderedKotsKinds, err := renderKotsKinds(u, renderOptions)
if err != nil {
return nil, errors.Wrap(err, "failed to render kots kinds")
}

return renderedKotsKinds, nil
}

// RenderUpstream is responsible for any conversions or transpilation steps are required
// to take an upstream and make it a valid kubernetes base
func RenderUpstream(u *upstreamtypes.Upstream, renderOptions *RenderOptions) (base *Base, helmBases []Base, renderedKotsKinds map[string][]byte, err error) {
func RenderUpstream(u *upstreamtypes.Upstream, renderOptions *RenderOptions, renderedKotsKinds *kotsutil.KotsKinds) (base *Base, helmBases []Base, err error) {
if u.Type == "helm" {
base, err = RenderHelm(u, renderOptions)
return
}

if u.Type == "replicated" {
base, helmBases, renderedKotsKinds, err = renderReplicated(u, renderOptions)
base, helmBases, err = renderReplicated(u, renderOptions, renderedKotsKinds)
return
}

return nil, nil, nil, errors.New("unknown upstream type")
return nil, nil, errors.New("unknown upstream type")
}
91 changes: 37 additions & 54 deletions pkg/base/replicated.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
kotsv1beta2 "github.com/replicatedhq/kotskinds/apis/kots/v1beta2"
kotsscheme "github.com/replicatedhq/kotskinds/client/kotsclientset/scheme"
"github.com/replicatedhq/kotskinds/pkg/helmchart"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
troubleshootscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"helm.sh/helm/v3/pkg/chart"
Expand All @@ -44,33 +43,15 @@ type Document struct {
Kind string `yaml:"kind"`
}

func renderReplicated(u *upstreamtypes.Upstream, renderOptions *RenderOptions) (*Base, []Base, map[string][]byte, error) {
func renderReplicated(u *upstreamtypes.Upstream, renderOptions *RenderOptions, renderedKotsKinds *kotsutil.KotsKinds) (*Base, []Base, error) {
commonBase := Base{
Files: []BaseFile{},
Bases: []Base{},
}

builder, itemValues, err := NewConfigContextTemplateBuilder(u, renderOptions)
if err != nil {
return nil, nil, nil, errors.Wrap(err, "failed to create new config context template builder")
}

kotsKinds, err := getKotsKinds(u)
builder, _, err := NewConfigContextTemplateBuilder(u, renderOptions)
if err != nil {
return nil, nil, nil, errors.Wrap(err, "failed to find config file")
}

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, renderOptions.RegistrySettings, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace, true)
if err != nil {
return nil, nil, nil, errors.Wrap(err, "failed to template config objects")
}

renderedKotsKinds, err := renderKotsKinds(u.Files, renderedConfig, renderOptions, builder)
if err != nil {
return nil, nil, nil, errors.Wrap(err, "failed to render the kots kinds")
return nil, nil, errors.Wrap(err, "failed to create new config context template builder")
}

for _, upstreamFile := range u.Files {
Expand All @@ -94,23 +75,23 @@ func renderReplicated(u *upstreamtypes.Upstream, renderOptions *RenderOptions) (
upstreamFile.Content = bytes.Join(newContent, []byte("\n---\n"))
}

c, err := processVariadicConfig(&upstreamFile, renderedConfig, renderOptions.Log)
c, err := processVariadicConfig(&upstreamFile, renderedKotsKinds.Config, renderOptions.Log)
if err != nil {
return nil, nil, nil, errors.Wrapf(err, "failed to process variadic config in file %s", upstreamFile.Path)
return nil, nil, errors.Wrapf(err, "failed to process variadic config in file %s", upstreamFile.Path)
}
upstreamFile.Content = c

baseFile, err := upstreamFileToBaseFile(upstreamFile, *builder, renderOptions.Log)
if err != nil {
return nil, nil, nil, errors.Wrapf(err, "failed to convert upstream file %s to base", upstreamFile.Path)
return nil, nil, errors.Wrapf(err, "failed to convert upstream file %s to base", upstreamFile.Path)
}

baseFiles := convertToSingleDocBaseFiles([]BaseFile{baseFile})
for _, f := range baseFiles {
include, err := f.ShouldBeIncludedInBaseKustomization(renderOptions.ExcludeKotsKinds)
if err != nil {
if _, ok := err.(ParseError); !ok {
return nil, nil, nil, errors.Wrapf(err, "failed to determine if file %s should be included in base", f.Path)
return nil, nil, errors.Wrapf(err, "failed to determine if file %s should be included in base", f.Path)
}
}
if include {
Expand All @@ -127,21 +108,21 @@ func renderReplicated(u *upstreamtypes.Upstream, renderOptions *RenderOptions) (
// NOTE: we only render v1beta1 HelmCharts to base
kotsV1Beta1HelmCharts, err := findAllKotsV1Beta1HelmCharts(u.Files, *builder, renderOptions.Log)
if err != nil {
return nil, nil, nil, errors.Wrap(err, "failed to find helm charts")
return nil, nil, errors.Wrap(err, "failed to find helm charts")
}

helmBases := []Base{}
for _, kotsHelmChart := range kotsV1Beta1HelmCharts {
helmBase, err := renderReplicatedHelmChart(&kotsHelmChart, u.Files, renderOptions, builder)
if err != nil {
return nil, nil, nil, errors.Wrapf(err, "failed to render helm chart %s", kotsHelmChart.Name)
return nil, nil, errors.Wrapf(err, "failed to render helm chart %s", kotsHelmChart.Name)
} else if helmBase == nil {
continue
}

renderedHelmBase, err := renderReplicatedHelmBase(u, renderOptions, *helmBase, *builder)
if err != nil {
return nil, nil, nil, errors.Wrapf(err, "failed to render helm chart base %s", helmBase.Path)
return nil, nil, errors.Wrapf(err, "failed to render helm chart base %s", helmBase.Path)
}

if kotsHelmChart.Spec.UseHelmInstall {
Expand All @@ -151,13 +132,31 @@ func renderReplicated(u *upstreamtypes.Upstream, renderOptions *RenderOptions) (
}
}

return &commonBase, helmBases, renderedKotsKinds, nil
return &commonBase, helmBases, nil
}

func renderKotsKinds(upstreamFiles []upstreamtypes.UpstreamFile, renderedConfig *kotsv1beta1.Config, renderOptions *RenderOptions, builder *template.Builder) (map[string][]byte, error) {
renderedKotsKinds := make(map[string][]byte)
func renderKotsKinds(u *upstreamtypes.Upstream, renderOptions *RenderOptions) (map[string][]byte, error) {
renderedKotsKindsMap := make(map[string][]byte)

for _, upstreamFile := range upstreamFiles {
builder, itemValues, err := NewConfigContextTemplateBuilder(u, renderOptions)
if err != nil {
return nil, errors.Wrap(err, "failed to create new config context template builder")
}

kotsKinds, err := getTemplatingKotsKinds(u)
if err != nil {
return nil, errors.Wrap(err, "failed to find config file")
}

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, renderOptions.RegistrySettings, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace, true)
if err != nil {
return nil, errors.Wrap(err, "failed to template config objects")
}

for _, upstreamFile := range u.Files {
for _, doc := range util.ConvertToSingleDocs(upstreamFile.Content) {
gvk := OverlySimpleGVK{}
if err := yaml.Unmarshal(doc, &gvk); err != nil {
Expand Down Expand Up @@ -212,15 +211,15 @@ func renderKotsKinds(upstreamFiles []upstreamtypes.UpstreamFile, renderedConfig
doc = []byte(bytes)
}

if existing, exists := renderedKotsKinds[upstreamFile.Path]; exists {
if existing, exists := renderedKotsKindsMap[upstreamFile.Path]; exists {
doc = bytes.Join([][]byte{existing, doc}, []byte("\n---\n"))
}

renderedKotsKinds[upstreamFile.Path] = doc
renderedKotsKindsMap[upstreamFile.Path] = doc
}
}

return renderedKotsKinds, nil
return renderedKotsKindsMap, nil
}

func extractHelmBases(b Base) []Base {
Expand Down Expand Up @@ -440,7 +439,7 @@ func tryGetConfigFromFileContent(content []byte, log *logger.CLILogger) *kotsv1b
return nil
}

func getKotsKinds(u *upstreamtypes.Upstream) (*kotsutil.KotsKinds, error) {
func getTemplatingKotsKinds(u *upstreamtypes.Upstream) (*kotsutil.KotsKinds, error) {
kotsKinds := &kotsutil.KotsKinds{}

for _, file := range u.Files {
Expand All @@ -455,7 +454,7 @@ func getKotsKinds(u *upstreamtypes.Upstream) (*kotsutil.KotsKinds, error) {
decoded, gvk, err := decode(doc, nil, nil)
if err != nil {
if document.APIVersion == "kots.io/v1beta1" && (document.Kind == "Config" || document.Kind == "License") {
errMessage := fmt.Sprintf("Failed to decode %s", file.Path)
errMessage := fmt.Sprintf("Failed to decode %s: %v", file.Path, string(doc))
return nil, errors.Wrap(err, errMessage)
}
continue
Expand All @@ -470,26 +469,10 @@ func getKotsKinds(u *upstreamtypes.Upstream) (*kotsutil.KotsKinds, error) {
kotsKinds.KotsApplication = *decoded.(*kotsv1beta1.Application)
case "kots.io/v1beta1, Kind=License":
kotsKinds.License = decoded.(*kotsv1beta1.License)
case "kots.io/v1beta1, Kind=Identity":
kotsKinds.Identity = decoded.(*kotsv1beta1.Identity)
case "kots.io/v1beta1, Kind=IdentityConfig":
kotsKinds.IdentityConfig = decoded.(*kotsv1beta1.IdentityConfig)
case "kots.io/v1beta1, Kind=Installation":
kotsKinds.Installation = *decoded.(*kotsv1beta1.Installation)
case "troubleshoot.sh/v1beta2, Kind=Collector":
kotsKinds.Collector = decoded.(*troubleshootv1beta2.Collector)
case "troubleshoot.sh/v1beta2, Kind=Analyzer":
kotsKinds.Analyzer = decoded.(*troubleshootv1beta2.Analyzer)
case "troubleshoot.sh/v1beta2, Kind=SupportBundle":
kotsKinds.SupportBundle = decoded.(*troubleshootv1beta2.SupportBundle)
case "troubleshoot.sh/v1beta2, Kind=Redactor":
kotsKinds.Redactor = decoded.(*troubleshootv1beta2.Redactor)
case "troubleshoot.sh/v1beta2, Kind=Preflight":
kotsKinds.Preflight = decoded.(*troubleshootv1beta2.Preflight)
case "velero.io/v1, Kind=Backup":
kotsKinds.Backup = decoded.(*velerov1.Backup)
case "app.k8s.io/v1beta1, Kind=Application":
kotsKinds.Application = decoded.(*applicationv1beta1.Application)
}
}
}
Expand Down
42 changes: 25 additions & 17 deletions pkg/base/replicated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,17 @@ status: {}
t.Run(test.name, func(t *testing.T) {
req := require.New(t)

base, _, kotsKinds, err := renderReplicated(test.upstream, test.renderOptions)
renderedKotsKindsMap, err := renderKotsKinds(test.upstream, test.renderOptions)
req.NoError(err)

renderedKotsKinds, err := kotsutil.KotsKindsFromMap(renderedKotsKindsMap)
req.NoError(err)

expectedKotsKinds, err := kotsutil.KotsKindsFromMap(test.expectedKotsKinds)
req.NoError(err)
req.Equal(expectedKotsKinds, renderedKotsKinds)

base, _, err := renderReplicated(test.upstream, test.renderOptions, renderedKotsKinds)
req.NoError(err)

decode := scheme.Codecs.UniversalDeserializer().Decode
Expand All @@ -876,12 +886,6 @@ status: {}

expectedMultidoc := multidocobj.(*corev1.ServiceAccount)

expKindsStruct, err := kotsutil.KotsKindsFromMap(test.expectedKotsKinds)
req.NoError(err)
kindsStruct, err := kotsutil.KotsKindsFromMap(kotsKinds)
req.NoError(err)
req.Equal(expKindsStruct, kindsStruct)

var unmarshaledSecrets []*corev1.Secret
for _, expectedSecret := range test.expectedSecrets {
secobj, _, err := decode(expectedSecret.Content, nil, nil)
Expand Down Expand Up @@ -1910,21 +1914,25 @@ version: 1.10.1
t.Run(test.name, func(t *testing.T) {
req := require.New(t)

base, helmBase, kotsKinds, err := renderReplicated(test.upstream, test.renderOptions)
renderedKotsKindsMap, err := renderKotsKinds(test.upstream, test.renderOptions)
req.NoError(err)

renderedKotsKinds, err := kotsutil.KotsKindsFromMap(renderedKotsKindsMap)
req.NoError(err)
req.ElementsMatch(test.expectedHelm, helmBase)
req.ElementsMatch(test.expectedBase.Files, base.Files)

expKindsStruct, err := kotsutil.KotsKindsFromMap(test.expectedKotsKinds)
expectedKotsKinds, err := kotsutil.KotsKindsFromMap(test.expectedKotsKinds)
req.NoError(err)
kindsStruct, err := kotsutil.KotsKindsFromMap(kotsKinds)
req.Equal(expectedKotsKinds, renderedKotsKinds)

base, helmBase, err := renderReplicated(test.upstream, test.renderOptions, renderedKotsKinds)
req.NoError(err)
req.Equal(expKindsStruct, kindsStruct)
req.ElementsMatch(test.expectedHelm, helmBase)
req.ElementsMatch(test.expectedBase.Files, base.Files)
})
}
}

func Test_getKotsKinds(t *testing.T) {
func Test_getTemplatingKotsKinds(t *testing.T) {
type args struct {
u *upstreamtypes.Upstream
}
Expand Down Expand Up @@ -2142,13 +2150,13 @@ spec:

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := getKotsKinds(tt.args.u)
got, err := getTemplatingKotsKinds(tt.args.u)
if (err != nil) != tt.wantErr {
t.Errorf("getKotsKinds() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("getTemplatingKotsKinds() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("getKotsKinds() = %v, want %v", got, tt.want)
t.Errorf("getTemplatingKotsKinds() = %v, want %v", got, tt.want)
}
})
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/base/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func NewConfigContextTemplateBuilder(u *upstreamtypes.Upstream, renderOptions *RenderOptions) (*template.Builder, map[string]template.ItemValue, error) {
kotsKinds, err := getKotsKinds(u)
kotsKinds, err := getTemplatingKotsKinds(u)
if err != nil {
return nil, nil, err
}
Expand Down
17 changes: 14 additions & 3 deletions pkg/pull/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,19 +320,21 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) {
Sequence: pullOptions.AppSequence,
IsAirgap: pullOptions.AirgapRoot != "",
}
log.ActionWithSpinner("Creating base")
io.WriteString(pullOptions.ReportWriter, "Creating base\n")
log.ActionWithSpinner("Rendering KOTS custom resources")
io.WriteString(pullOptions.ReportWriter, "Rendering KOTS custom resources\n")

commonBase, helmBases, renderedKotsKindsMap, err := base.RenderUpstream(u, &renderOptions)
renderedKotsKindsMap, err := base.RenderKotsKinds(u, &renderOptions)
if err != nil {
log.FinishSpinnerWithError()
return "", errors.Wrap(err, "failed to render upstream")
}

renderedKotsKinds, err := kotsutil.KotsKindsFromMap(renderedKotsKindsMap)
if err != nil {
log.FinishSpinnerWithError()
return "", errors.Wrap(err, "failed to load rendered kotskinds from map")
}
log.FinishSpinner()

needsConfig, err := kotsadmconfig.NeedsConfiguration(pullOptions.AppSlug, pullOptions.AppSequence, pullOptions.AirgapRoot != "", renderedKotsKinds, registrySettings)
if err != nil {
Expand Down Expand Up @@ -409,6 +411,15 @@ func Pull(upstreamURI string, pullOptions PullOptions) (string, error) {
}
}

log.ActionWithSpinner("Creating base")
io.WriteString(pullOptions.ReportWriter, "Creating base\n")

commonBase, helmBases, err := base.RenderUpstream(u, &renderOptions, renderedKotsKinds)
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 {
Expand Down
Loading

0 comments on commit a7f6c61

Please sign in to comment.