Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/integration-tests/tests/performance.scenario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const chunkedRoutes = OrderedMap<string, {section: string, name: string}>()
.set('storage-class', {section: 'Storage', name: 'Storage Classes'})
.set('build-config', {section: 'Builds', name: 'Build Configs'})
.set('image-stream', {section: 'Builds', name: 'Image Streams'})
.set('node', {section: 'Administration', name: 'Nodes'})
.set('node', {section: 'Compute', name: 'Nodes'})
.set('service-account', {section: 'Administration', name: 'Service Accounts'})
.set('resource-quota', {section: 'Administration', name: 'Resource Quotas'})
.set('limit-range', {section: 'Administration', name: 'Limit Ranges'})
Expand Down
26 changes: 17 additions & 9 deletions frontend/public/components/machine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,34 @@ const getAWSPlacement = (machine: MachineKind) => _.get(machine, 'spec.providerS

export const getMachineRole = (obj: MachineKind | MachineSetKind | MachineDeploymentKind) => _.get(obj, ['metadata', 'labels', 'sigs.k8s.io/cluster-api-machine-role']);

const getNodeName = (obj) => _.get(obj, 'status.nodeRef.name');

const MachineHeader = props => <ListHeader>
<ColHead {...props} className="col-sm-4 col-xs-6" sortField="metadata.name">Name</ColHead>
<ColHead {...props} className="col-sm-4 col-xs-6" sortField="metadata.namespace">Namespace</ColHead>
<ColHead {...props} className="col-sm-2 hidden-xs" sortField="spec.providerSpec.value.placement.region">Region</ColHead>
<ColHead {...props} className="col-sm-2 hidden-xs" sortField="spec.providerSpec.value.placement.availabilityZone">Availability Zone</ColHead>
<ColHead {...props} className="col-lg-3 col-md-4 col-sm-4 col-xs-6" sortField="metadata.name">Name</ColHead>
<ColHead {...props} className="col-lg-2 col-md-4 col-sm-4 col-xs-6" sortField="metadata.namespace">Namespace</ColHead>
<ColHead {...props} className="col-lg-3 col-md-4 col-sm-4 hidden-xs" sortField="status.nodeRef.name">Node</ColHead>
<ColHead {...props} className="col-lg-2 hidden-md hidden-sm hidden-xs" sortField="spec.providerSpec.value.placement.region">Region</ColHead>
<ColHead {...props} className="col-lg-2 hidden-md hidden-sm hidden-xs" sortField="spec.providerSpec.value.placement.availabilityZone">Availability Zone</ColHead>
</ListHeader>;

const MachineRow: React.SFC<MachineRowProps> = ({obj}: {obj: MachineKind}) => {
const { availabilityZone, region } = getAWSPlacement(obj);
const nodeName = getNodeName(obj);

return <div className="row co-resource-list__item">
<div className="col-sm-4 col-xs-6 co-break-word">
<div className="col-lg-3 col-md-4 col-sm-4 col-xs-6 co-break-word">
<ResourceLink kind={machineReference} name={obj.metadata.name} namespace={obj.metadata.namespace} title={obj.metadata.name} />
</div>
<div className="col-sm-4 col-xs-6 co-break-word">
<div className="col-lg-2 col-md-4 col-sm-4 col-xs-6 co-break-word">
<ResourceLink kind="Namespace" name={obj.metadata.namespace} />
</div>
<div className="col-sm-2 hidden-xs">
<div className="col-lg-3 col-md-4 col-sm-4 hidden-xs">
{nodeName ? <NodeLink name={nodeName} /> : '-'}
</div>
<div className="col-lg-2 hidden-md hidden-sm hidden-xs">
{region || '-'}
</div>
<div className="col-sm-2 hidden-xs">
<div className="col-lg-2 hidden-md hidden-sm hidden-xs">
{availabilityZone || '-'}
</div>
<div className="dropdown-kebab-pf">
Expand All @@ -54,7 +62,7 @@ const MachineRow: React.SFC<MachineRowProps> = ({obj}: {obj: MachineKind}) => {
};

const MachineDetails: React.SFC<MachineDetailsProps> = ({obj}: {obj: MachineKind}) => {
const nodeName = _.get(obj, 'status.nodeRef.name');
const nodeName = getNodeName(obj);
const machineRole = getMachineRole(obj);
const { availabilityZone, region } = getAWSPlacement(obj);
return <React.Fragment>
Expand Down
16 changes: 7 additions & 9 deletions frontend/public/components/nav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,7 @@ HrefLink.propTypes = {

const navSectionStateToProps = (state, {required}) => {
const flags = state[featureReducerName];
// `required` can either be a single flag or array. Cast to an array when it's a single value.
const requiredArray = required ? _.castArray(required) : [];
const canRender = _.every(requiredArray, flag => flags.get(flag));
const canRender = required ? flags.get(required) : true;

return {
flags, canRender,
Expand Down Expand Up @@ -374,17 +372,17 @@ export const Navigation = ({ isNavOpen, onNavSelect }) => {

<MonitoringNavSection />

<NavSection title="Machines" required={[FLAGS.CLUSTER_API, FLAGS.MACHINE_CONFIG, FLAGS.CAN_LIST_MACHINE_CONFIG]}>
<ResourceNSLink resource={referenceForModel(MachineModel)} name="Machines" />
<ResourceNSLink resource={referenceForModel(MachineSetModel)} name="Machine Sets" />
<ResourceClusterLink resource={referenceForModel(MachineConfigModel)} name="Machine Configs" />
<ResourceClusterLink resource={referenceForModel(MachineConfigPoolModel)} name="Machine Config Pools" />
<NavSection title="Compute" required={FLAGS.CAN_LIST_NODE}>
<ResourceClusterLink resource="nodes" name="Nodes" />
<ResourceNSLink resource={referenceForModel(MachineModel)} name="Machines" required={FLAGS.CLUSTER_API} />
<ResourceNSLink resource={referenceForModel(MachineSetModel)} name="Machine Sets" required={FLAGS.CLUSTER_API} isSeparated />
<ResourceClusterLink resource={referenceForModel(MachineConfigModel)} name="Machine Configs" required={FLAGS.MACHINE_CONFIG} />
<ResourceClusterLink resource={referenceForModel(MachineConfigPoolModel)} name="Machine Config Pools" required={FLAGS.MACHINE_CONFIG} />
</NavSection>

<NavSection title="Administration">
<HrefLink href="/settings/cluster" activePath="/settings/cluster/" name="Cluster Settings" required={FLAGS.CLUSTER_VERSION} startsWith={clusterSettingsStartsWith} />
<ResourceClusterLink resource="namespaces" name="Namespaces" required={FLAGS.CAN_LIST_NS} />
<ResourceClusterLink resource="nodes" name="Nodes" required={FLAGS.CAN_LIST_NODE} />
<ResourceNSLink resource="serviceaccounts" name="Service Accounts" />
<ResourceNSLink resource="roles" name="Roles" startsWith={rolesStartsWith} />
<ResourceNSLink resource="rolebindings" name="Role Bindings" startsWith={rolebindingsStartsWith} />
Expand Down
62 changes: 19 additions & 43 deletions frontend/public/components/node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ const menuActions = [MarkAsSchedulable, MarkAsUnschedulable, ModifyLabels, Modif

const NodeKebab = ({node}) => <ResourceKebab actions={menuActions} kind="Node" resource={node} />;

const getMachine = (node: K8sResourceKind) => {
const machine = _.get(node, 'metadata.annotations["machine.openshift.io/machine"]');
if (!machine) {
return null;
}

const [namespace, name] = machine.split('/');
return { namespace, name };
};

export const NodeIPList = ({ips, expand = false}) => <div>
{_.sortBy(ips, ['type']).map((ip, i) => ip.address && <div key={i} className="co-node-ip">
{(expand || ip.type === 'InternalIP') && <p>
Expand All @@ -44,29 +54,25 @@ const Header = props => {
return null;
}
return <ListHeader>
<ColHead {...props} className="col-md-5 col-sm-6 col-xs-8" sortField="metadata.name">Node Name</ColHead>
<ColHead {...props} className="col-md-2 col-sm-6 col-xs-4" sortFunc="nodeReadiness">Status</ColHead>
<ColHead {...props} className="col-md-5 hidden-sm hidden-xs" sortField="status.addresses">Node Addresses</ColHead>
<ColHead {...props} className="col-md-4 col-sm-5 col-xs-8" sortField="metadata.name">Node Name</ColHead>
<ColHead {...props} className="col-md-2 col-sm-3 col-xs-4" sortFunc="nodeReadiness">Status</ColHead>
<ColHead {...props} className="col-md-3 col-sm-4 hidden-xs" sortField="metadata.annotations['machine.openshift.io/machine']">Machine</ColHead>
<ColHead {...props} className="col-md-3 hidden-sm hidden-xs" sortField="status.addresses">Node Addresses</ColHead>
</ListHeader>;
};

const HeaderSearch = props => <ListHeader>
<ColHead {...props} className="col-lg-2 col-md-3 col-sm-4 col-xs-5" sortField="metadata.name">Node Name</ColHead>
<ColHead {...props} className="col-md-2 hidden-sm hidden-xs" sortFunc="nodeReadiness">Status</ColHead>
<ColHead {...props} className="col-sm-5 col-xs-7" sortField="metadata.labels">Node Labels</ColHead>
<ColHead {...props} className="col-md-2 col-sm-3 hidden-xs" sortField="status.addresses">Node Addresses</ColHead>
</ListHeader>;

const NodeStatus = ({node}) => <StatusIcon status={nodeStatus(node)} />;

const NodeRow = ({obj: node, expand}) => {
const machine = getMachine(node);

return <ResourceRow obj={node}>
<div className="col-md-5 col-sm-6 col-xs-8">
<div className="col-md-4 col-sm-5 col-xs-8">
<ResourceLink kind="Node" name={node.metadata.name} title={node.metadata.uid} />
</div>
<div className="col-md-2 col-sm-6 col-xs-4"><NodeStatus node={node} /></div>
<div className="col-md-5 hidden-sm hidden-xs"><NodeIPList ips={node.status.addresses} expand={expand} /></div>
<div className="col-md-2 col-sm-3 col-xs-4"><NodeStatus node={node} /></div>
<div className="col-md-3 col-sm-4 hidden-xs"><ResourceLink kind={referenceForModel(MachineModel)} name={machine.name} namespace={machine.namespace} /></div>
<div className="col-md-3 hidden-sm hidden-xs"><NodeIPList ips={node.status.addresses} expand={expand} /></div>
{expand && <div className="col-xs-12">
<LabelList kind="Node" labels={node.metadata.labels} />
</div>}
Expand All @@ -76,27 +82,7 @@ const NodeRow = ({obj: node, expand}) => {
</ResourceRow>;
};

const NodeRowSearch = ({obj: node}) => <div className="row co-resource-list__item">
<div className="col-lg-2 col-md-3 col-sm-4 col-xs-5">
<ResourceLink kind="Node" name={node.metadata.name} title={node.metadata.uid} />
</div>
<div className="col-md-2 hidden-sm hidden-xs">
<NodeStatus node={node} />
</div>
<div className="col-sm-5 col-xs-7">
<LabelList kind="Node" labels={node.metadata.labels} expand={false} />
</div>
<div className="col-md-2 col-sm-3 hidden-xs">
<NodeIPList ips={node.status.addresses} />
</div>
<div className="dropdown-kebab-pf">
<NodeKebab node={node} />
</div>
</div>;

// We have different list layouts for the Nodes page list and the Search page list
const NodesList = props => <List {...props} Header={Header} Row={NodeRow} />;
export const NodesListSearch = props => <List {...props} Header={HeaderSearch} Row={NodeRowSearch} kind="node" />;

const filters = [{
type: 'node-status',
Expand Down Expand Up @@ -141,16 +127,6 @@ const NodeGraphs = requirePrometheus(({node}) => {
</React.Fragment>;
});

const getMachine = (node: K8sResourceKind) => {
const machine = _.get(node, 'metadata.annotations.machine');
if (!machine) {
return null;
}

const [namespace, name] = machine.split('/');
return { namespace, name };
};

const Details = ({obj: node}) => {
const images = _.filter(node.status.images, 'names');
const machine = getMachine(node);
Expand Down
4 changes: 0 additions & 4 deletions frontend/public/features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export enum FLAGS {
CAN_LIST_PV = 'CAN_LIST_PV',
CAN_LIST_STORE = 'CAN_LIST_STORE',
CAN_LIST_CRD = 'CAN_LIST_CRD',
CAN_LIST_MACHINE_CONFIG = 'CAN_LIST_MACHINE_CONFIG',
CAN_CREATE_PROJECT = 'CAN_CREATE_PROJECT',
SHOW_OPENSHIFT_START_GUIDE = 'SHOW_OPENSHIFT_START_GUIDE',
SERVICE_CATALOG = 'SERVICE_CATALOG',
Expand Down Expand Up @@ -241,9 +240,6 @@ const ssarChecks = [{
}, {
flag: FLAGS.CAN_LIST_CRD,
resourceAttributes:{ group: 'apiextensions.k8s.io', resource: 'customresourcedefinitions', verb: 'list' },
}, {
flag: FLAGS.CAN_LIST_MACHINE_CONFIG,
resourceAttributes:{ group: MachineConfigModel.apiGroup, resource: MachineConfigModel.plural, verb: 'list' },
}];

ssarChecks.forEach(({flag, resourceAttributes, after}) => {
Expand Down