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;