@rancher/shell 0.3.20 → 0.3.22
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 +8 -2
- package/assets/translations/zh-hans.yaml +8 -1
- package/cloud-credential/__tests__/azure.test.ts +53 -0
- package/cloud-credential/azure.vue +6 -0
- package/components/GrowlManager.vue +33 -30
- package/components/Questions/Array.vue +2 -2
- package/components/Questions/Boolean.vue +7 -1
- package/components/Questions/CloudCredential.vue +1 -0
- package/components/Questions/Enum.vue +21 -2
- package/components/Questions/Float.vue +8 -3
- package/components/Questions/Int.vue +8 -3
- package/components/Questions/Question.js +72 -0
- package/components/Questions/QuestionMap.vue +2 -1
- package/components/Questions/Radio.vue +33 -0
- package/components/Questions/Reference.vue +2 -0
- package/components/Questions/String.vue +8 -3
- package/components/Questions/Yaml.vue +46 -0
- package/components/Questions/__tests__/Boolean.test.ts +123 -0
- package/components/Questions/__tests__/Float.test.ts +123 -0
- package/components/Questions/__tests__/Int.test.ts +123 -0
- package/components/Questions/__tests__/String.test.ts +123 -0
- package/components/Questions/__tests__/Yaml.test.ts +123 -0
- package/components/Questions/index.vue +8 -1
- package/components/ResourceTable.vue +6 -12
- package/components/SideNav.vue +634 -0
- package/components/__tests__/NamespaceFilter.test.ts +3 -4
- package/components/form/ResourceQuota/ProjectRow.vue +38 -15
- package/components/form/UnitInput.vue +1 -0
- package/components/form/__tests__/KeyValue.test.ts +2 -1
- package/components/form/__tests__/UnitInput.test.ts +2 -2
- package/components/formatter/ClusterProvider.vue +9 -3
- package/components/formatter/LinkName.vue +12 -1
- package/components/formatter/__tests__/ClusterProvider.test.ts +5 -1
- package/components/nav/Header.vue +1 -0
- package/components/nav/WorkspaceSwitcher.vue +4 -1
- package/config/settings.ts +59 -2
- package/config/types.js +2 -0
- package/core/plugin-helpers.js +4 -1
- package/core/types.ts +1 -0
- package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +28 -0
- package/creators/pkg/files/.github/workflows/build-extension-charts.yml +26 -0
- package/creators/pkg/init +63 -4
- package/detail/provisioning.cattle.io.cluster.vue +4 -2
- package/edit/fleet.cattle.io.gitrepo.vue +8 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +4 -4
- package/layouts/default.vue +11 -597
- package/middleware/authenticated.js +2 -14
- package/mixins/__tests__/chart.test.ts +40 -0
- package/mixins/chart.js +5 -0
- package/models/catalog.cattle.io.clusterrepo.js +6 -2
- package/models/fleet.cattle.io.cluster.js +10 -2
- package/models/fleet.cattle.io.gitrepo.js +3 -1
- package/package.json +1 -1
- package/pages/c/_cluster/fleet/index.vue +4 -0
- package/pages/c/_cluster/gatekeeper/index.vue +10 -1
- package/pages/c/_cluster/uiplugins/index.vue +3 -3
- package/plugins/steve/__tests__/header-warnings.spec.ts +238 -0
- package/plugins/steve/actions.js +4 -23
- package/plugins/steve/header-warnings.ts +91 -0
- package/promptRemove/management.cattle.io.project.vue +9 -6
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +8 -0
- package/rancher-components/components/Form/Radio/RadioButton.test.ts +7 -3
- package/scripts/extension/parse-tag-name +30 -0
- package/types/shell/index.d.ts +3 -0
- package/utils/auth.js +17 -0
- package/utils/object.js +0 -1
- package/utils/settings.ts +2 -17
- package/utils/validators/__tests__/cidr.test.ts +33 -0
- package/utils/validators/cidr.js +5 -0
- package/vue-config-helper.js +135 -0
- package/vue.config.js +23 -139
- package/yarn-error.log +200 -0
- package/creators/pkg/files/.github/workflows/build-container.yml +0 -64
- package/creators/pkg/files/.github/workflows/build-extension.yml +0 -110
|
@@ -206,6 +206,13 @@ export default (
|
|
|
206
206
|
}
|
|
207
207
|
},
|
|
208
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Emit on input change
|
|
211
|
+
*/
|
|
212
|
+
onChange(event: Event): void {
|
|
213
|
+
this.$emit('change', event);
|
|
214
|
+
},
|
|
215
|
+
|
|
209
216
|
/**
|
|
210
217
|
* Emit on input with delay. Note: Arrow function is avoided due context
|
|
211
218
|
* binding.
|
|
@@ -299,6 +306,7 @@ export default (
|
|
|
299
306
|
@input="onInput($event.target.value)"
|
|
300
307
|
@focus="onFocus"
|
|
301
308
|
@blur="onBlur"
|
|
309
|
+
@change="onChange"
|
|
302
310
|
>
|
|
303
311
|
</slot>
|
|
304
312
|
|
|
@@ -4,7 +4,7 @@ import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
|
|
|
4
4
|
|
|
5
5
|
describe('radioButton.vue', () => {
|
|
6
6
|
it('renders label slot contents', () => {
|
|
7
|
-
const wrapper = shallowMount(RadioButton, { slots: { label: 'Test Label' } });
|
|
7
|
+
const wrapper = shallowMount(RadioButton, { slots: { label: 'Test Label' }, propsData: { val: {}, value: {} } });
|
|
8
8
|
|
|
9
9
|
expect(wrapper.find('.radio-label').text()).toBe('Test Label');
|
|
10
10
|
});
|
|
@@ -14,7 +14,9 @@ describe('radioButton.vue', () => {
|
|
|
14
14
|
RadioButton,
|
|
15
15
|
{
|
|
16
16
|
directives: { cleanHtmlDirective },
|
|
17
|
-
propsData: {
|
|
17
|
+
propsData: {
|
|
18
|
+
label: 'Test Label', val: {}, value: {}
|
|
19
|
+
}
|
|
18
20
|
});
|
|
19
21
|
|
|
20
22
|
expect(wrapper.find('.radio-label').text()).toBe('Test Label');
|
|
@@ -23,7 +25,9 @@ describe('radioButton.vue', () => {
|
|
|
23
25
|
it('renders slot contents when both slot and label prop are provided', () => {
|
|
24
26
|
const wrapper = shallowMount(RadioButton, {
|
|
25
27
|
slots: { label: 'Test Label - Slot' },
|
|
26
|
-
propsData: {
|
|
28
|
+
propsData: {
|
|
29
|
+
label: 'Test Label - Props', val: {}, value: {}
|
|
30
|
+
},
|
|
27
31
|
});
|
|
28
32
|
|
|
29
33
|
expect(wrapper.find('.radio-label').text()).toBe('Test Label - Slot');
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
GITHUB_RELEASE_TAG=$1
|
|
4
|
+
GITHUB_RUN_ID=$2
|
|
5
|
+
GITHUB_WORKFLOW_TYPE=$3
|
|
6
|
+
|
|
7
|
+
# Check packages for released tag name
|
|
8
|
+
if [[ "${GITHUB_WORKFLOW_TYPE}" == "container" ]]; then
|
|
9
|
+
for d in pkg/*/ ; do
|
|
10
|
+
pkg=$(basename $d)
|
|
11
|
+
|
|
12
|
+
PKG_VERSION=$(jq -r .version pkg/${pkg}/package.json)
|
|
13
|
+
PKG_NAME="${pkg}-${PKG_VERSION}"
|
|
14
|
+
|
|
15
|
+
if [[ "${GITHUB_RELEASE_TAG}" == "${PKG_NAME}" ]]; then
|
|
16
|
+
gh run cancel ${GITHUB_RUN_ID}
|
|
17
|
+
else
|
|
18
|
+
continue
|
|
19
|
+
fi
|
|
20
|
+
done
|
|
21
|
+
else
|
|
22
|
+
# Check base extension name for tag name
|
|
23
|
+
BASE_EXT=$(jq -r .name package.json)
|
|
24
|
+
EXT_VERSION=$(jq -r .version package.json)
|
|
25
|
+
|
|
26
|
+
if [[ "${GITHUB_RELEASE_TAG}" == "${BASE_EXT}-${EXT_VERSION}" ]]; then
|
|
27
|
+
echo -e "tag: ${GITHUB_RELEASE_TAG}"
|
|
28
|
+
gh run cancel ${GITHUB_RUN_ID}
|
|
29
|
+
fi
|
|
30
|
+
fi
|
package/types/shell/index.d.ts
CHANGED
|
@@ -2003,6 +2003,7 @@ export namespace AUTH_TYPE {
|
|
|
2003
2003
|
const _SSH: string;
|
|
2004
2004
|
const _S3: string;
|
|
2005
2005
|
}
|
|
2006
|
+
export const LOCAL_CLUSTER: "local";
|
|
2006
2007
|
}
|
|
2007
2008
|
|
|
2008
2009
|
// @shell/mixins/create-edit-view/impl
|
|
@@ -3029,6 +3030,7 @@ export function authProvidersInfo(store: any): Promise<{
|
|
|
3029
3030
|
}>;
|
|
3030
3031
|
export function checkSchemasForFindAllHash(types: any, store: any): any;
|
|
3031
3032
|
export function checkPermissions(types: any, getters: any): any;
|
|
3033
|
+
export function canViewResource(store: any, resource: any): boolean;
|
|
3032
3034
|
}
|
|
3033
3035
|
|
|
3034
3036
|
// @shell/utils/aws
|
|
@@ -4060,6 +4062,7 @@ export default _default;
|
|
|
4060
4062
|
|
|
4061
4063
|
declare module '@shell/utils/validators/cidr' {
|
|
4062
4064
|
export function isValidCIDR(cidr: any): boolean;
|
|
4065
|
+
export function isValidIP(ip: any): boolean;
|
|
4063
4066
|
export function isValidMac(value: any): boolean;
|
|
4064
4067
|
}
|
|
4065
4068
|
|
package/utils/auth.js
CHANGED
|
@@ -144,3 +144,20 @@ export const checkPermissions = (types, getters) => {
|
|
|
144
144
|
|
|
145
145
|
return allHash(hash);
|
|
146
146
|
};
|
|
147
|
+
|
|
148
|
+
export const canViewResource = (store, resource) => {
|
|
149
|
+
// Note - don't use the current products store... because products can override stores for resources with `typeStoreMap`
|
|
150
|
+
const inStore = store.getters['currentStore'](resource);
|
|
151
|
+
// There's a chance we're in an extension's product who's store could be anything, so confirm schemaFor exists
|
|
152
|
+
const schemaFor = store.getters[`${ inStore }/schemaFor`];
|
|
153
|
+
|
|
154
|
+
// In order to check a resource is valid we need these
|
|
155
|
+
if (!inStore || !schemaFor) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Resource is valid if a schema exists for it (standard resource, spoofed resource) or it's a virtual resource
|
|
160
|
+
const validResource = schemaFor(resource) || store.getters['type-map/isVirtual'](resource);
|
|
161
|
+
|
|
162
|
+
return !!validResource;
|
|
163
|
+
};
|
package/utils/object.js
CHANGED
package/utils/settings.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { MANAGEMENT } from '@shell/config/types';
|
|
2
2
|
import { Store } from 'vuex';
|
|
3
|
-
import { DEFAULT_PERF_SETTING, SETTING } from '@shell/config/settings';
|
|
4
|
-
import { GC_PREFERENCES } from '@shell/utils/gc/gc-types';
|
|
3
|
+
import { DEFAULT_PERF_SETTING, PerfSettings, SETTING } from '@shell/config/settings';
|
|
5
4
|
|
|
6
5
|
export const fetchOrCreateSetting = async(store: Store<any>, id: string, val: string, save = true): Promise<any> => {
|
|
7
6
|
let setting;
|
|
@@ -44,21 +43,7 @@ export const setSetting = async(store: Store<any>, id: string, val: string): Pro
|
|
|
44
43
|
return setting;
|
|
45
44
|
};
|
|
46
45
|
|
|
47
|
-
export const getPerformanceSetting = (rootGetters: Record<string, (arg0: string, arg1: string) => any>): {
|
|
48
|
-
inactivity: {
|
|
49
|
-
enabled: boolean;
|
|
50
|
-
threshold: number;
|
|
51
|
-
};
|
|
52
|
-
incrementalLoading: {
|
|
53
|
-
enabled: boolean;
|
|
54
|
-
threshold: number;
|
|
55
|
-
};
|
|
56
|
-
manualRefresh: {};
|
|
57
|
-
disableWebsocketNotification: boolean;
|
|
58
|
-
garbageCollection: GC_PREFERENCES;
|
|
59
|
-
forceNsFilterV2: any;
|
|
60
|
-
advancedWorker: {};
|
|
61
|
-
} => {
|
|
46
|
+
export const getPerformanceSetting = (rootGetters: Record<string, (arg0: string, arg1: string) => any>): PerfSettings => {
|
|
62
47
|
const perfSettingResource = rootGetters['management/byId'](MANAGEMENT.SETTING, SETTING.UI_PERFORMANCE);
|
|
63
48
|
let perfSetting = {};
|
|
64
49
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { isValidCIDR, isValidIP, isValidMac } from '@shell/utils/validators/cidr';
|
|
2
|
+
|
|
3
|
+
describe('fx: isValidCIDR', () => {
|
|
4
|
+
it('should be valid', () => {
|
|
5
|
+
expect(isValidCIDR('10.42.0.0/8')).toBe(true);
|
|
6
|
+
});
|
|
7
|
+
it('should be invalid', () => {
|
|
8
|
+
expect(isValidCIDR('10.42.0.0')).toBe(false);
|
|
9
|
+
expect(isValidCIDR('10.42.0.0/500')).toBe(false);
|
|
10
|
+
expect(isValidCIDR('300.42.0.0/8')).toBe(false);
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
describe('fx: isValidIP', () => {
|
|
15
|
+
it('should be valid', () => {
|
|
16
|
+
expect(isValidIP('10.42.0.1')).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
it('should be invalid', () => {
|
|
19
|
+
expect(isValidIP('10.42.0.0/8')).toBe(false);
|
|
20
|
+
expect(isValidIP('300.42.0.0')).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('fx: isValidMac', () => {
|
|
25
|
+
it('should be valid', () => {
|
|
26
|
+
expect(isValidMac('00-08-20-83-53-D1')).toBe(true);
|
|
27
|
+
expect(isValidMac('00-08-20-83-53-d1')).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
it('should be invalid', () => {
|
|
30
|
+
expect(isValidMac('invalid')).toBe(false);
|
|
31
|
+
expect(isValidMac('00-08-20-83-53')).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
});
|
package/utils/validators/cidr.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
const validCIDRregex = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(3[0-2]|2[0-9]|1[0-9]|[0-9])$/;
|
|
2
|
+
const validIPRegex = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
2
3
|
|
|
3
4
|
export function isValidCIDR(cidr) {
|
|
4
5
|
return !!cidr.match(validCIDRregex);
|
|
5
6
|
}
|
|
6
7
|
|
|
8
|
+
export function isValidIP(ip) {
|
|
9
|
+
return !!ip.match(validIPRegex);
|
|
10
|
+
}
|
|
11
|
+
|
|
7
12
|
export function isValidMac(value) {
|
|
8
13
|
return /^[A-Fa-f0-9]{2}(-[A-Fa-f0-9]{2}){5}$|^[A-Fa-f0-9]{2}(:[A-Fa-f0-9]{2}){5}$/.test(value);
|
|
9
14
|
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const dev = (process.env.NODE_ENV !== 'production');
|
|
2
|
+
const devPorts = dev || process.env.DEV_PORTS === 'true';
|
|
3
|
+
const prime = process.env.PRIME;
|
|
4
|
+
|
|
5
|
+
let api = process.env.API || 'http://localhost:8989';
|
|
6
|
+
|
|
7
|
+
if ( !api.startsWith('http') ) {
|
|
8
|
+
api = `https://${ api }`;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// ===============================================================================================
|
|
12
|
+
// Functions for the request proxying used in dev
|
|
13
|
+
// ===============================================================================================
|
|
14
|
+
|
|
15
|
+
function proxyMetaOpts(target) {
|
|
16
|
+
return {
|
|
17
|
+
target,
|
|
18
|
+
followRedirects: true,
|
|
19
|
+
secure: !dev,
|
|
20
|
+
changeOrigin: true,
|
|
21
|
+
onProxyReq,
|
|
22
|
+
onProxyReqWs,
|
|
23
|
+
onError,
|
|
24
|
+
onProxyRes,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function proxyOpts(target) {
|
|
29
|
+
return {
|
|
30
|
+
target,
|
|
31
|
+
secure: !devPorts,
|
|
32
|
+
changeOrigin: true,
|
|
33
|
+
onProxyReq,
|
|
34
|
+
onProxyReqWs,
|
|
35
|
+
onError,
|
|
36
|
+
onProxyRes
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Intercept the /rancherversion API call wnad modify the 'RancherPrime' value
|
|
41
|
+
// if configured to do so by the environment variable PRIME
|
|
42
|
+
function proxyPrimeOpts(target) {
|
|
43
|
+
const opts = proxyOpts(target);
|
|
44
|
+
|
|
45
|
+
// Don't intercept if the PRIME environment variable is not set
|
|
46
|
+
if (!prime?.length) {
|
|
47
|
+
return opts;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
opts.onProxyRes = (proxyRes, req, res) => {
|
|
51
|
+
const _end = res.end;
|
|
52
|
+
let body = '';
|
|
53
|
+
|
|
54
|
+
proxyRes.on( 'data', (data) => {
|
|
55
|
+
data = data.toString('utf-8');
|
|
56
|
+
body += data;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
res.write = () => {};
|
|
60
|
+
|
|
61
|
+
res.end = () => {
|
|
62
|
+
let output = body;
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const out = JSON.parse(body);
|
|
66
|
+
|
|
67
|
+
out.RancherPrime = prime;
|
|
68
|
+
output = JSON.stringify(out);
|
|
69
|
+
} catch (err) {}
|
|
70
|
+
|
|
71
|
+
res.setHeader('content-length', output.length );
|
|
72
|
+
res.setHeader('content-type', 'application/json' );
|
|
73
|
+
res.setHeader('transfer-encoding', '');
|
|
74
|
+
res.setHeader('cache-control', 'no-cache');
|
|
75
|
+
res.writeHead(proxyRes.statusCode);
|
|
76
|
+
_end.apply(res, [output]);
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
return opts;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function onProxyRes(proxyRes, req, res) {
|
|
84
|
+
if (devPorts) {
|
|
85
|
+
proxyRes.headers['X-Frame-Options'] = 'ALLOWALL';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function proxyWsOpts(target) {
|
|
90
|
+
return {
|
|
91
|
+
...proxyOpts(target),
|
|
92
|
+
ws: true,
|
|
93
|
+
changeOrigin: true,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function onProxyReq(proxyReq, req) {
|
|
98
|
+
if (!(proxyReq._currentRequest && proxyReq._currentRequest._headerSent)) {
|
|
99
|
+
proxyReq.setHeader('x-api-host', req.headers['host']);
|
|
100
|
+
proxyReq.setHeader('x-forwarded-proto', 'https');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function onProxyReqWs(proxyReq, req, socket, options, head) {
|
|
105
|
+
req.headers.origin = options.target.href;
|
|
106
|
+
proxyReq.setHeader('origin', options.target.href);
|
|
107
|
+
proxyReq.setHeader('x-api-host', req.headers['host']);
|
|
108
|
+
proxyReq.setHeader('x-forwarded-proto', 'https');
|
|
109
|
+
// console.log(proxyReq.getHeaders());
|
|
110
|
+
|
|
111
|
+
socket.on('error', (err) => {
|
|
112
|
+
console.error('Proxy WS Error:', err); // eslint-disable-line no-console
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function onError(err, req, res) {
|
|
117
|
+
res.statusCode = 598;
|
|
118
|
+
console.error('Proxy Error:', err); // eslint-disable-line no-console
|
|
119
|
+
res.write(JSON.stringify(err));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
module.exports = {
|
|
123
|
+
dev,
|
|
124
|
+
devPorts,
|
|
125
|
+
prime,
|
|
126
|
+
api,
|
|
127
|
+
proxyMetaOpts,
|
|
128
|
+
proxyOpts,
|
|
129
|
+
proxyPrimeOpts,
|
|
130
|
+
onProxyRes,
|
|
131
|
+
proxyWsOpts,
|
|
132
|
+
onProxyReq,
|
|
133
|
+
onProxyReqWs,
|
|
134
|
+
onError
|
|
135
|
+
};
|
package/vue.config.js
CHANGED
|
@@ -5,6 +5,7 @@ const webpack = require('webpack');
|
|
|
5
5
|
const { generateDynamicTypeImport } = require('./pkg/auto-import');
|
|
6
6
|
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
|
7
7
|
const serverMiddlewares = require('./server/server-middleware.js');
|
|
8
|
+
const configHelper = require('./vue-config-helper.js');
|
|
8
9
|
|
|
9
10
|
// Suppress info level logging messages from http-proxy-middleware
|
|
10
11
|
// This hides all of the "[HPM Proxy created] ..." messages
|
|
@@ -20,24 +21,18 @@ console.info = oldInfoLogger; // eslint-disable-line no-console
|
|
|
20
21
|
// const { STANDARD } = require('./config/private-label');
|
|
21
22
|
const STANDARD = 1;
|
|
22
23
|
|
|
23
|
-
const dev =
|
|
24
|
-
const devPorts =
|
|
24
|
+
const dev = configHelper.dev;
|
|
25
|
+
const devPorts = configHelper.devPorts;
|
|
25
26
|
|
|
26
27
|
// human readable version used on rancher dashboard about page
|
|
27
28
|
const dashboardVersion = process.env.DASHBOARD_VERSION;
|
|
28
29
|
|
|
29
|
-
const prime = process.env.PRIME;
|
|
30
|
-
|
|
31
30
|
const pl = process.env.PL || STANDARD;
|
|
32
31
|
const commit = process.env.COMMIT || 'head';
|
|
33
32
|
const perfTest = (process.env.PERF_TEST === 'true'); // Enable performance testing when in dev
|
|
34
33
|
const instrumentCode = (process.env.TEST_INSTRUMENT === 'true'); // Instrument code for code coverage in e2e tests
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if ( !api.startsWith('http') ) {
|
|
39
|
-
api = `https://${ api }`;
|
|
40
|
-
}
|
|
35
|
+
const api = configHelper.api;
|
|
41
36
|
// ===============================================================================================
|
|
42
37
|
// Nuxt configuration
|
|
43
38
|
// ===============================================================================================
|
|
@@ -276,26 +271,26 @@ module.exports = function(dir, _appConfig) {
|
|
|
276
271
|
console.log(`API: '${ api }'. Env: '${ rancherEnv }'`); // eslint-disable-line no-console
|
|
277
272
|
const proxy = {
|
|
278
273
|
...appConfig.proxies,
|
|
279
|
-
'/k8s': proxyWsOpts(api), // Straight to a remote cluster (/k8s/clusters/<id>/)
|
|
280
|
-
'/pp': proxyWsOpts(api), // For (epinio) standalone API
|
|
281
|
-
'/api': proxyWsOpts(api), // Management k8s API
|
|
282
|
-
'/apis': proxyWsOpts(api), // Management k8s API
|
|
283
|
-
'/v1': proxyWsOpts(api), // Management Steve API
|
|
284
|
-
'/v3': proxyWsOpts(api), // Rancher API
|
|
285
|
-
'/v3-public': proxyOpts(api), // Rancher Unauthed API
|
|
286
|
-
'/api-ui': proxyOpts(api), // Browser API UI
|
|
287
|
-
'/meta': proxyMetaOpts(api), // Browser API UI
|
|
288
|
-
'/v1-*': proxyOpts(api), // SAML, KDM, etc
|
|
289
|
-
'/rancherversion': proxyPrimeOpts(api), // Rancher version endpoint
|
|
274
|
+
'/k8s': configHelper.proxyWsOpts(api), // Straight to a remote cluster (/k8s/clusters/<id>/)
|
|
275
|
+
'/pp': configHelper.proxyWsOpts(api), // For (epinio) standalone API
|
|
276
|
+
'/api': configHelper.proxyWsOpts(api), // Management k8s API
|
|
277
|
+
'/apis': configHelper.proxyWsOpts(api), // Management k8s API
|
|
278
|
+
'/v1': configHelper.proxyWsOpts(api), // Management Steve API
|
|
279
|
+
'/v3': configHelper.proxyWsOpts(api), // Rancher API
|
|
280
|
+
'/v3-public': configHelper.proxyOpts(api), // Rancher Unauthed API
|
|
281
|
+
'/api-ui': configHelper.proxyOpts(api), // Browser API UI
|
|
282
|
+
'/meta': configHelper.proxyMetaOpts(api), // Browser API UI
|
|
283
|
+
'/v1-*': configHelper.proxyOpts(api), // SAML, KDM, etc
|
|
284
|
+
'/rancherversion': configHelper.proxyPrimeOpts(api), // Rancher version endpoint
|
|
290
285
|
// These are for Ember embedding
|
|
291
|
-
'/c/*/edit': proxyOpts('https://127.0.0.1:8000'), // Can't proxy all of /c because that's used by Vue too
|
|
292
|
-
'/k/': proxyOpts('https://127.0.0.1:8000'),
|
|
293
|
-
'/g/': proxyOpts('https://127.0.0.1:8000'),
|
|
294
|
-
'/n/': proxyOpts('https://127.0.0.1:8000'),
|
|
295
|
-
'/p/': proxyOpts('https://127.0.0.1:8000'),
|
|
296
|
-
'/assets': proxyOpts('https://127.0.0.1:8000'),
|
|
297
|
-
'/translations': proxyOpts('https://127.0.0.1:8000'),
|
|
298
|
-
'/engines-dist': proxyOpts('https://127.0.0.1:8000'),
|
|
286
|
+
'/c/*/edit': configHelper.proxyOpts('https://127.0.0.1:8000'), // Can't proxy all of /c because that's used by Vue too
|
|
287
|
+
'/k/': configHelper.proxyOpts('https://127.0.0.1:8000'),
|
|
288
|
+
'/g/': configHelper.proxyOpts('https://127.0.0.1:8000'),
|
|
289
|
+
'/n/': configHelper.proxyOpts('https://127.0.0.1:8000'),
|
|
290
|
+
'/p/': configHelper.proxyOpts('https://127.0.0.1:8000'),
|
|
291
|
+
'/assets': configHelper.proxyOpts('https://127.0.0.1:8000'),
|
|
292
|
+
'/translations': configHelper.proxyOpts('https://127.0.0.1:8000'),
|
|
293
|
+
'/engines-dist': configHelper.proxyOpts('https://127.0.0.1:8000'),
|
|
299
294
|
};
|
|
300
295
|
|
|
301
296
|
const config = {
|
|
@@ -570,114 +565,3 @@ module.exports = function(dir, _appConfig) {
|
|
|
570
565
|
|
|
571
566
|
return config;
|
|
572
567
|
};
|
|
573
|
-
|
|
574
|
-
// ===============================================================================================
|
|
575
|
-
// Functions for the request proxying used in dev
|
|
576
|
-
// ===============================================================================================
|
|
577
|
-
|
|
578
|
-
function proxyMetaOpts(target) {
|
|
579
|
-
return {
|
|
580
|
-
target,
|
|
581
|
-
followRedirects: true,
|
|
582
|
-
secure: !dev,
|
|
583
|
-
changeOrigin: true,
|
|
584
|
-
onProxyReq,
|
|
585
|
-
onProxyReqWs,
|
|
586
|
-
onError,
|
|
587
|
-
onProxyRes,
|
|
588
|
-
};
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
function proxyOpts(target) {
|
|
592
|
-
return {
|
|
593
|
-
target,
|
|
594
|
-
secure: !devPorts,
|
|
595
|
-
changeOrigin: true,
|
|
596
|
-
onProxyReq,
|
|
597
|
-
onProxyReqWs,
|
|
598
|
-
onError,
|
|
599
|
-
onProxyRes
|
|
600
|
-
};
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
// Intercept the /rancherversion API call wnad modify the 'RancherPrime' value
|
|
604
|
-
// if configured to do so by the environment variable PRIME
|
|
605
|
-
function proxyPrimeOpts(target) {
|
|
606
|
-
const opts = proxyOpts(target);
|
|
607
|
-
|
|
608
|
-
// Don't intercept if the PRIME environment variable is not set
|
|
609
|
-
if (!prime?.length) {
|
|
610
|
-
return opts;
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
opts.onProxyRes = (proxyRes, req, res) => {
|
|
614
|
-
const _end = res.end;
|
|
615
|
-
let body = '';
|
|
616
|
-
|
|
617
|
-
proxyRes.on( 'data', (data) => {
|
|
618
|
-
data = data.toString('utf-8');
|
|
619
|
-
body += data;
|
|
620
|
-
});
|
|
621
|
-
|
|
622
|
-
res.write = () => {};
|
|
623
|
-
|
|
624
|
-
res.end = () => {
|
|
625
|
-
let output = body;
|
|
626
|
-
|
|
627
|
-
try {
|
|
628
|
-
const out = JSON.parse(body);
|
|
629
|
-
|
|
630
|
-
out.RancherPrime = prime;
|
|
631
|
-
output = JSON.stringify(out);
|
|
632
|
-
} catch (err) {}
|
|
633
|
-
|
|
634
|
-
res.setHeader('content-length', output.length );
|
|
635
|
-
res.setHeader('content-type', 'application/json' );
|
|
636
|
-
res.setHeader('transfer-encoding', '');
|
|
637
|
-
res.setHeader('cache-control', 'no-cache');
|
|
638
|
-
res.writeHead(proxyRes.statusCode);
|
|
639
|
-
_end.apply(res, [output]);
|
|
640
|
-
};
|
|
641
|
-
};
|
|
642
|
-
|
|
643
|
-
return opts;
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
function onProxyRes(proxyRes, req, res) {
|
|
647
|
-
if (devPorts) {
|
|
648
|
-
proxyRes.headers['X-Frame-Options'] = 'ALLOWALL';
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
function proxyWsOpts(target) {
|
|
653
|
-
return {
|
|
654
|
-
...proxyOpts(target),
|
|
655
|
-
ws: true,
|
|
656
|
-
changeOrigin: true,
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
function onProxyReq(proxyReq, req) {
|
|
661
|
-
if (!(proxyReq._currentRequest && proxyReq._currentRequest._headerSent)) {
|
|
662
|
-
proxyReq.setHeader('x-api-host', req.headers['host']);
|
|
663
|
-
proxyReq.setHeader('x-forwarded-proto', 'https');
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
function onProxyReqWs(proxyReq, req, socket, options, head) {
|
|
668
|
-
req.headers.origin = options.target.href;
|
|
669
|
-
proxyReq.setHeader('origin', options.target.href);
|
|
670
|
-
proxyReq.setHeader('x-api-host', req.headers['host']);
|
|
671
|
-
proxyReq.setHeader('x-forwarded-proto', 'https');
|
|
672
|
-
// console.log(proxyReq.getHeaders());
|
|
673
|
-
|
|
674
|
-
socket.on('error', (err) => {
|
|
675
|
-
console.error('Proxy WS Error:', err); // eslint-disable-line no-console
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
function onError(err, req, res) {
|
|
680
|
-
res.statusCode = 598;
|
|
681
|
-
console.error('Proxy Error:', err); // eslint-disable-line no-console
|
|
682
|
-
res.write(JSON.stringify(err));
|
|
683
|
-
}
|