@rancher/shell 3.0.0 → 3.0.1-rc.2
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/brand/harvester/favicon.png +0 -0
- package/assets/brand/harvester/metadata.json +3 -0
- package/assets/images/pl/harvester.svg +1 -0
- package/assets/translations/en-us.yaml +26 -8
- package/assets/translations/zh-hans.yaml +1 -1
- package/components/BrandImage.vue +5 -1
- package/components/CopyToClipboardText.vue +2 -0
- package/components/CruResourceFooter.vue +1 -0
- package/components/DetailTop.vue +1 -1
- package/components/ExplorerMembers.vue +5 -1
- package/components/ExplorerProjectsNamespaces.vue +39 -15
- package/components/HardwareResourceGauge.vue +12 -2
- package/components/InputOrDisplay.vue +6 -2
- package/components/LandingPagePreference.vue +2 -2
- package/components/MessageLink.vue +1 -1
- package/components/ResourceDetail/Masthead.vue +22 -1
- package/components/ResourceDetail/index.vue +2 -8
- package/components/ResourceTable.vue +14 -6
- package/components/ResourceYaml.vue +1 -1
- package/components/SideNav.vue +6 -4
- package/components/TableDataUserIcon.vue +1 -1
- package/components/fleet/FleetRepos.vue +0 -7
- package/components/form/ArrayList.vue +5 -1
- package/components/form/ArrayListSelect.vue +5 -1
- package/components/form/KeyValue.vue +1 -1
- package/components/form/LabeledSelect.vue +26 -6
- package/components/form/Password.vue +7 -1
- package/components/form/UnitInput.vue +10 -1
- package/components/form/__tests__/UnitInput.test.ts +1 -0
- package/components/formatter/ClusterProvider.vue +3 -3
- package/components/formatter/ImagePercentageBar.vue +1 -1
- package/components/formatter/Si.vue +5 -1
- package/components/formatter/Translate.vue +1 -1
- package/components/nav/Header.vue +29 -5
- package/components/nav/NamespaceFilter.vue +5 -8
- package/components/nav/TopLevelMenu.vue +16 -14
- package/config/labels-annotations.js +2 -0
- package/config/table-headers.js +15 -0
- package/config/types.js +3 -0
- package/detail/fleet.cattle.io.bundle.vue +5 -68
- package/detail/fleet.cattle.io.gitrepo.vue +2 -1
- package/directives/clean-tooltip.js +4 -4
- package/edit/constraints.gatekeeper.sh.constraint/index.vue +5 -2
- package/edit/logging-flow/Match.vue +75 -42
- package/edit/logging-flow/index.vue +89 -10
- package/edit/logging.banzaicloud.io.output/index.vue +2 -2
- package/edit/management.cattle.io.project.vue +2 -2
- package/edit/namespace.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +17 -7
- package/edit/provisioning.cattle.io.cluster/index.vue +2 -1
- package/edit/provisioning.cattle.io.cluster/rke2.vue +1 -3
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +20 -6
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryMirrors.vue +1 -1
- package/list/harvesterhci.io.management.cluster.vue +244 -0
- package/list/namespace.vue +16 -4
- package/models/__tests__/management.cattle.io.cluster.test.ts +45 -3
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +0 -86
- package/models/fleet.cattle.io.bundle.js +3 -1
- package/models/fleet.cattle.io.gitrepo.js +46 -48
- package/models/k8s.cni.cncf.io.networkattachmentdefinition.js +88 -0
- package/models/management.cattle.io.cluster.js +26 -5
- package/models/management.cattle.io.setting.js +25 -0
- package/models/provisioning.cattle.io.cluster.js +5 -14
- package/models/storage.k8s.io.storageclass.js +15 -4
- package/package.json +8 -6
- package/pages/auth/login.vue +8 -2
- package/pages/auth/setup.vue +1 -1
- package/pages/c/_cluster/fleet/index.vue +2 -4
- package/pages/c/_cluster/settings/brand.vue +4 -1
- package/pages/prefs.vue +22 -10
- package/plugins/dashboard-store/resource-class.js +11 -3
- package/plugins/steve/steve-pagination-utils.ts +1 -1
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +7 -2
- package/scripts/extension/parse-tag-name +19 -12
- package/scripts/publish-shell.sh +10 -2
- package/scripts/test-plugins-build.sh +8 -9
- package/scripts/typegen.sh +2 -0
- package/store/features.js +1 -0
- package/store/i18n.js +5 -1
- package/store/prefs.js +8 -0
- package/types/resources/fleet.d.ts +40 -0
- package/types/shell/index.d.ts +524 -396
- package/utils/auth.js +1 -1
- package/utils/create-yaml.js +1 -1
- package/utils/favicon.js +2 -0
- package/utils/fleet.ts +159 -0
- package/utils/gc/gc.ts +1 -1
- package/utils/v-sphere.ts +31 -0
- package/utils/validators/cron-schedule.js +1 -1
- package/utils/validators/formRules/index.ts +1 -1
- package/utils/version.js +1 -1
- package/vue.config.js +2 -2
|
@@ -13,10 +13,10 @@ function purifyContent(value) {
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
function
|
|
16
|
+
function beforeMount(el, { value, oldValue, modifiers }) {
|
|
17
17
|
const purifiedValue = purifyContent(value);
|
|
18
18
|
|
|
19
|
-
VTooltip.
|
|
19
|
+
VTooltip.beforeMount(
|
|
20
20
|
el,
|
|
21
21
|
{
|
|
22
22
|
value: purifiedValue, oldValue, modifiers
|
|
@@ -25,8 +25,8 @@ function bind(el, { value, oldValue, modifiers }) {
|
|
|
25
25
|
|
|
26
26
|
const cleanTooltipDirective = {
|
|
27
27
|
...VTooltip,
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
beforeMount,
|
|
29
|
+
updated: beforeMount,
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
export default cleanTooltipDirective;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import merge from 'lodash/merge';
|
|
3
3
|
import { ucFirst } from '@shell/utils/string';
|
|
4
|
-
import { isSimpleKeyValue } from '@shell/utils/object';
|
|
4
|
+
import { isSimpleKeyValue, set } from '@shell/utils/object';
|
|
5
5
|
import { _CREATE, _VIEW } from '@shell/config/query-params';
|
|
6
6
|
import { SCHEMA, NAMESPACE } from '@shell/config/types';
|
|
7
7
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
@@ -222,6 +222,9 @@ export default {
|
|
|
222
222
|
this.value.spec.match.namespaces = [];
|
|
223
223
|
this.value.spec.match.excludedNamespaces = [];
|
|
224
224
|
}
|
|
225
|
+
},
|
|
226
|
+
setParameters(e) {
|
|
227
|
+
return set(this.value.spec, 'parameters', e);
|
|
225
228
|
}
|
|
226
229
|
}
|
|
227
230
|
};
|
|
@@ -356,7 +359,7 @@ export default {
|
|
|
356
359
|
v-model:value="parametersYaml"
|
|
357
360
|
class="yaml-editor"
|
|
358
361
|
:editor-mode="editorMode"
|
|
359
|
-
@newObject="
|
|
362
|
+
@newObject="setParameters"
|
|
360
363
|
/>
|
|
361
364
|
</Tab>
|
|
362
365
|
</Tabbed>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import KeyValue from '@shell/components/form/KeyValue';
|
|
3
3
|
import Select from '@shell/components/form/Select';
|
|
4
4
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
5
|
+
import { HARVESTER_NAME as VIRTUAL } from '@shell/config/features';
|
|
5
6
|
|
|
6
7
|
export default {
|
|
7
8
|
emits: ['remove'],
|
|
@@ -39,6 +40,12 @@ export default {
|
|
|
39
40
|
}
|
|
40
41
|
},
|
|
41
42
|
|
|
43
|
+
computed: {
|
|
44
|
+
isHarvester() {
|
|
45
|
+
return this.$store.getters['currentProduct'].inStore === VIRTUAL;
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
|
|
42
49
|
methods: {
|
|
43
50
|
update() {},
|
|
44
51
|
|
|
@@ -51,19 +58,22 @@ export default {
|
|
|
51
58
|
|
|
52
59
|
<template>
|
|
53
60
|
<div>
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
<template v-if="!isHarvester">
|
|
62
|
+
<KeyValue
|
|
63
|
+
v-model:value="value.labels"
|
|
64
|
+
:title="value.select ? t('logging.flow.matches.pods.title.include') : t('logging.flow.matches.pods.title.exclude')"
|
|
65
|
+
:mode="mode"
|
|
66
|
+
:initial-empty-row="true"
|
|
67
|
+
:read-allowed="false"
|
|
68
|
+
:title-add="true"
|
|
69
|
+
protip=""
|
|
70
|
+
:key-label="t('logging.flow.matches.pods.keyLabel')"
|
|
71
|
+
:value-label="t('logging.flow.matches.pods.valueLabel')"
|
|
72
|
+
:add-label="t('logging.flow.matches.pods.addLabel')"
|
|
73
|
+
/>
|
|
74
|
+
<div class="spacer" />
|
|
75
|
+
</template>
|
|
76
|
+
|
|
67
77
|
<h3>
|
|
68
78
|
{{ value.select ? t('logging.flow.matches.nodes.title.include') : t('logging.flow.matches.nodes.title.exclude') }}
|
|
69
79
|
</h3>
|
|
@@ -83,48 +93,71 @@ export default {
|
|
|
83
93
|
/>
|
|
84
94
|
</div>
|
|
85
95
|
</div>
|
|
86
|
-
<div
|
|
87
|
-
<h3>
|
|
88
|
-
{{ value.select ? t('logging.flow.matches.containerNames.title.include') : t('logging.flow.matches.containerNames.title.exclude') }}
|
|
89
|
-
</h3>
|
|
90
|
-
<div class="row">
|
|
91
|
-
<div class="col span-12">
|
|
92
|
-
<LabeledSelect
|
|
93
|
-
v-model:value="value.container_names"
|
|
94
|
-
:mode="mode"
|
|
95
|
-
:options="[]"
|
|
96
|
-
:disabled="false"
|
|
97
|
-
:placeholder="t('logging.flow.matches.containerNames.placeholder')"
|
|
98
|
-
:multiple="true"
|
|
99
|
-
:taggable="true"
|
|
100
|
-
:clearable="true"
|
|
101
|
-
:searchable="true"
|
|
102
|
-
:close-on-select="false"
|
|
103
|
-
no-options-label-key="logging.flow.matches.containerNames.enter"
|
|
104
|
-
placement="top"
|
|
105
|
-
/>
|
|
106
|
-
</div>
|
|
107
|
-
</div>
|
|
108
|
-
<div v-if="isClusterFlow">
|
|
96
|
+
<div v-if="!isHarvester">
|
|
109
97
|
<div class="spacer" />
|
|
110
98
|
<h3>
|
|
111
|
-
{{ value.select ? t('logging.flow.matches.
|
|
99
|
+
{{ value.select ? t('logging.flow.matches.containerNames.title.include') : t('logging.flow.matches.containerNames.title.exclude') }}
|
|
112
100
|
</h3>
|
|
113
101
|
<div class="row">
|
|
114
102
|
<div class="col span-12">
|
|
115
|
-
<
|
|
116
|
-
v-model:value="value.
|
|
117
|
-
|
|
118
|
-
:options="
|
|
119
|
-
:
|
|
103
|
+
<LabeledSelect
|
|
104
|
+
v-model:value="value.container_names"
|
|
105
|
+
:mode="mode"
|
|
106
|
+
:options="[]"
|
|
107
|
+
:disabled="false"
|
|
108
|
+
:placeholder="t('logging.flow.matches.containerNames.placeholder')"
|
|
120
109
|
:multiple="true"
|
|
121
110
|
:taggable="true"
|
|
122
111
|
:clearable="true"
|
|
112
|
+
:searchable="true"
|
|
123
113
|
:close-on-select="false"
|
|
114
|
+
no-options-label-key="logging.flow.matches.containerNames.enter"
|
|
124
115
|
placement="top"
|
|
125
116
|
/>
|
|
126
117
|
</div>
|
|
127
118
|
</div>
|
|
119
|
+
<div v-if="isClusterFlow">
|
|
120
|
+
<div class="spacer" />
|
|
121
|
+
<h3>
|
|
122
|
+
{{ value.select ? t('logging.flow.matches.containerNames.title.include') : t('logging.flow.matches.containerNames.title.exclude') }}
|
|
123
|
+
</h3>
|
|
124
|
+
<div class="row">
|
|
125
|
+
<div class="col span-12">
|
|
126
|
+
<Select
|
|
127
|
+
v-model:value="value.namespaces"
|
|
128
|
+
class="lg"
|
|
129
|
+
:options="namespaces"
|
|
130
|
+
:placeholder="t('logging.flow.matches.namespaces.placeholder')"
|
|
131
|
+
:multiple="true"
|
|
132
|
+
:taggable="true"
|
|
133
|
+
:clearable="true"
|
|
134
|
+
:searchable="true"
|
|
135
|
+
:close-on-select="false"
|
|
136
|
+
no-options-label-key="logging.flow.matches.containerNames.enter"
|
|
137
|
+
placement="top"
|
|
138
|
+
/>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
<div class="spacer" />
|
|
142
|
+
<h3>
|
|
143
|
+
{{ value.select ? t('logging.flow.matches.namespaces.title.include') : t('logging.flow.matches.namespaces.title.exclude') }}
|
|
144
|
+
</h3>
|
|
145
|
+
<div class="row">
|
|
146
|
+
<div class="col span-12">
|
|
147
|
+
<Select
|
|
148
|
+
v-model="value.namespaces"
|
|
149
|
+
class="lg"
|
|
150
|
+
:options="namespaces"
|
|
151
|
+
:placeholder="t('logging.flow.matches.namespaces.placeholder')"
|
|
152
|
+
:multiple="true"
|
|
153
|
+
:taggable="true"
|
|
154
|
+
:clearable="true"
|
|
155
|
+
:close-on-select="false"
|
|
156
|
+
placement="top"
|
|
157
|
+
/>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
128
161
|
</div>
|
|
129
162
|
</div>
|
|
130
163
|
</template>
|
|
@@ -6,20 +6,28 @@ import Loading from '@shell/components/Loading';
|
|
|
6
6
|
import NameNsDescription from '@shell/components/form/NameNsDescription';
|
|
7
7
|
import Tabbed from '@shell/components/Tabbed';
|
|
8
8
|
import Tab from '@shell/components/Tabbed/Tab';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
LOGGING, NAMESPACE, NODE, POD, SCHEMA
|
|
11
|
+
} from '@shell/config/types';
|
|
10
12
|
import jsyaml from 'js-yaml';
|
|
11
13
|
import { createYaml } from '@shell/utils/create-yaml';
|
|
12
14
|
import YamlEditor, { EDITOR_MODES } from '@shell/components/YamlEditor';
|
|
13
15
|
import { allHash } from '@shell/utils/promise';
|
|
14
|
-
import { isArray } from '@shell/utils/array';
|
|
16
|
+
import { isArray, uniq } from '@shell/utils/array';
|
|
15
17
|
import { matchRuleIsPopulated } from '@shell/models/logging.banzaicloud.io.flow';
|
|
16
18
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
17
19
|
import { clone } from '@shell/utils/object';
|
|
18
20
|
import isEmpty from 'lodash/isEmpty';
|
|
19
21
|
import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
|
|
20
22
|
import { exceptionToErrorsArray } from '@shell/utils/error';
|
|
23
|
+
import { HARVESTER_NAME as VIRTUAL } from '@shell/config/features';
|
|
21
24
|
import Match from './Match';
|
|
22
25
|
|
|
26
|
+
const FLOW_LOGGING = 'Logging';
|
|
27
|
+
const FLOW_AUDIT = 'Audit';
|
|
28
|
+
const FLOW_EVENT = 'Event';
|
|
29
|
+
const FLOW_TYPE = [FLOW_LOGGING, FLOW_AUDIT, FLOW_EVENT];
|
|
30
|
+
|
|
23
31
|
function emptyMatch(include = true) {
|
|
24
32
|
const rule = {
|
|
25
33
|
select: !!include,
|
|
@@ -53,14 +61,17 @@ export default {
|
|
|
53
61
|
inheritAttrs: false,
|
|
54
62
|
|
|
55
63
|
async fetch() {
|
|
56
|
-
const
|
|
57
|
-
const
|
|
64
|
+
const currentCluster = this.$store.getters['currentCluster'];
|
|
65
|
+
const inStore = currentCluster.isHarvester ? VIRTUAL : 'cluster';
|
|
66
|
+
const hasAccessToClusterOutputs = this.$store.getters[`${ inStore }/schemaFor`](LOGGING.CLUSTER_OUTPUT);
|
|
67
|
+
const hasAccessToOutputs = this.$store.getters[`${ inStore }/schemaFor`](LOGGING.OUTPUT);
|
|
58
68
|
const hasAccessToNamespaces = this.$store.getters[`cluster/schemaFor`](NAMESPACE);
|
|
59
|
-
const hasAccessToNodes = this.$store.getters[
|
|
69
|
+
const hasAccessToNodes = this.$store.getters[`${ inStore }/schemaFor`](NODE);
|
|
70
|
+
const hasAccessToPods = this.$store.getters[`${ inStore }/schemaFor`](POD);
|
|
60
71
|
const isFlow = this.value.type === LOGGING.FLOW;
|
|
61
72
|
|
|
62
73
|
const getAllOrDefault = (type, hasAccess) => {
|
|
63
|
-
return hasAccess ? this.$store.dispatch(
|
|
74
|
+
return hasAccess ? this.$store.dispatch(`${ inStore }/findAll`, { type }) : Promise.resolve([]);
|
|
64
75
|
};
|
|
65
76
|
|
|
66
77
|
const hash = await allHash({
|
|
@@ -68,6 +79,7 @@ export default {
|
|
|
68
79
|
allClusterOutputs: getAllOrDefault(LOGGING.CLUSTER_OUTPUT, hasAccessToClusterOutputs),
|
|
69
80
|
allNamespaces: getAllOrDefault(NAMESPACE, hasAccessToNamespaces),
|
|
70
81
|
allNodes: getAllOrDefault(NODE, hasAccessToNodes),
|
|
82
|
+
allPods: getAllOrDefault(POD, hasAccessToPods),
|
|
71
83
|
});
|
|
72
84
|
|
|
73
85
|
for ( const k of Object.keys(hash) ) {
|
|
@@ -76,7 +88,9 @@ export default {
|
|
|
76
88
|
},
|
|
77
89
|
|
|
78
90
|
data() {
|
|
79
|
-
const
|
|
91
|
+
const currentCluster = this.$store.getters['currentCluster'];
|
|
92
|
+
const inStore = currentCluster.isHarvester ? VIRTUAL : 'cluster';
|
|
93
|
+
const schemas = this.$store.getters[`${ inStore }/all`](SCHEMA);
|
|
80
94
|
let filtersYaml;
|
|
81
95
|
|
|
82
96
|
this.value.spec = this.value.spec || {};
|
|
@@ -124,7 +138,8 @@ export default {
|
|
|
124
138
|
filtersYaml,
|
|
125
139
|
initialFiltersYaml: filtersYaml,
|
|
126
140
|
globalOutputRefs,
|
|
127
|
-
localOutputRefs
|
|
141
|
+
localOutputRefs,
|
|
142
|
+
loggingType: clone(this.value.loggingType || FLOW_LOGGING)
|
|
128
143
|
};
|
|
129
144
|
},
|
|
130
145
|
|
|
@@ -150,7 +165,17 @@ export default {
|
|
|
150
165
|
return true;
|
|
151
166
|
}
|
|
152
167
|
|
|
153
|
-
|
|
168
|
+
const isEqualNs = output.namespace === this.value.namespace;
|
|
169
|
+
|
|
170
|
+
if (!this.isHarvester) {
|
|
171
|
+
return isEqualNs;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (this.loggingType === FLOW_AUDIT) {
|
|
175
|
+
return output.loggingType === FLOW_AUDIT && isEqualNs;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return output.loggingType !== FLOW_AUDIT && isEqualNs;
|
|
154
179
|
}).map((x) => {
|
|
155
180
|
return { label: x.metadata.name, value: x.metadata.name };
|
|
156
181
|
});
|
|
@@ -165,7 +190,17 @@ export default {
|
|
|
165
190
|
|
|
166
191
|
return this.allClusterOutputs
|
|
167
192
|
.filter((clusterOutput) => {
|
|
168
|
-
|
|
193
|
+
const isEqualNs = clusterOutput.namespace === 'cattle-logging-system';
|
|
194
|
+
|
|
195
|
+
if (!this.isHarvester) {
|
|
196
|
+
return isEqualNs;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (this.loggingType === FLOW_AUDIT) {
|
|
200
|
+
return clusterOutput.loggingType === FLOW_AUDIT && isEqualNs;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return clusterOutput.loggingType !== FLOW_AUDIT && isEqualNs;
|
|
169
204
|
})
|
|
170
205
|
.map((clusterOutput) => {
|
|
171
206
|
return { label: clusterOutput.metadata.name, value: clusterOutput.metadata.name };
|
|
@@ -204,6 +239,25 @@ export default {
|
|
|
204
239
|
return out;
|
|
205
240
|
},
|
|
206
241
|
|
|
242
|
+
containerChoices() {
|
|
243
|
+
const out = [];
|
|
244
|
+
|
|
245
|
+
for ( const pod of this.allPods ) {
|
|
246
|
+
for ( const c of (pod.spec?.containers || []) ) {
|
|
247
|
+
out.push(c.name);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return uniq(out).sort();
|
|
252
|
+
},
|
|
253
|
+
|
|
254
|
+
isHarvester() {
|
|
255
|
+
return this.$store.getters['currentProduct'].inStore === VIRTUAL;
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
flowTypeOptions() {
|
|
259
|
+
return FLOW_TYPE;
|
|
260
|
+
},
|
|
207
261
|
},
|
|
208
262
|
|
|
209
263
|
watch: {
|
|
@@ -312,6 +366,20 @@ export default {
|
|
|
312
366
|
if (this.value.spec.match && this.isMatchEmpty(this.value.spec.match)) {
|
|
313
367
|
delete this.value.spec['match'];
|
|
314
368
|
}
|
|
369
|
+
|
|
370
|
+
if (this.loggingType === FLOW_AUDIT) {
|
|
371
|
+
this.value.spec['loggingRef'] = 'harvester-kube-audit-log-ref';
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (this.loggingType === FLOW_EVENT) {
|
|
375
|
+
const eventSelector = { select: { labels: { 'app.kubernetes.io/name': 'event-tailer' } } };
|
|
376
|
+
|
|
377
|
+
if (!this.value.spec.match) {
|
|
378
|
+
this.value.spec['match'] = [eventSelector];
|
|
379
|
+
} else {
|
|
380
|
+
this.value.spec.match.push(eventSelector);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
315
383
|
},
|
|
316
384
|
onYamlEditorReady(cm) {
|
|
317
385
|
cm.getMode().fold = 'yamlcomments';
|
|
@@ -359,10 +427,21 @@ export default {
|
|
|
359
427
|
:weight="3"
|
|
360
428
|
>
|
|
361
429
|
<Banner
|
|
430
|
+
v-if="!isHarvester"
|
|
362
431
|
color="info"
|
|
363
432
|
class="mt-0"
|
|
364
433
|
:label="t('logging.flow.matches.banner')"
|
|
365
434
|
/>
|
|
435
|
+
<div v-if="isHarvester">
|
|
436
|
+
<LabeledSelect
|
|
437
|
+
v-model:value="loggingType"
|
|
438
|
+
class="mb-20"
|
|
439
|
+
:options="flowTypeOptions"
|
|
440
|
+
:mode="mode"
|
|
441
|
+
:disabled="!isCreate"
|
|
442
|
+
:label="t('generic.type')"
|
|
443
|
+
/>
|
|
444
|
+
</div>
|
|
366
445
|
<ArrayListGrouped
|
|
367
446
|
v-model:value="matches"
|
|
368
447
|
:add-label="t('ingress.rules.addRule')"
|
|
@@ -199,13 +199,13 @@ export default {
|
|
|
199
199
|
v-if="hasMultipleProvidersSelected"
|
|
200
200
|
color="info"
|
|
201
201
|
>
|
|
202
|
-
|
|
202
|
+
{{ t('logging.output.tips.singleProvider') }}
|
|
203
203
|
</Banner>
|
|
204
204
|
<Banner
|
|
205
205
|
v-else-if="!value.allProvidersSupported"
|
|
206
206
|
color="info"
|
|
207
207
|
>
|
|
208
|
-
|
|
208
|
+
{{ t('logging.output.tips.multipleProviders') }}
|
|
209
209
|
</Banner>
|
|
210
210
|
<Tabbed
|
|
211
211
|
v-else
|
|
@@ -52,7 +52,7 @@ export default {
|
|
|
52
52
|
};
|
|
53
53
|
},
|
|
54
54
|
computed: {
|
|
55
|
-
...mapGetters(['currentCluster']),
|
|
55
|
+
...mapGetters(['currentCluster', 'isStandaloneHarvester']),
|
|
56
56
|
|
|
57
57
|
canViewMembers() {
|
|
58
58
|
return canViewProjectMembershipEditor(this.$store);
|
|
@@ -222,7 +222,7 @@ export default {
|
|
|
222
222
|
<ResourceQuota
|
|
223
223
|
:value="value"
|
|
224
224
|
:mode="canEditTabElements"
|
|
225
|
-
:types="
|
|
225
|
+
:types="isStandaloneHarvester ? HARVESTER_TYPES : RANCHER_TYPES"
|
|
226
226
|
@remove="removeQuota"
|
|
227
227
|
/>
|
|
228
228
|
</Tab>
|
package/edit/namespace.vue
CHANGED
|
@@ -15,9 +15,9 @@ import MoveModal from '@shell/components/MoveModal';
|
|
|
15
15
|
import ResourceQuota from '@shell/components/form/ResourceQuota/Namespace';
|
|
16
16
|
import Loading from '@shell/components/Loading';
|
|
17
17
|
import { HARVESTER_TYPES, RANCHER_TYPES } from '@shell/components/form/ResourceQuota/shared';
|
|
18
|
-
import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
|
|
19
18
|
import Labels from '@shell/components/form/Labels';
|
|
20
19
|
import { randomStr } from '@shell/utils/string';
|
|
20
|
+
import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
|
|
21
21
|
|
|
22
22
|
export default {
|
|
23
23
|
emits: ['input'],
|
|
@@ -113,7 +113,7 @@ describe('component: DirectoryConfig', () => {
|
|
|
113
113
|
expect(wrapper.vm.value.k8sDistro).toStrictEqual(k8sDistroValue);
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
-
it('should render the component with configuration being an empty object, without errors and radio be of value DATA_DIR_RADIO_OPTIONS.
|
|
116
|
+
it('should render the component with configuration being an empty object, without errors and radio be of value DATA_DIR_RADIO_OPTIONS.CUSTOM (edit scenario)', () => {
|
|
117
117
|
const newMountOptions = clone(mountOptions);
|
|
118
118
|
|
|
119
119
|
newMountOptions.propsData.value = {};
|
|
@@ -131,17 +131,21 @@ describe('component: DirectoryConfig', () => {
|
|
|
131
131
|
const k8sDistroInput = wrapper.find('[data-testid="rke2-directory-config-k8sDistro-data-dir"]');
|
|
132
132
|
|
|
133
133
|
expect(title.exists()).toBe(true);
|
|
134
|
-
expect(radioInput.
|
|
134
|
+
expect(radioInput.isVisible()).toBe(false);
|
|
135
135
|
|
|
136
|
-
expect(wrapper.vm.dataConfigRadioValue).toBe(DATA_DIR_RADIO_OPTIONS.
|
|
136
|
+
expect(wrapper.vm.dataConfigRadioValue).toBe(DATA_DIR_RADIO_OPTIONS.CUSTOM);
|
|
137
137
|
|
|
138
138
|
// since we have all of the vars empty, then the inputs should not be there
|
|
139
|
-
expect(systemAgentInput.exists()).toBe(
|
|
140
|
-
expect(provisioningInput.exists()).toBe(
|
|
141
|
-
expect(k8sDistroInput.exists()).toBe(
|
|
139
|
+
expect(systemAgentInput.exists()).toBe(true);
|
|
140
|
+
expect(provisioningInput.exists()).toBe(true);
|
|
141
|
+
expect(k8sDistroInput.exists()).toBe(true);
|
|
142
|
+
|
|
143
|
+
expect(systemAgentInput.attributes().disabled).toBeDefined();
|
|
144
|
+
expect(provisioningInput.attributes().disabled).toBeDefined();
|
|
145
|
+
expect(k8sDistroInput.attributes().disabled).toBeDefined();
|
|
142
146
|
});
|
|
143
147
|
|
|
144
|
-
it('radio input should be set to DATA_DIR_RADIO_OPTIONS.CUSTOM with all data dir values existing and different (edit scenario)',
|
|
148
|
+
it('radio input should be set to DATA_DIR_RADIO_OPTIONS.CUSTOM with all data dir values existing and different (edit scenario)', () => {
|
|
145
149
|
const newMountOptions = clone(mountOptions);
|
|
146
150
|
const inputPath = 'some-data-dir';
|
|
147
151
|
|
|
@@ -157,14 +161,20 @@ describe('component: DirectoryConfig', () => {
|
|
|
157
161
|
|
|
158
162
|
expect(wrapper.vm.dataConfigRadioValue).toBe(DATA_DIR_RADIO_OPTIONS.CUSTOM);
|
|
159
163
|
|
|
164
|
+
const radioInput = wrapper.find('[data-testid="rke2-directory-config-radio-input"]');
|
|
160
165
|
const systemAgentInput = wrapper.find('[data-testid="rke2-directory-config-systemAgent-data-dir"]');
|
|
161
166
|
const provisioningInput = wrapper.find('[data-testid="rke2-directory-config-provisioning-data-dir"]');
|
|
162
167
|
const k8sDistroInput = wrapper.find('[data-testid="rke2-directory-config-k8sDistro-data-dir"]');
|
|
163
168
|
|
|
169
|
+
expect(radioInput.isVisible()).toBe(false);
|
|
164
170
|
expect(systemAgentInput.isVisible()).toBe(true);
|
|
165
171
|
expect(provisioningInput.isVisible()).toBe(true);
|
|
166
172
|
expect(k8sDistroInput.isVisible()).toBe(true);
|
|
167
173
|
|
|
174
|
+
expect(systemAgentInput.attributes().disabled).toBeDefined();
|
|
175
|
+
expect(provisioningInput.attributes().disabled).toBeDefined();
|
|
176
|
+
expect(k8sDistroInput.attributes().disabled).toBeDefined();
|
|
177
|
+
|
|
168
178
|
expect(wrapper.vm.value.systemAgent).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.AGENT }`);
|
|
169
179
|
expect(wrapper.vm.value.provisioning).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.PROVISIONING }`);
|
|
170
180
|
expect(wrapper.vm.value.k8sDistro).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.K8S_DISTRO_K3S }`);
|
|
@@ -211,8 +211,9 @@ export default {
|
|
|
211
211
|
|
|
212
212
|
emberLink() {
|
|
213
213
|
if (this.value) {
|
|
214
|
+
// set subtype if editing EKS/GKE/AKS cluster -- this ensures that the component provided by extension is loaded instead of iframing old ember ui
|
|
214
215
|
if (this.value.provisioner) {
|
|
215
|
-
const matchingSubtype = this.subTypes.find((st) =>
|
|
216
|
+
const matchingSubtype = this.subTypes.find((st) => DRIVER_TO_IMPORT[st.id.toLowerCase()] === this.value.provisioner.toLowerCase());
|
|
216
217
|
|
|
217
218
|
if (matchingSubtype) {
|
|
218
219
|
this.selectType(matchingSubtype.id, false);
|
|
@@ -65,14 +65,12 @@ import Advanced from '@shell/edit/provisioning.cattle.io.cluster/tabs/Advanced';
|
|
|
65
65
|
import { DEFAULT_COMMON_BASE_PATH, DEFAULT_SUBDIRS } from '@shell/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig';
|
|
66
66
|
import ClusterAppearance from '@shell/components/form/ClusterAppearance';
|
|
67
67
|
import AddOnAdditionalManifest from '@shell/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest';
|
|
68
|
-
import VsphereUtils from '@shell/utils/v-sphere';
|
|
68
|
+
import VsphereUtils, { VMWARE_VSPHERE } from '@shell/utils/v-sphere';
|
|
69
69
|
|
|
70
70
|
const HARVESTER = 'harvester';
|
|
71
71
|
const HARVESTER_CLOUD_PROVIDER = 'harvester-cloud-provider';
|
|
72
72
|
const NETBIOS_TRUNCATION_LENGTH = 15;
|
|
73
73
|
|
|
74
|
-
const VMWARE_VSPHERE = 'vmwarevsphere';
|
|
75
|
-
|
|
76
74
|
/**
|
|
77
75
|
* Classes to be adopted by the node badges in Machine pools
|
|
78
76
|
*/
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
<script>
|
|
3
3
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
4
|
-
import { _CREATE } from '@shell/config/query-params';
|
|
4
|
+
import { _CREATE, _EDIT } from '@shell/config/query-params';
|
|
5
5
|
import RadioGroup from '@components/Form/Radio/RadioGroup.vue';
|
|
6
|
+
import { Banner } from '@components/Banner';
|
|
6
7
|
|
|
7
8
|
export const DATA_DIR_RADIO_OPTIONS = {
|
|
8
9
|
DEFAULT: 'defaultDataDir',
|
|
@@ -23,7 +24,8 @@ export default {
|
|
|
23
24
|
name: 'DirectoryConfig',
|
|
24
25
|
components: {
|
|
25
26
|
LabeledInput,
|
|
26
|
-
RadioGroup
|
|
27
|
+
RadioGroup,
|
|
28
|
+
Banner
|
|
27
29
|
},
|
|
28
30
|
props: {
|
|
29
31
|
mode: {
|
|
@@ -50,9 +52,7 @@ export default {
|
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
if (this.mode !== _CREATE) {
|
|
53
|
-
|
|
54
|
-
dataConfigRadioValue = DATA_DIR_RADIO_OPTIONS.CUSTOM;
|
|
55
|
-
}
|
|
55
|
+
dataConfigRadioValue = DATA_DIR_RADIO_OPTIONS.CUSTOM;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
return {
|
|
@@ -85,6 +85,9 @@ export default {
|
|
|
85
85
|
}
|
|
86
86
|
},
|
|
87
87
|
computed: {
|
|
88
|
+
isDisabled() {
|
|
89
|
+
return this.mode === _EDIT;
|
|
90
|
+
},
|
|
88
91
|
dataConfigRadioOptions() {
|
|
89
92
|
const defaultDataDirOption = {
|
|
90
93
|
value: DATA_DIR_RADIO_OPTIONS.DEFAULT,
|
|
@@ -148,10 +151,17 @@ export default {
|
|
|
148
151
|
<template>
|
|
149
152
|
<div class="row">
|
|
150
153
|
<div class="col span-8">
|
|
151
|
-
<h3
|
|
154
|
+
<h3>
|
|
152
155
|
{{ t('cluster.directoryConfig.title') }}
|
|
153
156
|
</h3>
|
|
157
|
+
<Banner
|
|
158
|
+
class="mb-20"
|
|
159
|
+
:closable="false"
|
|
160
|
+
color="info"
|
|
161
|
+
label-key="cluster.directoryConfig.banner"
|
|
162
|
+
/>
|
|
154
163
|
<RadioGroup
|
|
164
|
+
v-show="!isDisabled"
|
|
155
165
|
:value="dataConfigRadioValue"
|
|
156
166
|
class="mb-10"
|
|
157
167
|
:mode="mode"
|
|
@@ -167,6 +177,7 @@ export default {
|
|
|
167
177
|
:mode="mode"
|
|
168
178
|
:label="t('cluster.directoryConfig.common.label')"
|
|
169
179
|
:tooltip="t('cluster.directoryConfig.common.tooltip')"
|
|
180
|
+
:disabled="isDisabled"
|
|
170
181
|
data-testid="rke2-directory-config-common-data-dir"
|
|
171
182
|
/>
|
|
172
183
|
<div v-if="dataConfigRadioValue === DATA_DIR_RADIO_OPTIONS.CUSTOM">
|
|
@@ -176,6 +187,7 @@ export default {
|
|
|
176
187
|
:mode="mode"
|
|
177
188
|
:label="t('cluster.directoryConfig.systemAgent.label')"
|
|
178
189
|
:tooltip="t('cluster.directoryConfig.systemAgent.tooltip')"
|
|
190
|
+
:disabled="isDisabled"
|
|
179
191
|
data-testid="rke2-directory-config-systemAgent-data-dir"
|
|
180
192
|
/>
|
|
181
193
|
<LabeledInput
|
|
@@ -184,6 +196,7 @@ export default {
|
|
|
184
196
|
:mode="mode"
|
|
185
197
|
:label="t('cluster.directoryConfig.provisioning.label')"
|
|
186
198
|
:tooltip="t('cluster.directoryConfig.provisioning.tooltip')"
|
|
199
|
+
:disabled="isDisabled"
|
|
187
200
|
data-testid="rke2-directory-config-provisioning-data-dir"
|
|
188
201
|
/>
|
|
189
202
|
<LabeledInput
|
|
@@ -192,6 +205,7 @@ export default {
|
|
|
192
205
|
:mode="mode"
|
|
193
206
|
:label="t('cluster.directoryConfig.k8sDistro.label')"
|
|
194
207
|
:tooltip="t('cluster.directoryConfig.k8sDistro.tooltip')"
|
|
208
|
+
:disabled="isDisabled"
|
|
195
209
|
data-testid="rke2-directory-config-k8sDistro-data-dir"
|
|
196
210
|
/>
|
|
197
211
|
</div>
|