Skip to content

Commit

Permalink
feat(xo-web/host/network): display and edit the IPv6 PIF field
Browse files Browse the repository at this point in the history
  • Loading branch information
MathieuRA committed Dec 26, 2023
1 parent 4c8e402 commit e609fc4
Show file tree
Hide file tree
Showing 13 changed files with 55 additions and 42 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

> Users must be able to say: “Nice enhancement, I'm eager to test it”
- [Host/Network/PIF] Display and ability to edit IPv6 field [#5400](https://github.com/vatesfr/xen-orchestra/issues/5400) (PR [#7218](https://github.com/vatesfr/xen-orchestra/pull/7218))

### Bug fixes

> Users must be able to say: “I had this issue, happy to know it's fixed”
Expand All @@ -28,5 +30,6 @@
<!--packages-start-->

- xo-server minor
- xo-web minor

<!--packages-end-->
3 changes: 0 additions & 3 deletions packages/xo-web/src/common/intl/locales/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -1541,9 +1541,6 @@ export default {
// Original text: 'Invalid parameters'
configIpErrorTitle: undefined,

// Original text: 'IP address and netmask required'
configIpErrorMessage: undefined,

// Original text: 'Static IP address'
staticIp: undefined,

Expand Down
3 changes: 0 additions & 3 deletions packages/xo-web/src/common/intl/locales/fr.js
Original file line number Diff line number Diff line change
Expand Up @@ -1596,9 +1596,6 @@ export default {
// Original text: "Invalid parameters"
configIpErrorTitle: 'Paramètres invalides',

// Original text: "IP address and netmask required"
configIpErrorMessage: 'Adresse IP et masque de réseau requis',

// Original text: "Static IP address"
staticIp: 'Adresse IP statique',

Expand Down
3 changes: 0 additions & 3 deletions packages/xo-web/src/common/intl/locales/he.js
Original file line number Diff line number Diff line change
Expand Up @@ -1295,9 +1295,6 @@ export default {
// Original text: 'Invalid parameters'
configIpErrorTitle: undefined,

// Original text: 'IP address and netmask required'
configIpErrorMessage: undefined,

// Original text: 'Static IP address'
staticIp: undefined,

Expand Down
3 changes: 0 additions & 3 deletions packages/xo-web/src/common/intl/locales/hu.js
Original file line number Diff line number Diff line change
Expand Up @@ -1491,9 +1491,6 @@ export default {
// Original text: "Invalid parameters"
configIpErrorTitle: 'Invalid parameters',

// Original text: "IP address and netmask required"
configIpErrorMessage: 'IP cím and netmask required',

// Original text: "Static IP address"
staticIp: 'Static IP cím',

Expand Down
3 changes: 0 additions & 3 deletions packages/xo-web/src/common/intl/locales/it.js
Original file line number Diff line number Diff line change
Expand Up @@ -2387,9 +2387,6 @@ export default {
// Original text: 'Invalid parameters'
configIpErrorTitle: 'Parametri non validi',

// Original text: 'IP address and netmask required'
configIpErrorMessage: 'Indirizzo IP e maschera di rete richiesti',

// Original text: 'Static IP address'
staticIp: 'Indirizzo IP statico',

Expand Down
3 changes: 0 additions & 3 deletions packages/xo-web/src/common/intl/locales/pl.js
Original file line number Diff line number Diff line change
Expand Up @@ -1298,9 +1298,6 @@ export default {
// Original text: 'Invalid parameters'
configIpErrorTitle: undefined,

// Original text: 'IP address and netmask required'
configIpErrorMessage: undefined,

// Original text: 'Static IP address'
staticIp: undefined,

Expand Down
3 changes: 0 additions & 3 deletions packages/xo-web/src/common/intl/locales/pt.js
Original file line number Diff line number Diff line change
Expand Up @@ -1296,9 +1296,6 @@ export default {
// Original text: 'Invalid parameters'
configIpErrorTitle: undefined,

// Original text: 'IP address and netmask required'
configIpErrorMessage: undefined,

// Original text: 'Static IP address'
staticIp: undefined,

Expand Down
3 changes: 0 additions & 3 deletions packages/xo-web/src/common/intl/locales/ru.js
Original file line number Diff line number Diff line change
Expand Up @@ -1542,9 +1542,6 @@ export default {
// Original text: 'Invalid parameters'
configIpErrorTitle: undefined,

// Original text: 'IP address and netmask required'
configIpErrorMessage: undefined,

// Original text: 'Static IP address'
staticIp: undefined,

Expand Down
3 changes: 0 additions & 3 deletions packages/xo-web/src/common/intl/locales/tr.js
Original file line number Diff line number Diff line change
Expand Up @@ -1990,9 +1990,6 @@ export default {
// Original text: "Invalid parameters"
configIpErrorTitle: 'Geçersiz parametre',

// Original text: "IP address and netmask required"
configIpErrorMessage: 'IP adresi ve ağ maskesi gerekli',

// Original text: "Static IP address"
staticIp: 'Statik IP adresi',

Expand Down
4 changes: 3 additions & 1 deletion packages/xo-web/src/common/intl/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -1072,11 +1072,13 @@ const messages = {
defaultLockingMode: 'Default locking mode',
pifConfigureIp: 'Configure IP address',
configIpErrorTitle: 'Invalid parameters',
configIpErrorMessage: 'IP address and netmask required',
staticIp: 'Static IP address',
staticIpv6: 'Static IPv6 address',
netmask: 'Netmask',
dns: 'DNS',
gateway: 'Gateway',
ipRequired: 'An IP address is required',
netmaskRequired: 'Netmask required',
// ----- Host storage tabs -----
addSrDeviceButton: 'Add a storage',
srType: 'Type',
Expand Down
6 changes: 5 additions & 1 deletion packages/xo-web/src/common/xo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2244,18 +2244,22 @@ export const deletePifs = pifs =>
body: _('deletePifsConfirm', { nPifs: pifs.length }),
}).then(() => Promise.all(map(pifs, pif => _call('pif.delete', { pif: resolveId(pif) }))), noop)

export const reconfigurePifIp = (pif, { mode, ip, netmask, gateway, dns }) =>
export const reconfigurePifIp = (pif, { mode, ip, ipv6, ipv6Mode, netmask, gateway, dns }) =>
_call('pif.reconfigureIp', {
pif: resolveId(pif),
mode,
ip,
ipv6,
ipv6Mode,
netmask,
gateway,
dns,
})

export const getIpv4ConfigModes = () => _call('pif.getIpv4ConfigurationModes')

export const getIpv6ConfigModes = () => _call('pif.getIpv6ConfigurationModes')

export const editPif = (pif, { vlan }) => _call('pif.editPif', { pif: resolveId(pif), vlan })

export const scanHostPifs = hostId => _call('host.scanPifs', { host: hostId })
Expand Down
57 changes: 44 additions & 13 deletions packages/xo-web/src/xo-app/host/tab-network.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
editNetwork,
editPif,
getIpv4ConfigModes,
getIpv6ConfigModes,
reconfigurePifIp,
scanHostPifs,
} from 'xo'
Expand All @@ -41,7 +42,10 @@ class ConfigureIpModal extends Component {

const { pif } = props
if (pif) {
this.state = pick(pif, ['ip', 'netmask', 'dns', 'gateway'])
this.state = {
...pick(pif, ['ip', 'netmask', 'dns', 'gateway']),
ipv6: pif.ipv6?.[0],
}
}
}

Expand All @@ -50,7 +54,7 @@ class ConfigureIpModal extends Component {
}

render() {
const { ip, netmask, dns, gateway } = this.state
const { ip, ipv6, netmask, dns, gateway } = this.state

return (
<div>
Expand All @@ -61,6 +65,13 @@ class ConfigureIpModal extends Component {
</Col>
</SingleLineRow>
&nbsp;
<SingleLineRow>
<Col size={6}>{_('staticIpv6')}</Col>
<Col size={6}>
<input className='form-control' onChange={this.linkState('ipv6')} value={ipv6} />
</Col>
</SingleLineRow>
&nbsp;
<SingleLineRow>
<Col size={6}>{_('netmask')}</Col>
<Col size={6}>
Expand Down Expand Up @@ -111,22 +122,27 @@ const reconfigureIp = (pif, mode) => {
title: _('pifConfigureIp'),
body: <ConfigureIpModal pif={pif} />,
}).then(params => {
if (!params.ip || !params.netmask) {
error(_('configIpErrorTitle'), _('configIpErrorMessage'))
return
if (params.ip === undefined && params.ipv6 === undefined) {
return error(_('configIpErrorTitle'), _('ipRequired'))
}
if (params.ip !== undefined && params.netmask === undefined) {
return error(_('configIpErrorTitle'), _('netmaskRequired'))
}
if (params.ipv6 !== undefined) {
params.ipv6Mode = mode
}
return reconfigurePifIp(pif, { mode, ...params })
}, noop)
}
return reconfigurePifIp(pif, { mode })
return reconfigurePifIp(pif, { [pif.primaryAddressType === 'IPv6' ? 'ipv6Mode' : 'mode']: mode })
}

class PifItemIp extends Component {
_onEditIp = () => reconfigureIp(this.props.pif, 'Static')

render() {
const { pif } = this.props
const pifIp = pif.ip
const pifIp = pif.primaryAddressType === 'IPv6' ? pif.ipv6?.[0] : pif.ip
return (
<div>
{pifIp}{' '}
Expand All @@ -143,26 +159,41 @@ class PifItemIp extends Component {
class PifItemMode extends Component {
state = { configModes: [] }

componentDidMount() {
getIpv4ConfigModes().then(configModes => this.setState({ configModes }))
async componentDidMount() {
const [ipv4ConfigModes, ipv6ConfigModes] = await Promise.all([getIpv4ConfigModes(), getIpv6ConfigModes()])
this.setState({ ipv4ConfigModes, ipv6ConfigModes })
}

_configIp = mode => mode != null && reconfigureIp(this.props.pif, mode.value)

_isIpv6 = createSelector(
() => this.props.pif.primaryAddressType,
primaryAddressType => primaryAddressType === 'IPv6'
)

_getOptions = createSelector(
() => this.state.configModes,
configModes => configModes.map(mode => ({ label: mode, value: mode }))
this._isIpv6,
() => this.state.ipv4ConfigModes,
() => this.state.ipv6ConfigModes,
(isIpv6, ipv4ConfigModes, ipv6ConfigModes) =>
(isIpv6 ? ipv6ConfigModes : ipv4ConfigModes).map(mode => ({ label: mode, value: mode }))
)

_getValue = createSelector(
this._isIpv6,
() => this.props.pif.mode,
mode => ({ label: mode, value: mode })
() => this.props.pif.ipv6Mode,
(isIpv6, mode, ipv6Mode) => {
mode = isIpv6 ? ipv6Mode : mode
return { label: mode, value: mode }
}
)

render() {
const isIpv6 = this._isIpv6()
return (
<Select onChange={this._configIp} options={this._getOptions()} value={this._getValue()}>
{this.props.pif.mode}
{this.props.pif[isIpv6 ? 'ipv6Mode' : 'mode']}
</Select>
)
}
Expand Down

0 comments on commit e609fc4

Please sign in to comment.