feat(xo-web/host/network): private networks (#3481)

Fixes #3387
This commit is contained in:
Pierre Donias 2018-10-02 14:42:24 +02:00 committed by GitHub
parent 5a71ab53be
commit 85c3d64c04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 11 deletions

View File

@ -5,6 +5,7 @@
### Enhancements
- [Host/Networks] Remove "Add network" button [#3386](https://github.com/vatesfr/xen-orchestra/issues/3386) (PR [#3478](https://github.com/vatesfr/xen-orchestra/pull/3478))
- [Host/networks] Private networks table [#3387](https://github.com/vatesfr/xen-orchestra/issues/3387) (PR [#3481](https://github.com/vatesfr/xen-orchestra/pull/3481))
### Bug fixes

View File

@ -676,6 +676,8 @@ const messages = {
poolNetworkNameLabel: 'Name',
poolNetworkDescription: 'Description',
poolNetworkPif: 'PIFs',
privateNetworks: 'Private networks',
manage: 'Manage',
poolNoNetwork: 'No networks',
poolNetworkMTU: 'MTU',
poolNetworkPifAttached: 'Connected',

View File

@ -13,6 +13,7 @@ import { editHost, fetchHostStats, subscribeHostMissingPatches } from 'xo'
import { connectStore, routes } from 'utils'
import {
createDoesHostNeedRestart,
createFilter,
createGetObject,
createGetObjectsOfType,
createSelector,
@ -76,6 +77,13 @@ const isRunning = host => host && host.power_state === 'Running'
createSelector(getPifs, pifs => map(pifs, pif => pif.$network))
)
const getPrivateNetworks = createFilter(
createGetObjectsOfType('network'),
createSelector(getPool, pool => network =>
network.$pool === pool.id && isEmpty(network.PIFs)
)
)
const getHostPatches = createSelector(
createGetObjectsOfType('pool_patch'),
createGetObjectsOfType('host_patch').pick(
@ -114,6 +122,7 @@ const isRunning = host => host && host.power_state === 'Running'
nVms: getNumberOfVms(state, props),
pifs: getPifs(state, props),
pool: getPool(state, props),
privateNetworks: getPrivateNetworks(state, props),
vmController: getVmController(state, props),
vms: getHostVms(state, props),
}
@ -317,6 +326,7 @@ export default class Host extends Component {
'nVms',
'pbds',
'pifs',
'privateNetworks',
'srs',
'vmController',
'vms',

View File

@ -1,22 +1,22 @@
import _ from 'intl'
import ActionButton from 'action-button'
import Component from 'base-component'
import copy from 'copy-to-clipboard'
import React from 'react'
import Icon from 'icon'
import pick from 'lodash/pick'
import SingleLineRow from 'single-line-row'
import some from 'lodash/some'
import SortedTable from 'sorted-table'
import StateButton from 'state-button'
import Tooltip from 'tooltip'
import { confirm } from 'modal'
import { connectStore, noop } from 'utils'
import { Container, Col, Row } from 'grid'
import { Container, Row, Col } from 'grid'
import { createGetObjectsOfType } from 'selectors'
import { error } from 'notification'
import { get } from '@xen-orchestra/defined'
import { Select, Number } from 'editable'
import { Toggle } from 'form'
import { isEmpty, pick, some } from 'lodash'
import {
connectPif,
deletePif,
@ -209,7 +209,7 @@ class PifItemLock extends Component {
}
}
const COLUMNS = [
const PIF_COLUMNS = [
{
default: true,
itemRenderer: pif => pif.device,
@ -291,7 +291,7 @@ const COLUMNS = [
},
]
const INDIVIDUAL_ACTIONS = [
const PIF_INDIVIDUAL_ACTIONS = [
{
handler: pif => copy(pif.uuid),
icon: 'clipboard',
@ -305,7 +305,7 @@ const INDIVIDUAL_ACTIONS = [
},
]
const GROUPED_ACTIONS = [
const PIF_GROUPED_ACTIONS = [
{
handler: deletePifs,
icon: 'delete',
@ -314,19 +314,79 @@ const GROUPED_ACTIONS = [
},
]
export default ({ networks, pifs }) => (
const PVT_NETWORK_COLUMNS = [
{
name: _('poolNetworkNameLabel'),
itemRenderer: network => network.name_label,
},
{
name: _('poolNetworkDescription'),
itemRenderer: network => network.name_description,
},
{
name: _('poolNetworkMTU'),
itemRenderer: network => network.MTU,
},
{
name: (
<div className='text-xs-center'>
<Tooltip content={_('defaultLockingMode')}>
<Icon size='lg' icon='lock' />
</Tooltip>
</div>
),
itemRenderer: network => (
<Icon icon={network.defaultIsLocked ? 'lock' : 'unlock'} />
),
},
]
const PVT_NETWORK_ACTIONS = [
{
handler: network => copy(network.uuid),
icon: 'clipboard',
label: network => _('copyUuid', { uuid: network.uuid }),
},
]
export default ({ host, networks, pifs, privateNetworks }) => (
<Container>
<Row>
<Col>
<h1>{_('poolNetworkPif')}</h1>
<SortedTable
collection={pifs}
columns={COLUMNS}
columns={PIF_COLUMNS}
data-networks={networks}
groupedActions={GROUPED_ACTIONS}
individualActions={INDIVIDUAL_ACTIONS}
groupedActions={PIF_GROUPED_ACTIONS}
individualActions={PIF_INDIVIDUAL_ACTIONS}
stateUrlParam='s'
/>
</Col>
</Row>
{!isEmpty(privateNetworks) && (
<Row>
<Col>
<h1>
{_('privateNetworks')}
<ActionButton
className='ml-1'
handler={noop}
icon='edit'
redirectOnSuccess={`/pools/${
host.$pool
}/network?s=${encodeURIComponent('!PIFs:length?')}`}
>
{_('manage')}
</ActionButton>
</h1>
<SortedTable
collection={privateNetworks}
columns={PVT_NETWORK_COLUMNS}
individualActions={PVT_NETWORK_ACTIONS}
/>
</Col>
</Row>
)}
</Container>
)

View File

@ -376,7 +376,11 @@ export default class TabNetworks extends Component {
<Row>
<Col>
{!isEmpty(networks) ? (
<SortedTable collection={networks} columns={NETWORKS_COLUMNS} />
<SortedTable
collection={networks}
columns={NETWORKS_COLUMNS}
stateUrlParam='s'
/>
) : (
<h4 className='text-xs-center'>{_('poolNoNetwork')}</h4>
)}