@rancher/shell 0.1.3 → 0.1.21

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.
Files changed (245) hide show
  1. package/assets/brand/suse/dark/rancher-logo.svg +1 -148
  2. package/assets/brand/suse/favicon.png +0 -0
  3. package/assets/brand/suse/rancher-logo.svg +1 -130
  4. package/assets/images/featured/img1.jpg +0 -0
  5. package/assets/images/featured.jpg +0 -0
  6. package/assets/images/generic-plugin.svg +1 -0
  7. package/assets/styles/themes/_dark.scss +3 -0
  8. package/assets/styles/themes/_light.scss +3 -0
  9. package/assets/styles/themes/_suse.scss +1 -1
  10. package/assets/translations/en-us.yaml +219 -47
  11. package/assets/translations/zh-hans.yaml +21 -24
  12. package/components/AsyncButton.vue +17 -2
  13. package/components/ButtonDropdown.vue +4 -0
  14. package/components/Carousel.vue +291 -0
  15. package/components/CommunityLinks.vue +64 -22
  16. package/components/CruResource.vue +11 -3
  17. package/components/Dialog.vue +102 -0
  18. package/components/ExplorerMembers.vue +2 -4
  19. package/components/ExplorerProjectsNamespaces.vue +25 -9
  20. package/components/IconMessage.vue +9 -1
  21. package/components/LazyImage.vue +21 -8
  22. package/components/LocaleSelector.vue +62 -29
  23. package/components/PromptRemove.vue +2 -2
  24. package/components/ResourceList/Masthead.vue +21 -1
  25. package/components/ResourceList/ResourceLoadingIndicator.vue +0 -8
  26. package/components/ResourceList/index.vue +9 -23
  27. package/components/ResourceTable.vue +7 -2
  28. package/components/SimpleBox.vue +6 -4
  29. package/components/SortableTable/index.vue +18 -25
  30. package/components/Tabbed/Tab.vue +5 -0
  31. package/components/Tabbed/index.vue +54 -9
  32. package/components/TypeDescription.vue +10 -1
  33. package/components/auth/Principal.vue +1 -0
  34. package/components/fleet/FleetBundles.vue +8 -3
  35. package/components/fleet/FleetClusters.vue +6 -0
  36. package/components/fleet/FleetRepos.vue +7 -1
  37. package/components/fleet/FleetSummary.vue +6 -0
  38. package/components/form/Command.vue +5 -0
  39. package/components/form/EnvVars.vue +5 -0
  40. package/components/form/KeyValue.vue +80 -58
  41. package/components/form/NameNsDescription.vue +13 -5
  42. package/components/form/NodeScheduling.vue +6 -1
  43. package/components/form/PodAffinity.vue +5 -0
  44. package/components/form/ResourceTabs/index.vue +5 -1
  45. package/components/form/ServiceNameSelect.vue +5 -0
  46. package/components/form/ValueFromResource.vue +7 -1
  47. package/components/formatter/ClusterLink.vue +3 -7
  48. package/components/nav/NamespaceFilter.vue +3 -3
  49. package/components/nav/TopLevelMenu.vue +12 -29
  50. package/config/home-links.js +155 -0
  51. package/config/labels-annotations.js +2 -1
  52. package/config/private-label.js +1 -1
  53. package/config/product/explorer.js +5 -4
  54. package/config/product/legacy.js +0 -47
  55. package/config/product/manager.js +0 -2
  56. package/config/product/multi-cluster-apps.js +0 -12
  57. package/config/product/settings.js +12 -1
  58. package/config/product/uiplugins.js +17 -0
  59. package/config/settings.js +23 -2
  60. package/config/types.js +5 -1
  61. package/config/uiplugins.js +117 -0
  62. package/config/version.js +17 -0
  63. package/content/docs/en-us/getting-started.md +1 -26
  64. package/core/plugin.ts +12 -0
  65. package/core/plugins.js +38 -2
  66. package/core/types.ts +6 -0
  67. package/creators/app/{.eslintignore → files/.eslintignore} +0 -0
  68. package/creators/app/{.eslintrc.js → files/.eslintrc.js} +0 -0
  69. package/creators/app/{.vscode → files/.vscode}/settings.json +0 -0
  70. package/creators/app/{babel.config.js → files/babel.config.js} +0 -0
  71. package/creators/app/{nuxt.config.js → files/nuxt.config.js} +0 -0
  72. package/creators/app/{tsconfig.json → files/tsconfig.json} +2 -1
  73. package/creators/app/init +16 -17
  74. package/creators/app/package.json +6 -0
  75. package/creators/pkg/{babel.config.js → files/babel.config.js} +0 -0
  76. package/creators/pkg/{index.ts → files/index.ts} +0 -0
  77. package/creators/pkg/{tsconfig.json → files/tsconfig.json} +13 -12
  78. package/creators/pkg/{vue.config.js → files/vue.config.js} +0 -0
  79. package/creators/pkg/init +1 -1
  80. package/creators/update/init +54 -0
  81. package/creators/update/package.json +20 -0
  82. package/creators/update/upgrade +56 -0
  83. package/creators/update/yarn-error.log +54 -0
  84. package/detail/provisioning.cattle.io.cluster.vue +3 -3
  85. package/detail/workload/index.vue +3 -2
  86. package/dialog/DiagnosticTimingsDialog.vue +116 -0
  87. package/dialog/RotateCertificatesDialog.vue +9 -3
  88. package/edit/auth/azuread.vue +28 -9
  89. package/edit/networking.k8s.io.ingress/index.vue +2 -2
  90. package/edit/persistentvolume/index.vue +51 -13
  91. package/edit/persistentvolumeclaim.vue +31 -13
  92. package/edit/pod.vue +27 -0
  93. package/edit/provisioning.cattle.io.cluster/rke2.vue +103 -24
  94. package/edit/service.vue +7 -5
  95. package/edit/workload/__tests__/Upgrading.test.ts +1 -0
  96. package/edit/workload/index.vue +32 -10
  97. package/edit/workload/mixins/workload.js +121 -126
  98. package/edit/workload/storage/ContainerMountPaths.vue +240 -0
  99. package/edit/workload/storage/Mount.vue +1 -0
  100. package/edit/workload/storage/awsElasticBlockStore.vue +20 -1
  101. package/edit/workload/storage/azureDisk.vue +22 -2
  102. package/edit/workload/storage/azureFile.vue +20 -2
  103. package/edit/workload/storage/csi/index.vue +23 -1
  104. package/edit/workload/storage/gcePersistentDisk.vue +20 -2
  105. package/edit/workload/storage/index.vue +33 -65
  106. package/edit/workload/storage/persistentVolumeClaim/index.vue +5 -0
  107. package/edit/workload/storage/secret.vue +6 -1
  108. package/edit/workload/storage/vsphereVolume.vue +11 -1
  109. package/layouts/default.vue +14 -8
  110. package/layouts/home.vue +9 -4
  111. package/layouts/plain.vue +10 -5
  112. package/list/catalog.cattle.io.app.vue +10 -9
  113. package/list/catalog.cattle.io.clusterrepo.vue +6 -61
  114. package/list/cis.cattle.io.clusterscan.vue +12 -12
  115. package/list/fleet.cattle.io.bundle.vue +33 -28
  116. package/list/fleet.cattle.io.cluster.vue +26 -22
  117. package/list/fleet.cattle.io.clustergroup.vue +6 -0
  118. package/list/fleet.cattle.io.clusterregistrationtoken.vue +28 -24
  119. package/list/fleet.cattle.io.gitrepo.vue +25 -14
  120. package/list/helm.cattle.io.projecthelmchart.vue +52 -33
  121. package/list/logging.banzaicloud.io.clusterflow.vue +7 -12
  122. package/list/logging.banzaicloud.io.flow.vue +7 -14
  123. package/list/management.cattle.io.cluster.vue +26 -15
  124. package/list/management.cattle.io.feature.vue +13 -8
  125. package/list/management.cattle.io.setting.vue +3 -3
  126. package/list/management.cattle.io.user.vue +38 -19
  127. package/list/monitoring.coreos.com.alertmanagerconfig.vue +8 -15
  128. package/list/namespace.vue +14 -1
  129. package/list/node.vue +13 -16
  130. package/list/persistentvolume.vue +16 -9
  131. package/list/persistentvolumeclaim.vue +5 -8
  132. package/list/provisioning.cattle.io.cluster.vue +35 -9
  133. package/list/service.vue +24 -12
  134. package/list/ui.cattle.io.navlink.vue +6 -0
  135. package/list/workload.vue +2 -2
  136. package/machine-config/harvester.vue +5 -3
  137. package/middleware/authenticated.js +6 -0
  138. package/mixins/resource-fetch.js +12 -18
  139. package/mixins/resource-manager.js +126 -0
  140. package/models/catalog.cattle.io.uiplugin.js +38 -0
  141. package/models/cluster/node.js +25 -2
  142. package/models/fleet.cattle.io.bundle.js +1 -1
  143. package/models/harvesterhci.io.management.cluster.js +11 -5
  144. package/models/pod.js +15 -5
  145. package/models/provisioning.cattle.io.cluster.js +16 -6
  146. package/models/workload.js +5 -3
  147. package/models/workload.service.js +10 -0
  148. package/nuxt.config.js +70 -25
  149. package/package.json +108 -109
  150. package/pages/auth/login.vue +11 -1
  151. package/pages/auth/verify.vue +9 -0
  152. package/pages/c/_cluster/apps/charts/index.vue +46 -1
  153. package/pages/c/_cluster/apps/charts/install.vue +10 -9
  154. package/pages/c/_cluster/explorer/index.vue +72 -9
  155. package/pages/c/_cluster/explorer/tools/index.vue +12 -5
  156. package/pages/c/_cluster/mcapps/index.vue +1 -1
  157. package/pages/c/_cluster/settings/DefaultLinksEditor.vue +108 -0
  158. package/pages/c/_cluster/settings/brand.vue +0 -40
  159. package/pages/c/_cluster/settings/links.vue +152 -0
  160. package/pages/c/_cluster/settings/performance.vue +90 -7
  161. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +232 -0
  162. package/pages/c/_cluster/uiplugins/InstallDialog.vue +293 -0
  163. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +300 -0
  164. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +125 -0
  165. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +261 -0
  166. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +122 -0
  167. package/pages/c/_cluster/uiplugins/index.vue +808 -0
  168. package/pages/diagnostic.vue +185 -101
  169. package/pages/docs/_doc.vue +3 -1
  170. package/pages/home.vue +21 -56
  171. package/pages/prefs.vue +108 -88
  172. package/pages/safeMode.vue +17 -0
  173. package/pages/support/index.vue +34 -137
  174. package/pkg/dynamic-importer.lib.js +4 -0
  175. package/plugins/dashboard-store/actions.js +19 -0
  176. package/plugins/dashboard-store/getters.js +20 -3
  177. package/plugins/dashboard-store/mutations.js +13 -7
  178. package/plugins/dashboard-store/resource-class.js +2 -2
  179. package/plugins/formatters.js +15 -0
  180. package/plugins/plugin.js +61 -6
  181. package/plugins/steve/getters.js +12 -0
  182. package/plugins/steve/mutations.js +1 -1
  183. package/plugins/steve/subscribe.js +94 -72
  184. package/plugins/steve/web-worker.steve-sub-worker.js +24 -15
  185. package/plugins/version.js +21 -0
  186. package/promptRemove/management.cattle.io.globalrole.vue +47 -0
  187. package/promptRemove/management.cattle.io.roletemplate.vue +47 -0
  188. package/promptRemove/mixin/roleDeletionCheck.js +97 -0
  189. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -7
  190. package/rancher-components/components/BadgeState/BadgeState.spec.ts +12 -0
  191. package/rancher-components/components/BadgeState/BadgeState.vue +107 -0
  192. package/rancher-components/components/BadgeState/index.ts +1 -0
  193. package/rancher-components/components/Banner/Banner.test.ts +13 -0
  194. package/rancher-components/components/Banner/Banner.vue +163 -0
  195. package/rancher-components/components/Banner/index.ts +1 -0
  196. package/rancher-components/components/Card/Card.vue +150 -0
  197. package/rancher-components/components/Card/index.ts +1 -0
  198. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +77 -0
  199. package/rancher-components/components/Form/Checkbox/Checkbox.vue +395 -0
  200. package/rancher-components/components/Form/Checkbox/index.ts +1 -0
  201. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +29 -0
  202. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +343 -0
  203. package/rancher-components/components/Form/LabeledInput/index.ts +1 -0
  204. package/rancher-components/components/Form/Radio/RadioButton.vue +270 -0
  205. package/rancher-components/components/Form/Radio/RadioGroup.vue +235 -0
  206. package/rancher-components/components/Form/Radio/index.ts +2 -0
  207. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +168 -0
  208. package/rancher-components/components/Form/TextArea/index.ts +1 -0
  209. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +107 -0
  210. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +137 -0
  211. package/rancher-components/components/Form/ToggleSwitch/index.ts +1 -0
  212. package/rancher-components/components/Form/index.ts +5 -0
  213. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +137 -0
  214. package/rancher-components/components/LabeledTooltip/index.ts +1 -0
  215. package/scripts/publish-shell.sh +40 -7
  216. package/scripts/record-deps.js +37 -0
  217. package/scripts/sync-shell-deps +37 -0
  218. package/scripts/test-plugins-build.sh +8 -5
  219. package/scripts/typegen.sh +84 -0
  220. package/store/auth.js +3 -0
  221. package/store/catalog.js +9 -8
  222. package/store/i18n.js +10 -1
  223. package/store/index.js +12 -3
  224. package/store/prefs.js +16 -0
  225. package/store/type-map.js +32 -5
  226. package/store/uiplugins.ts +15 -61
  227. package/types/shell/index.d.ts +3046 -0
  228. package/utils/__tests__/object.test.ts +0 -24
  229. package/utils/__tests__/selector.test.ts +1 -1
  230. package/utils/dynamic-importer.js +4 -0
  231. package/utils/favicon.js +8 -2
  232. package/utils/gc/gc-interval.ts +40 -0
  233. package/utils/gc/gc-root-store.js +76 -0
  234. package/utils/gc/gc-route-changed.ts +44 -0
  235. package/utils/gc/gc-types.ts +21 -0
  236. package/utils/gc/gc.ts +282 -0
  237. package/utils/grafana.js +2 -6
  238. package/utils/socket.js +41 -20
  239. package/utils/string.js +1 -7
  240. package/utils/validators/formRules/__tests__/index.test.ts +108 -0
  241. package/utils/validators/formRules/index.ts +9 -1
  242. package/config/footer.js +0 -19
  243. package/creators/pkg/nuxt.config.js +0 -6
  244. package/pages/plugins.vue +0 -387
  245. package/server/verdaccio-middleware.js +0 -56
