@rancher/shell 3.0.12-rc.5 → 3.0.12-rc.6
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/apis/intf/resources-api/resource-base.ts +42 -2
- package/apis/intf/resources-api/resource-instance.ts +101 -0
- package/apis/intf/resources-api/resources-api.ts +177 -23
- package/apis/intf/resources.ts +8 -6
- package/apis/resources/__tests__/resources-api-class.test.ts +309 -28
- package/apis/resources/resources-api-class.ts +232 -43
- package/assets/images/providers/traefik.png +0 -0
- package/assets/translations/en-us.yaml +10 -4
- package/chart/__tests__/rancher-monitoring-dashboards-index.test.ts +269 -0
- package/chart/rancher-monitoring-dashboards/index.vue +155 -0
- package/cloud-credential/__tests__/generic.test.ts +132 -0
- package/cloud-credential/generic.vue +33 -3
- package/components/EtcdInfoBanner.vue +2 -12
- package/components/GrafanaDashboard.vue +2 -8
- package/components/Resource/Detail/Masthead/__tests__/index.test.ts +68 -14
- package/components/Resource/Detail/Masthead/index.vue +8 -3
- package/components/form/Security.vue +1 -1
- package/components/formatter/Translate.vue +22 -1
- package/components/nav/Group.vue +5 -10
- package/components/nav/TopLevelMenu.vue +1 -30
- package/components/nav/__tests__/Group.test.ts +61 -0
- package/config/labels-annotations.js +1 -0
- package/config/table-headers.js +5 -2
- package/core/__tests__/plugin-products-apply.test.ts +787 -0
- package/core/__tests__/plugin-products-extend.test.ts +189 -0
- package/core/__tests__/plugin-products-helpers.test.ts +81 -78
- package/core/__tests__/plugin-products-new.test.ts +389 -0
- package/core/__tests__/plugin-products-scenarios.test.ts +980 -0
- package/core/__tests__/plugin-products-side-menu.test.ts +1935 -0
- package/core/plugin-products-base.ts +201 -93
- package/core/plugin-products-extending.ts +1 -1
- package/core/plugin-products-external.ts +380 -0
- package/core/plugin-products-helpers.ts +28 -24
- package/core/plugin-products-internal.ts +207 -0
- package/core/plugin-products-top-level.ts +10 -5
- package/core/plugin-products-type-guards.ts +17 -6
- package/core/plugin-products.ts +5 -7
- package/core/plugin-types.ts +1 -389
- package/core/plugin.ts +10 -11
- package/core/types.ts +6 -202
- package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +52 -0
- package/detail/pod.vue +1 -1
- package/detail/provisioning.cattle.io.cluster.vue +0 -2
- package/edit/auth/AuthProviderWarningBanners.vue +12 -0
- package/edit/auth/__tests__/AuthProviderWarningBanners.test.ts +10 -1
- package/edit/auth/__tests__/azuread.test.ts +1 -0
- package/edit/auth/__tests__/github.test.ts +1 -0
- package/edit/auth/__tests__/oidc.test.ts +1 -0
- package/edit/auth/__tests__/saml.test.ts +1 -0
- package/edit/auth/ldap/__tests__/index.test.ts +1 -0
- package/edit/provisioning.cattle.io.cluster/index.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/rke2.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +2 -2
- package/list/management.cattle.io.user.vue +24 -5
- package/list/utils/management.cattle.io.cluster.utils.ts +1 -1
- package/machine-config/__tests__/generic.test.ts +163 -0
- package/machine-config/components/EC2Networking.vue +31 -7
- package/machine-config/components/__tests__/EC2Networking.test.ts +38 -15
- package/machine-config/generic.vue +32 -5
- package/mixins/resource-fetch.js +1 -1
- package/models/__tests__/rke-machine.cattle.io.vmwarevspheremachinetemplate.test.ts +22 -0
- package/models/pod.js +12 -10
- package/models/rke-machine.cattle.io.vmwarevspheremachinetemplate.js +9 -0
- package/package.json +1 -1
- package/pages/auth/login.vue +1 -1
- package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +110 -0
- package/pages/c/_cluster/apps/charts/install.vue +29 -0
- package/pages/c/_cluster/auth/config/index.vue +11 -4
- package/pages/c/_cluster/monitoring/index.vue +6 -1
- package/plugins/dashboard-store/resource-class.js +10 -3
- package/plugins/steve/__tests__/steve-class-resource-api.test.ts +147 -0
- package/plugins/steve/steve-class.js +43 -0
- package/plugins/steve/subscribe.js +11 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +115 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +83 -3
- package/store/__tests__/auth.test.ts +18 -0
- package/store/__tests__/notifications.test.ts +466 -1
- package/store/__tests__/ui-context.test.ts +255 -0
- package/store/auth.js +11 -1
- package/store/features.js +1 -0
- package/store/plugins.js +6 -0
- package/types/rancher/steve.api.ts +2 -2
- package/types/shell/index.d.ts +58 -0
- package/types/store/dashboard-store.types.ts +2 -2
- package/types/store/type-map.ts +262 -1
- package/utils/async.ts +2 -0
- package/utils/grafana.js +2 -17
- package/utils/monitoring.js +38 -1
- package/core/__tests__/plugin-products.test.ts +0 -4694
package/core/types.ts
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import { ProductFunction } from './plugin';
|
|
2
1
|
import { RouteRecordRaw } from 'vue-router';
|
|
3
2
|
import type { ExtensionManager } from '@shell/types/extension-manager';
|
|
4
3
|
import { PaginationSettingsStores } from '@shell/types/resources/settings';
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
ProductChildGroup,
|
|
9
|
-
ProductChildPage
|
|
10
|
-
} from './plugin-types';
|
|
4
|
+
import { IExtensionProducts } from '@shell/core/plugin-products-external';
|
|
5
|
+
import { RouteRecordRawWithParams } from '@shell/core/plugin-types';
|
|
6
|
+
import { TypeMapProduct } from '@shell/types/store/type-map';
|
|
11
7
|
|
|
12
8
|
// Cluster Provisioning types
|
|
13
9
|
export * from './types-provisioning';
|
|
@@ -200,137 +196,6 @@ export type ExtensionEnvironment = {
|
|
|
200
196
|
docsVersion: string; /** e.g. 'v2.10' */
|
|
201
197
|
};
|
|
202
198
|
|
|
203
|
-
export interface ProductOptions {
|
|
204
|
-
/**
|
|
205
|
-
* The category this product belongs under. i.e. 'config'
|
|
206
|
-
*/
|
|
207
|
-
category?: string;
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Hide the Copy KubeConfig button in the header
|
|
211
|
-
*/
|
|
212
|
-
hideCopyConfig?: boolean;
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Hide the Download KubeConfig button in the header
|
|
216
|
-
*/
|
|
217
|
-
hideKubeConfig?: boolean;
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Hide the Kubectl Shell button in the header
|
|
221
|
-
*/
|
|
222
|
-
hideKubeShell?: boolean;
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Hide the Namespace location
|
|
226
|
-
*/
|
|
227
|
-
hideNamespaceLocation?: boolean;
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Hide the system resources
|
|
231
|
-
*/
|
|
232
|
-
|
|
233
|
-
hideSystemResources?: boolean;
|
|
234
|
-
/**
|
|
235
|
-
* The icon that should be displayed beside this item in the navigation.
|
|
236
|
-
*/
|
|
237
|
-
icon?: string,
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Only load the product if the feature is present
|
|
241
|
-
*/
|
|
242
|
-
ifFeature?: string | RegExp;
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Only load the product if the type is present
|
|
246
|
-
*/
|
|
247
|
-
ifHave?: string;
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Only load the product if the group is present
|
|
251
|
-
*/
|
|
252
|
-
ifHaveGroup?: string | RegExp;
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Only load the product if the type is present
|
|
256
|
-
*/
|
|
257
|
-
ifHaveType?: string | RegExp;
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Hide the product if the type is present (opposite of ifHaveType)
|
|
261
|
-
*/
|
|
262
|
-
ifNotHaveType?: string | RegExp;
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* The vuex store that this product should use by default i.e. 'management'
|
|
266
|
-
*/
|
|
267
|
-
inStore?: string;
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Show the cluster switcher in the navigation
|
|
271
|
-
*/
|
|
272
|
-
showClusterSwitcher?: boolean;
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Indicates whether UI Extensions can add pages to this product
|
|
276
|
-
*/
|
|
277
|
-
extendable?: boolean;
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Show the namespace filter in the header
|
|
281
|
-
*/
|
|
282
|
-
showNamespaceFilter?: boolean;
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* A number used to determine where in navigation this item will be placed. The highest number will be at the top of the list.
|
|
286
|
-
*/
|
|
287
|
-
weight?: number;
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* The route that the product will lead to if click on in navigation.
|
|
291
|
-
*/
|
|
292
|
-
to?: PluginRouteRecordRaw;
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Whether the product can be removed by users (default: false — products are built-in/not removable unless explicitly set to true)
|
|
296
|
-
*/
|
|
297
|
-
removable?: boolean;
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Alternative to the icon property. Uses require
|
|
301
|
-
*/
|
|
302
|
-
svg?: Function;
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Product name
|
|
306
|
-
*/
|
|
307
|
-
name?: string;
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* controls whether a workspace switcher dropdown appears in the header (instead of the namespace filter) if set to true
|
|
311
|
-
*/
|
|
312
|
-
showWorkspaceSwitcher?: boolean;
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
*
|
|
316
|
-
*/
|
|
317
|
-
label?: string;
|
|
318
|
-
|
|
319
|
-
labelKey?: string;
|
|
320
|
-
|
|
321
|
-
iconHeader?: string;
|
|
322
|
-
|
|
323
|
-
// Do not use - internal use only
|
|
324
|
-
version?: number;
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* Leaving these here for completeness but I don't think these should be advertised as useable to plugin creators.
|
|
328
|
-
*/
|
|
329
|
-
// ifHaveVerb: string | RegExp;
|
|
330
|
-
// supportRoute: string;
|
|
331
|
-
// typeStoreMap: string;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
199
|
/**
|
|
335
200
|
* Configuration required to show a header in a ResourceTable
|
|
336
201
|
*/
|
|
@@ -399,17 +264,6 @@ export interface HeaderOptions {
|
|
|
399
264
|
*/
|
|
400
265
|
export type PaginationHeaderOptions = Omit<HeaderOptions, 'getValue'>
|
|
401
266
|
|
|
402
|
-
export type ResourceTypeConfig = {
|
|
403
|
-
options?: {
|
|
404
|
-
isCreatable?: boolean;
|
|
405
|
-
isEditable?: boolean;
|
|
406
|
-
},
|
|
407
|
-
listHeaders?: {
|
|
408
|
-
legacy?: HeaderOptions[];
|
|
409
|
-
paginated?: PaginationHeaderOptions[];
|
|
410
|
-
}
|
|
411
|
-
};
|
|
412
|
-
|
|
413
267
|
/**
|
|
414
268
|
* External extension configuration for @HeaderOptions
|
|
415
269
|
*/
|
|
@@ -568,7 +422,7 @@ export interface DSLReturnType {
|
|
|
568
422
|
* @param options {@link ProductOptions}
|
|
569
423
|
* @returns {@link void}
|
|
570
424
|
*/
|
|
571
|
-
product: (options:
|
|
425
|
+
product: (options: TypeMapProduct) => void;
|
|
572
426
|
|
|
573
427
|
/**
|
|
574
428
|
/**
|
|
@@ -691,62 +545,12 @@ export type ModelExtensionContext = {
|
|
|
691
545
|
/**
|
|
692
546
|
* Constructor signature for a model extension
|
|
693
547
|
*/
|
|
694
|
-
export type ModelExtensionConstructor = (context: ModelExtensionContext) => Object;
|
|
548
|
+
export type ModelExtensionConstructor = new (context: ModelExtensionContext) => Object;
|
|
695
549
|
|
|
696
550
|
/**
|
|
697
551
|
* Interface for a UI Extension
|
|
698
552
|
*/
|
|
699
|
-
export interface IExtension {
|
|
700
|
-
/**
|
|
701
|
-
* Register a top-level product as a flag on the plugin
|
|
702
|
-
* @internal - DO NOT USE - Internal API only
|
|
703
|
-
*/
|
|
704
|
-
_registerTopLevelProduct(): void;
|
|
705
|
-
/**
|
|
706
|
-
*
|
|
707
|
-
* @internal - DO NOT USE - Internal API only
|
|
708
|
-
*/
|
|
709
|
-
_setStartRouteWithProduct(value: boolean): void;
|
|
710
|
-
|
|
711
|
-
/**
|
|
712
|
-
* Add a product to the sidebar, with children and a side menu for navigation for internal pages
|
|
713
|
-
* @param name
|
|
714
|
-
* @param config
|
|
715
|
-
*/
|
|
716
|
-
addProduct(product: ProductMetadata, config: ProductChildPage[]): void;
|
|
717
|
-
addProduct(product: ProductMetadata, config: ProductChildGroup[]): void;
|
|
718
|
-
addProduct(product: ProductMetadata, config: ProductChild[]): void;
|
|
719
|
-
|
|
720
|
-
/**
|
|
721
|
-
* Add a product to the sidebar, without children (no side menu, single page only)
|
|
722
|
-
* @param product
|
|
723
|
-
*/
|
|
724
|
-
addProduct(product: ProductSinglePage): void;
|
|
725
|
-
|
|
726
|
-
/**
|
|
727
|
-
* Add a product with just a name (convenience/bridge method for quick setup).
|
|
728
|
-
* Creates a basic product with an empty page component automatically.
|
|
729
|
-
* This is useful for getting started quickly - expand to the full API once you're ready to add custom pages.
|
|
730
|
-
* @param productName Simple product name - will be used as both the name and label
|
|
731
|
-
*/
|
|
732
|
-
addProduct(productName: string): void;
|
|
733
|
-
|
|
734
|
-
/**
|
|
735
|
-
* Add a product to the sidebar (deprecated, use other signatures of addProduct instead)
|
|
736
|
-
* @deprecated Use other `addProduct` signatures instead
|
|
737
|
-
* @param importFn Function that will import the module containing a product definition
|
|
738
|
-
*/
|
|
739
|
-
addProduct(importFn: ProductFunction): void;
|
|
740
|
-
|
|
741
|
-
/**
|
|
742
|
-
* Extend an existing product in Rancher, with children and a side menu for navigation for internal pages
|
|
743
|
-
*
|
|
744
|
-
* @param product Product to be extended
|
|
745
|
-
* @param config Product extension configuration
|
|
746
|
-
*/
|
|
747
|
-
extendProduct(product: StandardProductName | string, config: ProductChildPage[]): void;
|
|
748
|
-
extendProduct(product: StandardProductName | string, config: ProductChildGroup[]): void;
|
|
749
|
-
extendProduct(product: StandardProductName | string, config: ProductChild[]): void;
|
|
553
|
+
export interface IExtension extends IExtensionProducts {
|
|
750
554
|
|
|
751
555
|
/**
|
|
752
556
|
* Add a locale to the i18n store
|
|
@@ -241,4 +241,56 @@ describe('view: provisioning.cattle.io.cluster', () => {
|
|
|
241
241
|
expect(wrapper.vm.fakeMachines).toHaveLength(0);
|
|
242
242
|
});
|
|
243
243
|
});
|
|
244
|
+
|
|
245
|
+
describe('computed: showLog', () => {
|
|
246
|
+
it('returns true when mgmt has a log link and extDetailTabs.logs is enabled', async() => {
|
|
247
|
+
const value = { mgmt: { hasLink: (link: string) => link === 'log' } };
|
|
248
|
+
|
|
249
|
+
const wrapper = shallowMount(ProvisioningCattleIoCluster, {
|
|
250
|
+
props: { value },
|
|
251
|
+
global: { mocks },
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
await wrapper.setData({ extDetailTabs: { logs: true } });
|
|
255
|
+
|
|
256
|
+
expect(wrapper.vm.showLog).toStrictEqual(true);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('returns false when mgmt does not have a log link', async() => {
|
|
260
|
+
const value = { mgmt: { hasLink: () => false } };
|
|
261
|
+
|
|
262
|
+
const wrapper = shallowMount(ProvisioningCattleIoCluster, {
|
|
263
|
+
props: { value },
|
|
264
|
+
global: { mocks },
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
await wrapper.setData({ extDetailTabs: { logs: true } });
|
|
268
|
+
|
|
269
|
+
expect(wrapper.vm.showLog).toStrictEqual(false);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('returns false when mgmt has a log link but extDetailTabs.logs is disabled', async() => {
|
|
273
|
+
const value = { mgmt: { hasLink: (link: string) => link === 'log' } };
|
|
274
|
+
|
|
275
|
+
const wrapper = shallowMount(ProvisioningCattleIoCluster, {
|
|
276
|
+
props: { value },
|
|
277
|
+
global: { mocks },
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
await wrapper.setData({ extDetailTabs: { logs: false } });
|
|
281
|
+
|
|
282
|
+
expect(wrapper.vm.showLog).toStrictEqual(false);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('returns false when mgmt is undefined', async() => {
|
|
286
|
+
const value = {};
|
|
287
|
+
|
|
288
|
+
const wrapper = shallowMount(ProvisioningCattleIoCluster, {
|
|
289
|
+
props: { value },
|
|
290
|
+
global: { mocks },
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
expect(wrapper.vm.showLog).toBeFalsy();
|
|
294
|
+
});
|
|
295
|
+
});
|
|
244
296
|
});
|
package/detail/pod.vue
CHANGED
|
@@ -38,7 +38,7 @@ export default {
|
|
|
38
38
|
const projectId = namespace?.metadata?.labels[PROJECT];
|
|
39
39
|
|
|
40
40
|
if (projectId) {
|
|
41
|
-
this.POD_PROJECT_METRICS_DETAIL_URL = `/api/v1/namespaces/cattle-project-${ projectId }-monitoring/services/http:cattle-project-${ projectId }-monitoring-grafana:80/proxy/d/rancher-pod-containers-1/rancher-pod-containers?orgId=1
|
|
41
|
+
this.POD_PROJECT_METRICS_DETAIL_URL = `/api/v1/namespaces/cattle-project-${ projectId }-monitoring/services/http:cattle-project-${ projectId }-monitoring-grafana:80/proxy/d/rancher-pod-containers-1/rancher-pod-containers?orgId=1`;
|
|
42
42
|
this.POD_PROJECT_METRICS_SUMMARY_URL = `/api/v1/namespaces/cattle-project-${ projectId }-monitoring/services/http:cattle-project-${ projectId }-monitoring-grafana:80/proxy/d/rancher-pod-1/rancher-pod?orgId=1`;
|
|
43
43
|
|
|
44
44
|
this.showProjectMetrics = await allDashboardsExist(this.$store, this.currentCluster.id, [this.POD_PROJECT_METRICS_DETAIL_URL, this.POD_PROJECT_METRICS_SUMMARY_URL], 'cluster', projectId);
|
|
@@ -227,9 +227,7 @@ export default {
|
|
|
227
227
|
if ( this.$store.getters['management/canList'](MANAGEMENT.RKE_TEMPLATE) ) {
|
|
228
228
|
this.$store.dispatch('management/findAll', { type: MANAGEMENT.RKE_TEMPLATE });
|
|
229
229
|
}
|
|
230
|
-
},
|
|
231
230
|
|
|
232
|
-
created() {
|
|
233
231
|
if ( this.showLog ) {
|
|
234
232
|
this.connectLog();
|
|
235
233
|
}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { defineComponent } from 'vue';
|
|
3
3
|
import { Banner } from '@components/Banner';
|
|
4
|
+
import { HIDE_LOCAL_AUTH_PROVIDER } from '@shell/store/features';
|
|
4
5
|
|
|
5
6
|
export default defineComponent({
|
|
6
7
|
name: 'AuthProviderWarningBanners',
|
|
7
8
|
|
|
8
9
|
components: { Banner },
|
|
9
10
|
|
|
11
|
+
data() {
|
|
12
|
+
return { disableLocalAuth: this.$store.getters['features/get'](HIDE_LOCAL_AUTH_PROVIDER) };
|
|
13
|
+
},
|
|
14
|
+
|
|
10
15
|
props: {
|
|
11
16
|
tArgs: {
|
|
12
17
|
type: Object,
|
|
@@ -24,6 +29,13 @@ export default defineComponent({
|
|
|
24
29
|
color="warning"
|
|
25
30
|
data-testid="auth-provider-disabled-warning-banner"
|
|
26
31
|
/>
|
|
32
|
+
<Banner
|
|
33
|
+
v-if="disableLocalAuth"
|
|
34
|
+
color="warning"
|
|
35
|
+
data-testid="auth-provider-disable-local-auth-banner"
|
|
36
|
+
>
|
|
37
|
+
<span v-clean-html="t('authConfig.bannerEnableAuthProvider', {}, true)" />
|
|
38
|
+
</Banner>
|
|
27
39
|
<Banner
|
|
28
40
|
color="warning"
|
|
29
41
|
data-testid="auth-provider-admin-permissions-warning-banner"
|
|
@@ -4,7 +4,16 @@ import { mount } from '@vue/test-utils';
|
|
|
4
4
|
describe('component: AuthProviderWarningBanners.vue', () => {
|
|
5
5
|
const wrapper = mount(AuthProviderWarningBanners, {
|
|
6
6
|
props: { tArgs: { provider: 'Any Provider', username: 'username' } },
|
|
7
|
-
global: {
|
|
7
|
+
global: {
|
|
8
|
+
mocks: {
|
|
9
|
+
$store: {
|
|
10
|
+
getters: {
|
|
11
|
+
'i18n/t': (text: string) => text,
|
|
12
|
+
'features/get': () => false,
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
8
17
|
});
|
|
9
18
|
|
|
10
19
|
it('should render properly', () => {
|
|
@@ -87,7 +87,7 @@ export default {
|
|
|
87
87
|
await this.$store.dispatch('management/watch', { type: MANAGEMENT.CLUSTER, registerType: true });
|
|
88
88
|
await this.$store.dispatch('management/watch', { type: CAPI.RANCHER_CLUSTER, registerType: true });
|
|
89
89
|
} else {
|
|
90
|
-
hash.
|
|
90
|
+
hash.mgmtCluster = this.value.waitForMgmt();
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// No need to fetch charts when editing an RKE1 cluster
|
|
@@ -1629,7 +1629,7 @@ export default {
|
|
|
1629
1629
|
const isIpv6 = this.hasOnlyIpv6Pools;
|
|
1630
1630
|
|
|
1631
1631
|
const flannelMasqInvalid = isIpv6 && isK3s && !flannelMasqEnabled;
|
|
1632
|
-
const stackPrefInvalid = (isIpv6 && stackPreference !== STACK_PREFS.IPV6) || (isDualStack &&
|
|
1632
|
+
const stackPrefInvalid = (isIpv6 && stackPreference !== STACK_PREFS.IPV6) || (isDualStack && stackPreference !== STACK_PREFS.DUAL);
|
|
1633
1633
|
|
|
1634
1634
|
const clusterCIDRInvalid = (isIpv6 || isDualStack) && !clusterCIDR.includes(':');
|
|
1635
1635
|
const serviceCIDRInvalid = (isIpv6 || isDualStack) && !serviceCIDR.includes(':');
|
|
@@ -120,7 +120,7 @@ export default {
|
|
|
120
120
|
|
|
121
121
|
stackPreference: {
|
|
122
122
|
get() {
|
|
123
|
-
return this.localValue.spec?.networking?.stackPreference || STACK_PREFS.
|
|
123
|
+
return this.localValue.spec?.networking?.stackPreference || STACK_PREFS.DUAL;
|
|
124
124
|
},
|
|
125
125
|
set(neu) {
|
|
126
126
|
if (!this.localValue.spec.networking) {
|
|
@@ -295,7 +295,7 @@ export default {
|
|
|
295
295
|
<div class="col span-3">
|
|
296
296
|
<LabeledSelect
|
|
297
297
|
:key="hasSomeIpv6Pools"
|
|
298
|
-
:value="localValue?.spec?.rkeConfig?.networking?.stackPreference || STACK_PREFS.
|
|
298
|
+
:value="localValue?.spec?.rkeConfig?.networking?.stackPreference || STACK_PREFS.DUAL"
|
|
299
299
|
:mode="mode"
|
|
300
300
|
:options="stackPreferenceOptions"
|
|
301
301
|
data-testid="network-tab-stackpreferences"
|
|
@@ -8,6 +8,8 @@ import ResourceFetch from '@shell/mixins/resource-fetch';
|
|
|
8
8
|
import { isAdminUser } from '@shell/store/type-map';
|
|
9
9
|
import TableDataUserIcon from '@shell/components/TableDataUserIcon';
|
|
10
10
|
import { RcButton } from '@components/RcButton';
|
|
11
|
+
import { allHash } from '@shell/utils/promise';
|
|
12
|
+
import Loading from '@shell/components/Loading.vue';
|
|
11
13
|
|
|
12
14
|
export default {
|
|
13
15
|
components: {
|
|
@@ -15,7 +17,8 @@ export default {
|
|
|
15
17
|
ResourceTable,
|
|
16
18
|
Masthead,
|
|
17
19
|
TableDataUserIcon,
|
|
18
|
-
RcButton
|
|
20
|
+
RcButton,
|
|
21
|
+
Loading
|
|
19
22
|
},
|
|
20
23
|
mixins: [ResourceFetch],
|
|
21
24
|
props: {
|
|
@@ -40,9 +43,16 @@ export default {
|
|
|
40
43
|
}
|
|
41
44
|
},
|
|
42
45
|
async fetch() {
|
|
43
|
-
|
|
46
|
+
const promises = {
|
|
47
|
+
resources: this.$fetchType(this.resource),
|
|
48
|
+
localProviderEnabled: this.$store.dispatch('auth/getLocalProviderEnabled'),
|
|
49
|
+
membershipRefreshRequests: this.$store.dispatch('management/create', { type: EXT.GROUP_MEMBERSHIP_REFRESH_REQUESTS }),
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const res = await allHash(promises);
|
|
44
53
|
|
|
45
|
-
this.
|
|
54
|
+
this.localProviderEnabled = res.localProviderEnabled;
|
|
55
|
+
this.membershipRefreshRequests = res.membershipRefreshRequests;
|
|
46
56
|
this.canRefreshMemberships = !!this.membershipRefreshRequests?.canRefreshMemberships;
|
|
47
57
|
},
|
|
48
58
|
|
|
@@ -87,7 +97,14 @@ export default {
|
|
|
87
97
|
|
|
88
98
|
isAdmin() {
|
|
89
99
|
return isAdminUser(this.$store.getters);
|
|
90
|
-
}
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
canCreateUsers() {
|
|
103
|
+
const userCan = !!this.schema?.collectionMethods?.find((x) => x.toLowerCase() === 'post');
|
|
104
|
+
const systemCan = this.localProviderEnabled;
|
|
105
|
+
|
|
106
|
+
return userCan && systemCan;
|
|
107
|
+
},
|
|
91
108
|
},
|
|
92
109
|
|
|
93
110
|
methods: {
|
|
@@ -107,13 +124,15 @@ export default {
|
|
|
107
124
|
</script>
|
|
108
125
|
|
|
109
126
|
<template>
|
|
110
|
-
<
|
|
127
|
+
<Loading v-if="$fetchState.pending" />
|
|
128
|
+
<div v-else>
|
|
111
129
|
<Masthead
|
|
112
130
|
:schema="schema"
|
|
113
131
|
:resource="resource"
|
|
114
132
|
:show-incremental-loading-indicator="incrementalLoadingIndicator"
|
|
115
133
|
:load-resources="loadResources"
|
|
116
134
|
:load-indeterminate="loadIndeterminate"
|
|
135
|
+
:is-creatable="canCreateUsers"
|
|
117
136
|
>
|
|
118
137
|
<template #extraActions>
|
|
119
138
|
<AsyncButton
|
|
@@ -31,7 +31,7 @@ class ManagementClusterUtils {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
const existingFilters = pagination.filters;
|
|
34
|
-
const requiredFilters = paginationFilterClusters($store
|
|
34
|
+
const requiredFilters = paginationFilterClusters($store);
|
|
35
35
|
|
|
36
36
|
for (let i = 0; i < requiredFilters.length; i++) {
|
|
37
37
|
let found = false;
|