@rancher/shell 0.3.24 → 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.
Files changed (115) hide show
  1. package/assets/styles/themes/_light.scss +1 -1
  2. package/assets/translations/en-us.yaml +36 -7
  3. package/assets/translations/zh-hans.yaml +1 -1
  4. package/components/ClusterIconMenu.vue +143 -0
  5. package/components/CruResource.vue +10 -1
  6. package/components/ExplorerProjectsNamespaces.vue +11 -1
  7. package/components/FixedBanner.vue +17 -1
  8. package/components/Markdown.vue +1 -1
  9. package/components/Questions/__tests__/Yaml.test.ts +3 -2
  10. package/components/SortableTable/index.vue +3 -2
  11. package/components/__tests__/ProjectRow.test.ts +63 -0
  12. package/components/auth/RoleDetailEdit.vue +19 -2
  13. package/components/auth/__tests__/RoleDetailEdit.test.ts +41 -0
  14. package/components/auth/login/saml.vue +12 -1
  15. package/components/form/LabeledSelect.vue +12 -5
  16. package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
  17. package/components/form/Members/MembershipEditor.vue +6 -1
  18. package/components/form/ResourceQuota/ProjectRow.vue +6 -2
  19. package/components/form/__tests__/KeyValue.test.ts +6 -3
  20. package/components/form/__tests__/LabeledSelect.test.ts +18 -0
  21. package/components/formatter/PodsUsage.vue +11 -36
  22. package/components/formatter/PrincipalGroupBindings.vue +8 -5
  23. package/components/formatter/__tests__/PodsUsage.test.ts +36 -19
  24. package/components/nav/Group.vue +25 -27
  25. package/components/nav/Header.vue +12 -5
  26. package/components/nav/Pinned.vue +47 -0
  27. package/components/nav/TopLevelMenu.vue +233 -60
  28. package/components/nav/Type.vue +57 -3
  29. package/config/home-links.js +1 -1
  30. package/config/product/istio.js +15 -5
  31. package/config/router.js +3 -9
  32. package/config/table-headers.js +5 -6
  33. package/config/uiplugins.js +1 -0
  34. package/core/plugin-helpers.js +3 -0
  35. package/core/types.ts +6 -1
  36. package/creators/app/files/.vscode/settings.json +0 -1
  37. package/detail/__tests__/autoscaling.horizontalpodautoscaler.test.ts +118 -0
  38. package/detail/autoscaling.horizontalpodautoscaler/index.vue +4 -4
  39. package/detail/provisioning.cattle.io.cluster.vue +7 -5
  40. package/edit/__tests__/management.cattle.io.clusterroletemplatebinding.test.ts +58 -0
  41. package/edit/__tests__/namespace.test.ts +5 -3
  42. package/edit/management.cattle.io.clusterroletemplatebinding.vue +3 -11
  43. package/edit/namespace.vue +8 -4
  44. package/edit/provisioning.cattle.io.cluster/Basics.vue +662 -0
  45. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +6 -0
  46. package/edit/provisioning.cattle.io.cluster/DrainOptions.vue +13 -8
  47. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -2
  48. package/edit/provisioning.cattle.io.cluster/MemberRoles.vue +40 -0
  49. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +237 -0
  50. package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.tests.ts +71 -23
  51. package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +52 -0
  52. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +65 -142
  53. package/edit/provisioning.cattle.io.cluster/rke2.vue +211 -599
  54. package/edit/workload/storage/__tests__/Storage.test.ts +2 -2
  55. package/edit/workload/storage/persistentVolumeClaim/__tests__/persistentvolumeclaim.test.ts +36 -0
  56. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +15 -7
  57. package/initialize/index.js +5 -5
  58. package/layouts/default.vue +6 -6
  59. package/layouts/home.vue +6 -2
  60. package/layouts/plain.vue +9 -2
  61. package/list/fleet.cattle.io.cluster.vue +2 -2
  62. package/list/management.cattle.io.feature.vue +1 -1
  63. package/machine-config/vmwarevsphere.vue +48 -7
  64. package/mixins/brand.js +0 -8
  65. package/mixins/child-hook.js +2 -2
  66. package/mixins/create-edit-view/impl.js +3 -3
  67. package/models/__tests__/management.cattle.io.node.ts +96 -0
  68. package/models/__tests__/node.ts +74 -0
  69. package/models/cluster/node.js +6 -5
  70. package/models/cluster.x-k8s.io.machinedeployment.js +2 -2
  71. package/models/management.cattle.io.cluster.js +22 -1
  72. package/models/management.cattle.io.clusterroletemplatebinding.js +3 -3
  73. package/models/management.cattle.io.globalrole.js +17 -2
  74. package/models/management.cattle.io.node.js +6 -4
  75. package/models/management.cattle.io.projectroletemplatebinding.js +3 -3
  76. package/models/management.cattle.io.roletemplate.js +17 -2
  77. package/package.json +2 -6
  78. package/pages/about.vue +2 -0
  79. package/pages/auth/setup.vue +5 -4
  80. package/pages/c/_cluster/monitoring/index.vue +8 -3
  81. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +9 -66
  82. package/pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue +182 -0
  83. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +15 -32
  84. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +8 -46
  85. package/pages/c/_cluster/uiplugins/index.vue +64 -64
  86. package/pages/diagnostic.vue +0 -39
  87. package/pages/home.vue +1 -1
  88. package/plugins/dashboard-store/normalize.js +4 -4
  89. package/plugins/int-number.js +5 -2
  90. package/plugins/positive-int-number.js +19 -0
  91. package/plugins/steve/__tests__/getters.spec.ts +15 -0
  92. package/plugins/steve/getters.js +22 -10
  93. package/rancher-components/Form/LabeledInput/LabeledInput.vue +0 -8
  94. package/rancher-components/Form/Radio/RadioButton.test.ts +3 -7
  95. package/scripts/extension/helm/charts/ui-plugin-server/Chart.yaml +2 -2
  96. package/store/index.js +4 -0
  97. package/store/prefs.js +1 -0
  98. package/types/shell/index.d.ts +13 -4
  99. package/utils/__tests__/cluster.test.ts +55 -0
  100. package/utils/__tests__/object.test.ts +21 -2
  101. package/utils/cluster.js +47 -1
  102. package/utils/object.js +12 -5
  103. package/utils/validators/formRules/__tests__/index.test.ts +13 -1
  104. package/utils/validators/formRules/index.ts +4 -0
  105. package/utils/validators/role-template.js +9 -1
  106. package/utils/version.js +1 -1
  107. package/yarn-error.log +16 -16
  108. package/components/ClusterProviderIconMenu.vue +0 -161
  109. package/content/docs/en-us/getting-started.md +0 -224
  110. package/content/docs/en-us/whats-new.md +0 -29
  111. package/content/docs/zh-hans/getting-started.md +0 -224
  112. package/content/docs/zh-hans/whats-new.md +0 -28
  113. package/pages/docs/_doc.vue +0 -345
  114. package/pages/docs/toc.js +0 -27
  115. package/plugins/console.js +0 -34
