@rancher/shell 0.3.25 → 0.3.26

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.
@@ -653,6 +653,10 @@ asyncButton:
653
653
  action: Save
654
654
  success: Saved
655
655
  waiting: Saving…
656
+ editAndContinue:
657
+ action: Save and Continue
658
+ success: Saved
659
+ waiting: Saving…
656
660
  enable:
657
661
  action: Enable
658
662
  success: Enabled
@@ -1841,6 +1845,9 @@ cluster:
1841
1845
  pspChange:
1842
1846
  title: Pod Security Policy deprecation
1843
1847
  body: <p>Kubernetes has removed support for Pod Security Policies (PSPs) starting with version 1.25. If your cluster has PodSecurityPolicy admission controller enabled via "kube-apiserver-arg.enable-admission-plugins" in Cluster YAML, it has to be <i>manually</i> removed before proceeding with the upgrade. Additionally, any PSPs that may be present in the cluster will no longer be available/enforced. Do you want to proceed?</p>
1848
+ editYamlMachinePool:
1849
+ title: Save Machine Configurations
1850
+ body: Machine Configurations define how machines in Pools are deployed.<br><br> They will be saved upfront to ensure valid Cluster YAML can be saved.
1844
1851
  snapshots:
1845
1852
  suffix: Snapshots per node
1846
1853
  systemService:
@@ -327,10 +327,13 @@ export default {
327
327
 
328
328
  async showPreviewYaml() {
329
329
  if ( this.applyHooks ) {
330
- await this.applyHooks(
331
- BEFORE_SAVE_HOOKS,
332
- CONTEXT_HOOK_EDIT_YAML,
333
- );
330
+ try {
331
+ await this.applyHooks(BEFORE_SAVE_HOOKS, CONTEXT_HOOK_EDIT_YAML);
332
+ } catch (e) {
333
+ console.warn('Unable to show yaml: ', e); // eslint-disable-line no-console
334
+
335
+ return;
336
+ }
334
337
  }
335
338
 
336
339
  const resourceYaml = this.createResourceYaml(this.yamlModifiers);
@@ -0,0 +1,63 @@
1
+ import ProjectRow from '@shell/components/form/ResourceQuota/ProjectRow.vue';
2
+ import { RANCHER_TYPES } from '@shell/components/form/ResourceQuota/shared';
3
+ import { shallowMount } from '@vue/test-utils';
4
+ import Vue from 'vue';
5
+
6
+ const CONFIGMAP_STRING = RANCHER_TYPES[0].value;
7
+
8
+ describe('component: ProjectRow.vue', () => {
9
+ const wrapper = shallowMount(ProjectRow,
10
+ {
11
+ propsData: {
12
+ mode: 'edit',
13
+ types: RANCHER_TYPES,
14
+ type: CONFIGMAP_STRING,
15
+ value: {
16
+ spec: {
17
+ namespaceDefaultResourceQuota: { limit: {} },
18
+ resourceQuota: { limit: {} }
19
+ }
20
+ }
21
+ }
22
+ });
23
+
24
+ it('should render the correct input fields and set the correct computed values, based on the provided data', () => {
25
+ const typeInput = wrapper.find(`[data-testid="projectrow-type-input"]`);
26
+ const projectQuotaInput = wrapper.find(`[data-testid="projectrow-project-quota-input"]`);
27
+ const namespaceQuotaInput = wrapper.find(`[data-testid="projectrow-namespace-quota-input"]`);
28
+
29
+ expect(typeInput.exists()).toBe(true);
30
+ expect(projectQuotaInput.exists()).toBe(true);
31
+ expect(namespaceQuotaInput.exists()).toBe(true);
32
+ expect(wrapper.vm.resourceQuotaLimit).toStrictEqual({});
33
+ expect(wrapper.vm.namespaceDefaultResourceQuotaLimit).toStrictEqual({});
34
+ });
35
+
36
+ it('triggering "updateQuotaLimit" should trigger Vue.set with the correct data', () => {
37
+ const vueSet = jest.spyOn(Vue, 'set');
38
+
39
+ wrapper.vm.updateQuotaLimit('resourceQuota', CONFIGMAP_STRING, 10);
40
+
41
+ expect(vueSet).toHaveBeenCalledTimes(1);
42
+ expect(wrapper.vm.value).toStrictEqual({
43
+ spec: {
44
+ namespaceDefaultResourceQuota: { limit: {} },
45
+ resourceQuota: { limit: { [`${ CONFIGMAP_STRING }`]: 10 } }
46
+ }
47
+ });
48
+ });
49
+
50
+ it('triggering "updateType" with the same type that existed should clear limits and trigger emit', () => {
51
+ wrapper.vm.updateType(CONFIGMAP_STRING);
52
+
53
+ expect(wrapper.vm.value).toStrictEqual({
54
+ spec: {
55
+ namespaceDefaultResourceQuota: { limit: {} },
56
+ resourceQuota: { limit: {} }
57
+ }
58
+ });
59
+
60
+ expect(wrapper.emitted('type-change')).toBeTruthy();
61
+ expect(wrapper.emitted('type-change')[0]).toStrictEqual([CONFIGMAP_STRING]);
62
+ });
63
+ });
@@ -152,6 +152,10 @@ export default {
152
152
  });
153
153
  }
