Skip to content

Commit

Permalink
snapshot reporting (#4138)
Browse files Browse the repository at this point in the history
  • Loading branch information
Craig O'Donnell authored Nov 22, 2023
1 parent d0d8b35 commit 09f1c18
Show file tree
Hide file tree
Showing 15 changed files with 592 additions and 142 deletions.
33 changes: 19 additions & 14 deletions pkg/api/reporting/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@ package types

// This type is mimicked in the instance_report table.
type ReportingInfo struct {
InstanceID string `json:"instance_id"`
ClusterID string `json:"cluster_id"`
Downstream DownstreamInfo `json:"downstream"`
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"`
UserAgent string `json:"user_agent"`
KOTSInstallID string `json:"kots_install_id"`
KURLInstallID string `json:"kurl_install_id"`
IsGitOpsEnabled bool `json:"is_gitops_enabled"`
GitOpsProvider string `json:"gitops_provider"`
InstanceID string `json:"instance_id"`
ClusterID string `json:"cluster_id"`
Downstream DownstreamInfo `json:"downstream"`
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"`
UserAgent string `json:"user_agent"`
KOTSInstallID string `json:"kots_install_id"`
KURLInstallID string `json:"kurl_install_id"`
IsGitOpsEnabled bool `json:"is_gitops_enabled"`
GitOpsProvider string `json:"gitops_provider"`
SnapshotProvider string `json:"snapshot_provider"`
SnapshotFullSchedule string `json:"snapshot_full_schedule"`
SnapshotFullTTL string `json:"snapshot_full_ttl"`
SnapshotPartialSchedule string `json:"snapshot_partial_schedule"`
SnapshotPartialTTL string `json:"snapshot_partial_ttl"`
}

type DownstreamInfo struct {
Expand Down
29 changes: 28 additions & 1 deletion pkg/handlers/snapshot_logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,44 @@ import (

"github.com/gorilla/mux"
"github.com/pkg/errors"
"github.com/replicatedhq/kots/pkg/k8sutil"
snapshot "github.com/replicatedhq/kots/pkg/kotsadmsnapshot"
"github.com/replicatedhq/kots/pkg/logger"
kotssnapshot "github.com/replicatedhq/kots/pkg/snapshot"
"github.com/replicatedhq/kots/pkg/util"
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
veleroclientv1 "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1"
"k8s.io/client-go/kubernetes"
)

func (h *Handler) DownloadSnapshotLogs(w http.ResponseWriter, r *http.Request) {
backupName := mux.Vars(r)["backup"]

bsl, err := kotssnapshot.FindBackupStoreLocation(r.Context(), util.PodNamespace)
cfg, err := k8sutil.GetClusterConfig()
if err != nil {
err = errors.Wrap(err, "failed to get cluster config")
logger.Error(err)
w.WriteHeader(http.StatusInternalServerError)
return
}

clientset, err := kubernetes.NewForConfig(cfg)
if err != nil {
err = errors.Wrap(err, "failed to create clientset")
logger.Error(err)
w.WriteHeader(http.StatusInternalServerError)
return
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
if err != nil {
err = errors.Wrap(err, "failed to create velero clientset")
logger.Error(err)
w.WriteHeader(http.StatusInternalServerError)
return
}

bsl, err := kotssnapshot.FindBackupStoreLocation(r.Context(), clientset, veleroClient, util.PodNamespace)
if err != nil {
err = errors.Wrap(err, "failed to find backup store location")
logger.Error(err)
Expand Down
24 changes: 18 additions & 6 deletions pkg/kotsadm/minio.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/replicatedhq/kots/pkg/logger"
"github.com/replicatedhq/kots/pkg/snapshot"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
veleroclientv1 "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1"
corev1 "k8s.io/api/core/v1"
kuberneteserrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
Expand Down Expand Up @@ -180,7 +181,22 @@ func MigrateExistingMinioFilesystemDeployments(log *logger.CLILogger, deployOpti
}
veleroNamespace := veleroStatus.Namespace

bsl, err := snapshot.FindBackupStoreLocation(context.TODO(), deployOptions.Namespace)
cfg, err := k8sutil.GetClusterConfig()
if err != nil {
return errors.Wrap(err, "failed to get cluster config")
}

clientset, err := kubernetes.NewForConfig(cfg)
if err != nil {
return errors.Wrap(err, "failed to create clientset")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
if err != nil {
return errors.Wrap(err, "failed to create velero clientset")
}

bsl, err := snapshot.FindBackupStoreLocation(context.TODO(), clientset, veleroClient, deployOptions.Namespace)
if err != nil {
return errors.Wrap(err, "failed to find backupstoragelocations")
}
Expand Down Expand Up @@ -226,10 +242,6 @@ func MigrateExistingMinioFilesystemDeployments(log *logger.CLILogger, deployOpti
}

// Add the config map to configure the new plugin
clientset, err := k8sutil.GetClientset()
if err != nil {
return errors.Wrap(err, "failed to get k8s clientset")
}
fsDeployOptions := &snapshot.FileSystemDeployOptions{
Namespace: deployOptions.Namespace,
IsOpenShift: k8sutil.IsOpenShift(clientset),
Expand All @@ -250,7 +262,7 @@ func MigrateExistingMinioFilesystemDeployments(log *logger.CLILogger, deployOpti
success := false
defer func() {
if !success {
err := snapshot.RevertToMinioFS(context.TODO(), deployOptions.Namespace, veleroNamespace, previousBsl)
err := snapshot.RevertToMinioFS(context.TODO(), clientset, veleroClient, deployOptions.Namespace, veleroNamespace, previousBsl)
if err != nil {
log.Error(errors.Wrap(err, "Could not restore minio backup storage location"))
return
Expand Down
137 changes: 81 additions & 56 deletions pkg/kotsadmsnapshot/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,23 @@ func CreateApplicationBackup(ctx context.Context, a *apptypes.App, isScheduled b
return nil, errors.Wrap(err, "failed to get app version archive")
}

cfg, err := k8sutil.GetClusterConfig()
if err != nil {
return nil, errors.Wrap(err, "failed to get cluster config")
}

clientset, err := kubernetes.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create velero clientset")
}

kotsadmNamespace := util.PodNamespace
kotsadmVeleroBackendStorageLocation, err := kotssnapshot.FindBackupStoreLocation(ctx, kotsadmNamespace)
kotsadmVeleroBackendStorageLocation, err := kotssnapshot.FindBackupStoreLocation(ctx, clientset, veleroClient, kotsadmNamespace)
if err != nil {
return nil, errors.Wrap(err, "failed to find backupstoragelocations")
}
Expand Down Expand Up @@ -160,26 +175,11 @@ func CreateApplicationBackup(ctx context.Context, a *apptypes.App, isScheduled b
}
}

clientset, err := k8sutil.GetClientset()
if err != nil {
return nil, errors.Wrap(err, "failed to create k8s clientset")
}

err = excludeShutdownPodsFromBackup(ctx, clientset, veleroBackup)
if err != nil {
logger.Error(errors.Wrap(err, "failed to exclude shutdown pods from backup"))
}

cfg, err := k8sutil.GetClusterConfig()
if err != nil {
return nil, errors.Wrap(err, "failed to get cluster config")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}

backup, err := veleroClient.Backups(kotsadmVeleroBackendStorageLocation.Namespace).Create(ctx, veleroBackup, metav1.CreateOptions{})
if err != nil {
return nil, errors.Wrap(err, "failed to create velero backup")
Expand All @@ -191,9 +191,14 @@ func CreateApplicationBackup(ctx context.Context, a *apptypes.App, isScheduled b
func CreateInstanceBackup(ctx context.Context, cluster *downstreamtypes.Downstream, isScheduled bool) (*velerov1.Backup, error) {
logger.Debug("creating instance backup")

clientset, err := k8sutil.GetClientset()
cfg, err := k8sutil.GetClusterConfig()
if err != nil {
return nil, errors.Wrap(err, "failed to get cluster config")
}

clientset, err := kubernetes.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create k8s clientset")
return nil, errors.Wrap(err, "failed to create clientset")
}

isKurl, err := kurl.IsKurl(clientset)
Expand Down Expand Up @@ -310,7 +315,12 @@ func CreateInstanceBackup(ctx context.Context, cluster *downstreamtypes.Downstre
backupHooks.Resources = append(backupHooks.Resources, veleroBackup.Spec.Hooks.Resources...)
}

kotsadmVeleroBackendStorageLocation, err := kotssnapshot.FindBackupStoreLocation(ctx, kotsadmNamespace)
veleroClient, err := veleroclientv1.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create velero clientset")
}

kotsadmVeleroBackendStorageLocation, err := kotssnapshot.FindBackupStoreLocation(ctx, clientset, veleroClient, kotsadmNamespace)
if err != nil {
return nil, errors.Wrap(err, "failed to find backupstoragelocations")
}
Expand Down Expand Up @@ -398,16 +408,6 @@ func CreateInstanceBackup(ctx context.Context, cluster *downstreamtypes.Downstre
logger.Error(errors.Wrap(err, "failed to exclude shutdown pods from backup"))
}

cfg, err := k8sutil.GetClusterConfig()
if err != nil {
return nil, errors.Wrap(err, "failed to get cluster config")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create velero clientset")
}

backup, err := veleroClient.Backups(kotsadmVeleroBackendStorageLocation.Namespace).Create(ctx, veleroBackup, metav1.CreateOptions{})
if err != nil {
return nil, errors.Wrap(err, "failed to create velero backup")
Expand All @@ -422,12 +422,17 @@ func ListBackupsForApp(ctx context.Context, kotsadmNamespace string, appID strin
return nil, errors.Wrap(err, "failed to get cluster config")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
clientset, err := kubernetes.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}

backendStorageLocation, err := kotssnapshot.FindBackupStoreLocation(ctx, kotsadmNamespace)
veleroClient, err := veleroclientv1.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create velero clientset")
}

backendStorageLocation, err := kotssnapshot.FindBackupStoreLocation(ctx, clientset, veleroClient, kotsadmNamespace)
if err != nil {
return nil, errors.Wrap(err, "failed to find backupstoragelocations")
}
Expand Down Expand Up @@ -550,12 +555,17 @@ func ListInstanceBackups(ctx context.Context, kotsadmNamespace string) ([]*types
return nil, errors.Wrap(err, "failed to get cluster config")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
clientset, err := kubernetes.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}

backendStorageLocation, err := kotssnapshot.FindBackupStoreLocation(ctx, kotsadmNamespace)
veleroClient, err := veleroclientv1.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create velero clientset")
}

backendStorageLocation, err := kotssnapshot.FindBackupStoreLocation(ctx, clientset, veleroClient, kotsadmNamespace)
if err != nil {
return nil, errors.Wrap(err, "failed to find backupstoragelocations")
}
Expand Down Expand Up @@ -717,7 +727,22 @@ func getSnapshotVolumeSummary(ctx context.Context, veleroBackup *velerov1.Backup
}

func GetBackup(ctx context.Context, kotsadmNamespace string, snapshotName string) (*velerov1.Backup, error) {
bsl, err := kotssnapshot.FindBackupStoreLocation(ctx, kotsadmNamespace)
cfg, err := k8sutil.GetClusterConfig()
if err != nil {
return nil, errors.Wrap(err, "failed to get cluster config")
}

clientset, err := kubernetes.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create velero clientset")
}

bsl, err := kotssnapshot.FindBackupStoreLocation(ctx, clientset, veleroClient, kotsadmNamespace)
if err != nil {
return nil, errors.Wrap(err, "failed to get velero namespace")
}
Expand All @@ -728,26 +753,31 @@ func GetBackup(ctx context.Context, kotsadmNamespace string, snapshotName string
veleroNamespace := bsl.Namespace

// get the backup
cfg, err := k8sutil.GetClusterConfig()
backup, err := veleroClient.Backups(veleroNamespace).Get(ctx, snapshotName, metav1.GetOptions{})
if err != nil {
return nil, errors.Wrap(err, "failed to get cluster config")
return nil, errors.Wrap(err, "failed to get backup")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
return backup, nil
}

func DeleteBackup(ctx context.Context, kotsadmNamespace string, snapshotName string) error {
cfg, err := k8sutil.GetClusterConfig()
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
return errors.Wrap(err, "failed to get cluster config")
}

backup, err := veleroClient.Backups(veleroNamespace).Get(ctx, snapshotName, metav1.GetOptions{})
clientset, err := kubernetes.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to get backup")
return errors.Wrap(err, "failed to create clientset")
}

return backup, nil
}
veleroClient, err := veleroclientv1.NewForConfig(cfg)
if err != nil {
return errors.Wrap(err, "failed to create velero clientset")
}

func DeleteBackup(ctx context.Context, kotsadmNamespace string, snapshotName string) error {
bsl, err := kotssnapshot.FindBackupStoreLocation(ctx, kotsadmNamespace)
bsl, err := kotssnapshot.FindBackupStoreLocation(ctx, clientset, veleroClient, kotsadmNamespace)
if err != nil {
return errors.Wrap(err, "failed to get velero namespace")
}
Expand All @@ -766,16 +796,6 @@ func DeleteBackup(ctx context.Context, kotsadmNamespace string, snapshotName str
},
}

cfg, err := k8sutil.GetClusterConfig()
if err != nil {
return errors.Wrap(err, "failed to get cluster config")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
if err != nil {
return errors.Wrap(err, "failed to create clientset")
}

_, err = veleroClient.DeleteBackupRequests(veleroNamespace).Create(context.TODO(), veleroDeleteBackupRequest, metav1.CreateOptions{})
if err != nil {
return errors.Wrap(err, "failed to create delete backup request")
Expand Down Expand Up @@ -820,12 +840,17 @@ func GetBackupDetail(ctx context.Context, kotsadmNamespace string, backupName st
return nil, errors.Wrap(err, "failed to get cluster config")
}

veleroClient, err := veleroclientv1.NewForConfig(cfg)
clientset, err := kubernetes.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}

backendStorageLocation, err := kotssnapshot.FindBackupStoreLocation(ctx, kotsadmNamespace)
veleroClient, err := veleroclientv1.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "failed to create velero clientset")
}

backendStorageLocation, err := kotssnapshot.FindBackupStoreLocation(ctx, clientset, veleroClient, kotsadmNamespace)
if err != nil {
return nil, errors.Wrap(err, "failed to find backupstoragelocations")
}
Expand Down
Loading

0 comments on commit 09f1c18

Please sign in to comment.