@rancher/shell 0.3.9 → 0.3.11

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 (132) hide show
  1. package/assets/translations/en-us.yaml +19 -24
  2. package/assets/translations/zh-hans.yaml +82 -16
  3. package/chart/istio.vue +11 -11
  4. package/chart/rancher-backup/S3.vue +1 -1
  5. package/components/AsyncButton.vue +2 -2
  6. package/components/ButtonGroup.vue +1 -1
  7. package/components/CompoundStatusBadge.vue +1 -1
  8. package/components/CopyCode.vue +1 -1
  9. package/components/DetailText.vue +1 -0
  10. package/components/DetailTop.vue +1 -1
  11. package/components/ExplorerProjectsNamespaces.vue +3 -3
  12. package/components/GlobalRoleBindings.vue +1 -1
  13. package/components/HarvesterServiceAddOnConfig.vue +2 -117
  14. package/components/ResourceDetail/Masthead.vue +1 -1
  15. package/components/ResourceList/Masthead.vue +0 -6
  16. package/components/ResourceList/ResourceLoadingIndicator.vue +1 -9
  17. package/components/ResourceList/index.vue +7 -6
  18. package/components/ResourceTable.vue +13 -3
  19. package/components/SortableTable/THead.vue +4 -3
  20. package/components/SortableTable/index.vue +3 -3
  21. package/components/Tabbed/Tab.vue +1 -1
  22. package/components/Tabbed/index.vue +1 -1
  23. package/components/Wizard.vue +9 -6
  24. package/components/__tests__/NamespaceFilter.test.ts +26 -7
  25. package/components/auth/RoleDetailEdit.vue +1 -1
  26. package/components/auth/SelectPrincipal.vue +1 -1
  27. package/components/fleet/FleetRepos.vue +1 -1
  28. package/components/form/ArrayList.vue +1 -1
  29. package/components/form/ChangePassword.vue +3 -0
  30. package/components/form/KeyValue.vue +3 -2
  31. package/components/form/Labels.vue +34 -14
  32. package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
  33. package/components/form/NameNsDescription.vue +1 -1
  34. package/components/form/PlusMinus.vue +2 -2
  35. package/components/form/Probe.vue +1 -1
  36. package/components/form/ProjectMemberEditor.vue +8 -4
  37. package/components/form/ResourceQuota/NamespaceRow.vue +1 -1
  38. package/components/form/ServicePorts.vue +2 -2
  39. package/components/form/Tolerations.vue +30 -3
  40. package/components/form/WorkloadPorts.vue +2 -1
  41. package/components/form/__tests__/KeyValue.test.ts +17 -0
  42. package/components/formatter/ClusterLink.vue +3 -3
  43. package/components/formatter/LiveDate.vue +1 -1
  44. package/components/formatter/PodImages.vue +1 -1
  45. package/components/formatter/RKETemplateName.vue +1 -1
  46. package/components/formatter/Shortened.vue +1 -1
  47. package/components/nav/Header.vue +7 -7
  48. package/components/nav/NamespaceFilter.vue +103 -54
  49. package/config/labels-annotations.js +8 -5
  50. package/config/settings.ts +2 -5
  51. package/config/types.js +6 -4
  52. package/core/plugin-routes.ts +26 -7
  53. package/core/plugins-loader.js +2 -0
  54. package/detail/helm.cattle.io.projecthelmchart.vue +2 -2
  55. package/detail/provisioning.cattle.io.cluster.vue +4 -4
  56. package/edit/cis.cattle.io.clusterscan.vue +1 -1
  57. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +19 -149
  58. package/edit/logging-flow/index.vue +2 -2
  59. package/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue +12 -0
  60. package/edit/logging.banzaicloud.io.output/providers/opensearch.vue +12 -0
  61. package/edit/management.cattle.io.project.vue +7 -0
  62. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
  63. package/edit/monitoring.coreos.com.alertmanagerconfig/routeConfig.vue +2 -2
  64. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +11 -8
  65. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +2 -2
  66. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +12 -4
  67. package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +140 -0
  68. package/edit/networking.k8s.io.networkpolicy/__tests__/utils/mock.json +158 -0
  69. package/edit/networking.k8s.io.networkpolicy/__tests__/utils/selectors.ts +45 -0
  70. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  71. package/edit/provisioning.cattle.io.cluster/AgentConfiguration.vue +1 -1
  72. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +1 -1
  73. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +1 -1
  74. package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +2 -2
  75. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +143 -169
  76. package/edit/provisioning.cattle.io.cluster/rke2.vue +15 -6
  77. package/edit/resources.cattle.io.restore.vue +2 -2
  78. package/edit/service.vue +22 -3
  79. package/edit/storage.k8s.io.storageclass/index.vue +1 -1
  80. package/edit/token.vue +1 -0
  81. package/edit/workload/Job.vue +2 -2
  82. package/edit/workload/index.vue +1 -1
  83. package/edit/workload/mixins/workload.js +7 -1
  84. package/edit/workload/storage/__tests__/Storage.test.ts +84 -5
  85. package/initialize/index.js +1 -0
  86. package/layouts/default.vue +1 -1
  87. package/mixins/resource-fetch-namespaced.js +19 -27
  88. package/mixins/resource-fetch.js +0 -5
  89. package/models/__tests__/namespace.test.ts +125 -0
  90. package/models/management.cattle.io.project.js +6 -1
  91. package/models/persistentvolume.js +1 -1
  92. package/models/workload.service.js +22 -7
  93. package/package.json +17 -5
  94. package/pages/account/index.vue +3 -0
  95. package/pages/auth/login.vue +46 -49
  96. package/pages/c/_cluster/apps/charts/chart.vue +1 -1
  97. package/pages/c/_cluster/apps/charts/install.vue +42 -51
  98. package/pages/c/_cluster/explorer/index.vue +1 -1
  99. package/pages/c/_cluster/monitoring/index.vue +1 -1
  100. package/pages/c/_cluster/settings/performance.vue +53 -18
  101. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -1
  102. package/pages/c/_cluster/uiplugins/index.vue +16 -5
  103. package/pages/home.vue +1 -1
  104. package/pkg/vue.config.js +1 -0
  105. package/plugins/clean-html-directive.js +1 -1
  106. package/plugins/clean-tooltip-directive.js +33 -0
  107. package/plugins/dashboard-store/actions.js +4 -2
  108. package/plugins/dashboard-store/getters.js +6 -0
  109. package/plugins/dashboard-store/mutations.js +2 -2
  110. package/plugins/plugin.js +6 -1
  111. package/plugins/steve/actions.js +1 -1
  112. package/plugins/steve/getters.js +14 -3
  113. package/plugins/steve/resourceWatcher.js +36 -62
  114. package/plugins/steve/subscribe.js +164 -21
  115. package/plugins/steve/worker/index.js +8 -1
  116. package/plugins/steve/worker/web-worker.advanced.js +26 -8
  117. package/plugins/steve/worker/web-worker.basic.js +23 -4
  118. package/rancher-components/components/Form/Checkbox/Checkbox.vue +2 -2
  119. package/rancher-components/components/Form/Radio/RadioGroup.vue +2 -2
  120. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +1 -1
  121. package/store/index.js +16 -61
  122. package/store/store-types.js +5 -0
  123. package/store/type-map.js +1 -1
  124. package/types/shell/index.d.ts +23 -7
  125. package/utils/__tests__/create-yaml.test.ts +63 -0
  126. package/utils/array.ts +4 -0
  127. package/utils/create-yaml.js +5 -5
  128. package/utils/namespace-filter.js +17 -5
  129. package/utils/projectAndNamespaceFiltering.utils.ts +62 -0
  130. package/utils/selector.js +6 -5
  131. package/utils/settings.ts +5 -7
  132. package/models/k8s.cni.cncf.io.networkattachmentdefinition.js +0 -93