154
154
 
155
+ if (this.value?.metadata?.name && !this.value.displayName) {
156
+ this.$set(this.value, 'displayName', this.value.metadata.name);
157
+ }
158
+
155
159
  this.$nextTick(() => {
156
160
  this.$emit('set-subtype', this.label);
157
161
  });
@@ -0,0 +1,41 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import RoleDetailEdit from '@shell/components/auth/RoleDetailEdit.vue';
3
+ import { SUBTYPE_MAPPING } from '@shell/models/management.cattle.io.roletemplate';
4
+
5
+ const role = {
6
+ apiVersion: 'management.cattle.io/v3',
7
+ kind: 'GlobalRole',
8
+ metadata: { name: 'global-role-with-inherited' },
9
+ inheritedClusterRoles: ['cluster-admin'],
10
+ rules:
11
+ [{
12
+ verbs: ['get', 'list'],
13
+ resources: ['pods'],
14
+ apiGroups: ['']
15
+ }],
16
+ subtype: SUBTYPE_MAPPING.GLOBAL.id
17
+ };
18
+
19
+ describe('component: RoleDetailEdit', () => {
20
+ it('does not have validation errors when the role has no displayName', () => {
21
+ const wrapper = mount(RoleDetailEdit, {
22
+ propsData: { value: role },
23
+ mocks: {
24
+ $fetchState: { pending: false },
25
+ $route: { name: 'anything' },
26
+ $store: {
27
+ getters: {
28
+ currentStore: () => 'store', 'i18n/t': jest.fn(), 'store/schemaFor': jest.fn()
29
+ }
30
+ }
31
+ },
32
+ stubs: {
33
+ CruResource: { template: '<div><slot></slot></div>' },
34
+ // NameNsDescription: true,
35
+ Tab: { template: '<div><slot></slot></div>' },
36
+ }
37
+ });
38
+
39
+ expect((wrapper.vm as any).fvFormIsValid).toBe(true);
40
+ });
41
+ });
@@ -2,6 +2,7 @@
2
2
  import Select from '@shell/components/form/Select';
3
3
  import UnitInput from '@shell/components/form/UnitInput';
4
4
  import { ROW_COMPUTED } from './shared';
5
+ import Vue from 'vue';
5
6
 
6
7
  export default {
7
8
  components: { Select, UnitInput },
@@ -57,10 +58,10 @@ export default {
57
58
 
58
59
  updateQuotaLimit(prop, type, val) {
59
60
  if (!this.value.spec[prop]) {
60
- this.value.spec[prop] = { limit: { } };
61
+ Vue.set(this.value.spec, prop, { limit: { } });
61
62
  }
62
63
 
63
- this.value.spec[prop].limit[type] = val;
64
+ Vue.set(this.value.spec[prop].limit, type, val);
64
65
  }
65
66
  },
66
67
  };
