Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

save config api for upgrade service #4681

Merged
merged 6 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 4 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 @@ -650,7 +651,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 @@ -663,7 +664,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 @@ -736,6 +737,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 Down Expand Up @@ -800,28 +802,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
2 changes: 2 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 Down
2 changes: 2 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 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
65 changes: 22 additions & 43 deletions pkg/preflight/execute.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package preflight

import (
"encoding/json"
"strings"
"sync"
"time"
Expand All @@ -10,45 +9,16 @@ import (
"github.com/replicatedhq/kots/pkg/k8sutil"
"github.com/replicatedhq/kots/pkg/logger"
"github.com/replicatedhq/kots/pkg/preflight/types"
"github.com/replicatedhq/kots/pkg/store"
troubleshootanalyze "github.com/replicatedhq/troubleshoot/pkg/analyze"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
troubleshootcollect "github.com/replicatedhq/troubleshoot/pkg/collect"
"github.com/replicatedhq/troubleshoot/pkg/preflight"
troubleshootpreflight "github.com/replicatedhq/troubleshoot/pkg/preflight"
"go.uber.org/zap"
)

func setPreflightResult(appID string, sequence int64, preflightResults *types.PreflightResults, preflightRunError error) error {
if preflightRunError != nil {
if preflightResults.Errors == nil {
preflightResults.Errors = []*types.PreflightError{}
}
preflightResults.Errors = append(preflightResults.Errors, &types.PreflightError{
Error: preflightRunError.Error(),
IsRBAC: false,
})
}

b, err := json.Marshal(preflightResults)
if err != nil {
return errors.Wrap(err, "failed to marshal preflight results")
}

if err := store.GetStore().SetPreflightResults(appID, sequence, b); err != nil {
return errors.Wrap(err, "failed to set preflight results")
}

return nil
}

// execute will execute the preflights using spec in preflightSpec.
// Execute will Execute the preflights using spec in preflightSpec.
// This spec should be rendered, no template functions remaining
func execute(appID string, sequence int64, preflightSpec *troubleshootv1beta2.Preflight, ignorePermissionErrors bool) (*types.PreflightResults, error) {
logger.Info("executing preflight checks",
zap.String("appID", appID),
zap.Int64("sequence", sequence))

func Execute(preflightSpec *troubleshootv1beta2.Preflight, ignorePermissionErrors bool, setProgress func(progress map[string]interface{}) error, setResults func(results *types.PreflightResults) error) (*types.PreflightResults, error) {
progressChan := make(chan interface{}, 0) // non-zero buffer will result in missed messages
defer close(progressChan)

Expand All @@ -73,26 +43,25 @@ func execute(appID string, sequence int64, preflightSpec *troubleshootv1beta2.Pr
}
}

progress, ok := msg.(preflight.CollectProgress)
collectProgress, ok := msg.(preflight.CollectProgress)
if !ok {
continue
}

// TODO: We need a nice title to display
progressBytes, err := json.Marshal(map[string]interface{}{
"completedCount": progress.CompletedCount,
"totalCount": progress.TotalCount,
"currentName": progress.CurrentName,
"currentStatus": progress.CurrentStatus,
progress := map[string]interface{}{
"completedCount": collectProgress.CompletedCount,
"totalCount": collectProgress.TotalCount,
"currentName": collectProgress.CurrentName,
"currentStatus": collectProgress.CurrentStatus,
"updatedAt": time.Now().Format(time.RFC3339),
})
if err != nil {
continue
}

completeMx.Lock()
if !isComplete {
_ = store.GetStore().SetPreflightProgress(appID, sequence, string(progressBytes))
if err := setProgress(progress); err != nil {
logger.Error(errors.Wrap(err, "failed to set preflight progress"))
}
}
completeMx.Unlock()
}
Expand All @@ -104,7 +73,17 @@ func execute(appID string, sequence int64, preflightSpec *troubleshootv1beta2.Pr
defer completeMx.Unlock()

isComplete = true
if err := setPreflightResult(appID, sequence, uploadPreflightResults, preflightRunError); err != nil {

if preflightRunError != nil {
if uploadPreflightResults.Errors == nil {
uploadPreflightResults.Errors = []*types.PreflightError{}
}
uploadPreflightResults.Errors = append(uploadPreflightResults.Errors, &types.PreflightError{
Error: preflightRunError.Error(),
IsRBAC: false,
})
}
if err := setResults(uploadPreflightResults); err != nil {
logger.Error(errors.Wrap(err, "failed to set preflight results"))
return
}
Expand Down
Loading
Loading