diff --git a/packages/xo-server-sdn-controller/src/index.js b/packages/xo-server-sdn-controller/src/index.js index 323489ab3e2..750cbff5dee 100644 --- a/packages/xo-server-sdn-controller/src/index.js +++ b/packages/xo-server-sdn-controller/src/index.js @@ -183,17 +183,12 @@ async function generateCertificatesAndKey(dataDir) { // ----------------------------------------------------------------------------- -async function createTunnel(host, network) { +async function createTunnel(host, network, pif) { const otherConfig = network.other_config - const pifDevice = otherConfig['xo:sdn-controller:pif-device'] - const pifVlan = otherConfig['xo:sdn-controller:vlan'] - const hostPif = host.$PIFs.find( - pif => pif.device === pifDevice && pif.VLAN === +pifVlan && pif.ip_configuration_mode !== 'None' - ) + const hostPif = pif + if (hostPif === undefined) { log.error("Can't create tunnel: no available PIF", { - pifDevice, - pifVlan, network: network.name_label, host: host.name_label, pool: host.$pool.name_label, @@ -219,8 +214,6 @@ async function createTunnel(host, network) { } catch (error) { log.error('Error while creating tunnel', { error, - pifDevice, - pifVlan, network: network.name_label, host: host.name_label, pool: host.$pool.name_label, @@ -229,8 +222,6 @@ async function createTunnel(host, network) { } log.debug('New tunnel added', { - pifDevice, - pifVlan, network: network.name_label, host: host.name_label, pool: host.$pool.name_label, @@ -266,10 +257,8 @@ class SDNController extends EventEmitter { - `other_config`: - `xo:sdn-controller:encapsulation` : encapsulation protocol used for tunneling (either `gre` or `vxlan`) - `xo:sdn-controller:encrypted` : `true` if the network is encrypted - - `xo:sdn-controller:pif-device` : PIF device on which the tunnels are created, must be physical or VLAN or bond master and have an IP configuration - `xo:sdn-controller:preferred-center` : The host UUID to prioritize as network center (or not defined) - `xo:sdn-controller:private-network-uuid`: UUID of the private network, same across pools - - `xo:sdn-controller:vlan` : VLAN of the PIFs on which the network is created - `xo:sdn-controller:vni` : VxLAN Network Identifier, it is used by OpenVSwitch to route traffic of different networks in a single tunnel See: https://tools.ietf.org/html/rfc7348 @@ -526,28 +515,6 @@ class SDNController extends EventEmitter { await privateNetwork.addNetwork(network) - // Previously created network didn't store `pif-device` - // - // 2019-08-22 - // This is used to add the pif-device to networks created before this version. (v0.1.2) - // This will be removed in 1 year. - if (otherConfig['xo:sdn-controller:pif-device'] === undefined) { - const tunnel = getHostTunnelForNetwork(privateNetwork.center, network.$ref) - const pif = xapi.getObjectByRef(tunnel.transport_PIF) - await network.update_other_config('xo:sdn-controller:pif-device', pif.device) - } - - // Previously created network didn't store `vlan` - // - // 2020-01-27 - // This is used to add the `vlan` to networks created before this version. (v0.4.0) - // This will be removed in 1 year. - if (otherConfig['xo:sdn-controller:vlan'] === undefined) { - const tunnel = getHostTunnelForNetwork(privateNetwork.center, network.$ref) - const pif = xapi.getObjectByRef(tunnel.transport_PIF) - await network.update_other_config('xo:sdn-controller:vlan', String(pif.VLAN)) - } - this._networks.set(network.$id, network.$ref) if (privateNetwork.center !== undefined) { this._starCenters.set(privateNetwork.center.$id, privateNetwork.center.$ref) @@ -740,10 +707,8 @@ class SDNController extends EventEmitter { automatic: 'false', 'xo:sdn-controller:encapsulation': encapsulation, 'xo:sdn-controller:encrypted': encrypted ? 'true' : undefined, - 'xo:sdn-controller:pif-device': pif.device, 'xo:sdn-controller:preferred-center': preferredCenter?.uuid, 'xo:sdn-controller:private-network-uuid': privateNetwork.uuid, - 'xo:sdn-controller:vlan': String(pif.VLAN), 'xo:sdn-controller:vni': String(vni), }, }) @@ -760,7 +725,8 @@ class SDNController extends EventEmitter { const hosts = filter(pool.$xapi.objects.all, { $type: 'host' }) await Promise.all( map(hosts, async host => { - await createTunnel(host, createdNetwork) + const hostPif = host.$PIFs.find(_pif => _pif.network === pif.network) + await createTunnel(host, createdNetwork, hostPif) this._getOrCreateOvsdbClient(host) this._getOrCreateOfChannel(host) }) @@ -966,8 +932,9 @@ class SDNController extends EventEmitter { const privateNetworks = filter( this.privateNetworks, - privateNetwork => privateNetwork[host.$pool.uuid] !== undefined + privateNetwork => privateNetwork.networks[host.$pool.uuid] !== undefined ) + for (const privateNetwork of privateNetworks) { const network = privateNetwork.networks[host.$pool.uuid] const tunnel = getHostTunnelForNetwork(host, network.$ref) @@ -975,7 +942,10 @@ class SDNController extends EventEmitter { continue } - await createTunnel(host, network) + const transportPif = await privateNetwork.getTransportPif(network) + const hostPif = host.$PIFs.find(pif => pif.network === transportPif.network) + + await createTunnel(host, network, hostPif) } await this._addHostToPrivateNetworks(host) diff --git a/packages/xo-server-sdn-controller/src/private-network/private-network.js b/packages/xo-server-sdn-controller/src/private-network/private-network.js index 608d42acc66..48cbbd9ce59 100644 --- a/packages/xo-server-sdn-controller/src/private-network/private-network.js +++ b/packages/xo-server-sdn-controller/src/private-network/private-network.js @@ -58,8 +58,9 @@ export class PrivateNetwork { const vni = otherConfig['xo:sdn-controller:vni'] ?? '0' const password = otherConfig['xo:sdn-controller:encrypted'] === 'true' ? createPassword() : undefined - const hostPif = this._getHostTransportPif(host) - const centerPif = this._getHostTransportPif(this.center) + const transportPif = await this.getTransportPif(network) + const hostPif = host.$PIFs.find(pif => pif.network === transportPif.network) + const centerPif = this.center.$PIFs.find(pif => pif.network === transportPif.network) assert(hostPif !== undefined, 'No PIF found', { privateNetwork: this.uuid, @@ -153,6 +154,19 @@ export class PrivateNetwork { return pools } + /** + * + * @param {Network} network + * @returns {Pif} returns one transport_PIF of the private network + */ + async getTransportPif(network) { + // ensure to get an fresh version of the network + network = await network.$xapi.getRecord('network', network.$ref) + const privatePif = network.$PIFs[0] + const tunnels = privatePif.$tunnel_access_PIF_of + return tunnels?.find(tunnel => tunnel.$transport_PIF.ip_configuration_mode !== 'None').$transport_PIF + } + // --------------------------------------------------------------------------- _reset() { @@ -207,16 +221,4 @@ export class PrivateNetwork { } } } - - /** - * - * @param {Host} host - * @returns {Pif | undefined} - */ - _getHostTransportPif(host) { - const network = this.networks[host.$pool.uuid] - const privatePif = host.$PIFs.find(pif => pif.$network.uuid === network.uuid) - const tunnels = privatePif?.$tunnel_access_PIF_of - return tunnels?.find(tunnel => tunnel.$transport_PIF.ip_configuration_mode !== 'None').$transport_PIF - } }