Skip to content

Commit

Permalink
load non-rendered config
Browse files Browse the repository at this point in the history
  • Loading branch information
sgalsaleh committed Dec 21, 2023
1 parent b3aefa9 commit d459ac0
Show file tree
Hide file tree
Showing 15 changed files with 215 additions and 180 deletions.
29 changes: 23 additions & 6 deletions pkg/base/replicated.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,15 @@ func renderKotsKinds(u *upstreamtypes.Upstream, renderOptions *RenderOptions) (m
return nil, errors.Wrap(err, "failed to create new config context template builder")
}

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

versionInfo := template.VersionInfoFromInstallationSpec(renderOptions.Sequence, renderOptions.IsAirgap, templatingKotsKinds.Installation.Spec)
versionInfo := template.VersionInfoFromInstallationSpec(renderOptions.Sequence, renderOptions.IsAirgap, tkk.Installation.Spec)
appInfo := template.ApplicationInfo{Slug: renderOptions.AppSlug}

renderedConfig, err := kotsconfig.TemplateConfigObjects(templatingKotsKinds.Config, itemValues, templatingKotsKinds.License, &templatingKotsKinds.KotsApplication, renderOptions.RegistrySettings, &versionInfo, &appInfo, templatingKotsKinds.IdentityConfig, util.PodNamespace, true)
renderedConfig, err := kotsconfig.TemplateConfigObjects(tkk.Config, itemValues, tkk.License, &tkk.KotsApplication, renderOptions.RegistrySettings, &versionInfo, &appInfo, tkk.IdentityConfig, util.PodNamespace, true)
if err != nil {
return nil, errors.Wrap(err, "failed to template config objects")
}
Expand Down Expand Up @@ -450,12 +450,29 @@ func getTemplatingKotsKinds(u *upstreamtypes.Upstream) (*kotsutil.KotsKinds, err
continue
}

if !kotsutil.IsTemplatingKotsKind(document.APIVersion, document.Kind) {
decode := scheme.Codecs.UniversalDeserializer().Decode
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: %v", file.Path, string(doc))
return nil, errors.Wrap(err, errMessage)
}
continue
}

if err := kotsKinds.AddKotsKinds(doc); err != nil {
return nil, errors.Wrapf(err, "failed to add kots kinds from %s", file.Path)
switch gvk.String() {
case "kots.io/v1beta1, Kind=Config":
kotsKinds.Config = decoded.(*kotsv1beta1.Config)
case "kots.io/v1beta1, Kind=ConfigValues":
kotsKinds.ConfigValues = decoded.(*kotsv1beta1.ConfigValues)
case "kots.io/v1beta1, Kind=Application":
kotsKinds.KotsApplication = *decoded.(*kotsv1beta1.Application)
case "kots.io/v1beta1, Kind=License":
kotsKinds.License = decoded.(*kotsv1beta1.License)
case "kots.io/v1beta1, Kind=IdentityConfig":
kotsKinds.IdentityConfig = decoded.(*kotsv1beta1.IdentityConfig)
case "kots.io/v1beta1, Kind=Installation":
kotsKinds.Installation = *decoded.(*kotsv1beta1.Installation)
}
}
}
Expand Down
103 changes: 68 additions & 35 deletions pkg/handlers/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ func (h *Handler) LiveAppConfig(w http.ResponseWriter, r *http.Request) {
return
}

