@rancher/shell 3.0.4 → 3.0.5-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.
- package/assets/images/providers/sks.svg +1 -0
- package/assets/styles/base/_basic.scss +6 -0
- package/assets/styles/base/_helpers.scss +4 -0
- package/assets/styles/base/_variables.scss +1 -0
- package/assets/styles/global/_button.scss +1 -0
- package/assets/translations/en-us.yaml +65 -15
- package/assets/translations/zh-hans.yaml +4 -3
- package/chart/monitoring/index.vue +3 -1
- package/cloud-credential/aws.vue +2 -0
- package/components/ActionDropdownShell.vue +71 -0
- package/components/AppModal.vue +18 -4
- package/components/AsyncButton.vue +24 -7
- package/components/BannerGraphic.vue +1 -0
- package/components/CommunityLinks.vue +4 -59
- package/components/CopyToClipboardText.vue +2 -1
- package/components/CruResource.vue +6 -1
- package/components/DetailText.vue +5 -0
- package/components/ExplorerMembers.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +68 -18
- package/components/GlobalRoleBindings.vue +5 -1
- package/components/GrowlManager.vue +1 -0
- package/components/LandingPagePreference.vue +7 -3
- package/components/LocaleSelector.vue +39 -95
- package/components/ModalManager.vue +55 -0
- package/components/ModalWithCard.vue +1 -0
- package/components/PromptModal.vue +47 -8
- package/components/PromptRemove.vue +1 -0
- package/components/PromptRestore.vue +1 -0
- package/components/ResourceCancelModal.vue +1 -0
- package/components/ResourceDetail/Masthead.vue +38 -12
- package/components/ResourceDetail/__tests__/Masthead.test.ts +5 -1
- package/components/ResourceDetail/index.vue +47 -12
- package/components/ResourceTable.vue +54 -19
- package/components/SideNav.vue +5 -1
- package/components/SlideInPanelManager.vue +126 -0
- package/components/SortableTable/THead.vue +5 -2
- package/components/SortableTable/actions.js +1 -1
- package/components/SortableTable/index.vue +64 -51
- package/components/SortableTable/paging.js +16 -19
- package/components/SortableTable/selection.js +0 -11
- package/components/Wizard.vue +2 -2
- package/components/__tests__/AsyncButton.test.ts +2 -2
- package/components/__tests__/ModalManager.spec.ts +176 -0
- package/components/__tests__/PromptModal.test.ts +148 -0
- package/components/__tests__/SlideInPanelManager.spec.ts +166 -0
- package/components/auth/AuthBanner.vue +13 -11
- package/components/auth/Principal.vue +1 -0
- package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
- package/components/auth/login/ldap.vue +1 -1
- package/components/fleet/FleetResources.vue +21 -6
- package/components/form/ArrayList.vue +76 -60
- package/components/form/BannerSettings.vue +17 -2
- package/components/form/ColorInput.vue +35 -6
- package/components/form/Command.vue +6 -15
- package/components/form/EnvVars.vue +16 -8
- package/components/form/HealthCheck.vue +3 -3
- package/components/form/HookOption.vue +11 -16
- package/components/form/LabeledSelect.vue +18 -22
- package/components/form/LifecycleHooks.vue +3 -3
- package/components/form/MatchExpressions.vue +14 -8
- package/components/form/NameNsDescription.vue +128 -104
- package/components/form/Networking.vue +20 -12
- package/components/form/NodeAffinity.vue +31 -23
- package/components/form/NodeScheduling.vue +13 -3
- package/components/form/NotificationSettings.vue +15 -1
- package/components/form/Password.vue +1 -0
- package/components/form/PodAffinity.vue +43 -43
- package/components/form/Probe.vue +68 -66
- package/components/form/ResourceQuota/Project.vue +5 -1
- package/components/form/ResourceSelector.vue +7 -9
- package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +16 -24
- package/components/form/SSHKnownHosts/index.vue +30 -13
- package/components/form/Security.vue +54 -56
- package/components/form/Select.vue +32 -21
- package/components/form/ShellInput.vue +5 -1
- package/components/form/Tolerations.vue +5 -1
- package/components/form/ValueFromResource.vue +134 -121
- package/components/form/WorkloadPorts.vue +18 -18
- package/components/form/__tests__/ArrayList.test.ts +5 -2
- package/components/form/__tests__/ColorInput.test.ts +35 -0
- package/components/form/__tests__/LabeledSelect.test.ts +40 -0
- package/components/form/__tests__/MatchExpressions.test.ts +12 -12
- package/components/form/__tests__/NameNsDescription.test.ts +115 -14
- package/components/form/__tests__/Probe.test.ts +12 -8
- package/components/form/__tests__/SSHKnownHosts.test.ts +22 -2
- package/components/form/__tests__/Select.test.ts +37 -0
- package/components/formatter/InternalExternalIP.vue +2 -0
- package/components/formatter/SecretData.vue +20 -7
- package/components/nav/Group.vue +27 -5
- package/components/nav/Header.vue +17 -43
- package/components/nav/NamespaceFilter.vue +134 -86
- package/components/nav/TopLevelMenu.vue +4 -5
- package/components/nav/Type.vue +12 -1
- package/components/nav/WindowManager/ContainerLogs.vue +87 -61
- package/components/nav/WindowManager/ContainerLogsActions.vue +76 -0
- package/components/templates/blank.vue +4 -1
- package/components/templates/default.vue +8 -3
- package/components/templates/home.vue +10 -1
- package/components/templates/plain.vue +10 -4
- package/composables/focusTrap.ts +12 -4
- package/composables/useRuntimeFlag.ts +29 -0
- package/config/router/routes.js +20 -13
- package/config/store.js +4 -0
- package/config/uiplugins.js +5 -1
- package/core/types.ts +12 -6
- package/detail/catalog.cattle.io.app.vue +6 -1
- package/detail/fleet.cattle.io.bundle.vue +70 -6
- package/detail/fleet.cattle.io.gitrepo.vue +1 -1
- package/detail/namespace.vue +0 -3
- package/detail/node.vue +17 -13
- package/detail/provisioning.cattle.io.cluster.vue +72 -6
- package/dialog/AddCustomBadgeDialog.vue +1 -1
- package/{pages/c/_cluster/uiplugins/AddExtensionRepos.vue → dialog/AddExtensionReposDialog.vue} +72 -42
- package/{components/AssignTo.vue → dialog/AssignToDialog.vue} +71 -80
- package/dialog/ChangePasswordDialog.vue +106 -0
- package/dialog/DeactivateDriverDialog.vue +1 -0
- package/{pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue → dialog/DeveloperLoadExtensionDialog.vue} +74 -71
- package/dialog/DisableAuthProviderDialog.vue +101 -0
- package/dialog/DrainNode.vue +1 -1
- package/{pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue → dialog/ExtensionCatalogInstallDialog.vue} +100 -88
- package/{pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue → dialog/ExtensionCatalogUninstallDialog.vue} +69 -57
- package/dialog/FeatureFlagListDialog.vue +288 -0
- package/dialog/ForceMachineRemoveDialog.vue +5 -2
- package/{components/Import.vue → dialog/ImportDialog.vue} +0 -5
- package/{pages/c/_cluster/uiplugins/InstallDialog.vue → dialog/InstallExtensionDialog.vue} +124 -106
- package/{components/form/SSHKnownHosts → dialog}/KnownHostsEditDialog.vue +52 -59
- package/dialog/MoveNamespaceDialog.vue +157 -0
- package/dialog/ScalePoolDownDialog.vue +1 -1
- package/{components/nav/Jump.vue → dialog/SearchDialog.vue} +34 -14
- package/{pages/c/_cluster/uiplugins/UninstallDialog.vue → dialog/UninstallExtensionDialog.vue} +67 -58
- package/dialog/WechatDialog.vue +57 -0
- package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +16 -3
- package/edit/auth/__tests__/oidc.test.ts +152 -109
- package/edit/auth/azuread.vue +2 -1
- package/edit/auth/github.vue +1 -1
- package/edit/auth/googleoauth.vue +5 -1
- package/edit/auth/ldap/index.vue +1 -1
- package/edit/auth/oidc.vue +38 -5
- package/edit/auth/saml.vue +1 -1
- package/edit/cloudcredential.vue +24 -9
- package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +40 -9
- package/edit/management.cattle.io.user.vue +28 -3
- package/edit/namespace.vue +1 -4
- package/edit/networking.k8s.io.ingress/IngressClass.vue +7 -3
- package/edit/networking.k8s.io.ingress/__tests__/IngressClass.test.ts +58 -0
- package/edit/persistentvolume/__tests__/persistentvolume.test.ts +14 -2
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +4 -1
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +26 -9
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +8 -8
- package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +26 -12
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +66 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/utils/rke2-test-data.ts +58 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +49 -41
- package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +6 -1
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +5 -3
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +33 -2
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +2 -2
- package/edit/token.vue +2 -0
- package/edit/workload/index.vue +1 -0
- package/edit/workload/mixins/workload.js +0 -2
- package/initialize/install-plugins.js +2 -1
- package/list/harvesterhci.io.management.cluster.vue +4 -1
- package/list/management.cattle.io.feature.vue +4 -287
- package/list/provisioning.cattle.io.cluster.vue +20 -12
- package/machine-config/azure.vue +16 -4
- package/mixins/vue-select-overrides.js +0 -4
- package/models/__tests__/namespace.test.ts +25 -1
- package/models/cloudcredential.js +5 -0
- package/models/fleet.cattle.io.cluster.js +8 -2
- package/models/fleet.cattle.io.gitrepo.js +8 -34
- package/models/kontainerdriver.js +6 -3
- package/models/management.cattle.io.feature.js +7 -1
- package/models/management.cattle.io.node.js +3 -3
- package/models/namespace.js +11 -6
- package/models/nodedriver.js +6 -3
- package/models/workload.js +4 -1
- package/package.json +3 -3
- package/pages/about.vue +13 -3
- package/pages/account/index.vue +16 -6
- package/pages/auth/login.vue +18 -7
- package/pages/auth/logout.vue +4 -1
- package/pages/auth/setup.vue +2 -0
- package/pages/auth/verify.vue +13 -8
- package/pages/c/_cluster/apps/charts/chart.vue +1 -1
- package/pages/c/_cluster/apps/charts/install.vue +26 -26
- package/pages/c/_cluster/auth/config/index.vue +10 -12
- package/pages/c/_cluster/explorer/EventsTable.vue +38 -33
- package/pages/c/_cluster/explorer/index.vue +17 -15
- package/pages/c/_cluster/istio/index.vue +2 -2
- package/pages/c/_cluster/longhorn/index.vue +1 -1
- package/pages/c/_cluster/monitoring/index.vue +1 -1
- package/pages/c/_cluster/monitoring/monitor/_namespace/_id.vue +4 -2
- package/pages/c/_cluster/monitoring/monitor/create.vue +4 -2
- package/pages/c/_cluster/monitoring/route-receiver/_id.vue +4 -2
- package/pages/c/_cluster/monitoring/route-receiver/create.vue +5 -2
- package/pages/c/_cluster/neuvector/index.vue +1 -1
- package/pages/c/_cluster/settings/banners.vue +4 -3
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +8 -10
- package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +4 -7
- package/pages/c/_cluster/uiplugins/index.vue +98 -55
- package/pages/diagnostic.vue +59 -11
- package/pages/fail-whale.vue +14 -8
- package/pages/home.vue +24 -18
- package/pages/prefs.vue +7 -6
- package/pages/support/index.vue +4 -1
- package/plugins/internal-api/index.ts +37 -0
- package/plugins/internal-api/shared/base-api.ts +13 -0
- package/plugins/internal-api/shell/shell.api.ts +108 -0
- package/plugins/steve/actions.js +0 -12
- package/public/index.html +1 -0
- package/rancher-components/Card/Card.vue +1 -1
- package/rancher-components/Form/Checkbox/Checkbox.test.ts +59 -1
- package/rancher-components/Form/Checkbox/Checkbox.vue +27 -3
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +47 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +20 -2
- package/rancher-components/Form/Radio/RadioButton.test.ts +36 -1
- package/rancher-components/Form/Radio/RadioButton.vue +20 -4
- package/rancher-components/Form/Radio/RadioGroup.test.ts +60 -0
- package/rancher-components/Form/Radio/RadioGroup.vue +52 -10
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +17 -0
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +5 -0
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +10 -1
- package/rancher-components/RcButton/RcButton.vue +2 -1
- package/rancher-components/RcButton/types.ts +1 -0
- package/rancher-components/RcDropdown/RcDropdown.vue +18 -6
- package/rancher-components/RcDropdown/RcDropdownItem.vue +3 -56
- package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +68 -0
- package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +92 -0
- package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -0
- package/rancher-components/RcDropdown/index.ts +2 -0
- package/rancher-components/RcDropdown/useDropdownCollection.ts +8 -0
- package/rancher-components/RcDropdown/useDropdownContext.ts +9 -3
- package/rancher-components/RcDropdown/useDropdownItem.ts +63 -0
- package/scripts/extension/bundle +20 -0
- package/scripts/extension/helm/charts/ui-plugin-server/templates/cr.yaml +2 -1
- package/scripts/extension/helm/charts/ui-plugin-server/values.yaml +2 -0
- package/scripts/extension/helmpatch +44 -31
- package/scripts/extension/publish +12 -12
- package/scripts/typegen.sh +2 -4
- package/server/har-file.js +25 -3
- package/store/action-menu.js +26 -56
- package/store/features.js +2 -1
- package/store/index.js +5 -0
- package/store/modal.ts +71 -0
- package/store/slideInPanel.ts +47 -0
- package/store/type-map.js +12 -1
- package/store/type-map.utils.ts +4 -4
- package/types/global-vue.d.ts +5 -0
- package/types/internal-api/shell/growl.d.ts +25 -0
- package/types/internal-api/shell/modal.d.ts +77 -0
- package/types/internal-api/shell/slideIn.d.ts +15 -0
- package/types/resources/fleet.d.ts +0 -14
- package/types/shell/index.d.ts +43 -24
- package/types/vue-shim.d.ts +4 -1
- package/utils/__mocks__/tabbable.js +13 -0
- package/utils/__tests__/object.test.ts +38 -4
- package/utils/cluster.js +35 -0
- package/utils/fleet.ts +15 -73
- package/utils/object.js +48 -5
- package/utils/validators/formRules/__tests__/index.test.ts +10 -1
- package/utils/validators/formRules/index.ts +27 -3
- package/utils/validators/machine-pool.ts +20 -0
- package/components/DisableAuthProviderModal.vue +0 -114
- package/components/MoveModal.vue +0 -166
- package/components/PromptChangePassword.vue +0 -123
- package/components/fleet/FleetBundleResources.vue +0 -86
- package/components/formatter/ExtensionCache.vue +0 -74
- package/components/formatter/Port.vue +0 -24
- package/components/formatter/SecretType.vue +0 -41
- package/types/vue-shim.d +0 -20
package/edit/auth/azuread.vue
CHANGED
|
@@ -363,7 +363,7 @@ export default {
|
|
|
363
363
|
</template>
|
|
364
364
|
</AuthBanner>
|
|
365
365
|
|
|
366
|
-
<hr>
|
|
366
|
+
<hr role="none">
|
|
367
367
|
|
|
368
368
|
<AllowedPrincipals
|
|
369
369
|
provider="azuread"
|
|
@@ -388,6 +388,7 @@ export default {
|
|
|
388
388
|
<label class="reply-url">{{ t('authConfig.azuread.reply.label') }} </label>
|
|
389
389
|
<CopyToClipboardText
|
|
390
390
|
:plain="true"
|
|
391
|
+
:aria-label="t('authConfig.azuread.reply.ariaLabel')"
|
|
391
392
|
:text="replyUrl"
|
|
392
393
|
/>
|
|
393
394
|
</InfoBox>
|
package/edit/auth/github.vue
CHANGED
|
@@ -90,7 +90,7 @@ export default {
|
|
|
90
90
|
</template>
|
|
91
91
|
</AuthBanner>
|
|
92
92
|
|
|
93
|
-
<hr>
|
|
93
|
+
<hr role="none">
|
|
94
94
|
|
|
95
95
|
<AllowedPrincipals
|
|
96
96
|
provider="googleoauth"
|
|
@@ -143,12 +143,14 @@ export default {
|
|
|
143
143
|
<b>{{ t('authConfig.googleoauth.steps.1.body.2', {}, true) }}</b> {{ t('authConfig.googleoauth.steps.1.topPrivateDomain', {}, true) }} <CopyToClipboardText
|
|
144
144
|
:plain="true"
|
|
145
145
|
:text="tArgs.hostname"
|
|
146
|
+
:aria-label="t('authConfig.googleoauth.steps.1.ariaLabel.hostname')"
|
|
146
147
|
/>
|
|
147
148
|
</li>
|
|
148
149
|
<li>
|
|
149
150
|
<b>{{ t('authConfig.googleoauth.steps.1.body.3', {}, true) }}</b> <CopyToClipboardText
|
|
150
151
|
:plain="true"
|
|
151
152
|
:text="serverUrl"
|
|
153
|
+
:aria-label="t('authConfig.googleoauth.steps.1.ariaLabel.serverUrl')"
|
|
152
154
|
/>
|
|
153
155
|
</li>
|
|
154
156
|
<li>{{ t('authConfig.googleoauth.steps.1.body.4', {}, true) }} </li>
|
|
@@ -170,12 +172,14 @@ export default {
|
|
|
170
172
|
<b>{{ t('authConfig.googleoauth.steps.2.body.2', {}, true) }}</b> <CopyToClipboardText
|
|
171
173
|
:plain="true"
|
|
172
174
|
:text="serverUrl"
|
|
175
|
+
:aria-label="t('authConfig.googleoauth.steps.1.ariaLabel.serverUrl')"
|
|
173
176
|
/>
|
|
174
177
|
</li>
|
|
175
178
|
<li>
|
|
176
179
|
<b>{{ t('authConfig.googleoauth.steps.2.body.3', {}, true) }}</b> <CopyToClipboardText
|
|
177
180
|
:plain="true"
|
|
178
181
|
:text="serverUrl+'/verify-auth'"
|
|
182
|
+
:aria-label="t('authConfig.googleoauth.steps.2.ariaLabel.serverUrlVerify')"
|
|
179
183
|
/>
|
|
180
184
|
</li>
|
|
181
185
|
<li>{{ t('authConfig.googleoauth.steps.2.body.4', {}, true) }} </li>
|
package/edit/auth/ldap/index.vue
CHANGED
package/edit/auth/oidc.vue
CHANGED
|
@@ -12,6 +12,7 @@ import ArrayList from '@shell/components/form/ArrayList';
|
|
|
12
12
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
13
13
|
import { RadioGroup } from '@components/Form/Radio';
|
|
14
14
|
import { Checkbox } from '@components/Form/Checkbox';
|
|
15
|
+
import { BASE_SCOPES } from '@shell/store/auth';
|
|
15
16
|
|
|
16
17
|
export default {
|
|
17
18
|
components: {
|
|
@@ -50,6 +51,7 @@ export default {
|
|
|
50
51
|
tokenEndpoint: null,
|
|
51
52
|
userInfoEndpoint: null,
|
|
52
53
|
},
|
|
54
|
+
// TODO #13457: this is duplicated due wrong format
|
|
53
55
|
oidcScope: []
|
|
54
56
|
};
|
|
55
57
|
},
|
|
@@ -76,9 +78,10 @@ export default {
|
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
const { clientId, clientSecret } = this.model;
|
|
79
|
-
const
|
|
81
|
+
const isMissingAuthEndpoint = (this.requiresAuthEndpoint && !this.model.authEndpoint);
|
|
82
|
+
const isMissingScopes = !this.requiredScopes.every((scope) => this.oidcScope.includes(scope));
|
|
80
83
|
|
|
81
|
-
if (
|
|
84
|
+
if (isMissingAuthEndpoint || isMissingScopes) {
|
|
82
85
|
return false;
|
|
83
86
|
}
|
|
84
87
|
|
|
@@ -91,6 +94,19 @@ export default {
|
|
|
91
94
|
|
|
92
95
|
return !!(clientId && clientSecret && rancherUrl && issuer);
|
|
93
96
|
}
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
requiresAuthEndpoint() {
|
|
100
|
+
return ['genericoidc', 'keycloakoidc'].includes(this.model.id);
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* TODO #13457: Refactor scopes to be an array of terms
|
|
105
|
+
* Return valid scopes
|
|
106
|
+
* The scopes for given auth provider (model.id) have format of ['scope1 scope2 scope3']
|
|
107
|
+
*/
|
|
108
|
+
requiredScopes() {
|
|
109
|
+
return this.model.id ? (BASE_SCOPES[this.model.id] || []) ? (BASE_SCOPES[this.model.id] || [])[0].split(' ') : [] : [];
|
|
94
110
|
}
|
|
95
111
|
},
|
|
96
112
|
|
|
@@ -104,6 +120,7 @@ export default {
|
|
|
104
120
|
},
|
|
105
121
|
|
|
106
122
|
'model.enabled'(neu) {
|
|
123
|
+
// TODO #13457: Refactor scopes to be an array of terms
|
|
107
124
|
// Cover case where oidc gets disabled and we return to the edit screen with a reset model
|
|
108
125
|
if (!neu) {
|
|
109
126
|
this.oidcUrls = {
|
|
@@ -114,8 +131,10 @@ export default {
|
|
|
114
131
|
userInfoEndpoint: null,
|
|
115
132
|
};
|
|
116
133
|
this.customEndpoint.value = false;
|
|
134
|
+
// TODO #13457: Refactor scopes to be an array of terms
|
|
117
135
|
this.oidcScope = this.model?.scope?.split(' ');
|
|
118
136
|
} else {
|
|
137
|
+
// TODO #13457: Refactor scopes to be an array of terms
|
|
119
138
|
this.oidcScope = this.model?.scope?.split(' ');
|
|
120
139
|
}
|
|
121
140
|
},
|
|
@@ -130,10 +149,16 @@ export default {
|
|
|
130
149
|
|
|
131
150
|
methods: {
|
|
132
151
|
updateEndpoints() {
|
|
152
|
+
const isKeycloak = this.model.id === 'keycloakoidc';
|
|
153
|
+
|
|
133
154
|
if (!this.oidcUrls.url) {
|
|
155
|
+
this.model.issuer = '';
|
|
156
|
+
if (isKeycloak) {
|
|
157
|
+
this.model.authEndpoint = '';
|
|
158
|
+
}
|
|
159
|
+
|
|
134
160
|
return;
|
|
135
161
|
}
|
|
136
|
-
const isKeycloak = this.model.id === 'keycloakoidc';
|
|
137
162
|
|
|
138
163
|
const url = this.oidcUrls.url.replaceAll(' ', '');
|
|
139
164
|
const realmsPath = 'realms';
|
|
@@ -184,7 +209,7 @@ export default {
|
|
|
184
209
|
</template>
|
|
185
210
|
</AuthBanner>
|
|
186
211
|
|
|
187
|
-
<hr>
|
|
212
|
+
<hr role="none">
|
|
188
213
|
|
|
189
214
|
<AllowedPrincipals
|
|
190
215
|
:provider="NAME"
|
|
@@ -201,6 +226,7 @@ export default {
|
|
|
201
226
|
|
|
202
227
|
<h3>{{ t(`authConfig.oidc.${NAME}`) }}</h3>
|
|
203
228
|
|
|
229
|
+
<!-- Auth credentials -->
|
|
204
230
|
<div class="row mb-20">
|
|
205
231
|
<div class="col span-6">
|
|
206
232
|
<LabeledInput
|
|
@@ -222,6 +248,7 @@ export default {
|
|
|
222
248
|
</div>
|
|
223
249
|
</div>
|
|
224
250
|
|
|
251
|
+
<!-- Key/Certificate -->
|
|
225
252
|
<div class="row mb-20">
|
|
226
253
|
<div class="col span-6">
|
|
227
254
|
<LabeledInput
|
|
@@ -255,6 +282,7 @@ export default {
|
|
|
255
282
|
</div>
|
|
256
283
|
</div>
|
|
257
284
|
|
|
285
|
+
<!-- Allow group search -->
|
|
258
286
|
<div class="row mb-20">
|
|
259
287
|
<div class="col span-6">
|
|
260
288
|
<Checkbox
|
|
@@ -267,6 +295,7 @@ export default {
|
|
|
267
295
|
</div>
|
|
268
296
|
</div>
|
|
269
297
|
|
|
298
|
+
<!-- Scopes -->
|
|
270
299
|
<div class="row mb-20">
|
|
271
300
|
<div class="col span-6">
|
|
272
301
|
<ArrayList
|
|
@@ -280,6 +309,7 @@ export default {
|
|
|
280
309
|
</div>
|
|
281
310
|
</div>
|
|
282
311
|
|
|
312
|
+
<!-- Generated vs Specific Endpoints -->
|
|
283
313
|
<div class="row mb-20">
|
|
284
314
|
<div class="col span-6">
|
|
285
315
|
<RadioGroup
|
|
@@ -297,6 +327,7 @@ export default {
|
|
|
297
327
|
</div>
|
|
298
328
|
</div>
|
|
299
329
|
|
|
330
|
+
<!-- Generated endpoints -->
|
|
300
331
|
<div class="row mb-20">
|
|
301
332
|
<div class="col span-6">
|
|
302
333
|
<LabeledInput
|
|
@@ -320,6 +351,7 @@ export default {
|
|
|
320
351
|
</div>
|
|
321
352
|
</div>
|
|
322
353
|
|
|
354
|
+
<!-- Specific Endpoints -->
|
|
323
355
|
<div class="row mb-20">
|
|
324
356
|
<div class="col span-6">
|
|
325
357
|
<LabeledInput
|
|
@@ -350,12 +382,13 @@ export default {
|
|
|
350
382
|
:label="t(`authConfig.oidc.authEndpoint`)"
|
|
351
383
|
:mode="mode"
|
|
352
384
|
:disabled="!customEndpoint.value"
|
|
353
|
-
:required="
|
|
385
|
+
:required="requiresAuthEndpoint"
|
|
354
386
|
data-testid="oidc-auth-endpoint"
|
|
355
387
|
/>
|
|
356
388
|
</div>
|
|
357
389
|
</div>
|
|
358
390
|
|
|
391
|
+
<!-- Advanced section -->
|
|
359
392
|
<AdvancedSection :mode="mode">
|
|
360
393
|
<div class="row mb-20">
|
|
361
394
|
<div class="col span-6">
|
package/edit/auth/saml.vue
CHANGED
package/edit/cloudcredential.vue
CHANGED
|
@@ -100,6 +100,30 @@ export default {
|
|
|
100
100
|
computed: {
|
|
101
101
|
rke2Enabled: mapFeature(RKE2_FEATURE),
|
|
102
102
|
|
|
103
|
+
hasCustomCloudCredentialComponent() {
|
|
104
|
+
const driverName = this.driverName;
|
|
105
|
+
|
|
106
|
+
return this.$store.getters['type-map/hasCustomCloudCredentialComponent'](driverName);
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
cloudCredentialComponent() {
|
|
110
|
+
const driverName = this.driverName;
|
|
111
|
+
|
|
112
|
+
return this.$store.getters['type-map/importCloudCredential'](driverName);
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
genericCloudCredentialComponent() {
|
|
116
|
+
return this.$store.getters['type-map/importCloudCredential']('generic');
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
cloudComponent() {
|
|
120
|
+
if (this.hasCustomCloudCredentialComponent) {
|
|
121
|
+
return this.cloudCredentialComponent;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return this.genericCloudCredentialComponent;
|
|
125
|
+
},
|
|
126
|
+
|
|
103
127
|
validationPassed() {
|
|
104
128
|
return this.credCustomComponentValidation && this.nameRequiredValidation;
|
|
105
129
|
},
|
|
@@ -112,14 +136,6 @@ export default {
|
|
|
112
136
|
return this.value?.provider;
|
|
113
137
|
},
|
|
114
138
|
|
|
115
|
-
cloudComponent() {
|
|
116
|
-
if (this.$store.getters['type-map/hasCustomCloudCredentialComponent'](this.driverName)) {
|
|
117
|
-
return this.$store.getters['type-map/importCloudCredential'](this.driverName);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return this.$store.getters['type-map/importCloudCredential']('generic');
|
|
121
|
-
},
|
|
122
|
-
|
|
123
139
|
// array of id, label, description, initials for type selection step
|
|
124
140
|
secretSubTypes() {
|
|
125
141
|
const out = [];
|
|
@@ -194,7 +210,6 @@ export default {
|
|
|
194
210
|
},
|
|
195
211
|
|
|
196
212
|
methods: {
|
|
197
|
-
|
|
198
213
|
createValidationChanged(passed) {
|
|
199
214
|
this.credCustomComponentValidation = passed;
|
|
200
215
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mount } from '@vue/test-utils';
|
|
2
2
|
import Banzai from '@shell/edit/logging.banzaicloud.io.output/index.vue';
|
|
3
|
+
import { createStore } from 'vuex';
|
|
3
4
|
|
|
4
5
|
const outputSchema = {
|
|
5
6
|
id: 'logging.banzaicloud.io.output',
|
|
@@ -109,16 +110,26 @@ describe('view: logging.banzaicloud.io.output', () => {
|
|
|
109
110
|
['http://localhost:3100', []],
|
|
110
111
|
['not a proper URL', ['logging.loki.urlInvalid']],
|
|
111
112
|
])('should validate Loki URL on save', (url, expectation) => {
|
|
113
|
+
const store = createStore({
|
|
114
|
+
getters: {
|
|
115
|
+
namespaces: () => () => ({}),
|
|
116
|
+
currentStore: () => () => 'cluster',
|
|
117
|
+
'cluster/schemaFor': () => jest.fn()
|
|
118
|
+
}
|
|
119
|
+
});
|
|
112
120
|
const wrapper = mount(Banzai, {
|
|
113
121
|
data: () => ({ selectedProvider: 'loki' }),
|
|
114
122
|
props: {
|
|
115
123
|
value: {
|
|
116
|
-
save:
|
|
117
|
-
|
|
124
|
+
save: jest.fn(),
|
|
125
|
+
setAnnotation: jest.fn(),
|
|
126
|
+
spec: { loki: { url } },
|
|
127
|
+
metadata: {},
|
|
118
128
|
}
|
|
119
129
|
},
|
|
120
130
|
global: {
|
|
121
|
-
|
|
131
|
+
provide: { store },
|
|
132
|
+
mocks: {
|
|
122
133
|
$fetchState: { pending: false },
|
|
123
134
|
$store: {
|
|
124
135
|
dispatch: jest.fn(),
|
|
@@ -149,16 +160,26 @@ describe('view: logging.banzaicloud.io.output', () => {
|
|
|
149
160
|
});
|
|
150
161
|
|
|
151
162
|
it('should load the default YAML data for output buffer config (from schema) in a CREATE scenario', async() => {
|
|
163
|
+
const store = createStore({
|
|
164
|
+
getters: {
|
|
165
|
+
namespaces: () => () => ({}),
|
|
166
|
+
currentStore: () => () => 'cluster',
|
|
167
|
+
'cluster/schemaFor': () => jest.fn()
|
|
168
|
+
}
|
|
169
|
+
});
|
|
152
170
|
const wrapper = mount(Banzai, {
|
|
153
171
|
data: () => ({ selectedProvider: 'awsElasticsearch' }),
|
|
154
172
|
props: {
|
|
155
173
|
value: {
|
|
156
|
-
save:
|
|
157
|
-
|
|
174
|
+
save: jest.fn(),
|
|
175
|
+
setAnnotation: jest.fn(),
|
|
176
|
+
spec: {},
|
|
177
|
+
metadata: {},
|
|
158
178
|
}
|
|
159
179
|
},
|
|
160
180
|
global: {
|
|
161
|
-
|
|
181
|
+
provide: { store },
|
|
182
|
+
mocks: {
|
|
162
183
|
$fetchState: { pending: false },
|
|
163
184
|
$store: {
|
|
164
185
|
dispatch(arg: any) {
|
|
@@ -230,16 +251,26 @@ describe('view: logging.banzaicloud.io.output', () => {
|
|
|
230
251
|
});
|
|
231
252
|
|
|
232
253
|
it('should load current output buffer config in an EDIT scenario', async() => {
|
|
254
|
+
const store = createStore({
|
|
255
|
+
getters: {
|
|
256
|
+
namespaces: () => () => ({}),
|
|
257
|
+
currentStore: () => () => 'cluster',
|
|
258
|
+
'cluster/schemaFor': () => jest.fn()
|
|
259
|
+
}
|
|
260
|
+
});
|
|
233
261
|
const wrapper = mount(Banzai, {
|
|
234
262
|
data: () => ({ selectedProvider: 'awsElasticsearch' }),
|
|
235
263
|
props: {
|
|
236
264
|
value: {
|
|
237
|
-
save:
|
|
238
|
-
|
|
265
|
+
save: jest.fn(),
|
|
266
|
+
setAnnotation: jest.fn(),
|
|
267
|
+
spec: { awsElasticsearch: { buffer: '#chunk_limit_records: int' } },
|
|
268
|
+
metadata: {}
|
|
239
269
|
}
|
|
240
270
|
},
|
|
241
271
|
global: {
|
|
242
|
-
|
|
272
|
+
provide: { store },
|
|
273
|
+
mocks: {
|
|
243
274
|
$fetchState: { pending: false },
|
|
244
275
|
$store: {
|
|
245
276
|
dispatch(arg: any) {
|
|
@@ -15,6 +15,8 @@ export default {
|
|
|
15
15
|
ChangePassword, GlobalRoleBindings, CruResource, LabeledInput, Loading
|
|
16
16
|
},
|
|
17
17
|
|
|
18
|
+
emits: ['update:mode'],
|
|
19
|
+
|
|
18
20
|
mixins: [
|
|
19
21
|
CreateEditView
|
|
20
22
|
],
|
|
@@ -40,6 +42,7 @@ export default {
|
|
|
40
42
|
roles: !showGlobalRoles,
|
|
41
43
|
rolesChanged: false,
|
|
42
44
|
},
|
|
45
|
+
watchOverride: false,
|
|
43
46
|
};
|
|
44
47
|
},
|
|
45
48
|
|
|
@@ -115,7 +118,11 @@ export default {
|
|
|
115
118
|
this.$router.replace({ name: this.doneRoute });
|
|
116
119
|
buttonDone(true);
|
|
117
120
|
} catch (err) {
|
|
118
|
-
|
|
121
|
+
if (err?.message?.includes('errors due to escalation')) {
|
|
122
|
+
this.errors = [this.t('rbac.errors.escalation')];
|
|
123
|
+
} else {
|
|
124
|
+
this.errors = exceptionToErrorsArray(err);
|
|
125
|
+
}
|
|
119
126
|
buttonDone(false);
|
|
120
127
|
}
|
|
121
128
|
},
|
|
@@ -150,7 +157,7 @@ export default {
|
|
|
150
157
|
|
|
151
158
|
const normanUser = await this.$store.dispatch('rancher/find', {
|
|
152
159
|
type: NORMAN.USER,
|
|
153
|
-
id: this.value.id,
|
|
160
|
+
id: this.value.id || this.user?.id,
|
|
154
161
|
});
|
|
155
162
|
|
|
156
163
|
// Save change of password
|
|
@@ -181,8 +188,25 @@ export default {
|
|
|
181
188
|
},
|
|
182
189
|
|
|
183
190
|
async updateRoles(userId) {
|
|
184
|
-
if (this.$refs.grb) {
|
|
191
|
+
if (!this.$refs.grb) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
try {
|
|
185
196
|
await this.$refs.grb.save(userId);
|
|
197
|
+
} catch (err) {
|
|
198
|
+
if (this.isCreate) {
|
|
199
|
+
this.watchOverride = true;
|
|
200
|
+
this.$emit(
|
|
201
|
+
'update:mode',
|
|
202
|
+
{
|
|
203
|
+
userId,
|
|
204
|
+
mode: _EDIT,
|
|
205
|
+
resource: 'management.cattle.io.user',
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
throw err;
|
|
186
210
|
}
|
|
187
211
|
}
|
|
188
212
|
}
|
|
@@ -255,6 +279,7 @@ export default {
|
|
|
255
279
|
:user-id="value.id || liveValue.id"
|
|
256
280
|
:mode="mode"
|
|
257
281
|
:real-mode="realMode"
|
|
282
|
+
:watch-override="watchOverride"
|
|
258
283
|
type="user"
|
|
259
284
|
@hasChanges="validation.rolesChanged = $event"
|
|
260
285
|
@canLogIn="validation.roles = $event"
|
package/edit/namespace.vue
CHANGED
|
@@ -11,7 +11,6 @@ import Tab from '@shell/components/Tabbed/Tab';
|
|
|
11
11
|
import ResourceTabs from '@shell/components/form/ResourceTabs/index.vue';
|
|
12
12
|
import CruResource from '@shell/components/CruResource';
|
|
13
13
|
import { PROJECT_ID, _VIEW, FLAT_VIEW, _CREATE } from '@shell/config/query-params';
|
|
14
|
-
import MoveModal from '@shell/components/MoveModal';
|
|
15
14
|
import ResourceQuota from '@shell/components/form/ResourceQuota/Namespace';
|
|
16
15
|
import Loading from '@shell/components/Loading';
|
|
17
16
|
import { HARVESTER_TYPES, RANCHER_TYPES } from '@shell/components/form/ResourceQuota/shared';
|
|
@@ -31,8 +30,7 @@ export default {
|
|
|
31
30
|
PodSecurityAdmission,
|
|
32
31
|
ResourceQuota,
|
|
33
32
|
Tab,
|
|
34
|
-
ResourceTabs
|
|
35
|
-
MoveModal
|
|
33
|
+
ResourceTabs
|
|
36
34
|
},
|
|
37
35
|
|
|
38
36
|
mixins: [CreateEditView],
|
|
@@ -277,6 +275,5 @@ export default {
|
|
|
277
275
|
/>
|
|
278
276
|
</Tab>
|
|
279
277
|
</ResourceTabs>
|
|
280
|
-
<MoveModal v-if="projects" />
|
|
281
278
|
</CruResource>
|
|
282
279
|
</template>
|
|
@@ -5,6 +5,7 @@ import { get, set, remove } from '@shell/utils/object';
|
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
7
|
components: { LabeledSelect },
|
|
8
|
+
emits: ['update:value'],
|
|
8
9
|
props: {
|
|
9
10
|
value: {
|
|
10
11
|
type: Object,
|
|
@@ -37,13 +38,16 @@ export default {
|
|
|
37
38
|
},
|
|
38
39
|
methods: {
|
|
39
40
|
update(e) {
|
|
40
|
-
if (!e || e.label === this.t('generic.none')) {
|
|
41
|
+
if (!e || e === '' || e.label === this.t('generic.none')) {
|
|
41
42
|
remove(this.value, 'spec.ingressClassName');
|
|
42
43
|
this.ingressClassName = '';
|
|
44
|
+
this.$emit('update:value', this.value);
|
|
43
45
|
} else {
|
|
44
46
|
// when a user manually types an ingress class name, the event emitted has a 'label' but no 'value'
|
|
45
|
-
this.ingressClassName = e.
|
|
47
|
+
this.ingressClassName = e.label || e;
|
|
46
48
|
set(this.value, 'spec.ingressClassName', this.ingressClassName);
|
|
49
|
+
|
|
50
|
+
this.$emit('update:value', this.value);
|
|
47
51
|
}
|
|
48
52
|
}
|
|
49
53
|
}
|
|
@@ -59,7 +63,7 @@ export default {
|
|
|
59
63
|
:label="t('ingress.ingressClass.label')"
|
|
60
64
|
:options="ingressClassOptions"
|
|
61
65
|
option-label="label"
|
|
62
|
-
@
|
|
66
|
+
@update:value="update"
|
|
63
67
|
/>
|
|
64
68
|
</div>
|
|
65
69
|
</template>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { shallowMount } from '@vue/test-utils';
|
|
2
|
+
import IngressClass from '@shell/edit/networking.k8s.io.ingress/IngressClass.vue';
|
|
3
|
+
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
4
|
+
import { _EDIT } from '@shell/config/query-params';
|
|
5
|
+
|
|
6
|
+
jest.mock('@shell/components/form/LabeledSelect', () => ({
|
|
7
|
+
name: 'LabeledSelect',
|
|
8
|
+
template: '<div></div>',
|
|
9
|
+
props: ['value', 'taggable', 'searchable', 'mode', 'label', 'options', 'optionLabel'],
|
|
10
|
+
emits: ['update:value'],
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
describe('ingressClass.vue', () => {
|
|
14
|
+
it('renders correctly', () => {
|
|
15
|
+
const wrapper = shallowMount(IngressClass, {
|
|
16
|
+
props: {
|
|
17
|
+
value: {},
|
|
18
|
+
ingressClasses: [],
|
|
19
|
+
mode: _EDIT,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(wrapper.exists()).toBe(true);
|
|
24
|
+
expect(wrapper.findComponent(LabeledSelect).exists()).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('updates ingressClassName correctly', async() => {
|
|
28
|
+
const wrapper = shallowMount(IngressClass, {
|
|
29
|
+
props: {
|
|
30
|
+
value: {},
|
|
31
|
+
ingressClasses: [{ label: 'nginx', value: 'nginx' }],
|
|
32
|
+
mode: _EDIT,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
await wrapper.findComponent(LabeledSelect).vm.$emit('update:value', 'nginx');
|
|
37
|
+
|
|
38
|
+
expect(wrapper.vm.ingressClassName).toBe('nginx');
|
|
39
|
+
expect(wrapper.props('value').spec.ingressClassName).toBe('nginx');
|
|
40
|
+
expect(wrapper.emitted()['update:value']).toBeTruthy();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('removes ingressClassName when none is selected', async() => {
|
|
44
|
+
const wrapper = shallowMount(IngressClass, {
|
|
45
|
+
props: {
|
|
46
|
+
value: { spec: { ingressClassName: 'nginx' } },
|
|
47
|
+
ingressClasses: [{ label: 'nginx', value: 'nginx' }],
|
|
48
|
+
mode: _EDIT,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
await wrapper.findComponent(LabeledSelect).vm.$emit('update:value', '');
|
|
53
|
+
|
|
54
|
+
expect(wrapper.vm.ingressClassName).toBe('');
|
|
55
|
+
expect(wrapper.props('value').spec.ingressClassName).toBeUndefined();
|
|
56
|
+
expect(wrapper.emitted()['update:value']).toBeTruthy();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -9,7 +9,13 @@ describe('view: PersistentVolume', () => {
|
|
|
9
9
|
};
|
|
10
10
|
const resource = 'PersistentVolume';
|
|
11
11
|
const wrapper = mount(PersistentVolume as ExtendedVue<Vue, {}, {}, {}, PersistentVolume>, {
|
|
12
|
-
props: {
|
|
12
|
+
props: {
|
|
13
|
+
value: {
|
|
14
|
+
setAnnotation: jest.fn(),
|
|
15
|
+
spec: {},
|
|
16
|
+
metadata: {},
|
|
17
|
+
}
|
|
18
|
+
},
|
|
13
19
|
|
|
14
20
|
global: {
|
|
15
21
|
mocks: {
|
|
@@ -54,7 +60,13 @@ describe('view: PersistentVolume', () => {
|
|
|
54
60
|
const plugin = 'csi';
|
|
55
61
|
const resource = 'PersistentVolume';
|
|
56
62
|
const wrapper = mount(PersistentVolume as ExtendedVue<Vue, {}, {}, {}, PersistentVolume>, {
|
|
57
|
-
props:
|
|
63
|
+
props: {
|
|
64
|
+
value: {
|
|
65
|
+
setAnnotation: jest.fn(),
|
|
66
|
+
spec: { [plugin]: { value: plugin } },
|
|
67
|
+
metadata: {},
|
|
68
|
+
}
|
|
69
|
+
},
|
|
58
70
|
global: {
|
|
59
71
|
mocks: {
|
|
60
72
|
$store: {
|
|
@@ -260,7 +260,10 @@ export default {
|
|
|
260
260
|
/>
|
|
261
261
|
|
|
262
262
|
<template v-if="cluster.supportsWindows">
|
|
263
|
-
<hr
|
|
263
|
+
<hr
|
|
264
|
+
class="mt-20 mb-20"
|
|
265
|
+
role="none"
|
|
266
|
+
>
|
|
264
267
|
<h4 v-t="'cluster.custom.registrationCommand.windowsDetail'" />
|
|
265
268
|
<Banner
|
|
266
269
|
v-if="readyForWindows"
|