From 7e9cab3a693ba6ae961954832d1daf3894111338 Mon Sep 17 00:00:00 2001 From: Jiri Tomasek Date: Mon, 8 Apr 2019 11:23:39 +0200 Subject: [PATCH 1/2] Add Start Maintenance action to Host --- .../public/metalkube/components/host/host.tsx | 14 +++-- .../metalkube/components/host/menu-actions.ts | 46 +++++++++++--- .../modals/start-maintenance-modal.jsx | 61 +++++++++++++++++++ 3 files changed, 109 insertions(+), 12 deletions(-) create mode 100644 frontend/public/metalkube/components/modals/start-maintenance-modal.jsx diff --git a/frontend/public/metalkube/components/host/host.tsx b/frontend/public/metalkube/components/host/host.tsx index baa588e51fb..efec30ea114 100644 --- a/frontend/public/metalkube/components/host/host.tsx +++ b/frontend/public/metalkube/components/host/host.tsx @@ -4,6 +4,8 @@ import { BaremetalHostRole, BaremetalHostStatus, getHostMachineName, + getHostBmcAddress, + getResource, getSimpleHostStatus, } from 'kubevirt-web-ui-components'; @@ -19,7 +21,7 @@ import { import { ResourceLink, ResourceKebab } from '../utils/okdutils'; import MachineCell from './machine-cell'; import { WithResources } from '../../../kubevirt/components/utils/withResources'; -import { BaremetalHostModel, MachineModel } from '../../models'; +import { BaremetalHostModel, MachineModel, NodeModel } from '../../models'; import { menuActions } from './menu-actions'; import { openCreateBaremetalHostModal } from '../modals/create-host-modal'; @@ -56,12 +58,11 @@ const HostHeader = props => ( const HostRow = ({ obj: host }) => { const { metadata: { name, namespace, uid }, - spec: { - bmc: { address }, - }, } = host; const machineName = getHostMachineName(host); + const address = getHostBmcAddress(host) + const machineResource = { kind: referenceForModel(MachineModel), name: machineName, @@ -77,6 +78,10 @@ const HostRow = ({ obj: host }) => { }, }; + const hostResources = machineName + ? [machineResource, getResource(NodeModel, { namespaced: false })] + : []; + return (
@@ -104,6 +109,7 @@ const HostRow = ({ obj: host }) => { actions={menuActions} kind={BaremetalHostModel.kind} resource={host} + resources={hostResources} />
diff --git a/frontend/public/metalkube/components/host/menu-actions.ts b/frontend/public/metalkube/components/host/menu-actions.ts index c0775f0cbf7..bb9421e9383 100644 --- a/frontend/public/metalkube/components/host/menu-actions.ts +++ b/frontend/public/metalkube/components/host/menu-actions.ts @@ -1,17 +1,44 @@ +import { + getHostPoweredOn, + getMachineNode, + canHostStartMaintenance, + canHostStopMaintenance, +} from 'kubevirt-web-ui-components'; + +import { makeNodeSchedulable } from '../../../module/k8s'; import { Kebab } from '../utils/okdutils'; +import { startMaintenanceModal } from '../modals/start-maintenance-modal'; + +const menuActionStartMaintenance = (kind, host, { machine, Node: nodes }) => { + const node = getMachineNode(nodes, machine); + return { + hidden: !canHostStartMaintenance(node), + label: 'Start Maintenance', + callback: () => startMaintenanceModal({ resource: node }), + }; +}; + +const menuActionStopMaintenance = (kind, host, { machine, Node: nodes }) => { + const node = getMachineNode(nodes, machine); + return { + hidden: !canHostStopMaintenance(node), + label: 'Stop Maintenance', + callback: () => makeNodeSchedulable(node), + }; +}; -const menuActionDrainHost = (kind, host) => ({ - hidden: false, // TODO(jtomasek): use canDrainHost selector - label: 'Drain Host', +const menuActionPowerOn = (kind, host) => ({ + hidden: getHostPoweredOn(host), + label: 'Power On', callback: () => { // eslint-disable-next-line no-console console.log(host); }, }); -const menuActionStartMaintenance = (kind, host) => ({ - hidden: false, - label: 'Start Maintenance', +const menuActionPowerOff = (kind, host) => ({ + hidden: !getHostPoweredOn(host), + label: 'Power Off', callback: () => { // eslint-disable-next-line no-console console.log(host); @@ -19,7 +46,10 @@ const menuActionStartMaintenance = (kind, host) => ({ }); export const menuActions = [ - menuActionDrainHost, + menuActionPowerOn, + menuActionPowerOff, menuActionStartMaintenance, - ...Kebab.factory.common, + menuActionStopMaintenance, + Kebab.factory.Edit, + Kebab.factory.Delete, ]; diff --git a/frontend/public/metalkube/components/modals/start-maintenance-modal.jsx b/frontend/public/metalkube/components/modals/start-maintenance-modal.jsx new file mode 100644 index 00000000000..fb02c18a1b1 --- /dev/null +++ b/frontend/public/metalkube/components/modals/start-maintenance-modal.jsx @@ -0,0 +1,61 @@ +import * as React from 'react'; +import * as PropTypes from 'prop-types'; + +import { makeNodeUnschedulable } from '../../../module/k8s'; +import { + createModalLauncher, + ModalTitle, + ModalBody, + ModalSubmitFooter, +} from '../factory/okdfactory'; +import { PromiseComponent } from '../utils/okdutils'; + +class StartMaintenanceModal extends PromiseComponent { + constructor(props) { + super(props); + this._submit = this._submit.bind(this); + this._cancel = this.props.cancel.bind(this); + } + + _submit(event) { + event.preventDefault(); + + this.handlePromise(makeNodeUnschedulable(this.props.resource)) + .then(this.props.close) + .catch(error => { + throw error; + }); + } + + render() { + return ( +
+ Start Maintenance + +

+ All managed workloads will be moved off of this host. New workloads + and data will not be added to this host until maintenance is + stopped. +

+

+ If the host does not exit maintenance within{' '} + 30 minutes, the cluster will automatically rebuild + the host's data using replicated copies +

+
+ + + ); + } +} + +StartMaintenanceModal.propTypes = { + resource: PropTypes.object.isRequired, +}; + +export const startMaintenanceModal = createModalLauncher(StartMaintenanceModal); From 5ef0e09409a13437e382c40374cb923747c9af2a Mon Sep 17 00:00:00 2001 From: Jiri Tomasek Date: Mon, 15 Apr 2019 12:33:32 +0200 Subject: [PATCH 2/2] Use selectors for host metadata, add confirmation modal for stop maintenance --- frontend/public/metalkube/components/host/host.tsx | 12 +++++++----- .../metalkube/components/host/menu-actions.ts | 14 ++++++++++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/frontend/public/metalkube/components/host/host.tsx b/frontend/public/metalkube/components/host/host.tsx index efec30ea114..12b0319ddce 100644 --- a/frontend/public/metalkube/components/host/host.tsx +++ b/frontend/public/metalkube/components/host/host.tsx @@ -5,8 +5,11 @@ import { BaremetalHostStatus, getHostMachineName, getHostBmcAddress, + getName, + getNamespace, getResource, getSimpleHostStatus, + getUid, } from 'kubevirt-web-ui-components'; import { actions, referenceForModel } from '../../../kubevirt/module/okdk8s'; @@ -56,12 +59,11 @@ const HostHeader = props => ( ); const HostRow = ({ obj: host }) => { - const { - metadata: { name, namespace, uid }, - } = host; - + const name = getName(host); + const namespace = getNamespace(host); + const uid = getUid(host); const machineName = getHostMachineName(host); - const address = getHostBmcAddress(host) + const address = getHostBmcAddress(host); const machineResource = { kind: referenceForModel(MachineModel), diff --git a/frontend/public/metalkube/components/host/menu-actions.ts b/frontend/public/metalkube/components/host/menu-actions.ts index bb9421e9383..606023e5eea 100644 --- a/frontend/public/metalkube/components/host/menu-actions.ts +++ b/frontend/public/metalkube/components/host/menu-actions.ts @@ -1,5 +1,5 @@ import { - getHostPoweredOn, + isHostPoweredOn, getMachineNode, canHostStartMaintenance, canHostStopMaintenance, @@ -8,6 +8,7 @@ import { import { makeNodeSchedulable } from '../../../module/k8s'; import { Kebab } from '../utils/okdutils'; import { startMaintenanceModal } from '../modals/start-maintenance-modal'; +import { confirmModal } from '../../../components/modals/confirm-modal'; const menuActionStartMaintenance = (kind, host, { machine, Node: nodes }) => { const node = getMachineNode(nodes, machine); @@ -23,12 +24,17 @@ const menuActionStopMaintenance = (kind, host, { machine, Node: nodes }) => { return { hidden: !canHostStopMaintenance(node), label: 'Stop Maintenance', - callback: () => makeNodeSchedulable(node), + callback: () => + confirmModal({ + executeFn: () => makeNodeSchedulable(node), + title: 'Stop Maintenance', + message: 'Node will exit maintenance and start taking workloads.', + }), }; }; const menuActionPowerOn = (kind, host) => ({ - hidden: getHostPoweredOn(host), + hidden: isHostPoweredOn(host), label: 'Power On', callback: () => { // eslint-disable-next-line no-console @@ -37,7 +43,7 @@ const menuActionPowerOn = (kind, host) => ({ }); const menuActionPowerOff = (kind, host) => ({ - hidden: !getHostPoweredOn(host), + hidden: !isHostPoweredOn(host), label: 'Power Off', callback: () => { // eslint-disable-next-line no-console