@rancher/shell 0.5.2 → 1.2.0
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/.DS_Store +0 -0
- package/assets/images/providers/aks-black.svg +28 -0
- package/assets/images/providers/aks.svg +31 -0
- package/assets/styles/global/_labeled-input.scss +1 -0
- package/assets/styles/global/_layout.scss +0 -99
- package/assets/translations/en-us.yaml +77 -71
- package/assets/translations/zh-hans.yaml +25 -23
- package/babel.config.js +1 -7
- package/chart/gatekeeper.vue +11 -2
- package/chart/istio.vue +10 -1
- package/chart/logging/index.vue +11 -2
- package/chart/monitoring/alerting/index.vue +21 -7
- package/chart/monitoring/grafana/index.vue +2 -57
- package/chart/monitoring/index.vue +26 -52
- package/chart/monitoring/prometheus/index.vue +43 -37
- package/chart/rancher-backup/index.vue +10 -3
- package/cloud-credential/azure.vue +17 -4
- package/components/AsyncButton.vue +0 -9
- package/components/Carousel.vue +0 -1
- package/components/ChartPsp.vue +76 -0
- package/components/CodeMirror.vue +21 -19
- package/components/CopyCode.vue +2 -6
- package/components/CopyToClipboard.vue +1 -2
- package/components/CopyToClipboardText.vue +9 -14
- package/components/CruResource.vue +0 -1
- package/components/EtcdInfoBanner.vue +5 -5
- package/components/ExplorerProjectsNamespaces.vue +1 -25
- package/components/IconOrSvg.vue +1 -1
- package/components/Markdown.vue +12 -16
- package/components/Questions/index.vue +1 -1
- package/components/ResourceDetail/Masthead.vue +9 -25
- package/components/ResourceList/Masthead.vue +18 -1
- package/components/ResourceTable.vue +2 -14
- package/components/ResourceYaml.vue +0 -5
- package/components/SideNav.vue +1 -1
- package/components/SortableTable/THead.vue +9 -7
- package/components/SortableTable/index.vue +3 -2
- package/components/StatusTable.vue +1 -5
- package/components/TabTitle.vue +84 -0
- package/components/Tabbed/index.vue +0 -12
- package/components/__tests__/ChartPsp.test.ts +75 -0
- package/components/__tests__/CopyCode.test.ts +4 -5
- package/components/fleet/FleetBundles.vue +11 -5
- package/components/fleet/FleetRepos.vue +27 -62
- package/components/fleet/FleetResources.vue +1 -6
- package/components/fleet/FleetStatus.vue +3 -3
- package/components/fleet/FleetSummary.vue +30 -35
- package/components/form/ArrayList.vue +8 -1
- package/components/form/ArrayListSelect.vue +9 -9
- package/components/form/KeyValue.vue +0 -1
- package/components/form/LabeledSelect.vue +0 -4
- package/components/form/Password.vue +1 -3
- package/components/form/Select.vue +1 -1
- package/components/form/SelectOrCreateAuthSecret.vue +4 -4
- package/components/form/__tests__/KeyValue.test.ts +1 -1
- package/components/formatter/Checked.vue +3 -11
- package/components/formatter/ClusterProvider.vue +18 -1
- package/components/formatter/FleetSummaryGraph.vue +11 -23
- package/components/formatter/LiveDate.vue +16 -0
- package/components/formatter/LiveDuration.vue +1 -1
- package/components/formatter/PercentageBar.vue +1 -1
- package/components/formatter/__tests__/ClusterProvider.test.ts +28 -0
- package/components/nav/Group.vue +2 -2
- package/components/nav/Header.vue +2 -1
- package/components/nav/TopLevelMenu.vue +3 -29
- package/components/nav/Type.vue +3 -1
- package/components/nav/WindowManager/ContainerLogs.vue +19 -120
- package/components/nav/WindowManager/ContainerShell.vue +1 -6
- package/components/nav/WindowManager/index.vue +10 -11
- package/components/nav/__tests__/TopLevelMenu.test.ts +0 -33
- package/components/nav/__tests__/Type.test.ts +1 -1
- package/components/nuxt/nuxt-child.js +78 -14
- package/components/nuxt/nuxt.js +1 -1
- package/components/user.retention/user-retention-header.vue +34 -0
- package/composables/useI18n.ts +26 -0
- package/composables/useStore.ts +16 -0
- package/config/harvester-manager-types.js +0 -2
- package/config/home-links.js +32 -2
- package/config/private-label.js +0 -22
- package/config/product/explorer.js +4 -4
- package/config/product/fleet.js +1 -6
- package/config/product/legacy.js +1 -84
- package/config/product/manager.js +15 -8
- package/config/query-params.js +0 -1
- package/config/router.js +368 -385
- package/config/settings.ts +9 -2
- package/config/store.js +1 -1
- package/config/system-namespaces.js +0 -3
- package/config/table-headers.js +27 -47
- package/config/types.js +5 -0
- package/config/uiplugins.js +1 -1
- package/core/plugin-helpers.js +5 -3
- package/core/plugin-routes.ts +114 -56
- package/core/plugin.ts +10 -16
- package/core/plugins-loader.js +9 -7
- package/core/plugins.js +3 -0
- package/core/types-provisioning.ts +0 -7
- package/creators/app/init +0 -19
- package/detail/fleet.cattle.io.cluster.vue +1 -11
- package/detail/node.vue +0 -42
- package/detail/pod.vue +1 -68
- package/detail/provisioning.cattle.io.cluster.vue +4 -6
- package/detail/workload/index.vue +1 -15
- package/dialog/ScaleMachineDownDialog.vue +17 -34
- package/edit/auth/googleoauth.vue +5 -1
- package/edit/catalog.cattle.io.clusterrepo.vue +7 -20
- package/edit/cloudcredential.vue +0 -2
- package/edit/fleet.cattle.io.gitrepo.vue +4 -3
- package/edit/management.cattle.io.project.vue +52 -1
- package/edit/management.cattle.io.setting.vue +2 -31
- package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +3 -12
- package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +1 -2
- package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +1 -1
- package/edit/provisioning.cattle.io.cluster/{tabs/Basics.vue → Basics.vue} +126 -109
- package/edit/provisioning.cattle.io.cluster/{tabs/MachinePool.vue → MachinePool.vue} +7 -1
- package/edit/provisioning.cattle.io.cluster/{tabs/registries/RegistryConfigs.vue → RegistryConfigs.vue} +3 -1
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +7 -15
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +237 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/{CustomCommand.test.ts → CustomCommand.tests.ts} +0 -6
- package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +1 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +1 -7
- package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/index.vue +37 -99
- package/edit/provisioning.cattle.io.cluster/rke2.vue +690 -181
- package/edit/service.vue +0 -12
- package/edit/workload/Upgrading.vue +2 -3
- package/edit/workload/index.vue +1 -2
- package/edit/workload/mixins/workload.js +1 -1
- package/initialize/App.js +71 -25
- package/initialize/client.js +162 -21
- package/initialize/index.js +124 -47
- package/initialize/layouts.ts +26 -0
- package/{components/templates → layouts}/blank.vue +1 -1
- package/{components/templates → layouts}/default.vue +98 -8
- package/{components/templates → layouts}/error.vue +19 -10
- package/{components/templates → layouts}/home.vue +1 -4
- package/{components/templates → layouts}/plain.vue +1 -4
- package/{components/templates → layouts}/standalone.vue +1 -1
- package/{components/templates → layouts}/unauthenticated.vue +1 -1
- package/list/management.cattle.io.feature.vue +7 -1
- package/list/management.cattle.io.user.vue +25 -1
- package/list/node.vue +0 -1
- package/machine-config/__tests__/vmwarevsphere.test.ts +161 -56
- package/machine-config/amazonec2.vue +1 -0
- package/machine-config/azure.vue +37 -21
- package/machine-config/vmwarevsphere.vue +47 -42
- package/middleware/authenticated.js +19 -14
- package/mixins/auth-config.js +7 -2
- package/mixins/brand.js +41 -29
- package/mixins/fetch.server.js +73 -0
- package/mixins/labeled-form-element.ts +1 -6
- package/models/__tests__/management.cattle.io.node.ts +0 -85
- package/models/__tests__/namespace.test.ts +9 -49
- package/models/cluster/node.js +4 -4
- package/models/cluster.x-k8s.io.machine.js +1 -1
- package/models/cluster.x-k8s.io.machinedeployment.js +0 -14
- package/models/fleet.cattle.io.cluster.js +0 -4
- package/models/fleet.cattle.io.gitrepo.js +13 -56
- package/models/management.cattle.io.cluster.js +3 -11
- package/models/management.cattle.io.kontainerdriver.js +0 -1
- package/models/management.cattle.io.node.js +14 -18
- package/models/management.cattle.io.nodepool.js +0 -17
- package/models/management.cattle.io.project.js +36 -0
- package/models/management.cattle.io.setting.js +7 -11
- package/models/management.cattle.io.user.js +65 -0
- package/models/namespace.js +1 -1
- package/models/pod.js +0 -20
- package/models/provisioning.cattle.io.cluster.js +8 -55
- package/models/secret.js +18 -117
- package/models/workload.js +0 -16
- package/models/workload.service.js +0 -18
- package/package.json +10 -12
- package/pages/about.vue +1 -0
- package/pages/account/create-key.vue +1 -0
- package/pages/account/index.vue +1 -0
- package/pages/auth/login.vue +1 -0
- package/pages/auth/logout.vue +2 -0
- package/pages/auth/setup.vue +4 -37
- package/pages/auth/verify.vue +8 -14
- package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +17 -2
- package/pages/c/_cluster/apps/charts/index.vue +58 -64
- package/pages/c/_cluster/apps/charts/install.helpers.js +13 -2
- package/pages/c/_cluster/apps/charts/install.vue +5 -5
- package/pages/c/_cluster/apps/index.vue +2 -0
- package/pages/c/_cluster/auth/index.vue +2 -0
- package/pages/c/_cluster/auth/user.retention/index.vue +384 -0
- package/pages/c/_cluster/ecm/index.vue +2 -0
- package/pages/c/_cluster/explorer/index.vue +53 -56
- package/pages/c/_cluster/explorer/tools/index.vue +3 -171
- package/pages/c/_cluster/fleet/index.vue +1 -1
- package/pages/c/_cluster/index.vue +2 -0
- package/pages/c/_cluster/manager/pages/_page.vue +5 -4
- package/pages/c/_cluster/monitoring/index.vue +1 -17
- package/pages/c/_cluster/settings/DefaultLinksEditor.vue +1 -0
- package/pages/c/_cluster/settings/banners.vue +2 -0
- package/pages/c/_cluster/settings/brand.vue +2 -0
- package/pages/c/_cluster/settings/index.vue +2 -0
- package/pages/c/_cluster/settings/links.vue +3 -2
- package/pages/c/_cluster/settings/performance.vue +1 -0
- package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +4 -4
- package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +1 -2
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +46 -10
- package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +5 -2
- package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +96 -0
- package/pages/c/_cluster/uiplugins/__tests__/SetupUIPlugins.test.ts +128 -0
- package/pages/c/_cluster/uiplugins/index.vue +2 -0
- package/pages/c/index.vue +9 -0
- package/pages/diagnostic.vue +2 -1
- package/pages/fail-whale.vue +1 -0
- package/pages/prefs.vue +1 -0
- package/pages/rio/mesh.vue +508 -0
- package/pages/support/index.vue +8 -2
- package/pkg/auto-import.js +1 -1
- package/plugins/axios.js +36 -0
- package/plugins/back-button.js +5 -3
- package/plugins/clean-html-directive.js +19 -1
- package/plugins/clean-tooltip-directive.js +1 -1
- package/plugins/codemirror-loader.js +1 -1
- package/plugins/codemirror.js +0 -41
- package/plugins/dashboard-store/__tests__/actions.spec.ts +250 -0
- package/plugins/dashboard-store/__tests__/{mutations.test.ts → mutations.spec.ts} +1 -1
- package/plugins/dashboard-store/actions.js +21 -22
- package/plugins/dashboard-store/classify.js +18 -1
- package/plugins/dashboard-store/getters.js +5 -10
- package/plugins/dashboard-store/index.js +12 -0
- package/plugins/dashboard-store/mutations.js +4 -0
- package/plugins/dashboard-store/resource-class.js +18 -59
- package/plugins/i18n.js +1 -1
- package/plugins/steve/__tests__/getters.spec.ts +56 -24
- package/plugins/steve/__tests__/subscribe.spec.ts +106 -0
- package/plugins/steve/getters.js +30 -7
- package/plugins/steve/mutations.js +5 -2
- package/plugins/steve/norman-class.js +0 -19
- package/plugins/steve/steve-class.js +0 -22
- package/plugins/steve/subscribe.js +34 -13
- package/plugins/transitions.js +4 -0
- package/plugins/vue-clipboard2.js +4 -0
- package/rancher-components/Accordion/Accordion.vue +3 -2
- package/rancher-components/BadgeState/BadgeState.vue +3 -3
- package/rancher-components/Banner/Banner.test.ts +1 -5
- package/rancher-components/Banner/Banner.vue +2 -2
- package/rancher-components/Card/Card.vue +4 -4
- package/rancher-components/Form/Checkbox/Checkbox.vue +4 -3
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +1 -1
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +55 -24
- package/rancher-components/Form/Radio/RadioButton.test.ts +1 -3
- package/rancher-components/Form/Radio/RadioButton.vue +13 -7
- package/rancher-components/Form/Radio/RadioGroup.vue +4 -3
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -5
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
- package/rancher-components/StringList/StringList.vue +8 -8
- package/rancher-components/components/Accordion/Accordion.vue +3 -2
- package/rancher-components/components/BadgeState/BadgeState.test.ts +12 -0
- package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +2 -19
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +14 -11
- package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +1 -1
- package/rancher-components/components/StringList/StringList.test.ts +0 -270
- package/rancher-components/components/StringList/StringList.vue +18 -57
- package/scripts/extension/bundle +7 -19
- package/scripts/extension/helm/scripts/package +3 -11
- package/scripts/extension/parse-tag-name +4 -4
- package/scripts/extension/publish +9 -20
- package/scripts/publish-shell.sh +1 -11
- package/scripts/test-plugins-build.sh +9 -85
- package/store/catalog.js +1 -1
- package/store/features.js +0 -1
- package/store/i18n.js +0 -11
- package/store/index.js +11 -8
- package/store/prefs.js +38 -33
- package/store/type-map.js +8 -13
- package/tsconfig.default.json +46 -0
- package/tsconfig.json +9 -35
- package/types/shell/index.d.ts +404 -463
- package/utils/__tests__/create-yaml.test.ts +10 -0
- package/utils/axios.js +19 -0
- package/utils/create-yaml.js +6 -6
- package/utils/custom-validators.js +2 -0
- package/utils/error.js +1 -16
- package/utils/monitoring.js +2 -37
- package/utils/nuxt.js +39 -18
- package/utils/object.js +0 -14
- package/utils/router.scrollBehavior.js +14 -12
- package/utils/socket.js +1 -0
- package/utils/time.js +1 -1
- package/utils/title.ts +3 -0
- package/utils/url.ts +1 -1
- package/utils/validators/formRules/__tests__/index.test.ts +4 -49
- package/utils/validators/formRules/index.ts +9 -12
- package/utils/validators/setting.js +10 -6
- package/vue.config.js +3 -24
- package/chart/monitoring/steps/uninstall-v1.vue +0 -135
- package/components/Certificates.vue +0 -164
- package/components/fleet/__tests__/FleetSummary.test.ts +0 -316
- package/components/formatter/FleetClusterSummaryGraph.vue +0 -27
- package/components/formatter/__tests__/Checked.test.ts +0 -19
- package/components/nav/WindowManager/__tests__/ContainerLogs.test.ts +0 -186
- package/composables/useCompactInput.ts +0 -20
- package/composables/useLabeledFormElement.ts +0 -138
- package/creators/app/files/.gitlab-ci.yml +0 -14
- package/edit/__tests__/service.test.ts +0 -89
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +0 -112
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +0 -473
- package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +0 -73
- package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +0 -386
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +0 -137
- package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +0 -157
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +0 -135
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +0 -189
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +0 -144
- package/edit/provisioning.cattle.io.cluster/tabs/upgrade/index.vue +0 -76
- package/mixins/v1-workload-metrics.js +0 -43
- package/models/__tests__/management.cattle.io.cluster.test.ts +0 -23
- package/models/__tests__/management.cattle.io.nodepool.ts +0 -83
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +0 -90
- package/models/__tests__/workload.test.ts +0 -91
- package/plugins/clean-html.js +0 -53
- package/plugins/dashboard-store/__tests__/actions.test.ts +0 -165
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +0 -49
- package/plugins/dashboard-store/__tests__/utils/store-mocks.ts +0 -7
- package/plugins/index.js +0 -11
- package/plugins/steve/__tests__/steve-class.spec.ts +0 -59
- package/plugins/steve/__tests__/utils/steve-mocks.ts +0 -31
- package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +0 -50
- package/server/har-file.js +0 -183
- package/tsconfig.paths.json +0 -18
- package/utils/azure.js +0 -24
- package/utils/clipboard.js +0 -5
- /package/components/form/__tests__/{NameNsDescription.test.ts → NameNsDescription.ts} +0 -0
- /package/edit/networking.k8s.io.networkpolicy/__tests__/utils/{selectors.test.ts → selectors.ts} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{tabs/networking/ACE.vue → ACE.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{tabs/AgentConfiguration.vue → AgentConfiguration.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{tabs/upgrade/DrainOptions.vue → DrainOptions.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{tabs/MemberRoles.vue → MemberRoles.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{tabs/registries/RegistryMirrors.vue → RegistryMirrors.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{tabs/etcd/S3Config.vue → S3Config.vue} +0 -0
- /package/plugins/dashboard-store/__tests__/{getters.test.ts → getters.spec.ts} +0 -0
- /package/rancher-components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
|
@@ -93,89 +93,4 @@ describe('class MgmtNode', () => {
|
|
|
93
93
|
resetMocks();
|
|
94
94
|
});
|
|
95
95
|
});
|
|
96
|
-
|
|
97
|
-
describe('canScaleDown', () => {
|
|
98
|
-
const mgmtClusterId = 'test';
|
|
99
|
-
const nodeId = 'test/id';
|
|
100
|
-
const specs = {
|
|
101
|
-
worker: {
|
|
102
|
-
worker: true, etcd: false, controlPlane: false
|
|
103
|
-
},
|
|
104
|
-
etcd: {
|
|
105
|
-
worker: false, etcd: true, controlPlane: false
|
|
106
|
-
},
|
|
107
|
-
controlPlane: {
|
|
108
|
-
worker: false, etcd: false, controlPlane: true
|
|
109
|
-
},
|
|
110
|
-
etcdAndControlPlane: {
|
|
111
|
-
worker: false, etcd: true, controlPlane: true
|
|
112
|
-
},
|
|
113
|
-
all: {
|
|
114
|
-
worker: true, etcd: true, controlPlane: true
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
const workerNode = {
|
|
119
|
-
id: '01',
|
|
120
|
-
isWorker: true,
|
|
121
|
-
isControlPlane: false,
|
|
122
|
-
isEtcd: false
|
|
123
|
-
};
|
|
124
|
-
const etcdNode = {
|
|
125
|
-
id: '02',
|
|
126
|
-
isWorker: false,
|
|
127
|
-
isControlPlane: false,
|
|
128
|
-
isEtcd: true
|
|
129
|
-
};
|
|
130
|
-
const controlPlaneNode = {
|
|
131
|
-
id: '03',
|
|
132
|
-
isWorker: false,
|
|
133
|
-
isControlPlane: true,
|
|
134
|
-
isEtcd: false
|
|
135
|
-
};
|
|
136
|
-
const etcdAndControlPlaneNode = {
|
|
137
|
-
id: '03',
|
|
138
|
-
isWorker: false,
|
|
139
|
-
isControlPlane: true,
|
|
140
|
-
isEtcd: true
|
|
141
|
-
};
|
|
142
|
-
const allNode = {
|
|
143
|
-
id: '04',
|
|
144
|
-
isWorker: true,
|
|
145
|
-
isControlPlane: true,
|
|
146
|
-
isEtcd: true
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
const baseCtx = {
|
|
150
|
-
rootGetters: {
|
|
151
|
-
'rancher/byId': () => ({ actions: { scaledown: 'scaledown' } }),
|
|
152
|
-
'i18n/t': t
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
it.each([
|
|
157
|
-
[{ spec: specs.worker, nodes: [workerNode] }, true],
|
|
158
|
-
[{ spec: specs.etcd, nodes: [etcdNode, etcdNode, controlPlaneNode] }, true],
|
|
159
|
-
[{ spec: specs.etcdAndControlPlane, nodes: [etcdAndControlPlaneNode, etcdAndControlPlaneNode] }, true],
|
|
160
|
-
[{ spec: specs.etcdAndControlPlane, nodes: [etcdAndControlPlaneNode] }, false],
|
|
161
|
-
[{ spec: specs.all, nodes: [allNode] }, false],
|
|
162
|
-
[{ spec: specs.all, nodes: [allNode, allNode] }, true],
|
|
163
|
-
])('should return canScaleDown properly', (data, expected) => {
|
|
164
|
-
const { spec, nodes } = data;
|
|
165
|
-
const mgmtNode = new MgmtNode({
|
|
166
|
-
spec,
|
|
167
|
-
id: nodeId
|
|
168
|
-
}, {
|
|
169
|
-
...baseCtx,
|
|
170
|
-
getters: {
|
|
171
|
-
all: () => [{
|
|
172
|
-
mgmtClusterId,
|
|
173
|
-
nodes
|
|
174
|
-
}]
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
expect(mgmtNode.canScaleDown).toStrictEqual(expected);
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
96
|
});
|
|
@@ -1,48 +1,11 @@
|
|
|
1
1
|
import Namespace from '@shell/models/namespace';
|
|
2
|
-
import { SYSTEM_NAMESPACE } from '@shell/config/labels-annotations';
|
|
3
|
-
import SYSTEM_NAMESPACES from '@shell/config/system-namespaces';
|
|
4
2
|
|
|
5
3
|
describe('class Namespace', () => {
|
|
6
4
|
describe('checking if isSystem', () => {
|
|
7
5
|
it.each([
|
|
8
|
-
['
|
|
9
|
-
['
|
|
10
|
-
|
|
11
|
-
])('should return true if it has the correct annotation', (name, annotation, expectation) => {
|
|
12
|
-
const namespace = new Namespace({});
|
|
13
|
-
|
|
14
|
-
namespace.metadata = { ...namespace.metadata, name };
|
|
15
|
-
|
|
16
|
-
if (annotation) {
|
|
17
|
-
namespace.metadata.annotations = { [annotation]: 'true' };
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
expect(namespace.isSystem).toBe(expectation);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const assertionsArr = [];
|
|
24
|
-
|
|
25
|
-
SYSTEM_NAMESPACES.forEach((ns) => {
|
|
26
|
-
assertionsArr.push([ns, true]);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
assertionsArr.push(['c-whatever-system', false]);
|
|
30
|
-
assertionsArr.push(['cattle-whatever', false]);
|
|
31
|
-
assertionsArr.push(['', false]);
|
|
32
|
-
|
|
33
|
-
it.each(assertionsArr)('should return true if it belongs to the curated list of namespaces', (name, expectation) => {
|
|
34
|
-
const namespace = new Namespace({});
|
|
35
|
-
|
|
36
|
-
namespace.metadata = { ...namespace.metadata, name };
|
|
37
|
-
|
|
38
|
-
expect(namespace.isSystem).toBe(expectation);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it.each([
|
|
42
|
-
['cattle-c-whatever-system', true],
|
|
43
|
-
['cattle-whatever', false],
|
|
44
|
-
['c-whatever-system', false]
|
|
45
|
-
])('should return true if starts with "cattle-" end with "-system', (name, expectation) => {
|
|
6
|
+
['c-whatever-system', true],
|
|
7
|
+
['whatever', false]
|
|
8
|
+
])('should return true if end with "-system', (name, expectation) => {
|
|
46
9
|
const namespace = new Namespace({});
|
|
47
10
|
|
|
48
11
|
namespace.metadata = { ...namespace.metadata, name };
|
|
@@ -55,21 +18,18 @@ describe('class Namespace', () => {
|
|
|
55
18
|
|
|
56
19
|
describe('checking if isObscure', () => {
|
|
57
20
|
it.each([
|
|
58
|
-
['c-whatever-system',
|
|
59
|
-
['
|
|
60
|
-
['
|
|
61
|
-
|
|
62
|
-
])('should return a value if is system AND has the correct prefix', (name, annotation, expectation) => {
|
|
21
|
+
['c-whatever-system', true],
|
|
22
|
+
['whatever', false],
|
|
23
|
+
['', false]
|
|
24
|
+
])('should return a value if has or not a name in the metadata', (name, expectation) => {
|
|
63
25
|
const namespace = new Namespace({});
|
|
64
26
|
|
|
65
27
|
namespace.metadata = { ...namespace.metadata, name };
|
|
66
28
|
|
|
67
|
-
if (annotation) {
|
|
68
|
-
namespace.metadata.annotations = { [annotation]: 'true' };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
29
|
expect(namespace.isObscure).toBe(expectation);
|
|
72
30
|
});
|
|
31
|
+
|
|
32
|
+
it.todo('should return a value if is or not system');
|
|
73
33
|
});
|
|
74
34
|
|
|
75
35
|
it.each([
|
package/models/cluster/node.js
CHANGED
|
@@ -187,7 +187,7 @@ export default class ClusterNode extends SteveModel {
|
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
get cpuCapacity() {
|
|
190
|
-
return parseSi(this.status.allocatable
|
|
190
|
+
return parseSi(this.status.allocatable.cpu);
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
get cpuUsagePercentage() {
|
|
@@ -203,7 +203,7 @@ export default class ClusterNode extends SteveModel {
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
get ramCapacity() {
|
|
206
|
-
return parseSi(this.status.capacity
|
|
206
|
+
return parseSi(this.status.capacity.memory);
|
|
207
207
|
}
|
|
208
208
|
|
|
209
209
|
get ramUsagePercentage() {
|
|
@@ -219,7 +219,7 @@ export default class ClusterNode extends SteveModel {
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
get podUsage() {
|
|
222
|
-
return calculatePercentage(this.status.allocatable
|
|
222
|
+
return calculatePercentage(this.status.allocatable.pods, this.status.capacity.pods);
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
get podConsumedUsage() {
|
|
@@ -227,7 +227,7 @@ export default class ClusterNode extends SteveModel {
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
get podCapacity() {
|
|
230
|
-
return Number.parseInt(this.status.capacity
|
|
230
|
+
return Number.parseInt(this.status.capacity.pods);
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
get podConsumed() {
|
|
@@ -7,7 +7,6 @@ import { handleConflict } from '@shell/plugins/dashboard-store/normalize';
|
|
|
7
7
|
import { MACHINE_ROLES } from '@shell/config/labels-annotations';
|
|
8
8
|
import { notOnlyOfRole } from '@shell/models/cluster.x-k8s.io.machine';
|
|
9
9
|
import { KIND } from '../config/elemental-types';
|
|
10
|
-
import { KIND as HARVESTER_KIND } from '../config/harvester-manager-types';
|
|
11
10
|
|
|
12
11
|
export default class CapiMachineDeployment extends SteveModel {
|
|
13
12
|
get cluster() {
|
|
@@ -70,19 +69,6 @@ export default class CapiMachineDeployment extends SteveModel {
|
|
|
70
69
|
return this.template?.providerSize || this.t('node.list.poolDescription.noSize');
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
get providerSummary() {
|
|
74
|
-
if (this.template) {
|
|
75
|
-
switch (this.infrastructureRefKind) {
|
|
76
|
-
case HARVESTER_KIND.MACHINE_TEMPLATE:
|
|
77
|
-
return null;
|
|
78
|
-
default:
|
|
79
|
-
return `${ this.providerDisplay } \u2013 ${ this.providerLocation } / ${ this.providerSize } (${ this.providerName })`;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
72
|
get desired() {
|
|
87
73
|
return this.spec?.replicas || 0;
|
|
88
74
|
}
|
|
@@ -107,10 +107,6 @@ export default class FleetCluster extends SteveModel {
|
|
|
107
107
|
return this.metadata?.labels?.[FLEET_LABELS.CLUSTER_DISPLAY_NAME] || this.metadata?.name || this.id;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
get name() {
|
|
111
|
-
return this.metadata?.name || this.metadata?.labels?.[FLEET_LABELS.CLUSTER_NAME];
|
|
112
|
-
}
|
|
113
|
-
|
|
114
110
|
get state() {
|
|
115
111
|
if (this.spec?.paused === true) {
|
|
116
112
|
return 'paused';
|
|
@@ -7,9 +7,7 @@ import { FLEET as FLEET_ANNOTATIONS } from '@shell/config/labels-annotations';
|
|
|
7
7
|
import { addObject, addObjects, findBy, insertAt } from '@shell/utils/array';
|
|
8
8
|
import { set } from '@shell/utils/object';
|
|
9
9
|
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
10
|
-
import {
|
|
11
|
-
STATES_ENUM, colorForState, mapStateToEnum, primaryDisplayStatusFromCount, stateDisplay, stateSort
|
|
12
|
-
} from '@shell/plugins/dashboard-store/resource-class';
|
|
10
|
+
import { STATES_ENUM, colorForState, stateDisplay, stateSort } from '@shell/plugins/dashboard-store/resource-class';
|
|
13
11
|
import { NAME } from '@shell/config/product/explorer';
|
|
14
12
|
|
|
15
13
|
function quacksLikeAHash(str) {
|
|
@@ -205,6 +203,17 @@ export default class GitRepo extends SteveModel {
|
|
|
205
203
|
return hash;
|
|
206
204
|
}
|
|
207
205
|
|
|
206
|
+
get clusterInfo() {
|
|
207
|
+
const ready = this.status?.readyClusters || 0;
|
|
208
|
+
const total = this.status?.desiredReadyClusters || 0;
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
ready,
|
|
212
|
+
unready: total - ready,
|
|
213
|
+
total,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
208
217
|
get targetInfo() {
|
|
209
218
|
let mode = null;
|
|
210
219
|
let cluster = null;
|
|
@@ -375,9 +384,8 @@ export default class GitRepo extends SteveModel {
|
|
|
375
384
|
namespace: r.namespace,
|
|
376
385
|
name: r.name,
|
|
377
386
|
clusterId: c.id,
|
|
378
|
-
clusterLabel: c.metadata.labels[FLEET_ANNOTATIONS.CLUSTER_NAME],
|
|
379
387
|
clusterName: c.nameDisplay,
|
|
380
|
-
state
|
|
388
|
+
state,
|
|
381
389
|
stateBackground: color,
|
|
382
390
|
stateDisplay: display,
|
|
383
391
|
stateSort: stateSort(color, display),
|
|
@@ -393,57 +401,6 @@ export default class GitRepo extends SteveModel {
|
|
|
393
401
|
return out;
|
|
394
402
|
}
|
|
395
403
|
|
|
396
|
-
get clusterInfo() {
|
|
397
|
-
const ready = this.status?.readyClusters || 0;
|
|
398
|
-
const total = this.status?.desiredReadyClusters || 0;
|
|
399
|
-
|
|
400
|
-
return {
|
|
401
|
-
ready,
|
|
402
|
-
unready: total - ready,
|
|
403
|
-
total,
|
|
404
|
-
};
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
get clusterResourceStatus() {
|
|
408
|
-
const clusterStatuses = this.resourcesStatuses.reduce((prev, curr) => {
|
|
409
|
-
const { clusterId, clusterLabel } = curr;
|
|
410
|
-
|
|
411
|
-
const state = curr.state;
|
|
412
|
-
|
|
413
|
-
if (!prev[clusterId]) {
|
|
414
|
-
prev[clusterId] = {
|
|
415
|
-
clusterLabel,
|
|
416
|
-
resourceCounts: { [state]: 0, desiredReady: 0 }
|
|
417
|
-
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
if (!prev[clusterId].resourceCounts[state]) {
|
|
422
|
-
prev[clusterId].resourceCounts[state] = 0;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
prev[clusterId].resourceCounts[state] += 1;
|
|
426
|
-
prev[clusterId].resourceCounts.desiredReady += 1;
|
|
427
|
-
|
|
428
|
-
return prev;
|
|
429
|
-
}, {});
|
|
430
|
-
|
|
431
|
-
const values = Object.keys(clusterStatuses).map((key) => {
|
|
432
|
-
const { clusterLabel, resourceCounts } = clusterStatuses[key];
|
|
433
|
-
|
|
434
|
-
return {
|
|
435
|
-
clusterId: key,
|
|
436
|
-
clusterLabel, // FLEET LABEL
|
|
437
|
-
status: {
|
|
438
|
-
displayStatus: primaryDisplayStatusFromCount(resourceCounts),
|
|
439
|
-
resourceCounts: { ...resourceCounts }
|
|
440
|
-
}
|
|
441
|
-
};
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
return values;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
404
|
get clustersList() {
|
|
448
405
|
return this.$getters['all'](FLEET.CLUSTER);
|
|
449
406
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Vue from 'vue';
|
|
1
2
|
import { CATALOG, CLUSTER_BADGE } from '@shell/config/labels-annotations';
|
|
2
3
|
import { NODE, FLEET, MANAGEMENT, CAPI } from '@shell/config/types';
|
|
3
4
|
import { insertAt, addObject, removeObject } from '@shell/utils/array';
|
|
@@ -14,7 +15,6 @@ import HybridModel from '@shell/plugins/steve/hybrid-class';
|
|
|
14
15
|
import { LINUX, WINDOWS } from '@shell/store/catalog';
|
|
15
16
|
import { KONTAINER_TO_DRIVER } from './management.cattle.io.kontainerdriver';
|
|
16
17
|
import { PINNED_CLUSTERS } from '@shell/store/prefs';
|
|
17
|
-
import { copyTextToClipboard } from '@shell/utils/clipboard';
|
|
18
18
|
|
|
19
19
|
// See translation file cluster.providers for list of providers
|
|
20
20
|
// If the logo is not named with the provider name, add an override here
|
|
@@ -88,10 +88,6 @@ export default class MgmtCluster extends HybridModel {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
get provisioner() {
|
|
91
|
-
if (this.status?.provider ) {
|
|
92
|
-
return this.status.provider;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
91
|
// For imported K3s clusters, this.status.driver is 'k3s.'
|
|
96
92
|
return this.status?.driver ? this.status.driver : 'imported';
|
|
97
93
|
}
|
|
@@ -408,13 +404,9 @@ export default class MgmtCluster extends HybridModel {
|
|
|
408
404
|
}
|
|
409
405
|
|
|
410
406
|
async copyKubeConfig() {
|
|
411
|
-
|
|
412
|
-
const config = await this.generateKubeConfig();
|
|
407
|
+
const config = await this.generateKubeConfig();
|
|
413
408
|
|
|
414
|
-
|
|
415
|
-
await copyTextToClipboard(config);
|
|
416
|
-
}
|
|
417
|
-
} catch {}
|
|
409
|
+
Vue.prototype.$copyText(config);
|
|
418
410
|
}
|
|
419
411
|
|
|
420
412
|
async fetchNodeMetrics() {
|
|
@@ -8,7 +8,6 @@ import { insertAt } from '@shell/utils/array';
|
|
|
8
8
|
import { downloadUrl } from '@shell/utils/download';
|
|
9
9
|
import findLast from 'lodash/findLast';
|
|
10
10
|
import HybridModel from '@shell/plugins/steve/hybrid-class';
|
|
11
|
-
import { notOnlyOfRole } from '@shell/models/cluster.x-k8s.io.machine';
|
|
12
11
|
|
|
13
12
|
export default class MgmtNode extends HybridModel {
|
|
14
13
|
get _availableActions() {
|
|
@@ -22,12 +21,11 @@ export default class MgmtNode extends HybridModel {
|
|
|
22
21
|
};
|
|
23
22
|
|
|
24
23
|
const scaleDown = {
|
|
25
|
-
action:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
bulkable: true,
|
|
24
|
+
action: 'scaleDown',
|
|
25
|
+
enabled: !!this.canScaleDown,
|
|
26
|
+
icon: 'icon icon-minus icon-fw',
|
|
27
|
+
label: this.t('node.actions.scaleDown'),
|
|
28
|
+
bulkable: true,
|
|
31
29
|
};
|
|
32
30
|
|
|
33
31
|
insertAt(out, 0, { divider: true });
|
|
@@ -107,12 +105,12 @@ export default class MgmtNode extends HybridModel {
|
|
|
107
105
|
}
|
|
108
106
|
}
|
|
109
107
|
|
|
110
|
-
async scaleDown(resources
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
});
|
|
108
|
+
async scaleDown(resources) {
|
|
109
|
+
const safeResources = Array.isArray(resources) ? resources : [this];
|
|
110
|
+
|
|
111
|
+
await Promise.all(safeResources.map((node) => {
|
|
112
|
+
return node.norman?.doAction('scaledown');
|
|
113
|
+
}));
|
|
116
114
|
}
|
|
117
115
|
|
|
118
116
|
get provisioningCluster() {
|
|
@@ -168,12 +166,10 @@ export default class MgmtNode extends HybridModel {
|
|
|
168
166
|
}
|
|
169
167
|
|
|
170
168
|
get canScaleDown() {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
|
|
169
|
+
const isInOnlyPool = this.pool?.provisioningCluster?.pools?.length === 1;
|
|
170
|
+
const isOnlyNode = this.pool?.nodes?.length === 1;
|
|
175
171
|
const hasAction = this.norman?.actions?.scaledown;
|
|
176
172
|
|
|
177
|
-
return hasAction &&
|
|
173
|
+
return hasAction && (!isInOnlyPool || !isOnlyNode);
|
|
178
174
|
}
|
|
179
175
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { CAPI, MANAGEMENT, NORMAN } from '@shell/config/types';
|
|
2
2
|
import { sortBy } from '@shell/utils/sort';
|
|
3
3
|
import HybridModel from '@shell/plugins/steve/hybrid-class';
|
|
4
|
-
import { notOnlyOfRole } from '@shell/models/cluster.x-k8s.io.machine';
|
|
5
4
|
|
|
6
5
|
export default class MgmtNodePool extends HybridModel {
|
|
7
6
|
get nodeTemplate() {
|
|
@@ -162,22 +161,6 @@ export default class MgmtNodePool extends HybridModel {
|
|
|
162
161
|
return this.norman?.hasLink('update');
|
|
163
162
|
}
|
|
164
163
|
|
|
165
|
-
get isControlPlane() {
|
|
166
|
-
return this.spec?.controlPlane === true;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
get isEtcd() {
|
|
170
|
-
return this.spec?.etcd === true;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
canScaleDownPool() {
|
|
174
|
-
if (!this.isEtcd && !this.isControlPlane) {
|
|
175
|
-
return true;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return notOnlyOfRole(this, this?.provisioningCluster?.nodes);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
164
|
remove() {
|
|
182
165
|
return this.norman?.remove();
|
|
183
166
|
}
|
|
@@ -99,6 +99,42 @@ export default class Project extends HybridModel {
|
|
|
99
99
|
// and the PUT request should have a query param _replace=true.
|
|
100
100
|
const newValue = await norman.save({ replace: forceReplaceOnReq });
|
|
101
101
|
|
|
102
|
+
let retryCount = 0;
|
|
103
|
+
|
|
104
|
+
const finishProjectCreation = async() => {
|
|
105
|
+
try {
|
|
106
|
+
await newValue.doAction('setpodsecuritypolicytemplate', { podSecurityPolicyTemplateId: this.spec.podSecurityPolicyTemplateId || null });
|
|
107
|
+
} catch (err) {
|
|
108
|
+
if ( err.status === 409 || err.status === 403 ) {
|
|
109
|
+
// The backend updates each new project soon after it is created,
|
|
110
|
+
// so there is a chance of a 409 resource conflict or forbidden error. If that happens,
|
|
111
|
+
// retry the action.
|
|
112
|
+
|
|
113
|
+
// The 403 permission error can happen due to the user requesting
|
|
114
|
+
// the project before the project is fully created and the project
|
|
115
|
+
// permissions are assigned to the user so we allow some
|
|
116
|
+
// time for that process to complete.
|
|
117
|
+
|
|
118
|
+
if (retryCount < 3) {
|
|
119
|
+
retryCount++;
|
|
120
|
+
await setTimeout(() => {
|
|
121
|
+
// Delay for three seconds to avoid another failure due to latency.
|
|
122
|
+
finishProjectCreation();
|
|
123
|
+
}, '3000');
|
|
124
|
+
} else {
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// Only update PSP template if the value changed
|
|
132
|
+
const newPSPTemplateID = this.spec.podSecurityPolicyTemplateId || null;
|
|
133
|
+
|
|
134
|
+
if (norman.podSecurityPolicyTemplateId !== newPSPTemplateID) {
|
|
135
|
+
await finishProjectCreation();
|
|
136
|
+
}
|
|
137
|
+
|
|
102
138
|
return newValue;
|
|
103
139
|
}
|
|
104
140
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ALLOWED_SETTINGS } from '@shell/config/settings';
|
|
2
2
|
import HybridModel from '@shell/plugins/steve/hybrid-class';
|
|
3
|
-
import { isServerUrl } from '@shell/utils/validators/setting';
|
|
4
3
|
|
|
5
4
|
export default class Setting extends HybridModel {
|
|
6
5
|
get fromEnv() {
|
|
@@ -32,15 +31,12 @@ export default class Setting extends HybridModel {
|
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
get customValidationRules() {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return out;
|
|
34
|
+
return [
|
|
35
|
+
{
|
|
36
|
+
path: 'value',
|
|
37
|
+
translationKey: 'setting.serverUrl.https',
|
|
38
|
+
validators: [`isHttps:${ this.metadata.name }`]
|
|
39
|
+
},
|
|
40
|
+
];
|
|
45
41
|
}
|
|
46
42
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NORMAN } from '@shell/config/types';
|
|
2
2
|
import HybridModel, { cleanHybridResources } from '@shell/plugins/steve/hybrid-class';
|
|
3
|
+
import day from 'dayjs';
|
|
3
4
|
|
|
4
5
|
export default class User extends HybridModel {
|
|
5
6
|
// Preserve description
|
|
@@ -99,6 +100,38 @@ export default class User extends HybridModel {
|
|
|
99
100
|
return this.$rootGetters['i18n/withFallback'](`model.authConfig.provider."${ this.provider }"`, null, this.provider);
|
|
100
101
|
}
|
|
101
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Gets the last-login label in milliseconds
|
|
105
|
+
* @returns {number}
|
|
106
|
+
*/
|
|
107
|
+
get userLastLogin() {
|
|
108
|
+
return this.metadata?.labels?.['cattle.io/last-login'] * 1000;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Gets the disabled-after label in milliseconds
|
|
113
|
+
* @returns {number}
|
|
114
|
+
*/
|
|
115
|
+
get userDisabledIn() {
|
|
116
|
+
return this.metadata?.labels?.['cattle.io/disable-after'] * 1000;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Provides a display value for the userDisabledIn date based on the user
|
|
121
|
+
* state.
|
|
122
|
+
*/
|
|
123
|
+
get userDisabledInDisplay() {
|
|
124
|
+
return this.state === 'inactive' ? null : this.userDisabledIn;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Gets the delete-after label in milliseconds
|
|
129
|
+
* @returns {number}
|
|
130
|
+
*/
|
|
131
|
+
get userDeletedIn() {
|
|
132
|
+
return this.metadata?.labels?.['cattle.io/delete-after'] * 1000;
|
|
133
|
+
}
|
|
134
|
+
|
|
102
135
|
get state() {
|
|
103
136
|
if ( this.enabled === false ) {
|
|
104
137
|
return 'inactive';
|
|
@@ -107,6 +140,19 @@ export default class User extends HybridModel {
|
|
|
107
140
|
return this.metadata?.state?.name || 'unknown';
|
|
108
141
|
}
|
|
109
142
|
|
|
143
|
+
get stateDisplay() {
|
|
144
|
+
switch (this.state) {
|
|
145
|
+
case 'inactive':
|
|
146
|
+
return this.t('user.state.inactive');
|
|
147
|
+
case 'active':
|
|
148
|
+
return this.t('user.state.active');
|
|
149
|
+
case 'unknown':
|
|
150
|
+
return this.t('user.state.unknown');
|
|
151
|
+
default:
|
|
152
|
+
return this.state;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
110
156
|
get description() {
|
|
111
157
|
return this._description;
|
|
112
158
|
}
|
|
@@ -211,6 +257,25 @@ export default class User extends HybridModel {
|
|
|
211
257
|
formatter: 'CopyToClipboard',
|
|
212
258
|
content: this.username
|
|
213
259
|
},
|
|
260
|
+
{ separator: true },
|
|
261
|
+
{
|
|
262
|
+
label: this.t('tableHeaders.userLastLogin'),
|
|
263
|
+
formatter: 'LiveDate',
|
|
264
|
+
formatterOpts: { addSuffix: true, suffix: `${ this.t('suffix.ago') } (${ day(this.userLastLogin) })` },
|
|
265
|
+
content: this.userLastLogin,
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
label: this.t('tableHeaders.userDisabledIn'),
|
|
269
|
+
formatter: 'LiveDate',
|
|
270
|
+
formatterOpts: { isCountdown: true },
|
|
271
|
+
content: this.userDisabledInDisplay,
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
label: this.t('tableHeaders.userDeletedIn'),
|
|
275
|
+
formatter: 'LiveDate',
|
|
276
|
+
formatterOpts: { isCountdown: true },
|
|
277
|
+
content: this.userDeletedIn,
|
|
278
|
+
},
|
|
214
279
|
...this._details
|
|
215
280
|
];
|
|
216
281
|
}
|
package/models/namespace.js
CHANGED