package/utils/socket.js CHANGED
@@ -31,6 +31,8 @@ export default class Socket extends EventTarget {
31
31
  hasBeenOpen = false;
32
32
  hasReconnected = false;
33
33
  protocol = null;
34
+ maxTries = null;
35
+ tries = 0;
34
36
 
35
37
  // "Private"
36
38
  socket = null;
@@ -38,17 +40,19 @@ export default class Socket extends EventTarget {
38
40
  framesReceived = 0;
39
41
  frameTimer;
40
42
  reconnectTimer;
41
- tries = 0;
42
43
  disconnectCbs = [];
43
44
  disconnectedAt = 0;
44
45
  closingId = 0;
45
46
 
46
- constructor(url, autoReconnect = true, frameTimeout = null, protocol = null) {
47
+ constructor(url, autoReconnect = true, frameTimeout = null, protocol = null, maxTries = null) {
47
48
  super();
48
49
 
49
50
  this.setUrl(url);
50
51
  this.autoReconnect = autoReconnect;
51
52
  this.protocol = protocol;
53
+ // maxTries = null === never stop trying to reconnect
54
+ // allow maxTries to be defined on individual sockets bc not all will clearly warn the user that we've stopped trying
55
+ this.maxTries = maxTries;
52
56
 
53
57
  if ( frameTimeout !== null ) {
54
58
  this.frameTimeout = frameTimeout;
@@ -57,10 +61,10 @@ export default class Socket extends EventTarget {
57
61
 
58
62
  setUrl(url) {
59
63
  if ( !url.match(/wss?:\/\//) ) {
60
- url = window.location.origin.replace(/^http/, 'ws') + url;
64
+ url = self.location.origin.replace(/^http/, 'ws') + url;
61
65
  }
62
66
 
63
- if ( window.location.protocol === 'https:' && url.startsWith(INSECURE) ) {
67
+ if ( self.location.protocol === 'https:' && url.startsWith(INSECURE) ) {
64
68
  url = SECURE + url.substr(INSECURE.length);
65
69
  }
66
70
 
@@ -74,6 +78,10 @@ export default class Socket extends EventTarget {
74
78
  return;
75
79
  }
76
80
 
81
+ if (this.state !== STATE_RECONNECTING) {
82
+ this.state = STATE_CONNECTING;
83
+ }
84
+
77
85
  Object.assign(this.metadata, metadata);
78
86
 
79
87
  const id = sockId++;
@@ -83,6 +91,8 @@ export default class Socket extends EventTarget {
83
91
 
84
92
  let socket;
85
93
 
94
+ this.tries++;
95
+
86
96
  if ( this.protocol ) {
87
97
  socket = new WebSocket(url, this.protocol);
88
98
  } else {
@@ -209,11 +219,11 @@ export default class Socket extends EventTarget {
209
219
  this._log('opened');
210
220
  const now = (new Date()).getTime();
211
221
 
212
- const at = this.disconnectedAt;
213
- let after = 0;
222
+ const atTime = this.disconnectedAt;
223
+ let afterMilliseconds = 0;
214
224
 
215
- if ( at ) {
216
- after = now - at;
225
+ if ( atTime ) {
226
+ afterMilliseconds = now - atTime;
217
227
  }
218
228
 
219
229
  if ( this.hasBeenOpen ) {
@@ -225,7 +235,8 @@ export default class Socket extends EventTarget {
225
235
  this.framesReceived = 0;
226
236
  this.disconnectedAt = 0;
227
237
 
228
- this.dispatchEvent(new CustomEvent(EVENT_CONNECTED, { detail: { tries: this.tries, after } }));
238
+ this.dispatchEvent(new CustomEvent(EVENT_CONNECTED, { detail: { tries: this.tries, afterMilliseconds } }));
239
+ this.tries = 0;
229
240
  this._resetWatchdog();
230
241
  clearTimeout(this.reconnectTimer);
231
242
  }
@@ -291,18 +302,26 @@ export default class Socket extends EventTarget {
291
302
  this.dispatchEvent(e);
292
303
  warningShown = true;
293
304
  } else if ( this.autoReconnect ) {
294
- if (this.tries === 0) {
295
- const e = new CustomEvent(EVENT_DISCONNECT_ERROR);
305
+ this.state = STATE_RECONNECTING;
306
+
307
+ if (this.maxTries && this.tries > 1 && this.tries <= this.maxTries) {
308
+ // dispatch an event which will trigger a growl from steve-plugin sockets warning users that we've lost connection and are attemping to reconnect
309
+ const e = new CustomEvent(EVENT_CONNECT_ERROR);
296
310
 
297
311
  this.dispatchEvent(e);
298
312
  }
299
- this.state = STATE_RECONNECTING;
300
- this.tries++;
301
- const delay = Math.max(1000, Math.min(1000 * this.tries, 30000));
302
313
 
303
- this.reconnectTimer = setTimeout(() => {
304
- this.connect();
305
- }, delay);
314
+ if (this.maxTries && this.tries > this.maxTries) {
315
+ this.state = STATE_DISCONNECTED;
316
+ // dispatch an event which will trigger a growl from steve-plugin sockets warning users that we've given up trying to reconnect
317
+ this.dispatchEvent(new CustomEvent(EVENT_DISCONNECT_ERROR));
318
+ } else {
319
+ const delay = Math.max(1000, Math.min(1000 * this.tries, 30000));
320
+
321
+ this.reconnectTimer = setTimeout(() => {
322
+ this.connect();
323
+ }, delay);
324
+ }
306
325
  } else {
307
326
  this.state = STATE_DISCONNECTED;
308
327
  }
@@ -315,10 +334,12 @@ export default class Socket extends EventTarget {
315
334
  }
316
335
 
317
336
  _log(...args) {
318
- args.unshift('Socket');
337
+ const message = JSON.parse(JSON.stringify([...args]));
338
+
339
+ message.unshift('Socket');
319
340
 
320
- args.push(`(state=${ this.state }, id=${ this.socket ? this.socket.sockId : 0 })`);
341
+ message.push(`(state=${ this.state }, id=${ this.socket ? this.socket.sockId : 0 })`);
321
342
 
322
- console.log(args.join(' ')); // eslint-disable-line no-console
343
+ console.log(message.join(' ')); // eslint-disable-line no-console
323
344
  }
324
345
  }
package/utils/string.js CHANGED
@@ -70,13 +70,7 @@ export function random32(count) {
70
70
  const out = [];
71
71
  let i;
72
72
 
73
- if ( process.server ) {
74
- const crypto = require('crypto');
75
-
76
- for ( i = 0 ; i < count ; i++ ) {
77
- out[i] = crypto.randomBytes(4).readUInt32BE(0, true);
78
- }
79
- } else if (window.crypto && window.crypto.getRandomValues) {
73
+ if (window.crypto && window.crypto.getRandomValues) {
80
74
  const tmp = new Uint32Array(count);
81
75
 
82
76
  window.crypto.getRandomValues(tmp);
@@ -906,6 +906,114 @@ describe('formRules', () => {
906
906
  expect(formRuleResult).toStrictEqual(expectedResult);
907
907
  });
908
908
 
909
+ // this rule is pretty much identical to the standard hostname, but also allows for wildcards
910
+ it('"wildcardHostname" : returns undefined when value is valid hostname', () => {
911
+ const testValue = 'www.url.com';
912
+ const formRuleResult = formRules.wildcardHostname(testValue);
913
+
914
+ expect(formRuleResult).toBeUndefined();
915
+ });
916
+
917
+ it('"wildcardHostname" : returns expected message when value starts with a dot', () => {
918
+ const testValue = '.hostname';
919
+ const formRuleResult = formRules.wildcardHostname(testValue);
920
+ const expectedResult = JSON.stringify({ message: 'validation.dns.hostname.startDot', key: 'testDisplayKey' });
921
+
922
+ expect(formRuleResult).toStrictEqual(expectedResult);
923
+ });
924
+
925
+ it('"wildcardHostname" : returns expected message when value starts is too long for a hostname', () => {
926
+ const testValue = 'There.are.many.variations.of.passages.of.Lorem.Ipsum.available.but.the.majority.have.suffered.alteration.in.some.form.by.injected.humour.or.randomised.words.which.dont.look.even.slightly.believable.If.you.are.going.to.use.a.passage.of.Lorem.Ipsum.you.need';
927
+ const formRuleResult = formRules.wildcardHostname(testValue);
928
+ const expectedResult = JSON.stringify({
929
+ message: 'validation.dns.hostname.tooLong', key: 'testDisplayKey', max: 253
930
+ });
931
+
932
+ expect(formRuleResult).toStrictEqual(expectedResult);
933
+ });
934
+
935
+ it('"wildcardHostname" : returns expected message when value contains invalid characters', () => {
936
+ const testValue = 'www.host*name.com';
937
+ const formRuleResult = formRules.wildcardHostname(testValue);
938
+ const expectedResult = JSON.stringify({
939
+ message: 'validation.chars', key: 'testDisplayKey', count: 1, chars: '"*"'
940
+ });
941
+
942
+ expect(formRuleResult).toStrictEqual(expectedResult);
943
+ });
944
+
945
+ it('"wildcardHostname" : returns expected message when value contains a space character', () => {
946
+ const testValue = 'www.host name.com';
947
+ const formRuleResult = formRules.wildcardHostname(testValue);
948
+ const expectedResult = JSON.stringify({
949
+ message: 'validation.chars', key: 'testDisplayKey', count: 1, chars: 'Space'
950
+ });
951
+
952
+ expect(formRuleResult).toStrictEqual(expectedResult);
953
+ });
954
+
955
+ it('"wildcardHostname" : returns expected message when hostname label starts with a dash', () => {
956
+ const testValue = 'www.-hostname.com';
957
+ const formRuleResult = formRules.wildcardHostname(testValue);
958
+ const expectedResult = JSON.stringify({ message: 'validation.dns.hostname.startHyphen', key: 'testDisplayKey' });
959
+
960
+ expect(formRuleResult).toStrictEqual(expectedResult);
961
+ });
962
+
963
+ it('"wildcardHostname" : returns expected message when hostname label ends with a dash', () => {
964
+ const testValue = 'www.hostname-.com';
965
+ const formRuleResult = formRules.wildcardHostname(testValue);
966
+ const expectedResult = JSON.stringify({ message: 'validation.dns.hostname.endHyphen', key: 'testDisplayKey' });
967
+
968
+ expect(formRuleResult).toStrictEqual(expectedResult);
969
+ });
970
+
971
+ it('"wildcardHostname" : returns expected message when hostname label contains a double-dash at the third character position', () => {
972
+ const testValue = 'www.ho--stname.com';
973
+ const formRuleResult = formRules.wildcardHostname(testValue);
974
+ const expectedResult = JSON.stringify({ message: 'validation.dns.doubleHyphen', key: 'testDisplayKey' });
975
+
976
+ expect(formRuleResult).toStrictEqual(expectedResult);
977
+ });
978
+
979
+ it('"wildcardHostname" : returns expected message when hostname label is too long', () => {
980
+ const testValue = 'www.0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.com';
981
+ const formRuleResult = formRules.wildcardHostname(testValue);
982
+ const expectedResult = JSON.stringify({
983
+ message: 'validation.dns.hostname.tooLongLabel', key: 'testDisplayKey', max: 63
984
+ });
985
+
986
+ expect(formRuleResult).toStrictEqual(expectedResult);
987
+ });
988
+
989
+ it('"wildcardHostname" : returns expected message when wildcard character is not the first part', () => {
990
+ const testValue = 'www.*.hostname.com';
991
+ const formRuleResult = formRules.wildcardHostname(testValue);
992
+ const expectedResult = JSON.stringify({
993
+ message: 'validation.chars', key: 'testDisplayKey', count: 1, chars: '"*"'
994
+ });
995
+
996
+ expect(formRuleResult).toStrictEqual(expectedResult);
997
+ });
998
+
999
+ it('"wildcardHostname" : returns expected message when wildcard character is at the beginning but not its own part', () => {
1000
+ const testValue = '*hostname.com';
1001
+ const formRuleResult = formRules.wildcardHostname(testValue);
1002
+
1003
+ const expectedResult = JSON.stringify({
1004
+ message: 'validation.chars', key: 'testDisplayKey', count: 1, chars: '"*"'
1005
+ });
1006
+
1007
+ expect(formRuleResult).toStrictEqual(expectedResult);
1008
+ });
1009
+
1010
+ it('"wildcardHostname" : returns valid when wildcard character is the first part', () => {
1011
+ const testValue = '*.hostname.com';
1012
+ const formRuleResult = formRules.wildcardHostname(testValue);
1013
+
1014
+ expect(formRuleResult).toBeUndefined();
1015
+ });
1016
+
909
1017
  it('"absolutePath" : return expected message when path doesn\'t begin with a "/"', () => {
910
1018
  const formRuleResult = formRules.absolutePath('absolute_path');
911
1019
  const expectedResult = JSON.stringify({ message: 'validation.path', key: 'testDisplayKey' });
@@ -204,6 +204,13 @@ export default function(t: (key: string, options?: any) => string, opt: {display
204
204
  }
205
205
  };
206
206
 
207
+ const wildcardHostname: Validator = (val: string) => {
208
+ // allow wildcard in first part of hostname
209
+ val = val ? val.replace(/^\*\./, '') : val;
210
+
211
+ return hostname(val);
212
+ };
213
+
207
214
  const externalName: Validator = (val: string) => {
208
215
  if (isEmpty(val)) {
209
216
  return t('validation.service.externalName.none');
@@ -442,6 +449,7 @@ export default function(t: (key: string, options?: any) => string, opt: {display
442
449
  hostname,
443
450
  testRule,
444
451
  subDomain,
445
- absolutePath
452
+ absolutePath,
453
+ wildcardHostname,
446
454
  };
447
455
  }
package/config/footer.js DELETED
@@ -1,19 +0,0 @@
1
- import { DOCS_BASE } from '@shell/config/private-label';
2
-
3
- export function options(issues, hideRancher) {
4
- if (!issues) {
5
- if (hideRancher) {
6
- return { };
7
- }
8
- issues = 'https://github.com/rancher/dashboard/issues/new';
9
- } else if (hideRancher) {
10
- return { 'footer.issue': issues };
11
- }
12
-
13
- return {
14
- 'footer.docs': DOCS_BASE,
15
- 'footer.forums': 'https://forums.rancher.com/',
16
- 'footer.slack': 'https://slack.rancher.io',
17
- 'footer.issue': issues,
18
- };
19
- }
@@ -1,6 +0,0 @@
1
- import config from '@rancher/shell/nuxt.config';
2
-
3
- export default config(__dirname, {
4
- excludes: [],
5
- autoImport: []
6
- });