mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2026-10-01 03:36:04 +08:00
Compare commits
12
Commits
v1.8.0-rc3
...
v1.8.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1dcb528717 | ||
|
|
36fc21ccbc | ||
|
|
8803b79524 | ||
|
|
3f80a71303 | ||
|
|
13e4154335 | ||
|
|
a80b87ce4f | ||
|
|
809b9925fa | ||
|
|
7788161d94 | ||
|
|
90b8a821a1 | ||
|
|
87ff014bd8 | ||
|
|
20328b06e6 | ||
|
|
bbc415a2b4 |
@@ -34,12 +34,14 @@
|
||||
{
|
||||
"matchUpdateTypes": ["minor"],
|
||||
"groupName": "minor dependencies",
|
||||
"minimumReleaseAge": "7 days",
|
||||
"labels": ["minor-update"],
|
||||
"reviewers": ["a110605", "houhoucoop"]
|
||||
},
|
||||
{
|
||||
"matchUpdateTypes": ["patch", "digest"],
|
||||
"automerge": true,
|
||||
"minimumReleaseAge": "7 days",
|
||||
"groupName": "patch digest dependencies",
|
||||
"labels": ["patch-update", "automerge"]
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
run: ./scripts/build-upload-gate
|
||||
|
||||
- name: Get gcs auth
|
||||
uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
|
||||
uses: rancher-eio/read-vault-secrets@d266f55186f80a893839f6e15662e67388e443e6 # v3
|
||||
with:
|
||||
secrets: |
|
||||
secret/data/github/repo/${{ github.repository }}/google-auth/harvester/credentials token | GOOGLE_AUTH ;
|
||||
@@ -90,7 +90,7 @@ jobs:
|
||||
DISABLED_EMBED_PKG: https://releases.rancher.com/harvester-ui/plugin/harvester-1.0.3.tar.gz
|
||||
|
||||
- name: Get gcs auth
|
||||
uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
|
||||
uses: rancher-eio/read-vault-secrets@d266f55186f80a893839f6e15662e67388e443e6 # v3
|
||||
with:
|
||||
secrets: |
|
||||
secret/data/github/repo/${{ github.repository }}/google-auth/harvester/credentials token | GOOGLE_AUTH ;
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
run: ./scripts/build-upload-gate
|
||||
|
||||
- name: Get gcs auth
|
||||
uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
|
||||
uses: rancher-eio/read-vault-secrets@d266f55186f80a893839f6e15662e67388e443e6 # v3
|
||||
with:
|
||||
secrets: |
|
||||
secret/data/github/repo/${{ github.repository }}/google-auth/harvester/credentials token | GOOGLE_AUTH ;
|
||||
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
build-status: ${{ job.status }}
|
||||
steps:
|
||||
- name: Read Secrets
|
||||
uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
|
||||
uses: rancher-eio/read-vault-secrets@d266f55186f80a893839f6e15662e67388e443e6 # v3
|
||||
with:
|
||||
secrets: |
|
||||
secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ;
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
needs:
|
||||
- setup-release-tag
|
||||
- check-version
|
||||
uses: rancher/dashboard/.github/workflows/build-extension-charts.yml@9eb70a732e9be146722e1dbab431338366c2afc6 # creators-pkg-v3.0.10
|
||||
uses: rancher/dashboard/.github/workflows/build-extension-charts.yml@3b26a36bad555e5e2b8634b24823be29732f287c # master
|
||||
permissions:
|
||||
actions: write
|
||||
contents: write
|
||||
|
||||
@@ -20,13 +20,13 @@ jobs:
|
||||
# The FOSSA token is shared between all repos in Harvester's GH org. It can
|
||||
# be used directly and there is no need to request specific access to EIO.
|
||||
- name: Read FOSSA token
|
||||
uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
|
||||
uses: rancher-eio/read-vault-secrets@d266f55186f80a893839f6e15662e67388e443e6 # v3
|
||||
with:
|
||||
secrets: |
|
||||
secret/data/github/org/harvester/fossa/credentials token | FOSSA_API_KEY_PUSH_ONLY
|
||||
|
||||
- name: FOSSA scan
|
||||
uses: fossas/fossa-action@c414b9ad82eaad041e47a7cf62a4f02411f427a0 # v1.8.0
|
||||
uses: fossas/fossa-action@ff70fe9fe17cbd2040648f1c45e8ec4e4884dcf3 # v1.9.0
|
||||
with:
|
||||
api-key: ${{ env.FOSSA_API_KEY_PUSH_ONLY }}
|
||||
# Only runs the scan and do not provide/returns any results back to the
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "harvester-ui-extension",
|
||||
"version": "1.8.0-rc3",
|
||||
"version": "1.8.0",
|
||||
"private": false,
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Card } from '@components/Card';
|
||||
import AsyncButton from '@shell/components/AsyncButton';
|
||||
import { escapeHtml } from '@shell/utils/string';
|
||||
import { HCI } from '../types';
|
||||
import { getHarvesterUserName } from '../utils/auth';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterEnablePciPassthrough',
|
||||
@@ -34,16 +35,7 @@ export default {
|
||||
},
|
||||
|
||||
async save(buttonCb) {
|
||||
// isSingleProduct == this is a standalone Harvester cluster
|
||||
const isSingleProduct = this.$store.getters['isSingleProduct'];
|
||||
let userName = 'admin';
|
||||
|
||||
// if this is imported Harvester, there may be users other than 'admin
|
||||
if (!isSingleProduct) {
|
||||
const user = this.$store.getters['auth/v3User'];
|
||||
|
||||
userName = user?.username || user?.id;
|
||||
}
|
||||
const userName = getHarvesterUserName(this.$store.getters);
|
||||
|
||||
for (let i = 0; i < this.resources.length; i++) {
|
||||
const actionResource = this.resources[i];
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Card } from '@components/Card';
|
||||
import AsyncButton from '@shell/components/AsyncButton';
|
||||
import { escapeHtml } from '@shell/utils/string';
|
||||
import { HCI } from '../types';
|
||||
import { getHarvesterUserName } from '../utils/auth';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterEnableUSBPassthrough',
|
||||
@@ -34,16 +35,7 @@ export default {
|
||||
},
|
||||
|
||||
async save(buttonCb) {
|
||||
// isSingleProduct == this is a standalone Harvester cluster
|
||||
const isSingleProduct = this.$store.getters['isSingleProduct'];
|
||||
let userName = 'admin';
|
||||
|
||||
// if this is imported Harvester, there may be users other than 'admin
|
||||
if (!isSingleProduct) {
|
||||
const user = this.$store.getters['auth/v3User'];
|
||||
|
||||
userName = user?.username || user?.id;
|
||||
}
|
||||
const userName = getHarvesterUserName(this.$store.getters);
|
||||
|
||||
for (let i = 0; i < this.resources.length; i++) {
|
||||
const actionResource = this.resources[i];
|
||||
|
||||
@@ -243,9 +243,9 @@ export default {
|
||||
<Banner color="info">
|
||||
<MessageLink
|
||||
:to="toVGpuDevicesPage"
|
||||
prefix-label="harvester.pci.howToUseDevice.prefix"
|
||||
middle-label="harvester.pci.howToUseDevice.middle"
|
||||
suffix-label="harvester.pci.howToUseDevice.suffix"
|
||||
prefix-label="harvester.pci.howToUseDeviceInVMCreation.prefix"
|
||||
middle-label="harvester.pci.howToUseDeviceInVMCreation.middle"
|
||||
suffix-label="harvester.pci.howToUseDeviceInVMCreation.suffix"
|
||||
/>
|
||||
</Banner>
|
||||
<Banner
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script>
|
||||
import { NORMAN } from '@shell/config/types';
|
||||
import { HCI } from '../types';
|
||||
import { getHarvesterUser } from '../utils/auth';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@@ -25,7 +26,7 @@ export default {
|
||||
},
|
||||
|
||||
data() {
|
||||
const user = this.$store.getters['auth/v3User'];
|
||||
const user = getHarvesterUser(this.$store.getters);
|
||||
|
||||
return {
|
||||
harvesterSettings: [],
|
||||
|
||||
@@ -376,10 +376,14 @@ harvester:
|
||||
available: Available Devices
|
||||
compatibleNodes: Compatible Nodes
|
||||
impossibleSelection: 'There are no hosts with all of the selected devices.'
|
||||
howToUseDevice:
|
||||
prefix: 'Use the table below to enable PCI passthrough on each device you want to use in this virtual machine.<br>For vGPU devices, please enable them on the'
|
||||
middle: vGPU Devices
|
||||
howToUseDeviceInVMCreation:
|
||||
prefix: 'Use the table below to enable PCI passthrough on each device you want to use in this virtual machine. <br>For vGPU devices, please enable them on the'
|
||||
middle: vGPU Devices
|
||||
suffix: page first.
|
||||
howToUseDevice:
|
||||
prefix: 'Select the device in the table to enable PCI passthrough. <br>For vGPU devices, please enable them on the'
|
||||
middle: vGPU Devices
|
||||
suffix: page.
|
||||
deviceInTheSameHost: 'You can only select devices on the same host.'
|
||||
oldFormatDevices:
|
||||
help: |-
|
||||
|
||||
@@ -60,6 +60,17 @@ export default {
|
||||
return schema;
|
||||
},
|
||||
|
||||
toVGpuDevicesPage() {
|
||||
return {
|
||||
name: 'harvester-c-cluster-resource',
|
||||
params: { cluster: this.$store.getters['clusterId'], resource: HCI.VGPU_DEVICE },
|
||||
};
|
||||
},
|
||||
|
||||
vGPUAsPCIDeviceEnabled() {
|
||||
return this.$store.getters['harvester-common/getFeatureEnabled']('vGPUAsPCIDevice');
|
||||
},
|
||||
|
||||
rows() {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const rows = this.$store.getters[`${ inStore }/all`](HCI.PCI_DEVICE);
|
||||
@@ -85,11 +96,23 @@ export default {
|
||||
{{ t('harvester.pci.noPCIPermission') }}
|
||||
</Banner>
|
||||
</div>
|
||||
<DeviceList
|
||||
v-else-if="hasSchema && enabledPCI"
|
||||
:devices="rows"
|
||||
:schema="schema"
|
||||
/>
|
||||
<div v-else-if="hasSchema && enabledPCI">
|
||||
<Banner
|
||||
v-if="vGPUAsPCIDeviceEnabled"
|
||||
color="info"
|
||||
>
|
||||
<MessageLink
|
||||
:to="toVGpuDevicesPage"
|
||||
prefix-label="harvester.pci.howToUseDevice.prefix"
|
||||
middle-label="harvester.pci.howToUseDevice.middle"
|
||||
suffix-label="harvester.pci.howToUseDevice.suffix"
|
||||
/>
|
||||
</Banner>
|
||||
<DeviceList
|
||||
:devices="rows"
|
||||
:schema="schema"
|
||||
/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<Banner color="warning">
|
||||
<MessageLink
|
||||
|
||||
@@ -2,6 +2,7 @@ import SteveModel from '@shell/plugins/steve/steve-class';
|
||||
import { escapeHtml } from '@shell/utils/string';
|
||||
import { HCI } from '../types';
|
||||
import { HCI as HCI_ANNOTATIONS } from '@pkg/harvester/config/labels-annotations';
|
||||
import { getHarvesterUserName } from '../utils/auth';
|
||||
|
||||
const STATUS_DISPLAY = {
|
||||
enabled: {
|
||||
@@ -96,15 +97,8 @@ export default class PCIDevice extends SteveModel {
|
||||
if (!this.passthroughClaim) {
|
||||
return false;
|
||||
}
|
||||
const isSingleProduct = this.$rootGetters['isSingleProduct'];
|
||||
let userName = 'admin';
|
||||
|
||||
// if this is imported Harvester, there may be users other than admin
|
||||
if (!isSingleProduct) {
|
||||
const user = this.$rootGetters['auth/v3User'];
|
||||
|
||||
userName = user?.username || user?.id;
|
||||
}
|
||||
const userName = getHarvesterUserName(this.$rootGetters);
|
||||
|
||||
return this.claimedBy === userName;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import SteveModel from '@shell/plugins/steve/steve-class';
|
||||
import { escapeHtml } from '@shell/utils/string';
|
||||
import { HCI } from '../types';
|
||||
import { getHarvesterUserName } from '../utils/auth';
|
||||
|
||||
const STATUS_DISPLAY = {
|
||||
enabled: {
|
||||
@@ -87,15 +88,8 @@ export default class USBDevice extends SteveModel {
|
||||
if (!this.passthroughClaim) {
|
||||
return false;
|
||||
}
|
||||
const isSingleProduct = this.$rootGetters['isSingleProduct'];
|
||||
let userName = 'admin';
|
||||
|
||||
// if this is imported Harvester, there may be users other than admin
|
||||
if (!isSingleProduct) {
|
||||
const user = this.$rootGetters['auth/v3User'];
|
||||
|
||||
userName = user?.username || user?.id;
|
||||
}
|
||||
const userName = getHarvesterUserName(this.$rootGetters);
|
||||
|
||||
return this.claimedBy === userName;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "harvester",
|
||||
"description": "Rancher UI Extension for Harvester",
|
||||
"version": "1.8.0-rc3",
|
||||
"version": "1.8.0",
|
||||
"private": false,
|
||||
"rancher": {
|
||||
"annotations": {
|
||||
@@ -29,4 +29,4 @@
|
||||
"last 2 versions",
|
||||
"not dead"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Resolve the Harvester username from Vuex getters.
|
||||
*
|
||||
* Works with both `this.$store.getters` (in components) and
|
||||
* `this.$rootGetters` (in Steve models).
|
||||
*
|
||||
* - In single-product (standalone Harvester) mode, always returns the
|
||||
* default username (`admin`).
|
||||
* - Otherwise, falls back to the authenticated user's `username` or `id`.
|
||||
*/
|
||||
export function getHarvesterUserName(getters, defaultUserName = 'admin') {
|
||||
const isSingleProduct = getters?.['isSingleProduct'];
|
||||
|
||||
if (isSingleProduct) {
|
||||
return defaultUserName;
|
||||
}
|
||||
|
||||
const user = getHarvesterUser(getters);
|
||||
|
||||
return user?.username || user?.id || defaultUserName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the authenticated user object from Vuex getters.
|
||||
*
|
||||
* Works with both `this.$store.getters` (in components) and
|
||||
* `this.$rootGetters` (in Steve models).
|
||||
*/
|
||||
export function getHarvesterUser(getters) {
|
||||
return getters?.['auth/user'];
|
||||
}
|
||||
Reference in New Issue
Block a user