@rancher/shell 3.0.8 → 3.0.9-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/apis/intf/modal.ts +38 -0
  2. package/apis/intf/slide-in.ts +3 -1
  3. package/apis/shell/__tests__/slide-in.test.ts +36 -0
  4. package/apis/shell/slide-in.ts +5 -1
  5. package/assets/styles/base/_color.scss +1 -0
  6. package/assets/styles/base/_typography.scss +14 -5
  7. package/assets/styles/themes/_light.scss +1 -1
  8. package/assets/styles/themes/_modern.scss +1 -1
  9. package/assets/translations/en-us.yaml +94 -33
  10. package/assets/translations/zh-hans.yaml +0 -2
  11. package/components/ActionMenuShell.vue +4 -4
  12. package/components/CodeMirror.vue +4 -3
  13. package/components/DetailText.vue +54 -7
  14. package/components/Drawer/Chrome.vue +11 -4
  15. package/components/Drawer/DrawerCard.vue +19 -0
  16. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +3 -11
  17. package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +2 -2
  18. package/components/Drawer/ResourceDetailDrawer/index.vue +3 -20
  19. package/components/Drawer/types.ts +1 -0
  20. package/components/DynamicContent/DynamicContentCloseButton.vue +2 -2
  21. package/components/LocaleSelector.vue +1 -1
  22. package/components/Markdown.vue +1 -1
  23. package/components/PopoverCard.vue +3 -3
  24. package/components/Resource/Detail/Card/ExtrasCard.vue +39 -0
  25. package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +142 -0
  26. package/components/Resource/Detail/Card/StateCard/composables.ts +41 -11
  27. package/components/Resource/Detail/Card/StateCard/index.vue +3 -9
  28. package/components/Resource/Detail/Card/StateCard/types.ts +6 -0
  29. package/components/Resource/Detail/Card/{PodsCard → StatusCard}/index.vue +11 -10
  30. package/components/Resource/Detail/Card/__tests__/PodsCard.test.ts +24 -25
  31. package/components/Resource/Detail/Cards.vue +27 -0
  32. package/components/Resource/Detail/Masthead/__tests__/index.test.ts +70 -0
  33. package/components/Resource/Detail/Masthead/index.vue +5 -0
  34. package/components/Resource/Detail/Metadata/KeyValueRow.vue +4 -2
  35. package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +2 -2
  36. package/components/Resource/Detail/ResourceRow.types.ts +14 -0
  37. package/components/Resource/Detail/ResourceRow.vue +23 -35
  38. package/components/Resource/Detail/StatusRow.vue +5 -2
  39. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +38 -7
  40. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +106 -2
  41. package/components/Resource/Detail/TitleBar/composables.ts +2 -1
  42. package/components/Resource/Detail/TitleBar/index.vue +41 -6
  43. package/components/ResourceDetail/Masthead/__tests__/index.test.ts +49 -1
  44. package/components/ResourceDetail/Masthead/__tests__/latest.test.ts +85 -0
  45. package/components/ResourceDetail/Masthead/index.vue +1 -0
  46. package/components/ResourceDetail/Masthead/latest.vue +8 -1
  47. package/components/ResourceDetail/Masthead/legacy.vue +1 -1
  48. package/components/Setting.vue +1 -1
  49. package/components/SortableTable/index.vue +25 -0
  50. package/components/SortableTable/selection.js +25 -12
  51. package/components/SortableTable/sorting.js +1 -1
  52. package/components/Tabbed/Tab.vue +1 -0
  53. package/components/Tabbed/index.vue +29 -6
  54. package/components/Window/ContainerShell.vue +10 -13
  55. package/components/fleet/FleetClusterTargets/TargetsList.vue +47 -29
  56. package/components/fleet/FleetClusterTargets/index.vue +82 -29
  57. package/components/fleet/FleetClusters.vue +26 -12
  58. package/components/fleet/FleetGitRepoPaths.vue +2 -2
  59. package/components/fleet/FleetResources.vue +14 -0
  60. package/components/fleet/FleetValuesFrom.vue +2 -2
  61. package/components/fleet/__tests__/FleetClusterTargets.test.ts +531 -0
  62. package/components/fleet/__tests__/FleetClusters.test.ts +576 -0
  63. package/components/fleet/dashboard/ResourceDetails.vue +96 -123
  64. package/components/form/Conditions.vue +1 -15
  65. package/components/form/HookOption.vue +5 -0
  66. package/components/form/LabeledSelect.vue +1 -1
  67. package/components/form/LifecycleHooks.vue +2 -6
  68. package/components/form/ResourceLabeledSelect.vue +12 -1
  69. package/components/form/SeccompProfile.vue +113 -0
  70. package/components/form/Security.vue +244 -133
  71. package/components/form/__tests__/LabeledSelect.test.ts +1 -1
  72. package/components/form/__tests__/SeccompProfile.test.js +124 -0
  73. package/components/form/__tests__/Security.test.ts +125 -37
  74. package/components/formatter/Autoscaler.vue +2 -2
  75. package/components/formatter/FleetSummaryGraph.vue +4 -1
  76. package/components/nav/Group.vue +5 -0
  77. package/components/nav/Header.vue +3 -3
  78. package/components/nav/HeaderPageActionMenu.vue +1 -1
  79. package/components/nav/NamespaceFilter.vue +6 -6
  80. package/components/nav/NotificationCenter/index.vue +1 -1
  81. package/components/nav/TopLevelMenu.helper.ts +41 -16
  82. package/components/nav/TopLevelMenu.vue +45 -25
  83. package/components/nav/WorkspaceSwitcher.vue +1 -1
  84. package/components/nav/__tests__/TopLevelMenu.helper.test.ts +277 -0
  85. package/components/nav/__tests__/TopLevelMenu.test.ts +160 -4
  86. package/components/templates/default.vue +0 -3
  87. package/components/templates/home.vue +0 -3
  88. package/components/templates/plain.vue +0 -3
  89. package/composables/useClickOutside.ts +1 -1
  90. package/config/product/explorer.js +1 -2
  91. package/config/types.js +41 -8
  92. package/detail/__tests__/workload.test.ts +8 -16
  93. package/detail/catalog.cattle.io.app.vue +6 -0
  94. package/detail/fleet.cattle.io.cluster.vue +6 -0
  95. package/detail/workload/index.vue +7 -109
  96. package/edit/__tests__/projectsecret.test.ts +42 -0
  97. package/edit/auth/__tests__/oidc.test.ts +50 -0
  98. package/edit/auth/oidc.vue +68 -44
  99. package/edit/autoscaling.horizontalpodautoscaler/index.vue +140 -59
  100. package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +41 -5
  101. package/edit/projectsecret.vue +29 -0
  102. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +89 -200
  103. package/edit/provisioning.cattle.io.cluster/__tests__/Networking.test.ts +58 -17
  104. package/edit/provisioning.cattle.io.cluster/rke2.vue +11 -0
  105. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +3 -63
  106. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +82 -14
  107. package/edit/workload/__tests__/index.test.ts +122 -85
  108. package/edit/workload/index.vue +48 -29
  109. package/edit/workload/mixins/workload.js +85 -32
  110. package/list/catalog.cattle.io.clusterrepo.vue +1 -1
  111. package/list/projectsecret.vue +2 -2
  112. package/machine-config/__tests__/vmwarevsphere.test.ts +64 -0
  113. package/machine-config/amazonec2.vue +2 -2
  114. package/machine-config/vmwarevsphere.vue +58 -4
  115. package/mixins/__tests__/brand.spec.ts +18 -13
  116. package/mixins/__tests__/chart.test.ts +63 -0
  117. package/mixins/chart.js +56 -51
  118. package/models/__tests__/catalog.cattle.io.app.test.ts +33 -0
  119. package/models/__tests__/workload.test.ts +333 -0
  120. package/models/catalog.cattle.io.app.js +8 -0
  121. package/models/pod.js +14 -0
  122. package/models/secret.js +1 -1
  123. package/models/workload.js +93 -27
  124. package/package.json +4 -4
  125. package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +91 -0
  126. package/pages/c/_cluster/apps/charts/install.vue +4 -4
  127. package/pages/c/_cluster/explorer/EventsTable.vue +2 -2
  128. package/pages/c/_cluster/fleet/index.vue +18 -12
  129. package/pages/c/_cluster/manager/hostedprovider/index.vue +1 -19
  130. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -1
  131. package/pages/c/_cluster/uiplugins/index.vue +1 -1
  132. package/plugins/dashboard-store/__tests__/resource-class.test.ts +234 -0
  133. package/plugins/dashboard-store/actions.js +9 -8
  134. package/plugins/dashboard-store/resource-class.js +97 -1
  135. package/plugins/steve/__tests__/revision.test.ts +84 -0
  136. package/plugins/steve/__tests__/steve-pagination-utils.test.ts +30 -0
  137. package/plugins/steve/__tests__/subscribe.spec.ts +134 -0
  138. package/plugins/steve/mutations.js +9 -0
  139. package/plugins/steve/revision.ts +26 -0
  140. package/plugins/steve/steve-pagination-utils.ts +6 -5
  141. package/plugins/steve/subscribe.js +211 -51
  142. package/plugins/subscribe-events.ts +2 -2
  143. package/rancher-components/Form/Checkbox/Checkbox.vue +13 -0
  144. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -1
  145. package/rancher-components/Pill/RcCounterBadge/RcCounterBadge.vue +1 -1
  146. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +3 -1
  147. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +3 -1
  148. package/rancher-components/Pill/RcTag/RcTag.vue +1 -1
  149. package/rancher-components/Pill/index.ts +4 -0
  150. package/rancher-components/RcButton/RcButton.test.ts +53 -9
  151. package/rancher-components/RcButton/RcButton.vue +217 -25
  152. package/rancher-components/RcButton/types.ts +27 -1
  153. package/rancher-components/RcDropdown/RcDropdownMenu.vue +4 -4
  154. package/rancher-components/RcDropdown/types.ts +3 -3
  155. package/rancher-components/RcIcon/RcIcon.test.ts +42 -0
  156. package/rancher-components/RcIcon/RcIcon.vue +9 -6
  157. package/rancher-components/RcIcon/types.ts +13 -9
  158. package/rancher-components/utils/status.test.ts +10 -15
  159. package/rancher-components/utils/status.ts +5 -6
  160. package/store/aws.js +18 -12
  161. package/store/index.js +4 -8
  162. package/store/type-map.utils.ts +1 -1
  163. package/types/kube/kube-api.ts +29 -3
  164. package/types/rancher/steve.api.ts +40 -0
  165. package/types/shell/index.d.ts +99 -0
  166. package/types/store/dashboard-store.types.ts +29 -7
  167. package/types/store/pagination.types.ts +1 -0
  168. package/types/store/subscribe-events.types.ts +1 -0
  169. package/utils/__tests__/azure.test.ts +56 -0
  170. package/utils/__tests__/back-off.test.ts +364 -245
  171. package/utils/__tests__/error.test.ts +44 -0
  172. package/utils/__tests__/fleet.test.ts +8 -1
  173. package/utils/__tests__/pagination-wrapper.test.ts +167 -0
  174. package/utils/__tests__/version.test.ts +55 -1
  175. package/utils/azure.js +12 -0
  176. package/utils/back-off.ts +302 -69
  177. package/utils/cspAdaptor.ts +32 -14
  178. package/utils/dynamic-content/__tests__/index.test.ts +1 -1
  179. package/utils/dynamic-content/__tests__/new-release.test.ts +48 -7
  180. package/utils/dynamic-content/__tests__/support-notice.test.ts +1 -4
  181. package/utils/dynamic-content/index.ts +1 -6
  182. package/utils/dynamic-content/new-release.ts +5 -3
  183. package/utils/dynamic-content/types.d.ts +0 -1
  184. package/utils/error.js +9 -0
  185. package/utils/fleet.ts +2 -2
  186. package/utils/inactivity.ts +2 -3
  187. package/utils/pagination-wrapper.ts +101 -17
  188. package/utils/validators/formRules/index.ts +3 -0
  189. package/utils/version.js +38 -0
  190. package/components/auth/AzureWarning.vue +0 -77
  191. /package/components/Resource/Detail/{Card/PodsCard/Bubble.vue → Bubble.vue} +0 -0
  192. /package/components/Resource/Detail/Card/{PodsCard → StatusCard}/composable.ts +0 -0
