diff --git a/go.mod b/go.mod
index 008c4bbe37..a6e61baf76 100644
--- a/go.mod
+++ b/go.mod
@@ -48,8 +48,8 @@ require (
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
- github.com/replicatedhq/embedded-cluster-kinds v1.1.11
- github.com/replicatedhq/kotskinds v0.0.0-20240416132840-4e646b87f7a1
+ github.com/replicatedhq/embedded-cluster-kinds v1.2.2
+ github.com/replicatedhq/kotskinds v0.0.0-20240523174825-f4d441adb453
github.com/replicatedhq/kurlkinds v1.5.0
github.com/replicatedhq/troubleshoot v0.92.1
github.com/replicatedhq/yaml/v3 v3.0.0-beta5-replicatedhq
@@ -147,7 +147,7 @@ require (
github.com/chzyer/readline v1.5.1 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/containerd/cgroups/v3 v3.0.2 // indirect
- github.com/containerd/containerd v1.7.13 // indirect
+ github.com/containerd/containerd v1.7.16 // indirect
github.com/containerd/continuity v0.4.2 // indirect
github.com/containerd/errdefs v0.1.0 // indirect
github.com/containerd/log v0.1.0 // indirect
@@ -249,7 +249,7 @@ require (
github.com/jmoiron/sqlx v1.3.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
- github.com/k0sproject/k0s v1.28.5-0.20231116142149-82f76181191c // indirect
+ github.com/k0sproject/k0s v1.28.10-0.20240418084644-c99e4b437507 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.17.7 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
diff --git a/go.sum b/go.sum
index bed2e8c4f7..fa362dac30 100644
--- a/go.sum
+++ b/go.sum
@@ -406,8 +406,8 @@ github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMe
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0=
github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE=
-github.com/containerd/containerd v1.7.13 h1:wPYKIeGMN8vaggSKuV1X0wZulpMz4CrgEsZdaCyB6Is=
-github.com/containerd/containerd v1.7.13/go.mod h1:zT3up6yTRfEUa6+GsITYIJNgSVL9NQ4x4h1RPzk0Wu4=
+github.com/containerd/containerd v1.7.16 h1:7Zsfe8Fkj4Wi2My6DXGQ87hiqIrmOXolm72ZEkFU5Mg=
+github.com/containerd/containerd v1.7.16/go.mod h1:NL49g7A/Fui7ccmxV6zkBWwqMgmMxFWzujYCc+JLt7k=
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
@@ -1013,8 +1013,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
-github.com/k0sproject/k0s v1.28.5-0.20231116142149-82f76181191c h1:rL7cCMTRv92zDbVQtkItOtp0p97GsuPCya0rTXYQxug=
-github.com/k0sproject/k0s v1.28.5-0.20231116142149-82f76181191c/go.mod h1:4+Y6RiiR9Up/rU/3SirRNlrdPhIo3TCZUZiInuaCQus=
+github.com/k0sproject/k0s v1.28.10-0.20240418084644-c99e4b437507 h1:P0fdgZ7haUEH4dUZHKk0VvgbmaBul0L8cIYrln/ScVI=
+github.com/k0sproject/k0s v1.28.10-0.20240418084644-c99e4b437507/go.mod h1:bJe0YdBjheJhuLsTteYy00PdWOeY/AM4m0WPRtYCBTA=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
@@ -1308,10 +1308,10 @@ github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDO
github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY=
github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
-github.com/replicatedhq/embedded-cluster-kinds v1.1.11 h1:M4a8TPINV8jILw85Pk24lcEqrTbSVg2+mdmAi5M6ZZQ=
-github.com/replicatedhq/embedded-cluster-kinds v1.1.11/go.mod h1:EBLOLIx/5GQsA1KB7Wrv98nfydBRP7V+5PFMRb1AGnU=
-github.com/replicatedhq/kotskinds v0.0.0-20240416132840-4e646b87f7a1 h1:+RvMZ646tQTRzWFZTy6mnmgWJZOLFu6B9PXv8tcIcFY=
-github.com/replicatedhq/kotskinds v0.0.0-20240416132840-4e646b87f7a1/go.mod h1:QjhIUu3+OmHZ09u09j3FCoTt8F3BYtQglS+OLmftu9I=
+github.com/replicatedhq/embedded-cluster-kinds v1.2.2 h1:KW9fSCTt4xr3MpcCQpgwHcwmZp+mz7uA2JOVR+2TD9Q=
+github.com/replicatedhq/embedded-cluster-kinds v1.2.2/go.mod h1:NIwwkFGoNHIxx+5mHRihvQU6RqZ/xt/A5RzaHpBh2ZY=
+github.com/replicatedhq/kotskinds v0.0.0-20240523174825-f4d441adb453 h1:g8CQQ9R4gjIdoHuBX1LN1hmF3Omq2JfA040JfpfNVC8=
+github.com/replicatedhq/kotskinds v0.0.0-20240523174825-f4d441adb453/go.mod h1:QjhIUu3+OmHZ09u09j3FCoTt8F3BYtQglS+OLmftu9I=
github.com/replicatedhq/kurlkinds v1.5.0 h1:zZ0PKNeh4kXvSzVGkn62DKTo314GxhXg1TSB3azURMc=
github.com/replicatedhq/kurlkinds v1.5.0/go.mod h1:rUpBMdC81IhmJNCWMU/uRsMETv9P0xFoMvdSP/TAr5A=
github.com/replicatedhq/termui/v3 v3.1.1-0.20200811145416-f40076d26851 h1:eRlNDHxGfVkPCRXbA4BfQJvt5DHjFiTtWy3R/t4djyY=
diff --git a/pkg/embeddedcluster/util.go b/pkg/embeddedcluster/util.go
index cf9b775f49..65ede96bd9 100644
--- a/pkg/embeddedcluster/util.go
+++ b/pkg/embeddedcluster/util.go
@@ -147,7 +147,7 @@ func startClusterUpgrade(ctx context.Context, newcfg embeddedclusterv1beta1.Conf
Config: &newcfg,
EndUserK0sConfigOverrides: current.Spec.EndUserK0sConfigOverrides,
BinaryName: current.Spec.BinaryName,
- LicenseInfo: &embeddedclusterv1beta1.LicenseInfo{IsSnapshotSupported: license.Spec.IsSnapshotSupported},
+ LicenseInfo: &embeddedclusterv1beta1.LicenseInfo{IsDisasterRecoverySupported: license.Spec.IsDisasterRecoverySupported},
},
}
if err := kbClient.Create(ctx, &newins); err != nil {
diff --git a/pkg/handlers/app.go b/pkg/handlers/app.go
index 522bd33766..bf06e7d3eb 100644
--- a/pkg/handlers/app.go
+++ b/pkg/handlers/app.go
@@ -238,7 +238,13 @@ func responseAppFromApp(a *apptypes.App) (*types.ResponseApp, error) {
if err != nil {
return nil, errors.Wrap(err, "failed to check if snapshots is allowed")
}
- allowSnapshots := s && license.Spec.IsSnapshotSupported
+
+ var allowSnapshots bool
+ if util.IsEmbeddedCluster() {
+ allowSnapshots = s && license.Spec.IsDisasterRecoverySupported
+ } else {
+ allowSnapshots = s && license.Spec.IsSnapshotSupported
+ }
isGitopsSupported := license.Spec.IsGitOpsSupported && !util.IsEmbeddedCluster() // gitops is not allowed in embedded cluster installations today
diff --git a/pkg/handlers/license.go b/pkg/handlers/license.go
index cc28386f00..6f9cf40723 100644
--- a/pkg/handlers/license.go
+++ b/pkg/handlers/license.go
@@ -48,6 +48,7 @@ type LicenseResponse struct {
IsGeoaxisSupported bool `json:"isGeoaxisSupported"`
IsSemverRequired bool `json:"isSemverRequired"`
IsSnapshotSupported bool `json:"isSnapshotSupported"`
+ IsDisasterRecoverySupported bool `json:"isDisasterRecoverySupported"`
LastSyncedAt string `json:"lastSyncedAt"`
IsSupportBundleUploadSupported bool `json:"isSupportBundleUploadSupported"`
}
@@ -679,6 +680,7 @@ func licenseResponseFromLicense(license *kotsv1beta1.License, app *apptypes.App)
IsGeoaxisSupported: license.Spec.IsGeoaxisSupported,
IsSemverRequired: license.Spec.IsSemverRequired,
IsSnapshotSupported: license.Spec.IsSnapshotSupported,
+ IsDisasterRecoverySupported: license.Spec.IsDisasterRecoverySupported,
LastSyncedAt: app.LastLicenseSync,
IsSupportBundleUploadSupported: license.Spec.IsSupportBundleUploadSupported,
}
diff --git a/pkg/license/signature.go b/pkg/license/signature.go
index fc5a50d6c7..d606046527 100644
--- a/pkg/license/signature.go
+++ b/pkg/license/signature.go
@@ -158,6 +158,9 @@ func verifyLicenseData(outerLicense *kotsv1beta1.License, innerLicense *kotsv1be
if outerLicense.Spec.IsSnapshotSupported != innerLicense.Spec.IsSnapshotSupported {
return errors.New("\"IsSnapshotSupported\" field has changed")
}
+ if outerLicense.Spec.IsDisasterRecoverySupported != innerLicense.Spec.IsDisasterRecoverySupported {
+ return errors.New("\"IsDisasterRecoverySupported\" field has changed")
+ }
if outerLicense.Spec.IsSupportBundleUploadSupported != innerLicense.Spec.IsSupportBundleUploadSupported {
return errors.New("\"IsSupportBundleUploadSupported\" field has changed")
}
diff --git a/pkg/template/license_context.go b/pkg/template/license_context.go
index e3b243849c..988d11f1af 100644
--- a/pkg/template/license_context.go
+++ b/pkg/template/license_context.go
@@ -40,6 +40,8 @@ func (ctx licenseCtx) licenseFieldValue(name string) string {
switch name {
case "isSnapshotSupported":
return strconv.FormatBool(ctx.License.Spec.IsSnapshotSupported)
+ case "IsDisasterRecoverySupported":
+ return strconv.FormatBool(ctx.License.Spec.IsDisasterRecoverySupported)
case "isGitOpsSupported":
return strconv.FormatBool(ctx.License.Spec.IsGitOpsSupported)
case "isSupportBundleUploadSupported":
diff --git a/pkg/template/license_context_test.go b/pkg/template/license_context_test.go
index 8362ba994b..5d07cacfd3 100644
--- a/pkg/template/license_context_test.go
+++ b/pkg/template/license_context_test.go
@@ -253,6 +253,16 @@ func TestLicenseCtx_licenseFieldValue(t *testing.T) {
fieldName: "isSnapshotSupported",
want: "true",
},
+ {
+ name: "built-in IsDisasterRecoverySupported",
+ License: &kotsv1beta1.License{
+ Spec: kotsv1beta1.LicenseSpec{
+ IsDisasterRecoverySupported: true,
+ },
+ },
+ fieldName: "IsDisasterRecoverySupported",
+ want: "true",
+ },
{
name: "built-in isGeoaxisSupported",
License: &kotsv1beta1.License{
diff --git a/web/src/Root.tsx b/web/src/Root.tsx
index 0a7d547c89..5a79c7b3d2 100644
--- a/web/src/Root.tsx
+++ b/web/src/Root.tsx
@@ -789,7 +789,17 @@ const Root = () => {
/>
} />
- } />
+
+ }
+ />
}
diff --git a/web/src/components/apps/AppLicense.tsx b/web/src/components/apps/AppLicense.tsx
index b2b10e1be7..3339e6f12a 100644
--- a/web/src/components/apps/AppLicense.tsx
+++ b/web/src/components/apps/AppLicense.tsx
@@ -25,8 +25,7 @@ import Icon from "../Icon";
type Props = {
app: App;
- changeCallback: () => void;
- syncCallback: () => void;
+ isEmbeddedCluster: boolean;
};
type State = {
@@ -83,7 +82,7 @@ const AppLicenseComponent = () => {
}, [licenseWithInterceptResponse]);
const syncAppLicense = (licenseData: string) => {
- const { app, syncCallback } = outletContext;
+ const { app } = outletContext;
setState({
loading: true,
message: "",
@@ -132,10 +131,6 @@ const AppLicenseComponent = () => {
messageType: "info",
showNextStepModal: licenseResponse.synced,
});
-
- if (syncCallback) {
- syncCallback();
- }
})
.catch((err) => {
console.log(err);
@@ -209,7 +204,7 @@ const AppLicenseComponent = () => {
licenseChangeMessageType: "info",
});
- const { app, changeCallback } = outletContext;
+ const { app } = outletContext;
const payload = {
licenseData,
@@ -242,10 +237,6 @@ const AppLicenseComponent = () => {
licenseChangeFile: null,
licenseChangeMessage: "",
});
-
- if (changeCallback) {
- changeCallback();
- }
})
.catch((err) => {
console.log(err);
@@ -315,7 +306,7 @@ const AppLicenseComponent = () => {
);
}
- const { app } = outletContext;
+ const { app, isEmbeddedCluster } = outletContext;
const expiresAt = getLicenseExpiryDate(appLicense);
const gitops = app.downstream?.gitops;
const appName = app?.name || "Your application";
@@ -457,7 +448,14 @@ const AppLicenseComponent = () => {
Airgap enabled{" "}
) : null}
- {appLicense?.isSnapshotSupported ? (
+ {isEmbeddedCluster &&
+ appLicense?.isDisasterRecoverySupported ? (
+
+ Disaster
+ Recovery enabled{" "}
+
+ ) : null}
+ {!isEmbeddedCluster && appLicense?.isSnapshotSupported ? (
Snapshots
enabled{" "}
diff --git a/web/src/types/index.ts b/web/src/types/index.ts
index d42ecd4a18..0e17e8718d 100644
--- a/web/src/types/index.ts
+++ b/web/src/types/index.ts
@@ -41,6 +41,7 @@ export type AppLicense = {
isIdentityServiceSupported: boolean;
isSemverRequired: boolean;
isSnapshotSupported: boolean;
+ isDisasterRecoverySupported: boolean;
isSupportBundleUploadSupported: boolean;
lastSyncedAt: string;
licenseSequence: number;