Add harvesterhci.io.management.cluster.vue edit & detail page + bug fixing

Signed-off-by: Francesco Torchia <francesco.torchia@suse.com>
This commit is contained in:
Francesco Torchia 2024-10-01 15:10:22 +02:00
parent 8bd9051739
commit 77cedfd675
No known key found for this signature in database
GPG Key ID: E6D011B7415D4393
3 changed files with 263 additions and 1 deletions

View File

@ -0,0 +1,104 @@
<script>
import Loading from '@shell/components/Loading';
import ResourceTabs from '@shell/components/form/ResourceTabs';
import CopyCode from '@shell/components/CopyCode';
import Tab from '@shell/components/Tabbed/Tab';
import { allHash } from '@shell/utils/promise';
export default {
emits: ['input'],
components: {
Loading,
ResourceTabs,
Tab,
CopyCode,
},
props: {
value: {
type: Object,
default: () => {
return {};
}
}
},
async fetch() {
await this.value.waitForProvisioner();
const hash = { clusterToken: this.value.getOrCreateToken() };
const res = await allHash(hash);
this.allNodes = res.allNodes || [];
this.allNodePools = res.allNodePools || [];
this.clusterToken = res.clusterToken;
},
data() {
return { clusterToken: null };
},
computed: {
defaultTab() {
if (this.showRegistration && !this.machines?.length) {
return 'registration';
}
return '';
},
showRegistration() {
if ( !this.clusterToken ) {
return false;
}
if ( this.value.isImported ) {
return !this.value.mgmt?.isReady;
}
return false;
},
registrationURL() {
return (this.clusterToken?.command || '').replace('kubectl apply -f ', '');
},
},
};
</script>
<template>
<Loading v-if="$fetchState.pending" />
<ResourceTabs
v-else
:value="value"
:default-tab="defaultTab"
@input="$emit('input', $event)"
>
<Tab
v-if="showRegistration"
name="registration"
:label="t('cluster.tabs.registration')"
:weight="2"
class="p-10"
>
<h4
v-clean-html="t('cluster.harvester.registration.step1', null, true)"
/>
<h4
v-clean-html="t('cluster.harvester.registration.step2', null, true)"
class="mt-10"
/>
<h4
v-clean-html="t('cluster.harvester.registration.step3', null, true)"
class="mt-10"
/>
<CopyCode class="m-10 p-10">
{{ registrationURL }}
</CopyCode>
</Tab>
</ResourceTabs>
</template>

View File

@ -0,0 +1,158 @@
<script>
import CreateEditView from '@shell/mixins/create-edit-view';
import CruResource from '@shell/components/CruResource';
import NameNsDescription from '@shell/components/form/NameNsDescription';
import Tab from '@shell/components/Tabbed/Tab';
import Tabbed from '@shell/components/Tabbed';
import { HCI, SCHEMA, CAPI, VIRTUAL_HARVESTER_PROVIDER } from '@shell/config/types';
import ClusterMembershipEditor from '@shell/components/form/Members/ClusterMembershipEditor';
import { Banner } from '@components/Banner';
import Labels from '@shell/edit/provisioning.cattle.io.cluster/Labels';
import AgentEnv from '@shell/edit/provisioning.cattle.io.cluster/AgentEnv';
import { set, get, clone } from '@shell/utils/object';
import { CAPI as CAPI_LABEL } from '@shell/config/labels-annotations';
import { createYaml } from '@shell/utils/create-yaml';
const REAL_TYPE = CAPI.RANCHER_CLUSTER;
export default {
emits: ['input'],
components: {
Banner,
ClusterMembershipEditor,
NameNsDescription,
CruResource,
Tab,
Tabbed,
Labels,
AgentEnv
},
mixins: [CreateEditView],
props: {
mode: {
type: String,
required: true,
},
value: {
type: Object,
required: true,
},
},
data() {
return { membershipUpdate: {} };
},
computed: {
generateYaml() {
return () => {
const resource = this.value;
const inStore = this.$store.getters['currentStore'](resource);
const schemas = this.$store.getters[`${ inStore }/all`](SCHEMA);
const clonedResource = clone(resource);
delete clonedResource.isSpoofed;
const out = createYaml(schemas, REAL_TYPE, clonedResource);
return out;
};
},
},
methods: {
done() {
return this.$router.replace({
name: 'c-cluster-product-resource-namespace-id',
params: {
resource: HCI.CLUSTER,
namespace: this.value.metadata.namespace,
id: this.value.metadata.name,
},
});
},
async saveOverride() {
set(this.value, 'metadata.labels', {
...(get(this.value, 'metadata.labels') || {}),
[CAPI_LABEL.PROVIDER]: VIRTUAL_HARVESTER_PROVIDER,
});
set(this.value, 'type', REAL_TYPE);
await this.save(...arguments);
this.value.waitForMgmt().then(() => {
if (this.membershipUpdate.save) {
this.membershipUpdate.save(this.value.mgmt.id);
}
});
},
onMembershipUpdate(update) {
this['membershipUpdate'] = update;
},
},
};
</script>
<template>
<CruResource
:mode="mode"
:resource="value"
:errors="errors"
:validation-passed="true"
:done-route="doneRoute"
:generate-yaml="generateYaml"
@finish="saveOverride"
@error="e=>errors = e"
>
<div class="mt-20">
<NameNsDescription
v-if="!isView"
:value="value"
:mode="mode"
:namespaced="false"
name-label="cluster.name.label"
name-placeholder="cluster.name.placeholder"
description-label="cluster.description.label"
description-placeholder="cluster.description.placeholder"
@update:value="$emit('input', $event)"
/>
</div>
<Tabbed :side-tabs="true">
<Tab
name="memberRoles"
label-key="cluster.tabs.memberRoles"
:weight="3"
>
<Banner
v-if="isEdit"
color="info"
>
{{ t('cluster.memberRoles.removeMessage') }}
</Banner>
<ClusterMembershipEditor
:mode="mode"
:parent-id="value.mgmt ? value.mgmt.id : null"
@membership-update="onMembershipUpdate"
/>
</Tab>
<AgentEnv
:value="value"
:mode="mode"
@update:value="$emit('input', $event)"
/>
<Labels
:value="value"
:mode="mode"
@update:value="$emit('input', $event)"
/>
</Tabbed>
</CruResource>
</template>

View File

@ -82,7 +82,7 @@ export default {
},
typeDisplay() {
return this.t(`typeLabel."${ HCI.CLUSTER }"`, { count: this.row?.length || 0 });
return this.t(`typeLabel."${ HCI.CLUSTER }"`, { count: this.rows?.length || 0 });
},
},