@@ -17,6 +17,7 @@ import { NotificationLevel } from '@shell/types/notifications';
17
17
  import { READ_NEW_RELEASE } from '@shell/store/prefs';
18
18
  import { Context, ReleaseInfo, VersionInfo } from './types';
19
19
  import { removeMatchingNotifications } from './util';
20
+ import { getReleaseNotesURL } from '@shell/utils/version';
20
21
 
21
22
  export async function processReleaseVersion(context: Context, releaseInfo: ReleaseInfo[] | undefined, versionInfo: VersionInfo) {
22
23
  if (!releaseInfo || !versionInfo?.version || !Array.isArray(releaseInfo)) {
@@ -55,7 +56,8 @@ export async function processReleaseVersion(context: Context, releaseInfo: Relea
55
56
 
56
57
  async function addNewReleaseNotification(context: Context, version: string) {
57
58
  const prefix = 'new-release-';
58
- const releaseNotesUrl = context.settings.releaseNotesUrl.replace('$version', version);
59
+ const releaseNotesUrl = getReleaseNotesURL(context.config.prime, version);
60
+
59
61
  const { dispatch, getters, logger } = context;
60
62
 
61
63
  // TODO: Get the preference
@@ -89,8 +91,8 @@ async function addNewReleaseNotification(context: Context, version: string) {
89
91
  async function addNewMultipleReleasesNotification(context: Context, version1: string, version2: string) {
90
92
  const prefix = 'new-release-';
91
93
  const key = `${ version1 }-${ version2 }`;
92
- const releaseNotesUrl1 = context.settings.releaseNotesUrl.replace('$version', version1);
93
- const releaseNotesUrl2 = context.settings.releaseNotesUrl.replace('$version', version2);
94
+ const releaseNotesUrl1 = getReleaseNotesURL(context.config.prime, version1);
95
+ const releaseNotesUrl2 = getReleaseNotesURL(context.config.prime, version2);
94
96
  const { dispatch, getters, logger } = context;
95
97
 
96
98
  // TODO: Get the preference
@@ -34,7 +34,6 @@ export type Configuration = {
34
34
  * Settings configuration that can be supplied in the dynamic content package
35
35
  */
36
36
  export type SettingsInfo = {
37
- releaseNotesUrl: string; // URL format to use when generating release note links for new releases
38
37
  suseExtensions: string[]; // Names of extra SUSE UI extensions on top of the list built-in
39
38
  debugVersion?: string;
40
39
  };
package/utils/error.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { isArray } from '@shell/utils/array';
2
+ const AWS_SDK_UNHANDLED_ERROR = 'Deserialization error:';
2
3
 
3
4
  export class ClusterNotFoundError extends Error {
4
5
  static NAME = 'ClusterNotFoundError'
@@ -129,3 +130,11 @@ export const normalizeError = (err) => {
129
130
  statusCode: (err.statusCode || err.status || (err.response && err.response.status) || 500)
130
131
  };
131
132
  };
133
+
134
+ export const formatAWSError = (err) => {
135
+ if (err instanceof TypeError && err.message.includes(AWS_SDK_UNHANDLED_ERROR)) {
136
+ return err.$response.reason;
137
+ }
138
+
139
+ return err;
140
+ };
package/utils/fleet.ts CHANGED
@@ -64,11 +64,11 @@ class Application {
64
64
  clusterGroupSelector,
65
65
  } = target;
66
66
 
67
- if (clusterGroup || clusterGroupSelector) {
67
+ if (clusterGroupSelector) {
68
68
  return 'advanced';
69
69
  }
70
70
 
71
- if (clusterName) {
71
+ if (clusterName || clusterGroup) {
72
72
  mode = 'clusters';
73
73
  }
74
74
 
@@ -1,8 +1,7 @@
1
1
  import { EXT } from '@shell/config/types';
2
- import { RancherKubeMetadata } from '@shell/types/kube/kube-api';
2
+ import { SteveGetResponse } from '@shell/types/rancher/steve.api';
3
3
 
4
- interface UserActivityResponse {
5
- metadata: RancherKubeMetadata,
4
+ interface UserActivityResponse extends SteveGetResponse {
6
5
  status: {
7
6
  expiresAt: string
8
7
  }
@@ -1,10 +1,13 @@
1
1
  import paginationUtils from '@shell/utils/pagination-utils';
2
2
  import { PaginationArgs, PaginationResourceContext } from '@shell/types/store/pagination.types';
3
3
  import { VuexStore } from '@shell/types/store/vuex';
4
- import { ActionFindPageArgs, ActionFindPageTransientResult } from '@shell/types/store/dashboard-store.types';
4
+ import { ActionFindPageArgs, ActionFindPageTransientResponse } from '@shell/types/store/dashboard-store.types';
5
5
  import { STEVE_WATCH_EVENT_TYPES, STEVE_WATCH_MODE } from '@shell/types/store/subscribe.types';
6
6
  import { Reactive, reactive } from 'vue';
7
7
  import { STEVE_UNWATCH_EVENT_PARAMS, STEVE_WATCH_EVENT_LISTENER_CALLBACK, STEVE_WATCH_EVENT_PARAMS, STEVE_WATCH_EVENT_PARAMS_COMMON } from '@shell/types/store/subscribe-events.types';
8
+ import backOff from '@shell/utils/back-off';
9
+ import { SteveRevision } from '@shell/plugins/steve/revision';
10
+ import { STEVE_RESPONSE_CODE } from '@shell/types/rancher/steve.api';
8
11
 
9
12
  interface Args {
10
13
  $store: VuexStore,
@@ -30,8 +33,8 @@ interface Args {
30
33
  }
31
34
  }
32
35
 
33
- interface Result<T> extends Omit<ActionFindPageTransientResult<T>, 'data'> {
34
- data: Reactive<T[]>
36
+ interface Result<T> extends Omit<ActionFindPageTransientResponse<T>, 'data'> {
37
+ data: Reactive<T[]> | T[]
35
38
  }
36
39
 
37
40
  /**
@@ -50,9 +53,12 @@ class PaginationWrapper<T extends object> {
50
53
  private $store: VuexStore;
51
54
  private enabledFor: PaginationResourceContext;
52
55
  private onChange?: STEVE_WATCH_EVENT_LISTENER_CALLBACK;
53
- private id: string;
56
+ public id: string;
57
+ private backOffId: string;
54
58
  private classify: boolean;
55
59
  private reactive: boolean;
60
+ private cachedRevision?: string;
61
+ private cachedResult?: Result<T>;
56
62
 
57
63
  public isEnabled: boolean;
58
64
  private steveWatchParams: STEVE_WATCH_EVENT_PARAMS_COMMON | undefined;
@@ -64,6 +70,7 @@ class PaginationWrapper<T extends object> {
64
70
 
65
71
  this.$store = $store;
66
72
  this.id = id;
73
+ this.backOffId = `${ this.id }`;
67
74
  this.enabledFor = enabledFor;
68
75
  this.onChange = onChange;
69
76
  this.classify = formatResponse?.classify || false;
@@ -72,31 +79,106 @@ class PaginationWrapper<T extends object> {
72
79
  this.isEnabled = paginationUtils.isEnabled({ rootGetters: $store.getters, $extension: this.$store.$extension }, enabledFor);
73
80
  }
74
81
 
75
- async request({ pagination, forceWatch }: {
82
+ async request(requestArgs: {
76
83
  forceWatch?: boolean,
77
84
  pagination: PaginationArgs,
85
+ revision?: string,
78
86
  }): Promise<Result<T>> {
87
+ const { pagination, forceWatch, revision } = requestArgs;
88
+ const type = this.enabledFor.resource?.id;
89
+
79
90
  if (!this.isEnabled) {
80
- throw new Error(`Wrapper for type '${ this.enabledFor.store }/${ this.enabledFor.resource?.id }' in context '${ this.enabledFor.resource?.context }' not supported`);
91
+ throw new Error(`Wrapper for type '${ this.enabledFor.store }/${ type }' in context '${ this.enabledFor.resource?.context }' not supported`);
81
92
  }
82
- const opt: ActionFindPageArgs = {
83
- watch: false,
84
- pagination,
85
- transient: true,
86
- };
87
93
 
88
- // Fetch
89
- const out: ActionFindPageTransientResult<T> = await this.$store.dispatch(`${ this.enabledFor.store }/findPage`, { opt, type: this.enabledFor.resource?.id });
94
+ const backOffId = this.backOffId;
95
+
96
+ const activeRevisionSt = backOff.getBackOff(backOffId)?.metadata.revision;
97
+ const cachedRevisionSt = this.cachedRevision;
98
+
99
+ const targetRevision = new SteveRevision(revision);
100
+ const activeRevision = new SteveRevision(activeRevisionSt);
101
+ const cachedRevision = new SteveRevision(cachedRevisionSt);
102
+ const currentRevision = new SteveRevision(activeRevisionSt || cachedRevisionSt);
103
+
104
+ // Three cases to support HA scenarios 2 + 3
105
+ // 1. current version is newer than target revision - abort/ignore (don't overwrite new with old)
106
+ // 2. current version in cache is older than target revision - reset previous (drop older requests with older revision, use new revision)
107
+ // 3. current version in cache is same as target revision - we're retrying
108
+
109
+ // There are two places we do this to cover the two cases we make http request following socket changes
110
+ // shell/utils/pagination-wrapper.ts - request
111
+ // shell/plugins/steve/subscribe.js - fetchPageResources
112
+
113
+ if (currentRevision.isNewerThan(targetRevision)) {
114
+ if (activeRevision.isNewerThan(targetRevision)) {
115
+ // eslint-disable-next-line no-console
116
+ console.info(`Ignoring event listener request to update '${ this.id }' with revision '${ targetRevision.revision }' (newer in-progress revision '${ activeRevision.revision }'). `);
117
+
118
+ // Case 1 - abort/ignore (don't overwrite new with old). Specifically we're fetching something with a higher revision, ignore the newer request with older revision
119
+ return Promise.reject(new Error('Ignoring current request in favour of other in-progress request with newer revision')); // This will abort the current batch of updates, meaning the other in-progress can update with the newer revision
120
+ }
121
+
122
+ if (cachedRevision.isNewerThan(targetRevision)) {
123
+ // eslint-disable-next-line no-console
124
+ console.info(`Ignoring event listener request to update '${ this.id }' with revision '${ targetRevision.revision }' (newer cached revision '${ cachedRevision.revision }'). `);
125
+
126
+ // Case 1 - abort/ignore (don't overwrite new with old). Specifically we're already fetched something with a higher revision, ignore the newer request with older revision and just return the cached version
127
+ if (this.cachedResult) {
128
+ return this.cachedResult;
129
+ }
130
+
131
+ return Promise.reject(new Error('Cache has higher revision than target revision... but no cached results?'));
132
+ }
133
+ }
134
+
135
+ if (targetRevision.isNewerThan(activeRevision)) {
136
+ // Case 2 - reset previous (drop older requests with older revision, use new revision)
137
+
138
+ // eslint-disable-next-line no-console
139
+ console.info(`Dropping event listener request to update '${ this.id }' with revision '${ currentRevision.revision }' (newer target revision '${ targetRevision.revision }'). `);
140
+
141
+ backOff.reset(backOffId);
142
+ }
143
+
144
+ // Keep making requests until we make one that succeeds, fails with unknown revision or we run out of retries
145
+ const out = await backOff.recurse<any, ActionFindPageTransientResponse<T>>({
146
+ id: backOffId,
147
+ metadata: { revision },
148
+ description: `Fetching resources for ${ type } (wrapper). Initial request, or triggered by web socket`,
149
+ continueOnError: async(err) => {
150
+ // Have we made a request to a stale replica that does not know about the required revision? If so continue to try until we hit a ripe replica
151
+ return err?.status === 400 && err?.code === STEVE_RESPONSE_CODE.UNKNOWN_REVISION;
152
+ },
153
+ delayedFn: async() => {
154
+ const opt: ActionFindPageArgs = {
155
+ watch: false,
156
+ pagination,
157
+ transient: true,
158
+ revision
159
+ };
160
+ const res: ActionFindPageTransientResponse<T> = await this.$store.dispatch(`${ this.enabledFor.store }/findPage`, { opt, type });
161
+
162
+ this.cachedRevision = res.pagination?.result.revision;
163
+
164
+ return res;
165
+ },
166
+ });
167
+
168
+ if (!out) {
169
+ // Skip
170
+ throw new Error(`Wrapper for type '${ this.enabledFor.store }/${ type }' in context '${ this.enabledFor.resource?.context }' failed to fetch resources`);
171
+ }
90
172
 
91
173
  // Watch
92
174
  const firstTime = !this.steveWatchParams;
93
175
 
94
- if (this.onChange && (firstTime || forceWatch) ) { // && !this.steveWatchParams
176
+ if (this.onChange && (firstTime || forceWatch) ) {
95
177
  this.steveWatchParams = {
96
178
  event: STEVE_WATCH_EVENT_TYPES.CHANGES,
97
179
  id: this.id,
98
180
  params: {
99
- type: this.enabledFor.resource?.id as string,
181
+ type: type as string,
100
182
  mode: STEVE_WATCH_MODE.RESOURCE_CHANGES,
101
183
  force: forceWatch,
102
184
  },
@@ -112,13 +194,15 @@ class PaginationWrapper<T extends object> {
112
194
  }
113
195
 
114
196
  if (this.reactive) {
115
- return {
197
+ this.cachedResult = {
116
198
  ...out,
117
199
  data: reactive(out.data)
118
200
  };
201
+ } else {
202
+ this.cachedResult = out;
119
203
  }
120
204
 
121
- return out;
205
+ return this.cachedResult;
122
206
  }
123
207
 
124
208
  private async watch() {
@@ -270,6 +270,8 @@ export default function(
270
270
 
271
271
  const containerImage: Validator = (val: any) => !val?.image ? t('workload.validation.containerImage', { name: val.name }) : undefined;
272
272
 
273
+ const localhostProfile: Validator = (val: any) => (val?.securityContext?.seccompProfile?.type === 'Localhost' && !val?.securityContext.seccompProfile?.localhostProfile && !val?.securityContext?.privileged) ? t('workload.validation.localhostProfile', { name: val.name }) : undefined;
274
+
273
275
  const containerImages: Validator = (val: any | [any]) => {
274
276
  const containers = val.jobTemplate ? val?.jobTemplate?.spec?.template?.spec?.containers : val?.template?.spec?.containers;
275
277
 
@@ -602,6 +604,7 @@ export default function(
602
604
  clusterName,
603
605
  containerImage,
604
606
  containerImages,
607
+ localhostProfile,
605
608
  cronSchedule,
606
609
  dnsLabel,
607
610
  dnsLabelIanaServiceName,
package/utils/version.js CHANGED
@@ -141,3 +141,41 @@ export async function markReadReleaseNotes(store) {
141
141
  await store.dispatch('prefs/set', { key: READ_WHATS_NEW, value: getVersionInfo(store).fullVersion });
142
142
  }
143
143
  }
144
+
145
+ const DEFAULT_RELEASE_NOTES_URLS = {
146
+ COMMUNITY: {
147
+ DEV: 'https://github.com/rancher/rancher/releases/latest',
148
+ RELEASE: 'https://github.com/rancher/rancher/releases/tag/v$VERSION',
149
+ },
150
+ PRIME: {
151
+ DEV: 'https://documentation.suse.com/cloudnative/rancher-manager/latest/en/release-notes.html',
152
+ RELEASE: 'https://documentation.suse.com/cloudnative/rancher-manager/v$MAJOR_MINOR/en/release-notes/v$VERSION.html',
153
+ }
154
+ };
155
+
156
+ /**
157
+ * Get the release notes URL for a given version
158
+ *
159
+ * @param {Get} version s
160
+ */
161
+ export function getReleaseNotesURL(isPrime, version) {
162
+ // If version is not specified, return latest community release notes URL
163
+ if (!version) {
164
+ return DEFAULT_RELEASE_NOTES_URLS.COMMUNITY.DEV;
165
+ }
166
+
167
+ const vers = version.startsWith('v') ? version.slice(1) : version;
168
+ const vParts = vers.split('.');
169
+ let majorMinor = version;
170
+
171
+ if (vParts.length > 2) {
172
+ majorMinor = `${ vParts[0] }.${ vParts[1] }`;
173
+ }
174
+
175
+ const urls = isPrime ? DEFAULT_RELEASE_NOTES_URLS.PRIME : DEFAULT_RELEASE_NOTES_URLS.COMMUNITY;
176
+ const urlTemplate = isDevBuild(version) ? urls.DEV : urls.RELEASE;
177
+
178
+ return urlTemplate
179
+ .replace('$VERSION', vers)
180
+ .replace('$MAJOR_MINOR', majorMinor);
181
+ }
@@ -1,77 +0,0 @@
1
- <script>
2
- // This component will become redundant in 2023, see https://docs.microsoft.com/en-us/graph/migrate-azure-ad-graph-overview
3
- import { NORMAN, MANAGEMENT } from '@shell/config/types';
4
- import { get } from '@shell/utils/object';
5
- import { AZURE_MIGRATED } from '@shell/config/labels-annotations';
6
- import { BLANK_CLUSTER } from '@shell/store/store-types.js';
7
-
8
- export default {
9
- async fetch() {
10
- // Check for access to steve authConfigs because everyone can load the norman auth config schema
11
- if (
12
- this.$store.getters['isRancher'] &&
13
- this.$store.getters['management/schemaFor'](MANAGEMENT.AUTH_CONFIG)
14
- ) {
15
- this.authConfig = await this.$store.dispatch('rancher/find', {
16
- type: NORMAN.AUTH_CONFIG,
17
- id: 'azuread',
18
- opt: { url: `/v3/${ NORMAN.AUTH_CONFIG }/azuread` }
19
- });
20
- }
21
- },
22
-
23
- data() {
24
- return {
25
- authConfig: null,
26
- authConfigRoute: {
27
- name: 'c-cluster-auth-config-id',
28
- params: {
29
- cluster: this.$route.params.cluster || BLANK_CLUSTER,
30
- id: 'azuread'
31
- }
32
- }
33
- };
34
- },
35
-
36
- computed: {
37
- showWarning() {
38
- if (!this.authConfig) {
39
- return false;
40
- }
41
-
42
- return (
43
- get(this.authConfig, `annotations."${ AZURE_MIGRATED }"`) !== 'true' &&
44
- this.authConfig.enabled
45
- );
46
- }
47
- }
48
- };
49
- </script>
50
-
51
- <template>
52
- <div
53
- v-if="showWarning"
54
- id="azure-warn"
55
- class="banner"
56
- >
57
- <p>
58
- {{ t('authConfig.azuread.updateEndpoint.banner.message') }}
59
- <router-link :to="authConfigRoute">
60
- {{ t('authConfig.azuread.updateEndpoint.banner.linkText') }}
61
- </router-link>
62
- </p>
63
- </div>
64
- </template>
65
-
66
- <style lang="scss" scoped>
67
- #azure-warn {
68
- background-color: var(--warning);
69
- color: var(--warning-text);
70
- line-height: 2em;
71
- width: 100%;
72
-
73
- > p {
74
- text-align: center;
75
- }
76
- }
77
- </style>