Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release-23.2: ui: add license change notification to db console #130425

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pkg/server/server_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ func (s *httpServer) setupRoutes(
}
return nil
},
Flags: flags,
Flags: flags,
Settings: s.cfg.Settings,
})

// The authentication mux used here is created in "allow anonymous" mode so that the UI
Expand Down
6 changes: 3 additions & 3 deletions pkg/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ Binary built without web UI.
respBytes, err = io.ReadAll(resp.Body)
require.NoError(t, err)
expected := fmt.Sprintf(
`{"Insecure":true,"LoggedInUser":null,"Tag":"%s","Version":"%s","NodeID":"%d","OIDCAutoLogin":false,"OIDCLoginEnabled":false,"OIDCButtonText":"","FeatureFlags":{"can_view_kv_metric_dashboards":true},"OIDCGenerateJWTAuthTokenEnabled":false}`,
`{"Insecure":true,"LoggedInUser":null,"Tag":"%s","Version":"%s","NodeID":"%d","OIDCAutoLogin":false,"OIDCLoginEnabled":false,"OIDCButtonText":"","FeatureFlags":{"can_view_kv_metric_dashboards":true},"OIDCGenerateJWTAuthTokenEnabled":false,"LicenseType":"OSS","SecondsUntilLicenseExpiry":0}`,
build.GetInfo().Tag,
build.BinaryVersionPrefix(),
1,
Expand Down Expand Up @@ -785,7 +785,7 @@ Binary built without web UI.
{
loggedInClient,
fmt.Sprintf(
`{"Insecure":false,"LoggedInUser":"authentic_user","Tag":"%s","Version":"%s","NodeID":"%d","OIDCAutoLogin":false,"OIDCLoginEnabled":false,"OIDCButtonText":"","FeatureFlags":{"can_view_kv_metric_dashboards":true},"OIDCGenerateJWTAuthTokenEnabled":false}`,
`{"Insecure":false,"LoggedInUser":"authentic_user","Tag":"%s","Version":"%s","NodeID":"%d","OIDCAutoLogin":false,"OIDCLoginEnabled":false,"OIDCButtonText":"","FeatureFlags":{"can_view_kv_metric_dashboards":true},"OIDCGenerateJWTAuthTokenEnabled":false,"LicenseType":"OSS","SecondsUntilLicenseExpiry":0}`,
build.GetInfo().Tag,
build.BinaryVersionPrefix(),
1,
Expand All @@ -794,7 +794,7 @@ Binary built without web UI.
{
loggedOutClient,
fmt.Sprintf(
`{"Insecure":false,"LoggedInUser":null,"Tag":"%s","Version":"%s","NodeID":"%d","OIDCAutoLogin":false,"OIDCLoginEnabled":false,"OIDCButtonText":"","FeatureFlags":{"can_view_kv_metric_dashboards":true},"OIDCGenerateJWTAuthTokenEnabled":false}`,
`{"Insecure":false,"LoggedInUser":null,"Tag":"%s","Version":"%s","NodeID":"%d","OIDCAutoLogin":false,"OIDCLoginEnabled":false,"OIDCButtonText":"","FeatureFlags":{"can_view_kv_metric_dashboards":true},"OIDCGenerateJWTAuthTokenEnabled":false,"LicenseType":"OSS","SecondsUntilLicenseExpiry":0}`,
build.GetInfo().Tag,
build.BinaryVersionPrefix(),
1,
Expand Down
1 change: 1 addition & 0 deletions pkg/ui/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ go_library(
"//pkg/build",
"//pkg/server/serverpb",
"//pkg/settings",
"//pkg/settings/cluster",
"//pkg/util/httputil",
"//pkg/util/log",
],
Expand Down
13 changes: 13 additions & 0 deletions pkg/ui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/build"
"github.com/cockroachdb/cockroach/pkg/server/serverpb"
"github.com/cockroachdb/cockroach/pkg/settings"
"github.com/cockroachdb/cockroach/pkg/settings/cluster"
"github.com/cockroachdb/cockroach/pkg/util/httputil"
"github.com/cockroachdb/cockroach/pkg/util/log"
)
Expand Down Expand Up @@ -92,6 +93,9 @@ type indexHTMLArgs struct {
FeatureFlags serverpb.FeatureFlags

OIDCGenerateJWTAuthTokenEnabled bool

LicenseType string
SecondsUntilLicenseExpiry int64
}

// OIDCUIConf is a variable that stores data required by the
Expand Down Expand Up @@ -129,6 +133,7 @@ type Config struct {
GetUser func(ctx context.Context) *string
OIDC OIDCUI
Flags serverpb.FeatureFlags
Settings *cluster.Settings
}

var uiConfigPath = regexp.MustCompile("^/uiconfig$")
Expand Down Expand Up @@ -158,6 +163,11 @@ func Handler(cfg Config) http.Handler {
buildInfo := build.GetInfo()

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
licenseType, err := base.LicenseType(cfg.Settings)
if err != nil {
log.Errorf(context.Background(), "unable to get license type: %+v", err)
}
licenseTTL := base.LicenseTTL.Value()
oidcConf := cfg.OIDC.GetOIDCConf()
args := indexHTMLArgs{
Insecure: cfg.Insecure,
Expand All @@ -170,6 +180,9 @@ func Handler(cfg Config) http.Handler {
FeatureFlags: cfg.Flags,

OIDCGenerateJWTAuthTokenEnabled: oidcConf.GenerateJWTAuthTokenEnabled,

LicenseType: licenseType,
SecondsUntilLicenseExpiry: licenseTTL,
}
if cfg.NodeID != nil {
args.NodeID = cfg.NodeID.String()
Expand Down
2 changes: 2 additions & 0 deletions pkg/ui/workspaces/cluster-ui/src/util/dataFromServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export interface DataFromServer {
OIDCButtonText: string;
OIDCGenerateJWTAuthTokenEnabled: boolean;
FeatureFlags: FeatureFlags;
LicenseType: string;
SecondsUntilLicenseExpiry: number;
}

// Tell TypeScript about `window.dataFromServer`, which is set in a script
Expand Down
30 changes: 30 additions & 0 deletions pkg/ui/workspaces/db-console/src/redux/alerts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { createHashHistory } from "history";
import * as protos from "src/js/protos";
import { cockroach } from "src/js/protos";
import { API_PREFIX } from "src/util/api";
import { setDataFromServer } from "src/util/dataFromServer";
import fetchMock from "src/util/fetch-mock";

import { AdminUIState, AppDispatch, createAdminUIStore } from "./state";
Expand All @@ -31,11 +32,13 @@ import {
emailSubscriptionAlertSelector,
clusterPreserveDowngradeOptionDismissedSetting,
clusterPreserveDowngradeOptionOvertimeSelector,
licenseUpdateNotificationSelector,
} from "./alerts";
import { versionsSelector } from "src/redux/nodes";
import {
VERSION_DISMISSED_KEY,
INSTRUCTIONS_BOX_COLLAPSED_KEY,
LICENSE_UPDATE_DISMISSED_KEY,
setUIDataKey,
isInFlight,
} from "./uiData";
Expand All @@ -47,6 +50,7 @@ import {
healthReducerObj,
settingsReducerObj,
} from "./apiReducers";

import Long from "long";
import MembershipStatus = cockroach.kv.kvserver.liveness.livenesspb.MembershipStatus;
import { loginSuccess } from "./login";
Expand Down Expand Up @@ -257,6 +261,31 @@ describe("alerts", function () {
});
});

describe("licence update notification", function () {
it("displays the alert when nothing is done", function () {
dispatch(setUIDataKey(LICENSE_UPDATE_DISMISSED_KEY, null));
const alert = licenseUpdateNotificationSelector(state());
expect(typeof alert).toBe("object");
expect(alert.level).toEqual(AlertLevel.INFORMATION);
expect(alert.text).toEqual(
"Important changes to CockroachDB’s licensing model.",
);
});

it("hides the alert when dismissed timestamp is present", function () {
dispatch(setUIDataKey(LICENSE_UPDATE_DISMISSED_KEY, moment()));
expect(licenseUpdateNotificationSelector(state())).toBeUndefined();
});

it("hides the alert when license is enterprise", function () {
dispatch(setUIDataKey(LICENSE_UPDATE_DISMISSED_KEY, null));
setDataFromServer({
LicenseType: "Enterprise",
} as any);
expect(licenseUpdateNotificationSelector(state())).toBeUndefined();
});
});

describe("new version available notification", function () {
it("displays nothing when versions have not yet been loaded", function () {
dispatch(setUIDataKey(VERSION_DISMISSED_KEY, null));
Expand Down Expand Up @@ -630,6 +659,7 @@ describe("alerts", function () {
);
dispatch(setUIDataKey(VERSION_DISMISSED_KEY, "blank"));
dispatch(setUIDataKey(INSTRUCTIONS_BOX_COLLAPSED_KEY, false));
dispatch(setUIDataKey(LICENSE_UPDATE_DISMISSED_KEY, moment()));
dispatch(
versionReducerObj.receiveData({
details: [],
Expand Down
Loading