Skip to content

Commit

Permalink
Merge pull request #3881 from n313893254/cloud
Browse files Browse the repository at this point in the history
Add harvester cloud provider and Fix credential lack of clusterId
  • Loading branch information
richard-cox authored Sep 23, 2021
2 parents b74eb55 + 1d7fcd5 commit dfe5932
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 31 deletions.
3 changes: 3 additions & 0 deletions assets/translations/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,8 @@ cluster:
rancher-vsphere:
label: vSphere
note: '<b>Important:</b> Configure the vSphere Cloud Provider and Storage Provider options in the Add-On Config tab.'
harvester:
label: Harvester
custom:
nodeRole:
label: Node Role
Expand Down Expand Up @@ -1030,6 +1032,7 @@ cluster:
kubeconfigContent:
label: KubeconfigContent
placeholder: 'Namespace/Name'
cluster: Cluster
description:
label: Cluster Description
placeholder: Any text you want that better describes this cluster
Expand Down
18 changes: 10 additions & 8 deletions cloud-credential/harvester.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import LabeledInput from '@/components/form/LabeledInput';
import LabeledSelect from '@/components/form/LabeledSelect';
import RadioGroup from '@/components/form/RadioGroup';
import { get } from '@/utils/object';
import { get, set } from '@/utils/object';
import { MANAGEMENT, VIRTUAL_HARVESTER_PROVIDER } from '@/config/types';
import { HCI } from '@/config/labels-annotations';
const IMPORTED = 'imported';
export default {
components: {
Expand All @@ -22,14 +23,15 @@ export default {
this.$emit('validationChanged', true);
if (!this.value.decodedData.clusterType) {
this.value.setData('clusterType', 'import');
this.value.setData('clusterType', IMPORTED);
}
const cluster = get(this.value, `metadata.annotations."${ HCI.CLUSTER_ID }"`) || '';
const cluster = get(this.value, 'harvestercredentialConfig.clusterId') || '';
return {
clusters: [],
cluster,
IMPORTED,
};
},
Expand All @@ -44,7 +46,7 @@ export default {
},
isImportCluster() {
return this.value.decodedData.clusterType === 'import';
return this.value.decodedData.clusterType === IMPORTED;
}
},
Expand All @@ -64,7 +66,7 @@ export default {
}
if (this.isCreate) {
this.value.setAnnotation(HCI.CLUSTER_ID, neu);
set(this.value, 'harvestercredentialConfig.clusterId', neu);
}
const currentCluster = this.$store.getters['management/all'](MANAGEMENT.CLUSTER).find(x => x.id === neu);
Expand Down Expand Up @@ -113,7 +115,7 @@ export default {
:disabled="isEdit"
name="clusterType"
:labels="[t('cluster.credential.harvester.import'),t('cluster.credential.harvester.external')]"
:options="['import', 'external']"
:options="[IMPORTED, 'external']"
@input="value.setData('clusterType', $event);"
/>
</div>
Expand All @@ -126,7 +128,7 @@ export default {
:disabled="isEdit"
:options="clusterOptions"
:required="true"
label="Cluster"
:label="t('cluster.credential.harvester.cluster')"
/>
</div>
Expand Down
90 changes: 86 additions & 4 deletions edit/provisioning.cattle.io.cluster/rke2.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import { _CREATE, _EDIT, _VIEW } from '@/config/query-params';
import { DEFAULT_WORKSPACE } from '@/models/provisioning.cattle.io.cluster';
import { findBy, removeObject, clear } from '@/utils/array';
import { clone, diff, isEmpty, set } from '@/utils/object';
import {
clone, diff, isEmpty, set, get
} from '@/utils/object';
import { allHash } from '@/utils/promise';
import { sortBy } from '@/utils/sort';
import { camelToTitle, nlToBr } from '@/utils/string';
Expand Down Expand Up @@ -57,6 +59,8 @@ const PUBLIC = 'public';
const PRIVATE = 'private';
const ADVANCED = 'advanced';
const HARVESTER = 'harvester';
export default {
components: {
ACE,
Expand Down Expand Up @@ -143,13 +147,20 @@ export default {
}
if ( this.value.spec.cloudCredentialSecretName ) {
await this.$store.dispatch('rancher/findAll', { type: NORMAN.CLOUD_CREDENTIAL });
this.credentialId = `${ this.value.spec.cloudCredentialSecretName }`;
}
if ( !this.value.spec.kubernetesVersion ) {
const option = this.versionOptions.find(x => !!x.value);
const rke2 = this.filterAndMap(this.rke2Versions, null);
const showRke2 = rke2.length;
set(this.value.spec, 'kubernetesVersion', option.value);
if (this.isHarvesterDriver && showRke2) {
this.setHarvesterK8sDefaultVersion();
} else {
set(this.value.spec, 'kubernetesVersion', option.value);
}
}
for ( const k in this.serverArgs ) {
Expand Down Expand Up @@ -200,6 +211,10 @@ export default {
set(this.value.spec, 'defaultPodSecurityPolicyTemplateName', '');
}
if (this.isHarvesterDriver && this.mode === _CREATE) {
this.agentConfig['cloud-provider-name'] = HARVESTER;
}
await this.initAddons();
await this.initRegistry();
Expand Down Expand Up @@ -453,7 +468,7 @@ export default {
const preferred = this.$store.getters['plugins/cloudProviderForDriver'](this.provider);
for ( const opt of this.agentArgs['cloud-provider-name'].options ) {
if ( !preferred || opt === preferred || opt === 'external' ) {
if ( (!preferred && opt !== HARVESTER) || opt === preferred || opt === 'external' || preferred === HARVESTER) {
out.push({
label: this.$store.getters['i18n/withFallback'](`cluster.cloudProvider."${ opt }".label`, null, opt),
value: opt,
Expand Down Expand Up @@ -638,6 +653,7 @@ export default {
case 'none': return false;
case 'aws': return false;
case 'rancher-vsphere': return false;
case HARVESTER: return false;
default: return true;
}
},
Expand Down Expand Up @@ -692,7 +708,11 @@ export default {
canManageMembers() {
return canViewClusterMembershipEditor(this.$store);
}
},
isHarvesterDriver() {
return this.$route.query.type === HARVESTER;
},
},
watch: {
Expand Down Expand Up @@ -939,12 +959,34 @@ export default {
}
}
if (!this.value.metadata.name && this.agentConfig['cloud-provider-name'] === HARVESTER) {
this.errors.push(this.t('validation.required', { key: this.t('cluster.name.label') }, true));
}
if (this.errors.length) {
btnCb(false);
return;
}
const clusterId = get(this.credential, 'decodedData.clusterId') || '';
if (this.agentConfig['cloud-provider-name'] === HARVESTER && clusterId && this.isCreate) {
const namespace = this.machinePools?.[0]?.config?.vmNamespace;
const res = await this.$store.dispatch('management/request', {
url: `/k8s/clusters/${ clusterId }/v1/harvester/kubeconfig`,
method: 'POST',
data: {
clusterRoleName: 'harvesterhci.io:cloudprovider',
namespace,
serviceAccountName: this.value.metadata.name,
},
});
set(this.agentConfig, 'cloud-provider-config', res.data);
}
await this.save(btnCb);
},
Expand Down Expand Up @@ -1139,6 +1181,46 @@ export default {
set(this.rkeConfig.registries, 'mirrors', {});
}
},
filterAndMap(versions, minVersion) {
const out = (versions || []).filter(obj => !!obj.serverArgs).map((obj) => {
let disabled = false;
if ( minVersion ) {
disabled = compare(obj.id, minVersion) < 0;
}
return {
label: obj.id,
value: obj.id,
sort: sortable(obj.id),
serverArgs: obj.serverArgs,
agentArgs: obj.agentArgs,
charts: obj.charts,
disabled,
};
});
return sortBy(out, 'sort:desc');
},
setHarvesterK8sDefaultVersion() {
const rke2 = this.filterAndMap(this.rke2Versions, null);
const satisfiesVersion = rke2.filter((v) => {
const rkeVersion = v.value.replace(/.+rke2r/i, '');
return semver.satisfies(semver.coerce(v.value), '>=v1.21.4+rke2r4') && Number(rkeVersion) >= 4;
}) || [];
if (satisfiesVersion.length > 0) {
set(this.value.spec, 'kubernetesVersion', satisfiesVersion[0]?.value);
} else {
const option = this.versionOptions.find(x => !!x.value);
set(this.value.spec, 'kubernetesVersion', option.value);
}
},
},
};
</script>
Expand Down
39 changes: 24 additions & 15 deletions machine-config/harvester.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ export default {
try {
this.credential = await this.$store.dispatch('rancher/find', { type: NORMAN.CLOUD_CREDENTIAL, id: this.credentialId });
const clusterId = get(this.credential, `metadata.annotations."${ HCI_ANNOTATIONS.CLUSTER_ID }"`);
const clusterId = get(this.credential, 'decodedData.clusterId');
const url = `/k8s/clusters/${ clusterId }/v1`;
const isImportCluster = this.credential.decodedData.clusterType === 'import';
const isImportCluster = this.credential.decodedData.clusterType === 'imported';
this.isImportCluster = isImportCluster;
Expand Down Expand Up @@ -191,16 +192,24 @@ export default {
};
},
computed: { ...mapGetters({ t: 'i18n/t' }) },
computed: {
...mapGetters({ t: 'i18n/t' }),
disabledEdit() {
return this.disabled || !!(this.isEdit && this.value.id);
}
},
watch: {
'credentialId'() {
this.imageOptions = [];
this.networkOptions = [];
this.namespaceOptions = [];
this.value.imageName = '';
this.value.networkName = '';
this.value.vmNamespace = '';
if (!this.isEdit) {
this.imageOptions = [];
this.networkOptions = [];
this.namespaceOptions = [];
this.value.imageName = '';
this.value.networkName = '';
this.value.vmNamespace = '';
}
this.$fetch();
},
Expand Down Expand Up @@ -342,7 +351,7 @@ export default {
:options="namespaceOptions"
:searchable="true"
:required="true"
:disabled="disabled"
:disabled="disabledEdit"
label-key="cluster.credential.harvester.namespace"
/>
Expand All @@ -352,7 +361,7 @@ export default {
label-key="cluster.credential.harvester.namespace"
:required="true"
:mode="mode"
:disabled="disabled"
:disabled="disabledEdit"
/>
</div>
</div>
Expand All @@ -364,7 +373,7 @@ export default {
:mode="mode"
:options="imageOptions"
:required="true"
:disabled="disabled"
:disabled="disabledEdit"
label-key="cluster.credential.harvester.image"
/>
</div>
Expand All @@ -375,7 +384,7 @@ export default {
:mode="mode"
:options="networkOptions"
:required="true"
:disabled="disabled"
:disabled="disabledEdit"
label-key="cluster.credential.harvester.network"
/>
</div>
Expand All @@ -388,7 +397,7 @@ export default {
:mode="mode"
:required="true"
:placeholder="t('cluster.credential.harvester.placeholder')"
:disabled="disabled"
:disabled="disabledEdit"
label-key="cluster.credential.harvester.image"
/>
</div>
Expand All @@ -399,7 +408,7 @@ export default {
:mode="mode"
:required="true"
:placeholder="t('cluster.credential.harvester.placeholder')"
:disabled="disabled"
:disabled="disabledEdit"
label-key="cluster.credential.harvester.network"
/>
</div>
Expand Down
2 changes: 1 addition & 1 deletion models/namespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export default {
return null;
}

const clusterId = this.$rootGetters['currentCluster'].id;
const clusterId = this.$rootGetters['currentCluster']?.id;
const project = this.$rootGetters['management/byId'](MANAGEMENT.PROJECT, `${ clusterId }/${ this.projectId }`);

return project;
Expand Down
Loading

0 comments on commit dfe5932

Please sign in to comment.