@@ -75,6 +76,7 @@ export default {
75
76
  :mode="mode"
76
77
  :value="type"
77
78
  :options="types"
79
+ data-testid="projectrow-type-input"
78
80
  @input="updateType($event)"
79
81
  />
80
82
  <UnitInput
@@ -86,6 +88,7 @@ export default {
86
88
  :input-exponent="typeOption.inputExponent"
87
89
  :base-unit="typeOption.baseUnit"
88
90
  :output-modifier="true"
91
+ data-testid="projectrow-project-quota-input"
89
92
  @input="updateQuotaLimit('resourceQuota', type, $event)"
90
93
  />
91
94
  <UnitInput
@@ -96,6 +99,7 @@ export default {
96
99
  :input-exponent="typeOption.inputExponent"
97
100
  :base-unit="typeOption.baseUnit"
98
101
  :output-modifier="true"
102
+ data-testid="projectrow-namespace-quota-input"
99
103
  @input="updateQuotaLimit('namespaceDefaultResourceQuota', type, $event)"
100
104
  />
101
105
  </div>
@@ -864,7 +864,7 @@ export default {
864
864
  },
865
865
 
866
866
  created() {
867
- this.registerBeforeHook(this.saveMachinePools, 'save-machine-pools');
867
+ this.registerBeforeHook(this.saveMachinePools, 'save-machine-pools', 1);
868
868
  this.registerBeforeHook(this.setRegistryConfig, 'set-registry-config');
869
869
  this.registerAfterHook(this.cleanupMachinePools, 'cleanup-machine-pools');
870
870
  this.registerAfterHook(this.saveRoleBindings, 'save-role-bindings');
@@ -1235,7 +1235,23 @@ export default {
1235
1235
 
1236
1236
  async saveMachinePools(hookContext) {
1237
1237
  if (hookContext === CONTEXT_HOOK_EDIT_YAML) {
1238
- return;
1238
+ await new Promise((resolve, reject) => {
1239
+ this.$store.dispatch('cluster/promptModal', {
1240
+ component: 'GenericPrompt',
1241
+ componentProps: {
1242
+ title: this.t('cluster.rke2.modal.editYamlMachinePool.title'),
1243
+ body: this.t('cluster.rke2.modal.editYamlMachinePool.body'),
1244
+ applyMode: 'editAndContinue',
1245
+ confirm: (confirmed) => {
1246
+ if (confirmed) {
1247
+ resolve();
1248
+ } else {
1249
+ reject(new Error('User Cancelled'));
1250
+ }
1251
+ }
1252
+ },
1253
+ });
1254
+ });
1239
1255
  }
1240
1256
 
1241
1257
  const finalPools = [];
@@ -144,7 +144,7 @@ export default class GlobalRole extends SteveDescriptionModel {
144
144
  const norman = await this.norman;
145
145
 
146
146
  for (const rule of norman.rules) {
147
- if (rule.nonResourceURLs.length) {
147
+ if (rule.nonResourceURLs && rule.nonResourceURLs.length) {
148
148
  delete rule.resources;
149
149
  delete rule.apiGroups;
150
150
  } else {
@@ -192,7 +192,7 @@ export default class RoleTemplate extends SteveDescriptionModel {
192
192
  const norman = await this.norman;
193
193
 
194
194
  for (const rule of norman.rules) {
195
- if (rule.nonResourceURLs.length) {
195
+ if (rule.nonResourceURLs && rule.nonResourceURLs.length) {
196
196
  delete rule.resources;
197
197
  delete rule.apiGroups;
198
198
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rancher/shell",
3
- "version": "0.3.25",
3
+ "version": "0.3.26",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",
@@ -1,10 +1,10 @@
1
1
  annotations:
2
2
  catalog.cattle.io/certified: rancher # Any application we are adding as a helm chart
3
- catalog.cattle.io/kube-version: '>= 1.16.0-0 < 1.28.0-0'
3
+ catalog.cattle.io/kube-version: '>= 1.16.0-0 < 1.29.0-0'
4
4
  catalog.cattle.io/namespace: cattle-ui-plugin-system # Must prefix with cattle- and suffix with -system=
5
5
  catalog.cattle.io/os: linux
6
6
  catalog.cattle.io/permits-os: linux, windows
7
- catalog.cattle.io/rancher-version: '>= 2.7.0-0 < 2.8.0-0'
7
+ catalog.cattle.io/rancher-version: '>= 2.7.0-0 < 2.9.0-0'
8
8
  catalog.cattle.io/scope: management
9
9
  catalog.cattle.io/ui-component: plugins
10
10
  apiVersion: v2