@rancher/shell 0.2.1 → 0.2.3
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/translations/en-us.yaml +9 -5
- package/assets/translations/zh-hans.yaml +328 -117
- package/components/Carousel.vue +25 -9
- package/components/Import.vue +7 -1
- package/components/SortableTable/index.vue +7 -1
- package/components/form/MatchExpressions.vue +15 -3
- package/components/nav/Header.vue +14 -1
- package/detail/cis.cattle.io.clusterscan.vue +6 -2
- package/detail/provisioning.cattle.io.cluster.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/ACE.vue +1 -2
- package/edit/provisioning.cattle.io.cluster/MachinePool.vue +5 -3
- package/list/node.vue +7 -2
- package/mixins/resource-manager.js +5 -0
- package/models/cluster.x-k8s.io.machinedeployment.js +8 -0
- package/models/management.cattle.io.cluster.js +6 -1
- package/nuxt.config.js +113 -108
- package/package.json +1 -1
- package/pages/c/_cluster/apps/charts/index.vue +1 -1
- package/pages/c/_cluster/apps/charts/install.vue +24 -38
- package/pages/c/_cluster/settings/performance.vue +11 -0
- package/pages/c/_cluster/uiplugins/InstallDialog.vue +15 -1
- package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +28 -6
- package/pages/c/_cluster/uiplugins/index.vue +1 -1
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -7
- package/scripts/publish-shell.sh +1 -1
- package/scripts/test-plugins-build.sh +1 -0
- package/scripts/typegen.sh +2 -2
- package/store/type-map.js +11 -2
- package/types/vue-shim.d +20 -0
- package/utils/create-yaml.js +30 -6
- package/creators/update/yarn-error.log +0 -54
- package/rancher-components/components/BadgeState/BadgeState.spec.ts +0 -12
- package/rancher-components/components/BadgeState/BadgeState.vue +0 -107
- package/rancher-components/components/BadgeState/index.ts +0 -1
- package/rancher-components/components/Banner/Banner.test.ts +0 -13
- package/rancher-components/components/Banner/Banner.vue +0 -163
- package/rancher-components/components/Banner/index.ts +0 -1
- package/rancher-components/components/Card/Card.vue +0 -150
- package/rancher-components/components/Card/index.ts +0 -1
- package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +0 -77
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +0 -395
- package/rancher-components/components/Form/Checkbox/index.ts +0 -1
- package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +0 -29
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +0 -343
- package/rancher-components/components/Form/LabeledInput/index.ts +0 -1
- package/rancher-components/components/Form/Radio/RadioButton.vue +0 -270
- package/rancher-components/components/Form/Radio/RadioGroup.vue +0 -235
- package/rancher-components/components/Form/Radio/index.ts +0 -2
- package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +0 -168
- package/rancher-components/components/Form/TextArea/index.ts +0 -1
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +0 -107
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +0 -137
- 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 -137
- package/rancher-components/components/LabeledTooltip/index.ts +0 -1
package/components/Carousel.vue
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { get } from '@shell/utils/object';
|
|
3
3
|
import { BadgeState } from '@components/BadgeState';
|
|
4
|
+
import { mapGetters } from 'vuex';
|
|
5
|
+
|
|
6
|
+
const carouselSeenStorageKey = `carousel-seen`;
|
|
4
7
|
|
|
5
8
|
export default {
|
|
6
9
|
components: { BadgeState },
|
|
@@ -31,16 +34,18 @@ export default {
|
|
|
31
34
|
default: 'noopener noreferrer nofollow'
|
|
32
35
|
},
|
|
33
36
|
},
|
|
37
|
+
|
|
34
38
|
data() {
|
|
35
39
|
return {
|
|
36
|
-
slider:
|
|
37
|
-
activeItemId:
|
|
38
|
-
autoScroll:
|
|
40
|
+
slider: this.sliders,
|
|
41
|
+
activeItemId: 0,
|
|
42
|
+
autoScroll: true,
|
|
43
|
+
autoScrollSlideInterval: null,
|
|
39
44
|
};
|
|
40
45
|
},
|
|
41
46
|
|
|
42
47
|
computed: {
|
|
43
|
-
|
|
48
|
+
...mapGetters(['clusterId']),
|
|
44
49
|
trackStyle() {
|
|
45
50
|
const sliderItem = this.activeItemId * 100 / this.slider.length;
|
|
46
51
|
const width = 60 * this.slider.length;
|
|
@@ -77,9 +82,6 @@ export default {
|
|
|
77
82
|
this.slidePosition();
|
|
78
83
|
},
|
|
79
84
|
|
|
80
|
-
timer() {
|
|
81
|
-
setInterval(this.autoScrollSlide, 2000);
|
|
82
|
-
},
|
|
83
85
|
autoScrollSlide() {
|
|
84
86
|
if (this.activeItemId < this.slider.length && this.autoScroll ) {
|
|
85
87
|
this.activeItemId++;
|
|
@@ -103,9 +105,23 @@ export default {
|
|
|
103
105
|
}
|
|
104
106
|
},
|
|
105
107
|
|
|
108
|
+
beforeDestroy() {
|
|
109
|
+
if (this.autoScrollSlideInterval) {
|
|
110
|
+
clearInterval(this.autoScrollSlideInterval);
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
|
|
106
114
|
mounted() {
|
|
107
|
-
|
|
108
|
-
|
|
115
|
+
const lastSeenCluster = sessionStorage.getItem(carouselSeenStorageKey);
|
|
116
|
+
|
|
117
|
+
if (lastSeenCluster !== this.clusterId) {
|
|
118
|
+
// Session storage lasts until tab/window closed (retained on refresh)
|
|
119
|
+
sessionStorage.setItem(carouselSeenStorageKey, this.clusterId);
|
|
120
|
+
|
|
121
|
+
this.autoScrollSlideInterval = setInterval(this.autoScrollSlide, 5000);
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
|
|
109
125
|
};
|
|
110
126
|
|
|
111
127
|
</script>
|
package/components/Import.vue
CHANGED
|
@@ -27,6 +27,13 @@ export default {
|
|
|
27
27
|
SortableTable
|
|
28
28
|
},
|
|
29
29
|
|
|
30
|
+
props: {
|
|
31
|
+
defaultNamespace: {
|
|
32
|
+
type: String,
|
|
33
|
+
default: 'default'
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
|
|
30
37
|
async fetch() {
|
|
31
38
|
this.allNamespaces = await this.$store.dispatch('cluster/findAll', { type: NAMESPACE, opt: { url: 'namespaces' } });
|
|
32
39
|
},
|
|
@@ -34,7 +41,6 @@ export default {
|
|
|
34
41
|
data() {
|
|
35
42
|
return {
|
|
36
43
|
currentYaml: '',
|
|
37
|
-
defaultNamespace: 'default',
|
|
38
44
|
allNamespaces: null,
|
|
39
45
|
errors: null,
|
|
40
46
|
rows: null,
|
|
@@ -716,7 +716,11 @@ export default {
|
|
|
716
716
|
}
|
|
717
717
|
|
|
718
718
|
if (isLabel) {
|
|
719
|
-
|
|
719
|
+
if (row.metadata?.labels && row.metadata?.labels[col.label]) {
|
|
720
|
+
return row.metadata?.labels[col.label];
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
return '';
|
|
720
724
|
}
|
|
721
725
|
|
|
722
726
|
// Use to debug table columns using expensive value getters
|
|
@@ -1181,6 +1185,8 @@ export default {
|
|
|
1181
1185
|
:full-colspan="fullColspan"
|
|
1182
1186
|
:row="row.row"
|
|
1183
1187
|
:sub-matches="subMatches"
|
|
1188
|
+
:onRowMouseEnter="onRowMouseEnter"
|
|
1189
|
+
:onRowMouseLeave="onRowMouseLeave"
|
|
1184
1190
|
>
|
|
1185
1191
|
<tr
|
|
1186
1192
|
v-if="row.row.stateDescription"
|
|
@@ -5,9 +5,10 @@ import { mapGetters } from 'vuex';
|
|
|
5
5
|
import { isArray, removeObject } from '@shell/utils/array';
|
|
6
6
|
import { clone } from '@shell/utils/object';
|
|
7
7
|
import { convert, simplify } from '@shell/utils/selector';
|
|
8
|
+
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
8
9
|
|
|
9
10
|
export default {
|
|
10
|
-
components: { Select },
|
|
11
|
+
components: { Select, LabeledSelect },
|
|
11
12
|
props: {
|
|
12
13
|
// Array of actual match expressions
|
|
13
14
|
// or k8s selector Object of {matchExpressions, matchLabels}
|
|
@@ -38,6 +39,12 @@ export default {
|
|
|
38
39
|
showRemove: {
|
|
39
40
|
type: Boolean,
|
|
40
41
|
default: true
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
// if options are passed for keys, then the key's input will become a select
|
|
45
|
+
keysSelectOptions: {
|
|
46
|
+
type: Array,
|
|
47
|
+
default: () => []
|
|
41
48
|
}
|
|
42
49
|
},
|
|
43
50
|
|
|
@@ -108,6 +115,10 @@ export default {
|
|
|
108
115
|
return POD;
|
|
109
116
|
},
|
|
110
117
|
|
|
118
|
+
hasKeySelectOptions() {
|
|
119
|
+
return !!this.keysSelectOptions?.length;
|
|
120
|
+
},
|
|
121
|
+
|
|
111
122
|
...mapGetters({ t: 'i18n/t' })
|
|
112
123
|
},
|
|
113
124
|
|
|
@@ -194,11 +205,12 @@ export default {
|
|
|
194
205
|
<div v-if="isView">
|
|
195
206
|
{{ row.key }}
|
|
196
207
|
</div>
|
|
197
|
-
<input
|
|
208
|
+
<input v-else-if="!hasKeySelectOptions" v-model="row.key" :mode="mode" @input="update" />
|
|
209
|
+
<LabeledSelect
|
|
198
210
|
v-else
|
|
199
211
|
v-model="row.key"
|
|
200
212
|
:mode="mode"
|
|
201
|
-
|
|
213
|
+
:options="keysSelectOptions"
|
|
202
214
|
/>
|
|
203
215
|
</div>
|
|
204
216
|
<div
|
|
@@ -109,6 +109,19 @@ export default {
|
|
|
109
109
|
return !this.featureRancherDesktop;
|
|
110
110
|
},
|
|
111
111
|
|
|
112
|
+
showFilter() {
|
|
113
|
+
// Some products won't have a current cluster
|
|
114
|
+
const validClusterOrProduct = this.currentCluster ||
|
|
115
|
+
(this.currentProduct && this.currentProduct.customNamespaceFilter) ||
|
|
116
|
+
(this.currentProduct && this.currentProduct.showWorkspaceSwitcher);
|
|
117
|
+
// Don't show if the header is in 'simple' mode
|
|
118
|
+
const notSimple = !this.simple;
|
|
119
|
+
// One of these must be enabled, otherwise t here's no component to show
|
|
120
|
+
const validFilterSettings = this.currentProduct.showNamespaceFilter || this.currentProduct.showWorkspaceSwitcher;
|
|
121
|
+
|
|
122
|
+
return validClusterOrProduct && notSimple && validFilterSettings;
|
|
123
|
+
},
|
|
124
|
+
|
|
112
125
|
featureRancherDesktop() {
|
|
113
126
|
return this.$config.rancherEnv === 'desktop';
|
|
114
127
|
},
|
|
@@ -332,7 +345,7 @@ export default {
|
|
|
332
345
|
<component :is="navHeaderRight" />
|
|
333
346
|
|
|
334
347
|
<div
|
|
335
|
-
v-if="
|
|
348
|
+
v-if="showFilter"
|
|
336
349
|
class="top"
|
|
337
350
|
>
|
|
338
351
|
<NamespaceFilter v-if="clusterReady && currentProduct && (currentProduct.showNamespaceFilter || isExplorer)" />
|
|
@@ -290,8 +290,12 @@ export default {
|
|
|
290
290
|
:headers="reportCheckHeaders"
|
|
291
291
|
key-field="id"
|
|
292
292
|
>
|
|
293
|
-
<template #sub-row="{row, fullColspan}">
|
|
294
|
-
<tr
|
|
293
|
+
<template #sub-row="{row, fullColspan, onRowMouseEnter, onRowMouseLeave}">
|
|
294
|
+
<tr
|
|
295
|
+
class="sub-row"
|
|
296
|
+
@mouseenter="onRowMouseEnter"
|
|
297
|
+
@mouseleave="onRowMouseLeave"
|
|
298
|
+
>
|
|
295
299
|
<td :colspan="fullColspan">
|
|
296
300
|
<Banner v-if="(row.state==='fail' || row.state==='warn')&& row.remediation" class="sub-banner" :label="remediationDisplay(row)" color="warning" />
|
|
297
301
|
<SortableTable
|
|
@@ -631,11 +631,11 @@ export default {
|
|
|
631
631
|
</div>
|
|
632
632
|
</div>
|
|
633
633
|
<div v-if="group.ref" class="right mr-45">
|
|
634
|
-
<template v-if="value.hasLink('update')">
|
|
634
|
+
<template v-if="value.hasLink('update') && group.ref.showScalePool">
|
|
635
635
|
<button v-tooltip="t('node.list.scaleDown')" :disabled="!group.ref.canScaleDownPool()" type="button" class="btn btn-sm role-secondary" @click="group.ref.scalePool(-1)">
|
|
636
636
|
<i class="icon icon-sm icon-minus" />
|
|
637
637
|
</button>
|
|
638
|
-
<button v-tooltip="t('node.list.scaleUp')" type="button" class="btn btn-sm role-secondary ml-10" @click="group.ref.scalePool(1)">
|
|
638
|
+
<button v-tooltip="t('node.list.scaleUp')" :disabled="!group.ref.canScaleUpPool()" type="button" class="btn btn-sm role-secondary ml-10" @click="group.ref.scalePool(1)">
|
|
639
639
|
<i class="icon icon-sm icon-plus" />
|
|
640
640
|
</button>
|
|
641
641
|
</template>
|
|
@@ -4,7 +4,6 @@ import { LabeledInput } from '@components/Form/LabeledInput';
|
|
|
4
4
|
import FileSelector, { createOnSelected } from '@shell/components/form/FileSelector';
|
|
5
5
|
import { set } from '@shell/utils/object';
|
|
6
6
|
import isEmpty from 'lodash/isEmpty';
|
|
7
|
-
import { _CREATE } from '@shell/config/query-params';
|
|
8
7
|
|
|
9
8
|
export default {
|
|
10
9
|
components: {
|
|
@@ -24,7 +23,7 @@ export default {
|
|
|
24
23
|
},
|
|
25
24
|
|
|
26
25
|
data() {
|
|
27
|
-
if ( isEmpty(this.value?.spec?.localClusterAuthEndpoint)
|
|
26
|
+
if ( isEmpty(this.value?.spec?.localClusterAuthEndpoint) ) {
|
|
28
27
|
set(this.value, 'spec.localClusterAuthEndpoint', {
|
|
29
28
|
enabled: false,
|
|
30
29
|
caCerts: '',
|
|
@@ -35,9 +35,10 @@ export default {
|
|
|
35
35
|
default: () => ({})
|
|
36
36
|
},
|
|
37
37
|
|
|
38
|
+
// no credentials are required for elemental machine pools
|
|
38
39
|
credentialId: {
|
|
39
|
-
type:
|
|
40
|
-
|
|
40
|
+
type: String,
|
|
41
|
+
default: null
|
|
41
42
|
},
|
|
42
43
|
|
|
43
44
|
mode: {
|
|
@@ -219,7 +220,8 @@ export default {
|
|
|
219
220
|
:machine-pools="machinePools"
|
|
220
221
|
@error="e=>errors = e"
|
|
221
222
|
/>
|
|
222
|
-
<Banner v-else color="
|
|
223
|
+
<Banner v-else-if="value.configMissing" color="error" label-key="cluster.machinePool.configNotFound" />
|
|
224
|
+
<Banner v-else color="info" label-key="cluster.machinePool.noAccessBanner" />
|
|
223
225
|
|
|
224
226
|
<AdvancedSection :mode="mode" class="advanced">
|
|
225
227
|
<portal-target :name="'advanced-' + uuid" multiple />
|
package/list/node.vue
CHANGED
|
@@ -153,8 +153,13 @@ export default {
|
|
|
153
153
|
:loading="loading"
|
|
154
154
|
v-on="$listeners"
|
|
155
155
|
>
|
|
156
|
-
<template #sub-row="{fullColspan, row}">
|
|
157
|
-
<tr
|
|
156
|
+
<template #sub-row="{fullColspan, row, onRowMouseEnter, onRowMouseLeave}">
|
|
157
|
+
<tr
|
|
158
|
+
class="taints sub-row"
|
|
159
|
+
:class="{'empty-taints': !row.spec.taints || !row.spec.taints.length}"
|
|
160
|
+
@mouseenter="onRowMouseEnter"
|
|
161
|
+
@mouseleave="onRowMouseLeave"
|
|
162
|
+
>
|
|
158
163
|
<template v-if="row.spec.taints && row.spec.taints.length">
|
|
159
164
|
<td> </td>
|
|
160
165
|
<td> </td>
|
|
@@ -74,6 +74,11 @@ export default {
|
|
|
74
74
|
// - id param = this.$store.getters['cluster/keyFieldForType'](type)
|
|
75
75
|
// - id value = new dashboard-store getter, overwritten by steve store getter
|
|
76
76
|
requestData.forEach((item) => {
|
|
77
|
+
// if there's already a prop type, don't overwrite it without storing it first...
|
|
78
|
+
// only do this operation once in multiple apply's because the requestData is the same!
|
|
79
|
+
if (item.type && !item._type) {
|
|
80
|
+
item._type = item.type;
|
|
81
|
+
}
|
|
77
82
|
item.type = type;
|
|
78
83
|
item.id = `${ item.metadata.namespace }/${ item.metadata.name }`;
|
|
79
84
|
});
|
|
@@ -159,6 +159,14 @@ export default class CapiMachineDeployment extends SteveModel {
|
|
|
159
159
|
return notOnlyOfRole(this, this.cluster.machines);
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
+
canScaleUpPool() {
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
get showScalePool() {
|
|
167
|
+
return this.canScaleDownPool() || this.canScaleUpPool();
|
|
168
|
+
}
|
|
169
|
+
|
|
162
170
|
get stateParts() {
|
|
163
171
|
const out = [
|
|
164
172
|
{
|
|
@@ -432,7 +432,12 @@ export default class MgmtCluster extends HybridModel {
|
|
|
432
432
|
}
|
|
433
433
|
|
|
434
434
|
get provClusterId() {
|
|
435
|
-
const
|
|
435
|
+
const isRKE1 = !!this.spec?.rancherKubernetesEngineConfig;
|
|
436
|
+
// Note: RKE1 provisioning cluster IDs are in a different format. For example,
|
|
437
|
+
// RKE2 cluster IDs include the name - fleet-default/cluster-name - whereas an RKE1
|
|
438
|
+
// cluster has the less human readable management cluster ID in it: fleet-default/c-khk48
|
|
439
|
+
|
|
440
|
+
const verb = this.isLocal || isRKE1 ? 'to' : 'from';
|
|
436
441
|
const from = `${ verb }Type`;
|
|
437
442
|
const id = `${ verb }Id`;
|
|
438
443
|
|
package/nuxt.config.js
CHANGED
|
@@ -10,6 +10,29 @@ import { trimWhitespaceSsr as trimWhitespace } from './plugins/trim-whitespace';
|
|
|
10
10
|
|
|
11
11
|
const createProxyMiddleware = require('http-proxy-middleware');
|
|
12
12
|
|
|
13
|
+
// Global variables
|
|
14
|
+
let api = process.env.API || 'http://localhost:8989';
|
|
15
|
+
|
|
16
|
+
if ( !api.startsWith('http') ) {
|
|
17
|
+
api = `https://${ api }`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// needed for proxies
|
|
21
|
+
export const API_PATH = api;
|
|
22
|
+
|
|
23
|
+
const dev = (process.env.NODE_ENV !== 'production');
|
|
24
|
+
const devPorts = dev || process.env.DEV_PORTS === 'true';
|
|
25
|
+
const version = process.env.VERSION ||
|
|
26
|
+
process.env.DRONE_TAG ||
|
|
27
|
+
process.env.DRONE_VERSION ||
|
|
28
|
+
require('./package.json').version;
|
|
29
|
+
|
|
30
|
+
const prime = process.env.PRIME;
|
|
31
|
+
|
|
32
|
+
const pl = process.env.PL || STANDARD;
|
|
33
|
+
const commit = process.env.COMMIT || 'head';
|
|
34
|
+
const perfTest = (process.env.PERF_TEST === 'true'); // Enable performance testing when in dev
|
|
35
|
+
|
|
13
36
|
// ===============================================================================================
|
|
14
37
|
// Nuxt configuration
|
|
15
38
|
// ===============================================================================================
|
|
@@ -195,25 +218,6 @@ export default function(dir, _appConfig) {
|
|
|
195
218
|
require('events').EventEmitter.defaultMaxListeners = 20;
|
|
196
219
|
require('dotenv').config();
|
|
197
220
|
|
|
198
|
-
const version = process.env.VERSION ||
|
|
199
|
-
process.env.DRONE_TAG ||
|
|
200
|
-
process.env.DRONE_VERSION ||
|
|
201
|
-
require('./package.json').version;
|
|
202
|
-
|
|
203
|
-
const prime = process.env.PRIME;
|
|
204
|
-
|
|
205
|
-
const dev = (process.env.NODE_ENV !== 'production');
|
|
206
|
-
const devPorts = dev || process.env.DEV_PORTS === 'true';
|
|
207
|
-
const pl = process.env.PL || STANDARD;
|
|
208
|
-
const commit = process.env.COMMIT || 'head';
|
|
209
|
-
const perfTest = (process.env.PERF_TEST === 'true'); // Enable performance testing when in dev
|
|
210
|
-
|
|
211
|
-
let api = process.env.API || 'http://localhost:8989';
|
|
212
|
-
|
|
213
|
-
if ( !api.startsWith('http') ) {
|
|
214
|
-
api = `https://${ api }`;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
221
|
let routerBasePath = '/';
|
|
218
222
|
let resourceBase = '';
|
|
219
223
|
let outputDir = 'dist';
|
|
@@ -587,6 +591,7 @@ export default function(dir, _appConfig) {
|
|
|
587
591
|
|
|
588
592
|
// Proxy: https://github.com/nuxt-community/proxy-module#options
|
|
589
593
|
proxy: {
|
|
594
|
+
...appConfig.proxies,
|
|
590
595
|
'/k8s': proxyWsOpts(api), // Straight to a remote cluster (/k8s/clusters/<id>/)
|
|
591
596
|
'/pp': proxyWsOpts(api), // For (epinio) standalone API
|
|
592
597
|
'/api': proxyWsOpts(api), // Management k8s API
|
|
@@ -637,114 +642,114 @@ export default function(dir, _appConfig) {
|
|
|
637
642
|
};
|
|
638
643
|
|
|
639
644
|
return config;
|
|
645
|
+
}
|
|
640
646
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
function proxyMetaOpts(target) {
|
|
646
|
-
return {
|
|
647
|
-
target,
|
|
648
|
-
followRedirects: true,
|
|
649
|
-
secure: !dev,
|
|
650
|
-
onProxyReq,
|
|
651
|
-
onProxyReqWs,
|
|
652
|
-
onError,
|
|
653
|
-
onProxyRes,
|
|
654
|
-
};
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
function proxyOpts(target) {
|
|
658
|
-
return {
|
|
659
|
-
target,
|
|
660
|
-
secure: !devPorts,
|
|
661
|
-
onProxyReq,
|
|
662
|
-
onProxyReqWs,
|
|
663
|
-
onError,
|
|
664
|
-
onProxyRes,
|
|
665
|
-
};
|
|
666
|
-
}
|
|
647
|
+
// ===============================================================================================
|
|
648
|
+
// Functions for the request proxying used in dev
|
|
649
|
+
// ===============================================================================================
|
|
667
650
|
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
651
|
+
export function proxyMetaOpts(target) {
|
|
652
|
+
return {
|
|
653
|
+
target,
|
|
654
|
+
followRedirects: true,
|
|
655
|
+
secure: !dev,
|
|
656
|
+
onProxyReq,
|
|
657
|
+
onProxyReqWs,
|
|
658
|
+
onError,
|
|
659
|
+
onProxyRes,
|
|
660
|
+
};
|
|
661
|
+
}
|
|
672
662
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
663
|
+
export function proxyOpts(target) {
|
|
664
|
+
return {
|
|
665
|
+
target,
|
|
666
|
+
secure: !devPorts,
|
|
667
|
+
onProxyReq,
|
|
668
|
+
onProxyReqWs,
|
|
669
|
+
onError,
|
|
670
|
+
onProxyRes,
|
|
671
|
+
};
|
|
672
|
+
}
|
|
677
673
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
674
|
+
// Intercept the /rancherversion API call wnad modify the 'RancherPrime' value
|
|
675
|
+
// if configured to do so by the environment variable PRIME
|
|
676
|
+
export function proxyPrimeOpts(target) {
|
|
677
|
+
const opts = proxyOpts(target);
|
|
681
678
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
679
|
+
// Don't intercept if the PRIME environment variable is not set
|
|
680
|
+
if (!prime?.length) {
|
|
681
|
+
return opts;
|
|
682
|
+
}
|
|
686
683
|
|
|
687
|
-
|
|
684
|
+
opts.onProxyRes = (proxyRes, req, res) => {
|
|
685
|
+
const _end = res.end;
|
|
686
|
+
let body = '';
|
|
688
687
|
|
|
689
|
-
|
|
690
|
-
|
|
688
|
+
proxyRes.on( 'data', (data) => {
|
|
689
|
+
data = data.toString('utf-8');
|
|
690
|
+
body += data;
|
|
691
|
+
});
|
|
691
692
|
|
|
692
|
-
|
|
693
|
-
const out = JSON.parse(body);
|
|
693
|
+
res.write = () => {};
|
|
694
694
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
} catch (err) {}
|
|
695
|
+
res.end = () => {
|
|
696
|
+
let output = body;
|
|
698
697
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
698
|
+
try {
|
|
699
|
+
const out = JSON.parse(body);
|
|
700
|
+
|
|
701
|
+
out.RancherPrime = prime;
|
|
702
|
+
output = JSON.stringify(out);
|
|
703
|
+
} catch (err) {}
|
|
704
|
+
|
|
705
|
+
res.setHeader('content-length', output.length );
|
|
706
|
+
res.setHeader('content-type', 'application/json' );
|
|
707
|
+
res.setHeader('transfer-encoding', '');
|
|
708
|
+
res.setHeader('cache-control', 'no-cache');
|
|
709
|
+
res.writeHead(proxyRes.statusCode);
|
|
710
|
+
_end.apply(res, [output]);
|
|
706
711
|
};
|
|
712
|
+
};
|
|
707
713
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
function onProxyRes(proxyRes, req, res) {
|
|
712
|
-
if (devPorts) {
|
|
713
|
-
proxyRes.headers['X-Frame-Options'] = 'ALLOWALL';
|
|
714
|
-
}
|
|
715
|
-
}
|
|
714
|
+
return opts;
|
|
715
|
+
}
|
|
716
716
|
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
ws: true,
|
|
721
|
-
changeOrigin: true,
|
|
722
|
-
};
|
|
717
|
+
export function onProxyRes(proxyRes, req, res) {
|
|
718
|
+
if (devPorts) {
|
|
719
|
+
proxyRes.headers['X-Frame-Options'] = 'ALLOWALL';
|
|
723
720
|
}
|
|
721
|
+
}
|
|
724
722
|
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
723
|
+
export function proxyWsOpts(target) {
|
|
724
|
+
return {
|
|
725
|
+
...proxyOpts(target),
|
|
726
|
+
ws: true,
|
|
727
|
+
changeOrigin: true,
|
|
728
|
+
};
|
|
729
|
+
}
|
|
732
730
|
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
proxyReq.setHeader('origin', options.target.href);
|
|
731
|
+
export function onProxyReq(proxyReq, req) {
|
|
732
|
+
if (!(proxyReq._currentRequest && proxyReq._currentRequest._headerSent)) {
|
|
736
733
|
proxyReq.setHeader('x-api-host', req.headers['host']);
|
|
737
734
|
proxyReq.setHeader('x-forwarded-proto', 'https');
|
|
738
735
|
// console.log(proxyReq.getHeaders());
|
|
739
|
-
|
|
740
|
-
socket.on('error', (err) => {
|
|
741
|
-
console.error('Proxy WS Error:', err); // eslint-disable-line no-console
|
|
742
|
-
});
|
|
743
736
|
}
|
|
737
|
+
}
|
|
744
738
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
739
|
+
export function onProxyReqWs(proxyReq, req, socket, options, head) {
|
|
740
|
+
req.headers.origin = options.target.href;
|
|
741
|
+
proxyReq.setHeader('origin', options.target.href);
|
|
742
|
+
proxyReq.setHeader('x-api-host', req.headers['host']);
|
|
743
|
+
proxyReq.setHeader('x-forwarded-proto', 'https');
|
|
744
|
+
// console.log(proxyReq.getHeaders());
|
|
745
|
+
|
|
746
|
+
socket.on('error', (err) => {
|
|
747
|
+
console.error('Proxy WS Error:', err); // eslint-disable-line no-console
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
export function onError(err, req, res) {
|
|
752
|
+
res.statusCode = 598;
|
|
753
|
+
console.error('Proxy Error:', err); // eslint-disable-line no-console
|
|
754
|
+
res.write(JSON.stringify(err));
|
|
750
755
|
}
|
package/package.json
CHANGED