Skip to content

Commit

Permalink
Merge pull request #1539 from jtomasek/metal3_plugin
Browse files Browse the repository at this point in the history
Introduce Metal3 plugin for openshift console
  • Loading branch information
openshift-merge-robot committed Jun 6, 2019
2 parents 32e4fee + e1d1ef7 commit 30c16b7
Show file tree
Hide file tree
Showing 10 changed files with 297 additions and 1 deletion.
1 change: 1 addition & 0 deletions frontend/packages/console-shared/src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const DASH = '-';
3 changes: 2 additions & 1 deletion frontend/packages/console-shared/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export default {};
export * from './selectors';
export * from './constants';
6 changes: 6 additions & 0 deletions frontend/packages/console-shared/src/selectors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as _ from 'lodash-es';

import { K8sResourceKind } from '@console/internal/module/k8s';

export const getName = (value: K8sResourceKind): string => _.get(value, 'metadata.name');
export const getNamespace = (value: K8sResourceKind): string => _.get(value, 'metadata.namespace');
10 changes: 10 additions & 0 deletions frontend/packages/metal3-plugin/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
reviewers:
- jtomasek
- honza
- flofuchs
- knowncitizen
- dantrainor
approvers:
- jtomasek
- honza
- flofuchs
13 changes: 13 additions & 0 deletions frontend/packages/metal3-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@console/metal3-plugin",
"version": "0.0.0-fixed",
"description": "Metal Kubed - Bare Metal Host Provisioning for Kubernetes",
"private": true,
"dependencies": {
"@console/plugin-sdk": "0.0.0-fixed",
"@console/shared": "0.0.0-fixed"
},
"consolePlugin": {
"entry": "src/plugin.ts"
}
}
130 changes: 130 additions & 0 deletions frontend/packages/metal3-plugin/src/components/host.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import * as React from 'react';

import { getName, getNamespace } from '@console/shared';
// TODO(jtomasek): update import once models are moved to console-shared package
// import { MachineModel, NodeModel } from '@console/internal/models';
import { referenceForModel } from '@console/internal/module/k8s';

import {
ListHeader,
ColHead,
List,
ListPage,
ResourceRow,
} from '@console/internal/components/factory';

import { ResourceLink } from '@console/internal/components/utils';
// import { WithResources } from '@console/shared';

import { BaremetalHostModel } from '../models';
import { getHostBMCAddress } from '../selectors';
import MachineCell from './machine-cell';

// const nameColumnClasses = 'col-lg-2 col-md-4 col-sm-6 col-xs-6';
// const statusColumnClasses = 'col-lg-2 col-md-4 hidden-sm hidden-xs';
// const machineColumnClasses = 'col-lg-3 visible-lg';
// const roleColumnClasses = 'col-lg-2 visible-lg';
// const addressColumnClasses = 'col-lg-2 visible-lg';
const columnClasses = 'col-sm-4';

const HostHeader = (props: React.ComponentProps<typeof ColHead>) => (
<ListHeader>
<ColHead {...props} className={columnClasses} sortField="metadata.name">
Name
</ColHead>
{/* <ColHead {...props} className={statusColumnClasses}>
Status
</ColHead> */}
<ColHead {...props} className={columnClasses}>
Machine
</ColHead>
{/* <ColHead {...props} className={roleColumnClasses}>
Role
</ColHead> */}
<ColHead {...props} className={columnClasses} sortField="spec.bmc.address">
Management Address
</ColHead>
</ListHeader>
);

const HostRow = ({ obj: host }: React.ComponentProps<typeof ResourceRow>) => {
const name = getName(host);
const namespace = getNamespace(host);
// const machineName = getHostMachineName(host);
const address = getHostBMCAddress(host);

// TODO(jtomasek): other resource references will be updated as a subsequent change
// const machineResource = {
// kind: referenceForModel(MachineModel),
// name: machineName,
// namespaced: true,
// namespace,
// isList: false,
// prop: 'machine',
// };

// const hostResourceMap = {
// machine: {
// resource: machineResource,
// },
// nodes: {
// resource: getResource(NodeModel, { namespaced: false }),
// },
// };

return (
<ResourceRow obj={host}>
<div className={columnClasses}>
<ResourceLink
kind={referenceForModel(BaremetalHostModel)}
name={name}
namespace={namespace}
/>
</div>
{/* <div className={statusColumnClasses}>
<WithResources resourceMap={machineName ? hostResourceMap : {}}>
<BaremetalHostStatus host={host} />
</WithResources>
</div> */}
<div className={columnClasses}>
<MachineCell host={host} />
</div>
{/* <div className={roleColumnClasses}>
<WithResources resourceMap={machineName ? hostResourceMap : {}}>
<BaremetalHostRole />
</WithResources>
</div> */}
<div className={columnClasses}>{address}</div>
</ResourceRow>
);
};

const HostList = (props: React.ComponentProps<typeof List>) => (
<List {...props} Header={HostHeader} Row={HostRow} />
);

// TODO(jtomasek): re-enable filters once the extension point for list.tsx is in place
const filters = [];
// const filters = [
// {
// type: 'baremetalhost-status',
// selected: ['online', 'offline'],
// reducer: getSimpleHostStatus,
// items: [{ id: 'online', title: 'online' }, { id: 'offline', title: 'offline' }],
// },
// ];

