Skip to content

Commit

Permalink
wip: save config api for upgrade service
Browse files Browse the repository at this point in the history
  • Loading branch information
Craig O'Donnell committed Jun 13, 2024
1 parent bb1c47c commit 500848e
Show file tree
Hide file tree
Showing 18 changed files with 805 additions and 161 deletions.
39 changes: 15 additions & 24 deletions pkg/handlers/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
registrytypes "github.com/replicatedhq/kots/pkg/registry/types"
"github.com/replicatedhq/kots/pkg/render"
rendertypes "github.com/replicatedhq/kots/pkg/render/types"
"github.com/replicatedhq/kots/pkg/reporting"
"github.com/replicatedhq/kots/pkg/store"
storetypes "github.com/replicatedhq/kots/pkg/store/types"
"github.com/replicatedhq/kots/pkg/template"
Expand Down Expand Up @@ -611,7 +612,7 @@ func updateAppConfig(updateApp *apptypes.App, sequence int64, configGroups []kot
return updateAppConfigResponse, err
}

requiredItems, requiredItemsTitles := getMissingRequiredConfig(configGroups)
requiredItems, requiredItemsTitles := kotsadmconfig.GetMissingRequiredConfig(configGroups)

// not having all the required items is only a failure for the version that the user intended to edit
if len(requiredItems) > 0 && isPrimaryVersion {
Expand All @@ -624,7 +625,7 @@ func updateAppConfig(updateApp *apptypes.App, sequence int64, configGroups []kot
// so we don't need the complex logic in kots, we can just write
if kotsKinds.ConfigValues != nil {
values := kotsKinds.ConfigValues.Spec.Values
kotsKinds.ConfigValues.Spec.Values = updateAppConfigValues(values, configGroups)
kotsKinds.ConfigValues.Spec.Values = kotsadmconfig.UpdateAppConfigValues(values, configGroups)

configValuesSpec, err := kotsKinds.Marshal("kots.io", "v1beta1", "ConfigValues")
if err != nil {
Expand Down Expand Up @@ -697,6 +698,7 @@ func updateAppConfig(updateApp *apptypes.App, sequence int64, configGroups []kot
Downstreams: downstreams,
RegistrySettings: registrySettings,
Sequence: renderSequence,
ReportingInfo: reporting.GetReportingInfo(app.ID),
})
if err != nil {
cause := errors.Cause(err)
Expand All @@ -708,6 +710,17 @@ func updateAppConfig(updateApp *apptypes.App, sequence int64, configGroups []kot
return updateAppConfigResponse, err
}

updatedInstallation, err := kotsutil.LoadInstallationFromPath(filepath.Join(archiveDir, "upstream", "userdata", "installation.yaml"))
if err != nil {
updateAppConfigResponse.Error = "failed to load installation from path"
return updateAppConfigResponse, errors.Wrap(err, "failed to load installation from path")
}

if err := store.GetStore().UpdateAppVersionInstallationSpec(app.ID, renderSequence, *updatedInstallation); err != nil {
updateAppConfigResponse.Error = "failed to update installation spec"
return updateAppConfigResponse, errors.Wrap(err, "failed to update installation spec")
}

if createNewVersion {
newSequence, err := store.GetStore().CreateAppVersion(updateApp.ID, &sequence, archiveDir, "Config Change", skipPreflights, &version.DownstreamGitOps{}, render.Renderer{})
if err != nil {
Expand Down Expand Up @@ -761,28 +774,6 @@ func updateAppConfig(updateApp *apptypes.App, sequence int64, configGroups []kot
return updateAppConfigResponse, nil
}

func getMissingRequiredConfig(configGroups []kotsv1beta1.ConfigGroup) ([]string, []string) {
requiredItems := make([]string, 0, 0)
requiredItemsTitles := make([]string, 0, 0)
for _, group := range configGroups {
if group.When == "false" {
continue
}
for _, item := range group.Items {
if kotsadmconfig.IsRequiredItem(item) && kotsadmconfig.IsUnsetItem(item) {
requiredItems = append(requiredItems, item.Name)
if item.Title != "" {
requiredItemsTitles = append(requiredItemsTitles, item.Title)
} else {
requiredItemsTitles = append(requiredItemsTitles, item.Name)
}
}
}
}

return requiredItems, requiredItemsTitles
}

func updateAppConfigValues(values map[string]kotsv1beta1.ConfigValue, configGroups []kotsv1beta1.ConfigGroup) map[string]kotsv1beta1.ConfigValue {
for _, group := range configGroups {
for _, item := range group.Items {
Expand Down
17 changes: 17 additions & 0 deletions pkg/handlers/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/replicatedhq/kots/pkg/rbac"
"github.com/replicatedhq/kots/pkg/render"
rendertypes "github.com/replicatedhq/kots/pkg/render/types"
"github.com/replicatedhq/kots/pkg/reporting"
"github.com/replicatedhq/kots/pkg/store"
"github.com/replicatedhq/kots/pkg/util"
"github.com/replicatedhq/kots/pkg/version"
Expand Down Expand Up @@ -461,6 +462,7 @@ func (h *Handler) ConfigureAppIdentityService(w http.ResponseWriter, r *http.Req
Downstreams: downstreams,
RegistrySettings: registrySettings,
Sequence: nextAppSequence,
ReportingInfo: reporting.GetReportingInfo(a.ID),
})
if err != nil {
err = errors.Wrap(err, "failed to render archive directory")
Expand All @@ -469,6 +471,21 @@ func (h *Handler) ConfigureAppIdentityService(w http.ResponseWriter, r *http.Req
return
}

updatedInstallation, err := kotsutil.LoadInstallationFromPath(filepath.Join(archiveDir, "upstream", "userdata", "installation.yaml"))
if err != nil {
err = errors.Wrap(err, "failed to load installation from path")
logger.Error(err)
w.WriteHeader(http.StatusInternalServerError)
return
}

if err := store.GetStore().UpdateAppVersionInstallationSpec(a.ID, nextAppSequence, *updatedInstallation); err != nil {
err = errors.Wrap(err, "failed to update app version installation spec")
logger.Error(err)
w.WriteHeader(http.StatusInternalServerError)
return
}

newSequence, err := store.GetStore().CreateAppVersion(a.ID, &latestSequence, archiveDir, "Identity Service", false, &version.DownstreamGitOps{}, render.Renderer{})
if err != nil {
err = errors.Wrap(err, "failed to create an app version")
Expand Down
17 changes: 17 additions & 0 deletions pkg/handlers/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/replicatedhq/kots/pkg/preflight"
"github.com/replicatedhq/kots/pkg/render"
rendertypes "github.com/replicatedhq/kots/pkg/render/types"
"github.com/replicatedhq/kots/pkg/reporting"
"github.com/replicatedhq/kots/pkg/store"
storetypes "github.com/replicatedhq/kots/pkg/store/types"
"github.com/replicatedhq/kots/pkg/util"
Expand Down Expand Up @@ -165,6 +166,7 @@ func (h *Handler) UploadExistingApp(w http.ResponseWriter, r *http.Request) {
Downstreams: downstreams,
RegistrySettings: registrySettings,
Sequence: nextAppSequence,
ReportingInfo: reporting.GetReportingInfo(a.ID),
})
if err != nil {
cause := errors.Cause(err)
Expand All @@ -180,6 +182,21 @@ func (h *Handler) UploadExistingApp(w http.ResponseWriter, r *http.Request) {
return
}

updatedInstallation, err := kotsutil.LoadInstallationFromPath(filepath.Join(archiveDir, "upstream", "userdata", "installation.yaml"))
if err != nil {
uploadResponse.Error = util.StrPointer("failed to load installation from path")
logger.Error(errors.Wrap(err, *uploadResponse.Error))
JSON(w, http.StatusInternalServerError, uploadResponse)
return
}

if err := store.GetStore().UpdateAppVersionInstallationSpec(a.ID, nextAppSequence, *updatedInstallation); err != nil {
uploadResponse.Error = util.StrPointer("failed to update app version installation spec")
logger.Error(errors.Wrap(err, *uploadResponse.Error))
JSON(w, http.StatusInternalServerError, uploadResponse)
return
}

baseSequence, err := store.GetStore().GetAppVersionBaseSequence(a.ID, kotsKinds.Installation.Spec.VersionLabel)
if err != nil {
uploadResponse.Error = util.StrPointer("failed to app version base sequence")
Expand Down
75 changes: 75 additions & 0 deletions pkg/kotsadmconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ package kotsadmconfig

import (
"context"
"encoding/base64"
"fmt"
"os"
"strconv"

"github.com/pkg/errors"
kotsconfig "github.com/replicatedhq/kots/pkg/config"
"github.com/replicatedhq/kots/pkg/crypto"
"github.com/replicatedhq/kots/pkg/k8sutil"
"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"
"github.com/replicatedhq/kots/pkg/util"
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
"github.com/replicatedhq/kotskinds/multitype"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -91,6 +96,76 @@ func NeedsConfiguration(appSlug string, sequence int64, isAirgap bool, kotsKinds
return false, nil
}

func GetMissingRequiredConfig(configGroups []kotsv1beta1.ConfigGroup) ([]string, []string) {
requiredItems := make([]string, 0, 0)
requiredItemsTitles := make([]string, 0, 0)
for _, group := range configGroups {
if group.When == "false" {
continue
}
for _, item := range group.Items {
if IsRequiredItem(item) && IsUnsetItem(item) {
requiredItems = append(requiredItems, item.Name)
if item.Title != "" {
requiredItemsTitles = append(requiredItemsTitles, item.Title)
} else {
requiredItemsTitles = append(requiredItemsTitles, item.Name)
}
}
}
}

return requiredItems, requiredItemsTitles
}

func UpdateAppConfigValues(values map[string]kotsv1beta1.ConfigValue, configGroups []kotsv1beta1.ConfigGroup) map[string]kotsv1beta1.ConfigValue {
for _, group := range configGroups {
for _, item := range group.Items {
if item.Type == "file" {
v := values[item.Name]
v.Filename = item.Filename
values[item.Name] = v
}
if item.Value.Type == multitype.Bool {
updatedValue := item.Value.BoolVal
v := values[item.Name]
v.Value = strconv.FormatBool(updatedValue)
values[item.Name] = v
} else if item.Value.Type == multitype.String {
updatedValue := item.Value.String()
if item.Type == "password" {
// encrypt using the key
// if the decryption succeeds, don't encrypt again
_, err := util.DecryptConfigValue(updatedValue)
if err != nil {
updatedValue = base64.StdEncoding.EncodeToString(crypto.Encrypt([]byte(updatedValue)))
}
}

v := values[item.Name]
v.Value = updatedValue
values[item.Name] = v
}
for _, repeatableValues := range item.ValuesByGroup {
// clear out all variadic values for this group first
for name, value := range values {
if value.RepeatableItem == item.Name {
delete(values, name)
}
}
// add variadic groups back in declaratively
for itemName, valueItem := range repeatableValues {
v := values[itemName]
v.Value = fmt.Sprintf("%v", valueItem)
v.RepeatableItem = item.Name
values[itemName] = v
}
}
}
}
return values
}

func ReadConfigValuesFromInClusterSecret() (string, error) {
log := logger.NewCLILogger(os.Stdout)

Expand Down
7 changes: 5 additions & 2 deletions pkg/kotsadmlicense/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/replicatedhq/kots/pkg/preflight"
"github.com/replicatedhq/kots/pkg/render"
"github.com/replicatedhq/kots/pkg/replicatedapp"
"github.com/replicatedhq/kots/pkg/reporting"
"github.com/replicatedhq/kots/pkg/store"
"github.com/replicatedhq/kots/pkg/version"
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
Expand Down Expand Up @@ -84,7 +85,8 @@ func Sync(a *apptypes.App, licenseString string, failOnVersionCreate bool) (*kot
if updatedLicense.Spec.ChannelID != currentLicense.Spec.ChannelID {
channelChanged = true
}
newSequence, err := store.GetStore().UpdateAppLicense(a.ID, latestSequence, archiveDir, updatedLicense, licenseString, channelChanged, failOnVersionCreate, &version.DownstreamGitOps{}, &render.Renderer{})
reportingInfo := reporting.GetReportingInfo(a.ID)
newSequence, err := store.GetStore().UpdateAppLicense(a.ID, latestSequence, archiveDir, updatedLicense, licenseString, channelChanged, failOnVersionCreate, &version.DownstreamGitOps{}, &render.Renderer{}, reportingInfo)
if err != nil {
return nil, false, errors.Wrap(err, "failed to update license")
}
Expand Down Expand Up @@ -190,7 +192,8 @@ func Change(a *apptypes.App, newLicenseString string) (*kotsv1beta1.License, err
if newLicense.Spec.ChannelID != currentLicense.Spec.ChannelID {
channelChanged = true
}
newSequence, err := store.GetStore().UpdateAppLicense(a.ID, latestSequence, archiveDir, newLicense, newLicenseString, channelChanged, true, &version.DownstreamGitOps{}, &render.Renderer{})
reportingInfo := reporting.GetReportingInfo(a.ID)
newSequence, err := store.GetStore().UpdateAppLicense(a.ID, latestSequence, archiveDir, newLicense, newLicenseString, channelChanged, true, &version.DownstreamGitOps{}, &render.Renderer{}, reportingInfo)
if err != nil {
return nil, errors.Wrap(err, "failed to update license")
}
Expand Down
9 changes: 9 additions & 0 deletions pkg/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,15 @@ func RewriteImages(appID string, sequence int64, hostname string, username strin
return "", errors.Wrap(err, "failed to rewrite images")
}

updatedInstallation, err := kotsutil.LoadInstallationFromPath(filepath.Join(appDir, "upstream", "userdata", "installation.yaml"))
if err != nil {
return "", errors.Wrap(err, "failed to load installation from path")
}

if err := store.GetStore().UpdateAppVersionInstallationSpec(a.ID, nextAppSequence, *updatedInstallation); err != nil {
return "", errors.Wrap(err, "failed to update installation spec")
}

return appDir, nil
}

Expand Down
3 changes: 1 addition & 2 deletions pkg/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/replicatedhq/kots/pkg/kotsutil"
registrytypes "github.com/replicatedhq/kots/pkg/registry/types"
types "github.com/replicatedhq/kots/pkg/render/types"
"github.com/replicatedhq/kots/pkg/reporting"
"github.com/replicatedhq/kots/pkg/rewrite"
"github.com/replicatedhq/kots/pkg/template"
"github.com/replicatedhq/kots/pkg/util"
Expand Down Expand Up @@ -145,7 +144,7 @@ func RenderDir(opts types.RenderDirOptions) error {
AppSlug: opts.App.Slug,
IsGitOps: opts.App.IsGitOps,
AppSequence: opts.Sequence,
ReportingInfo: reporting.GetReportingInfo(opts.App.ID),
ReportingInfo: opts.ReportingInfo,
RegistrySettings: opts.RegistrySettings,

// TODO: pass in as arguments if this is ever called from CLI
Expand Down
2 changes: 2 additions & 0 deletions pkg/render/types/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package types

import (
downstreamtypes "github.com/replicatedhq/kots/pkg/api/downstream/types"
reportingtypes "github.com/replicatedhq/kots/pkg/api/reporting/types"
apptypes "github.com/replicatedhq/kots/pkg/app/types"
"github.com/replicatedhq/kots/pkg/kotsutil"
registrytypes "github.com/replicatedhq/kots/pkg/registry/types"
Expand All @@ -23,6 +24,7 @@ type RenderDirOptions struct {
Downstreams []downstreamtypes.Downstream
RegistrySettings registrytypes.RegistrySettings
Sequence int64
ReportingInfo *reportingtypes.ReportingInfo
}

type Renderer interface {
Expand Down
5 changes: 0 additions & 5 deletions pkg/rewrite/rewrite.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"github.com/replicatedhq/kots/pkg/midstream"
registrytypes "github.com/replicatedhq/kots/pkg/registry/types"
"github.com/replicatedhq/kots/pkg/rendered"
"github.com/replicatedhq/kots/pkg/store"
"github.com/replicatedhq/kots/pkg/upstream"
upstreamtypes "github.com/replicatedhq/kots/pkg/upstream/types"
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
Expand Down Expand Up @@ -311,10 +310,6 @@ func Rewrite(rewriteOptions RewriteOptions) error {
return errors.Wrap(err, "failed to write downstreams")
}

if err := store.GetStore().UpdateAppVersionInstallationSpec(rewriteOptions.AppID, rewriteOptions.AppSequence, renderedKotsKinds.Installation); err != nil {
return errors.Wrap(err, "failed to update installation spec")
}

if err := rendered.WriteRenderedApp(&rendered.WriteOptions{
BaseDir: u.GetBaseDir(writeUpstreamOptions),
OverlaysDir: u.GetOverlaysDir(writeUpstreamOptions),
Expand Down
Loading

0 comments on commit 500848e

Please sign in to comment.