@rancher/shell 3.0.8-rc.2 → 3.0.8-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/brand/suse/dark/rancher-logo.svg +64 -1
- package/assets/brand/suse/rancher-logo.svg +1 -1
- package/assets/styles/global/_cards.scss +0 -3
- package/assets/styles/themes/_modern.scss +9 -1
- package/assets/styles/themes/_suse.scss +81 -24
- package/assets/translations/en-us.yaml +68 -3
- package/components/AutoscalerCard.vue +113 -0
- package/components/AutoscalerTab.vue +94 -0
- package/components/ClusterIconMenu.vue +1 -1
- package/components/ClusterProviderIcon.vue +1 -1
- package/components/IconOrSvg.vue +2 -2
- package/components/PopoverCard.vue +192 -0
- package/components/Resource/Detail/FetchLoader/composables.ts +18 -4
- package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +1 -1
- package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +4 -0
- package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +2 -19
- package/components/Resource/Detail/ResourcePopover/__tests__/ResourcePopoverCard.test.ts +0 -29
- package/components/Resource/Detail/ResourcePopover/__tests__/index.test.ts +132 -150
- package/components/Resource/Detail/ResourcePopover/index.vue +54 -159
- package/components/ResourceDetail/Masthead/latest.vue +29 -0
- package/components/ResourceList/Masthead.vue +1 -1
- package/components/__tests__/AutoscalerCard.test.ts +154 -0
- package/components/__tests__/AutoscalerTab.test.ts +125 -0
- package/components/__tests__/PopoverCard.test.ts +204 -0
- package/components/formatter/Autoscaler.vue +97 -0
- package/components/formatter/InternalExternalIP.vue +195 -24
- package/components/formatter/__tests__/Autoscaler.test.ts +156 -0
- package/components/formatter/__tests__/InternalExternalIP.test.ts +133 -0
- package/components/nav/Group.vue +12 -3
- package/components/nav/TopLevelMenu.vue +2 -2
- package/composables/useInterval.ts +15 -0
- package/config/labels-annotations.js +8 -1
- package/config/product/manager.js +20 -9
- package/config/router/routes.js +4 -0
- package/config/settings.ts +2 -1
- package/config/table-headers.js +8 -0
- package/config/types.js +2 -0
- package/config/version.js +1 -1
- package/core/types-provisioning.ts +3 -0
- package/detail/provisioning.cattle.io.cluster.vue +12 -1
- package/directives/ui-context.ts +8 -2
- package/edit/auth/github.vue +5 -0
- package/edit/cloudcredential.vue +1 -1
- package/edit/fleet.cattle.io.gitrepo.vue +0 -10
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +32 -5
- package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.test.ts +35 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Networking.test.ts +132 -0
- package/edit/provisioning.cattle.io.cluster/index.vue +18 -12
- package/edit/provisioning.cattle.io.cluster/rke2.vue +39 -8
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +107 -5
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +90 -3
- package/initialize/install-plugins.js +3 -1
- package/list/provisioning.cattle.io.cluster.vue +15 -2
- package/machine-config/amazonec2.vue +36 -135
- package/machine-config/components/EC2Networking.vue +474 -0
- package/machine-config/components/__tests__/EC2Networking.test.ts +94 -0
- package/machine-config/components/__tests__/utils/vpcSubnetMockData.js +294 -0
- package/machine-config/digitalocean.vue +11 -0
- package/models/cluster/node.js +13 -6
- package/models/cluster.x-k8s.io.machine.js +10 -20
- package/models/cluster.x-k8s.io.machinedeployment.js +5 -1
- package/models/management.cattle.io.kontainerdriver.js +1 -0
- package/models/provisioning.cattle.io.cluster.js +223 -2
- package/package.json +2 -2
- package/pages/c/_cluster/apps/charts/install.vue +1 -1
- package/pages/c/_cluster/manager/hostedprovider/index.vue +209 -0
- package/plugins/dynamic-content.js +13 -0
- package/rancher-components/Form/Checkbox/Checkbox.vue +1 -1
- package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +8 -0
- package/store/features.js +1 -0
- package/store/notifications.ts +32 -1
- package/store/plugins.js +7 -3
- package/store/prefs.js +1 -0
- package/types/notifications/index.ts +24 -3
- package/types/shell/index.d.ts +27 -2
- package/utils/__tests__/object.test.ts +19 -0
- package/utils/autoscaler-utils.ts +7 -0
- package/utils/dynamic-content/__tests__/announcement.test.ts +498 -0
- package/utils/dynamic-content/announcement.ts +112 -0
- package/utils/dynamic-content/example.json +40 -0
- package/utils/dynamic-content/index.ts +6 -2
- package/utils/dynamic-content/new-release.ts +1 -1
- package/utils/dynamic-content/notification-handler.ts +48 -0
- package/utils/dynamic-content/types.d.ts +33 -1
- package/utils/object.js +20 -2
- package/utils/scroll.js +7 -0
- package/utils/settings.ts +15 -0
- package/utils/validators/machine-pool.ts +13 -3
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* The code in this file is responsible for adding 'announcement 'notifications driven off of the dynamic content metadata
|
|
4
|
+
*
|
|
5
|
+
* Announcements will be able to be shown in different places in the UI
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import semver from 'semver';
|
|
10
|
+
import { NotificationLevel, Notification } from '@shell/types/notifications';
|
|
11
|
+
import { READ_ANNOUNCEMENTS } from '@shell/store/prefs';
|
|
12
|
+
import { Context, VersionInfo, Announcement } from './types';
|
|
13
|
+
import { DynamicContentAnnouncementHandlerName } from './notification-handler';
|
|
14
|
+
|
|
15
|
+
// Prefixes used in the notifications IDs created here
|
|
16
|
+
export const ANNOUNCEMENT_PREFIX = 'announcement-';
|
|
17
|
+
|
|
18
|
+
const ALLOWED_NOTIFICATIONS: Record<string, NotificationLevel> = {
|
|
19
|
+
announcement: NotificationLevel.Announcement,
|
|
20
|
+
info: NotificationLevel.Info,
|
|
21
|
+
warning: NotificationLevel.Warning,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Main exported function that will process the announcements
|
|
26
|
+
*
|
|
27
|
+
* @param context Context helper providing access to config, logger, store
|
|
28
|
+
* @param announcements Announcement information
|
|
29
|
+
* @param versionInfo Version information
|
|
30
|
+
*/
|
|
31
|
+
export async function processAnnouncements(context: Context, announcements: Announcement[] | undefined, versionInfo: VersionInfo): Promise<void> {
|
|
32
|
+
if (!announcements || !announcements.length || !versionInfo?.version) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const { dispatch, getters, logger } = context;
|
|
37
|
+
|
|
38
|
+
// Process each announcement
|
|
39
|
+
await Promise.all(announcements.map(async(announcement: Announcement) => {
|
|
40
|
+
// Check version
|
|
41
|
+
if (announcement.version && !semver.satisfies(versionInfo.version, announcement.version)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Check audience (currently only admin or all, but may add more in the future)
|
|
46
|
+
if (announcement.audience === 'admin' && !context.isAdmin) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Check type
|
|
51
|
+
const targetSplit = announcement.target.split('/');
|
|
52
|
+
|
|
53
|
+
if (targetSplit[0] === 'notification') {
|
|
54
|
+
// Show a notification
|
|
55
|
+
const subType = targetSplit.length === 2 ? targetSplit[1] : 'announcement';
|
|
56
|
+
|
|
57
|
+
// Because 0 is a falsy, see if we find something of type number to check for existence
|
|
58
|
+
if (typeof ALLOWED_NOTIFICATIONS[subType] !== 'number') {
|
|
59
|
+
logger.error(`Announcement notification type ${ subType } is not supported`);
|
|
60
|
+
} else {
|
|
61
|
+
logger.info(`Going to add a notification for announcement ${ announcement.target }`);
|
|
62
|
+
|
|
63
|
+
if (!announcement.id) {
|
|
64
|
+
logger.error(`No ID For announcement - not going to add a notification for the announcement`);
|
|
65
|
+
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// We should check if the notification already exists
|
|
70
|
+
const id = `${ ANNOUNCEMENT_PREFIX }${ announcement.id }`;
|
|
71
|
+
const existing = getters['notifications/item'](id);
|
|
72
|
+
|
|
73
|
+
// Check if the pref for 'read announcements' has the id
|
|
74
|
+
const pref = getters['prefs/get'](READ_ANNOUNCEMENTS) || '';
|
|
75
|
+
const prefExists = pref.split(',').includes(announcement.id);
|
|
76
|
+
|
|
77
|
+
if (existing || prefExists) {
|
|
78
|
+
logger.info(`Not adding announcement with ID ${ id } as it already exists or has been read previously (title: ${ announcement.title })`);
|
|
79
|
+
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const notification: Notification = {
|
|
83
|
+
id,
|
|
84
|
+
level: ALLOWED_NOTIFICATIONS[subType],
|
|
85
|
+
title: announcement.title,
|
|
86
|
+
message: announcement.message,
|
|
87
|
+
handlerName: DynamicContentAnnouncementHandlerName,
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
if (announcement.cta?.primary) {
|
|
91
|
+
notification.primaryAction = {
|
|
92
|
+
label: announcement.cta.primary.action,
|
|
93
|
+
target: announcement.cta.primary.link,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (announcement.cta?.secondary) {
|
|
98
|
+
notification.secondaryAction = {
|
|
99
|
+
label: announcement.cta.secondary.action,
|
|
100
|
+
target: announcement.cta.secondary.link,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
logger.info(`Adding announcement with ID ${ id } (title: ${ announcement.title })`);
|
|
105
|
+
|
|
106
|
+
await dispatch('notifications/add', notification);
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
logger.error(`Announcement type ${ announcement.target } is not supported`);
|
|
110
|
+
}
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"releases": [
|
|
4
|
+
{
|
|
5
|
+
"name": "2.12.2"
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"name": "2.11.3"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"name": "2.10.3"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"announcements": [
|
|
15
|
+
{
|
|
16
|
+
"id": "security-update",
|
|
17
|
+
"target": "notification/announcement",
|
|
18
|
+
"title": "Important Security Update",
|
|
19
|
+
"message": "A critical security vulnerability has been discovered in version 2.10.1. Users are strongly advised to update to version 2.12.2 immediately to ensure their systems remain secure.",
|
|
20
|
+
"cta": {
|
|
21
|
+
"primary" : {
|
|
22
|
+
"action": "Update Now",
|
|
23
|
+
"link": "https://www.suse.com/"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "suse-rocks",
|
|
29
|
+
"target": "homepage/banner",
|
|
30
|
+
"title": "Important Security Update",
|
|
31
|
+
"message": "A critical security vulnerability has been discovered in version 2.10.1. Users are strongly advised to update to version 2.12.2 immediately to ensure their systems remain secure.",
|
|
32
|
+
"cta": {
|
|
33
|
+
"primary" : {
|
|
34
|
+
"action": "Update Now",
|
|
35
|
+
"link": "https://www.suse.com/"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
@@ -15,6 +15,7 @@ import { Context, DynamicContent, VersionInfo } from './types';
|
|
|
15
15
|
import { createLogger, LOCAL_STORAGE_CONTENT_DEBUG_LOG } from './util';
|
|
16
16
|
import { getConfig } from './config';
|
|
17
17
|
import { SystemInfoProvider } from './info';
|
|
18
|
+
import { processAnnouncements } from './announcement';
|
|
18
19
|
|
|
19
20
|
const FETCH_DELAY = 3 * 1000; // Short delay to let UI settle before we fetch the updates document
|
|
20
21
|
const FETCH_REQUEST_TIMEOUT = 15000; // Time out the request after 15 seconds
|
|
@@ -83,7 +84,7 @@ export async function fetchAndProcessDynamicContent(dispatch: Function, getters:
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
const versionInfo: VersionInfo = {
|
|
86
|
-
version,
|
|
87
|
+
version: version as semver.SemVer, // Will be defined, can not be null here
|
|
87
88
|
isPrime: config.prime,
|
|
88
89
|
};
|
|
89
90
|
|
|
@@ -103,7 +104,7 @@ export async function fetchAndProcessDynamicContent(dispatch: Function, getters:
|
|
|
103
104
|
// If the cached content has a debug version then use that as an override for the current version number
|
|
104
105
|
// This is only for debug and testing purposes
|
|
105
106
|
if (content.settings?.debugVersion) {
|
|
106
|
-
versionInfo.version = semver.coerce(content.settings.debugVersion);
|
|
107
|
+
versionInfo.version = semver.coerce(content.settings.debugVersion) || version;
|
|
107
108
|
logger.debug(`Overriding version number to ${ content.settings.debugVersion }`);
|
|
108
109
|
}
|
|
109
110
|
|
|
@@ -117,6 +118,9 @@ export async function fetchAndProcessDynamicContent(dispatch: Function, getters:
|
|
|
117
118
|
// EOM, EOL notifications
|
|
118
119
|
processSupportNotices(context, content.support, versionInfo);
|
|
119
120
|
}
|
|
121
|
+
|
|
122
|
+
// Announcements - processed for all users
|
|
123
|
+
processAnnouncements(context, content.announcements, versionInfo);
|
|
120
124
|
} catch (e) {
|
|
121
125
|
logger.error('Error reading or processing dynamic content', e);
|
|
122
126
|
}
|
|
@@ -27,7 +27,7 @@ export async function processReleaseVersion(context: Context, releaseInfo: Relea
|
|
|
27
27
|
const versions = releaseInfo.map((v: any) => semver.coerce(v.name));
|
|
28
28
|
|
|
29
29
|
// Sort the versions, so that the newest is first in the list
|
|
30
|
-
versions.sort((a: any, b: any) => semver.
|
|
30
|
+
versions.sort((a: any, b: any) => semver.rcompare(a, b));
|
|
31
31
|
|
|
32
32
|
// Find first newer version
|
|
33
33
|
const newer = versions.find((v: any) => semver.gt(v, version));
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notification handler for dynamic content announcements
|
|
3
|
+
*
|
|
4
|
+
* This provides custom handling for read/unread state using a single user preference
|
|
5
|
+
*/
|
|
6
|
+
import { Notification, NotificationHandler } from '@shell/types/notifications';
|
|
7
|
+
import { READ_ANNOUNCEMENTS } from '@shell/store/prefs';
|
|
8
|
+
import { ANNOUNCEMENT_PREFIX } from './announcement';
|
|
9
|
+
|
|
10
|
+
// Global name for this handler that can be used when creating notifications to associate them with this handler
|
|
11
|
+
export const DynamicContentAnnouncementHandlerName = 'dc-announcements';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Create the dynamic content notification handler
|
|
15
|
+
*
|
|
16
|
+
* This is for announcements, where we need to manage an array of IDs of announcements that have been read, which
|
|
17
|
+
* is taken care of by this custom handler.
|
|
18
|
+
*
|
|
19
|
+
* When a notification is read/unread that specifies this handler, we will add or remove its ID from the list of
|
|
20
|
+
* read IDs that we maintain in the user preference value.
|
|
21
|
+
*
|
|
22
|
+
* This allows us to use a single user preference to track read announcements
|
|
23
|
+
*/
|
|
24
|
+
export function createHandler(store: any): NotificationHandler {
|
|
25
|
+
return {
|
|
26
|
+
async onReadUpdated(notification: Notification, read: boolean) {
|
|
27
|
+
if (!notification.id.startsWith(ANNOUNCEMENT_PREFIX)) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const id = notification.id.substring(ANNOUNCEMENT_PREFIX.length);
|
|
32
|
+
const announcements = store.getters['notifications/all'].filter((n: any) => n.id.startsWith(ANNOUNCEMENT_PREFIX));
|
|
33
|
+
const pref = store.getters['prefs/get'](READ_ANNOUNCEMENTS) || '';
|
|
34
|
+
const values = !pref.length ? [] : pref.split(',').filter((v: string) => !announcements.includes(v));
|
|
35
|
+
const valuesUnique = new Set(values);
|
|
36
|
+
|
|
37
|
+
if (read) {
|
|
38
|
+
valuesUnique.add(id);
|
|
39
|
+
} else {
|
|
40
|
+
valuesUnique.delete(id);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const newValues = Array.from(valuesUnique).sort();
|
|
44
|
+
|
|
45
|
+
await store.dispatch('prefs/set', { key: READ_ANNOUNCEMENTS, value: newValues.join(',') });
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -56,7 +56,7 @@ export type Context = {
|
|
|
56
56
|
* Version information
|
|
57
57
|
*/
|
|
58
58
|
export type VersionInfo = {
|
|
59
|
-
version: SemVer
|
|
59
|
+
version: SemVer;
|
|
60
60
|
isPrime: boolean;
|
|
61
61
|
};
|
|
62
62
|
|
|
@@ -90,6 +90,37 @@ export type SupportInfo = {
|
|
|
90
90
|
}
|
|
91
91
|
};
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Call to action for an announcement
|
|
95
|
+
*/
|
|
96
|
+
export type CallToAction = {
|
|
97
|
+
action: string;
|
|
98
|
+
link: string;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Announcements to be shown in the notification center or on the home page
|
|
103
|
+
*
|
|
104
|
+
* Target determines where the notification will be shown, supported values:
|
|
105
|
+
*
|
|
106
|
+
* - `notification/announcement` - Shown with `Announcement` level in the Notification Center
|
|
107
|
+
* - `notification/info` - Shown with `Info` level in the Notification Center
|
|
108
|
+
* - `notification/warning` - Shown with `Warning` level in the Notification Center
|
|
109
|
+
*
|
|
110
|
+
*/
|
|
111
|
+
export type Announcement = {
|
|
112
|
+
id: string; // Unique id for this announcement
|
|
113
|
+
title: string; // Title to be shown
|
|
114
|
+
message: string; // Message/Body for the announcement
|
|
115
|
+
target: string; // Where the announcement should be shown
|
|
116
|
+
version?: string; // Version or semver expression for when to show this announcement
|
|
117
|
+
audience?: 'admin' | 'all'; // Audience - show for just Admins or for all users
|
|
118
|
+
cta?: {
|
|
119
|
+
primary: CallToAction, // Must have a primary call to action, if we have a cta field
|
|
120
|
+
secondary?: CallToAction,
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
93
124
|
/**
|
|
94
125
|
* Main type for the metadata that is retrieved from the dynamic content endpoint
|
|
95
126
|
*/
|
|
@@ -97,5 +128,6 @@ export type DynamicContent = {
|
|
|
97
128
|
version: string;
|
|
98
129
|
releases: ReleaseInfo[],
|
|
99
130
|
support: SupportInfo,
|
|
131
|
+
announcements: Announcement[],
|
|
100
132
|
settings?: Partial<SettingsInfo>,
|
|
101
133
|
};
|
package/utils/object.js
CHANGED
|
@@ -205,7 +205,7 @@ export function definedKeys(obj) {
|
|
|
205
205
|
return compact(flattenDeep(keys));
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
export function diff(from, to) {
|
|
208
|
+
export function diff(from, to, preventNull = false) {
|
|
209
209
|
from = from || {};
|
|
210
210
|
to = to || {};
|
|
211
211
|
|
|
@@ -234,7 +234,25 @@ export function diff(from, to) {
|
|
|
234
234
|
const missing = difference(fromKeys, toKeys);
|
|
235
235
|
|
|
236
236
|
for ( const k of missing ) {
|
|
237
|
-
|
|
237
|
+
// we need to gate this in order to prevent unforseen problems with addonConfig
|
|
238
|
+
if (preventNull) {
|
|
239
|
+
// keys that come from "definedKeys" method are strings with "" chars inside... We need to clean them up
|
|
240
|
+
// so that we can access the value of the obj property
|
|
241
|
+
let key = k;
|
|
242
|
+
|
|
243
|
+
if (!k.includes('.')) {
|
|
244
|
+
key = k.replaceAll('"', '');
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// // if value exists in "from" but is missing in "to", let's add it, otherwise we just set it null as we did before
|
|
248
|
+
if (from[key] !== undefined && from[key] !== null) {
|
|
249
|
+
set(out, key, from[key]);
|
|
250
|
+
} else {
|
|
251
|
+
set(out, key, null);
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
set(out, k, null);
|
|
255
|
+
}
|
|
238
256
|
}
|
|
239
257
|
|
|
240
258
|
return out;
|
package/utils/scroll.js
ADDED
package/utils/settings.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Store } from 'vuex';
|
|
|
3
3
|
import { DEFAULT_PERF_SETTING, PerfSettings, SETTING } from '@shell/config/settings';
|
|
4
4
|
import { pluralize } from '@shell/utils/string';
|
|
5
5
|
import { _MULTI } from '@shell/plugins/dashboard-store/actions';
|
|
6
|
+
import { ClusterProvisionerContext } from '@shell/core/types';
|
|
6
7
|
|
|
7
8
|
export const fetchOrCreateSetting = async(store: Store<any>, id: string, val: string, save = true): Promise<any> => {
|
|
8
9
|
let setting;
|
|
@@ -109,3 +110,17 @@ export const getPerformanceSetting = (rootGetters: Record<string, (arg0: string,
|
|
|
109
110
|
|
|
110
111
|
return Object.assign(safeDefaults, perfSetting || {});
|
|
111
112
|
};
|
|
113
|
+
|
|
114
|
+
export const isProviderEnabled = (context: ClusterProvisionerContext, provider: string): boolean => {
|
|
115
|
+
const providerTypesJSON = context.getters['management/byId'](MANAGEMENT.SETTING, SETTING.KEV2_OPERATORS )?.value;
|
|
116
|
+
const providerTypes = providerTypesJSON ? JSON.parse(providerTypesJSON) : [];
|
|
117
|
+
|
|
118
|
+
for ( let i = 0; i < providerTypes.length; i++) {
|
|
119
|
+
if ( providerTypes[i].name === provider) {
|
|
120
|
+
return providerTypes[i].active;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// We want to have providers enabled by default unless they are turned off by a setting
|
|
125
|
+
return true;
|
|
126
|
+
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const FIELDS = {
|
|
2
|
-
NAME:
|
|
3
|
-
QUANTITY:
|
|
2
|
+
NAME: 'pool.name',
|
|
3
|
+
QUANTITY: 'pool.quantity',
|
|
4
|
+
AUTOSCALER_MIN: 'pool.autoscalingMinSize',
|
|
5
|
+
AUTOSCALER_MAX: 'pool.autoscalingMaxSize'
|
|
4
6
|
};
|
|
5
7
|
|
|
6
8
|
const RULESETS = [
|
|
@@ -11,7 +13,15 @@ const RULESETS = [
|
|
|
11
13
|
{
|
|
12
14
|
path: FIELDS.NAME,
|
|
13
15
|
rules: ['required'],
|
|
14
|
-
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
path: FIELDS.AUTOSCALER_MIN,
|
|
19
|
+
rules: ['isPositive', 'isAutoscalerMaxGreaterThanMin'],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
path: FIELDS.AUTOSCALER_MAX,
|
|
23
|
+
rules: ['isPositive', 'isAutoscalerMaxGreaterThanMin'],
|
|
24
|
+
},
|
|
15
25
|
];
|
|
16
26
|
|
|
17
27
|
export const MACHINE_POOL_VALIDATION = {
|