type BaremetalHostsPageProps = {
namespace: string;
};

export const BaremetalHostsPage = (props: BaremetalHostsPageProps) => (
<ListPage
{...props}
canCreate
rowFilters={filters}
createButtonText="Add Host"
kind={referenceForModel(BaremetalHostModel)}
ListComponent={HostList}
/>
);
51 changes: 51 additions & 0 deletions frontend/packages/metal3-plugin/src/components/machine-cell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import * as React from 'react';
// import { Link } from 'react-router-dom';
// import { Icon } from 'patternfly-react';

import { DASH } from '@console/shared';
import { MachineModel } from '@console/internal/models';
import { ResourceLink /* , RequireCreatePermission */ } from '@console/internal/components/utils';
import { referenceForModel, K8sResourceKind } from '@console/internal/module/k8s';

import { getHostMachineName } from '../selectors';

interface MachineCellProps {
host: K8sResourceKind;
}

const MachineCell = ({ host }: MachineCellProps) => {
const machineName = getHostMachineName(host);

const {
metadata: { namespace },
} = host;

if (machineName) {
return (
<ResourceLink
kind={referenceForModel(MachineModel)}
name={machineName}
namespace={namespace}
title={machineName}
/>
);
}
// TODO(jtomasek): Re-enable this once host status is added
// if (canHostAddMachine(host)) {
// const ns = namespace || 'default';
// const href = `/k8s/ns/${ns}/${referenceForModel(MachineModel)}/~new`;
// return (
// <RequireCreatePermission model={MachineModel} namespace={ns}>
// <Link to={href}>
// <span className="co-icon-and-text">
// <Icon type="pf" name="add-circle-o" className="co-icon-and-text__icon" />
// Add machine
// </span>
// </Link>
// </RequireCreatePermission>
// );
// }
return <>{DASH}</>;
};

export default MachineCell;
15 changes: 15 additions & 0 deletions frontend/packages/metal3-plugin/src/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { K8sKind } from '@console/internal/module/k8s';

export const BaremetalHostModel: K8sKind = {
label: 'Bare Metal Host',
labelPlural: 'Bare Metal Hosts',
apiVersion: 'v1alpha1',
path: 'baremetalhosts',
apiGroup: 'metalkube.org',
plural: 'baremetalhosts',
abbr: 'BMH',
namespaced: true,
kind: 'BareMetalHost',
id: 'baremetalhost',
crd: true,
};
53 changes: 53 additions & 0 deletions frontend/packages/metal3-plugin/src/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {
Plugin,
ResourceNSNavItem,
ResourceListPage,
ModelFeatureFlag,
ModelDefinition,
} from '@console/plugin-sdk';

import { BaremetalHostModel } from './models';

type ConsumedExtensions = ResourceNSNavItem | ResourceListPage | ModelFeatureFlag | ModelDefinition;

const METAL3_FLAG = 'METAL3';

const plugin: Plugin<ConsumedExtensions> = [
{
type: 'ModelDefinition',
properties: {
models: [BaremetalHostModel],
},
},
{
type: 'FeatureFlag/Model',
properties: {
model: BaremetalHostModel,
flag: METAL3_FLAG,
},
},
{
type: 'NavItem/ResourceNS',
properties: {
section: 'Compute',
mergeAfter: 'Machine Autoscalers',
componentProps: {
name: 'Bare Metal Hosts',
resource: 'baremetalhosts',
required: METAL3_FLAG,
},
},
},
{
type: 'Page/Resource/List',
properties: {
model: BaremetalHostModel,
loader: () =>
import('./components/host' /* webpackChunkName: "metal3-baremetalhost" */).then(
(m) => m.BaremetalHostsPage,
),
},
},
];

export default plugin;
16 changes: 16 additions & 0 deletions frontend/packages/metal3-plugin/src/selectors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as _ from 'lodash-es';

export const getOperationalStatus = (host) => _.get(host, 'status.operationalStatus');
export const getProvisioningState = (host) => _.get(host, 'status.provisioning.state');
export const getHostMachineName = (host) => _.get(host, 'spec.machineRef.name');
export const getHostBMCAddress = (host) => _.get(host, 'spec.bmc.address');
export const isHostOnline = (host) => _.get(host, 'spec.online', false);
export const getHostNICs = (host) => _.get(host, 'status.hardware.nics', []);
export const getHostStorage = (host) => _.get(host, 'status.hardware.storage', []);
export const getHostCPUs = (host) => _.get(host, 'status.hardware.cpus', []);
export const getHostRAM = (host) => _.get(host, 'status.hardware.ramGiB');
export const getHostErrorMessage = (host) => _.get(host, 'status.errorMessage');
export const getHostDescription = (host) => _.get(host, 'spec.description', '');
export const isHostPoweredOn = (host) => _.get(host, 'status.poweredOn', false);
export const getHostTotalStorageCapacity = (host) =>
_.reduce(getHostStorage(host), (sum, disk) => sum + disk.sizeGiB, 0);

0 comments on commit 30c16b7

Please sign in to comment.