diff --git a/pkg/api/reporting/types/types.go b/pkg/api/reporting/types/types.go index 527d741e85..ec8ac91333 100644 --- a/pkg/api/reporting/types/types.go +++ b/pkg/api/reporting/types/types.go @@ -11,7 +11,7 @@ type ReportingInfo struct { KurlNodeCountReady int `json:"kurl_node_count_ready"` K8sVersion string `json:"k8s_version"` K8sDistribution string `json:"k8s_distribution"` - KOTSVersion string `json:"kots_version"` + UserAgent string `json:"user_agent"` KOTSInstallID string `json:"kots_install_id"` KURLInstallID string `json:"kurl_install_id"` IsGitOpsEnabled bool `json:"is_gitops_enabled"` diff --git a/pkg/handlers/preflight.go b/pkg/handlers/preflight.go index 5138d6b8af..550545d4a3 100644 --- a/pkg/handlers/preflight.go +++ b/pkg/handlers/preflight.go @@ -366,7 +366,7 @@ func (h *Handler) PreflightsReports(w http.ResponseWriter, r *http.Request) { go func() { if err := reporting.GetReporter().SubmitPreflightData(license, foundApp.ID, clusterID, 0, true, "", false, "", ""); err != nil { - logger.Debugf("failed to send preflights data to replicated app: %v", err) + logger.Debugf("failed to submit preflight data: %v", err) return } }() diff --git a/pkg/reporting/app.go b/pkg/reporting/app.go index dcb02e12c4..744e8f35ce 100644 --- a/pkg/reporting/app.go +++ b/pkg/reporting/app.go @@ -47,7 +47,14 @@ func Init() error { } if kotsadm.IsAirgap() { - reporter = &AirgapReporter{} + clientset, err := k8sutil.GetClientset() + if err != nil { + return errors.Wrap(err, "failed to get clientset") + } + reporter = &AirgapReporter{ + clientset: clientset, + store: store.GetStore(), + } } else { reporter = &OnlineReporter{} } @@ -175,7 +182,7 @@ func GetReportingInfo(appID string) *types.ReportingInfo { InstanceID: appID, KOTSInstallID: os.Getenv("KOTS_INSTALL_ID"), KURLInstallID: os.Getenv("KURL_INSTALL_ID"), - KOTSVersion: buildversion.Version(), + UserAgent: buildversion.GetUserAgent(), } clientset, err := k8sutil.GetClientset() diff --git a/pkg/reporting/app_airgap.go b/pkg/reporting/app_airgap.go index fbd7a0f742..e8cb5c0a14 100644 --- a/pkg/reporting/app_airgap.go +++ b/pkg/reporting/app_airgap.go @@ -1,29 +1,75 @@ package reporting import ( + "strconv" + "time" + "github.com/pkg/errors" - "github.com/replicatedhq/kots/pkg/store" + "github.com/replicatedhq/kots/pkg/api/reporting/types" + "github.com/replicatedhq/kots/pkg/logger" + "github.com/replicatedhq/kots/pkg/util" ) func (r *AirgapReporter) SubmitAppInfo(appID string) error { - a, err := store.GetStore().GetApp(appID) + a, err := r.store.GetApp(appID) if err != nil { - if store.GetStore().IsNotFound(err) { + if r.store.IsNotFound(err) { return nil } - return errors.Wrap(err, "failed to get airgaped app") + return errors.Wrap(err, "failed to get airgapped app") } - license, err := store.GetStore().GetLatestLicenseForApp(a.ID) + license, err := r.store.GetLatestLicenseForApp(a.ID) if err != nil { return errors.Wrap(err, "failed to get license for airgapped app") } reportingInfo := GetReportingInfo(appID) - err = store.GetStore().SaveReportingInfo(license.Spec.LicenseID, reportingInfo) - if err != nil { - return errors.Wrap(err, "failed to save reporting info") + report := BuildInstanceReport(license.Spec.LicenseID, reportingInfo) + + if err := AppendReport(r.clientset, util.PodNamespace, a.Slug, report); err != nil { + return errors.Wrap(err, "failed to append instance report") } return nil } + +func BuildInstanceReport(licenseID string, reportingInfo *types.ReportingInfo) *InstanceReport { + // not using the "cursor" packages because it doesn't provide access to the underlying int64 + downstreamSequence, err := strconv.ParseUint(reportingInfo.Downstream.Cursor, 10, 64) + if err != nil { + logger.Debugf("failed to parse downstream cursor %q: %v", reportingInfo.Downstream.Cursor, err) + } + + return &InstanceReport{ + Events: []InstanceReportEvent{ + { + ReportedAt: time.Now().UTC().UnixMilli(), + LicenseID: licenseID, + InstanceID: reportingInfo.InstanceID, + ClusterID: reportingInfo.ClusterID, + AppStatus: reportingInfo.AppStatus, + IsKurl: reportingInfo.IsKurl, + KurlNodeCountTotal: reportingInfo.KurlNodeCountTotal, + KurlNodeCountReady: reportingInfo.KurlNodeCountReady, + K8sVersion: reportingInfo.K8sVersion, + K8sDistribution: reportingInfo.K8sDistribution, + UserAgent: reportingInfo.UserAgent, + KotsInstallID: reportingInfo.KOTSInstallID, + KurlInstallID: reportingInfo.KURLInstallID, + IsGitOpsEnabled: reportingInfo.IsGitOpsEnabled, + GitOpsProvider: reportingInfo.GitOpsProvider, + DownstreamChannelID: reportingInfo.Downstream.ChannelID, + DownstreamChannelSequence: downstreamSequence, + DownstreamChannelName: reportingInfo.Downstream.ChannelName, + DownstreamSequence: reportingInfo.Downstream.Sequence, + DownstreamSource: reportingInfo.Downstream.Source, + InstallStatus: reportingInfo.Downstream.Status, + PreflightState: reportingInfo.Downstream.PreflightState, + SkipPreflights: reportingInfo.Downstream.SkipPreflights, + ReplHelmInstalls: reportingInfo.Downstream.ReplHelmInstalls, + NativeHelmInstalls: reportingInfo.Downstream.NativeHelmInstalls, + }, + }, + } +} diff --git a/pkg/reporting/instance_report.go b/pkg/reporting/instance_report.go new file mode 100644 index 0000000000..8c2eb06701 --- /dev/null +++ b/pkg/reporting/instance_report.go @@ -0,0 +1,76 @@ +package reporting + +import ( + "fmt" + "sync" + + "github.com/pkg/errors" +) + +var instanceReportMtx = sync.Mutex{} + +type InstanceReport struct { + Events []InstanceReportEvent `json:"events"` +} + +type InstanceReportEvent struct { + ReportedAt int64 `json:"reported_at"` + LicenseID string `json:"license_id"` + InstanceID string `json:"instance_id"` + ClusterID string `json:"cluster_id"` + AppStatus string `json:"app_status"` + IsKurl bool `json:"is_kurl"` + KurlNodeCountTotal int `json:"kurl_node_count_total"` + KurlNodeCountReady int `json:"kurl_node_count_ready"` + K8sVersion string `json:"k8s_version"` + K8sDistribution string `json:"k8s_distribution,omitempty"` + UserAgent string `json:"user_agent"` + KotsInstallID string `json:"kots_install_id,omitempty"` + KurlInstallID string `json:"kurl_install_id,omitempty"` + IsGitOpsEnabled bool `json:"is_gitops_enabled"` + GitOpsProvider string `json:"gitops_provider"` + DownstreamChannelID string `json:"downstream_channel_id,omitempty"` + DownstreamChannelSequence uint64 `json:"downstream_channel_sequence,omitempty"` + DownstreamChannelName string `json:"downstream_channel_name,omitempty"` + DownstreamSequence *int64 `json:"downstream_sequence,omitempty"` + DownstreamSource string `json:"downstream_source,omitempty"` + InstallStatus string `json:"install_status,omitempty"` + PreflightState string `json:"preflight_state,omitempty"` + SkipPreflights bool `json:"skip_preflights"` + ReplHelmInstalls int `json:"repl_helm_installs"` + NativeHelmInstalls int `json:"native_helm_installs"` +} + +func (r *InstanceReport) GetType() ReportType { + return ReportTypeInstance +} + +func (r *InstanceReport) GetSecretName(appSlug string) string { + return fmt.Sprintf(ReportSecretNameFormat, fmt.Sprintf("%s-%s", appSlug, r.GetType())) +} + +func (r *InstanceReport) GetSecretKey() string { + return ReportSecretKey +} + +func (r *InstanceReport) AppendEvents(report Report) error { + reportToAppend, ok := report.(*InstanceReport) + if !ok { + return errors.Errorf("report is not an instance report") + } + + r.Events = append(r.Events, reportToAppend.Events...) + if len(r.Events) > r.GetEventLimit() { + r.Events = r.Events[len(r.Events)-r.GetEventLimit():] + } + + return nil +} + +func (r *InstanceReport) GetEventLimit() int { + return ReportEventLimit +} + +func (r *InstanceReport) GetMtx() *sync.Mutex { + return &instanceReportMtx +} diff --git a/pkg/reporting/preflight.go b/pkg/reporting/preflight.go index 29fc6cab11..d13f13e37e 100644 --- a/pkg/reporting/preflight.go +++ b/pkg/reporting/preflight.go @@ -82,7 +82,7 @@ func WaitAndReportPreflightChecks(appID string, sequence int64, isSkipPreflights } if err := GetReporter().SubmitPreflightData(license, appID, clusterID, sequence, isSkipPreflights, currentVersionStatus, isCLI, preflightState, string(appStatus)); err != nil { - logger.Debugf("failed to send preflights data to replicated app: %v", err) + logger.Debugf("failed to submit preflight data: %v", err) return } }() diff --git a/pkg/reporting/preflight_airgap.go b/pkg/reporting/preflight_airgap.go index 913bf43f7f..cdad45749b 100644 --- a/pkg/reporting/preflight_airgap.go +++ b/pkg/reporting/preflight_airgap.go @@ -1,29 +1,44 @@ package reporting import ( + "time" + "github.com/pkg/errors" - reportingtypes "github.com/replicatedhq/kots/pkg/api/reporting/types" "github.com/replicatedhq/kots/pkg/buildversion" - "github.com/replicatedhq/kots/pkg/store" storetypes "github.com/replicatedhq/kots/pkg/store/types" + "github.com/replicatedhq/kots/pkg/util" kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1" ) func (r *AirgapReporter) SubmitPreflightData(license *kotsv1beta1.License, appID string, clusterID string, sequence int64, skipPreflights bool, installStatus storetypes.DownstreamVersionStatus, isCLI bool, preflightStatus string, appStatus string) error { - status := &reportingtypes.PreflightStatus{ - InstanceID: appID, - ClusterID: clusterID, - Sequence: sequence, - SkipPreflights: skipPreflights, - InstallStatus: string(installStatus), - IsCLI: isCLI, - PreflightStatus: preflightStatus, - AppStatus: preflightStatus, - KOTSVersion: buildversion.Version(), - } - err := store.GetStore().SavePreflightReport(license.Spec.LicenseID, status) + app, err := r.store.GetApp(appID) if err != nil { - return errors.Wrap(err, "failed to save preflight report") + if r.store.IsNotFound(err) { + return nil + } + return errors.Wrap(err, "failed to get airgapped app") + } + + report := &PreflightReport{ + Events: []PreflightReportEvent{ + { + ReportedAt: time.Now().UTC().UnixMilli(), + LicenseID: license.Spec.LicenseID, + InstanceID: appID, + ClusterID: clusterID, + Sequence: sequence, + SkipPreflights: skipPreflights, + InstallStatus: string(installStatus), + IsCLI: isCLI, + PreflightStatus: preflightStatus, + AppStatus: appStatus, + UserAgent: buildversion.GetUserAgent(), + }, + }, + } + + if err := AppendReport(r.clientset, util.PodNamespace, app.Slug, report); err != nil { + return errors.Wrap(err, "failed to append preflight report") } return nil diff --git a/pkg/reporting/preflight_report.go b/pkg/reporting/preflight_report.go new file mode 100644 index 0000000000..f8b918cde0 --- /dev/null +++ b/pkg/reporting/preflight_report.go @@ -0,0 +1,62 @@ +package reporting + +import ( + "fmt" + "sync" + + "github.com/pkg/errors" +) + +var preflightReportMtx = sync.Mutex{} + +type PreflightReport struct { + Events []PreflightReportEvent `json:"events"` +} + +type PreflightReportEvent struct { + ReportedAt int64 `json:"reported_at"` + LicenseID string `json:"license_id"` + InstanceID string `json:"instance_id"` + ClusterID string `json:"cluster_id"` + Sequence int64 `json:"sequence"` + SkipPreflights bool `json:"skip_preflights"` + InstallStatus string `json:"install_status"` + IsCLI bool `json:"is_cli"` + PreflightStatus string `json:"preflight_status"` + AppStatus string `json:"app_status"` + UserAgent string `json:"user_agent"` +} + +func (r *PreflightReport) GetType() ReportType { + return ReportTypePreflight +} + +func (r *PreflightReport) GetSecretName(appSlug string) string { + return fmt.Sprintf(ReportSecretNameFormat, fmt.Sprintf("%s-%s", appSlug, r.GetType())) +} + +func (r *PreflightReport) GetSecretKey() string { + return ReportSecretKey +} + +func (r *PreflightReport) AppendEvents(report Report) error { + reportToAppend, ok := report.(*PreflightReport) + if !ok { + return errors.Errorf("report is not a preflight report") + } + + r.Events = append(r.Events, reportToAppend.Events...) + if len(r.Events) > r.GetEventLimit() { + r.Events = r.Events[len(r.Events)-r.GetEventLimit():] + } + + return nil +} + +func (r *PreflightReport) GetEventLimit() int { + return ReportEventLimit +} + +func (r *PreflightReport) GetMtx() *sync.Mutex { + return &preflightReportMtx +} diff --git a/pkg/reporting/report.go b/pkg/reporting/report.go new file mode 100644 index 0000000000..584d682aa5 --- /dev/null +++ b/pkg/reporting/report.go @@ -0,0 +1,154 @@ +package reporting + +import ( + "context" + "encoding/base64" + "encoding/json" + "sync" + + "github.com/pkg/errors" + kotsadmtypes "github.com/replicatedhq/kots/pkg/kotsadm/types" + "github.com/replicatedhq/kots/pkg/util" + corev1 "k8s.io/api/core/v1" + kuberneteserrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +const ( + ReportSecretNameFormat = "kotsadm-%s-report" + ReportSecretKey = "report" + ReportEventLimit = 4000 +) + +type ReportType string + +const ( + ReportTypeInstance ReportType = "instance" + ReportTypePreflight ReportType = "preflight" +) + +type Report interface { + GetType() ReportType + GetSecretName(appSlug string) string + GetSecretKey() string + AppendEvents(report Report) error + GetEventLimit() int + GetMtx() *sync.Mutex +} + +var _ Report = &InstanceReport{} +var _ Report = &PreflightReport{} + +func AppendReport(clientset kubernetes.Interface, namespace string, appSlug string, report Report) error { + report.GetMtx().Lock() + defer report.GetMtx().Unlock() + + existingSecret, err := clientset.CoreV1().Secrets(namespace).Get(context.TODO(), report.GetSecretName(appSlug), metav1.GetOptions{}) + if err != nil && !kuberneteserrors.IsNotFound(err) { + return errors.Wrap(err, "failed to get report secret") + } else if kuberneteserrors.IsNotFound(err) { + data, err := EncodeReport(report) + if err != nil { + return errors.Wrap(err, "failed to encode report") + } + + secret := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: report.GetSecretName(appSlug), + Namespace: namespace, + Labels: kotsadmtypes.GetKotsadmLabels(), + }, + Data: map[string][]byte{ + report.GetSecretKey(): data, + }, + } + + _, err = clientset.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{}) + if err != nil { + return errors.Wrap(err, "failed to create report secret") + } + + return nil + } + + if existingSecret.Data == nil { + existingSecret.Data = map[string][]byte{} + } + + var existingReport Report + if existingSecret.Data[report.GetSecretKey()] != nil { + existingReport, err = DecodeReport(existingSecret.Data[report.GetSecretKey()], report.GetType()) + if err != nil { + return errors.Wrap(err, "failed to load existing report") + } + + if err := existingReport.AppendEvents(report); err != nil { + return errors.Wrap(err, "failed to append events to existing report") + } + } else { + // secret exists but doesn't have the report key, so just use the report that was passed in + existingReport = report + } + + data, err := EncodeReport(existingReport) + if err != nil { + return errors.Wrap(err, "failed to encode existing report") + } + + existingSecret.Data[report.GetSecretKey()] = data + + _, err = clientset.CoreV1().Secrets(namespace).Update(context.TODO(), existingSecret, metav1.UpdateOptions{}) + if err != nil { + return errors.Wrap(err, "failed to update report secret") + } + + return nil +} + +func EncodeReport(r Report) ([]byte, error) { + data, err := json.Marshal(r) + if err != nil { + return nil, errors.Wrap(err, "failed to marshal report") + } + compressedData, err := util.GzipData(data) + if err != nil { + return nil, errors.Wrap(err, "failed to gzip report") + } + encodedData := base64.StdEncoding.EncodeToString(compressedData) + + return []byte(encodedData), nil +} + +func DecodeReport(encodedData []byte, reportType ReportType) (Report, error) { + decodedData, err := base64.StdEncoding.DecodeString(string(encodedData)) + if err != nil { + return nil, errors.Wrap(err, "failed to decode report") + } + decompressedData, err := util.GunzipData(decodedData) + if err != nil { + return nil, errors.Wrap(err, "failed to gunzip report") + } + + var r Report + switch reportType { + case ReportTypeInstance: + r = &InstanceReport{} + if err := json.Unmarshal(decompressedData, r); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal instance report") + } + case ReportTypePreflight: + r = &PreflightReport{} + if err := json.Unmarshal(decompressedData, r); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal preflight report") + } + default: + return nil, errors.Errorf("unknown report type %q", reportType) + } + + return r, nil +} diff --git a/pkg/reporting/report_test.go b/pkg/reporting/report_test.go new file mode 100644 index 0000000000..0d43129692 --- /dev/null +++ b/pkg/reporting/report_test.go @@ -0,0 +1,266 @@ +package reporting + +import ( + "context" + "testing" + + kotsadmtypes "github.com/replicatedhq/kots/pkg/kotsadm/types" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/fake" +) + +func Test_EncodeDecodeAirgapReport(t *testing.T) { + req := require.New(t) + + // instance report + testDownstreamSequence := int64(123) + testInstanceReport := &InstanceReport{ + Events: []InstanceReportEvent{ + { + ReportedAt: 1234567890, + LicenseID: "test-license-id", + InstanceID: "test-instance-id", + ClusterID: "test-cluster-id", + AppStatus: "ready", + IsKurl: true, + KurlNodeCountTotal: 3, + KurlNodeCountReady: 3, + K8sVersion: "1.28.0", + K8sDistribution: "kurl", + UserAgent: "KOTS/1.100.0", + KotsInstallID: "test-kots-install-id", + KurlInstallID: "test-kurl-install-id", + IsGitOpsEnabled: true, + GitOpsProvider: "test-gitops-provider", + DownstreamChannelID: "test-downstream-channel-id", + DownstreamChannelSequence: 123, + DownstreamChannelName: "test-downstream-channel-name", + DownstreamSequence: &testDownstreamSequence, + DownstreamSource: "test-downstream-source", + InstallStatus: "installed", + PreflightState: "passed", + SkipPreflights: false, + ReplHelmInstalls: 1, + NativeHelmInstalls: 2, + }, + }, + } + + encodedInstanceReport, err := EncodeReport(testInstanceReport) + req.NoError(err) + + decodedInstanceReport, err := DecodeReport(encodedInstanceReport, testInstanceReport.GetType()) + req.NoError(err) + + req.Equal(testInstanceReport, decodedInstanceReport) + + // preflight report + testPrelightReport := &PreflightReport{ + Events: []PreflightReportEvent{ + { + ReportedAt: 1234567890, + LicenseID: "test-license-id", + InstanceID: "test-instance-id", + ClusterID: "test-cluster-id", + Sequence: 123, + SkipPreflights: false, + InstallStatus: "installed", + IsCLI: true, + PreflightStatus: "pass", + AppStatus: "ready", + UserAgent: "KOTS/1.100.0", + }, + }, + } + + encodedPreflightReport, err := EncodeReport(testPrelightReport) + req.NoError(err) + + decodedPreflightReport, err := DecodeReport(encodedPreflightReport, testPrelightReport.GetType()) + req.NoError(err) + + req.Equal(testPrelightReport, decodedPreflightReport) +} + +func Test_AppendReport(t *testing.T) { + // instance report + testDownstreamSequence := int64(123) + testInstanceReport := &InstanceReport{ + Events: []InstanceReportEvent{ + { + ReportedAt: 1234567890, + LicenseID: "test-license-id", + InstanceID: "test-instance-id", + ClusterID: "test-cluster-id", + AppStatus: "ready", + IsKurl: true, + KurlNodeCountTotal: 3, + KurlNodeCountReady: 3, + K8sVersion: "1.28.0", + K8sDistribution: "kurl", + UserAgent: "KOTS/1.100.0", + KotsInstallID: "test-kots-install-id", + KurlInstallID: "test-kurl-install-id", + IsGitOpsEnabled: true, + GitOpsProvider: "test-gitops-provider", + DownstreamChannelID: "test-downstream-channel-id", + DownstreamChannelSequence: 123, + DownstreamChannelName: "test-downstream-channel-name", + DownstreamSequence: &testDownstreamSequence, + DownstreamSource: "test-downstream-source", + InstallStatus: "installed", + PreflightState: "passed", + SkipPreflights: false, + ReplHelmInstalls: 1, + NativeHelmInstalls: 2, + }, + }, + } + + // preflight report + testPreflightReport := &PreflightReport{ + Events: []PreflightReportEvent{ + { + ReportedAt: 1234567890, + LicenseID: "test-license-id", + InstanceID: "test-instance-id", + ClusterID: "test-cluster-id", + Sequence: 123, + SkipPreflights: false, + InstallStatus: "installed", + IsCLI: true, + PreflightStatus: "pass", + AppStatus: "ready", + UserAgent: "KOTS/1.100.0", + }, + }, + } + + tests := append(createTestsForReport(t, testInstanceReport), createTestsForReport(t, testPreflightReport)...) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req := require.New(t) + + err := AppendReport(tt.args.clientset, tt.args.namespace, tt.args.appSlug, tt.args.report) + if tt.wantErr { + req.Error(err) + return + } + req.NoError(err) + + // validate secret exists and has the expected data + secret, err := tt.args.clientset.CoreV1().Secrets(tt.args.namespace).Get(context.TODO(), tt.args.report.GetSecretName(tt.args.appSlug), metav1.GetOptions{}) + req.NoError(err) + req.NotNil(secret.Data[tt.args.report.GetSecretKey()]) + + report, err := DecodeReport(secret.Data[tt.args.report.GetSecretKey()], tt.args.report.GetType()) + req.NoError(err) + req.Equal(tt.args.report, report) + }) + } +} + +type AppendReportTest struct { + name string + args AppendReportTestArgs + wantNumEvents int + wantErr bool +} + +type AppendReportTestArgs struct { + clientset kubernetes.Interface + namespace string + appSlug string + report Report +} + +func createTestsForReport(t *testing.T, testReport Report) []AppendReportTest { + testReportWithOneEventData, err := EncodeReport(testReport) + require.NoError(t, err) + + for i := 0; i < testReport.GetEventLimit(); i++ { + err := testReport.AppendEvents(testReport) + require.NoError(t, err) + } + testReportWithMaxEventsData, err := EncodeReport(testReport) + require.NoError(t, err) + + tests := []AppendReportTest{ + { + name: "secret does not exist", + args: AppendReportTestArgs{ + clientset: fake.NewSimpleClientset(), + namespace: "default", + appSlug: "test-app-slug", + report: testReport, + }, + wantNumEvents: 1, + }, + { + name: "secret exists with an existing event", + args: AppendReportTestArgs{ + clientset: fake.NewSimpleClientset( + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: testReport.GetSecretName("test-app-slug"), + Namespace: "default", + Labels: kotsadmtypes.GetKotsadmLabels(), + }, + Data: map[string][]byte{ + testReport.GetSecretKey(): testReportWithOneEventData, + }, + }, + ), + namespace: "default", + appSlug: "test-app-slug", + report: testReport, + }, + wantNumEvents: 2, + }, + { + name: "secret exists without data", + args: AppendReportTestArgs{ + clientset: fake.NewSimpleClientset( + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: testReport.GetSecretName("test-app-slug"), + Namespace: "default", + Labels: kotsadmtypes.GetKotsadmLabels(), + }, + }, + ), + namespace: "default", + appSlug: "test-app-slug", + report: testReport, + }, + wantNumEvents: 1, + }, + { + name: "secret exists with max number of events", + args: AppendReportTestArgs{ + clientset: fake.NewSimpleClientset( + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: testReport.GetSecretName("test-app-slug"), + Namespace: "default", + Labels: kotsadmtypes.GetKotsadmLabels(), + }, + Data: map[string][]byte{ + testReport.GetSecretKey(): testReportWithMaxEventsData, + }, + }, + ), + namespace: "default", + appSlug: "test-app-slug", + report: testReport, + }, + wantNumEvents: ReportEventLimit, + }, + } + + return tests +} diff --git a/pkg/reporting/types.go b/pkg/reporting/types.go index ce96e9e5a0..95589b58ad 100644 --- a/pkg/reporting/types.go +++ b/pkg/reporting/types.go @@ -1,8 +1,10 @@ package reporting import ( + "github.com/replicatedhq/kots/pkg/store" storetypes "github.com/replicatedhq/kots/pkg/store/types" kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1" + "k8s.io/client-go/kubernetes" ) type Distribution int64 @@ -33,6 +35,8 @@ type Reporter interface { var reporter Reporter type AirgapReporter struct { + clientset kubernetes.Interface + store store.Store } var _ Reporter = &AirgapReporter{} diff --git a/pkg/store/kotsstore/reporting_store.go b/pkg/store/kotsstore/reporting_store.go deleted file mode 100644 index d8138af0f0..0000000000 --- a/pkg/store/kotsstore/reporting_store.go +++ /dev/null @@ -1,246 +0,0 @@ -package kotsstore - -import ( - "fmt" - "strconv" - "time" - - "github.com/pkg/errors" - reportingtypes "github.com/replicatedhq/kots/pkg/api/reporting/types" - "github.com/replicatedhq/kots/pkg/logger" - "github.com/replicatedhq/kots/pkg/persistence" - "github.com/rqlite/gorqlite" -) - -func (s *KOTSStore) SavePreflightReport(licenseID string, preflightStatus *reportingtypes.PreflightStatus) error { - db := persistence.MustGetDBSession() - - createdAt := time.Now().UTC() - - query := ` - INSERT INTO preflight_report ( - created_at, - license_id, - instance_id, - cluster_id, - sequence, - skip_preflights, - install_status, - is_cli, - preflight_status, - app_status, - kots_version) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - ON CONFLICT(created_at) DO UPDATE SET - license_id = EXCLUDED.license_id, - instance_id = EXCLUDED.instance_id, - cluster_id = EXCLUDED.cluster_id, - sequence = EXCLUDED.sequence, - skip_preflights = EXCLUDED.skip_preflights, - install_status = EXCLUDED.install_status, - is_cli = EXCLUDED.is_cli, - preflight_status = EXCLUDED.preflight_status, - app_status = EXCLUDED.app_status, - kots_version = EXCLUDED.kots_version` - - statement := gorqlite.ParameterizedStatement{ - Query: query, - Arguments: []interface{}{ - createdAt.UnixMilli(), - licenseID, - preflightStatus.InstanceID, - preflightStatus.ClusterID, - preflightStatus.Sequence, - preflightStatus.SkipPreflights, - preflightStatus.InstallStatus, - preflightStatus.IsCLI, - preflightStatus.PreflightStatus, - preflightStatus.AppStatus, - preflightStatus.KOTSVersion, - }, - } - - wr, err := db.WriteOneParameterized(statement) - if err != nil { - return fmt.Errorf("failed to write preflight report: %v: %v", err, wr.Err) - } - - go func() { - err := s.removeOldReportingData("preflight_report") - if err != nil { - logger.Warnf("failed to delete old data from preflight_report: %v", err) - } - }() - - return nil -} - -func (s *KOTSStore) SaveReportingInfo(licenseID string, reportingInfo *reportingtypes.ReportingInfo) error { - db := persistence.MustGetDBSession() - - createdAt := time.Now().UTC() - - // not using the "cursor" packages because it doesn't provide access to the underlying int64 - downstreamSequence, err := strconv.ParseUint(reportingInfo.Downstream.Cursor, 10, 64) - if err != nil { - logger.Debugf("failed to parse downstream cursor %q: %v", reportingInfo.Downstream.Cursor, err) - } - - query := ` - INSERT INTO instance_report ( - created_at, - license_id, - instance_id, - cluster_id, - app_status, - is_kurl, - kurl_node_count_total, - kurl_node_count_ready, - k8s_version, - kots_version, - kots_install_id, - kurl_install_id, - is_gitops_enabled, - gitops_provider, - downstream_channel_sequence, - downstream_channel_id, - downstream_channel_name, - downstream_sequence, - downstream_source, - install_status, - preflight_state, - skip_preflights, - repl_helm_installs, - native_helm_installs) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - ON CONFLICT(created_at) DO UPDATE SET - license_id = EXCLUDED.license_id, - instance_id = EXCLUDED.instance_id, - cluster_id = EXCLUDED.cluster_id, - app_status = EXCLUDED.app_status, - is_kurl = EXCLUDED.is_kurl, - kurl_node_count_total = EXCLUDED.kurl_node_count_total, - kurl_node_count_ready = EXCLUDED.kurl_node_count_ready, - k8s_version = EXCLUDED.k8s_version, - kots_version = EXCLUDED.kots_version, - kots_install_id = EXCLUDED.kots_install_id, - kurl_install_id = EXCLUDED.kurl_install_id, - is_gitops_enabled = EXCLUDED.is_gitops_enabled, - gitops_provider = EXCLUDED.gitops_provider, - downstream_channel_sequence = EXCLUDED.downstream_channel_sequence, - downstream_channel_id = EXCLUDED.downstream_channel_id, - downstream_channel_name = EXCLUDED.downstream_channel_name, - downstream_sequence = EXCLUDED.downstream_sequence, - downstream_source = EXCLUDED.downstream_source, - install_status = EXCLUDED.install_status, - preflight_state = EXCLUDED.preflight_state, - skip_preflights = EXCLUDED.skip_preflights, - repl_helm_installs = EXCLUDED.repl_helm_installs, - native_helm_installs = EXCLUDED.native_helm_installs` - - statement := gorqlite.ParameterizedStatement{ - Query: query, - Arguments: []interface{}{ - createdAt.UnixMilli(), - licenseID, - reportingInfo.InstanceID, - reportingInfo.ClusterID, - reportingInfo.AppStatus, - reportingInfo.IsKurl, - reportingInfo.KurlNodeCountTotal, - reportingInfo.KurlNodeCountReady, - reportingInfo.K8sVersion, - reportingInfo.KOTSVersion, - reportingInfo.KOTSInstallID, - reportingInfo.KURLInstallID, - reportingInfo.IsGitOpsEnabled, - reportingInfo.GitOpsProvider, - downstreamSequence, - reportingInfo.Downstream.ChannelID, - reportingInfo.Downstream.ChannelName, - reportingInfo.Downstream.Sequence, - reportingInfo.Downstream.Source, - reportingInfo.Downstream.Status, - reportingInfo.Downstream.PreflightState, - reportingInfo.Downstream.SkipPreflights, - reportingInfo.Downstream.ReplHelmInstalls, - reportingInfo.Downstream.NativeHelmInstalls, - }, - } - - wr, err := db.WriteOneParameterized(statement) - if err != nil { - return fmt.Errorf("failed to write instance report: %v: %v", err, wr.Err) - } - - go func() { - err := s.removeOldReportingData("instance_report") - if err != nil { - logger.Warnf("failed to delete old data from instance_report: %v", err) - } - }() - - return nil -} - -func (s *KOTSStore) removeOldReportingData(reportingTable string) error { - db := persistence.MustGetDBSession() - - query := fmt.Sprintf(`select count(1) from %s`, reportingTable) - rows, err := db.QueryOneParameterized(gorqlite.ParameterizedStatement{ - Query: query, - }) - if err != nil { - return fmt.Errorf("failed to query number of rows: %v: %v", err, rows.Err) - } - - if !rows.Next() { - return ErrNotFound - } - - var numRows int64 - if err := rows.Scan(&numRows); err != nil { - return errors.Wrap(err, "failed to scan number of rows") - } - - reportingMaxRows := int64(4000) // at 10 records per day, this is more than a year of data - if numRows <= reportingMaxRows { - logger.Debugf("no old data to delete from %s", reportingTable) - return nil - } - - query = fmt.Sprintf(`select created_at from %s order by created_at desc limit ?, 1`, reportingTable) - rows, err = db.QueryOneParameterized(gorqlite.ParameterizedStatement{ - Query: query, - Arguments: []interface{}{ - reportingMaxRows, - }, - }) - if err != nil { - return fmt.Errorf("failed to query timestamp: %v: %v", err, rows.Err) - } - - if !rows.Next() { - return ErrNotFound - } - - // timestamps are stored with millisecond precision, but scanning directly into a Time variable assumes second precision - var timeMs int64 - if err := rows.Scan(&timeMs); err != nil { - return errors.Wrap(err, "failed to scan timestamp") - } - oldestCreatedAt := time.UnixMilli(timeMs) - - query = fmt.Sprintf(`delete from %s where created_at <= ?`, reportingTable) - wr, err := db.WriteOneParameterized(gorqlite.ParameterizedStatement{ - Query: query, - Arguments: []interface{}{ - oldestCreatedAt.UnixMilli(), - }, - }) - if err != nil { - return fmt.Errorf("failed to delete: %v: %v", err, wr.Err) - } - - return nil -} diff --git a/pkg/store/mock/mock.go b/pkg/store/mock/mock.go index a71c1b9f57..7a0eacccc2 100644 --- a/pkg/store/mock/mock.go +++ b/pkg/store/mock/mock.go @@ -12,21 +12,20 @@ import ( gomock "github.com/golang/mock/gomock" types "github.com/replicatedhq/kots/pkg/airgap/types" types0 "github.com/replicatedhq/kots/pkg/api/downstream/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" + 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" v1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1" redact "github.com/replicatedhq/troubleshoot/pkg/redact" ) @@ -111,10 +110,10 @@ func (mr *MockStoreMockRecorder) ClearTaskStatus(taskID interface{}) *gomock.Cal } // CreateApp mocks base method. -func (m *MockStore) CreateApp(name, upstreamURI, licenseData string, isAirgapEnabled, skipImagePush, registryIsReadOnly bool) (*types3.App, error) { +func (m *MockStore) CreateApp(name, upstreamURI, licenseData string, isAirgapEnabled, skipImagePush, registryIsReadOnly bool) (*types2.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateApp", name, upstreamURI, licenseData, isAirgapEnabled, skipImagePush, registryIsReadOnly) - ret0, _ := ret[0].(*types3.App) + ret0, _ := ret[0].(*types2.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -126,7 +125,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 types5.DownstreamGitOps, renderer types10.Renderer) (int64, error) { +func (m *MockStore) CreateAppVersion(appID string, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types4.DownstreamGitOps, renderer types9.Renderer) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateAppVersion", appID, baseSequence, filesInDir, source, skipPreflights, gitops, renderer) ret0, _ := ret[0].(int64) @@ -155,7 +154,7 @@ func (mr *MockStoreMockRecorder) CreateAppVersionArchive(appID, sequence, archiv } // CreateInProgressSupportBundle mocks base method. -func (m *MockStore) CreateInProgressSupportBundle(supportBundle *types13.SupportBundle) error { +func (m *MockStore) CreateInProgressSupportBundle(supportBundle *types12.SupportBundle) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateInProgressSupportBundle", supportBundle) ret0, _ := ret[0].(error) @@ -199,7 +198,7 @@ func (mr *MockStoreMockRecorder) CreateNewCluster(userID, isAllUsers, title, tok } // CreatePendingDownloadAppVersion mocks base method. -func (m *MockStore) CreatePendingDownloadAppVersion(appID string, update types14.Update, kotsApplication *v1beta1.Application, license *v1beta1.License) (int64, error) { +func (m *MockStore) CreatePendingDownloadAppVersion(appID string, update types13.Update, kotsApplication *v1beta1.Application, license *v1beta1.License) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreatePendingDownloadAppVersion", appID, update, kotsApplication, license) ret0, _ := ret[0].(int64) @@ -242,10 +241,10 @@ func (mr *MockStoreMockRecorder) CreateScheduledSnapshot(snapshotID, appID, time } // CreateSession mocks base method. -func (m *MockStore) CreateSession(user *types15.User, issuedAt, expiresAt time.Time, roles []string) (*types11.Session, error) { +func (m *MockStore) CreateSession(user *types14.User, issuedAt, expiresAt time.Time, roles []string) (*types10.Session, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateSession", user, issuedAt, expiresAt, roles) - ret0, _ := ret[0].(*types11.Session) + ret0, _ := ret[0].(*types10.Session) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -257,10 +256,10 @@ func (mr *MockStoreMockRecorder) CreateSession(user, issuedAt, expiresAt, roles } // CreateSupportBundle mocks base method. -func (m *MockStore) CreateSupportBundle(bundleID, appID, archivePath string, marshalledTree []byte) (*types13.SupportBundle, error) { +func (m *MockStore) CreateSupportBundle(bundleID, appID, archivePath string, marshalledTree []byte) (*types12.SupportBundle, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateSupportBundle", bundleID, appID, archivePath, marshalledTree) - ret0, _ := ret[0].(*types13.SupportBundle) + ret0, _ := ret[0].(*types12.SupportBundle) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -429,10 +428,10 @@ func (mr *MockStoreMockRecorder) GetAllAppLicenses() *gomock.Call { } // GetApp mocks base method. -func (m *MockStore) GetApp(appID string) (*types3.App, error) { +func (m *MockStore) GetApp(appID string) (*types2.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetApp", appID) - ret0, _ := ret[0].(*types3.App) + ret0, _ := ret[0].(*types2.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -444,10 +443,10 @@ func (mr *MockStoreMockRecorder) GetApp(appID interface{}) *gomock.Call { } // GetAppFromSlug mocks base method. -func (m *MockStore) GetAppFromSlug(slug string) (*types3.App, error) { +func (m *MockStore) GetAppFromSlug(slug string) (*types2.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAppFromSlug", slug) - ret0, _ := ret[0].(*types3.App) + ret0, _ := ret[0].(*types2.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -489,10 +488,10 @@ func (mr *MockStoreMockRecorder) GetAppIDsFromRegistry(hostname interface{}) *go } // GetAppStatus mocks base method. -func (m *MockStore) GetAppStatus(appID string) (*types4.AppStatus, error) { +func (m *MockStore) GetAppStatus(appID string) (*types3.AppStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAppStatus", appID) - ret0, _ := ret[0].(*types4.AppStatus) + ret0, _ := ret[0].(*types3.AppStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -504,10 +503,10 @@ func (mr *MockStoreMockRecorder) GetAppStatus(appID interface{}) *gomock.Call { } // GetAppVersion mocks base method. -func (m *MockStore) GetAppVersion(appID string, sequence int64) (*types2.AppVersion, error) { +func (m *MockStore) GetAppVersion(appID string, sequence int64) (*types1.AppVersion, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAppVersion", appID, sequence) - ret0, _ := ret[0].(*types2.AppVersion) + ret0, _ := ret[0].(*types1.AppVersion) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -714,10 +713,10 @@ func (mr *MockStoreMockRecorder) GetDownstreamVersionSource(appID, sequence inte } // GetDownstreamVersionStatus mocks base method. -func (m *MockStore) GetDownstreamVersionStatus(appID string, sequence int64) (types12.DownstreamVersionStatus, error) { +func (m *MockStore) GetDownstreamVersionStatus(appID string, sequence int64) (types11.DownstreamVersionStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetDownstreamVersionStatus", appID, sequence) - ret0, _ := ret[0].(types12.DownstreamVersionStatus) + ret0, _ := ret[0].(types11.DownstreamVersionStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -956,10 +955,10 @@ func (mr *MockStoreMockRecorder) GetPendingAirgapUploadApp() *gomock.Call { } // GetPendingInstallationStatus mocks base method. -func (m *MockStore) GetPendingInstallationStatus() (*types7.InstallStatus, error) { +func (m *MockStore) GetPendingInstallationStatus() (*types6.InstallStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPendingInstallationStatus") - ret0, _ := ret[0].(*types7.InstallStatus) + ret0, _ := ret[0].(*types6.InstallStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -986,10 +985,10 @@ func (mr *MockStoreMockRecorder) GetPreflightProgress(appID, sequence interface{ } // GetPreflightResults mocks base method. -func (m *MockStore) GetPreflightResults(appID string, sequence int64) (*types8.PreflightResult, error) { +func (m *MockStore) GetPreflightResults(appID string, sequence int64) (*types7.PreflightResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPreflightResults", appID, sequence) - ret0, _ := ret[0].(*types8.PreflightResult) + ret0, _ := ret[0].(*types7.PreflightResult) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1046,10 +1045,10 @@ func (mr *MockStoreMockRecorder) GetRedactions(bundleID interface{}) *gomock.Cal } // GetRegistryDetailsForApp mocks base method. -func (m *MockStore) GetRegistryDetailsForApp(appID string) (types9.RegistrySettings, error) { +func (m *MockStore) GetRegistryDetailsForApp(appID string) (types8.RegistrySettings, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetRegistryDetailsForApp", appID) - ret0, _ := ret[0].(types9.RegistrySettings) + ret0, _ := ret[0].(types8.RegistrySettings) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1061,10 +1060,10 @@ func (mr *MockStoreMockRecorder) GetRegistryDetailsForApp(appID interface{}) *go } // GetSession mocks base method. -func (m *MockStore) GetSession(sessionID string) (*types11.Session, error) { +func (m *MockStore) GetSession(sessionID string) (*types10.Session, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSession", sessionID) - ret0, _ := ret[0].(*types11.Session) + ret0, _ := ret[0].(*types10.Session) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1091,10 +1090,10 @@ func (mr *MockStoreMockRecorder) GetSharedPasswordBcrypt() *gomock.Call { } // GetStatusForVersion mocks base method. -func (m *MockStore) GetStatusForVersion(appID, clusterID string, sequence int64) (types12.DownstreamVersionStatus, error) { +func (m *MockStore) GetStatusForVersion(appID, clusterID string, sequence int64) (types11.DownstreamVersionStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetStatusForVersion", appID, clusterID, sequence) - ret0, _ := ret[0].(types12.DownstreamVersionStatus) + ret0, _ := ret[0].(types11.DownstreamVersionStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1106,10 +1105,10 @@ func (mr *MockStoreMockRecorder) GetStatusForVersion(appID, clusterID, sequence } // GetSupportBundle mocks base method. -func (m *MockStore) GetSupportBundle(bundleID string) (*types13.SupportBundle, error) { +func (m *MockStore) GetSupportBundle(bundleID string) (*types12.SupportBundle, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSupportBundle", bundleID) - ret0, _ := ret[0].(*types13.SupportBundle) + ret0, _ := ret[0].(*types12.SupportBundle) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1121,10 +1120,10 @@ func (mr *MockStoreMockRecorder) GetSupportBundle(bundleID interface{}) *gomock. } // GetSupportBundleAnalysis mocks base method. -func (m *MockStore) GetSupportBundleAnalysis(bundleID string) (*types13.SupportBundleAnalysis, error) { +func (m *MockStore) GetSupportBundleAnalysis(bundleID string) (*types12.SupportBundleAnalysis, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSupportBundleAnalysis", bundleID) - ret0, _ := ret[0].(*types13.SupportBundleAnalysis) + ret0, _ := ret[0].(*types12.SupportBundleAnalysis) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1316,7 +1315,7 @@ func (mr *MockStoreMockRecorder) IsRollbackSupportedForVersion(appID, sequence i } // IsSnapshotsSupportedForVersion mocks base method. -func (m *MockStore) IsSnapshotsSupportedForVersion(a *types3.App, sequence int64, renderer types10.Renderer) (bool, error) { +func (m *MockStore) IsSnapshotsSupportedForVersion(a *types2.App, sequence int64, renderer types9.Renderer) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsSnapshotsSupportedForVersion", a, sequence, renderer) ret0, _ := ret[0].(bool) @@ -1331,10 +1330,10 @@ func (mr *MockStoreMockRecorder) IsSnapshotsSupportedForVersion(a, sequence, ren } // ListAppsForDownstream mocks base method. -func (m *MockStore) ListAppsForDownstream(clusterID string) ([]*types3.App, error) { +func (m *MockStore) ListAppsForDownstream(clusterID string) ([]*types2.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListAppsForDownstream", clusterID) - ret0, _ := ret[0].([]*types3.App) + ret0, _ := ret[0].([]*types2.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1376,10 +1375,10 @@ func (mr *MockStoreMockRecorder) ListDownstreamsForApp(appID interface{}) *gomoc } // ListFailedApps mocks base method. -func (m *MockStore) ListFailedApps() ([]*types3.App, error) { +func (m *MockStore) ListFailedApps() ([]*types2.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListFailedApps") - ret0, _ := ret[0].([]*types3.App) + ret0, _ := ret[0].([]*types2.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1406,10 +1405,10 @@ func (mr *MockStoreMockRecorder) ListInstalledAppSlugs() *gomock.Call { } // ListInstalledApps mocks base method. -func (m *MockStore) ListInstalledApps() ([]*types3.App, error) { +func (m *MockStore) ListInstalledApps() ([]*types2.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListInstalledApps") - ret0, _ := ret[0].([]*types3.App) + ret0, _ := ret[0].([]*types2.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1421,10 +1420,10 @@ func (mr *MockStoreMockRecorder) ListInstalledApps() *gomock.Call { } // ListPendingScheduledInstanceSnapshots mocks base method. -func (m *MockStore) ListPendingScheduledInstanceSnapshots(clusterID string) ([]types6.ScheduledInstanceSnapshot, error) { +func (m *MockStore) ListPendingScheduledInstanceSnapshots(clusterID string) ([]types5.ScheduledInstanceSnapshot, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListPendingScheduledInstanceSnapshots", clusterID) - ret0, _ := ret[0].([]types6.ScheduledInstanceSnapshot) + ret0, _ := ret[0].([]types5.ScheduledInstanceSnapshot) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1436,10 +1435,10 @@ func (mr *MockStoreMockRecorder) ListPendingScheduledInstanceSnapshots(clusterID } // ListPendingScheduledSnapshots mocks base method. -func (m *MockStore) ListPendingScheduledSnapshots(appID string) ([]types6.ScheduledSnapshot, error) { +func (m *MockStore) ListPendingScheduledSnapshots(appID string) ([]types5.ScheduledSnapshot, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListPendingScheduledSnapshots", appID) - ret0, _ := ret[0].([]types6.ScheduledSnapshot) + ret0, _ := ret[0].([]types5.ScheduledSnapshot) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1451,10 +1450,10 @@ func (mr *MockStoreMockRecorder) ListPendingScheduledSnapshots(appID interface{} } // ListSupportBundles mocks base method. -func (m *MockStore) ListSupportBundles(appID string) ([]*types13.SupportBundle, error) { +func (m *MockStore) ListSupportBundles(appID string) ([]*types12.SupportBundle, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListSupportBundles", appID) - ret0, _ := ret[0].([]*types13.SupportBundle) + ret0, _ := ret[0].([]*types12.SupportBundle) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1533,34 +1532,6 @@ func (mr *MockStoreMockRecorder) RunMigrations() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunMigrations", reflect.TypeOf((*MockStore)(nil).RunMigrations)) } -// SavePreflightReport mocks base method. -func (m *MockStore) SavePreflightReport(licenseID string, preflightStatus *types1.PreflightStatus) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SavePreflightReport", licenseID, preflightStatus) - ret0, _ := ret[0].(error) - return ret0 -} - -// SavePreflightReport indicates an expected call of SavePreflightReport. -func (mr *MockStoreMockRecorder) SavePreflightReport(licenseID, preflightStatus interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SavePreflightReport", reflect.TypeOf((*MockStore)(nil).SavePreflightReport), licenseID, preflightStatus) -} - -// SaveReportingInfo mocks base method. -func (m *MockStore) SaveReportingInfo(licenseID string, reportingInfo *types1.ReportingInfo) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SaveReportingInfo", licenseID, reportingInfo) - ret0, _ := ret[0].(error) - return ret0 -} - -// SaveReportingInfo indicates an expected call of SaveReportingInfo. -func (mr *MockStoreMockRecorder) SaveReportingInfo(licenseID, reportingInfo interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveReportingInfo", reflect.TypeOf((*MockStore)(nil).SaveReportingInfo), licenseID, reportingInfo) -} - // SetAppChannelChanged mocks base method. func (m *MockStore) SetAppChannelChanged(appID string, channelChanged bool) error { m.ctrl.T.Helper() @@ -1604,7 +1575,7 @@ func (mr *MockStoreMockRecorder) SetAppIsAirgap(appID, isAirgap interface{}) *go } // SetAppStatus mocks base method. -func (m *MockStore) SetAppStatus(appID string, resourceStates types4.ResourceStates, updatedAt time.Time, sequence int64) error { +func (m *MockStore) SetAppStatus(appID string, resourceStates types3.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) @@ -1618,7 +1589,7 @@ func (mr *MockStoreMockRecorder) SetAppStatus(appID, resourceStates, updatedAt, } // SetAutoDeploy mocks base method. -func (m *MockStore) SetAutoDeploy(appID string, autoDeploy types3.AutoDeploy) error { +func (m *MockStore) SetAutoDeploy(appID string, autoDeploy types2.AutoDeploy) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SetAutoDeploy", appID, autoDeploy) ret0, _ := ret[0].(error) @@ -1632,7 +1603,7 @@ func (mr *MockStoreMockRecorder) SetAutoDeploy(appID, autoDeploy interface{}) *g } // SetDownstreamVersionStatus mocks base method. -func (m *MockStore) SetDownstreamVersionStatus(appID string, sequence int64, status types12.DownstreamVersionStatus, statusInfo string) error { +func (m *MockStore) SetDownstreamVersionStatus(appID string, sequence int64, status types11.DownstreamVersionStatus, statusInfo string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SetDownstreamVersionStatus", appID, sequence, status, statusInfo) ret0, _ := ret[0].(error) @@ -1857,7 +1828,7 @@ func (mr *MockStoreMockRecorder) SetUpdateCheckerSpec(appID, updateCheckerSpec i } // UpdateAppLicense mocks base method. -func (m *MockStore) UpdateAppLicense(appID string, sequence int64, archiveDir string, newLicense *v1beta1.License, originalLicenseData string, channelChanged, failOnVersionCreate bool, gitops types5.DownstreamGitOps, renderer types10.Renderer) (int64, error) { +func (m *MockStore) UpdateAppLicense(appID string, sequence int64, archiveDir string, newLicense *v1beta1.License, originalLicenseData string, channelChanged, failOnVersionCreate bool, gitops types4.DownstreamGitOps, renderer types9.Renderer) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateAppLicense", appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer) ret0, _ := ret[0].(int64) @@ -1886,7 +1857,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 types5.DownstreamGitOps, renderer types10.Renderer) error { +func (m *MockStore) UpdateAppVersion(appID string, sequence int64, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types4.DownstreamGitOps, renderer types9.Renderer) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateAppVersion", appID, sequence, baseSequence, filesInDir, source, skipPreflights, gitops, renderer) ret0, _ := ret[0].(error) @@ -1998,7 +1969,7 @@ func (mr *MockStoreMockRecorder) UpdateSessionExpiresAt(sessionID, expiresAt int } // UpdateSupportBundle mocks base method. -func (m *MockStore) UpdateSupportBundle(bundle *types13.SupportBundle) error { +func (m *MockStore) UpdateSupportBundle(bundle *types12.SupportBundle) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateSupportBundle", bundle) ret0, _ := ret[0].(error) @@ -2127,10 +2098,10 @@ func (mr *MockRegistryStoreMockRecorder) GetAppIDsFromRegistry(hostname interfac } // GetRegistryDetailsForApp mocks base method. -func (m *MockRegistryStore) GetRegistryDetailsForApp(appID string) (types9.RegistrySettings, error) { +func (m *MockRegistryStore) GetRegistryDetailsForApp(appID string) (types8.RegistrySettings, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetRegistryDetailsForApp", appID) - ret0, _ := ret[0].(types9.RegistrySettings) + ret0, _ := ret[0].(types8.RegistrySettings) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2179,7 +2150,7 @@ func (m *MockSupportBundleStore) EXPECT() *MockSupportBundleStoreMockRecorder { } // CreateInProgressSupportBundle mocks base method. -func (m *MockSupportBundleStore) CreateInProgressSupportBundle(supportBundle *types13.SupportBundle) error { +func (m *MockSupportBundleStore) CreateInProgressSupportBundle(supportBundle *types12.SupportBundle) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateInProgressSupportBundle", supportBundle) ret0, _ := ret[0].(error) @@ -2193,10 +2164,10 @@ func (mr *MockSupportBundleStoreMockRecorder) CreateInProgressSupportBundle(supp } // CreateSupportBundle mocks base method. -func (m *MockSupportBundleStore) CreateSupportBundle(bundleID, appID, archivePath string, marshalledTree []byte) (*types13.SupportBundle, error) { +func (m *MockSupportBundleStore) CreateSupportBundle(bundleID, appID, archivePath string, marshalledTree []byte) (*types12.SupportBundle, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateSupportBundle", bundleID, appID, archivePath, marshalledTree) - ret0, _ := ret[0].(*types13.SupportBundle) + ret0, _ := ret[0].(*types12.SupportBundle) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2237,10 +2208,10 @@ func (mr *MockSupportBundleStoreMockRecorder) GetRedactions(bundleID interface{} } // GetSupportBundle mocks base method. -func (m *MockSupportBundleStore) GetSupportBundle(bundleID string) (*types13.SupportBundle, error) { +func (m *MockSupportBundleStore) GetSupportBundle(bundleID string) (*types12.SupportBundle, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSupportBundle", bundleID) - ret0, _ := ret[0].(*types13.SupportBundle) + ret0, _ := ret[0].(*types12.SupportBundle) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2252,10 +2223,10 @@ func (mr *MockSupportBundleStoreMockRecorder) GetSupportBundle(bundleID interfac } // GetSupportBundleAnalysis mocks base method. -func (m *MockSupportBundleStore) GetSupportBundleAnalysis(bundleID string) (*types13.SupportBundleAnalysis, error) { +func (m *MockSupportBundleStore) GetSupportBundleAnalysis(bundleID string) (*types12.SupportBundleAnalysis, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSupportBundleAnalysis", bundleID) - ret0, _ := ret[0].(*types13.SupportBundleAnalysis) + ret0, _ := ret[0].(*types12.SupportBundleAnalysis) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2282,10 +2253,10 @@ func (mr *MockSupportBundleStoreMockRecorder) GetSupportBundleArchive(bundleID i } // ListSupportBundles mocks base method. -func (m *MockSupportBundleStore) ListSupportBundles(appID string) ([]*types13.SupportBundle, error) { +func (m *MockSupportBundleStore) ListSupportBundles(appID string) ([]*types12.SupportBundle, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListSupportBundles", appID) - ret0, _ := ret[0].([]*types13.SupportBundle) + ret0, _ := ret[0].([]*types12.SupportBundle) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2325,7 +2296,7 @@ func (mr *MockSupportBundleStoreMockRecorder) SetSupportBundleAnalysis(bundleID, } // UpdateSupportBundle mocks base method. -func (m *MockSupportBundleStore) UpdateSupportBundle(bundle *types13.SupportBundle) error { +func (m *MockSupportBundleStore) UpdateSupportBundle(bundle *types12.SupportBundle) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateSupportBundle", bundle) ret0, _ := ret[0].(error) @@ -2391,10 +2362,10 @@ func (mr *MockPreflightStoreMockRecorder) GetPreflightProgress(appID, sequence i } // GetPreflightResults mocks base method. -func (m *MockPreflightStore) GetPreflightResults(appID string, sequence int64) (*types8.PreflightResult, error) { +func (m *MockPreflightStore) GetPreflightResults(appID string, sequence int64) (*types7.PreflightResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPreflightResults", appID, sequence) - ret0, _ := ret[0].(*types8.PreflightResult) + ret0, _ := ret[0].(*types7.PreflightResult) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2699,10 +2670,10 @@ func (m *MockSessionStore) EXPECT() *MockSessionStoreMockRecorder { } // CreateSession mocks base method. -func (m *MockSessionStore) CreateSession(user *types15.User, issuedAt, expiresAt time.Time, roles []string) (*types11.Session, error) { +func (m *MockSessionStore) CreateSession(user *types14.User, issuedAt, expiresAt time.Time, roles []string) (*types10.Session, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateSession", user, issuedAt, expiresAt, roles) - ret0, _ := ret[0].(*types11.Session) + ret0, _ := ret[0].(*types10.Session) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2742,10 +2713,10 @@ func (mr *MockSessionStoreMockRecorder) DeleteSession(sessionID interface{}) *go } // GetSession mocks base method. -func (m *MockSessionStore) GetSession(sessionID string) (*types11.Session, error) { +func (m *MockSessionStore) GetSession(sessionID string) (*types10.Session, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSession", sessionID) - ret0, _ := ret[0].(*types11.Session) + ret0, _ := ret[0].(*types10.Session) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2794,10 +2765,10 @@ func (m *MockAppStatusStore) EXPECT() *MockAppStatusStoreMockRecorder { } // GetAppStatus mocks base method. -func (m *MockAppStatusStore) GetAppStatus(appID string) (*types4.AppStatus, error) { +func (m *MockAppStatusStore) GetAppStatus(appID string) (*types3.AppStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAppStatus", appID) - ret0, _ := ret[0].(*types4.AppStatus) + ret0, _ := ret[0].(*types3.AppStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2809,7 +2780,7 @@ func (mr *MockAppStatusStoreMockRecorder) GetAppStatus(appID interface{}) *gomoc } // SetAppStatus mocks base method. -func (m *MockAppStatusStore) SetAppStatus(appID string, resourceStates types4.ResourceStates, updatedAt time.Time, sequence int64) error { +func (m *MockAppStatusStore) SetAppStatus(appID string, resourceStates types3.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) @@ -2860,10 +2831,10 @@ func (mr *MockAppStoreMockRecorder) AddAppToAllDownstreams(appID interface{}) *g } // CreateApp mocks base method. -func (m *MockAppStore) CreateApp(name, upstreamURI, licenseData string, isAirgapEnabled, skipImagePush, registryIsReadOnly bool) (*types3.App, error) { +func (m *MockAppStore) CreateApp(name, upstreamURI, licenseData string, isAirgapEnabled, skipImagePush, registryIsReadOnly bool) (*types2.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateApp", name, upstreamURI, licenseData, isAirgapEnabled, skipImagePush, registryIsReadOnly) - ret0, _ := ret[0].(*types3.App) + ret0, _ := ret[0].(*types2.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2875,10 +2846,10 @@ func (mr *MockAppStoreMockRecorder) CreateApp(name, upstreamURI, licenseData, is } // GetApp mocks base method. -func (m *MockAppStore) GetApp(appID string) (*types3.App, error) { +func (m *MockAppStore) GetApp(appID string) (*types2.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetApp", appID) - ret0, _ := ret[0].(*types3.App) + ret0, _ := ret[0].(*types2.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2890,10 +2861,10 @@ func (mr *MockAppStoreMockRecorder) GetApp(appID interface{}) *gomock.Call { } // GetAppFromSlug mocks base method. -func (m *MockAppStore) GetAppFromSlug(slug string) (*types3.App, error) { +func (m *MockAppStore) GetAppFromSlug(slug string) (*types2.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAppFromSlug", slug) - ret0, _ := ret[0].(*types3.App) + ret0, _ := ret[0].(*types2.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2950,10 +2921,10 @@ func (mr *MockAppStoreMockRecorder) IsGitOpsEnabledForApp(appID interface{}) *go } // ListAppsForDownstream mocks base method. -func (m *MockAppStore) ListAppsForDownstream(clusterID string) ([]*types3.App, error) { +func (m *MockAppStore) ListAppsForDownstream(clusterID string) ([]*types2.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListAppsForDownstream", clusterID) - ret0, _ := ret[0].([]*types3.App) + ret0, _ := ret[0].([]*types2.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2980,10 +2951,10 @@ func (mr *MockAppStoreMockRecorder) ListDownstreamsForApp(appID interface{}) *go } // ListFailedApps mocks base method. -func (m *MockAppStore) ListFailedApps() ([]*types3.App, error) { +func (m *MockAppStore) ListFailedApps() ([]*types2.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListFailedApps") - ret0, _ := ret[0].([]*types3.App) + ret0, _ := ret[0].([]*types2.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3010,10 +2981,10 @@ func (mr *MockAppStoreMockRecorder) ListInstalledAppSlugs() *gomock.Call { } // ListInstalledApps mocks base method. -func (m *MockAppStore) ListInstalledApps() ([]*types3.App, error) { +func (m *MockAppStore) ListInstalledApps() ([]*types2.App, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListInstalledApps") - ret0, _ := ret[0].([]*types3.App) + ret0, _ := ret[0].([]*types2.App) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3067,7 +3038,7 @@ func (mr *MockAppStoreMockRecorder) SetAppInstallState(appID, state interface{}) } // SetAutoDeploy mocks base method. -func (m *MockAppStore) SetAutoDeploy(appID string, autoDeploy types3.AutoDeploy) error { +func (m *MockAppStore) SetAutoDeploy(appID string, autoDeploy types2.AutoDeploy) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SetAutoDeploy", appID, autoDeploy) ret0, _ := ret[0].(error) @@ -3293,10 +3264,10 @@ func (mr *MockDownstreamStoreMockRecorder) GetDownstreamVersionSource(appID, seq } // GetDownstreamVersionStatus mocks base method. -func (m *MockDownstreamStore) GetDownstreamVersionStatus(appID string, sequence int64) (types12.DownstreamVersionStatus, error) { +func (m *MockDownstreamStore) GetDownstreamVersionStatus(appID string, sequence int64) (types11.DownstreamVersionStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetDownstreamVersionStatus", appID, sequence) - ret0, _ := ret[0].(types12.DownstreamVersionStatus) + ret0, _ := ret[0].(types11.DownstreamVersionStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3385,10 +3356,10 @@ func (mr *MockDownstreamStoreMockRecorder) GetPreviouslyDeployedSequence(appID, } // GetStatusForVersion mocks base method. -func (m *MockDownstreamStore) GetStatusForVersion(appID, clusterID string, sequence int64) (types12.DownstreamVersionStatus, error) { +func (m *MockDownstreamStore) GetStatusForVersion(appID, clusterID string, sequence int64) (types11.DownstreamVersionStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetStatusForVersion", appID, clusterID, sequence) - ret0, _ := ret[0].(types12.DownstreamVersionStatus) + ret0, _ := ret[0].(types11.DownstreamVersionStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3445,7 +3416,7 @@ func (mr *MockDownstreamStoreMockRecorder) MarkAsCurrentDownstreamVersion(appID, } // SetDownstreamVersionStatus mocks base method. -func (m *MockDownstreamStore) SetDownstreamVersionStatus(appID string, sequence int64, status types12.DownstreamVersionStatus, statusInfo string) error { +func (m *MockDownstreamStore) SetDownstreamVersionStatus(appID string, sequence int64, status types11.DownstreamVersionStatus, statusInfo string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SetDownstreamVersionStatus", appID, sequence, status, statusInfo) ret0, _ := ret[0].(error) @@ -3552,10 +3523,10 @@ func (mr *MockSnapshotStoreMockRecorder) DeletePendingScheduledSnapshots(appID i } // ListPendingScheduledInstanceSnapshots mocks base method. -func (m *MockSnapshotStore) ListPendingScheduledInstanceSnapshots(clusterID string) ([]types6.ScheduledInstanceSnapshot, error) { +func (m *MockSnapshotStore) ListPendingScheduledInstanceSnapshots(clusterID string) ([]types5.ScheduledInstanceSnapshot, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListPendingScheduledInstanceSnapshots", clusterID) - ret0, _ := ret[0].([]types6.ScheduledInstanceSnapshot) + ret0, _ := ret[0].([]types5.ScheduledInstanceSnapshot) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3567,10 +3538,10 @@ func (mr *MockSnapshotStoreMockRecorder) ListPendingScheduledInstanceSnapshots(c } // ListPendingScheduledSnapshots mocks base method. -func (m *MockSnapshotStore) ListPendingScheduledSnapshots(appID string) ([]types6.ScheduledSnapshot, error) { +func (m *MockSnapshotStore) ListPendingScheduledSnapshots(appID string) ([]types5.ScheduledSnapshot, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListPendingScheduledSnapshots", appID) - ret0, _ := ret[0].([]types6.ScheduledSnapshot) + ret0, _ := ret[0].([]types5.ScheduledSnapshot) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3633,7 +3604,7 @@ func (m *MockVersionStore) EXPECT() *MockVersionStoreMockRecorder { } // CreateAppVersion mocks base method. -func (m *MockVersionStore) CreateAppVersion(appID string, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types5.DownstreamGitOps, renderer types10.Renderer) (int64, error) { +func (m *MockVersionStore) CreateAppVersion(appID string, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types4.DownstreamGitOps, renderer types9.Renderer) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateAppVersion", appID, baseSequence, filesInDir, source, skipPreflights, gitops, renderer) ret0, _ := ret[0].(int64) @@ -3662,7 +3633,7 @@ func (mr *MockVersionStoreMockRecorder) CreateAppVersionArchive(appID, sequence, } // CreatePendingDownloadAppVersion mocks base method. -func (m *MockVersionStore) CreatePendingDownloadAppVersion(appID string, update types14.Update, kotsApplication *v1beta1.Application, license *v1beta1.License) (int64, error) { +func (m *MockVersionStore) CreatePendingDownloadAppVersion(appID string, update types13.Update, kotsApplication *v1beta1.Application, license *v1beta1.License) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreatePendingDownloadAppVersion", appID, update, kotsApplication, license) ret0, _ := ret[0].(int64) @@ -3677,10 +3648,10 @@ func (mr *MockVersionStoreMockRecorder) CreatePendingDownloadAppVersion(appID, u } // GetAppVersion mocks base method. -func (m *MockVersionStore) GetAppVersion(appID string, sequence int64) (*types2.AppVersion, error) { +func (m *MockVersionStore) GetAppVersion(appID string, sequence int64) (*types1.AppVersion, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAppVersion", appID, sequence) - ret0, _ := ret[0].(*types2.AppVersion) + ret0, _ := ret[0].(*types1.AppVersion) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -3842,7 +3813,7 @@ func (mr *MockVersionStoreMockRecorder) IsRollbackSupportedForVersion(appID, seq } // IsSnapshotsSupportedForVersion mocks base method. -func (m *MockVersionStore) IsSnapshotsSupportedForVersion(a *types3.App, sequence int64, renderer types10.Renderer) (bool, error) { +func (m *MockVersionStore) IsSnapshotsSupportedForVersion(a *types2.App, sequence int64, renderer types9.Renderer) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsSnapshotsSupportedForVersion", a, sequence, renderer) ret0, _ := ret[0].(bool) @@ -3857,7 +3828,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 types5.DownstreamGitOps, renderer types10.Renderer) error { +func (m *MockVersionStore) UpdateAppVersion(appID string, sequence int64, baseSequence *int64, filesInDir, source string, skipPreflights bool, gitops types4.DownstreamGitOps, renderer types9.Renderer) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateAppVersion", appID, sequence, baseSequence, filesInDir, source, skipPreflights, gitops, renderer) ret0, _ := ret[0].(error) @@ -3967,7 +3938,7 @@ func (mr *MockLicenseStoreMockRecorder) GetLicenseForAppVersion(appID, sequence } // UpdateAppLicense mocks base method. -func (m *MockLicenseStore) UpdateAppLicense(appID string, sequence int64, archiveDir string, newLicense *v1beta1.License, originalLicenseData string, channelChanged, failOnVersionCreate bool, gitops types5.DownstreamGitOps, renderer types10.Renderer) (int64, error) { +func (m *MockLicenseStore) UpdateAppLicense(appID string, sequence int64, archiveDir string, newLicense *v1beta1.License, originalLicenseData string, channelChanged, failOnVersionCreate bool, gitops types4.DownstreamGitOps, renderer types9.Renderer) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateAppLicense", appID, sequence, archiveDir, newLicense, originalLicenseData, channelChanged, failOnVersionCreate, gitops, renderer) ret0, _ := ret[0].(int64) @@ -4211,10 +4182,10 @@ func (m *MockInstallationStore) EXPECT() *MockInstallationStoreMockRecorder { } // GetPendingInstallationStatus mocks base method. -func (m *MockInstallationStore) GetPendingInstallationStatus() (*types7.InstallStatus, error) { +func (m *MockInstallationStore) GetPendingInstallationStatus() (*types6.InstallStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetPendingInstallationStatus") - ret0, _ := ret[0].(*types7.InstallStatus) + ret0, _ := ret[0].(*types6.InstallStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -4412,57 +4383,6 @@ func (mr *MockBrandingStoreMockRecorder) GetLatestBrandingForApp(appID interface return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLatestBrandingForApp", reflect.TypeOf((*MockBrandingStore)(nil).GetLatestBrandingForApp), appID) } -// MockReportingStore is a mock of ReportingStore interface. -type MockReportingStore struct { - ctrl *gomock.Controller - recorder *MockReportingStoreMockRecorder -} - -// MockReportingStoreMockRecorder is the mock recorder for MockReportingStore. -type MockReportingStoreMockRecorder struct { - mock *MockReportingStore -} - -// NewMockReportingStore creates a new mock instance. -func NewMockReportingStore(ctrl *gomock.Controller) *MockReportingStore { - mock := &MockReportingStore{ctrl: ctrl} - mock.recorder = &MockReportingStoreMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockReportingStore) EXPECT() *MockReportingStoreMockRecorder { - return m.recorder -} - -// SavePreflightReport mocks base method. -func (m *MockReportingStore) SavePreflightReport(licenseID string, preflightStatus *types1.PreflightStatus) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SavePreflightReport", licenseID, preflightStatus) - ret0, _ := ret[0].(error) - return ret0 -} - -// SavePreflightReport indicates an expected call of SavePreflightReport. -func (mr *MockReportingStoreMockRecorder) SavePreflightReport(licenseID, preflightStatus interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SavePreflightReport", reflect.TypeOf((*MockReportingStore)(nil).SavePreflightReport), licenseID, preflightStatus) -} - -// SaveReportingInfo mocks base method. -func (m *MockReportingStore) SaveReportingInfo(licenseID string, reportingInfo *types1.ReportingInfo) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SaveReportingInfo", licenseID, reportingInfo) - ret0, _ := ret[0].(error) - return ret0 -} - -// SaveReportingInfo indicates an expected call of SaveReportingInfo. -func (mr *MockReportingStoreMockRecorder) SaveReportingInfo(licenseID, reportingInfo interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveReportingInfo", reflect.TypeOf((*MockReportingStore)(nil).SaveReportingInfo), licenseID, reportingInfo) -} - // MockEmbeddedClusterStore is a mock of EmbeddedClusterStore interface. type MockEmbeddedClusterStore struct { ctrl *gomock.Controller diff --git a/pkg/store/store_interface.go b/pkg/store/store_interface.go index 34b5872db2..5038c1b6ad 100644 --- a/pkg/store/store_interface.go +++ b/pkg/store/store_interface.go @@ -6,7 +6,6 @@ import ( 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" @@ -46,7 +45,6 @@ type Store interface { KotsadmParamsStore EmbeddedStore BrandingStore - ReportingStore EmbeddedClusterStore Init() error // this may need options @@ -250,11 +248,6 @@ type BrandingStore interface { GetLatestBrandingForApp(appID string) ([]byte, error) } -type ReportingStore interface { - SavePreflightReport(licenseID string, preflightStatus *reportingtypes.PreflightStatus) error - SaveReportingInfo(licenseID string, reportingInfo *reportingtypes.ReportingInfo) error -} - type EmbeddedClusterStore interface { SetEmbeddedClusterInstallCommandRoles(roles []string) (string, error) GetEmbeddedClusterInstallCommandRoles(token string) ([]string, error) diff --git a/pkg/supportbundle/spec.go b/pkg/supportbundle/spec.go index b958df61b4..181cff1d82 100644 --- a/pkg/supportbundle/spec.go +++ b/pkg/supportbundle/spec.go @@ -805,6 +805,28 @@ func getDefaultDynamicCollectors(app apptypes.AppType, imageName string, pullSec }, }) + collectors = append(collectors, &troubleshootv1beta2.Collect{ + Secret: &troubleshootv1beta2.Secret{ + CollectorMeta: troubleshootv1beta2.CollectorMeta{ + CollectorName: fmt.Sprintf("kotsadm-%s-instance-report", app.GetSlug()), + }, + Name: fmt.Sprintf("kotsadm-%s-instance-report", app.GetSlug()), + Namespace: util.PodNamespace, + Key: "report", + IncludeValue: true, + }, + }, &troubleshootv1beta2.Collect{ + Secret: &troubleshootv1beta2.Secret{ + CollectorMeta: troubleshootv1beta2.CollectorMeta{ + CollectorName: fmt.Sprintf("kotsadm-%s-preflight-report", app.GetSlug()), + }, + Name: fmt.Sprintf("kotsadm-%s-preflight-report", app.GetSlug()), + Namespace: util.PodNamespace, + Key: "report", + IncludeValue: true, + }, + }) + collectors = append(collectors, makeVeleroCollectors()...) if app, ok := app.(*apptypes.App); ok { diff --git a/pkg/util/compress.go b/pkg/util/compress.go new file mode 100644 index 0000000000..e4c1fc1fa6 --- /dev/null +++ b/pkg/util/compress.go @@ -0,0 +1,42 @@ +package util + +import ( + "bytes" + "compress/gzip" + "io" + + "github.com/pkg/errors" +) + +func GzipData(input []byte) ([]byte, error) { + var buf bytes.Buffer + gw := gzip.NewWriter(&buf) + + _, err := gw.Write(input) + if err != nil { + return nil, errors.Wrap(err, "failed to write to gzip writer") + } + + err = gw.Close() + if err != nil { + return nil, errors.Wrap(err, "failed to close gzip writer") + } + + return buf.Bytes(), nil +} + +func GunzipData(input []byte) ([]byte, error) { + r := bytes.NewReader(input) + gr, err := gzip.NewReader(r) + if err != nil { + return nil, errors.Wrap(err, "failed to create gzip reader") + } + defer gr.Close() + + decompressedData, err := io.ReadAll(gr) + if err != nil { + return nil, errors.Wrap(err, "failed to read from gzip reader") + } + + return decompressedData, nil +}