@@ -10,7 +10,6 @@
10
10
  ".gitignore": true,
11
11
  ".nuxt*": true,
12
12
  ".nyc_output": true,
13
- "Dockerfile": true,
14
13
  ".vscode": true,
15
14
  "LICENSE": true,
16
15
  "node_modules": true,
@@ -0,0 +1,118 @@
1
+ import { shallowMount } from '@vue/test-utils';
2
+ import HorizontalPodAutoScaler from '@shell/detail/autoscaling.horizontalpodautoscaler/index.vue';
3
+
4
+ describe('view: autoscaling.horizontalpodautoscaler', () => {
5
+ const mockStore = {
6
+ getters: {
7
+ 'i18n/t': (text: string) => text,
8
+ t: (text: string) => text,
9
+ currentStore: () => 'current_store',
10
+ 'current_store/schemaFor': jest.fn(),
11
+ 'current_store/all': jest.fn(),
12
+ workspace: jest.fn(),
13
+ },
14
+ };
15
+
16
+ const mocks = {
17
+ $store: mockStore,
18
+ $fetchState: { pending: false },
19
+ $route: {
20
+ query: { AS: '' },
21
+ name: {
22
+ endsWith: () => {
23
+ return false;
24
+ },
25
+ },
26
+ },
27
+ };
28
+
29
+ const value = {
30
+ status: {
31
+ currentMetrics: [
32
+ {
33
+ resource: {
34
+ current: {
35
+ averageUtilization: 8,
36
+ averageValue: '11481088'
37
+ },
38
+ name: 'memory'
39
+ },
40
+ type: 'Resource'
41
+ },
42
+ {
43
+ resource: {
44
+ current: {
45
+ averageUtilization: 0,
46
+ averageValue: '1m'
47
+ },
48
+ name: 'cpu'
49
+ },
50
+ type: 'Resource'
51
+ }
52
+ ],
53
+ },
54
+ spec: {
55
+ maxReplicas: 10,
56
+ metrics: [
57
+ {
58
+ resource: {
59
+ name: 'memory',
60
+ target: {
61
+ averageUtilization: 80,
62
+ type: 'Utilization'
63
+ }
64
+ },
65
+ type: 'Resource'
66
+ },
67
+ {
68
+ resource: {
69
+ name: 'cpu',
70
+ target: {
71
+ averageUtilization: 50,
72
+ type: 'Utilization'
73
+ }
74
+ },
75
+ type: 'Resource'
76
+ }
77
+ ],
78
+ minReplicas: 1,
79
+ scaleTargetRef: {
80
+ apiVersion: 'apps/v1',
81
+ kind: 'Deployment',
82
+ name: 'php-apache'
83
+ }
84
+ }
85
+ };
86
+
87
+ const metricsValue = Object.values(value.spec.metrics);
88
+ const currentMetrics = Object.values(value.status.currentMetrics);
89
+
90
+ const wrapper = shallowMount(HorizontalPodAutoScaler, {
91
+ mocks,
92
+ propsData: { value },
93
+ });
94
+
95
+ describe.each(value.spec.metrics)('should display metrics for each resource:', (metric) => {
96
+ const name = metric.resource.name;
97
+
98
+ it(`${ name }:`, () => {
99
+ // Resource metrics
100
+ const resourceValue = wrapper.find(`[data-testid="resource-metrics-value-${ name }"]`);
101
+ const resourceName = wrapper.find(`[data-testid="resource-metrics-name-${ name }"]`);
102
+ const metricValue = metricsValue.find((f) => f.resource.name === name)?.resource;
103
+
104
+ // Current Metrics
105
+ const averageUtilization = wrapper.find(`[data-testid="current-metrics-Average Utilization-${ name }"]`);
106
+ const averageValue = wrapper.find(`[data-testid="current-metrics-Average Value-${ name }"]`);
107
+ const currentResource = currentMetrics.find((f) => f.resource.name === name)?.resource.current;
108
+
109
+ // Resource metrics
110
+ expect(resourceValue.element.textContent).toBe(`${ metricValue?.target?.averageUtilization }`);
111
+ expect(resourceName.element.textContent).toBe(`${ metricValue?.name }`);
112
+
113
+ // Current Metrics
114
+ expect(averageUtilization.element.textContent).toBe(`${ currentResource?.averageUtilization }`);
115
+ expect(averageValue.element.textContent).toBe(`${ currentResource?.averageValue }`);
116
+ });
117
+ });
118
+ });
@@ -43,7 +43,7 @@ export default {
43
43
  return metrics.map((metric) => {
44
44
  const metricValue = get(metric, camelCase(metric.type));
45
45
  const targetType = metricValue?.target?.type;
46
- const currentMatch = findBy(currentMetrics, 'type', metric.type);
46
+ const currentMatch = findBy(currentMetrics, 'resource.name', metric.resource.name);
47
47
  const current = currentMatch ? get(currentMatch, `${ camelCase(metric.type) }.current`) : null;
48
48
  const currentMetricsKVs = [];
49
49
 
@@ -128,7 +128,7 @@ export default {
128
128
  <label class="text-label">
129
129
  <t k="hpa.metrics.headers.value" />:
130
130
  </label>
131
- <span>{{ metric.targetValue }}</span>
131
+ <span :data-testid="`resource-metrics-value-${metric.subRowContent.resourceName}`">{{ metric.targetValue }}</span>
132
132
  </div>
133
133
  <div v-if="metric.metricSource === 'Object'">
134
134
  <div class="mb-5">
@@ -155,7 +155,7 @@ export default {
155
155
  <label class="text-label">
156
156
  <t k="hpa.metrics.headers.resource" />:
157
157
  </label>
158
- <span>{{ metric.subRowContent.resourceName }}</span>
158
+ <span :data-testid="`resource-metrics-name-${metric.subRowContent.resourceName}`">{{ metric.subRowContent.resourceName }}</span>
159
159
  </div>
160
160
  </div>
161
161
  </div>
@@ -173,7 +173,7 @@ export default {
173
173
  <label class="text-label">
174
174
  {{ current.targetName }}:
175
175
  </label>
176
- <span>{{ current.targetValue }}</span>
176
+ <span :data-testid="`current-metrics-${current.targetName}-${metric.subRowContent.resourceName}`">{{ current.targetValue }}</span>
177
177
  </div>
178
178
  </div>
179
179
  </div>
@@ -339,9 +339,10 @@ export default {
339
339
  pool._clusterSpec = mp;
340
340
 
341
341
  return {
342
- poolId: pool.id,
343
- mainRowKey: 'isFake',
342
+ poolId: pool.id,
343
+ mainRowKey: 'isFake',
344
344
  pool,
345
+ availableActions: []
345
346
  };
346
347
  });
347
348
  },
@@ -361,9 +362,10 @@ export default {
361
362
  const emptyNodePools = this.allNodePools.filter((x) => x.spec.clusterName === this.value.mgmtClusterId && x.spec.quantity === 0);
362
363
 
363
364
  return emptyNodePools.map((np) => ({
364
- spec: { nodePoolName: np.id.replace('/', ':') },
365
- mainRowKey: 'isFake',
366
- pool: np,
365
+ spec: { nodePoolName: np.id.replace('/', ':') },
366
+ mainRowKey: 'isFake',
367
+ pool: np,
368
+ availableActions: []
367
369
  }));
368
370
  },
369
371
 
@@ -0,0 +1,58 @@
1
+ /* eslint-disable jest/no-hooks */
2
+ import { mount } from '@vue/test-utils';
3
+ import ClusterRoleTemplateBinding from '@shell/edit/management.cattle.io.clusterroletemplatebinding.vue';
4
+ import Banner from '@components/Banner/Banner.vue';
5
+ import CruResource from '@shell/components/CruResource';
6
+
7
+ describe('view: management.cattle.io.clusterroletemplatebinding should', () => {
8
+ let wrapper: any;
9
+
10
+ const stubs = {
11
+ ClusterPermissionsEditor: true,
12
+ Loading: true
13
+ };
14
+
15
+ const requiredSetup = () => ({
16
+ // Remove all these mocks after migration to Vue 2.7/3 due mixin logic
17
+ mocks: {
18
+ $store: {
19
+ getters: {
20
+ currentStore: () => 'current_store',
21
+ 'current_store/schemaFor': jest.fn(),
22
+ 'current_store/all': jest.fn(),
23
+ currentCluster: { id: 'my-cluster' },
24
+ currentProduct: { inStore: 'whatever' },
25
+ 'i18n/t': (val) => val,
26
+ 'i18n/exists': jest.fn(),
27
+ },
28
+ dispatch: { 'management/findAll': () => ([]) }
29
+ },
30
+ $fetchState: { pending: false },
31
+ $route: { query: { AS: '' } },
32
+ $router: {
33
+ applyQuery: jest.fn(),
34
+ replace: jest.fn()
35
+ },
36
+ },
37
+ propsData: { value: {} },
38
+ stubs,
39
+ });
40
+
41
+ afterEach(() => {
42
+ wrapper.destroy();
43
+ });
44
+
45
+ it('should only show one error banner', async() => {
46
+ const errors = ['mistake!'];
47
+
48
+ wrapper = mount(ClusterRoleTemplateBinding, { ...requiredSetup() });
49
+
50
+ const cruResourceElem = wrapper.findComponent(CruResource);
51
+
52
+ await cruResourceElem.vm.$emit('error', errors);
53
+
54
+ const bannerElems = wrapper.findAllComponents(Banner);
55
+
56
+ expect(bannerElems).toHaveLength(1);
57
+ });
58
+ });
@@ -25,9 +25,10 @@ describe('view Namespace should', () => {
25
25
  $router: { applyQuery: {} },
26
26
  $store: {
27
27
  getters: {
28
- 'i18n/t': jest.fn(),
29
- 'management/all': () => ([project]),
30
- currentProduct: jest.fn(),
28
+ 'i18n/t': jest.fn(),
29
+ 'management/all': () => ([project]),
30
+ currentProduct: jest.fn(),
31
+ isStandaloneHarvester: false
31
32
  }
32
33
  }
33
34
  },
@@ -36,6 +37,7 @@ describe('view Namespace should', () => {
36
37
  ContainerResourceLimit: { template: '<div data-testid="limits"></div>' }, // Ensure value to be added to component
37
38
  NameNsDescription: true,
38
39
  Tab: true,
40
+ ResourceTabs: true
39
41
  }
40
42
  });
41
43
 
@@ -1,7 +1,6 @@
1
1
  <script>
2
2
  import CreateEditView from '@shell/mixins/create-edit-view';
3
3
  import CruResource from '@shell/components/CruResource';
4
- import Banner from '@components/Banner/Banner.vue';
5
4
  import { MANAGEMENT } from '@shell/config/types';
6
5
  import Loading from '@shell/components/Loading';
7
6
  import ClusterPermissionsEditor from '@shell/components/form/Members/ClusterPermissionsEditor';
@@ -9,7 +8,6 @@ import { exceptionToErrorsArray } from '@shell/utils/error';
9
8
 
10
9
  export default {
11
10
  components: {
12
- Banner,
13
11
  ClusterPermissionsEditor,
14
12
  CruResource,
15
13
  Loading,
@@ -64,15 +62,9 @@ export default {
64
62
  @finish="saveOverride"
65
63
  @cancel="done"
66
64
  >
67
- <ClusterPermissionsEditor
68
- v-model="bindings"
69
- :cluster-name="$store.getters['currentCluster'].id"
70
- />
71
- <Banner
72
- v-for="(err, i) in errors"
73
- :key="i"
74
- color="error"
75
- :label="err"
65
+ <ClusterPermissionsEditor
66
+ v-model="bindings"
67
+ :cluster-name="$store.getters['currentCluster'].id"
76
68
  />
77
69
  </CruResource>
78
70
  </template>
@@ -7,8 +7,8 @@ import { MANAGEMENT } from '@shell/config/types';
7
7
  import { CONTAINER_DEFAULT_RESOURCE_LIMIT, PROJECT } from '@shell/config/labels-annotations';
8
8
  import ContainerResourceLimit from '@shell/components/ContainerResourceLimit';
9
9
  import PodSecurityAdmission from '@shell/components/PodSecurityAdmission';
10
- import Tabbed from '@shell/components/Tabbed';
11
10
  import Tab from '@shell/components/Tabbed/Tab';
11
+ import ResourceTabs from '@shell/components/form/ResourceTabs/index.vue';
12
12
  import CruResource from '@shell/components/CruResource';
13
13
  import { PROJECT_ID, _VIEW, FLAT_VIEW, _CREATE } from '@shell/config/query-params';
14
14
  import MoveModal from '@shell/components/MoveModal';
@@ -30,7 +30,7 @@ export default {
30
30
  PodSecurityAdmission,
31
31
  ResourceQuota,
32
32
  Tab,
33
- Tabbed,
33
+ ResourceTabs,
34
34
  MoveModal
35
35
  },
36
36
 
@@ -198,7 +198,11 @@ export default {
198
198
  />
199
199
  </template>
200
200
  </NameNsDescription>
201
- <Tabbed :side-tabs="true">
201
+ <ResourceTabs
202
+ v-model="value"
203
+ :mode="mode"
204
+ :side-tabs="true"
205
+ >
202
206
  <Tab
203
207
  v-if="showResourceQuota"
204
208
  :weight="1"
@@ -269,7 +273,7 @@ export default {
269
273
  @updateLabels="PSAChanged"
270
274
  />
271
275
  </Tab>
272
- </Tabbed>
276
+ </ResourceTabs>
273
277
  <MoveModal v-if="projects" />
274
278
  </CruResource>
275
279
  </template>