-
Notifications
You must be signed in to change notification settings - Fork 670
Introduce Metal3 plugin for openshift console #1539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const DASH = '-'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| export default {}; | ||
| export * from './selectors'; | ||
| export * from './constants'; |
| 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'); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| reviewers: | ||
| - jtomasek | ||
| - honza | ||
| - flofuchs | ||
| - knowncitizen | ||
| - dantrainor | ||
| approvers: | ||
| - jtomasek | ||
| - honza | ||
| - flofuchs | ||
| 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" | ||
| } | ||
| } |
| 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} | ||
| /> | ||
| ); | ||
| 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; |
| 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, | ||
| }; | ||
| 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; | ||
| 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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: sources should have one trailing newline by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it's still missing the final newline