var templatingKotsKinds *kotsutil.KotsKinds
var kotsKinds *kotsutil.KotsKinds
var nonRenderedConfig *kotsv1beta1.Config
var appLicense *kotsv1beta1.License
var app apptypes.AppType
var localRegistry registrytypes.RegistrySettings
Expand All @@ -294,8 +295,9 @@ func (h *Handler) LiveAppConfig(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
return
}
templatingKotsKinds = &k
appLicense = templatingKotsKinds.License
kotsKinds = &k
nonRenderedConfig = kotsKinds.Config
appLicense = kotsKinds.License
createNewVersion = true
} else {
licenseID := helm.GetKotsLicenseID(&helmApp.Release)
Expand All @@ -320,8 +322,9 @@ func (h *Handler) LiveAppConfig(w http.ResponseWriter, r *http.Request) {
}
k.License = licenseData.License

templatingKotsKinds = &k
appLicense = templatingKotsKinds.License
kotsKinds = &k
nonRenderedConfig = kotsKinds.Config
appLicense = kotsKinds.License
}
} else {
foundApp, err := store.GetStore().GetAppFromSlug(appSlug)
Expand All @@ -341,7 +344,7 @@ func (h *Handler) LiveAppConfig(w http.ResponseWriter, r *http.Request) {
return
}

archiveDir, err := ioutil.TempDir("", "kotsadm")
archiveDir, err := os.MkdirTemp("", "kotsadm")
if err != nil {
liveAppConfigResponse.Error = "failed to create temp dir"
logger.Error(errors.Wrap(err, liveAppConfigResponse.Error))
Expand All @@ -358,14 +361,23 @@ func (h *Handler) LiveAppConfig(w http.ResponseWriter, r *http.Request) {
return
}

templatingKotsKinds, err = kotsutil.LoadTemplatingKotsKinds(archiveDir)
kotsKinds, err = kotsutil.LoadKotsKinds(archiveDir)
if err != nil {
liveAppConfigResponse.Error = "failed to load kots kinds from path"
logger.Error(errors.Wrap(err, liveAppConfigResponse.Error))
JSON(w, http.StatusInternalServerError, liveAppConfigResponse)
return
}

// get the non-rendered config from the upstream directory because we have to re-render it with the new values
nonRenderedConfig, err = kotsutil.FindConfigInPath(filepath.Join(archiveDir, "upstream"))
if err != nil {
liveAppConfigResponse.Error = "failed to find non-rendered config"
logger.Error(errors.Wrap(err, liveAppConfigResponse.Error))
JSON(w, http.StatusInternalServerError, liveAppConfigResponse)
return
}

registryInfo, err := store.GetStore().GetRegistryDetailsForApp(foundApp.ID)
if err != nil {
liveAppConfigResponse.Error = "failed to get app registry info"
Expand All @@ -390,9 +402,9 @@ func (h *Handler) LiveAppConfig(w http.ResponseWriter, r *http.Request) {
sequence += 1
}

versionInfo := template.VersionInfoFromInstallationSpec(sequence, app.GetIsAirgap(), templatingKotsKinds.Installation.Spec) // sequence +1 because the sequence will be incremented on save (and we want the preview to be accurate)
versionInfo := template.VersionInfoFromInstallationSpec(sequence, app.GetIsAirgap(), kotsKinds.Installation.Spec) // sequence +1 because the sequence will be incremented on save (and we want the preview to be accurate)
appInfo := template.ApplicationInfo{Slug: app.GetSlug()}
renderedConfig, err := kotsconfig.TemplateConfigObjects(templatingKotsKinds.Config, configValues, appLicense, &templatingKotsKinds.KotsApplication, localRegistry, &versionInfo, &appInfo, templatingKotsKinds.IdentityConfig, app.GetNamespace(), false)
renderedConfig, err := kotsconfig.TemplateConfigObjects(nonRenderedConfig, configValues, appLicense, &kotsKinds.KotsApplication, localRegistry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, app.GetNamespace(), false)
if err != nil {
liveAppConfigResponse.Error = "failed to render templates"
logger.Error(errors.Wrap(err, liveAppConfigResponse.Error))
Expand Down Expand Up @@ -482,7 +494,8 @@ func (h *Handler) CurrentAppConfig(w http.ResponseWriter, r *http.Request) {
return
}

var templatingKotsKinds *kotsutil.KotsKinds
var kotsKinds *kotsutil.KotsKinds
var nonRenderedConfig *kotsv1beta1.Config
var license *kotsv1beta1.License
var localRegistry registrytypes.RegistrySettings
var app apptypes.AppType
Expand Down Expand Up @@ -519,8 +532,9 @@ func (h *Handler) CurrentAppConfig(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
return
}
templatingKotsKinds = &k
license = templatingKotsKinds.License
kotsKinds = &k
nonRenderedConfig = kotsKinds.Config
license = kotsKinds.License
createNewVersion = true
} else {
appKotsKinds, err := helm.GetKotsKindsFromHelmApp(helmApp)
Expand Down Expand Up @@ -554,8 +568,9 @@ func (h *Handler) CurrentAppConfig(w http.ResponseWriter, r *http.Request) {
}
k.License = licenseData.License

templatingKotsKinds = &k
license = templatingKotsKinds.License
kotsKinds = &k
nonRenderedConfig = kotsKinds.Config
license = kotsKinds.License
}
} else {
foundApp, err := store.GetStore().GetAppFromSlug(appSlug)
Expand Down Expand Up @@ -590,7 +605,7 @@ func (h *Handler) CurrentAppConfig(w http.ResponseWriter, r *http.Request) {
return
}

archiveDir, err := ioutil.TempDir("", "kotsadm")
archiveDir, err := os.MkdirTemp("", "kotsadm")
if err != nil {
currentAppConfigResponse.Error = "failed to create temp dir"
logger.Error(errors.Wrap(err, currentAppConfigResponse.Error))
Expand All @@ -607,14 +622,23 @@ func (h *Handler) CurrentAppConfig(w http.ResponseWriter, r *http.Request) {
return
}

templatingKotsKinds, err = kotsutil.LoadTemplatingKotsKinds(archiveDir)
kotsKinds, err = kotsutil.LoadKotsKinds(archiveDir)
if err != nil {
currentAppConfigResponse.Error = "failed to load kots kinds from path"
logger.Error(errors.Wrap(err, currentAppConfigResponse.Error))
JSON(w, http.StatusInternalServerError, currentAppConfigResponse)
return
}

// get the non-rendered config from the upstream directory because we have to re-render it with the new values
nonRenderedConfig, err = kotsutil.FindConfigInPath(filepath.Join(archiveDir, "upstream"))
if err != nil {
currentAppConfigResponse.Error = "failed to find non-rendered config"
logger.Error(errors.Wrap(err, currentAppConfigResponse.Error))
JSON(w, http.StatusInternalServerError, currentAppConfigResponse)
return
}

registryInfo, err := store.GetStore().GetRegistryDetailsForApp(foundApp.ID)
if err != nil {
currentAppConfigResponse.Error = "failed to get app registry info"
Expand All @@ -639,8 +663,8 @@ func (h *Handler) CurrentAppConfig(w http.ResponseWriter, r *http.Request) {
// get values from saved app version
configValues := map[string]template.ItemValue{}

if templatingKotsKinds.ConfigValues != nil {
for key, value := range templatingKotsKinds.ConfigValues.Spec.Values {
if kotsKinds.ConfigValues != nil {
for key, value := range kotsKinds.ConfigValues.Spec.Values {
generatedValue := template.ItemValue{
Default: value.Default,
Value: value.Value,
Expand All @@ -655,9 +679,9 @@ func (h *Handler) CurrentAppConfig(w http.ResponseWriter, r *http.Request) {
sequence += 1
}

versionInfo := template.VersionInfoFromInstallationSpec(sequence, app.GetIsAirgap(), templatingKotsKinds.Installation.Spec) // sequence +1 because the sequence will be incremented on save (and we want the preview to be accurate)
versionInfo := template.VersionInfoFromInstallationSpec(sequence, app.GetIsAirgap(), kotsKinds.Installation.Spec) // sequence +1 because the sequence will be incremented on save (and we want the preview to be accurate)
appInfo := template.ApplicationInfo{Slug: app.GetSlug()}
renderedConfig, err := kotsconfig.TemplateConfigObjects(templatingKotsKinds.Config, configValues, license, &templatingKotsKinds.KotsApplication, localRegistry, &versionInfo, &appInfo, templatingKotsKinds.IdentityConfig, app.GetNamespace(), false)
renderedConfig, err := kotsconfig.TemplateConfigObjects(nonRenderedConfig, configValues, license, &kotsKinds.KotsApplication, localRegistry, &versionInfo, &appInfo, kotsKinds.IdentityConfig, app.GetNamespace(), false)
if err != nil {
logger.Error(err)
currentAppConfigResponse.Error = "failed to render templates"
Expand Down Expand Up @@ -749,12 +773,12 @@ func getAppConfigValueForFile(downloadApp *apptypes.App, sequence int64, filenam
return "", errors.Wrap(err, "failed to get app version archive")
}

templatingKotsKinds, err := kotsutil.LoadTemplatingKotsKinds(archiveDir)
kotsKinds, err := kotsutil.LoadKotsKinds(archiveDir)
if err != nil {
return "", errors.Wrap(err, "failed to load kots kinds from archive")
}

for _, v := range templatingKotsKinds.ConfigValues.Spec.Values {
for _, v := range kotsKinds.ConfigValues.Spec.Values {
if v.Filename == filename {
return v.Value, nil
}
Expand All @@ -770,7 +794,7 @@ func updateAppConfig(updateApp *apptypes.App, sequence int64, configGroups []kot
Success: false,
}

archiveDir, err := ioutil.TempDir("", "kotsadm")
archiveDir, err := os.MkdirTemp("", "kotsadm")
if err != nil {
updateAppConfigResponse.Error = "failed to create temp dir"
return updateAppConfigResponse, err
Expand All @@ -783,7 +807,7 @@ func updateAppConfig(updateApp *apptypes.App, sequence int64, configGroups []kot
return updateAppConfigResponse, err
}

templatingKotsKinds, err := kotsutil.LoadTemplatingKotsKinds(archiveDir)
kotsKinds, err := kotsutil.LoadKotsKinds(archiveDir)
if err != nil {
updateAppConfigResponse.Error = "failed to load kots kinds from path"
return updateAppConfigResponse, err
Expand All @@ -800,11 +824,11 @@ func updateAppConfig(updateApp *apptypes.App, sequence int64, configGroups []kot

// we don't merge, this is a wholesale replacement of the config values
// so we don't need the complex logic in kots, we can just write
if templatingKotsKinds.ConfigValues != nil {
values := templatingKotsKinds.ConfigValues.Spec.Values
templatingKotsKinds.ConfigValues.Spec.Values = updateAppConfigValues(values, configGroups)
if kotsKinds.ConfigValues != nil {
values := kotsKinds.ConfigValues.Spec.Values
kotsKinds.ConfigValues.Spec.Values = updateAppConfigValues(values, configGroups)

configValuesSpec, err := templatingKotsKinds.Marshal("kots.io", "v1beta1", "ConfigValues")
configValuesSpec, err := kotsKinds.Marshal("kots.io", "v1beta1", "ConfigValues")
if err != nil {
updateAppConfigResponse.Error = "failed to marshal config values spec"
return updateAppConfigResponse, err
Expand Down Expand Up @@ -1079,30 +1103,39 @@ func (h *Handler) SetAppConfigValues(w http.ResponseWriter, r *http.Request) {
return
}

templatingKotsKinds, err := kotsutil.LoadTemplatingKotsKinds(archiveDir)
kotsKinds, err := kotsutil.LoadKotsKinds(archiveDir)
if err != nil {
setAppConfigValuesResponse.Error = "failed to load kots kinds from path"
logger.Error(errors.Wrap(err, setAppConfigValuesResponse.Error))
JSON(w, http.StatusInternalServerError, setAppConfigValuesResponse)
return
}

if templatingKotsKinds.Config == nil {
// get the non-rendered config from the upstream directory because we have to re-render it with the new values
nonRenderedConfig, err := kotsutil.FindConfigInPath(filepath.Join(archiveDir, "upstream"))
if err != nil {
setAppConfigValuesResponse.Error = "failed to find non-rendered config"
logger.Error(errors.Wrap(err, setAppConfigValuesResponse.Error))
JSON(w, http.StatusInternalServerError, setAppConfigValuesResponse)
return
}

if nonRenderedConfig == nil {
setAppConfigValuesResponse.Error = fmt.Sprintf("app %s does not have a config", foundApp.Slug)
logger.Errorf(setAppConfigValuesResponse.Error)
JSON(w, http.StatusInternalServerError, setAppConfigValuesResponse)
return
}

if setAppConfigValuesRequest.Merge {
if err := templatingKotsKinds.DecryptConfigValues(); err != nil {
if err := kotsKinds.DecryptConfigValues(); err != nil {
setAppConfigValuesResponse.Error = "failed to decrypt existing values"
logger.Error(errors.Wrap(err, setAppConfigValuesResponse.Error))
JSON(w, http.StatusInternalServerError, setAppConfigValuesResponse)
return
}

newConfigValues, err = mergeConfigValues(templatingKotsKinds.Config, templatingKotsKinds.ConfigValues, newConfigValues)
newConfigValues, err = mergeConfigValues(nonRenderedConfig, kotsKinds.ConfigValues, newConfigValues)
if err != nil {
setAppConfigValuesResponse.Error = "failed to create new config"
logger.Error(errors.Wrap(err, setAppConfigValuesResponse.Error))
Expand All @@ -1111,7 +1144,7 @@ func (h *Handler) SetAppConfigValues(w http.ResponseWriter, r *http.Request) {
}
}

newConfig, err := updateConfigObject(templatingKotsKinds.Config, newConfigValues, setAppConfigValuesRequest.Merge)
newConfig, err := updateConfigObject(nonRenderedConfig, newConfigValues, setAppConfigValuesRequest.Merge)
if err != nil {
setAppConfigValuesResponse.Error = "failed to create new config object"
logger.Error(errors.Wrap(err, setAppConfigValuesResponse.Error))
Expand Down Expand Up @@ -1149,9 +1182,9 @@ func (h *Handler) SetAppConfigValues(w http.ResponseWriter, r *http.Request) {
return
}

versionInfo := template.VersionInfoFromInstallationSpec(nextAppSequence, foundApp.IsAirgap, templatingKotsKinds.Installation.Spec) // sequence +1 because the sequence will be incremented on save (and we want the preview to be accurate)
versionInfo := template.VersionInfoFromInstallationSpec(nextAppSequence, foundApp.IsAirgap, kotsKinds.Installation.Spec) // sequence +1 because the sequence will be incremented on save (and we want the preview to be accurate)
appInfo := template.ApplicationInfo{Slug: foundApp.Slug}
renderedConfig, err := kotsconfig.TemplateConfigObjects(newConfig, configValueMap, templatingKotsKinds.License, &templatingKotsKinds.KotsApplication, registryInfo, &versionInfo, &appInfo, templatingKotsKinds.IdentityConfig, util.PodNamespace, true)
renderedConfig, err := kotsconfig.TemplateConfigObjects(newConfig, configValueMap, kotsKinds.License, &kotsKinds.KotsApplication, registryInfo, &versionInfo, &appInfo, kotsKinds.IdentityConfig, util.PodNamespace, true)
if err != nil {
setAppConfigValuesResponse.Error = "failed to render templates"
logger.Error(errors.Wrap(err, setAppConfigValuesResponse.Error))
Expand Down
Loading

0 comments on commit d459ac0

Please sign in to comment.