From b4deb576da3743df23027b5e9297b7915bef55bd Mon Sep 17 00:00:00 2001 From: Craig O'Donnell Date: Fri, 14 Jun 2024 17:08:27 -0400 Subject: [PATCH] save config api for upgrade service (#4681) * save config api for upgrade service * update setProgress and setResults * remove TODO * Update pkg/upgradeservice/preflight/preflight.go Co-authored-by: Salah Al Saleh * clean up result and progress funcs * remove run error from setResult func --------- Co-authored-by: Salah Al Saleh --- pkg/handlers/config.go | 28 +-- pkg/handlers/identity.go | 2 + pkg/handlers/upload.go | 2 + pkg/kotsadmconfig/config.go | 75 ++++++ pkg/kotsadmlicense/license.go | 7 +- pkg/preflight/execute.go | 65 ++--- pkg/preflight/preflight.go | 55 ++++- pkg/render/render.go | 3 +- pkg/render/types/interface.go | 2 + pkg/reporting/app_online.go | 14 +- pkg/rewrite/rewrite.go | 5 - pkg/store/kotsstore/license_store.go | 8 +- pkg/store/kotsstore/version_store.go | 20 -- pkg/store/mock/mock.go | 277 ++++++++++------------ pkg/store/store_interface.go | 4 +- pkg/tests/renderdir/renderdir_test.go | 8 - pkg/upgradeservice/handlers/config.go | 166 +++++++++++++ pkg/upgradeservice/handlers/handlers.go | 1 + pkg/upgradeservice/handlers/interface.go | 1 + pkg/upgradeservice/preflight/preflight.go | 197 +++++++++++++++ 20 files changed, 669 insertions(+), 271 deletions(-) create mode 100644 pkg/upgradeservice/preflight/preflight.go diff --git a/pkg/handlers/config.go b/pkg/handlers/config.go index b064b18d04..2938247c98 100644 --- a/pkg/handlers/config.go +++ b/pkg/handlers/config.go @@ -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" @@ -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 { @@ -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 { @@ -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) @@ -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 { diff --git a/pkg/handlers/identity.go b/pkg/handlers/identity.go index a309ba3aa8..a1eec9f571 100644 --- a/pkg/handlers/identity.go +++ b/pkg/handlers/identity.go @@ -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" @@ -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") diff --git a/pkg/handlers/upload.go b/pkg/handlers/upload.go index fcd2a14ba9..2f0dd5ba21 100644 --- a/pkg/handlers/upload.go +++ b/pkg/handlers/upload.go @@ -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" @@ -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) diff --git a/pkg/kotsadmconfig/config.go b/pkg/kotsadmconfig/config.go index e887f5cb19..3b335ffa38 100644 --- a/pkg/kotsadmconfig/config.go +++ b/pkg/kotsadmconfig/config.go @@ -2,10 +2,14 @@ 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" @@ -13,6 +17,7 @@ import ( "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" ) @@ -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) diff --git a/pkg/kotsadmlicense/license.go b/pkg/kotsadmlicense/license.go index 79a41f3314..c5cf7581bb 100644 --- a/pkg/kotsadmlicense/license.go +++ b/pkg/kotsadmlicense/license.go @@ -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" @@ -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") } @@ -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") } diff --git a/pkg/preflight/execute.go b/pkg/preflight/execute.go index 4b73d70648..e54132945d 100644 --- a/pkg/preflight/execute.go +++ b/pkg/preflight/execute.go @@ -1,7 +1,6 @@ package preflight import ( - "encoding/json" "strings" "sync" "time" @@ -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) @@ -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() } @@ -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 } diff --git a/pkg/preflight/preflight.go b/pkg/preflight/preflight.go index d32e69a03c..54650628c1 100644 --- a/pkg/preflight/preflight.go +++ b/pkg/preflight/preflight.go @@ -3,6 +3,7 @@ package preflight import ( "bytes" "context" + "encoding/json" "fmt" "os" "path/filepath" @@ -90,7 +91,7 @@ func Run(appID string, appSlug string, sequence int64, isAirgap bool, archiveDir preflight = troubleshootpreflight.ConcatPreflightSpec(preflight, &v) } - injectDefaultPreflights(preflight, kotsKinds, registrySettings) + InjectDefaultPreflights(preflight, kotsKinds, registrySettings) numAnalyzers := 0 for _, analyzer := range preflight.Spec.Analyzers { @@ -125,7 +126,7 @@ func Run(appID string, appSlug string, sequence int64, isAirgap bool, archiveDir return errors.Wrap(err, "failed to load rendered preflight") } - injectDefaultPreflights(preflight, kotsKinds, registrySettings) + InjectDefaultPreflights(preflight, kotsKinds, registrySettings) numAnalyzers := 0 for _, analyzer := range preflight.Spec.Analyzers { @@ -141,8 +142,15 @@ func Run(appID string, appSlug string, sequence int64, isAirgap bool, archiveDir var preflightErr error defer func() { if preflightErr != nil { - err := setPreflightResult(appID, sequence, &types.PreflightResults{}, preflightErr) - if err != nil { + preflightResults := &types.PreflightResults{ + Errors: []*types.PreflightError{ + &types.PreflightError{ + Error: preflightErr.Error(), + IsRBAC: false, + }, + }, + } + if err := setPreflightResults(appID, sequence, preflightResults); err != nil { logger.Error(errors.Wrap(err, "failed to set preflight results")) return } @@ -170,8 +178,17 @@ func Run(appID string, appSlug string, sequence int64, isAirgap bool, archiveDir preflight.Spec.Collectors = collectors go func() { - logger.Info("preflight checks beginning") - uploadPreflightResults, err := execute(appID, sequence, preflight, ignoreRBAC) + logger.Info("preflight checks beginning", + zap.String("appID", appID), + zap.Int64("sequence", sequence)) + + setProgress := func(progress map[string]interface{}) error { + return setPreflightProgress(appID, sequence, progress) + } + setResults := func(results *types.PreflightResults) error { + return setPreflightResults(appID, sequence, results) + } + uploadPreflightResults, err := Execute(preflight, ignoreRBAC, setProgress, setResults) if err != nil { logger.Error(errors.Wrap(err, "failed to run preflight checks")) return @@ -239,6 +256,28 @@ func Run(appID string, appSlug string, sequence int64, isAirgap bool, archiveDir return nil } +func setPreflightProgress(appID string, sequence int64, progress map[string]interface{}) error { + b, err := json.Marshal(progress) + if err != nil { + return errors.Wrap(err, "failed to marshal preflight progress") + } + if err := store.GetStore().SetPreflightProgress(appID, sequence, string(b)); err != nil { + return errors.Wrap(err, "failed to set preflight progress") + } + return nil +} + +func setPreflightResults(appID string, sequence int64, preflightResults *types.PreflightResults) error { + 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 +} + // GetPreflightCheckState returns the state of a single preflight check result func GetPreflightCheckState(p *troubleshootpreflight.UploadPreflightResult) string { if p == nil { @@ -371,7 +410,7 @@ func CreateRenderedSpec(app *apptypes.App, sequence int64, origin string, inClus return errors.Wrap(err, "failed to get registry settings for app") } - injectDefaultPreflights(builtPreflight, kotsKinds, registrySettings) + InjectDefaultPreflights(builtPreflight, kotsKinds, registrySettings) collectors, err := registry.UpdateCollectorSpecsWithRegistryData(builtPreflight.Spec.Collectors, registrySettings, kotsKinds.Installation, kotsKinds.License, &kotsKinds.KotsApplication) if err != nil { @@ -448,7 +487,7 @@ func CreateRenderedSpec(app *apptypes.App, sequence int64, origin string, inClus return nil } -func injectDefaultPreflights(preflight *troubleshootv1beta2.Preflight, kotskinds *kotsutil.KotsKinds, registrySettings registrytypes.RegistrySettings) { +func InjectDefaultPreflights(preflight *troubleshootv1beta2.Preflight, kotskinds *kotsutil.KotsKinds, registrySettings registrytypes.RegistrySettings) { if registrySettings.IsValid() && registrySettings.IsReadOnly { // Get images from Installation.KnownImages, see UpdateCollectorSpecsWithRegistryData images := []string{} diff --git a/pkg/render/render.go b/pkg/render/render.go index d63e10ae14..a5bb8cc3d4 100644 --- a/pkg/render/render.go +++ b/pkg/render/render.go @@ -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" @@ -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 diff --git a/pkg/render/types/interface.go b/pkg/render/types/interface.go index 8bc5d85808..a56ce9fb99 100644 --- a/pkg/render/types/interface.go +++ b/pkg/render/types/interface.go @@ -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" @@ -23,6 +24,7 @@ type RenderDirOptions struct { Downstreams []downstreamtypes.Downstream RegistrySettings registrytypes.RegistrySettings Sequence int64 + ReportingInfo *reportingtypes.ReportingInfo } type Renderer interface { diff --git a/pkg/reporting/app_online.go b/pkg/reporting/app_online.go index 32b40bfb66..0686edac25 100644 --- a/pkg/reporting/app_online.go +++ b/pkg/reporting/app_online.go @@ -8,8 +8,10 @@ import ( "time" "github.com/pkg/errors" + "github.com/replicatedhq/kots/pkg/api/reporting/types" "github.com/replicatedhq/kots/pkg/store" "github.com/replicatedhq/kots/pkg/util" + kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1" ) var onlineAppInfoMtx sync.Mutex @@ -35,11 +37,20 @@ func (r *OnlineReporter) SubmitAppInfo(appID string) error { return errors.Wrap(err, "failed to get license for app") } + reportingInfo := GetReportingInfo(a.ID) + + if err := SendOnlineAppInfo(license, reportingInfo); err != nil { + return errors.Wrap(err, "failed to send online app info") + } + + return nil +} + +func SendOnlineAppInfo(license *kotsv1beta1.License, reportingInfo *types.ReportingInfo) error { endpoint := license.Spec.Endpoint if !canReport(endpoint) { return nil } - url := fmt.Sprintf("%s/kots_metrics/license_instance/info", endpoint) postReq, err := util.NewRequest("POST", url, nil) @@ -49,7 +60,6 @@ func (r *OnlineReporter) SubmitAppInfo(appID string) error { postReq.Header.Set("Authorization", fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", license.Spec.LicenseID, license.Spec.LicenseID))))) postReq.Header.Set("Content-Type", "application/json") - reportingInfo := GetReportingInfo(a.ID) InjectReportingInfoHeaders(postReq, reportingInfo) resp, err := http.DefaultClient.Do(postReq) diff --git a/pkg/rewrite/rewrite.go b/pkg/rewrite/rewrite.go index 95dde7e9cd..edfaceeb27 100644 --- a/pkg/rewrite/rewrite.go +++ b/pkg/rewrite/rewrite.go @@ -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" @@ -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), diff --git a/pkg/store/kotsstore/license_store.go b/pkg/store/kotsstore/license_store.go index bcf32fb9fc..56429d16cd 100644 --- a/pkg/store/kotsstore/license_store.go +++ b/pkg/store/kotsstore/license_store.go @@ -8,6 +8,7 @@ import ( "time" "github.com/pkg/errors" + reportingtypes "github.com/replicatedhq/kots/pkg/api/reporting/types" gitopstypes "github.com/replicatedhq/kots/pkg/gitops/types" "github.com/replicatedhq/kots/pkg/logger" "github.com/replicatedhq/kots/pkg/persistence" @@ -106,7 +107,7 @@ func (s *KOTSStore) GetAllAppLicenses() ([]*kotsv1beta1.License, error) { return licenses, nil } -func (s *KOTSStore) UpdateAppLicense(appID string, baseSequence int64, archiveDir string, newLicense *kotsv1beta1.License, originalLicenseData string, channelChanged bool, failOnVersionCreate bool, gitops gitopstypes.DownstreamGitOps, renderer rendertypes.Renderer) (int64, error) { +func (s *KOTSStore) UpdateAppLicense(appID string, baseSequence int64, archiveDir string, newLicense *kotsv1beta1.License, originalLicenseData string, channelChanged bool, failOnVersionCreate bool, gitops gitopstypes.DownstreamGitOps, renderer rendertypes.Renderer, reportingInfo *reportingtypes.ReportingInfo) (int64, error) { db := persistence.MustGetDBSession() statements := []gorqlite.ParameterizedStatement{} @@ -127,7 +128,7 @@ func (s *KOTSStore) UpdateAppLicense(appID string, baseSequence int64, archiveDi Arguments: []interface{}{originalLicenseData, time.Now().Unix(), channelChanged, appID}, }) - appVersionStatements, newSeq, err := s.createNewVersionForLicenseChangeStatements(appID, baseSequence, archiveDir, gitops, renderer) + appVersionStatements, newSeq, err := s.createNewVersionForLicenseChangeStatements(appID, baseSequence, archiveDir, gitops, renderer, reportingInfo) if err != nil { // ignore error here to prevent a failure to render the current version // preventing the end-user from updating the application @@ -164,7 +165,7 @@ func (s *KOTSStore) UpdateAppLicenseSyncNow(appID string) error { return nil } -func (s *KOTSStore) createNewVersionForLicenseChangeStatements(appID string, baseSequence int64, archiveDir string, gitops gitopstypes.DownstreamGitOps, renderer rendertypes.Renderer) ([]gorqlite.ParameterizedStatement, int64, error) { +func (s *KOTSStore) createNewVersionForLicenseChangeStatements(appID string, baseSequence int64, archiveDir string, gitops gitopstypes.DownstreamGitOps, renderer rendertypes.Renderer, reportingInfo *reportingtypes.ReportingInfo) ([]gorqlite.ParameterizedStatement, int64, error) { registrySettings, err := s.GetRegistryDetailsForApp(appID) if err != nil { return nil, int64(0), errors.Wrap(err, "failed to get registry settings for app") @@ -191,6 +192,7 @@ func (s *KOTSStore) createNewVersionForLicenseChangeStatements(appID string, bas Downstreams: downstreams, RegistrySettings: registrySettings, Sequence: nextAppSequence, + ReportingInfo: reportingInfo, }); err != nil { return nil, int64(0), errors.Wrap(err, "failed to render new version") } diff --git a/pkg/store/kotsstore/version_store.go b/pkg/store/kotsstore/version_store.go index 081f38dac5..adfc0b5339 100644 --- a/pkg/store/kotsstore/version_store.go +++ b/pkg/store/kotsstore/version_store.go @@ -1,7 +1,6 @@ package kotsstore import ( - "bytes" "encoding/base64" "encoding/json" "fmt" @@ -38,7 +37,6 @@ import ( "github.com/rqlite/gorqlite" velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - serializer "k8s.io/apimachinery/pkg/runtime/serializer/json" "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/application/api/v1beta1" ) @@ -977,24 +975,6 @@ func (s *KOTSStore) UpdateNextAppVersionDiffSummary(appID string, baseSequence i return nil } -func (s *KOTSStore) UpdateAppVersionInstallationSpec(appID string, sequence int64, installation kotsv1beta1.Installation) error { - ser := serializer.NewYAMLSerializer(serializer.DefaultMetaFactory, scheme.Scheme, scheme.Scheme) - var b bytes.Buffer - if err := ser.Encode(&installation, &b); err != nil { - return errors.Wrap(err, "failed to encode installation") - } - - db := persistence.MustGetDBSession() - wr, err := db.WriteOneParameterized(gorqlite.ParameterizedStatement{ - Query: `UPDATE app_version SET kots_installation_spec = ? WHERE app_id = ? AND sequence = ?`, - Arguments: []interface{}{b.String(), appID, sequence}, - }) - if err != nil { - return fmt.Errorf("failed to write: %v: %v", err, wr.Err) - } - return nil -} - func (s *KOTSStore) GetNextAppSequence(appID string) (int64, error) { db := persistence.MustGetDBSession() diff --git a/pkg/store/mock/mock.go b/pkg/store/mock/mock.go index 7f8feb9470..bbad145a29 100644 --- a/pkg/store/mock/mock.go +++ b/pkg/store/mock/mock.go @@ -13,20 +13,21 @@ import ( v1beta1 "github.com/replicatedhq/embedded-cluster-kinds/apis/v1beta1" types "github.com/replicatedhq/kots/pkg/airgap/types" types0 "github.com/replicatedhq/kots/pkg/api/downstream/types" - types1 "github.com/replicatedhq/kots/pkg/api/version/types" - types2 "github.com/replicatedhq/kots/pkg/app/types" - types3 "github.com/replicatedhq/kots/pkg/appstate/types" - types4 "github.com/replicatedhq/kots/pkg/gitops/types" - types5 "github.com/replicatedhq/kots/pkg/kotsadmsnapshot/types" - types6 "github.com/replicatedhq/kots/pkg/online/types" - types7 "github.com/replicatedhq/kots/pkg/preflight/types" - types8 "github.com/replicatedhq/kots/pkg/registry/types" - types9 "github.com/replicatedhq/kots/pkg/render/types" - types10 "github.com/replicatedhq/kots/pkg/session/types" - types11 "github.com/replicatedhq/kots/pkg/store/types" - types12 "github.com/replicatedhq/kots/pkg/supportbundle/types" - types13 "github.com/replicatedhq/kots/pkg/upstream/types" - types14 "github.com/replicatedhq/kots/pkg/user/types" + types1 "github.com/replicatedhq/kots/pkg/api/reporting/types" + types2 "github.com/replicatedhq/kots/pkg/api/version/types" + types3 "github.com/replicatedhq/kots/pkg/app/types" + types4 "github.com/replicatedhq/kots/pkg/appstate/types" + types5 "github.com/replicatedhq/kots/pkg/gitops/types" + types6 "github.com/replicatedhq/kots/pkg/kotsadmsnapshot/types" + types7 "github.com/replicatedhq/kots/pkg/online/types" + types8 "github.com/replicatedhq/kots/pkg/preflight/types" + types9 "github.com/replicatedhq/kots/pkg/registry/types" + types10 "github.com/replicatedhq/kots/pkg/render/types" + types11 "github.com/replicatedhq/kots/pkg/session/types" + types12 "github.com/replicatedhq/kots/pkg/store/types" + types13 "github.com/replicatedhq/kots/pkg/supportbundle/types" + types14 "github.com/replicatedhq/kots/pkg/upstream/types" + types15 "github.com/replicatedhq/kots/pkg/user/types" v1beta10 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1" redact "github.com/replicatedhq/troubleshoot/pkg/redact" ) @@ -97,10 +98,10 @@ func (mr *MockStoreMockRecorder) AddDownstreamVersionsDetails(appID, clusterID, } // CreateApp mocks base method. -func (m *MockStore) CreateApp(name, upstreamURI, licenseData string, isAirgapEnabled, skipImagePush, registryIsReadOnly bool) (*types2.App, error) { +func (m *MockStore) CreateApp(name, upstreamURI, licenseData string, isAirgapEnabled, skipImagePush, registryIsReadOnly bool) (*types3.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateApp", name, upstreamURI, licenseData, isAirgapEnabled, skipImagePush, registryIsReadOnly) - ret0, _ := ret[0].(*types2.App) + ret0, _ := ret[0].(*types3.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -112,7 +113,7 @@ func (mr *MockStoreMockRecorder) CreateApp(name, upstreamURI, licenseData, isAir } // CreateAppVersion mocks base method. -func (m *MockStore) CreateAppVersion(appID string, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types4.DownstreamGitOps, renderer types9.Renderer) (int64, error) { +func (m *MockStore) CreateAppVersion(appID string, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types5.DownstreamGitOps, renderer types10.Renderer) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateAppVersion", appID, baseSequence, filesInDir, source, skipPreflights, gitops, renderer) ret0, _ := ret[0].(int64) @@ -141,7 +142,7 @@ func (mr *MockStoreMockRecorder) CreateAppVersionArchive(appID, sequence, archiv } // CreateInProgressSupportBundle mocks base method. -func (m *MockStore) CreateInProgressSupportBundle(supportBundle *types12.SupportBundle) error { +func (m *MockStore) CreateInProgressSupportBundle(supportBundle *types13.SupportBundle) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateInProgressSupportBundle", supportBundle) ret0, _ := ret[0].(error) @@ -185,7 +186,7 @@ func (mr *MockStoreMockRecorder) CreateNewCluster(userID, isAllUsers, title, tok } // CreatePendingDownloadAppVersion mocks base method. -func (m *MockStore) CreatePendingDownloadAppVersion(appID string, update types13.Update, kotsApplication *v1beta10.Application, license *v1beta10.License) (int64, error) { +func (m *MockStore) CreatePendingDownloadAppVersion(appID string, update types14.Update, kotsApplication *v1beta10.Application, license *v1beta10.License) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreatePendingDownloadAppVersion", appID, update, kotsApplication, license) ret0, _ := ret[0].(int64) @@ -228,10 +229,10 @@ func (mr *MockStoreMockRecorder) CreateScheduledSnapshot(snapshotID, appID, time } // CreateSession mocks base method. -func (m *MockStore) CreateSession(user *types14.User, issuedAt, expiresAt time.Time, roles []string) (*types10.Session, error) { +func (m *MockStore) CreateSession(user *types15.User, issuedAt, expiresAt time.Time, roles []string) (*types11.Session, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateSession", user, issuedAt, expiresAt, roles) - ret0, _ := ret[0].(*types10.Session) + ret0, _ := ret[0].(*types11.Session) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -243,10 +244,10 @@ func (mr *MockStoreMockRecorder) CreateSession(user, issuedAt, expiresAt, roles } // CreateSupportBundle mocks base method. -func (m *MockStore) CreateSupportBundle(bundleID, appID, archivePath string, marshalledTree []byte) (*types12.SupportBundle, error) { +func (m *MockStore) CreateSupportBundle(bundleID, appID, archivePath string, marshalledTree []byte) (*types13.SupportBundle, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateSupportBundle", bundleID, appID, archivePath, marshalledTree) - ret0, _ := ret[0].(*types12.SupportBundle) + ret0, _ := ret[0].(*types13.SupportBundle) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -415,10 +416,10 @@ func (mr *MockStoreMockRecorder) GetAllAppLicenses() *gomock.Call { } // GetApp mocks base method. -func (m *MockStore) GetApp(appID string) (*types2.App, error) { +func (m *MockStore) GetApp(appID string) (*types3.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetApp", appID) - ret0, _ := ret[0].(*types2.App) + ret0, _ := ret[0].(*types3.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -430,10 +431,10 @@ func (mr *MockStoreMockRecorder) GetApp(appID interface{}) *gomock.Call { } // GetAppFromSlug mocks base method. -func (m *MockStore) GetAppFromSlug(slug string) (*types2.App, error) { +func (m *MockStore) GetAppFromSlug(slug string) (*types3.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAppFromSlug", slug) - ret0, _ := ret[0].(*types2.App) + ret0, _ := ret[0].(*types3.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -475,10 +476,10 @@ func (mr *MockStoreMockRecorder) GetAppIDsFromRegistry(hostname interface{}) *go } // GetAppStatus mocks base method. -func (m *MockStore) GetAppStatus(appID string) (*types3.AppStatus, error) { +func (m *MockStore) GetAppStatus(appID string) (*types4.AppStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAppStatus", appID) - ret0, _ := ret[0].(*types3.AppStatus) + ret0, _ := ret[0].(*types4.AppStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -490,10 +491,10 @@ func (mr *MockStoreMockRecorder) GetAppStatus(appID interface{}) *gomock.Call { } // GetAppVersion mocks base method. -func (m *MockStore) GetAppVersion(appID string, sequence int64) (*types1.AppVersion, error) { +func (m *MockStore) GetAppVersion(appID string, sequence int64) (*types2.AppVersion, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAppVersion", appID, sequence) - ret0, _ := ret[0].(*types1.AppVersion) + ret0, _ := ret[0].(*types2.AppVersion) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -700,10 +701,10 @@ func (mr *MockStoreMockRecorder) GetDownstreamVersionSource(appID, sequence inte } // GetDownstreamVersionStatus mocks base method. -func (m *MockStore) GetDownstreamVersionStatus(appID string, sequence int64) (types11.DownstreamVersionStatus, error) { +func (m *MockStore) GetDownstreamVersionStatus(appID string, sequence int64) (types12.DownstreamVersionStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetDownstreamVersionStatus", appID, sequence) - ret0, _ := ret[0].(types11.DownstreamVersionStatus) + ret0, _ := ret[0].(types12.DownstreamVersionStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -972,10 +973,10 @@ func (mr *MockStoreMockRecorder) GetPendingAirgapUploadApp() *gomock.Call { } // GetPendingInstallationStatus mocks base method. -func (m *MockStore) GetPendingInstallationStatus() (*types6.InstallStatus, error) { +func (m *MockStore) GetPendingInstallationStatus() (*types7.InstallStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPendingInstallationStatus") - ret0, _ := ret[0].(*types6.InstallStatus) + ret0, _ := ret[0].(*types7.InstallStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1002,10 +1003,10 @@ func (mr *MockStoreMockRecorder) GetPreflightProgress(appID, sequence interface{ } // GetPreflightResults mocks base method. -func (m *MockStore) GetPreflightResults(appID string, sequence int64) (*types7.PreflightResult, error) { +func (m *MockStore) GetPreflightResults(appID string, sequence int64) (*types8.PreflightResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPreflightResults", appID, sequence) - ret0, _ := ret[0].(*types7.PreflightResult) + ret0, _ := ret[0].(*types8.PreflightResult) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1062,10 +1063,10 @@ func (mr *MockStoreMockRecorder) GetRedactions(bundleID interface{}) *gomock.Cal } // GetRegistryDetailsForApp mocks base method. -func (m *MockStore) GetRegistryDetailsForApp(appID string) (types8.RegistrySettings, error) { +func (m *MockStore) GetRegistryDetailsForApp(appID string) (types9.RegistrySettings, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetRegistryDetailsForApp", appID) - ret0, _ := ret[0].(types8.RegistrySettings) + ret0, _ := ret[0].(types9.RegistrySettings) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1077,10 +1078,10 @@ func (mr *MockStoreMockRecorder) GetRegistryDetailsForApp(appID interface{}) *go } // GetSession mocks base method. -func (m *MockStore) GetSession(sessionID string) (*types10.Session, error) { +func (m *MockStore) GetSession(sessionID string) (*types11.Session, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSession", sessionID) - ret0, _ := ret[0].(*types10.Session) + ret0, _ := ret[0].(*types11.Session) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1107,10 +1108,10 @@ func (mr *MockStoreMockRecorder) GetSharedPasswordBcrypt() *gomock.Call { } // GetStatusForVersion mocks base method. -func (m *MockStore) GetStatusForVersion(appID, clusterID string, sequence int64) (types11.DownstreamVersionStatus, error) { +func (m *MockStore) GetStatusForVersion(appID, clusterID string, sequence int64) (types12.DownstreamVersionStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetStatusForVersion", appID, clusterID, sequence) - ret0, _ := ret[0].(types11.DownstreamVersionStatus) + ret0, _ := ret[0].(types12.DownstreamVersionStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1122,10 +1123,10 @@ func (mr *MockStoreMockRecorder) GetStatusForVersion(appID, clusterID, sequence } // GetSupportBundle mocks base method. -func (m *MockStore) GetSupportBundle(bundleID string) (*types12.SupportBundle, error) { +func (m *MockStore) GetSupportBundle(bundleID string) (*types13.SupportBundle, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSupportBundle", bundleID) - ret0, _ := ret[0].(*types12.SupportBundle) + ret0, _ := ret[0].(*types13.SupportBundle) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1137,10 +1138,10 @@ func (mr *MockStoreMockRecorder) GetSupportBundle(bundleID interface{}) *gomock. } // GetSupportBundleAnalysis mocks base method. -func (m *MockStore) GetSupportBundleAnalysis(bundleID string) (*types12.SupportBundleAnalysis, error) { +func (m *MockStore) GetSupportBundleAnalysis(bundleID string) (*types13.SupportBundleAnalysis, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSupportBundleAnalysis", bundleID) - ret0, _ := ret[0].(*types12.SupportBundleAnalysis) + ret0, _ := ret[0].(*types13.SupportBundleAnalysis) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1316,7 +1317,7 @@ func (mr *MockStoreMockRecorder) IsRollbackSupportedForVersion(appID, sequence i } // IsSnapshotsSupportedForVersion mocks base method. -func (m *MockStore) IsSnapshotsSupportedForVersion(a *types2.App, sequence int64, renderer types9.Renderer) (bool, error) { +func (m *MockStore) IsSnapshotsSupportedForVersion(a *types3.App, sequence int64, renderer types10.Renderer) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsSnapshotsSupportedForVersion", a, sequence, renderer) ret0, _ := ret[0].(bool) @@ -1331,10 +1332,10 @@ func (mr *MockStoreMockRecorder) IsSnapshotsSupportedForVersion(a, sequence, ren } // ListAppsForDownstream mocks base method. -func (m *MockStore) ListAppsForDownstream(clusterID string) ([]*types2.App, error) { +func (m *MockStore) ListAppsForDownstream(clusterID string) ([]*types3.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListAppsForDownstream", clusterID) - ret0, _ := ret[0].([]*types2.App) + ret0, _ := ret[0].([]*types3.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1376,10 +1377,10 @@ func (mr *MockStoreMockRecorder) ListDownstreamsForApp(appID interface{}) *gomoc } // ListFailedApps mocks base method. -func (m *MockStore) ListFailedApps() ([]*types2.App, error) { +func (m *MockStore) ListFailedApps() ([]*types3.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListFailedApps") - ret0, _ := ret[0].([]*types2.App) + ret0, _ := ret[0].([]*types3.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1406,10 +1407,10 @@ func (mr *MockStoreMockRecorder) ListInstalledAppSlugs() *gomock.Call { } // ListInstalledApps mocks base method. -func (m *MockStore) ListInstalledApps() ([]*types2.App, error) { +func (m *MockStore) ListInstalledApps() ([]*types3.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListInstalledApps") - ret0, _ := ret[0].([]*types2.App) + ret0, _ := ret[0].([]*types3.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1421,10 +1422,10 @@ func (mr *MockStoreMockRecorder) ListInstalledApps() *gomock.Call { } // ListPendingScheduledInstanceSnapshots mocks base method. -func (m *MockStore) ListPendingScheduledInstanceSnapshots(clusterID string) ([]types5.ScheduledInstanceSnapshot, error) { +func (m *MockStore) ListPendingScheduledInstanceSnapshots(clusterID string) ([]types6.ScheduledInstanceSnapshot, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListPendingScheduledInstanceSnapshots", clusterID) - ret0, _ := ret[0].([]types5.ScheduledInstanceSnapshot) + ret0, _ := ret[0].([]types6.ScheduledInstanceSnapshot) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1436,10 +1437,10 @@ func (mr *MockStoreMockRecorder) ListPendingScheduledInstanceSnapshots(clusterID } // ListPendingScheduledSnapshots mocks base method. -func (m *MockStore) ListPendingScheduledSnapshots(appID string) ([]types5.ScheduledSnapshot, error) { +func (m *MockStore) ListPendingScheduledSnapshots(appID string) ([]types6.ScheduledSnapshot, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListPendingScheduledSnapshots", appID) - ret0, _ := ret[0].([]types5.ScheduledSnapshot) + ret0, _ := ret[0].([]types6.ScheduledSnapshot) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1451,10 +1452,10 @@ func (mr *MockStoreMockRecorder) ListPendingScheduledSnapshots(appID interface{} } // ListSupportBundles mocks base method. -func (m *MockStore) ListSupportBundles(appID string) ([]*types12.SupportBundle, error) { +func (m *MockStore) ListSupportBundles(appID string) ([]*types13.SupportBundle, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListSupportBundles", appID) - ret0, _ := ret[0].([]*types12.SupportBundle) + ret0, _ := ret[0].([]*types13.SupportBundle) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1576,7 +1577,7 @@ func (mr *MockStoreMockRecorder) SetAppIsAirgap(appID, isAirgap interface{}) *go } // SetAppStatus mocks base method. -func (m *MockStore) SetAppStatus(appID string, resourceStates types3.ResourceStates, updatedAt time.Time, sequence int64) error { +func (m *MockStore) SetAppStatus(appID string, resourceStates types4.ResourceStates, updatedAt time.Time, sequence int64) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SetAppStatus", appID, resourceStates, updatedAt, sequence) ret0, _ := ret[0].(error) @@ -1590,7 +1591,7 @@ func (mr *MockStoreMockRecorder) SetAppStatus(appID, resourceStates, updatedAt, } // SetAutoDeploy mocks base method. -func (m *MockStore) SetAutoDeploy(appID string, autoDeploy types2.AutoDeploy) error { +func (m *MockStore) SetAutoDeploy(appID string, autoDeploy types3.AutoDeploy) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SetAutoDeploy", appID, autoDeploy) ret0, _ := ret[0].(error) @@ -1604,7 +1605,7 @@ func (mr *MockStoreMockRecorder) SetAutoDeploy(appID, autoDeploy interface{}) *g } // SetDownstreamVersionStatus mocks base method. -func (m *MockStore) SetDownstreamVersionStatus(appID string, sequence int64, status types11.DownstreamVersionStatus, statusInfo string) error { +func (m *MockStore) SetDownstreamVersionStatus(appID string, sequence int64, status types12.DownstreamVersionStatus, statusInfo string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SetDownstreamVersionStatus", appID, sequence, status, statusInfo) ret0, _ := ret[0].(error) @@ -1829,18 +1830,18 @@ func (mr *MockStoreMockRecorder) SetUpdateCheckerSpec(appID, updateCheckerSpec i } // UpdateAppLicense mocks base method. -func (m *MockStore) UpdateAppLicense(appID string, sequence int64, archiveDir string, newLicense *v1beta10.License, originalLicenseData string, channelChanged, failOnVersionCreate bool, gitops types4.DownstreamGitOps, renderer types9.Renderer) (int64, error) { +func (m *MockStore) UpdateAppLicense(appID string, sequence int64, archiveDir string, newLicense *v1beta10.License, originalLicenseData string, channelChanged, failOnVersionCreate bool, gitops types5.DownstreamGitOps, renderer types10.Renderer, reportingInfo *types1.ReportingInfo) (int64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateAppLicense", appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer) + ret := m.ctrl.Call(m, "UpdateAppLicense", appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer, reportingInfo) ret0, _ := ret[0].(int64) ret1, _ := ret[1].(error) return ret0, ret1 } // UpdateAppLicense indicates an expected call of UpdateAppLicense. -func (mr *MockStoreMockRecorder) UpdateAppLicense(appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) UpdateAppLicense(appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer, reportingInfo interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAppLicense", reflect.TypeOf((*MockStore)(nil).UpdateAppLicense), appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAppLicense", reflect.TypeOf((*MockStore)(nil).UpdateAppLicense), appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer, reportingInfo) } // UpdateAppLicenseSyncNow mocks base method. @@ -1858,7 +1859,7 @@ func (mr *MockStoreMockRecorder) UpdateAppLicenseSyncNow(appID interface{}) *gom } // UpdateAppVersion mocks base method. -func (m *MockStore) UpdateAppVersion(appID string, sequence int64, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types4.DownstreamGitOps, renderer types9.Renderer) error { +func (m *MockStore) UpdateAppVersion(appID string, sequence int64, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types5.DownstreamGitOps, renderer types10.Renderer) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateAppVersion", appID, sequence, baseSequence, filesInDir, source, skipPreflights, gitops, renderer) ret0, _ := ret[0].(error) @@ -1871,20 +1872,6 @@ func (mr *MockStoreMockRecorder) UpdateAppVersion(appID, sequence, baseSequence, return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAppVersion", reflect.TypeOf((*MockStore)(nil).UpdateAppVersion), appID, sequence, baseSequence, filesInDir, source, skipPreflights, gitops, renderer) } -// UpdateAppVersionInstallationSpec mocks base method. -func (m *MockStore) UpdateAppVersionInstallationSpec(appID string, sequence int64, spec v1beta10.Installation) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateAppVersionInstallationSpec", appID, sequence, spec) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateAppVersionInstallationSpec indicates an expected call of UpdateAppVersionInstallationSpec. -func (mr *MockStoreMockRecorder) UpdateAppVersionInstallationSpec(appID, sequence, spec interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAppVersionInstallationSpec", reflect.TypeOf((*MockStore)(nil).UpdateAppVersionInstallationSpec), appID, sequence, spec) -} - // UpdateDownstreamDeployStatus mocks base method. func (m *MockStore) UpdateDownstreamDeployStatus(appID, clusterID string, sequence int64, isError bool, output types0.DownstreamOutput) error { m.ctrl.T.Helper() @@ -1970,7 +1957,7 @@ func (mr *MockStoreMockRecorder) UpdateSessionExpiresAt(sessionID, expiresAt int } // UpdateSupportBundle mocks base method. -func (m *MockStore) UpdateSupportBundle(bundle *types12.SupportBundle) error { +func (m *MockStore) UpdateSupportBundle(bundle *types13.SupportBundle) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateSupportBundle", bundle) ret0, _ := ret[0].(error) @@ -2085,10 +2072,10 @@ func (mr *MockRegistryStoreMockRecorder) GetAppIDsFromRegistry(hostname interfac } // GetRegistryDetailsForApp mocks base method. -func (m *MockRegistryStore) GetRegistryDetailsForApp(appID string) (types8.RegistrySettings, error) { +func (m *MockRegistryStore) GetRegistryDetailsForApp(appID string) (types9.RegistrySettings, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetRegistryDetailsForApp", appID) - ret0, _ := ret[0].(types8.RegistrySettings) + ret0, _ := ret[0].(types9.RegistrySettings) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2137,7 +2124,7 @@ func (m *MockSupportBundleStore) EXPECT() *MockSupportBundleStoreMockRecorder { } // CreateInProgressSupportBundle mocks base method. -func (m *MockSupportBundleStore) CreateInProgressSupportBundle(supportBundle *types12.SupportBundle) error { +func (m *MockSupportBundleStore) CreateInProgressSupportBundle(supportBundle *types13.SupportBundle) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateInProgressSupportBundle", supportBundle) ret0, _ := ret[0].(error) @@ -2151,10 +2138,10 @@ func (mr *MockSupportBundleStoreMockRecorder) CreateInProgressSupportBundle(supp } // CreateSupportBundle mocks base method. -func (m *MockSupportBundleStore) CreateSupportBundle(bundleID, appID, archivePath string, marshalledTree []byte) (*types12.SupportBundle, error) { +func (m *MockSupportBundleStore) CreateSupportBundle(bundleID, appID, archivePath string, marshalledTree []byte) (*types13.SupportBundle, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateSupportBundle", bundleID, appID, archivePath, marshalledTree) - ret0, _ := ret[0].(*types12.SupportBundle) + ret0, _ := ret[0].(*types13.SupportBundle) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2195,10 +2182,10 @@ func (mr *MockSupportBundleStoreMockRecorder) GetRedactions(bundleID interface{} } // GetSupportBundle mocks base method. -func (m *MockSupportBundleStore) GetSupportBundle(bundleID string) (*types12.SupportBundle, error) { +func (m *MockSupportBundleStore) GetSupportBundle(bundleID string) (*types13.SupportBundle, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSupportBundle", bundleID) - ret0, _ := ret[0].(*types12.SupportBundle) + ret0, _ := ret[0].(*types13.SupportBundle) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2210,10 +2197,10 @@ func (mr *MockSupportBundleStoreMockRecorder) GetSupportBundle(bundleID interfac } // GetSupportBundleAnalysis mocks base method. -func (m *MockSupportBundleStore) GetSupportBundleAnalysis(bundleID string) (*types12.SupportBundleAnalysis, error) { +func (m *MockSupportBundleStore) GetSupportBundleAnalysis(bundleID string) (*types13.SupportBundleAnalysis, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSupportBundleAnalysis", bundleID) - ret0, _ := ret[0].(*types12.SupportBundleAnalysis) + ret0, _ := ret[0].(*types13.SupportBundleAnalysis) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2240,10 +2227,10 @@ func (mr *MockSupportBundleStoreMockRecorder) GetSupportBundleArchive(bundleID i } // ListSupportBundles mocks base method. -func (m *MockSupportBundleStore) ListSupportBundles(appID string) ([]*types12.SupportBundle, error) { +func (m *MockSupportBundleStore) ListSupportBundles(appID string) ([]*types13.SupportBundle, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListSupportBundles", appID) - ret0, _ := ret[0].([]*types12.SupportBundle) + ret0, _ := ret[0].([]*types13.SupportBundle) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2283,7 +2270,7 @@ func (mr *MockSupportBundleStoreMockRecorder) SetSupportBundleAnalysis(bundleID, } // UpdateSupportBundle mocks base method. -func (m *MockSupportBundleStore) UpdateSupportBundle(bundle *types12.SupportBundle) error { +func (m *MockSupportBundleStore) UpdateSupportBundle(bundle *types13.SupportBundle) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateSupportBundle", bundle) ret0, _ := ret[0].(error) @@ -2349,10 +2336,10 @@ func (mr *MockPreflightStoreMockRecorder) GetPreflightProgress(appID, sequence i } // GetPreflightResults mocks base method. -func (m *MockPreflightStore) GetPreflightResults(appID string, sequence int64) (*types7.PreflightResult, error) { +func (m *MockPreflightStore) GetPreflightResults(appID string, sequence int64) (*types8.PreflightResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPreflightResults", appID, sequence) - ret0, _ := ret[0].(*types7.PreflightResult) + ret0, _ := ret[0].(*types8.PreflightResult) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2576,10 +2563,10 @@ func (m *MockSessionStore) EXPECT() *MockSessionStoreMockRecorder { } // CreateSession mocks base method. -func (m *MockSessionStore) CreateSession(user *types14.User, issuedAt, expiresAt time.Time, roles []string) (*types10.Session, error) { +func (m *MockSessionStore) CreateSession(user *types15.User, issuedAt, expiresAt time.Time, roles []string) (*types11.Session, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateSession", user, issuedAt, expiresAt, roles) - ret0, _ := ret[0].(*types10.Session) + ret0, _ := ret[0].(*types11.Session) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2619,10 +2606,10 @@ func (mr *MockSessionStoreMockRecorder) DeleteSession(sessionID interface{}) *go } // GetSession mocks base method. -func (m *MockSessionStore) GetSession(sessionID string) (*types10.Session, error) { +func (m *MockSessionStore) GetSession(sessionID string) (*types11.Session, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSession", sessionID) - ret0, _ := ret[0].(*types10.Session) + ret0, _ := ret[0].(*types11.Session) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2671,10 +2658,10 @@ func (m *MockAppStatusStore) EXPECT() *MockAppStatusStoreMockRecorder { } // GetAppStatus mocks base method. -func (m *MockAppStatusStore) GetAppStatus(appID string) (*types3.AppStatus, error) { +func (m *MockAppStatusStore) GetAppStatus(appID string) (*types4.AppStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAppStatus", appID) - ret0, _ := ret[0].(*types3.AppStatus) + ret0, _ := ret[0].(*types4.AppStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2686,7 +2673,7 @@ func (mr *MockAppStatusStoreMockRecorder) GetAppStatus(appID interface{}) *gomoc } // SetAppStatus mocks base method. -func (m *MockAppStatusStore) SetAppStatus(appID string, resourceStates types3.ResourceStates, updatedAt time.Time, sequence int64) error { +func (m *MockAppStatusStore) SetAppStatus(appID string, resourceStates types4.ResourceStates, updatedAt time.Time, sequence int64) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SetAppStatus", appID, resourceStates, updatedAt, sequence) ret0, _ := ret[0].(error) @@ -2737,10 +2724,10 @@ func (mr *MockAppStoreMockRecorder) AddAppToAllDownstreams(appID interface{}) *g } // CreateApp mocks base method. -func (m *MockAppStore) CreateApp(name, upstreamURI, licenseData string, isAirgapEnabled, skipImagePush, registryIsReadOnly bool) (*types2.App, error) { +func (m *MockAppStore) CreateApp(name, upstreamURI, licenseData string, isAirgapEnabled, skipImagePush, registryIsReadOnly bool) (*types3.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateApp", name, upstreamURI, licenseData, isAirgapEnabled, skipImagePush, registryIsReadOnly) - ret0, _ := ret[0].(*types2.App) + ret0, _ := ret[0].(*types3.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2752,10 +2739,10 @@ func (mr *MockAppStoreMockRecorder) CreateApp(name, upstreamURI, licenseData, is } // GetApp mocks base method. -func (m *MockAppStore) GetApp(appID string) (*types2.App, error) { +func (m *MockAppStore) GetApp(appID string) (*types3.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetApp", appID) - ret0, _ := ret[0].(*types2.App) + ret0, _ := ret[0].(*types3.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2767,10 +2754,10 @@ func (mr *MockAppStoreMockRecorder) GetApp(appID interface{}) *gomock.Call { } // GetAppFromSlug mocks base method. -func (m *MockAppStore) GetAppFromSlug(slug string) (*types2.App, error) { +func (m *MockAppStore) GetAppFromSlug(slug string) (*types3.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAppFromSlug", slug) - ret0, _ := ret[0].(*types2.App) + ret0, _ := ret[0].(*types3.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2827,10 +2814,10 @@ func (mr *MockAppStoreMockRecorder) IsGitOpsEnabledForApp(appID interface{}) *go } // ListAppsForDownstream mocks base method. -func (m *MockAppStore) ListAppsForDownstream(clusterID string) ([]*types2.App, error) { +func (m *MockAppStore) ListAppsForDownstream(clusterID string) ([]*types3.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListAppsForDownstream", clusterID) - ret0, _ := ret[0].([]*types2.App) + ret0, _ := ret[0].([]*types3.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2857,10 +2844,10 @@ func (mr *MockAppStoreMockRecorder) ListDownstreamsForApp(appID interface{}) *go } // ListFailedApps mocks base method. -func (m *MockAppStore) ListFailedApps() ([]*types2.App, error) { +func (m *MockAppStore) ListFailedApps() ([]*types3.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListFailedApps") - ret0, _ := ret[0].([]*types2.App) + ret0, _ := ret[0].([]*types3.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2887,10 +2874,10 @@ func (mr *MockAppStoreMockRecorder) ListInstalledAppSlugs() *gomock.Call { } // ListInstalledApps mocks base method. -func (m *MockAppStore) ListInstalledApps() ([]*types2.App, error) { +func (m *MockAppStore) ListInstalledApps() ([]*types3.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListInstalledApps") - ret0, _ := ret[0].([]*types2.App) + ret0, _ := ret[0].([]*types3.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2944,7 +2931,7 @@ func (mr *MockAppStoreMockRecorder) SetAppInstallState(appID, state interface{}) } // SetAutoDeploy mocks base method. -func (m *MockAppStore) SetAutoDeploy(appID string, autoDeploy types2.AutoDeploy) error { +func (m *MockAppStore) SetAutoDeploy(appID string, autoDeploy types3.AutoDeploy) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SetAutoDeploy", appID, autoDeploy) ret0, _ := ret[0].(error) @@ -3170,10 +3157,10 @@ func (mr *MockDownstreamStoreMockRecorder) GetDownstreamVersionSource(appID, seq } // GetDownstreamVersionStatus mocks base method. -func (m *MockDownstreamStore) GetDownstreamVersionStatus(appID string, sequence int64) (types11.DownstreamVersionStatus, error) { +func (m *MockDownstreamStore) GetDownstreamVersionStatus(appID string, sequence int64) (types12.DownstreamVersionStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetDownstreamVersionStatus", appID, sequence) - ret0, _ := ret[0].(types11.DownstreamVersionStatus) + ret0, _ := ret[0].(types12.DownstreamVersionStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3262,10 +3249,10 @@ func (mr *MockDownstreamStoreMockRecorder) GetPreviouslyDeployedSequence(appID, } // GetStatusForVersion mocks base method. -func (m *MockDownstreamStore) GetStatusForVersion(appID, clusterID string, sequence int64) (types11.DownstreamVersionStatus, error) { +func (m *MockDownstreamStore) GetStatusForVersion(appID, clusterID string, sequence int64) (types12.DownstreamVersionStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetStatusForVersion", appID, clusterID, sequence) - ret0, _ := ret[0].(types11.DownstreamVersionStatus) + ret0, _ := ret[0].(types12.DownstreamVersionStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3322,7 +3309,7 @@ func (mr *MockDownstreamStoreMockRecorder) MarkAsCurrentDownstreamVersion(appID, } // SetDownstreamVersionStatus mocks base method. -func (m *MockDownstreamStore) SetDownstreamVersionStatus(appID string, sequence int64, status types11.DownstreamVersionStatus, statusInfo string) error { +func (m *MockDownstreamStore) SetDownstreamVersionStatus(appID string, sequence int64, status types12.DownstreamVersionStatus, statusInfo string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SetDownstreamVersionStatus", appID, sequence, status, statusInfo) ret0, _ := ret[0].(error) @@ -3429,10 +3416,10 @@ func (mr *MockSnapshotStoreMockRecorder) DeletePendingScheduledSnapshots(appID i } // ListPendingScheduledInstanceSnapshots mocks base method. -func (m *MockSnapshotStore) ListPendingScheduledInstanceSnapshots(clusterID string) ([]types5.ScheduledInstanceSnapshot, error) { +func (m *MockSnapshotStore) ListPendingScheduledInstanceSnapshots(clusterID string) ([]types6.ScheduledInstanceSnapshot, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListPendingScheduledInstanceSnapshots", clusterID) - ret0, _ := ret[0].([]types5.ScheduledInstanceSnapshot) + ret0, _ := ret[0].([]types6.ScheduledInstanceSnapshot) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3444,10 +3431,10 @@ func (mr *MockSnapshotStoreMockRecorder) ListPendingScheduledInstanceSnapshots(c } // ListPendingScheduledSnapshots mocks base method. -func (m *MockSnapshotStore) ListPendingScheduledSnapshots(appID string) ([]types5.ScheduledSnapshot, error) { +func (m *MockSnapshotStore) ListPendingScheduledSnapshots(appID string) ([]types6.ScheduledSnapshot, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListPendingScheduledSnapshots", appID) - ret0, _ := ret[0].([]types5.ScheduledSnapshot) + ret0, _ := ret[0].([]types6.ScheduledSnapshot) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3510,7 +3497,7 @@ func (m *MockVersionStore) EXPECT() *MockVersionStoreMockRecorder { } // CreateAppVersion mocks base method. -func (m *MockVersionStore) CreateAppVersion(appID string, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types4.DownstreamGitOps, renderer types9.Renderer) (int64, error) { +func (m *MockVersionStore) CreateAppVersion(appID string, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types5.DownstreamGitOps, renderer types10.Renderer) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateAppVersion", appID, baseSequence, filesInDir, source, skipPreflights, gitops, renderer) ret0, _ := ret[0].(int64) @@ -3539,7 +3526,7 @@ func (mr *MockVersionStoreMockRecorder) CreateAppVersionArchive(appID, sequence, } // CreatePendingDownloadAppVersion mocks base method. -func (m *MockVersionStore) CreatePendingDownloadAppVersion(appID string, update types13.Update, kotsApplication *v1beta10.Application, license *v1beta10.License) (int64, error) { +func (m *MockVersionStore) CreatePendingDownloadAppVersion(appID string, update types14.Update, kotsApplication *v1beta10.Application, license *v1beta10.License) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreatePendingDownloadAppVersion", appID, update, kotsApplication, license) ret0, _ := ret[0].(int64) @@ -3554,10 +3541,10 @@ func (mr *MockVersionStoreMockRecorder) CreatePendingDownloadAppVersion(appID, u } // GetAppVersion mocks base method. -func (m *MockVersionStore) GetAppVersion(appID string, sequence int64) (*types1.AppVersion, error) { +func (m *MockVersionStore) GetAppVersion(appID string, sequence int64) (*types2.AppVersion, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAppVersion", appID, sequence) - ret0, _ := ret[0].(*types1.AppVersion) + ret0, _ := ret[0].(*types2.AppVersion) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3734,7 +3721,7 @@ func (mr *MockVersionStoreMockRecorder) IsRollbackSupportedForVersion(appID, seq } // IsSnapshotsSupportedForVersion mocks base method. -func (m *MockVersionStore) IsSnapshotsSupportedForVersion(a *types2.App, sequence int64, renderer types9.Renderer) (bool, error) { +func (m *MockVersionStore) IsSnapshotsSupportedForVersion(a *types3.App, sequence int64, renderer types10.Renderer) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsSnapshotsSupportedForVersion", a, sequence, renderer) ret0, _ := ret[0].(bool) @@ -3749,7 +3736,7 @@ func (mr *MockVersionStoreMockRecorder) IsSnapshotsSupportedForVersion(a, sequen } // UpdateAppVersion mocks base method. -func (m *MockVersionStore) UpdateAppVersion(appID string, sequence int64, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types4.DownstreamGitOps, renderer types9.Renderer) error { +func (m *MockVersionStore) UpdateAppVersion(appID string, sequence int64, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types5.DownstreamGitOps, renderer types10.Renderer) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateAppVersion", appID, sequence, baseSequence, filesInDir, source, skipPreflights, gitops, renderer) ret0, _ := ret[0].(error) @@ -3762,20 +3749,6 @@ func (mr *MockVersionStoreMockRecorder) UpdateAppVersion(appID, sequence, baseSe return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAppVersion", reflect.TypeOf((*MockVersionStore)(nil).UpdateAppVersion), appID, sequence, baseSequence, filesInDir, source, skipPreflights, gitops, renderer) } -// UpdateAppVersionInstallationSpec mocks base method. -func (m *MockVersionStore) UpdateAppVersionInstallationSpec(appID string, sequence int64, spec v1beta10.Installation) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateAppVersionInstallationSpec", appID, sequence, spec) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateAppVersionInstallationSpec indicates an expected call of UpdateAppVersionInstallationSpec. -func (mr *MockVersionStoreMockRecorder) UpdateAppVersionInstallationSpec(appID, sequence, spec interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAppVersionInstallationSpec", reflect.TypeOf((*MockVersionStore)(nil).UpdateAppVersionInstallationSpec), appID, sequence, spec) -} - // UpdateNextAppVersionDiffSummary mocks base method. func (m *MockVersionStore) UpdateNextAppVersionDiffSummary(appID string, baseSequence int64) error { m.ctrl.T.Helper() @@ -3859,18 +3832,18 @@ func (mr *MockLicenseStoreMockRecorder) GetLicenseForAppVersion(appID, sequence } // UpdateAppLicense mocks base method. -func (m *MockLicenseStore) UpdateAppLicense(appID string, sequence int64, archiveDir string, newLicense *v1beta10.License, originalLicenseData string, channelChanged, failOnVersionCreate bool, gitops types4.DownstreamGitOps, renderer types9.Renderer) (int64, error) { +func (m *MockLicenseStore) UpdateAppLicense(appID string, sequence int64, archiveDir string, newLicense *v1beta10.License, originalLicenseData string, channelChanged, failOnVersionCreate bool, gitops types5.DownstreamGitOps, renderer types10.Renderer, reportingInfo *types1.ReportingInfo) (int64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateAppLicense", appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer) + ret := m.ctrl.Call(m, "UpdateAppLicense", appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer, reportingInfo) ret0, _ := ret[0].(int64) ret1, _ := ret[1].(error) return ret0, ret1 } // UpdateAppLicense indicates an expected call of UpdateAppLicense. -func (mr *MockLicenseStoreMockRecorder) UpdateAppLicense(appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer interface{}) *gomock.Call { +func (mr *MockLicenseStoreMockRecorder) UpdateAppLicense(appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer, reportingInfo interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAppLicense", reflect.TypeOf((*MockLicenseStore)(nil).UpdateAppLicense), appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAppLicense", reflect.TypeOf((*MockLicenseStore)(nil).UpdateAppLicense), appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer, reportingInfo) } // UpdateAppLicenseSyncNow mocks base method. @@ -4103,10 +4076,10 @@ func (m *MockInstallationStore) EXPECT() *MockInstallationStoreMockRecorder { } // GetPendingInstallationStatus mocks base method. -func (m *MockInstallationStore) GetPendingInstallationStatus() (*types6.InstallStatus, error) { +func (m *MockInstallationStore) GetPendingInstallationStatus() (*types7.InstallStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPendingInstallationStatus") - ret0, _ := ret[0].(*types6.InstallStatus) + ret0, _ := ret[0].(*types7.InstallStatus) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/pkg/store/store_interface.go b/pkg/store/store_interface.go index 146571ba90..6e503719e6 100644 --- a/pkg/store/store_interface.go +++ b/pkg/store/store_interface.go @@ -7,6 +7,7 @@ import ( embeddedclusterv1beta1 "github.com/replicatedhq/embedded-cluster-kinds/apis/v1beta1" airgaptypes "github.com/replicatedhq/kots/pkg/airgap/types" downstreamtypes "github.com/replicatedhq/kots/pkg/api/downstream/types" + reportingtypes "github.com/replicatedhq/kots/pkg/api/reporting/types" versiontypes "github.com/replicatedhq/kots/pkg/api/version/types" apptypes "github.com/replicatedhq/kots/pkg/app/types" appstatetypes "github.com/replicatedhq/kots/pkg/appstate/types" @@ -188,7 +189,6 @@ type VersionStore interface { GetAppVersion(appID string, sequence int64) (*versiontypes.AppVersion, error) GetLatestAppSequence(appID string, downloadedOnly bool) (int64, error) UpdateNextAppVersionDiffSummary(appID string, baseSequence int64) error - UpdateAppVersionInstallationSpec(appID string, sequence int64, spec kotsv1beta1.Installation) error GetNextAppSequence(appID string) (int64, error) GetCurrentUpdateCursor(appID string, channelID string) (string, error) HasStrictPreflights(appID string, sequence int64) (bool, error) @@ -201,7 +201,7 @@ type LicenseStore interface { GetAllAppLicenses() ([]*kotsv1beta1.License, error) // originalLicenseData is the data received from the replicated API that was never marshalled locally so all fields are intact - UpdateAppLicense(appID string, sequence int64, archiveDir string, newLicense *kotsv1beta1.License, originalLicenseData string, channelChanged bool, failOnVersionCreate bool, gitops gitopstypes.DownstreamGitOps, renderer rendertypes.Renderer) (int64, error) + UpdateAppLicense(appID string, sequence int64, archiveDir string, newLicense *kotsv1beta1.License, originalLicenseData string, channelChanged bool, failOnVersionCreate bool, gitops gitopstypes.DownstreamGitOps, renderer rendertypes.Renderer, reportingInfo *reportingtypes.ReportingInfo) (int64, error) UpdateAppLicenseSyncNow(appID string) error } diff --git a/pkg/tests/renderdir/renderdir_test.go b/pkg/tests/renderdir/renderdir_test.go index 9e95b4a37f..3eb9d5ccb1 100644 --- a/pkg/tests/renderdir/renderdir_test.go +++ b/pkg/tests/renderdir/renderdir_test.go @@ -13,8 +13,6 @@ import ( cp "github.com/otiai10/copy" "github.com/replicatedhq/kots/pkg/render" rendertypes "github.com/replicatedhq/kots/pkg/render/types" - "github.com/replicatedhq/kots/pkg/store" - mock_store "github.com/replicatedhq/kots/pkg/store/mock" "github.com/replicatedhq/kots/pkg/util" kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1" "github.com/stretchr/testify/assert" @@ -36,12 +34,6 @@ func TestKotsRenderDir(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - mockStore := mock_store.NewMockStore(ctrl) - store.SetStore(mockStore) - defer store.SetStore(nil) - - mockStore.EXPECT().UpdateAppVersionInstallationSpec(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() - t.Setenv("USE_MOCK_REPORTING", "1") defer os.Unsetenv("USE_MOCK_REPORTING") diff --git a/pkg/upgradeservice/handlers/config.go b/pkg/upgradeservice/handlers/config.go index 0f2f6b3ad4..c6922a119a 100644 --- a/pkg/upgradeservice/handlers/config.go +++ b/pkg/upgradeservice/handlers/config.go @@ -2,19 +2,29 @@ package handlers import ( "encoding/json" + "fmt" "net/http" + "os" "path/filepath" + "strings" "github.com/gorilla/mux" "github.com/pkg/errors" + downstreamtypes "github.com/replicatedhq/kots/pkg/api/downstream/types" + apptypes "github.com/replicatedhq/kots/pkg/app/types" "github.com/replicatedhq/kots/pkg/config" kotsconfig "github.com/replicatedhq/kots/pkg/config" + "github.com/replicatedhq/kots/pkg/kotsadmconfig" configtypes "github.com/replicatedhq/kots/pkg/kotsadmconfig/types" configvalidation "github.com/replicatedhq/kots/pkg/kotsadmconfig/validation" "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/render" + rendertypes "github.com/replicatedhq/kots/pkg/render/types" + "github.com/replicatedhq/kots/pkg/reporting" "github.com/replicatedhq/kots/pkg/template" + upgradepreflight "github.com/replicatedhq/kots/pkg/upgradeservice/preflight" "github.com/replicatedhq/kots/pkg/util" kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1" "github.com/replicatedhq/kotskinds/multitype" @@ -38,6 +48,17 @@ type LiveAppConfigResponse struct { ValidationErrors []configtypes.ConfigGroupValidationError `json:"validationErrors,omitempty"` } +type SaveAppConfigRequest struct { + ConfigGroups []kotsv1beta1.ConfigGroup `json:"configGroups"` +} + +type SaveAppConfigResponse struct { + Success bool `json:"success"` + Error string `json:"error,omitempty"` + RequiredItems []string `json:"requiredItems,omitempty"` + ValidationErrors []configtypes.ConfigGroupValidationError `json:"validationErrors,omitempty"` +} + func (h *Handler) CurrentAppConfig(w http.ResponseWriter, r *http.Request) { currentAppConfigResponse := CurrentAppConfigResponse{ Success: false, @@ -254,3 +275,148 @@ func configValuesFromConfigGroups(configGroups []kotsv1beta1.ConfigGroup) map[st return configValues } + +func (h *Handler) SaveAppConfig(w http.ResponseWriter, r *http.Request) { + saveAppConfigResponse := SaveAppConfigResponse{ + Success: false, + } + + params := GetContextParams(r) + appSlug := mux.Vars(r)["appSlug"] + + if params.AppSlug != appSlug { + saveAppConfigResponse.Error = "app slug does not match" + JSON(w, http.StatusForbidden, saveAppConfigResponse) + return + } + + appLicense, err := kotsutil.LoadLicenseFromBytes([]byte(params.AppLicense)) + if err != nil { + saveAppConfigResponse.Error = "failed to load license from bytes" + logger.Error(errors.Wrap(err, saveAppConfigResponse.Error)) + JSON(w, http.StatusInternalServerError, saveAppConfigResponse) + return + } + + saveAppConfigRequest := SaveAppConfigRequest{} + if err := json.NewDecoder(r.Body).Decode(&saveAppConfigRequest); err != nil { + logger.Error(err) + saveAppConfigResponse.Error = "failed to decode request body" + JSON(w, http.StatusBadRequest, saveAppConfigResponse) + return + } + + validationErrors, err := configvalidation.ValidateConfigSpec(kotsv1beta1.ConfigSpec{Groups: saveAppConfigRequest.ConfigGroups}) + if err != nil { + saveAppConfigResponse.Error = "failed to validate config spec." + logger.Error(errors.Wrap(err, saveAppConfigResponse.Error)) + JSON(w, http.StatusInternalServerError, saveAppConfigResponse) + return + } + + if len(validationErrors) > 0 { + saveAppConfigResponse.Error = "invalid config values" + saveAppConfigResponse.ValidationErrors = validationErrors + logger.Errorf("%v, validation errors: %+v", saveAppConfigResponse.Error, validationErrors) + JSON(w, http.StatusBadRequest, saveAppConfigResponse) + return + } + + requiredItems, requiredItemsTitles := kotsadmconfig.GetMissingRequiredConfig(saveAppConfigRequest.ConfigGroups) + if len(requiredItems) > 0 { + saveAppConfigResponse.RequiredItems = requiredItems + saveAppConfigResponse.Error = fmt.Sprintf("The following fields are required: %s", strings.Join(requiredItemsTitles, ", ")) + logger.Errorf("%v, required items: %+v", saveAppConfigResponse.Error, requiredItems) + JSON(w, http.StatusBadRequest, saveAppConfigResponse) + return + } + + localRegistry := registrytypes.RegistrySettings{ + Hostname: params.RegistryEndpoint, + Username: params.RegistryUsername, + Password: params.RegistryPassword, + Namespace: params.RegistryNamespace, + IsReadOnly: params.RegistryIsReadOnly, + } + + app := &apptypes.App{ + ID: params.AppID, + Slug: params.AppSlug, + IsAirgap: params.AppIsAirgap, + IsGitOps: params.AppIsGitOps, + } + + kotsKinds, err := kotsutil.LoadKotsKinds(params.BaseArchive) + if err != nil { + saveAppConfigResponse.Error = "failed to load kots kinds from path" + logger.Error(errors.Wrap(err, saveAppConfigResponse.Error)) + JSON(w, http.StatusInternalServerError, saveAppConfigResponse) + return + } + + if kotsKinds.ConfigValues == nil { + err = errors.New("config values not found") + saveAppConfigResponse.Error = err.Error() + logger.Error(err) + JSON(w, http.StatusInternalServerError, saveAppConfigResponse) + return + } + + values := kotsKinds.ConfigValues.Spec.Values + kotsKinds.ConfigValues.Spec.Values = kotsadmconfig.UpdateAppConfigValues(values, saveAppConfigRequest.ConfigGroups) + + configValuesSpec, err := kotsKinds.Marshal("kots.io", "v1beta1", "ConfigValues") + if err != nil { + saveAppConfigResponse.Error = "failed to marshal config values" + logger.Error(errors.Wrap(err, saveAppConfigResponse.Error)) + JSON(w, http.StatusInternalServerError, saveAppConfigResponse) + return + } + + if err := os.WriteFile(filepath.Join(params.BaseArchive, "upstream", "userdata", "config.yaml"), []byte(configValuesSpec), 0644); err != nil { + saveAppConfigResponse.Error = "failed to write config values" + logger.Error(errors.Wrap(err, saveAppConfigResponse.Error)) + JSON(w, http.StatusInternalServerError, saveAppConfigResponse) + return + } + + err = render.RenderDir(rendertypes.RenderDirOptions{ + ArchiveDir: params.BaseArchive, + App: app, + Downstreams: []downstreamtypes.Downstream{{Name: "this-cluster"}}, + RegistrySettings: localRegistry, + Sequence: params.NextSequence, + ReportingInfo: params.ReportingInfo, + }) + if err != nil { + cause := errors.Cause(err) + if _, ok := cause.(util.ActionableError); ok { + saveAppConfigResponse.Error = err.Error() + JSON(w, http.StatusInternalServerError, saveAppConfigResponse) + return + } else { + saveAppConfigResponse.Error = "failed to render templates" + logger.Error(errors.Wrap(err, saveAppConfigResponse.Error)) + JSON(w, http.StatusInternalServerError, saveAppConfigResponse) + return + } + } + + reportingFn := func() error { + if params.AppIsAirgap { + // TODO NOW: airgap reporting + return nil + } + return reporting.SendOnlineAppInfo(appLicense, params.ReportingInfo) + } + + if err := upgradepreflight.Run(app, params.BaseArchive, int64(params.NextSequence), localRegistry, false, reportingFn); err != nil { + saveAppConfigResponse.Error = "failed to run preflights" + logger.Error(errors.Wrap(err, saveAppConfigResponse.Error)) + JSON(w, http.StatusInternalServerError, saveAppConfigResponse) + return + } + + saveAppConfigResponse.Success = true + JSON(w, http.StatusOK, saveAppConfigResponse) +} diff --git a/pkg/upgradeservice/handlers/handlers.go b/pkg/upgradeservice/handlers/handlers.go index 65437c0897..f8c71f81ef 100644 --- a/pkg/upgradeservice/handlers/handlers.go +++ b/pkg/upgradeservice/handlers/handlers.go @@ -32,6 +32,7 @@ func RegisterRoutes(r *mux.Router, handler UpgradeServiceHandler) { subRouter.Path("/config").Methods("GET").HandlerFunc(handler.CurrentAppConfig) subRouter.Path("/liveconfig").Methods("POST").HandlerFunc(handler.LiveAppConfig) + subRouter.Path("/config").Methods("PUT").HandlerFunc(handler.SaveAppConfig) } func JSON(w http.ResponseWriter, code int, payload interface{}) { diff --git a/pkg/upgradeservice/handlers/interface.go b/pkg/upgradeservice/handlers/interface.go index 7825aa6dff..8361cd9cd9 100644 --- a/pkg/upgradeservice/handlers/interface.go +++ b/pkg/upgradeservice/handlers/interface.go @@ -7,4 +7,5 @@ type UpgradeServiceHandler interface { CurrentAppConfig(w http.ResponseWriter, r *http.Request) LiveAppConfig(w http.ResponseWriter, r *http.Request) + SaveAppConfig(w http.ResponseWriter, r *http.Request) } diff --git a/pkg/upgradeservice/preflight/preflight.go b/pkg/upgradeservice/preflight/preflight.go new file mode 100644 index 0000000000..7428964192 --- /dev/null +++ b/pkg/upgradeservice/preflight/preflight.go @@ -0,0 +1,197 @@ +package preflight + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + + "github.com/pkg/errors" + apptypes "github.com/replicatedhq/kots/pkg/app/types" + "github.com/replicatedhq/kots/pkg/kotsutil" + "github.com/replicatedhq/kots/pkg/logger" + preflightpkg "github.com/replicatedhq/kots/pkg/preflight" + "github.com/replicatedhq/kots/pkg/preflight/types" + "github.com/replicatedhq/kots/pkg/registry" + 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/util" + troubleshootanalyze "github.com/replicatedhq/troubleshoot/pkg/analyze" + troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" + troubleshootpreflight "github.com/replicatedhq/troubleshoot/pkg/preflight" + "go.uber.org/zap" +) + +type PreflightData struct { + Progress map[string]interface{} `json:"progress"` + Results *types.PreflightResults `json:"results"` +} + +var PreflightDataFilepath string + +func init() { + tmpDir, err := os.MkdirTemp("", "preflights") + if err != nil { + panic(errors.Wrap(err, "failed to create preflights data dir")) + } + PreflightDataFilepath = filepath.Join(tmpDir, "preflights.json") +} + +func Run(app *apptypes.App, archiveDir string, sequence int64, registrySettings registrytypes.RegistrySettings, ignoreRBAC bool, reportingFn func() error) error { + kotsKinds, err := kotsutil.LoadKotsKinds(archiveDir) + if err != nil { + return errors.Wrap(err, "failed to load rendered kots kinds") + } + + tsKinds, err := kotsutil.LoadTSKindsFromPath(filepath.Join(archiveDir, "rendered")) + if err != nil { + return errors.Wrap(err, fmt.Sprintf("failed to load troubleshoot kinds from path: %s", filepath.Join(archiveDir, "rendered"))) + } + + var preflight *troubleshootv1beta2.Preflight + if tsKinds.PreflightsV1Beta2 != nil { + for _, v := range tsKinds.PreflightsV1Beta2 { + preflight = troubleshootpreflight.ConcatPreflightSpec(preflight, &v) + } + } else if kotsKinds.Preflight != nil { + renderedMarshalledPreflights, err := kotsKinds.Marshal("troubleshoot.replicated.com", "v1beta1", "Preflight") + if err != nil { + return errors.Wrap(err, "failed to marshal rendered preflight") + } + renderedPreflight, err := render.RenderFile(rendertypes.RenderFileOptions{ + KotsKinds: kotsKinds, + RegistrySettings: registrySettings, + AppSlug: app.Slug, + Sequence: sequence, + IsAirgap: app.IsAirgap, + Namespace: util.PodNamespace, + InputContent: []byte(renderedMarshalledPreflights), + }) + if err != nil { + return errors.Wrap(err, "failed to render preflights") + } + preflight, err = kotsutil.LoadPreflightFromContents(renderedPreflight) + if err != nil { + return errors.Wrap(err, "failed to load rendered preflight") + } + } + + if preflight == nil { + logger.Info("no preflight spec found, not running preflights") + return nil + } + + preflightpkg.InjectDefaultPreflights(preflight, kotsKinds, registrySettings) + + numAnalyzers := 0 + for _, analyzer := range preflight.Spec.Analyzers { + exclude := troubleshootanalyze.GetExcludeFlag(analyzer).BoolOrDefaultFalse() + if !exclude { + numAnalyzers += 1 + } + } + if numAnalyzers == 0 { + logger.Info("no analyzers found, not running preflights") + return nil + } + + var preflightErr error + defer func() { + if preflightErr != nil { + preflightResults := &types.PreflightResults{ + Errors: []*types.PreflightError{ + &types.PreflightError{ + Error: preflightErr.Error(), + IsRBAC: false, + }, + }, + } + if err := setPreflightResults(preflightResults); err != nil { + logger.Error(errors.Wrap(err, "failed to set preflight results")) + return + } + } + }() + + collectors, err := registry.UpdateCollectorSpecsWithRegistryData(preflight.Spec.Collectors, registrySettings, kotsKinds.Installation, kotsKinds.License, &kotsKinds.KotsApplication) + if err != nil { + preflightErr = errors.Wrap(err, "failed to rewrite images in preflight") + return preflightErr + } + preflight.Spec.Collectors = collectors + + go func() { + logger.Info("preflight checks beginning", + zap.String("appID", app.ID), + zap.Int64("sequence", sequence)) + + _, err := preflightpkg.Execute(preflight, ignoreRBAC, setPreflightProgress, setPreflightResults) + if err != nil { + logger.Error(errors.Wrap(err, "failed to run preflight checks")) + return + } + + go func() { + if err := reportingFn(); err != nil { + logger.Debugf("failed to report app info: %v", err) + } + }() + }() + + return nil +} + +func setPreflightResults(results *types.PreflightResults) error { + preflightData, err := getPreflightData() + if err != nil { + return errors.Wrap(err, "failed to get preflight data") + } + preflightData.Results = results + if err := setPreflightData(preflightData); err != nil { + return errors.Wrap(err, "failed to set preflight results") + } + return nil +} + +func setPreflightProgress(progress map[string]interface{}) error { + preflightData, err := getPreflightData() + if err != nil { + return errors.Wrap(err, "failed to get preflight data") + } + preflightData.Progress = progress + if err := setPreflightData(preflightData); err != nil { + return errors.Wrap(err, "failed to set preflight progress") + } + return nil +} + +func getPreflightData() (*PreflightData, error) { + var preflightData *PreflightData + if _, err := os.Stat(PreflightDataFilepath); err != nil { + if !os.IsNotExist(err) { + return nil, errors.Wrap(err, "failed to stat existing preflight data") + } + preflightData = &PreflightData{} + } else { + existingBytes, err := os.ReadFile(PreflightDataFilepath) + if err != nil { + return nil, errors.Wrap(err, "failed to read existing preflight data") + } + if err := json.Unmarshal(existingBytes, &preflightData); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal existing preflight data") + } + } + return preflightData, nil +} + +func setPreflightData(preflightData *PreflightData) error { + b, err := json.Marshal(preflightData) + if err != nil { + return errors.Wrap(err, "failed to marshal preflight data") + } + if err := os.WriteFile(PreflightDataFilepath, b, 0644); err != nil { + return errors.Wrap(err, "failed to write preflight data") + } + return nil +}