Skip to content

Commit 6337f69

Browse files
authored
treat every embedded cluster app as if it has a backup object (#4571)
* treat every embedded cluster app as if it has a backup object * enable snapshots in EC * add unit test for backup resource
1 parent 01a487c commit 6337f69

File tree

3 files changed

+191
-2
lines changed

3 files changed

+191
-2
lines changed

pkg/handlers/app.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,6 @@ func responseAppFromApp(a *apptypes.App) (*types.ResponseApp, error) {
289289
return nil, errors.Wrap(err, "failed to check if snapshots is allowed")
290290
}
291291
allowSnapshots := s && license.Spec.IsSnapshotSupported
292-
allowSnapshots = allowSnapshots && !util.IsEmbeddedCluster() // snapshots are not allowed in embedded cluster installations today
293292

294293
isGitopsSupported := license.Spec.IsGitOpsSupported && !util.IsEmbeddedCluster() // gitops is not allowed in embedded cluster installations today
295294

pkg/kotsutil/kots.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,22 @@ func (o KotsKinds) Marshal(g string, v string, k string) (string, error) {
419419
if v == "v1" {
420420
if k == "Backup" {
421421
if o.Backup == nil {
422-
return "", nil
422+
if util.IsEmbeddedCluster() {
423+
// return the default backup object
424+
backup := &velerov1.Backup{
425+
TypeMeta: metav1.TypeMeta{
426+
APIVersion: "velero.io/v1",
427+
Kind: "Backup",
428+
},
429+
ObjectMeta: metav1.ObjectMeta{
430+
Name: "backup",
431+
},
432+
}
433+
o.Backup = backup
434+
} else {
435+
return "", nil
436+
}
437+
423438
}
424439
var b bytes.Buffer
425440
if err := s.Encode(o.Backup, &b); err != nil {

pkg/kotsutil/kots_test.go

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,21 @@ import (
99

1010
. "github.com/onsi/ginkgo/v2"
1111
. "github.com/onsi/gomega"
12+
embeddedclusterv1beta1 "github.com/replicatedhq/embedded-cluster-kinds/apis/v1beta1"
1213
"github.com/replicatedhq/kots/pkg/crypto"
1314
dockerregistrytypes "github.com/replicatedhq/kots/pkg/docker/registry/types"
1415
"github.com/replicatedhq/kots/pkg/kotsutil"
1516
"github.com/replicatedhq/kots/pkg/util"
1617
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
18+
kotsv1beta2 "github.com/replicatedhq/kotskinds/apis/kots/v1beta2"
19+
kurlv1beta1 "github.com/replicatedhq/kurlkinds/pkg/apis/cluster/v1beta1"
1720
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
1821
"github.com/stretchr/testify/assert"
1922
"github.com/stretchr/testify/require"
23+
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
2024
corev1 "k8s.io/api/core/v1"
25+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26+
applicationv1beta1 "sigs.k8s.io/application/api/v1beta1"
2127
)
2228

2329
var _ = Describe("Kots", func() {
@@ -882,3 +888,172 @@ func TestGetImagesFromKotsKinds(t *testing.T) {
882888
})
883889
}
884890
}
891+
892+
func TestKotsKinds_Marshal(t *testing.T) {
893+
type fields struct {
894+
KotsApplication kotsv1beta1.Application
895+
Application *applicationv1beta1.Application
896+
V1Beta1HelmCharts *kotsv1beta1.HelmChartList
897+
V1Beta2HelmCharts *kotsv1beta2.HelmChartList
898+
Collector *troubleshootv1beta2.Collector
899+
Preflight *troubleshootv1beta2.Preflight
900+
Analyzer *troubleshootv1beta2.Analyzer
901+
SupportBundle *troubleshootv1beta2.SupportBundle
902+
Redactor *troubleshootv1beta2.Redactor
903+
HostPreflight *troubleshootv1beta2.HostPreflight
904+
Config *kotsv1beta1.Config
905+
ConfigValues *kotsv1beta1.ConfigValues
906+
Installation kotsv1beta1.Installation
907+
License *kotsv1beta1.License
908+
Identity *kotsv1beta1.Identity
909+
IdentityConfig *kotsv1beta1.IdentityConfig
910+
Backup *velerov1.Backup
911+
Installer *kurlv1beta1.Installer
912+
LintConfig *kotsv1beta1.LintConfig
913+
EmbeddedClusterConfig *embeddedclusterv1beta1.Config
914+
}
915+
type args struct {
916+
g string
917+
v string
918+
k string
919+
}
920+
tests := []struct {
921+
name string
922+
fields fields
923+
args args
924+
preInit func()
925+
postRun func()
926+
want string
927+
}{
928+
{
929+
name: "backup exists, not EC",
930+
fields: fields{
931+
Backup: &velerov1.Backup{
932+
ObjectMeta: metav1.ObjectMeta{Name: "backup-name"},
933+
TypeMeta: metav1.TypeMeta{APIVersion: "velero.io/v1", Kind: "Backup"},
934+
},
935+
},
936+
args: args{
937+
g: "velero.io",
938+
v: "v1",
939+
k: "Backup",
940+
},
941+
want: `apiVersion: velero.io/v1
942+
kind: Backup
943+
metadata:
944+
creationTimestamp: null
945+
name: backup-name
946+
spec:
947+
csiSnapshotTimeout: 0s
948+
hooks: {}
949+
metadata: {}
950+
ttl: 0s
951+
status: {}
952+
`,
953+
},
954+
{
955+
name: "no backup exists, not EC",
956+
args: args{
957+
g: "velero.io",
958+
v: "v1",
959+
k: "Backup",
960+
},
961+
want: "",
962+
},
963+
{
964+
name: "no backup exists, EC",
965+
preInit: func() {
966+
os.Setenv("EMBEDDED_CLUSTER_ID", "test")
967+
},
968+
postRun: func() {
969+
os.Setenv("EMBEDDED_CLUSTER_ID", "")
970+
},
971+
args: args{
972+
g: "velero.io",
973+
v: "v1",
974+
k: "Backup",
975+
},
976+
want: `apiVersion: velero.io/v1
977+
kind: Backup
978+
metadata:
979+
creationTimestamp: null
980+
name: backup
981+
spec:
982+
csiSnapshotTimeout: 0s
983+
hooks: {}
984+
metadata: {}
985+
ttl: 0s
986+
status: {}
987+
`,
988+
},
989+
{
990+
name: "backup exists, EC",
991+
fields: fields{
992+
Backup: &velerov1.Backup{
993+
ObjectMeta: metav1.ObjectMeta{Name: "backup-name"},
994+
TypeMeta: metav1.TypeMeta{APIVersion: "velero.io/v1", Kind: "Backup"},
995+
},
996+
},
997+
preInit: func() {
998+
os.Setenv("EMBEDDED_CLUSTER_ID", "test")
999+
},
1000+
postRun: func() {
1001+
os.Setenv("EMBEDDED_CLUSTER_ID", "")
1002+
},
1003+
args: args{
1004+
g: "velero.io",
1005+
v: "v1",
1006+
k: "Backup",
1007+
},
1008+
want: `apiVersion: velero.io/v1
1009+
kind: Backup
1010+
metadata:
1011+
creationTimestamp: null
1012+
name: backup-name
1013+
spec:
1014+
csiSnapshotTimeout: 0s
1015+
hooks: {}
1016+
metadata: {}
1017+
ttl: 0s
1018+
status: {}
1019+
`,
1020+
},
1021+
}
1022+
for _, tt := range tests {
1023+
t.Run(tt.name, func(t *testing.T) {
1024+
o := kotsutil.KotsKinds{
1025+
KotsApplication: tt.fields.KotsApplication,
1026+
Application: tt.fields.Application,
1027+
V1Beta1HelmCharts: tt.fields.V1Beta1HelmCharts,
1028+
V1Beta2HelmCharts: tt.fields.V1Beta2HelmCharts,
1029+
Collector: tt.fields.Collector,
1030+
Preflight: tt.fields.Preflight,
1031+
Analyzer: tt.fields.Analyzer,
1032+
SupportBundle: tt.fields.SupportBundle,
1033+
Redactor: tt.fields.Redactor,
1034+
HostPreflight: tt.fields.HostPreflight,
1035+
Config: tt.fields.Config,
1036+
ConfigValues: tt.fields.ConfigValues,
1037+
Installation: tt.fields.Installation,
1038+
License: tt.fields.License,
1039+
Identity: tt.fields.Identity,
1040+
IdentityConfig: tt.fields.IdentityConfig,
1041+
Backup: tt.fields.Backup,
1042+
Installer: tt.fields.Installer,
1043+
LintConfig: tt.fields.LintConfig,
1044+
EmbeddedClusterConfig: tt.fields.EmbeddedClusterConfig,
1045+
}
1046+
1047+
req := require.New(t)
1048+
if tt.preInit != nil {
1049+
tt.preInit()
1050+
}
1051+
got, err := o.Marshal(tt.args.g, tt.args.v, tt.args.k)
1052+
if tt.postRun != nil {
1053+
tt.postRun()
1054+
}
1055+
req.NoError(err)
1056+
req.Equal(tt.want, got)
1057+
})
1058+
}
1059+
}

0 commit comments

Comments
 (0)