@rancher/shell 0.3.15 → 0.3.17
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/images/wechat-qr-code.jpg +0 -0
- package/assets/translations/en-us.yaml +70 -15
- package/assets/translations/zh-hans.yaml +155 -33
- package/chart/__tests__/S3.test.ts +50 -0
- package/chart/rancher-backup/S3.vue +21 -0
- package/chart/rancher-backup/index.vue +4 -0
- package/cloud-credential/generic.vue +1 -1
- package/components/BannerGraphic.vue +1 -0
- package/components/CommunityLinks.vue +1 -0
- package/components/CruResource.vue +1 -1
- package/components/EmberPage.vue +1 -0
- package/components/FileDiff.vue +92 -85
- package/components/GrafanaDashboard.vue +7 -1
- package/components/ResourceDetail/index.vue +4 -12
- package/components/ResourceList/index.vue +1 -1
- package/components/ResourceTable.vue +50 -2
- package/components/SimpleBox.vue +1 -0
- package/components/SortableTable/index.vue +5 -1
- package/components/YamlEditor.vue +1 -0
- package/components/auth/RoleDetailEdit.vue +1 -0
- package/components/form/GitPicker.vue +1 -1
- package/components/form/NameNsDescription.vue +28 -12
- package/components/form/NodeAffinity.vue +2 -2
- package/components/form/PodAffinity.vue +8 -3
- package/components/form/ResourceTabs/index.vue +8 -2
- package/components/form/Select.vue +16 -0
- package/components/form/__tests__/NodeAffinity.test.ts +38 -0
- package/components/form/__tests__/PodAffinity.test.ts +46 -0
- package/components/formatter/ClusterLink.vue +8 -4
- package/components/formatter/ImageName.vue +23 -0
- package/components/formatter/PodImages.vue +7 -1
- package/components/formatter/__tests__/ClusterLink.test.ts +101 -0
- package/components/nav/Header.vue +2 -2
- package/config/__test__/home-links.test.ts +62 -0
- package/config/home-links.js +15 -3
- package/config/labels-annotations.js +5 -1
- package/config/product/auth.js +1 -1
- package/config/router.js +0 -9
- package/config/settings.ts +4 -0
- package/config/table-headers.js +6 -5
- package/config/uiplugins.js +50 -5
- package/core/plugin-helpers.js +20 -12
- package/core/plugin.ts +9 -0
- package/core/plugins.js +1 -1
- package/core/types-provisioning.ts +253 -0
- package/core/types.ts +17 -3
- package/detail/autoscaling.horizontalpodautoscaler/index.vue +50 -1
- package/detail/catalog.cattle.io.clusterrepo.vue +8 -1
- package/detail/node.vue +6 -6
- package/detail/pod.vue +2 -6
- package/detail/provisioning.cattle.io.cluster.vue +46 -7
- package/detail/workload/index.vue +9 -9
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +62 -0
- package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +56 -0
- package/edit/auth/github.vue +1 -0
- package/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue +130 -0
- package/edit/autoscaling.horizontalpodautoscaler/index.vue +79 -0
- package/edit/fleet.cattle.io.gitrepo.vue +18 -1
- package/edit/monitoring.coreos.com.prometheusrule/index.vue +8 -3
- package/edit/namespace.vue +9 -1
- package/edit/networking.k8s.io.ingress/RulePath.vue +0 -2
- package/edit/provisioning.cattle.io.cluster/AgentConfiguration.vue +1 -30
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +79 -1
- package/edit/provisioning.cattle.io.cluster/index.vue +52 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +330 -150
- package/edit/ui.cattle.io.navlink.vue +2 -1
- package/initialize/App.js +3 -13
- package/initialize/layouts.ts +26 -0
- package/list/provisioning.cattle.io.cluster.vue +8 -1
- package/middleware/authenticated.js +93 -5
- package/mixins/brand.js +39 -3
- package/mixins/child-hook.js +2 -2
- package/mixins/create-edit-view/impl.js +2 -2
- package/models/fleet.cattle.io.gitrepo.js +1 -0
- package/models/provisioning.cattle.io.cluster.js +9 -1
- package/package.json +3 -3
- package/pages/about.vue +8 -2
- package/pages/auth/login.vue +10 -0
- package/pages/auth/logout.vue +11 -3
- package/pages/auth/setup.vue +4 -0
- package/pages/c/_cluster/apps/charts/index.vue +5 -2
- package/pages/c/_cluster/apps/charts/install.vue +5 -0
- package/pages/c/_cluster/auth/roles/index.vue +1 -1
- package/pages/c/_cluster/explorer/index.vue +1 -10
- package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +177 -0
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +19 -3
- package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +90 -21
- package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +107 -37
- package/pages/c/_cluster/uiplugins/index.vue +155 -44
- package/pages/docs/_doc.vue +9 -3
- package/pages/home.vue +10 -5
- package/pages/support/index.vue +10 -4
- package/pkg/auto-import.js +1 -1
- package/plugins/clean-tooltip-directive.js +1 -1
- package/plugins/dashboard-store/resource-class.js +35 -2
- package/plugins/plugin.js +9 -1
- package/plugins/steve/actions.js +22 -0
- package/rancher-components/BadgeState/BadgeState.vue +5 -1
- package/rancher-components/Banner/Banner.test.ts +51 -1
- package/rancher-components/Banner/Banner.vue +134 -53
- package/rancher-components/Card/Card.vue +24 -7
- package/rancher-components/Form/Checkbox/Checkbox.test.ts +20 -29
- package/rancher-components/Form/Checkbox/Checkbox.vue +45 -20
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +2 -8
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +22 -10
- package/rancher-components/Form/Radio/RadioButton.vue +30 -13
- package/rancher-components/Form/Radio/RadioGroup.vue +26 -7
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -6
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +25 -38
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +23 -11
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +19 -5
- package/rancher-components/StringList/StringList.test.ts +453 -49
- package/rancher-components/StringList/StringList.vue +92 -58
- package/scripts/extension/publish +2 -2
- package/scripts/typegen.sh +1 -0
- package/server/server-middleware.js +4 -12
- package/store/index.js +13 -0
- package/store/prefs.js +0 -3
- package/store/type-map.js +17 -29
- package/types/shell/index.d.ts +243 -90
- package/utils/kube.js +9 -0
- package/utils/object.js +27 -0
- package/utils/settings.ts +2 -2
- package/vue.config.js +3 -2
- package/pages/safeMode.vue +0 -17
- package/rancher-components/components/BadgeState/BadgeState.spec.ts +0 -12
- package/rancher-components/components/BadgeState/BadgeState.vue +0 -111
- package/rancher-components/components/BadgeState/index.ts +0 -1
- package/rancher-components/components/Banner/Banner.test.ts +0 -63
- package/rancher-components/components/Banner/Banner.vue +0 -244
- package/rancher-components/components/Banner/index.ts +0 -1
- package/rancher-components/components/Card/Card.vue +0 -167
- package/rancher-components/components/Card/index.ts +0 -1
- package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +0 -68
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +0 -420
- package/rancher-components/components/Form/Checkbox/index.ts +0 -1
- package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +0 -23
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +0 -355
- package/rancher-components/components/Form/LabeledInput/index.ts +0 -1
- package/rancher-components/components/Form/Radio/RadioButton.vue +0 -287
- package/rancher-components/components/Form/Radio/RadioGroup.vue +0 -254
- package/rancher-components/components/Form/Radio/index.ts +0 -2
- package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +0 -170
- package/rancher-components/components/Form/TextArea/index.ts +0 -1
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +0 -94
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +0 -149
- package/rancher-components/components/Form/ToggleSwitch/index.ts +0 -1
- package/rancher-components/components/Form/index.ts +0 -5
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -151
- package/rancher-components/components/LabeledTooltip/index.ts +0 -1
- package/rancher-components/components/StringList/StringList.test.ts +0 -484
- package/rancher-components/components/StringList/StringList.vue +0 -611
- package/rancher-components/components/StringList/index.ts +0 -1
- /package/rancher-components/{components/Card → Card}/Card.test.ts +0 -0
- /package/rancher-components/{components/Form → Form}/Radio/RadioButton.test.ts +0 -0
|
@@ -81,6 +81,24 @@ export default {
|
|
|
81
81
|
|
|
82
82
|
async fetch() {
|
|
83
83
|
await this.value.waitForProvisioner();
|
|
84
|
+
|
|
85
|
+
const extClass = this.$plugin.getDynamic('provisioner', this.value.machineProvider);
|
|
86
|
+
|
|
87
|
+
if (extClass) {
|
|
88
|
+
this.extProvider = new extClass({
|
|
89
|
+
dispatch: this.$store.dispatch,
|
|
90
|
+
getters: this.$store.getters,
|
|
91
|
+
axios: this.$store.$axios,
|
|
92
|
+
$plugin: this.$store.app.$plugin,
|
|
93
|
+
$t: this.t
|
|
94
|
+
});
|
|
95
|
+
this.extDetailTabs = {
|
|
96
|
+
...this.extDetailTabs,
|
|
97
|
+
...this.extProvider.detailTabs
|
|
98
|
+
};
|
|
99
|
+
this.extCustomParams = { provider: this.value.machineProvider };
|
|
100
|
+
}
|
|
101
|
+
|
|
84
102
|
const fetchOne = {};
|
|
85
103
|
|
|
86
104
|
if ( this.$store.getters['management/canList'](CAPI.MACHINE_DEPLOYMENT) ) {
|
|
@@ -206,6 +224,18 @@ export default {
|
|
|
206
224
|
logSocket: null,
|
|
207
225
|
logs: [],
|
|
208
226
|
|
|
227
|
+
extProvider: null,
|
|
228
|
+
extCustomParams: null,
|
|
229
|
+
extDetailTabs: {
|
|
230
|
+
machines: true, // in this component
|
|
231
|
+
logs: true, // in this component
|
|
232
|
+
registration: true, // in this component
|
|
233
|
+
snapshots: true, // in this component
|
|
234
|
+
related: true, // in ResourceTabs
|
|
235
|
+
events: true, // in ResourceTabs
|
|
236
|
+
conditions: true, // in ResourceTabs
|
|
237
|
+
},
|
|
238
|
+
|
|
209
239
|
showWindowsWarning: false
|
|
210
240
|
};
|
|
211
241
|
},
|
|
@@ -336,7 +366,9 @@ export default {
|
|
|
336
366
|
},
|
|
337
367
|
|
|
338
368
|
showMachines() {
|
|
339
|
-
|
|
369
|
+
const showMachines = this.haveMachines && (this.value.isRke2 || !!this.machines.length);
|
|
370
|
+
|
|
371
|
+
return showMachines && this.extDetailTabs.machines;
|
|
340
372
|
},
|
|
341
373
|
|
|
342
374
|
showNodes() {
|
|
@@ -345,9 +377,9 @@ export default {
|
|
|
345
377
|
|
|
346
378
|
showSnapshots() {
|
|
347
379
|
if (this.value.isRke1) {
|
|
348
|
-
return this.$store.getters['rancher/canList'](NORMAN.ETCD_BACKUP);
|
|
380
|
+
return this.$store.getters['rancher/canList'](NORMAN.ETCD_BACKUP) && this.extDetailTabs.snapshots;
|
|
349
381
|
} else if (this.value.isRke2) {
|
|
350
|
-
return this.$store.getters['management/canList'](SNAPSHOT);
|
|
382
|
+
return this.$store.getters['management/canList'](SNAPSHOT) && this.extDetailTabs.snapshots;
|
|
351
383
|
}
|
|
352
384
|
|
|
353
385
|
return false;
|
|
@@ -476,15 +508,15 @@ export default {
|
|
|
476
508
|
}
|
|
477
509
|
|
|
478
510
|
if ( this.value.isImported ) {
|
|
479
|
-
return !this.value.mgmt?.isReady;
|
|
511
|
+
return !this.value.mgmt?.isReady && this.extDetailTabs.registration;
|
|
480
512
|
}
|
|
481
513
|
|
|
482
514
|
if ( this.value.isCustom ) {
|
|
483
|
-
return
|
|
515
|
+
return this.extDetailTabs.registration;
|
|
484
516
|
}
|
|
485
517
|
|
|
486
518
|
if ( this.value.isHostedKubernetesProvider && !this.isClusterReady ) {
|
|
487
|
-
return
|
|
519
|
+
return this.extDetailTabs.registration;
|
|
488
520
|
}
|
|
489
521
|
|
|
490
522
|
return false;
|
|
@@ -495,7 +527,9 @@ export default {
|
|
|
495
527
|
},
|
|
496
528
|
|
|
497
529
|
showLog() {
|
|
498
|
-
|
|
530
|
+
const showLog = this.value.mgmt?.hasLink('log');
|
|
531
|
+
|
|
532
|
+
return showLog && this.extDetailTabs.logs;
|
|
499
533
|
},
|
|
500
534
|
|
|
501
535
|
dateTimeFormatStr() {
|
|
@@ -686,6 +720,10 @@ export default {
|
|
|
686
720
|
v-model="value"
|
|
687
721
|
:default-tab="defaultTab"
|
|
688
722
|
:need-related="hasLocalAccess"
|
|
723
|
+
:extension-params="extCustomParams"
|
|
724
|
+
:needRelated="extDetailTabs.related"
|
|
725
|
+
:needEvents="extDetailTabs.events"
|
|
726
|
+
:needConditions="extDetailTabs.conditions"
|
|
689
727
|
>
|
|
690
728
|
<Tab
|
|
691
729
|
v-if="showMachines"
|
|
@@ -773,6 +811,7 @@ export default {
|
|
|
773
811
|
</template>
|
|
774
812
|
</ResourceTable>
|
|
775
813
|
</Tab>
|
|
814
|
+
|
|
776
815
|
<Tab
|
|
777
816
|
v-else-if="showNodes"
|
|
778
817
|
name="node-pools"
|
|
@@ -4,7 +4,7 @@ import { NAMESPACE as NAMESPACE_COL } from '@shell/config/table-headers';
|
|
|
4
4
|
import {
|
|
5
5
|
POD, WORKLOAD_TYPES, SCALABLE_WORKLOAD_TYPES, SERVICE, INGRESS, NODE
|
|
6
6
|
} from '@shell/config/types';
|
|
7
|
-
import
|
|
7
|
+
import ResourceTable from '@shell/components/ResourceTable';
|
|
8
8
|
import Tab from '@shell/components/Tabbed/Tab';
|
|
9
9
|
import Loading from '@shell/components/Loading';
|
|
10
10
|
import ResourceTabs from '@shell/components/form/ResourceTabs';
|
|
@@ -46,7 +46,7 @@ export default {
|
|
|
46
46
|
Loading,
|
|
47
47
|
ResourceTabs,
|
|
48
48
|
CountGauge,
|
|
49
|
-
|
|
49
|
+
ResourceTable,
|
|
50
50
|
PlusMinus
|
|
51
51
|
},
|
|
52
52
|
|
|
@@ -380,12 +380,12 @@ export default {
|
|
|
380
380
|
:label="t('tableHeaders.jobs')"
|
|
381
381
|
:weight="4"
|
|
382
382
|
>
|
|
383
|
-
<
|
|
383
|
+
<ResourceTable
|
|
384
384
|
:rows="value.jobs"
|
|
385
385
|
:headers="jobHeaders"
|
|
386
386
|
key-field="id"
|
|
387
387
|
:schema="jobSchema"
|
|
388
|
-
:
|
|
388
|
+
:groupable="false"
|
|
389
389
|
:search="false"
|
|
390
390
|
/>
|
|
391
391
|
</Tab>
|
|
@@ -395,7 +395,7 @@ export default {
|
|
|
395
395
|
:label="t('tableHeaders.pods')"
|
|
396
396
|
:weight="4"
|
|
397
397
|
>
|
|
398
|
-
<
|
|
398
|
+
<ResourceTable
|
|
399
399
|
v-if="value.pods"
|
|
400
400
|
:rows="value.pods"
|
|
401
401
|
:headers="podHeaders"
|
|
@@ -458,13 +458,13 @@ export default {
|
|
|
458
458
|
>
|
|
459
459
|
{{ t('workload.detail.serviceListCaption') }}
|
|
460
460
|
</p>
|
|
461
|
-
<
|
|
461
|
+
<ResourceTable
|
|
462
462
|
v-if="serviceSchema && matchingServices.length > 0"
|
|
463
463
|
:rows="matchingServices"
|
|
464
464
|
:headers="serviceHeaders"
|
|
465
465
|
key-field="id"
|
|
466
466
|
:schema="serviceSchema"
|
|
467
|
-
:
|
|
467
|
+
:groupable="false"
|
|
468
468
|
:search="false"
|
|
469
469
|
:table-actions="false"
|
|
470
470
|
/>
|
|
@@ -499,13 +499,13 @@ export default {
|
|
|
499
499
|
>
|
|
500
500
|
{{ t('workload.detail.ingressListCaption') }}
|
|
501
501
|
</p>
|
|
502
|
-
<
|
|
502
|
+
<ResourceTable
|
|
503
503
|
v-if="ingressSchema && matchingIngresses.length > 0"
|
|
504
504
|
:rows="matchingIngresses"
|
|
505
505
|
:headers="ingressHeaders"
|
|
506
506
|
key-field="id"
|
|
507
507
|
:schema="ingressSchema"
|
|
508
|
-
:
|
|
508
|
+
:groupable="false"
|
|
509
509
|
:search="false"
|
|
510
510
|
:table-actions="false"
|
|
511
511
|
/>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { mount, createLocalVue } from '@vue/test-utils';
|
|
2
|
+
import GitRepo from '@shell/edit/fleet.cattle.io.gitrepo.vue';
|
|
3
|
+
import Vuex from 'vuex';
|
|
4
|
+
|
|
5
|
+
const localVue = createLocalVue();
|
|
6
|
+
|
|
7
|
+
localVue.use(Vuex);
|
|
8
|
+
|
|
9
|
+
describe('view: fleet.cattle.io.gitrepo should', () => {
|
|
10
|
+
const mockStore = {
|
|
11
|
+
getters: {
|
|
12
|
+
'i18n/t': (text: string) => text,
|
|
13
|
+
t: (text: string) => text,
|
|
14
|
+
currentStore: () => 'current_store',
|
|
15
|
+
'current_store/schemaFor': jest.fn(),
|
|
16
|
+
'current_store/all': jest.fn(),
|
|
17
|
+
workspace: jest.fn(),
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const mocks = {
|
|
21
|
+
$store: mockStore,
|
|
22
|
+
$fetchState: { pending: false },
|
|
23
|
+
$route: {
|
|
24
|
+
query: { AS: '' },
|
|
25
|
+
name: {
|
|
26
|
+
endsWith: () => {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const values = {
|
|
33
|
+
metadata: { namespace: 'test' }, spec: { template: {}, correctDrift: { enabled: false } }, targetInfo: { mode: 'all' },
|
|
34
|
+
};
|
|
35
|
+
const wrapper = mount(GitRepo, {
|
|
36
|
+
localVue,
|
|
37
|
+
propsData: { value: values },
|
|
38
|
+
mocks
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should have self-healing checkbox and banner', () => {
|
|
42
|
+
const correctDriftCheckbox = wrapper.find('[data-testid="GitRepo-correctDrift-checkbox"]');
|
|
43
|
+
const correctDriftBanner = wrapper.find('[data-testid="GitRepo-correctDrift-banner"]');
|
|
44
|
+
|
|
45
|
+
expect(correctDriftCheckbox.exists()).toBeTruthy();
|
|
46
|
+
expect(correctDriftBanner.exists()).toBeTruthy();
|
|
47
|
+
expect(correctDriftCheckbox.props().value).toBeFalsy();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should enable drift if self-healing is checked', async() => {
|
|
51
|
+
const correctDriftCheckbox = wrapper.find('[data-testid="GitRepo-correctDrift-checkbox"]');
|
|
52
|
+
const correctDriftContainer = wrapper.find('[data-testid="GitRepo-correctDrift-checkbox"] .checkbox-container');
|
|
53
|
+
|
|
54
|
+
expect(correctDriftContainer.exists()).toBeTruthy();
|
|
55
|
+
|
|
56
|
+
await correctDriftContainer.trigger('click');
|
|
57
|
+
|
|
58
|
+
expect(correctDriftCheckbox.emitted('input')).toHaveLength(1);
|
|
59
|
+
expect(correctDriftCheckbox.emitted('input')![0][0]).toBe(true);
|
|
60
|
+
expect(correctDriftCheckbox.props().value).toBeTruthy();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import FormValidation from '@shell/mixins/form-validation';
|
|
3
|
+
import Monitoring from '@shell/edit/monitoring.coreos.com.prometheusrule/index.vue';
|
|
4
|
+
import { _EDIT } from '@shell/config/query-params';
|
|
5
|
+
import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
|
|
6
|
+
|
|
7
|
+
describe('edit: management.cattle.io.setting should', () => {
|
|
8
|
+
const MOCKED_ERRORS = ['error1', 'error2', 'error3', 'error4', 'error5'];
|
|
9
|
+
const ERROR_BANNER_SELECTOR = '[data-testid="banner-close"]';
|
|
10
|
+
const requiredSetup = () => ({
|
|
11
|
+
// Remove all these mocks after migration to Vue 2.7/3 due mixin logic
|
|
12
|
+
mocks: {
|
|
13
|
+
$store: {
|
|
14
|
+
getters: {
|
|
15
|
+
currentStore: () => 'current_store',
|
|
16
|
+
'current_store/schemaFor': jest.fn(),
|
|
17
|
+
'current_store/all': jest.fn(),
|
|
18
|
+
'i18n/t': jest.fn(),
|
|
19
|
+
'i18n/exists': jest.fn(),
|
|
20
|
+
namespaces: () => ({})
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
$route: { query: { AS: '' }, name: '' },
|
|
24
|
+
$router: { applyQuery: jest.fn() }
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should close error banners', async() => {
|
|
29
|
+
jest.spyOn(FormValidation.computed, 'fvUnreportedValidationErrors').mockReturnValue(MOCKED_ERRORS);
|
|
30
|
+
|
|
31
|
+
const wrapper = mount(Monitoring, {
|
|
32
|
+
propsData: {
|
|
33
|
+
canYaml: false,
|
|
34
|
+
mode: _EDIT,
|
|
35
|
+
resource: {},
|
|
36
|
+
value: { value: 'anything' },
|
|
37
|
+
name: ''
|
|
38
|
+
},
|
|
39
|
+
directives: { cleanHtmlDirective },
|
|
40
|
+
...requiredSetup()
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const errorBanners = wrapper.findAll(ERROR_BANNER_SELECTOR);
|
|
44
|
+
|
|
45
|
+
// Assert that all the error banners are rendered
|
|
46
|
+
expect(errorBanners).toHaveLength(MOCKED_ERRORS.length);
|
|
47
|
+
|
|
48
|
+
for (let i = 0; i < MOCKED_ERRORS.length; i++) {
|
|
49
|
+
await errorBanners.at(0).trigger('click');
|
|
50
|
+
const resultErrorBanners = wrapper.findAll(ERROR_BANNER_SELECTOR);
|
|
51
|
+
|
|
52
|
+
// Assert that an error banner is closed until the last one
|
|
53
|
+
expect(resultErrorBanners).toHaveLength(MOCKED_ERRORS.length - 1 - i);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
});
|
package/edit/auth/github.vue
CHANGED
|
@@ -163,6 +163,7 @@ export default {
|
|
|
163
163
|
<RadioGroup
|
|
164
164
|
v-model="targetType"
|
|
165
165
|
name="targetType"
|
|
166
|
+
data-testid="authConfig-gitHub"
|
|
166
167
|
:options="['public','private']"
|
|
167
168
|
:mode="mode"
|
|
168
169
|
:labels="[ t(`authConfig.${NAME}.target.public`), t(`authConfig.${NAME}.target.private`)]"
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
|
|
3
|
+
import { _EDIT } from '@shell/config/query-params';
|
|
4
|
+
import LabeledSelect from '@shell/components/form/LabeledSelect.vue';
|
|
5
|
+
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
6
|
+
import ArrayListGrouped from '@shell/components/form/ArrayListGrouped.vue';
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
components: {
|
|
10
|
+
ArrayListGrouped,
|
|
11
|
+
LabeledInput,
|
|
12
|
+
LabeledSelect
|
|
13
|
+
},
|
|
14
|
+
props: {
|
|
15
|
+
value: {
|
|
16
|
+
type: Object,
|
|
17
|
+
default: () => {
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
mode: {
|
|
21
|
+
type: String,
|
|
22
|
+
default: _EDIT
|
|
23
|
+
},
|
|
24
|
+
type: {
|
|
25
|
+
type: String,
|
|
26
|
+
default: 'scaleUp'
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
data() {
|
|
30
|
+
if (!this.value.spec.behavior[this.type].policies) {
|
|
31
|
+
this.$set(this.value.spec.behavior[this.type], 'policies', []);
|
|
32
|
+
}
|
|
33
|
+
if (!this.value.spec.behavior[this.type].selectPolicy) {
|
|
34
|
+
this.$set(this.value.spec.behavior[this.type], 'selectPolicy', 'Max');
|
|
35
|
+
}
|
|
36
|
+
if (this.value.spec.behavior[this.type].stabilizationWindowSeconds === null || typeof this.value.spec.behavior[this.type].stabilizationWindowSeconds === 'undefined') {
|
|
37
|
+
if (this.type === 'scaleUp') {
|
|
38
|
+
this.$set(this.value.spec.behavior[this.type], 'stabilizationWindowSeconds', 0);
|
|
39
|
+
}
|
|
40
|
+
if (this.type === 'scaleDown') {
|
|
41
|
+
this.$set(this.value.spec.behavior[this.type], 'stabilizationWindowSeconds', 300);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return { selectPolicyOptions: ['Max', 'Min', 'Disabled'], policyTypeOptions: ['Pods', 'Percent'] };
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<template>
|
|
51
|
+
<div>
|
|
52
|
+
<div class="row mb-20">
|
|
53
|
+
<div class="col span-12">
|
|
54
|
+
<ArrayListGrouped
|
|
55
|
+
v-model="value.spec.behavior[type].policies"
|
|
56
|
+
:add-label="t('hpa.scalingRule.addPolicy')"
|
|
57
|
+
:default-add-value="{}"
|
|
58
|
+
:mode="mode"
|
|
59
|
+
>
|
|
60
|
+
<template #default="props">
|
|
61
|
+
<div class="row">
|
|
62
|
+
<div class="col span-4">
|
|
63
|
+
<LabeledSelect
|
|
64
|
+
v-model="props.row.value.type"
|
|
65
|
+
:mode="mode"
|
|
66
|
+
:options="policyTypeOptions"
|
|
67
|
+
:multiple="false"
|
|
68
|
+
:taggable="true"
|
|
69
|
+
:searchable="true"
|
|
70
|
+
:required="true"
|
|
71
|
+
:tooltip="t('hpa.scalingRule.policy.typeTooltip')"
|
|
72
|
+
:label="t('hpa.scalingRule.policy.type')"
|
|
73
|
+
/>
|
|
74
|
+
</div>
|
|
75
|
+
<div class="col span-4">
|
|
76
|
+
<LabeledInput
|
|
77
|
+
v-model.number="props.row.value.value"
|
|
78
|
+
:mode="mode"
|
|
79
|
+
type="number"
|
|
80
|
+
min="1"
|
|
81
|
+
:required="true"
|
|
82
|
+
:tooltip="t('hpa.scalingRule.policy.valueTooltip')"
|
|
83
|
+
:label="t('hpa.scalingRule.policy.value')"
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
<div class="col span-4">
|
|
87
|
+
<LabeledInput
|
|
88
|
+
v-model.number="props.row.value.periodSeconds"
|
|
89
|
+
:mode="mode"
|
|
90
|
+
type="number"
|
|
91
|
+
min="1"
|
|
92
|
+
max="1800"
|
|
93
|
+
:required="true"
|
|
94
|
+
:tooltip="t('hpa.scalingRule.policy.periodSecondsTooltip')"
|
|
95
|
+
:label="t('hpa.scalingRule.policy.periodSeconds')"
|
|
96
|
+
/>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</template>
|
|
100
|
+
</ArrayListGrouped>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
<div class="row">
|
|
104
|
+
<div class="col span-6">
|
|
105
|
+
<LabeledSelect
|
|
106
|
+
v-model="value.spec.behavior[type].selectPolicy"
|
|
107
|
+
:mode="mode"
|
|
108
|
+
:options="selectPolicyOptions"
|
|
109
|
+
:multiple="false"
|
|
110
|
+
:taggable="true"
|
|
111
|
+
:searchable="true"
|
|
112
|
+
:label="t('hpa.scalingRule.selectPolicy')"
|
|
113
|
+
:tooltip="t('hpa.scalingRule.selectPolicyTooltip')"
|
|
114
|
+
/>
|
|
115
|
+
</div>
|
|
116
|
+
<div class="col span-6">
|
|
117
|
+
<LabeledInput
|
|
118
|
+
v-model.number="value.spec.behavior[type].stabilizationWindowSeconds"
|
|
119
|
+
:mode="mode"
|
|
120
|
+
type="number"
|
|
121
|
+
min="0"
|
|
122
|
+
max="3600"
|
|
123
|
+
:label="t('hpa.scalingRule.stabilizationWindowSeconds')"
|
|
124
|
+
:tooltip="t('hpa.scalingRule.stabilizationWindowSecondsTooltip')"
|
|
125
|
+
/>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
<div class="row mb-40" />
|
|
129
|
+
</div>
|
|
130
|
+
</template>
|
|
@@ -12,12 +12,14 @@ import Tabbed from '@shell/components/Tabbed';
|
|
|
12
12
|
import MetricsRow from '@shell/edit/autoscaling.horizontalpodautoscaler/metrics-row';
|
|
13
13
|
import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
|
|
14
14
|
import { DEFAULT_RESOURCE_METRIC } from '@shell/edit/autoscaling.horizontalpodautoscaler/resource-metric';
|
|
15
|
+
import { Checkbox } from '@components/Form/Checkbox';
|
|
15
16
|
|
|
16
17
|
import { API_SERVICE, SCALABLE_WORKLOAD_TYPES } from '@shell/config/types';
|
|
17
18
|
import isEmpty from 'lodash/isEmpty';
|
|
18
19
|
import find from 'lodash/find';
|
|
19
20
|
import endsWith from 'lodash/endsWith';
|
|
20
21
|
import { findBy } from '@shell/utils/array';
|
|
22
|
+
import HpaScalingRule from '@shell/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue';
|
|
21
23
|
|
|
22
24
|
const RESOURCE_METRICS_API_GROUP = 'metrics.k8s.io';
|
|
23
25
|
|
|
@@ -25,7 +27,9 @@ export default {
|
|
|
25
27
|
name: 'CruHPA',
|
|
26
28
|
|
|
27
29
|
components: {
|
|
30
|
+
HpaScalingRule,
|
|
28
31
|
ArrayListGrouped,
|
|
32
|
+
Checkbox,
|
|
29
33
|
CruResource,
|
|
30
34
|
LabeledInput,
|
|
31
35
|
LabeledSelect,
|
|
@@ -107,6 +111,40 @@ export default {
|
|
|
107
111
|
|
|
108
112
|
return match ?? null;
|
|
109
113
|
},
|
|
114
|
+
hasScaleDownRules: {
|
|
115
|
+
get() {
|
|
116
|
+
return !!this.value.spec.behavior?.scaleDown;
|
|
117
|
+
},
|
|
118
|
+
set(hasScaleDownRules) {
|
|
119
|
+
if (hasScaleDownRules) {
|
|
120
|
+
if (!this.value.spec.behavior) {
|
|
121
|
+
this.$set(this.value.spec, 'behavior', {});
|
|
122
|
+
}
|
|
123
|
+
if (!this.value.spec.behavior?.scaleDown) {
|
|
124
|
+
this.$set(this.value.spec.behavior, 'scaleDown', {});
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
this.$delete(this.value.spec.behavior, 'scaleDown');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
hasScaleUpRules: {
|
|
132
|
+
get() {
|
|
133
|
+
return !!this.value.spec.behavior?.scaleUp;
|
|
134
|
+
},
|
|
135
|
+
set(hasScaleUpRules) {
|
|
136
|
+
if (hasScaleUpRules) {
|
|
137
|
+
if (!this.value.spec.behavior) {
|
|
138
|
+
this.$set(this.value.spec, 'behavior', {});
|
|
139
|
+
}
|
|
140
|
+
if (!this.value.spec.behavior?.scaleUp) {
|
|
141
|
+
this.$set(this.value.spec.behavior, 'scaleUp', {});
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
this.$delete(this.value.spec.behavior, 'scaleUp');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
},
|
|
110
148
|
},
|
|
111
149
|
|
|
112
150
|
created() {
|
|
@@ -242,6 +280,47 @@ export default {
|
|
|
242
280
|
</template>
|
|
243
281
|
</ArrayListGrouped>
|
|
244
282
|
</Tab>
|
|
283
|
+
<Tab
|
|
284
|
+
name="behavior"
|
|
285
|
+
:label="t('hpa.tabs.behavior')"
|
|
286
|
+
>
|
|
287
|
+
<div class="col span-12 mb-10">
|
|
288
|
+
<h3>
|
|
289
|
+
{{ t('hpa.scaleDownRules.label') }}
|
|
290
|
+
</h3>
|
|
291
|
+
<div class="row mb-10">
|
|
292
|
+
<Checkbox
|
|
293
|
+
v-model="hasScaleDownRules"
|
|
294
|
+
:mode="mode"
|
|
295
|
+
:label="t('hpa.scaleDownRules.enable')"
|
|
296
|
+
/>
|
|
297
|
+
</div>
|
|
298
|
+
<HpaScalingRule
|
|
299
|
+
v-if="hasScaleDownRules"
|
|
300
|
+
v-model="value"
|
|
301
|
+
type="scaleDown"
|
|
302
|
+
:mode="mode"
|
|
303
|
+
/>
|
|
304
|
+
</div>
|
|
305
|
+
<div class="col span-12">
|
|
306
|
+
<h3>
|
|
307
|
+
{{ t('hpa.scaleUpRules.label') }}
|
|
308
|
+
</h3>
|
|
309
|
+
<div class="row mb-10">
|
|
310
|
+
<Checkbox
|
|
311
|
+
v-model="hasScaleUpRules"
|
|
312
|
+
:mode="mode"
|
|
313
|
+
:label="t('hpa.scaleUpRules.enable')"
|
|
314
|
+
/>
|
|
315
|
+
</div>
|
|
316
|
+
<HpaScalingRule
|
|
317
|
+
v-if="hasScaleUpRules"
|
|
318
|
+
v-model="value"
|
|
319
|
+
type="scaleUp"
|
|
320
|
+
:mode="mode"
|
|
321
|
+
/>
|
|
322
|
+
</div>
|
|
323
|
+
</Tab>
|
|
245
324
|
<Tab
|
|
246
325
|
name="labels-and-annotations"
|
|
247
326
|
:label="t('hpa.tabs.labels')"
|
|
@@ -604,6 +604,23 @@ export default {
|
|
|
604
604
|
</template>
|
|
605
605
|
<div class="spacer" />
|
|
606
606
|
<h2 v-t="'fleet.gitRepo.resources.label'" />
|
|
607
|
+
<div>
|
|
608
|
+
<Checkbox
|
|
609
|
+
v-model="value.spec.correctDrift.enabled"
|
|
610
|
+
data-testid="GitRepo-correctDrift-checkbox"
|
|
611
|
+
class="check"
|
|
612
|
+
type="checkbox"
|
|
613
|
+
label-key="fleet.gitRepo.resources.correctDrift"
|
|
614
|
+
:mode="mode"
|
|
615
|
+
/>
|
|
616
|
+
<Banner
|
|
617
|
+
data-testid="GitRepo-correctDrift-banner"
|
|
618
|
+
color="info"
|
|
619
|
+
>
|
|
620
|
+
{{ t('fleet.gitRepo.resources.correctDriftBanner') }}
|
|
621
|
+
</Banner>
|
|
622
|
+
</div>
|
|
623
|
+
|
|
607
624
|
<Checkbox
|
|
608
625
|
v-model="value.spec.keepResources"
|
|
609
626
|
class="check"
|
|
@@ -614,7 +631,7 @@ export default {
|
|
|
614
631
|
<Banner
|
|
615
632
|
color="info"
|
|
616
633
|
>
|
|
617
|
-
{{ t('fleet.gitRepo.resources.
|
|
634
|
+
{{ t('fleet.gitRepo.resources.keepResourcesBanner') }}
|
|
618
635
|
</Banner>
|
|
619
636
|
<div class="spacer" />
|
|
620
637
|
<h2 v-t="'fleet.gitRepo.paths.label'" />
|
|
@@ -42,7 +42,10 @@ export default {
|
|
|
42
42
|
},
|
|
43
43
|
|
|
44
44
|
data() {
|
|
45
|
-
return {
|
|
45
|
+
return {
|
|
46
|
+
fvFormRuleSets: [{ path: 'metadata.name', rules: ['dnsLabel'] }],
|
|
47
|
+
closedErrorMessages: []
|
|
48
|
+
};
|
|
46
49
|
},
|
|
47
50
|
|
|
48
51
|
computed: {
|
|
@@ -54,7 +57,7 @@ export default {
|
|
|
54
57
|
return [this.t('validation.prometheusRule.noEdit')];
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
return this.fvUnreportedValidationErrors;
|
|
60
|
+
return this.fvUnreportedValidationErrors.filter((e) => !this.closedErrorMessages.includes(e));
|
|
58
61
|
}
|
|
59
62
|
},
|
|
60
63
|
|
|
@@ -102,6 +105,8 @@ export default {
|
|
|
102
105
|
}
|
|
103
106
|
});
|
|
104
107
|
|
|
108
|
+
this.closedErrorMessages = [];
|
|
109
|
+
|
|
105
110
|
return true;
|
|
106
111
|
},
|
|
107
112
|
|
|
@@ -125,7 +130,7 @@ export default {
|
|
|
125
130
|
:mode="mode"
|
|
126
131
|
:resource="value"
|
|
127
132
|
:validation-passed="fvFormIsValid"
|
|
128
|
-
@error="(
|
|
133
|
+
@error="(_, closedError) => closedErrorMessages.push(closedError)"
|
|
129
134
|
@finish="save"
|
|
130
135
|
>
|
|
131
136
|
<div class="row">
|
package/edit/namespace.vue
CHANGED
|
@@ -17,6 +17,7 @@ import Loading from '@shell/components/Loading';
|
|
|
17
17
|
import { HARVESTER_TYPES, RANCHER_TYPES } from '@shell/components/form/ResourceQuota/shared';
|
|
18
18
|
import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
|
|
19
19
|
import Labels from '@shell/components/form/Labels';
|
|
20
|
+
import { randomStr } from '@shell/utils/string';
|
|
20
21
|
|
|
21
22
|
export default {
|
|
22
23
|
components: {
|
|
@@ -58,6 +59,7 @@ export default {
|
|
|
58
59
|
projects: null,
|
|
59
60
|
viewMode: _VIEW,
|
|
60
61
|
containerResourceLimits: this.value.annotations?.[CONTAINER_DEFAULT_RESOURCE_LIMIT] || this.getDefaultContainerResourceLimits(projectName),
|
|
62
|
+
rerenderNums: randomStr(4),
|
|
61
63
|
projectName,
|
|
62
64
|
HARVESTER_TYPES,
|
|
63
65
|
RANCHER_TYPES,
|
|
@@ -152,6 +154,11 @@ export default {
|
|
|
152
154
|
const project = projects.find((p) => p.id.includes(projectName));
|
|
153
155
|
|
|
154
156
|
return project?.spec?.containerDefaultResourceLimit || {};
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
PSAChanged($event) {
|
|
160
|
+
this.value.setLabels($event);
|
|
161
|
+
this.rerenderNums = randomStr(4);
|
|
155
162
|
}
|
|
156
163
|
},
|
|
157
164
|
};
|
|
@@ -242,6 +249,7 @@ export default {
|
|
|
242
249
|
:weight="-1"
|
|
243
250
|
>
|
|
244
251
|
<Labels
|
|
252
|
+
:key="rerenderNums"
|
|
245
253
|
default-container-class="labels-and-annotations-container"
|
|
246
254
|
:value="value"
|
|
247
255
|
:mode="mode"
|
|
@@ -258,7 +266,7 @@ export default {
|
|
|
258
266
|
:labels="value.labels"
|
|
259
267
|
:mode="mode"
|
|
260
268
|
labels-prefix="pod-security.kubernetes.io/"
|
|
261
|
-
@updateLabels="
|
|
269
|
+
@updateLabels="PSAChanged"
|
|
262
270
|
/>
|
|
263
271
|
</Tab>
|
|
264
272
|
</Tabbed>
|