@rancher/shell 3.0.12-rc.4 → 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/styles/global/_button.scss +1 -1
- package/assets/translations/en-us.yaml +49 -14
- 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/ActionDropdownShell.vue +5 -3
- package/components/ButtonGroup.vue +26 -1
- package/components/CruResource.vue +51 -2
- package/components/EtcdInfoBanner.vue +2 -12
- package/components/GrafanaDashboard.vue +2 -8
- package/components/PromptRestore.vue +93 -32
- package/components/Questions/index.vue +1 -0
- package/components/Resource/Detail/Masthead/__tests__/index.test.ts +68 -14
- package/components/Resource/Detail/Masthead/index.vue +8 -3
- package/components/ResourceTable.vue +1 -0
- package/components/SortableTable/index.vue +4 -3
- package/components/Wizard.vue +14 -1
- package/components/__tests__/ButtonGroup.test.ts +56 -0
- package/components/__tests__/PromptRestore.test.ts +169 -19
- package/components/fleet/GitRepoAdvancedTab.vue +1 -0
- package/components/fleet/GitRepoMetadataTab.vue +5 -0
- package/components/fleet/HelmOpAppCoConfigTab.vue +4 -0
- package/components/fleet/HelmOpMetadataTab.vue +5 -0
- package/components/form/FileSelector.vue +39 -1
- package/components/form/PrivateRegistry.constants.ts +7 -0
- package/components/form/PrivateRegistry.vue +253 -18
- package/components/form/Security.vue +1 -1
- package/components/form/SelectOrCreateAuthSecret.vue +140 -17
- package/components/form/__tests__/FileSelector.test.ts +23 -0
- package/components/form/__tests__/PrivateRegistry.test.ts +463 -73
- package/components/form/__tests__/SelectOrCreateAuthSecret.test.ts +122 -0
- package/components/formatter/EtcdSnapshotName.vue +73 -0
- package/components/formatter/Translate.vue +22 -1
- package/components/nav/Group.vue +5 -10
- package/components/nav/Header.vue +8 -1
- package/components/nav/TopLevelMenu.vue +1 -30
- package/components/nav/__tests__/Group.test.ts +61 -0
- package/components/templates/default.vue +7 -0
- package/config/features.js +1 -0
- package/config/labels-annotations.js +3 -0
- package/config/product/manager.js +6 -0
- package/config/secret.ts +10 -0
- package/config/settings.ts +6 -2
- package/config/table-headers.js +5 -2
- package/config/types.js +7 -0
- 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 +79 -5
- package/dialog/RotateEncryptionKeyDialog.vue +33 -9
- package/dialog/__tests__/RotateEncryptionKeyDialog.test.ts +78 -0
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +92 -0
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +101 -0
- package/edit/__tests__/management.cattle.io.setting.test.ts +2 -1
- 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/compliance.cattle.io.clusterscanprofile.vue +39 -41
- package/edit/fleet.cattle.io.gitrepo.vue +70 -16
- package/edit/fleet.cattle.io.helmop.vue +51 -5
- package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
- package/edit/{management.cattle.io.setting.vue → management.cattle.io.setting/index.vue} +32 -9
- package/edit/management.cattle.io.setting/system-default-registry-pull-secrets.vue +81 -0
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -12
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +18 -0
- package/edit/provisioning.cattle.io.cluster/index.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/rke2.vue +6 -2
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +0 -1
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +14 -55
- 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__/provisioning.cattle.io.cluster.test.ts +156 -0
- package/models/__tests__/rke-machine.cattle.io.vmwarevspheremachinetemplate.test.ts +22 -0
- package/models/__tests__/secret.test.ts +68 -1
- package/models/management.cattle.io.cluster.js +21 -3
- package/models/pod.js +25 -12
- package/models/provisioning.cattle.io.cluster.js +59 -9
- package/models/rke-machine.cattle.io.vmwarevspheremachinetemplate.js +9 -0
- package/models/rke.cattle.io.etcdsnapshot.js +17 -9
- package/models/secret.js +19 -0
- package/models/workload.js +12 -7
- package/package.json +1 -1
- package/pages/auth/login.vue +1 -1
- package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +569 -81
- package/pages/c/_cluster/apps/charts/install.vue +143 -28
- package/pages/c/_cluster/auth/config/index.vue +11 -4
- package/pages/c/_cluster/monitoring/index.vue +6 -1
- package/pkg/require-asset.lib.js +25 -0
- package/pkg/vue.config.js +7 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +84 -0
- package/plugins/dashboard-store/getters.js +0 -1
- package/plugins/dashboard-store/resource-class.js +62 -15
- 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/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +30 -0
- package/rancher-components/Form/TextArea/__tests__/TextAreaAutoGrow.test.ts +95 -0
- package/rancher-components/RcButton/index.ts +1 -1
- package/rancher-components/RcDropdown/RcDropdownTrigger.vue +6 -1
- package/store/__tests__/auth.test.ts +18 -0
- package/store/__tests__/features.test.ts +131 -0
- package/store/__tests__/growl.test.ts +374 -0
- package/store/__tests__/modal.test.ts +131 -0
- package/store/__tests__/notifications.test.ts +466 -1
- package/store/__tests__/slideInPanel.test.ts +88 -0
- package/store/__tests__/type-map.utils.test.ts +433 -0
- package/store/__tests__/ui-context.test.ts +255 -0
- package/store/auth.js +11 -1
- package/store/features.js +5 -0
- package/store/plugins.js +6 -0
- package/types/rancher/steve.api.ts +2 -2
- package/types/shell/index.d.ts +120 -0
- package/types/store/dashboard-store.types.ts +2 -2
- package/types/store/type-map.ts +262 -1
- package/utils/__tests__/operation-cr.test.ts +34 -0
- package/utils/async.ts +2 -0
- package/utils/grafana.js +2 -17
- package/utils/monitoring.js +38 -1
- package/utils/operation-cr.js +19 -0
- package/utils/require-asset.ts +7 -0
- package/utils/validators/__tests__/private-registry.test.ts +27 -15
- package/utils/validators/private-registry.ts +15 -4
- package/core/__tests__/plugin-products.test.ts +0 -4694
|
@@ -196,7 +196,7 @@ export default {
|
|
|
196
196
|
label: this.t('fleet.helmOp.add.steps.metadata.label'),
|
|
197
197
|
subtext: this.t('fleet.helmOp.add.steps.metadata.subtext'),
|
|
198
198
|
descriptionKey: 'fleet.helmOp.add.steps.metadata.description',
|
|
199
|
-
ready: this.isView || !!this.value.metadata.name,
|
|
199
|
+
ready: this.isView || (!!this.value.metadata.name && this.stepPathErrors('basics').length === 0),
|
|
200
200
|
weight: 1
|
|
201
201
|
},
|
|
202
202
|
{
|
|
@@ -443,6 +443,15 @@ export default {
|
|
|
443
443
|
this.done();
|
|
444
444
|
},
|
|
445
445
|
|
|
446
|
+
stepPathErrors(stepName) {
|
|
447
|
+
// Helper is used to check which validations is for each step
|
|
448
|
+
const paths = this.fvFormRuleSets
|
|
449
|
+
.filter((rule) => rule.step === stepName)
|
|
450
|
+
.map((rule) => rule.path);
|
|
451
|
+
|
|
452
|
+
return this.fvGetPathErrors(paths);
|
|
453
|
+
},
|
|
454
|
+
|
|
446
455
|
onSourceTypeSelect(type) {
|
|
447
456
|
if (this.isSuseAppCollection) {
|
|
448
457
|
return;
|
|
@@ -659,35 +668,49 @@ export default {
|
|
|
659
668
|
},
|
|
660
669
|
|
|
661
670
|
updateValidationRules(sourceType) {
|
|
671
|
+
const nameRule = {
|
|
672
|
+
step: 'basics',
|
|
673
|
+
path: 'metadata.name',
|
|
674
|
+
rules: ['subDomain'],
|
|
675
|
+
translationKey: 'nameNsDescription.name.label'
|
|
676
|
+
};
|
|
677
|
+
|
|
662
678
|
switch (sourceType) {
|
|
663
679
|
case SOURCE_TYPE.REPO:
|
|
664
|
-
this.fvFormRuleSets = [{
|
|
680
|
+
this.fvFormRuleSets = [nameRule, {
|
|
681
|
+
step: 'chart',
|
|
665
682
|
path: 'spec.helm.repo',
|
|
666
683
|
rules: ['urlRepository'],
|
|
667
684
|
}, {
|
|
685
|
+
step: 'chart',
|
|
668
686
|
path: 'spec.helm.chart',
|
|
669
687
|
rules: ['required'],
|
|
670
688
|
}, {
|
|
689
|
+
step: 'chart',
|
|
671
690
|
path: 'spec.helm.version',
|
|
672
691
|
rules: ['semanticVersion'],
|
|
673
692
|
}];
|
|
674
693
|
break;
|
|
675
694
|
case SOURCE_TYPE.OCI:
|
|
676
|
-
this.fvFormRuleSets = [{
|
|
695
|
+
this.fvFormRuleSets = [nameRule, {
|
|
696
|
+
step: 'chart',
|
|
677
697
|
path: 'spec.helm.repo',
|
|
678
698
|
rules: ['ociRegistry'],
|
|
679
699
|
},
|
|
680
700
|
...(this.isSuseAppCollection ? [{
|
|
701
|
+
step: 'chart',
|
|
681
702
|
path: 'spec.helm.chart',
|
|
682
703
|
rules: ['required'],
|
|
683
704
|
}] : []),
|
|
684
705
|
{
|
|
706
|
+
step: 'chart',
|
|
685
707
|
path: 'spec.helm.version',
|
|
686
708
|
rules: this.isSuseAppCollection ? ['required', 'semanticVersion'] : ['semanticVersion'],
|
|
687
709
|
}];
|
|
688
710
|
break;
|
|
689
711
|
case SOURCE_TYPE.TARBALL:
|
|
690
|
-
this.fvFormRuleSets = [{
|
|
712
|
+
this.fvFormRuleSets = [nameRule, {
|
|
713
|
+
step: 'chart',
|
|
691
714
|
path: 'spec.helm.chart',
|
|
692
715
|
rules: ['urlRepository'],
|
|
693
716
|
}];
|
|
@@ -739,6 +762,26 @@ export default {
|
|
|
739
762
|
break;
|
|
740
763
|
}
|
|
741
764
|
},
|
|
765
|
+
|
|
766
|
+
async beforeNext(activeStep) {
|
|
767
|
+
if (activeStep.name !== 'basics' || !this.isCreate) {
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
await this.value.dryRunCreate({
|
|
772
|
+
type: this.value.type,
|
|
773
|
+
metadata: {
|
|
774
|
+
name: this.value.metadata.name,
|
|
775
|
+
namespace: this.value.metadata.namespace,
|
|
776
|
+
},
|
|
777
|
+
spec: {
|
|
778
|
+
helm: {
|
|
779
|
+
chart: 'placeholder',
|
|
780
|
+
repo: 'https://example.com',
|
|
781
|
+
},
|
|
782
|
+
}
|
|
783
|
+
});
|
|
784
|
+
},
|
|
742
785
|
},
|
|
743
786
|
};
|
|
744
787
|
</script>
|
|
@@ -753,11 +796,12 @@ export default {
|
|
|
753
796
|
:mode="mode"
|
|
754
797
|
:resource="value"
|
|
755
798
|
:subtypes="[]"
|
|
756
|
-
:validation-passed="
|
|
799
|
+
:validation-passed="fvFormIsValid"
|
|
757
800
|
:errors="errors"
|
|
758
801
|
:steps="!isView ? steps : undefined"
|
|
759
802
|
:finish-mode="'finish'"
|
|
760
803
|
:cancel-event="true"
|
|
804
|
+
:before-next="beforeNext"
|
|
761
805
|
class="wizard"
|
|
762
806
|
data-testid="helmop-cru-resource"
|
|
763
807
|
@cancel="onCancel"
|
|
@@ -773,6 +817,7 @@ export default {
|
|
|
773
817
|
:mode="mode"
|
|
774
818
|
:is-view="isView"
|
|
775
819
|
data-testid="helmop-metadata-tab"
|
|
820
|
+
:name-rules="fvGetAndReportPathRules('metadata.name')"
|
|
776
821
|
@update:value="$emit('input', $event)"
|
|
777
822
|
/>
|
|
778
823
|
</template>
|
|
@@ -1049,6 +1094,7 @@ export default {
|
|
|
1049
1094
|
>
|
|
1050
1095
|
<HelmOpAppCoConfigTab
|
|
1051
1096
|
v-bind="appCoConfigProps"
|
|
1097
|
+
:name-rules="fvGetAndReportPathRules('metadata.name')"
|
|
1052
1098
|
data-testid="helmop-appco-edit-config-tab"
|
|
1053
1099
|
v-on="appCoConfigListeners"
|
|
1054
1100
|
/>
|
|
@@ -32,13 +32,14 @@ export default {
|
|
|
32
32
|
const t = this.$store.getters['i18n/t'];
|
|
33
33
|
|
|
34
34
|
return {
|
|
35
|
-
setting:
|
|
36
|
-
description:
|
|
37
|
-
editHelp:
|
|
38
|
-
enumOptions:
|
|
39
|
-
canReset:
|
|
40
|
-
errors:
|
|
41
|
-
fvFormRuleSets:
|
|
35
|
+
setting: ALLOWED_SETTINGS[this.value.id],
|
|
36
|
+
description: t(`advancedSettings.descriptions.${ this.value.id }`),
|
|
37
|
+
editHelp: t(`advancedSettings.editHelp.${ this.value.id }`),
|
|
38
|
+
enumOptions: [],
|
|
39
|
+
canReset: false,
|
|
40
|
+
errors: [],
|
|
41
|
+
fvFormRuleSets: [],
|
|
42
|
+
customEditComponent: null
|
|
42
43
|
};
|
|
43
44
|
},
|
|
44
45
|
|
|
@@ -60,6 +61,14 @@ export default {
|
|
|
60
61
|
if (isServerUrl(this.value.id) && !this.value.default) {
|
|
61
62
|
this.canReset = false;
|
|
62
63
|
}
|
|
64
|
+
|
|
65
|
+
let component;
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
component = require(`@shell/edit/management.cattle.io.setting/${ this.value.id }.vue`).default;
|
|
69
|
+
} catch {}
|
|
70
|
+
|
|
71
|
+
this.customEditComponent = component;
|
|
63
72
|
},
|
|
64
73
|
|
|
65
74
|
computed: {
|
|
@@ -195,8 +204,22 @@ export default {
|
|
|
195
204
|
:label="err"
|
|
196
205
|
data-testid="setting-error-banner"
|
|
197
206
|
/>
|
|
198
|
-
|
|
199
|
-
|
|
207
|
+
<div
|
|
208
|
+
v-if="customEditComponent"
|
|
209
|
+
class="mt-20"
|
|
210
|
+
>
|
|
211
|
+
<component
|
|
212
|
+
:is="customEditComponent"
|
|
213
|
+
:setting-value="value.value"
|
|
214
|
+
:default-value="value.default"
|
|
215
|
+
:rules="fvGetAndReportPathRules('value')"
|
|
216
|
+
@update:setting-value="value.value=$event"
|
|
217
|
+
/>
|
|
218
|
+
</div>
|
|
219
|
+
<div
|
|
220
|
+
v-else
|
|
221
|
+
class="mt-20"
|
|
222
|
+
>
|
|
200
223
|
<div v-if="setting.kind === 'enum'">
|
|
201
224
|
<LabeledSelect
|
|
202
225
|
v-model:value="value.value"
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, computed, onMounted, toRef } from 'vue';
|
|
3
|
+
import { useStore } from 'vuex';
|
|
4
|
+
import LabeledSelect from '@shell/components/form/LabeledSelect.vue';
|
|
5
|
+
import { SECRET } from '@shell/config/types';
|
|
6
|
+
import { SECRET_TYPES } from '@shell/config/secret';
|
|
7
|
+
|
|
8
|
+
const AUTH_TYPES = [
|
|
9
|
+
SECRET_TYPES.DOCKER_JSON,
|
|
10
|
+
SECRET_TYPES.BASIC,
|
|
11
|
+
SECRET_TYPES.SSH,
|
|
12
|
+
SECRET_TYPES.RKE_AUTH_CONFIG
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const props = defineProps<{
|
|
16
|
+
settingValue: Record<string, any>;
|
|
17
|
+
defaultValue?: Record<string, any>;
|
|
18
|
+
rules?: Array<(value: any) => string | undefined>;
|
|
19
|
+
}>();
|
|
20
|
+
|
|
21
|
+
const emit = defineEmits(['update:settingValue']);
|
|
22
|
+
|
|
23
|
+
const store = useStore();
|
|
24
|
+
const settingValue = toRef(props, 'settingValue');
|
|
25
|
+
const defaultValue = toRef(props, 'defaultValue');
|
|
26
|
+
const secrets = ref<any[]>([]);
|
|
27
|
+
|
|
28
|
+
const secretOptions = computed(() => secrets.value
|
|
29
|
+
.filter((s) => AUTH_TYPES.includes(s._type))
|
|
30
|
+
.map((s) => {
|
|
31
|
+
const { dataPreview, subTypeDisplay, metadata } = s;
|
|
32
|
+
|
|
33
|
+
const label = subTypeDisplay && dataPreview ? `${ metadata.name } (${ subTypeDisplay }: ${ dataPreview })` : `${ metadata.name } (${ subTypeDisplay })`;
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
label,
|
|
37
|
+
value: s.metadata?.name
|
|
38
|
+
};
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const selectedSecrets = computed({
|
|
43
|
+
get: () => {
|
|
44
|
+
const sValue = settingValue.value || defaultValue.value || '';
|
|
45
|
+
|
|
46
|
+
return sValue.split(',').reduce((all: string[], secret: string) => {
|
|
47
|
+
if (!!secret.trim()) {
|
|
48
|
+
all.push(secret.trim());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return all;
|
|
52
|
+
}, []);
|
|
53
|
+
},
|
|
54
|
+
set: (neu: string[]) => {
|
|
55
|
+
const newSettingValue = neu?.length ? neu.join(',') : null;
|
|
56
|
+
|
|
57
|
+
emit('update:settingValue', newSettingValue);
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
onMounted(async() => {
|
|
62
|
+
const res = await store.dispatch('management/findAll', {
|
|
63
|
+
type: SECRET,
|
|
64
|
+
opt: { namespaced: 'cattle-system' },
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
secrets.value = Array.isArray(res) ? res : [];
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<template>
|
|
73
|
+
<LabeledSelect
|
|
74
|
+
id="pull-secrets"
|
|
75
|
+
v-model:value="selectedSecrets"
|
|
76
|
+
label="Image Pull Secrets"
|
|
77
|
+
:options="secretOptions"
|
|
78
|
+
:rules="rules"
|
|
79
|
+
:multiple="true"
|
|
80
|
+
/>
|
|
81
|
+
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import Loading from '@shell/components/Loading';
|
|
3
3
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
4
|
-
import { NORMAN
|
|
4
|
+
import { NORMAN } from '@shell/config/types';
|
|
5
5
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
6
6
|
import CruResource from '@shell/components/CruResource';
|
|
7
7
|
import NameNsDescription from '@shell/components/form/NameNsDescription';
|
|
@@ -50,11 +50,8 @@ export default {
|
|
|
50
50
|
const field = this.$store.getters['plugins/credentialFieldForDriver'](this.driverName);
|
|
51
51
|
|
|
52
52
|
this.newCredential = await this.$store.dispatch('rancher/create', {
|
|
53
|
-
type:
|
|
54
|
-
|
|
55
|
-
namespace: DEFAULT_WORKSPACE,
|
|
56
|
-
annotations: { [CAPI.CREDENTIAL_DRIVER]: this.driverName }
|
|
57
|
-
},
|
|
53
|
+
type: NORMAN.CLOUD_CREDENTIAL,
|
|
54
|
+
annotations: { [CAPI.CREDENTIAL_DRIVER]: this.driverName },
|
|
58
55
|
[`${ field }credentialConfig`]: {}
|
|
59
56
|
});
|
|
60
57
|
|
|
@@ -216,12 +213,6 @@ export default {
|
|
|
216
213
|
}
|
|
217
214
|
}
|
|
218
215
|
|
|
219
|
-
if ( this.newCredential.metadata.name ) {
|
|
220
|
-
delete this.newCredential.metadata.generateName;
|
|
221
|
-
} else {
|
|
222
|
-
this.newCredential.metadata.generateName = 'cloud-credential-';
|
|
223
|
-
}
|
|
224
|
-
|
|
225
216
|
try {
|
|
226
217
|
const res = await this.newCredential.save();
|
|
227
218
|
|
|
@@ -806,4 +806,22 @@ describe('component: rke2', () => {
|
|
|
806
806
|
expect(wrapper.vm.value.spec.rkeConfig.machineGlobalConfig[INGRESS_CONTROLLER]).toBe(INGRESS_NGINX);
|
|
807
807
|
});
|
|
808
808
|
});
|
|
809
|
+
|
|
810
|
+
describe('computed: canEditAsYaml', () => {
|
|
811
|
+
it('should return false when isUpstreamCAPIProvider is true', () => {
|
|
812
|
+
const vm = { isUpstreamCAPIProvider: true } as any;
|
|
813
|
+
|
|
814
|
+
const canEditAsYaml = rke2.computed!.canEditAsYaml.call(vm);
|
|
815
|
+
|
|
816
|
+
expect(canEditAsYaml).toBe(false);
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
it('should return true when isUpstreamCAPIProvider is false', () => {
|
|
820
|
+
const vm = { isUpstreamCAPIProvider: false } as any;
|
|
821
|
+
|
|
822
|
+
const canEditAsYaml = rke2.computed!.canEditAsYaml.call(vm);
|
|
823
|
+
|
|
824
|
+
expect(canEditAsYaml).toBe(true);
|
|
825
|
+
});
|
|
826
|
+
});
|
|
809
827
|
});
|
|
@@ -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
|
|
@@ -919,6 +919,10 @@ export default {
|
|
|
919
919
|
return this.needCredential && !this.credentialId;
|
|
920
920
|
},
|
|
921
921
|
|
|
922
|
+
canEditAsYaml() {
|
|
923
|
+
return !(this.isUpstreamCAPIProvider);
|
|
924
|
+
},
|
|
925
|
+
|
|
922
926
|
overallFormValidationPassed() {
|
|
923
927
|
return this.validationPassed &&
|
|
924
928
|
this.fvFormIsValid &&
|
|
@@ -1118,7 +1122,6 @@ export default {
|
|
|
1118
1122
|
|
|
1119
1123
|
this.rkeConfig.etcd.disableSnapshots = disableSnapshots;
|
|
1120
1124
|
}
|
|
1121
|
-
|
|
1122
1125
|
// Namespaces if required - this is mainly for custom provisioners via extensions that want
|
|
1123
1126
|
// to allow creating their resources in a different namespace
|
|
1124
1127
|
if (this.needsNamespace) {
|
|
@@ -1626,7 +1629,7 @@ export default {
|
|
|
1626
1629
|
const isIpv6 = this.hasOnlyIpv6Pools;
|
|
1627
1630
|
|
|
1628
1631
|
const flannelMasqInvalid = isIpv6 && isK3s && !flannelMasqEnabled;
|
|
1629
|
-
const stackPrefInvalid = (isIpv6 && stackPreference !== STACK_PREFS.IPV6) || (isDualStack &&
|
|
1632
|
+
const stackPrefInvalid = (isIpv6 && stackPreference !== STACK_PREFS.IPV6) || (isDualStack && stackPreference !== STACK_PREFS.DUAL);
|
|
1630
1633
|
|
|
1631
1634
|
const clusterCIDRInvalid = (isIpv6 || isDualStack) && !clusterCIDR.includes(':');
|
|
1632
1635
|
const serviceCIDRInvalid = (isIpv6 || isDualStack) && !serviceCIDR.includes(':');
|
|
@@ -2459,6 +2462,7 @@ export default {
|
|
|
2459
2462
|
:done-route="doneRoute"
|
|
2460
2463
|
:apply-hooks="applyHooks"
|
|
2461
2464
|
:generate-yaml="generateYaml"
|
|
2465
|
+
:can-yaml="canEditAsYaml"
|
|
2462
2466
|
class="rke2"
|
|
2463
2467
|
component-testid="rke2-custom-create"
|
|
2464
2468
|
@done="done"
|
|
@@ -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"
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
3
2
|
import { Banner } from '@components/Banner';
|
|
4
|
-
import
|
|
5
|
-
import SelectOrCreateAuthSecret from '@shell/components/form/SelectOrCreateAuthSecret';
|
|
3
|
+
import PrivateRegistry from '@shell/components/form/PrivateRegistry.vue';
|
|
6
4
|
import AdvancedSection from '@shell/components/AdvancedSection.vue';
|
|
7
5
|
import RegistryConfigs from '@shell/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs';
|
|
8
6
|
import RegistryMirrors from '@shell/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryMirrors';
|
|
@@ -10,10 +8,8 @@ import RegistryMirrors from '@shell/edit/provisioning.cattle.io.cluster/tabs/reg
|
|
|
10
8
|
export default {
|
|
11
9
|
emits: ['custom-registry-changed', 'registry-host-changed', 'registry-secret-changed', 'input', 'update-configs-changed', 'registry-validation-changed'],
|
|
12
10
|
components: {
|
|
13
|
-
LabeledInput,
|
|
14
11
|
Banner,
|
|
15
|
-
|
|
16
|
-
SelectOrCreateAuthSecret,
|
|
12
|
+
PrivateRegistry,
|
|
17
13
|
AdvancedSection,
|
|
18
14
|
RegistryConfigs,
|
|
19
15
|
RegistryMirrors
|
|
@@ -65,55 +61,18 @@ export default {
|
|
|
65
61
|
<div class="row">
|
|
66
62
|
<h3>{{ t('cluster.privateRegistry.label') }}</h3>
|
|
67
63
|
</div>
|
|
68
|
-
<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
:value="showCustomRegistryInput"
|
|
81
|
-
:mode="mode"
|
|
82
|
-
:label="t('cluster.privateRegistry.label')"
|
|
83
|
-
data-testid="registries-enable-checkbox"
|
|
84
|
-
@update:value="$emit('custom-registry-changed', $event)"
|
|
85
|
-
/>
|
|
86
|
-
</div>
|
|
87
|
-
<div
|
|
88
|
-
v-if="showCustomRegistryInput"
|
|
89
|
-
class="row mt-20"
|
|
90
|
-
>
|
|
91
|
-
<div class="col span-6">
|
|
92
|
-
<LabeledInput
|
|
93
|
-
:value="registryHost"
|
|
94
|
-
:mode="mode"
|
|
95
|
-
label-key="catalog.chart.registry.custom.inputLabel"
|
|
96
|
-
placeholder-key="catalog.chart.registry.custom.placeholder"
|
|
97
|
-
:min-height="30"
|
|
98
|
-
data-testid="registry-host-input"
|
|
99
|
-
@update:value="$emit('registry-host-changed', $event)"
|
|
100
|
-
/>
|
|
101
|
-
<SelectOrCreateAuthSecret
|
|
102
|
-
:value="registrySecret"
|
|
103
|
-
:register-before-hook="registerBeforeHook"
|
|
104
|
-
:hook-priority="1"
|
|
105
|
-
:mode="mode"
|
|
106
|
-
in-store="management"
|
|
107
|
-
:allow-ssh="false"
|
|
108
|
-
:allow-rke="true"
|
|
109
|
-
:vertical="true"
|
|
110
|
-
:namespace="value.metadata.namespace"
|
|
111
|
-
generate-name="registryconfig-auth-"
|
|
112
|
-
:cache-secrets="true"
|
|
113
|
-
@update:value="$emit('registry-secret-changed', $event)"
|
|
114
|
-
/>
|
|
115
|
-
</div>
|
|
116
|
-
</div>
|
|
64
|
+
<PrivateRegistry
|
|
65
|
+
:value="registryHost"
|
|
66
|
+
:enabled="showCustomRegistryInput"
|
|
67
|
+
:mode="mode"
|
|
68
|
+
:pull-secret="registrySecret"
|
|
69
|
+
:register-before-hook="registerBeforeHook"
|
|
70
|
+
checkbox-test-id="registries-enable-checkbox"
|
|
71
|
+
input-test-id="registry-host-input"
|
|
72
|
+
@update:value="$emit('registry-host-changed', $event)"
|
|
73
|
+
@update:enabled="$emit('custom-registry-changed', $event)"
|
|
74
|
+
@update:pull-secret="$emit('registry-secret-changed', $event)"
|
|
75
|
+
/>
|
|
117
76
|
<div
|
|
118
77
|
class="row"
|
|
119
78
|
>
|
|
@@ -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;
|