@@ -0,0 +1,140 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import PolicyRuleTarget from '@shell/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget';
3
+ import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
4
+ import mock from '@shell/edit/networking.k8s.io.networkpolicy/__tests__/utils/mock.json';
5
+ import { PolicyRuleTargetSelectors } from '@shell/edit/networking.k8s.io.networkpolicy/__tests__/utils/selectors';
6
+
7
+ describe.each([
8
+ 'view',
9
+ 'edit',
10
+ ])('component: PolicyRuleTarget', (mode) => {
11
+ const mockExists = jest.fn().mockReturnValue(true);
12
+ const mockT = jest.fn().mockReturnValue('some-string');
13
+
14
+ const wrapper = mount(PolicyRuleTarget, {
15
+ data() {
16
+ return { throttleTime: 0 };
17
+ },
18
+ propsData: {
19
+ namespace: mock.defaultNamespace,
20
+ allNamespaces: mock.allNamespaces,
21
+ allPods: mock.allPods,
22
+ type: 'ingress',
23
+ mode
24
+ },
25
+
26
+ directives: { cleanHtmlDirective },
27
+
28
+ mocks: {
29
+ $store: {
30
+ getters: {
31
+ 'i18n/exists': mockExists,
32
+ 'i18n/t': mockT
33
+ }
34
+ }
35
+ }
36
+ });
37
+
38
+ describe(`${ mode } mode`, () => {
39
+ it('should display ip-block selector rule', async() => {
40
+ const ipBlock = mock.selectors.ipBlock;
41
+
42
+ await wrapper.setProps({ value: { ipBlock } });
43
+
44
+ const selectors = new PolicyRuleTargetSelectors(wrapper);
45
+
46
+ // Check rule type selector
47
+ expect(selectors.ruleType.vm.$data._value.value).toBe('ipBlock');
48
+
49
+ expect(selectors.namespace.element).toBeUndefined();
50
+ expect(selectors.pod.element).toBeUndefined();
51
+ expect(selectors.namespaceAndPod.namespaceRule.element).toBeUndefined();
52
+ expect(selectors.namespaceAndPod.podRule.element).toBeUndefined();
53
+
54
+ expect(selectors.ipBlock.element._value).toStrictEqual(ipBlock.cidr);
55
+ });
56
+
57
+ it('should display namespace selector rule', async() => {
58
+ const namespaceSelector = mock.selectors.namespace;
59
+
60
+ await wrapper.setProps({ value: { namespaceSelector } });
61
+
62
+ const selectors = new PolicyRuleTargetSelectors(wrapper);
63
+
64
+ // Check rule type selector
65
+ expect(selectors.ruleType.vm.$data._value.value).toBe('namespaceSelector');
66
+
67
+ // Check the matching namespaces displayed by the banner
68
+ expect(wrapper.vm.$data.matchingNamespaces.matched).toBe(1);
69
+
70
+ // Check if namespace's labels match
71
+ expect(wrapper.vm.$data.matchingNamespaces.matches).toHaveLength(1);
72
+ expect(wrapper.vm.$data.matchingNamespaces.matches[0].metadata.name).toBe('default');
73
+ expect(wrapper.vm.$data.matchingNamespaces.matches[0].metadata.labels['user']).toBe('alice');
74
+
75
+ expect(selectors.pod.element).toBeUndefined();
76
+ expect(selectors.namespaceAndPod.namespaceRule.element).toBeUndefined();
77
+ expect(selectors.namespaceAndPod.podRule.element).toBeUndefined();
78
+
79
+ expect(selectors.namespace.element).toBeDefined();
80
+ });
81
+
82
+ it('should display pod selector rule', async() => {
83
+ const podSelector = mock.selectors.pod;
84
+
85
+ await wrapper.setProps({ value: { podSelector } });
86
+
87
+ const selectors = new PolicyRuleTargetSelectors(wrapper);
88
+
89
+ // Check rule type selector
90
+ expect(selectors.ruleType.vm.$data._value.value).toBe('podSelector');
91
+
92
+ // Check if namespace's labels match
93
+ expect(wrapper.vm.$data.matchingPods.matched).toBe(1);
94
+ expect(wrapper.vm.$data.matchingPods.matches).toHaveLength(1);
95
+
96
+ expect(wrapper.vm.$data.matchingPods.matches[0].metadata.name).toBe('test-pod');
97
+ expect(wrapper.vm.$data.matchingPods.matches[0].metadata.labels['foo']).toBe('bar');
98
+
99
+ expect(selectors.namespace.element).toBeUndefined();
100
+ expect(selectors.namespaceAndPod.namespaceRule.element).toBeUndefined();
101
+ expect(selectors.namespaceAndPod.podRule.element).toBeUndefined();
102
+
103
+ expect(selectors.pod.element).toBeDefined();
104
+ });
105
+
106
+ it('should display namespace/pod selector rule', async() => {
107
+ const namespaceSelector = mock.selectors.namespaceAndPod.namespace;
108
+ const podSelector = mock.selectors.namespaceAndPod.pod;
109
+
110
+ await wrapper.setProps({
111
+ value: {
112
+ namespaceSelector,
113
+ podSelector,
114
+ }
115
+ });
116
+
117
+ const selectors = new PolicyRuleTargetSelectors(wrapper);
118
+
119
+ // Check rule type selector
120
+ expect(selectors.ruleType.vm.$data._value.value).toBe('namespaceAndPodSelector');
121
+
122
+ // Check the matching pods displayed by the banner
123
+ expect(wrapper.vm.$data.matchingPods.matched).toBe(1);
124
+
125
+ // Check if namespace's labels match
126
+ expect(wrapper.vm.$data.matchingNamespaces.matches).toHaveLength(1);
127
+ expect(wrapper.vm.$data.matchingNamespaces.matches[0].metadata.name).toBe('default');
128
+ expect(wrapper.vm.$data.matchingNamespaces.matches[0].metadata.labels['user']).toBe('alice');
129
+
130
+ expect(wrapper.vm.$data.matchingPods.matches[0].metadata.name).toBe('test-pod');
131
+ expect(wrapper.vm.$data.matchingPods.matches[0].metadata.labels['foo']).toBe('bar');
132
+
133
+ expect(selectors.namespace.element).toBeUndefined();
134
+ expect(selectors.pod.element).toBeUndefined();
135
+
136
+ expect(selectors.namespaceAndPod.namespaceRule.element).toBeDefined();
137
+ expect(selectors.namespaceAndPod.podRule.element).toBeDefined();
138
+ });
139
+ });
140
+ });
@@ -0,0 +1,158 @@
1
+ {
2
+ "defaultNamespace": "default",
3
+ "selectors": {
4
+ "ipBlock": {
5
+ "cidr": "24.06.19.89/0"
6
+ },
7
+ "namespace": {
8
+ "matchLabels": {
9
+ "user": "alice"
10
+ },
11
+ "matchExpressions": [
12
+ {
13
+ "key": "user",
14
+ "operator": "In",
15
+ "values": "alice"
16
+ }
17
+ ]
18
+ },
19
+ "pod": {
20
+ "matchLabels": {
21
+ "foo": "bar"
22
+ },
23
+ "matchExpressions": [
24
+ {
25
+ "key": "foo",
26
+ "operator": "In",
27
+ "values": "bar"
28
+ }
29
+ ]
30
+ },
31
+ "namespaceAndPod": {
32
+ "namespace": {
33
+ "matchLabels": {
34
+ "user": "alice"
35
+ },
36
+ "matchExpressions": [
37
+ {
38
+ "key": "user",
39
+ "operator": "In",
40
+ "values": "alice"
41
+ }
42
+ ]
43
+ },
44
+ "pod": {
45
+ "matchLabels": {
46
+ "foo": "bar"
47
+ },
48
+ "matchExpressions": [
49
+ {
50
+ "key": "foo",
51
+ "operator": "In",
52
+ "values": "bar"
53
+ }
54
+ ]
55
+ }
56
+ }
57
+ },
58
+ "allNamespaces": [
59
+ {
60
+ "id": "default",
61
+ "type": "namespace",
62
+ "kind": "Namespace",
63
+ "metadata": {
64
+ "annotations": {
65
+ "user": "alice"
66
+ },
67
+ "name": "default",
68
+ "creationTimestamp": "2023-01-31T10:24:03Z",
69
+ "fields": ["default", "Active", "1d"],
70
+ "labels": {
71
+ "user": "alice"
72
+ },
73
+ "relationships": null,
74
+ "resourceVersion": "1",
75
+ "state": {
76
+ "error": false,
77
+ "message": "",
78
+ "name": "active",
79
+ "transitioning": false
80
+ }
81
+ },
82
+ "spec": { "finalizers": ["kubernetes"] },
83
+ "status": { "phase": "Active" }
84
+ },
85
+ {
86
+ "id": "not-default",
87
+ "type": "namespace",
88
+ "kind": "Namespace",
89
+ "metadata": {
90
+ "annotations": {
91
+ "user": "nicole"
92
+ },
93
+ "name": "not-default",
94
+ "creationTimestamp": "2023-01-31T10:24:03Z",
95
+ "fields": ["default", "Active", "1d"],
96
+ "labels": {
97
+ "user": "nicole"
98
+ },
99
+ "relationships": null,
100
+ "resourceVersion": "1",
101
+ "state": {
102
+ "error": false,
103
+ "message": "",
104
+ "name": "active",
105
+ "transitioning": false
106
+ }
107
+ },
108
+ "spec": { "finalizers": ["kubernetes"] },
109
+ "status": { "phase": "Active" }
110
+ }
111
+ ],
112
+ "allPods": [
113
+ {
114
+ "id": "default/test-pod",
115
+ "type": "pod",
116
+ "apiVersion": "v1",
117
+ "kind": "Pod",
118
+ "metadata": {
119
+ "creationTimestamp": "2023-02-27T16:10:55Z",
120
+ "generateName": "test-pod-",
121
+ "labels": {
122
+ "foo": "bar"
123
+ },
124
+ "name": "test-pod",
125
+ "namespace": "default",
126
+ "resourceVersion": "1",
127
+ "state": {
128
+ "error": false,
129
+ "message": "",
130
+ "name": "completed",
131
+ "transitioning": false
132
+ }
133
+ }
134
+ },
135
+ {
136
+ "id": "default/test-pod-2",
137
+ "type": "pod",
138
+ "apiVersion": "v1",
139
+ "kind": "Pod",
140
+ "metadata": {
141
+ "creationTimestamp": "2023-02-27T16:10:55Z",
142
+ "generateName": "test-pod-2-",
143
+ "labels": {
144
+ "foo": "bar"
145
+ },
146
+ "name": "test-pod-2",
147
+ "namespace": "not-default",
148
+ "resourceVersion": "1",
149
+ "state": {
150
+ "error": false,
151
+ "message": "",
152
+ "name": "completed",
153
+ "transitioning": false
154
+ }
155
+ }
156
+ }
157
+ ]
158
+ }
@@ -0,0 +1,45 @@
1
+ export class PolicyRuleTargetSelectors {
2
+ private wrapper;
3
+
4
+ constructor(wrapper: any) {
5
+ this.wrapper = wrapper;
6
+ }
7
+
8
+ get ipBlock() {
9
+ return this.wrapper.find('[data-testid=labeled-input-ip-block-selector]');
10
+ }
11
+
12
+ /**
13
+ * Namespace selector element; matches policies in OR condition, in conjunction with the other rules
14
+ */
15
+ get namespace() {
16
+ return this.wrapper.find(
17
+ '[data-testid=match-expression-namespace-selector]'
18
+ );
19
+ }
20
+
21
+ /**
22
+ * Pod selector element; matches policies in OR condition, in conjunction with the other rules
23
+ */
24
+ get pod() {
25
+ return this.wrapper.find('[data-testid=match-expression-pod-selector]');
26
+ }
27
+
28
+ /**
29
+ * Namespace and pod selector elements, matching policies in AND condition, within the same rule
30
+ */
31
+ get namespaceAndPod() {
32
+ return {
33
+ namespaceRule: this.wrapper.find(
34
+ '[data-testid=match-expression-namespace-and-pod-selector-ns-rule]'
35
+ ),
36
+ podRule: this.wrapper.find(
37
+ '[data-testid=match-expression-namespace-and-pod-selector-pod-rule]'
38
+ ),
39
+ };
40
+ }
41
+
42
+ get ruleType() {
43
+ return this.wrapper.find('[data-testid=labeled-select-type-selector]');
44
+ }
45
+ }
@@ -241,7 +241,7 @@ export default {
241
241
  <h2>
242
242
  {{ t('networkpolicy.selectors.label') }}
243
243
  <i
244
- v-tooltip="t('networkpolicy.selectors.hint')"
244
+ v-clean-tooltip="t('networkpolicy.selectors.hint')"
245
245
  class="icon icon-info"
246
246
  />
247
247
  </h2>
@@ -25,7 +25,7 @@ export function cleanAgentConfiguration(model, key) {
25
25
  delete v[k];
26
26
  }
27
27
 
28
- // prevent cleanup of namespaceSelector when an empty object because it represents all namespaces in pod/node affinity
28
+ // prevent cleanup of "namespaceSelector" when an empty object because it represents all namespaces in pod/node affinity
29
29
  // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#podaffinityterm-v1-core
30
30
  if (k !== 'namespaceSelector') {
31
31
  cleanAgentConfiguration(v, k);
@@ -268,7 +268,7 @@ export default {
268
268
  <h3>
269
269
  {{ t('cluster.machinePool.autoReplace.label') }}
270
270
  <i
271
- v-tooltip="t('cluster.machinePool.autoReplace.toolTip')"
271
+ v-clean-tooltip="t('cluster.machinePool.autoReplace.toolTip')"
272
272
  class="icon icon-info icon-lg"
273
273
  />
274
274
  </h3>
@@ -119,7 +119,7 @@ export default {
119
119
  <h3>
120
120
  {{ t('registryConfig.header') }}
121
121
  <i
122
- v-tooltip="t('registryConfig.toolTip')"
122
+ v-clean-tooltip="t('registryConfig.toolTip')"
123
123
  class="icon icon-info"
124
124
  />
125
125
  </h3>
@@ -77,7 +77,7 @@ export default {
77
77
  <h3>
78
78
  {{ t('registryMirror.header') }}
79
79
  <i
80
- v-tooltip="t('registryMirror.toolTip')"
80
+ v-clean-tooltip="t('registryMirror.toolTip')"
81
81
  class="icon icon-info"
82
82
  />
83
83
  </h3>
@@ -116,7 +116,7 @@ export default {
116
116
  <h3>
117
117
  {{ t('registryMirrorRewrite.header') }}
118
118
  <i
119
- v-tooltip="t('registryMirrorRewrite.toolTip')"
119
+ v-clean-tooltip="t('registryMirrorRewrite.toolTip')"
120
120
  class="icon icon-info"
121
121
  />
122
122
  </h3>