@rancher/shell 0.3.7 → 0.3.9
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 +55 -14
- package/babel.config.js +17 -4
- package/components/CodeMirror.vue +146 -14
- package/components/ContainerResourceLimit.vue +14 -1
- package/components/CruResource.vue +21 -5
- package/components/ExplorerProjectsNamespaces.vue +5 -1
- package/components/GroupPanel.vue +57 -0
- package/components/Inactivity.vue +229 -0
- package/components/YamlEditor.vue +2 -2
- package/components/form/ArrayList.vue +1 -1
- package/components/form/KeyValue.vue +34 -1
- package/components/form/MatchExpressions.vue +120 -21
- package/components/form/NodeAffinity.vue +54 -4
- package/components/form/PodAffinity.vue +160 -47
- package/components/form/Tolerations.vue +40 -4
- package/components/form/__tests__/ArrayList.test.ts +3 -3
- package/components/form/__tests__/MatchExpressions.test.ts +1 -1
- package/components/nav/Header.vue +2 -0
- package/config/settings.ts +10 -1
- package/core/plugins-loader.js +0 -2
- package/creators/app/files/.gitignore +73 -0
- package/creators/app/init +1 -0
- package/edit/configmap.vue +33 -6
- package/edit/provisioning.cattle.io.cluster/AgentConfiguration.vue +326 -0
- package/edit/provisioning.cattle.io.cluster/index.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +63 -15
- package/edit/workload/mixins/workload.js +12 -4
- package/layouts/blank.vue +4 -0
- package/layouts/default.vue +3 -0
- package/layouts/home.vue +4 -1
- package/layouts/plain.vue +4 -1
- package/mixins/chart.js +1 -1
- package/models/batch.cronjob.js +18 -3
- package/models/provisioning.cattle.io.cluster.js +24 -0
- package/models/workload.js +1 -1
- package/package.json +2 -3
- package/pages/auth/login.vue +1 -0
- package/pages/c/_cluster/explorer/index.vue +1 -4
- package/pages/c/_cluster/settings/performance.vue +61 -7
- package/pages/prefs.vue +18 -2
- package/pkg/vue.config.js +0 -1
- package/plugins/codemirror.js +158 -0
- package/public/index.html +1 -1
- package/store/index.js +36 -21
- package/types/shell/index.d.ts +20 -1
- package/utils/create-yaml.js +105 -8
- package/utils/settings.ts +12 -0
- package/vue.config.js +2 -2
|
@@ -1249,7 +1249,7 @@ cluster:
|
|
|
1249
1249
|
memory: Memory
|
|
1250
1250
|
disk: Disk
|
|
1251
1251
|
image: Image
|
|
1252
|
-
network:
|
|
1252
|
+
network:
|
|
1253
1253
|
title: Networks
|
|
1254
1254
|
network: Network
|
|
1255
1255
|
addNetwork: Add Network
|
|
@@ -1611,6 +1611,27 @@ cluster:
|
|
|
1611
1611
|
additionalManifest:
|
|
1612
1612
|
title: Additional Manifest
|
|
1613
1613
|
tooltip: 'Additional Kubernetes Manifest YAML to be applied to the cluster on startup.'
|
|
1614
|
+
agentConfig:
|
|
1615
|
+
tabs:
|
|
1616
|
+
cluster: Cluster Agent
|
|
1617
|
+
fleet: Fleet Agent
|
|
1618
|
+
groups:
|
|
1619
|
+
deploymentLabels: Deployment Labels
|
|
1620
|
+
selector: Selector
|
|
1621
|
+
podAffinity: Affinity
|
|
1622
|
+
podTolerations: Tolerations
|
|
1623
|
+
podRequestsAndLimits: Requests and Limits
|
|
1624
|
+
subGroups:
|
|
1625
|
+
podAffinityAnti: Pod Affinity/Anti-Affinity
|
|
1626
|
+
nodeAffinity: Node Affinity
|
|
1627
|
+
banners:
|
|
1628
|
+
advanced: These are advanced configuration options. Generally, they should be left as-is.
|
|
1629
|
+
tolerations: Additional Pod Tolerations will be added to the default Tolerations applied by Rancher.
|
|
1630
|
+
limits: Pod Requests and Limits do not have a default configuration.
|
|
1631
|
+
windowsCompatibility: "We do not recommended removing the Node Affinity rule that prevents the <b>agent</b> from running on Windows nodes as this is not a supported configuration."
|
|
1632
|
+
affinity:
|
|
1633
|
+
default: Use default affinity rules defined by Rancher
|
|
1634
|
+
custom: Use custom affinity rules
|
|
1614
1635
|
advanced:
|
|
1615
1636
|
argInfo:
|
|
1616
1637
|
title: Additional Kubelet Args
|
|
@@ -1827,7 +1848,7 @@ cluster:
|
|
|
1827
1848
|
option: Default - RKE2 Embedded
|
|
1828
1849
|
defaultPodSecurityAdmissionConfigurationTemplateName:
|
|
1829
1850
|
label: Pod Security Admission Configuration Template
|
|
1830
|
-
option:
|
|
1851
|
+
option:
|
|
1831
1852
|
none: (None)
|
|
1832
1853
|
default: Default - RKE2 Embedded
|
|
1833
1854
|
cisProfile:
|
|
@@ -2202,16 +2223,16 @@ fleet:
|
|
|
2202
2223
|
error: Error
|
|
2203
2224
|
ready: Ready
|
|
2204
2225
|
errors: Errors
|
|
2205
|
-
workspaces:
|
|
2226
|
+
workspaces:
|
|
2206
2227
|
tabs:
|
|
2207
2228
|
restrictions: Allowed Target Namespaces
|
|
2208
2229
|
timeout: Workspace creation timeout. It's possible the workspace was created. We suggest checking the workspace page before trying to create another.
|
|
2209
|
-
restrictions:
|
|
2230
|
+
restrictions:
|
|
2210
2231
|
addTitle: 'allowedTargetNamespaces'
|
|
2211
2232
|
addLabel: Add
|
|
2212
2233
|
banner: "{count, plural,
|
|
2213
2234
|
=0 { Adding namespaces here will create a GitRepoRestriction. }
|
|
2214
|
-
other { Only the Git Repo Restriction's <code>allowedTargetNamespaces</code> is managed here. You can make additional changes to the Git Repo Restriction}
|
|
2235
|
+
other { Only the Git Repo Restriction's <code>allowedTargetNamespaces</code> is managed here. You can make additional changes to the Git Repo Restriction}
|
|
2215
2236
|
}"
|
|
2216
2237
|
footer:
|
|
2217
2238
|
docs: Docs
|
|
@@ -2260,7 +2281,7 @@ gatekeeperIndex:
|
|
|
2260
2281
|
unavailable: OPA + Gatekeeper is not available in the system-charts catalog.
|
|
2261
2282
|
violations: Violations
|
|
2262
2283
|
|
|
2263
|
-
gatekeeperInstall:
|
|
2284
|
+
gatekeeperInstall:
|
|
2264
2285
|
auditInterval: Auto Interval
|
|
2265
2286
|
constraintViolationsLimit: Constraint Violations Limit
|
|
2266
2287
|
runtimeDefaultSeccompProfile: Enable Runtime Default Seccomp Profile
|
|
@@ -3952,6 +3973,15 @@ podDisruptionBudget:
|
|
|
3952
3973
|
maxUnavailable:
|
|
3953
3974
|
label: Max. unavailable Pods
|
|
3954
3975
|
|
|
3976
|
+
inactivity:
|
|
3977
|
+
title: Session expiring
|
|
3978
|
+
titleExpired: Session expired
|
|
3979
|
+
banner: Your session is about to expire due to inactivity. Any unsaved changes will be lost.
|
|
3980
|
+
bannerExpired: Your session has expired in this tab due to inactivity.
|
|
3981
|
+
content: Click “Resume Session” to keep the session in this tab active or refresh the browser after the session has expired.
|
|
3982
|
+
contentExpired: To return to this page click “Refresh” below or refresh the browser.
|
|
3983
|
+
cta: Resume Session
|
|
3984
|
+
ctaExpired: Refresh
|
|
3955
3985
|
|
|
3956
3986
|
# Rancher Extensions
|
|
3957
3987
|
plugins:
|
|
@@ -4051,7 +4081,7 @@ plugins:
|
|
|
4051
4081
|
podSecurityAdmission:
|
|
4052
4082
|
name: Pod Security Admission
|
|
4053
4083
|
description: Define the admission control mode you want to use for the pod security
|
|
4054
|
-
banner:
|
|
4084
|
+
banner:
|
|
4055
4085
|
modifications: 'Changing any template that is currently in use will cause an update to those live clusters the next time the cluster is updated'
|
|
4056
4086
|
labels:
|
|
4057
4087
|
enforce: Enforce
|
|
@@ -4065,7 +4095,7 @@ podSecurityAdmission:
|
|
|
4065
4095
|
restricted: restricted
|
|
4066
4096
|
version:
|
|
4067
4097
|
placeholder: 'Version (default: latest)'
|
|
4068
|
-
exemptions:
|
|
4098
|
+
exemptions:
|
|
4069
4099
|
title: Exemptions
|
|
4070
4100
|
description: Allow the creation of pods for specific Usernames, RuntimeClassNames, and Namespaces that would otherwise be prohibited due to the policies set above.
|
|
4071
4101
|
placeholder: Enter a comma separated list of {psaExemptionsControl}
|
|
@@ -5186,7 +5216,7 @@ storageClass:
|
|
|
5186
5216
|
warning: 'The {provisioner} in-tree plugin is deprecated: Find a CSI driver <a target="_blank" rel="noopener noreferrer nofollow" href="https://kubernetes-csi.github.io/docs/drivers.html">here.</a>'
|
|
5187
5217
|
harvesterhci:
|
|
5188
5218
|
title: Harvester (CSI)
|
|
5189
|
-
warning:
|
|
5219
|
+
warning:
|
|
5190
5220
|
unSatisfiesVersion: Please upgrade your Harvester CSI driver version to use this feature. (csi-driver >= v0.1.15)
|
|
5191
5221
|
hostStorageClass:
|
|
5192
5222
|
label: Host Storage Class
|
|
@@ -5935,15 +5965,19 @@ workload:
|
|
|
5935
5965
|
antiAffinityTitle: Run pods on nodes without pods matching these selectors
|
|
5936
5966
|
affinityOption: Affinity
|
|
5937
5967
|
antiAffinityOption: Anti-Affinity
|
|
5968
|
+
matchFields:
|
|
5969
|
+
label: Fields
|
|
5938
5970
|
matchExpressions:
|
|
5971
|
+
label: Expressions
|
|
5939
5972
|
addRule: Add Rule
|
|
5940
5973
|
doesNotExist: is not set
|
|
5941
5974
|
exists: is set
|
|
5942
5975
|
greaterThan: ">"
|
|
5943
5976
|
in: in list
|
|
5944
|
-
inNamespaces: "
|
|
5977
|
+
inNamespaces: "Specific namespaces"
|
|
5945
5978
|
key: Key
|
|
5946
5979
|
lessThan: <
|
|
5980
|
+
matchType: Match Type
|
|
5947
5981
|
namespaces: Namespaces
|
|
5948
5982
|
notIn: not in list
|
|
5949
5983
|
operator: Operator
|
|
@@ -5959,6 +5993,7 @@ workload:
|
|
|
5959
5993
|
schedulingRules: Run pods on node(s) matching scheduling rules
|
|
5960
5994
|
specificNode: Run pods on specific node(s)
|
|
5961
5995
|
thisPodNamespace: This pod's namespace
|
|
5996
|
+
allNamespaces: All namespaces
|
|
5962
5997
|
topologyKey:
|
|
5963
5998
|
label: Topology Key
|
|
5964
5999
|
placeholder: e.g. failure-domain.beta.kubernetes.io/zone
|
|
@@ -5986,7 +6021,7 @@ workload:
|
|
|
5986
6021
|
effectOptions:
|
|
5987
6022
|
all: All
|
|
5988
6023
|
noExecute: NoExecute
|
|
5989
|
-
noSchedule: "NoSchedule
|
|
6024
|
+
noSchedule: "NoSchedule"
|
|
5990
6025
|
preferNoSchedule: PreferNoSchedule
|
|
5991
6026
|
labelKey: Label Key
|
|
5992
6027
|
operator: Operator
|
|
@@ -6131,8 +6166,6 @@ workload:
|
|
|
6131
6166
|
pod: Pod
|
|
6132
6167
|
containers: Containers
|
|
6133
6168
|
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
6169
|
##############################
|
|
6137
6170
|
# Model Properties
|
|
6138
6171
|
##############################
|
|
@@ -6778,7 +6811,7 @@ typeLabel:
|
|
|
6778
6811
|
{count, plural,
|
|
6779
6812
|
one { Cluster Registration Token }
|
|
6780
6813
|
other { Cluster Registration Tokens }
|
|
6781
|
-
}
|
|
6814
|
+
}
|
|
6782
6815
|
|
|
6783
6816
|
action:
|
|
6784
6817
|
clone: Clone
|
|
@@ -7002,6 +7035,14 @@ performance:
|
|
|
7002
7035
|
label: Websocket Web Worker
|
|
7003
7036
|
description: Updates to resources pushed to the UI come via WebSocket and are handled in the UI thread. Enable this option to handle cluster WebSocket updates in a Web Worker in a separate thread. This should help the responsiveness of the UI in systems where resources change often.
|
|
7004
7037
|
checkboxLabel: Enable Advanced Websocket Web Worker
|
|
7038
|
+
inactivity:
|
|
7039
|
+
title: Inactivity
|
|
7040
|
+
checkboxLabel: Enable inactivity session expiration
|
|
7041
|
+
inputLabel: Inactivity timeout (minutes)
|
|
7042
|
+
information: To change the automatic logout behaviour, edit the authorisation and/or session token timeout values (<code>auth-user-session-ttl-minutes</code> and <code>auth-token-max-ttl-minutes</code>) in the Settings page.
|
|
7043
|
+
description: When enabled and the user is inactive past the specified timeout, the UI will no longer fresh page content and the user must reload the page to continue.
|
|
7044
|
+
authUserTTL: This timeout cannot be higher than the user session timeout auth-user-session-ttl-minutes, which is currently {current} minutes.
|
|
7045
|
+
|
|
7005
7046
|
|
|
7006
7047
|
banner:
|
|
7007
7048
|
label: Fixed Banners
|
package/babel.config.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
|
|
1
|
+
module.exports = function(api) {
|
|
2
|
+
api.cache(true);
|
|
3
|
+
const presets = [
|
|
3
4
|
[
|
|
4
5
|
'@vue/cli-plugin-babel/preset',
|
|
5
6
|
{ useBuiltIns: false }
|
|
@@ -8,6 +9,18 @@ module.exports = {
|
|
|
8
9
|
'@babel/preset-env',
|
|
9
10
|
{ targets: { node: 'current' } }
|
|
10
11
|
]
|
|
11
|
-
]
|
|
12
|
-
env
|
|
12
|
+
];
|
|
13
|
+
const env = { test: { presets: [['@babel/env', { targets: { node: 'current' } }]] } };
|
|
14
|
+
|
|
15
|
+
const plugins = [];
|
|
16
|
+
|
|
17
|
+
if (process.env.NODE_ENV === 'test') {
|
|
18
|
+
plugins.push('transform-require-context');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
presets,
|
|
23
|
+
plugins,
|
|
24
|
+
env
|
|
25
|
+
};
|
|
13
26
|
};
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { KEYMAP } from '@shell/store/prefs';
|
|
3
|
+
import { _EDIT, _VIEW } from '@shell/config/query-params';
|
|
3
4
|
|
|
4
5
|
export default {
|
|
5
6
|
name: 'CodeMirror',
|
|
6
7
|
props: {
|
|
8
|
+
/**
|
|
9
|
+
* Sets the edit mode for Text Area.
|
|
10
|
+
* @values _EDIT, _VIEW
|
|
11
|
+
*/
|
|
12
|
+
mode: {
|
|
13
|
+
type: String,
|
|
14
|
+
default: _EDIT
|
|
15
|
+
},
|
|
7
16
|
value: {
|
|
8
17
|
type: String,
|
|
9
18
|
required: true,
|
|
@@ -11,14 +20,26 @@ export default {
|
|
|
11
20
|
options: {
|
|
12
21
|
type: Object,
|
|
13
22
|
default: () => {}
|
|
23
|
+
},
|
|
24
|
+
asTextArea: {
|
|
25
|
+
type: Boolean,
|
|
26
|
+
default: false
|
|
14
27
|
}
|
|
15
28
|
},
|
|
16
29
|
|
|
17
30
|
data() {
|
|
18
|
-
return {
|
|
31
|
+
return {
|
|
32
|
+
codeMirrorRef: null,
|
|
33
|
+
loaded: false
|
|
34
|
+
};
|
|
19
35
|
},
|
|
20
36
|
|
|
21
37
|
computed: {
|
|
38
|
+
|
|
39
|
+
isDisabled() {
|
|
40
|
+
return this.mode === _VIEW;
|
|
41
|
+
},
|
|
42
|
+
|
|
22
43
|
combinedOptions() {
|
|
23
44
|
const theme = this.$store.getters['prefs/theme'];
|
|
24
45
|
const keymap = this.$store.getters['prefs/get'](KEYMAP);
|
|
@@ -39,6 +60,12 @@ export default {
|
|
|
39
60
|
showCursorWhenSelecting: true,
|
|
40
61
|
};
|
|
41
62
|
|
|
63
|
+
if (this.asTextArea) {
|
|
64
|
+
out.lineNumbers = false;
|
|
65
|
+
out.tabSize = 0;
|
|
66
|
+
out.extraKeys = { Tab: false };
|
|
67
|
+
}
|
|
68
|
+
|
|
42
69
|
Object.assign(out, this.options);
|
|
43
70
|
|
|
44
71
|
return out;
|
|
@@ -58,35 +85,44 @@ export default {
|
|
|
58
85
|
methods: {
|
|
59
86
|
|
|
60
87
|
focus() {
|
|
61
|
-
if ( this.$refs.
|
|
62
|
-
this.$refs.
|
|
88
|
+
if ( this.$refs.codeMirrorRef ) {
|
|
89
|
+
this.$refs.codeMirrorRef.codemirror.focus();
|
|
63
90
|
}
|
|
64
91
|
},
|
|
65
92
|
|
|
66
93
|
refresh() {
|
|
67
|
-
if ( this.$refs.
|
|
68
|
-
this.$refs.
|
|
94
|
+
if ( this.$refs.codeMirrorRef ) {
|
|
95
|
+
this.$refs.codeMirrorRef.refresh();
|
|
69
96
|
}
|
|
70
97
|
},
|
|
71
98
|
|
|
72
|
-
onReady(
|
|
99
|
+
onReady(codeMirrorRef) {
|
|
73
100
|
this.$nextTick(() => {
|
|
74
|
-
|
|
101
|
+
codeMirrorRef.refresh();
|
|
102
|
+
this.codeMirrorRef = codeMirrorRef;
|
|
75
103
|
});
|
|
76
|
-
this.$emit('onReady',
|
|
104
|
+
this.$emit('onReady', codeMirrorRef);
|
|
77
105
|
},
|
|
78
106
|
|
|
79
107
|
onInput(newCode) {
|
|
80
108
|
this.$emit('onInput', newCode);
|
|
81
109
|
},
|
|
82
110
|
|
|
83
|
-
onChanges(
|
|
84
|
-
this.$emit('onChanges',
|
|
111
|
+
onChanges(codeMirrorRef, changes) {
|
|
112
|
+
this.$emit('onChanges', codeMirrorRef, changes);
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
onFocus() {
|
|
116
|
+
this.$emit('onFocus', true);
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
onBlur() {
|
|
120
|
+
this.$emit('onFocus', false);
|
|
85
121
|
},
|
|
86
122
|
|
|
87
123
|
updateValue(value) {
|
|
88
|
-
if ( this.$refs.
|
|
89
|
-
this.$refs.
|
|
124
|
+
if ( this.$refs.codeMirrorRef ) {
|
|
125
|
+
this.$refs.codeMirrorRef.codemirror.doc.setValue(value);
|
|
90
126
|
}
|
|
91
127
|
}
|
|
92
128
|
}
|
|
@@ -95,15 +131,21 @@ export default {
|
|
|
95
131
|
|
|
96
132
|
<template>
|
|
97
133
|
<client-only placeholder=" Loading...">
|
|
98
|
-
<div
|
|
134
|
+
<div
|
|
135
|
+
class="code-mirror"
|
|
136
|
+
:class="{['as-text-area']: asTextArea}"
|
|
137
|
+
>
|
|
99
138
|
<codemirror
|
|
100
139
|
v-if="loaded"
|
|
101
|
-
ref="
|
|
140
|
+
ref="codeMirrorRef"
|
|
102
141
|
:value="value"
|
|
103
142
|
:options="combinedOptions"
|
|
143
|
+
:disabled="isDisabled"
|
|
104
144
|
@ready="onReady"
|
|
105
145
|
@input="onInput"
|
|
106
146
|
@changes="onChanges"
|
|
147
|
+
@focus="onFocus"
|
|
148
|
+
@blur="onBlur"
|
|
107
149
|
/>
|
|
108
150
|
<div v-else>
|
|
109
151
|
Loading...
|
|
@@ -120,5 +162,95 @@ export default {
|
|
|
120
162
|
height: initial;
|
|
121
163
|
background: none
|
|
122
164
|
}
|
|
165
|
+
|
|
166
|
+
&.as-text-area {
|
|
167
|
+
min-height: 40px;
|
|
168
|
+
position: relative;
|
|
169
|
+
display: block;
|
|
170
|
+
box-sizing: border-box;
|
|
171
|
+
width: 100%;
|
|
172
|
+
padding: 10px;
|
|
173
|
+
background-color: var(--input-bg);
|
|
174
|
+
border-radius: var(--border-radius);
|
|
175
|
+
border: solid var(--border-width) var(--input-border);
|
|
176
|
+
color: var(--input-text);
|
|
177
|
+
|
|
178
|
+
&:hover {
|
|
179
|
+
border-color: var(--input-hover-border);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
&:focus, &.focus {
|
|
183
|
+
outline: none;
|
|
184
|
+
border-color: var(--outline);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.CodeMirror-wrap pre {
|
|
188
|
+
word-break: break-word;
|
|
189
|
+
}
|
|
190
|
+
.CodeMirror-code {
|
|
191
|
+
.CodeMirror-line {
|
|
192
|
+
&:not(:last-child)>span:after,
|
|
193
|
+
.cm-markdown-single-trailing-space-odd:before,
|
|
194
|
+
.cm-markdown-single-trailing-space-even:before {
|
|
195
|
+
color: var(--muted);
|
|
196
|
+
position: absolute;
|
|
197
|
+
line-height: 20px;
|
|
198
|
+
pointer-events: none;
|
|
199
|
+
}
|
|
200
|
+
&:not(:last-child)>span:after {
|
|
201
|
+
content: '↵';
|
|
202
|
+
margin-left: 2px;
|
|
203
|
+
}
|
|
204
|
+
.cm-markdown-single-trailing-space-odd:before,
|
|
205
|
+
.cm-markdown-single-trailing-space-even:before {
|
|
206
|
+
font-weight: bold;
|
|
207
|
+
content: '·';
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.CodeMirror-lines {
|
|
213
|
+
color: var(--input-text);
|
|
214
|
+
padding: 0;
|
|
215
|
+
|
|
216
|
+
.CodeMirror-line > span > span {
|
|
217
|
+
&.cm-overlay {
|
|
218
|
+
font-family: monospace;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.CodeMirror-line > span {
|
|
223
|
+
font-family: $body-font;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.CodeMirror-sizer {
|
|
228
|
+
min-height: 20px;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.CodeMirror-selected {
|
|
232
|
+
background-color: var(--primary) !important;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.CodeMirror-selectedtext {
|
|
236
|
+
color: var(--primary-text);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.CodeMirror-line::selection,
|
|
240
|
+
.CodeMirror-line > span::selection,
|
|
241
|
+
.CodeMirror-line > span > span::selection {
|
|
242
|
+
color: var(--primary-text);
|
|
243
|
+
background-color: var(--primary);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.CodeMirror-line::-moz-selection,
|
|
247
|
+
.CodeMirror-line > span::-moz-selection,
|
|
248
|
+
.CodeMirror-line > span > span::-moz-selection {
|
|
249
|
+
color: var(--primary-text);
|
|
250
|
+
background-color: var(--primary);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
123
254
|
}
|
|
255
|
+
|
|
124
256
|
</style>
|
|
@@ -26,6 +26,11 @@ export default {
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
|
|
29
|
+
handleGpuLimit: {
|
|
30
|
+
type: Boolean,
|
|
31
|
+
default: true
|
|
32
|
+
},
|
|
33
|
+
|
|
29
34
|
registerBeforeHook: {
|
|
30
35
|
type: Function,
|
|
31
36
|
default: null
|
|
@@ -180,6 +185,7 @@ export default {
|
|
|
180
185
|
:input-exponent="-1"
|
|
181
186
|
:output-modifier="true"
|
|
182
187
|
:base-unit="t('suffix.cpus')"
|
|
188
|
+
data-testid="cpu-reservation"
|
|
183
189
|
@input="updateLimits"
|
|
184
190
|
/>
|
|
185
191
|
</span>
|
|
@@ -192,6 +198,7 @@ export default {
|
|
|
192
198
|
:input-exponent="2"
|
|
193
199
|
:increment="1024"
|
|
194
200
|
:output-modifier="true"
|
|
201
|
+
data-testid="memory-reservation"
|
|
195
202
|
@input="updateLimits"
|
|
196
203
|
/>
|
|
197
204
|
</span>
|
|
@@ -207,6 +214,7 @@ export default {
|
|
|
207
214
|
:input-exponent="-1"
|
|
208
215
|
:output-modifier="true"
|
|
209
216
|
:base-unit="t('suffix.cpus')"
|
|
217
|
+
data-testid="cpu-limit"
|
|
210
218
|
@input="updateLimits"
|
|
211
219
|
/>
|
|
212
220
|
</span>
|
|
@@ -219,11 +227,15 @@ export default {
|
|
|
219
227
|
:input-exponent="2"
|
|
220
228
|
:increment="1024"
|
|
221
229
|
:output-modifier="true"
|
|
230
|
+
data-testid="memory-limit"
|
|
222
231
|
@input="updateLimits"
|
|
223
232
|
/>
|
|
224
233
|
</span>
|
|
225
234
|
</div>
|
|
226
|
-
<div
|
|
235
|
+
<div
|
|
236
|
+
v-if="handleGpuLimit"
|
|
237
|
+
class="row"
|
|
238
|
+
>
|
|
227
239
|
<span class="col span-6">
|
|
228
240
|
<UnitInput
|
|
229
241
|
v-model="limitsGpu"
|
|
@@ -231,6 +243,7 @@ export default {
|
|
|
231
243
|
:label="t('containerResourceLimit.limitsGpu')"
|
|
232
244
|
:mode="mode"
|
|
233
245
|
:base-unit="t('suffix.gpus')"
|
|
246
|
+
data-testid="gpu-limit"
|
|
234
247
|
@input="updateLimits"
|
|
235
248
|
/>
|
|
236
249
|
</span>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import isEmpty from 'lodash/isEmpty';
|
|
3
|
-
import {
|
|
3
|
+
import { createYamlWithOptions } from '@shell/utils/create-yaml';
|
|
4
4
|
import { clone, get } from '@shell/utils/object';
|
|
5
5
|
import { SCHEMA, NAMESPACE } from '@shell/config/types';
|
|
6
6
|
import ResourceYaml from '@shell/components/ResourceYaml';
|
|
@@ -101,6 +101,11 @@ export default {
|
|
|
101
101
|
default: null,
|
|
102
102
|
},
|
|
103
103
|
|
|
104
|
+
preventEnterSubmit: {
|
|
105
|
+
type: Boolean,
|
|
106
|
+
default: false,
|
|
107
|
+
},
|
|
108
|
+
|
|
104
109
|
applyHooks: {
|
|
105
110
|
type: Function,
|
|
106
111
|
default: null,
|
|
@@ -141,6 +146,11 @@ export default {
|
|
|
141
146
|
description: {
|
|
142
147
|
type: String,
|
|
143
148
|
default: ''
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
yamlModifiers: {
|
|
152
|
+
type: Object,
|
|
153
|
+
default: undefined
|
|
144
154
|
}
|
|
145
155
|
},
|
|
146
156
|
|
|
@@ -296,7 +306,7 @@ export default {
|
|
|
296
306
|
}
|
|
297
307
|
},
|
|
298
308
|
|
|
299
|
-
createResourceYaml() {
|
|
309
|
+
createResourceYaml(modifiers) {
|
|
300
310
|
const resource = this.resource;
|
|
301
311
|
|
|
302
312
|
if ( typeof this.generateYaml === 'function' ) {
|
|
@@ -306,7 +316,7 @@ export default {
|
|
|
306
316
|
const schemas = this.$store.getters[`${ inStore }/all`](SCHEMA);
|
|
307
317
|
const clonedResource = clone(resource);
|
|
308
318
|
|
|
309
|
-
const out =
|
|
319
|
+
const out = createYamlWithOptions(schemas, resource.type, clonedResource, modifiers);
|
|
310
320
|
|
|
311
321
|
return out;
|
|
312
322
|
}
|
|
@@ -317,7 +327,7 @@ export default {
|
|
|
317
327
|
await this.applyHooks(BEFORE_SAVE_HOOKS);
|
|
318
328
|
}
|
|
319
329
|
|
|
320
|
-
const resourceYaml = this.createResourceYaml();
|
|
330
|
+
const resourceYaml = this.createResourceYaml(this.yamlModifiers);
|
|
321
331
|
|
|
322
332
|
this.resourceYaml = resourceYaml;
|
|
323
333
|
this.showAsForm = false;
|
|
@@ -380,6 +390,12 @@ export default {
|
|
|
380
390
|
throw new Error(`Could not create the new namespace. ${ e.message }`);
|
|
381
391
|
}
|
|
382
392
|
}
|
|
393
|
+
},
|
|
394
|
+
|
|
395
|
+
onPressEnter(event) {
|
|
396
|
+
if (this.preventEnterSubmit) {
|
|
397
|
+
event.preventDefault();
|
|
398
|
+
}
|
|
383
399
|
}
|
|
384
400
|
}
|
|
385
401
|
};
|
|
@@ -398,7 +414,7 @@ export default {
|
|
|
398
414
|
:is="(isView? 'div' : 'form')"
|
|
399
415
|
class="create-resource-container cru__form"
|
|
400
416
|
@submit.prevent
|
|
401
|
-
@keydown.enter
|
|
417
|
+
@keydown.enter="onPressEnter($event)"
|
|
402
418
|
>
|
|
403
419
|
<div
|
|
404
420
|
v-if="hasErrors"
|
|
@@ -11,6 +11,7 @@ import MoveModal from '@shell/components/MoveModal';
|
|
|
11
11
|
import { defaultTableSortGenerationFn } from '@shell/components/ResourceTable.vue';
|
|
12
12
|
import { NAMESPACE_FILTER_ALL_ORPHANS } from '@shell/utils/namespace-filter';
|
|
13
13
|
import ResourceFetch from '@shell/mixins/resource-fetch';
|
|
14
|
+
import DOMPurify from 'dompurify';
|
|
14
15
|
|
|
15
16
|
export default {
|
|
16
17
|
name: 'ListProjectNamespace',
|
|
@@ -319,7 +320,10 @@ export default {
|
|
|
319
320
|
const row = group.rows[0];
|
|
320
321
|
|
|
321
322
|
if (row.isFake) {
|
|
322
|
-
return
|
|
323
|
+
return DOMPurify.sanitize(
|
|
324
|
+
this.t('resourceTable.groupLabel.project', { name: row.project?.nameDisplay }, true),
|
|
325
|
+
{ ALLOWED_TAGS: ['span'] }
|
|
326
|
+
);
|
|
323
327
|
}
|
|
324
328
|
|
|
325
329
|
return row.groupByLabel;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export default {
|
|
3
|
+
props: {
|
|
4
|
+
/**
|
|
5
|
+
* Label for the group
|
|
6
|
+
*/
|
|
7
|
+
label: {
|
|
8
|
+
type: String,
|
|
9
|
+
default: null
|
|
10
|
+
},
|
|
11
|
+
/**
|
|
12
|
+
* The i18n key to use for the label
|
|
13
|
+
*/
|
|
14
|
+
labelKey: {
|
|
15
|
+
type: String,
|
|
16
|
+
default: null
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
</script>
|
|
21
|
+
<template>
|
|
22
|
+
<div class="group-panel-outer">
|
|
23
|
+
<div class="group-panel">
|
|
24
|
+
<div class="group-panel-title">
|
|
25
|
+
<t
|
|
26
|
+
v-if="labelKey"
|
|
27
|
+
:k="labelKey"
|
|
28
|
+
/>
|
|
29
|
+
<template v-else-if="label">
|
|
30
|
+
{{ label }}
|
|
31
|
+
</template>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="group-panel-content">
|
|
34
|
+
<slot />
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<style lang="scss" scoped>
|
|
41
|
+
.group-panel {
|
|
42
|
+
border: 1px solid var(--border);
|
|
43
|
+
border-radius: 5px;
|
|
44
|
+
padding: 10px;
|
|
45
|
+
position: relative;
|
|
46
|
+
margin-top: 10px;
|
|
47
|
+
.group-panel-title {
|
|
48
|
+
position: absolute;
|
|
49
|
+
top: -7px;
|
|
50
|
+
background-color: var(--body-bg);
|
|
51
|
+
padding: 0 5px;
|
|
52
|
+
}
|
|
53
|
+
.group-panel-content {
|
|
54
|
+
position: relative;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
</style>
|