From 1d7559ded2c29257285f984c03841646ae70efa8 Mon Sep 17 00:00:00 2001 From: Pierre Donias Date: Mon, 30 Oct 2023 11:32:12 +0100 Subject: [PATCH] fix(xo-server-netbox/VM): explicitly assign site (#7124) See Zammad#17766 See https://xcp-ng.org/forum/topic/7887 --- CHANGELOG.unreleased.md | 4 ++++ packages/xo-server-netbox/src/index.js | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 77ab5de5a..4cfc851dc 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -11,6 +11,8 @@ > Users must be able to say: “I had this issue, happy to know it's fixed” +- [Netbox] Fix "The selected cluster is not assigned to this site" error [Forum#7887](https://xcp-ng.org/forum/topic/7887) (PR [#7124](https://github.com/vatesfr/xen-orchestra/pull/7124)) + ### Packages to release > When modifying a package, add it here with its release type. @@ -27,4 +29,6 @@ +- xo-server-netbox patch + diff --git a/packages/xo-server-netbox/src/index.js b/packages/xo-server-netbox/src/index.js index d35feff2c..4878d9c75 100644 --- a/packages/xo-server-netbox/src/index.js +++ b/packages/xo-server-netbox/src/index.js @@ -144,7 +144,9 @@ class Netbox { const httpRequest = async () => { try { const response = await this.#xo.httpRequest(url, options) - this.#netboxApiVersion = response.headers['api-version'] + // API version only follows minor version, which is less precise and is not semver-valid + // See https://github.com/netbox-community/netbox/issues/12879#issuecomment-1589190236 + this.#netboxApiVersion = semver.coerce(response.headers['api-version'])?.version ?? undefined const body = await response.text() if (body.length > 0) { return JSON.parse(body) @@ -336,6 +338,14 @@ class Netbox { tags: [], } + // Prior to Netbox v3.3.0: no "site" field on VMs + // v3.3.0: "site" is REQUIRED and MUST be the same as cluster's site + // v3.3.5: "site" is OPTIONAL (auto-assigned in UI, not in API). `null` and cluster's site are accepted. + // v3.4.8: "site" is OPTIONAL and AUTO-ASSIGNED with cluster's site. If passed: ignored except if site is different from cluster's, then error. + if (this.#netboxApiVersion === undefined || semver.satisfies(this.#netboxApiVersion, '3.3.0 - 3.4.7')) { + nbVm.site = find(nbClusters, { id: nbCluster.id })?.site?.id ?? null + } + const distro = xoVm.os_version?.distro if (distro != null) { const slug = slugify(distro) @@ -379,10 +389,7 @@ class Netbox { nbVm.tags = nbVmTags.sort(({ id: id1 }, { id: id2 }) => (id1 < id2 ? -1 : 1)) // https://netbox.readthedocs.io/en/stable/release-notes/version-2.7/#api-choice-fields-now-use-string-values-3569 - if ( - this.#netboxApiVersion !== undefined && - !semver.satisfies(semver.coerce(this.#netboxApiVersion).version, '>=2.7.0') - ) { + if (this.#netboxApiVersion !== undefined && !semver.satisfies(this.#netboxApiVersion, '>=2.7.0')) { nbVm.status = xoVm.power_state === 'Running' ? 1 : 0 } @@ -395,6 +402,7 @@ class Netbox { cluster: nbVm.cluster?.id ?? null, status: nbVm.status?.value ?? null, platform: nbVm.platform?.id ?? null, + site: nbVm.site?.id, // Sort them so that they can be compared by diff() tags: nbVm.tags.map(nbTag => ({ id: nbTag.id })).sort(({ id: id1 }, { id: id2 }) => (id1 < id2 ? -1 : 1)), })