diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index b35b437c2..6a892e04b 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -3,6 +3,7 @@ ### Enhancements - [SR/Disk] Disable actions on unmanaged VDIs [#3988](https://github.com/vatesfr/xen-orchestra/issues/3988) (PR [#4000](https://github.com/vatesfr/xen-orchestra/pull/4000)) +- [Pool] Specify automatic networks on a Pool [#3916](https://github.com/vatesfr/xen-orchestra/issues/3916) (PR [#3958](https://github.com/vatesfr/xen-orchestra/pull/3958)) ### Bug fixes diff --git a/packages/xo-server/src/api/network.js b/packages/xo-server/src/api/network.js index 0af927457..1c36a837a 100644 --- a/packages/xo-server/src/api/network.js +++ b/packages/xo-server/src/api/network.js @@ -85,34 +85,35 @@ createBonded.description = // =================================================================== export async function set({ - network, - + automatic, + defaultIsLocked, name_description: nameDescription, name_label: nameLabel, - defaultIsLocked, - id, + network, }) { await this.getXapi(network).setNetworkProperties(network._xapiId, { + automatic, + defaultIsLocked, nameDescription, nameLabel, - defaultIsLocked, }) } set.params = { - id: { - type: 'string', + automatic: { + type: 'boolean', + optional: true, }, - name_label: { - type: 'string', + defaultIsLocked: { + type: 'boolean', optional: true, }, name_description: { type: 'string', optional: true, }, - defaultIsLocked: { - type: 'boolean', + name_label: { + type: 'string', optional: true, }, } diff --git a/packages/xo-server/src/xapi-object-to-xo.js b/packages/xo-server/src/xapi-object-to-xo.js index b057fde2b..9acf6479a 100644 --- a/packages/xo-server/src/xapi-object-to-xo.js +++ b/packages/xo-server/src/xapi-object-to-xo.js @@ -578,6 +578,7 @@ const TRANSFORMS = { network(obj) { return { + automatic: obj.other_config?.automatic === 'true', bridge: obj.bridge, defaultIsLocked: obj.default_locking_mode === 'disabled', MTU: +obj.MTU, diff --git a/packages/xo-server/src/xapi/index.js b/packages/xo-server/src/xapi/index.js index 775cb8b99..2c27a8c6b 100644 --- a/packages/xo-server/src/xapi/index.js +++ b/packages/xo-server/src/xapi/index.js @@ -305,17 +305,23 @@ export default class Xapi extends XapiBase { async setNetworkProperties( id, - { nameLabel, nameDescription, defaultIsLocked } + { automatic, defaultIsLocked, nameDescription, nameLabel } ) { let defaultLockingMode if (defaultIsLocked != null) { defaultLockingMode = defaultIsLocked ? 'disabled' : 'unlocked' } - await this._setObjectProperties(this.getObject(id), { - nameLabel, - nameDescription, - defaultLockingMode, - }) + const network = this.getObject(id) + await Promise.all([ + this._setObjectProperties(network, { + defaultLockingMode, + nameDescription, + nameLabel, + }), + this._updateObjectMapProperty(network, 'other_config', { + automatic: automatic === undefined ? undefined : automatic ? 'true' : null, + }), + ]) } // ================================================================= diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js index 2a59685cf..6a49bf6eb 100644 --- a/packages/xo-web/src/common/intl/messages.js +++ b/packages/xo-web/src/common/intl/messages.js @@ -733,6 +733,7 @@ const messages = { memoryLeftTooltip: '{used}% used ({free} free)', // ----- Pool network tab ----- pif: 'PIF', + poolNetworkAutomatic: 'Automatic', poolNetworkNameLabel: 'Name', poolNetworkDescription: 'Description', poolNetworkPif: 'PIFs', diff --git a/packages/xo-web/src/xo-app/new-vm/index.js b/packages/xo-web/src/xo-app/new-vm/index.js index 0ac1a0a41..a1980f3f2 100644 --- a/packages/xo-web/src/xo-app/new-vm/index.js +++ b/packages/xo-web/src/xo-app/new-vm/index.js @@ -81,6 +81,7 @@ import { resolveResourceSet, } from 'utils' import { + createFilter, createSelector, createGetObject, createGetObjectsOfType, @@ -485,20 +486,19 @@ export default class NewVm extends BaseComponent { } }) - const VIFs = [] + let VIFs = [] + const defaultNetworkIds = this._getDefaultNetworkIds(template) forEach(template.VIFs, vifId => { const vif = getObject(storeState, vifId, resourceSet) VIFs.push({ network: pool || isInResourceSet(vif.$network) ? vif.$network - : this._getDefaultNetworkId(template), + : defaultNetworkIds[0], }) }) if (VIFs.length === 0) { - VIFs.push({ - network: this._getDefaultNetworkId(template), - }) + VIFs = defaultNetworkIds.map(id => ({ network: id })) } const name_label = state.name_label === '' || !state.name_labelHasChanged @@ -631,21 +631,38 @@ export default class NewVm extends BaseComponent { ) } ) - _getDefaultNetworkId = template => { + + _getAutomaticNetworks = createSelector( + createFilter(this._getPoolNetworks, [network => network.automatic]), + networks => networks.map(_ => _.id) + ) + + _getDefaultNetworkIds = template => { if (template === undefined) { - return + return [] } - const network = - this.props.pool === undefined - ? find(this._getResolvedResourceSet().objectsByType.network, { - $pool: template.$pool, - }) - : find(this._getPoolNetworks(), network => { - const pif = getObject(store.getState(), network.PIFs[0]) - return pif && pif.management - }) - return network && network.id + if (this.props.pool === undefined) { + const network = find( + this._getResolvedResourceSet().objectsByType.network, + { + $pool: template.$pool, + } + ) + return network !== undefined ? [network.id] : [] + } + + const automaticNetworks = this._getAutomaticNetworks() + if (automaticNetworks.length !== 0) { + return automaticNetworks + } + + const network = find(this._getPoolNetworks(), network => { + const pif = getObject(store.getState(), network.PIFs[0]) + return pif && pif.management + }) + + return network !== undefined ? [network.id] : [] } _buildVmsNameTemplate = createSelector( @@ -788,9 +805,7 @@ export default class NewVm extends BaseComponent { this._setState({ VIFs: [ ...state.VIFs, - { - network: this._getDefaultNetworkId(state.template), - }, + { network: this._getDefaultNetworkIds(state.template)[0] }, ], }) } diff --git a/packages/xo-web/src/xo-app/pool/tab-network.js b/packages/xo-web/src/xo-app/pool/tab-network.js index 856842883..c0b722b67 100644 --- a/packages/xo-web/src/xo-app/pool/tab-network.js +++ b/packages/xo-web/src/xo-app/pool/tab-network.js @@ -79,6 +79,21 @@ class Name extends Component { // ----------------------------------------------------------------------------- +class AutomaticNetwork extends Component { + _editAutomaticNetwork = automatic => + editNetwork(this.props.network, { automatic }) + + render() { + const { network } = this.props + + return ( + + ) + } +} + +// ----------------------------------------------------------------------------- + class Description extends Component { _editDescription = value => editNetwork(this.props.network, { name_description: value }) @@ -343,6 +358,10 @@ const NETWORKS_COLUMNS = [ itemRenderer: network => !isEmpty(network.PIFs) && , }, + { + name: _('poolNetworkAutomatic'), + itemRenderer: network => , + }, { name: '', itemRenderer: network => ,