Skip to content
This repository was archived by the owner on Apr 28, 2020. It is now read-only.

Add subsystem health #362

Merged
merged 28 commits into from
Apr 17, 2019
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
deca658
Add subsystem health
yaacov Apr 15, 2019
bde1359
move status subtitle down
yaacov Apr 16, 2019
783e0a2
re-record snaps
yaacov Apr 16, 2019
0500145
css tweeks
yaacov Apr 17, 2019
c6b2542
Add status parsing logic
rawagner Apr 17, 2019
0238038
update subsystem health fixture
yaacov Apr 17, 2019
075874b
more css tweeks, making default state loading
yaacov Apr 17, 2019
04b2289
subsystem health is not a card
yaacov Apr 17, 2019
0170967
Update OCS props and not available message
rawagner Apr 17, 2019
b4310d4
Wrap health items in health body
rawagner Apr 17, 2019
65a736b
typos snaps ...
yaacov Apr 17, 2019
e5d1902
add state to subsystem
yaacov Apr 17, 2019
4780f3f
use state in fixture
yaacov Apr 17, 2019
8397fac
create utils for health
rawagner Apr 17, 2019
2f651e3
yarn test issues
yaacov Apr 17, 2019
d9cfed4
Improve health css
rawagner Apr 17, 2019
d0dab74
More css fixes
rawagner Apr 17, 2019
2de9579
fix subsystem health fixture
yaacov Apr 17, 2019
c1f4d75
fix import
yaacov Apr 17, 2019
43f132a
Add multiple errors cluster state
rawagner Apr 17, 2019
08467ae
Fix snapshots
rawagner Apr 17, 2019
80beb72
add tests for multiple errors in overview
yaacov Apr 17, 2019
985da51
Use popover title prop
rawagner Apr 17, 2019
d2c591a
Css tweaks
rawagner Apr 17, 2019
fa4e0c8
remove buttom border in subsystem health
yaacov Apr 17, 2019
1c9397b
do not default export TitleSeAall dashboard card
yaacov Apr 17, 2019
e2d988a
move subsystem health to dashboard
yaacov Apr 17, 2019
a0af870
Fix body height
rawagner Apr 17, 2019
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
5 changes: 3 additions & 2 deletions sass/components/ClusterOverview/compliance.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.kubevirt-compliance__body {
text-align: center;
max-height: 130px;
display: flex;
flex-wrap: wrap;
align-items: center;
}
6 changes: 0 additions & 6 deletions sass/components/ClusterOverview/health.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,3 @@
grid-gap: 0;
}
}

.kubevirt-compliance__body {
display: flex;
flex-wrap: wrap;
align-items: center;
}
30 changes: 29 additions & 1 deletion sass/components/Dashboard/health.scss
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
.kubevirt-health__body {
.kubevirt-health__item {
display: flex;
flex-wrap: wrap;
align-items: center;
}

/* stylelint-disable plugin/selector-bem-pattern */
.kubevirt-health__body--subsystem {
display: flex;
flex-wrap: wrap;
flex-direction: column;

.kubevirt-health__item {
border-bottom: 1px solid #ededed;
padding-top: 5px;
}
}
/* stylelint-enable */

.kubevirt-health__text {
font-size: 0.875rem;
margin-left: 1rem;
}

.kubevirt-health__message {
font-size: 0.875rem;
display: table-cell;
}

.kubevirt-health__title {
padding-left: 0.6rem;
}

.kubevirt-health__subtitle {
font-size: 0.6rem;
color: grey;
}

.kubevirt-health__icon {
display: table-cell;
font-size: 1.5rem;
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/ClusterOverview/ClusterOverview.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Dashboard, DashboardBody } from '../Dashboard';
import { MEDIA_QUERY_EXCLUSIVE_DEVIATION, MEDIA_QUERY_LG } from '../../utils';

import { DetailsConnected } from './Details/Details';
import HealthConnected from './Health/Health';
import { HealthConnected } from './Health/Health';
import ComplianceConnected from './Compliance/Compliance';
import EventsConnected from './Events/Events';
import { InventoryConnected } from './Inventory/Inventory';
Expand Down
98 changes: 80 additions & 18 deletions src/components/ClusterOverview/Health/Health.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,93 @@ import {
DashboardCardBody,
DashboardCardHeader,
DashboardCardTitle,
DashboardCardTitleSeeAll,
} from '../../Dashboard/DashboardCard';
import HealthBody from './HealthBody';
import { ClusterOverviewContextGenericConsumer } from '../ClusterOverviewContext';
import { ClusterOverviewContext } from '../ClusterOverviewContext';
import { InlineLoading } from '../../Loading';
import { SubsystemHealth } from '../../SubsystemHealth';
import { HealthItem, OK_STATE, ERROR_STATE, WARNING_STATE } from '../../Dashboard/Health/HealthItem';
import { HealthBody } from '../../Dashboard/Health/HealthBody';
import { getK8sHealthState, getKubevirtHealthState, getOCSHealthState } from '../../Dashboard/Health/utils';

export const Health = ({ data, loaded }) => (
<DashboardCard>
<DashboardCardHeader>
<DashboardCardTitle>Cluster Health</DashboardCardTitle>
</DashboardCardHeader>
<DashboardCardBody className="kubevirt-health__body" isLoading={!loaded} LoadingComponent={InlineLoading}>
<HealthBody data={data} />
</DashboardCardBody>
</DashboardCard>
);
const getClusterHealth = subsystemStates => {
let healthState = { state: OK_STATE, message: 'Cluster is healthy' };
const sortedStates = {
errorStates: [],
warningStates: [],
};

subsystemStates.forEach(state => {
switch (state.state) {
case ERROR_STATE:
sortedStates.errorStates.push(state);
break;
case WARNING_STATE:
sortedStates.warningStates.push(state);
break;
default:
break;
}
});

if (sortedStates.errorStates.length > 0) {
healthState =
sortedStates.errorStates.length === 1
? sortedStates.errorStates[0]
: { state: ERROR_STATE, message: 'Multiple errors', details: 'Cluster health is degrated' };
} else if (sortedStates.warningStates.length > 0) {
healthState =
sortedStates.warningStates.length === 1
? sortedStates.warningStates[0]
: { state: WARNING_STATE, message: 'Multiple warnings', details: 'Cluster health is degrated' };
}

return healthState;
};

export const Health = ({ k8sHealth, kubevirtHealth, cephHealth, LoadingComponent }) => {
const k8sHealthState = getK8sHealthState(k8sHealth);
const kubevirtHealthState = getKubevirtHealthState(kubevirtHealth);
const cephHealthState = getOCSHealthState(cephHealth);

const healthState = getClusterHealth([k8sHealthState, kubevirtHealthState, cephHealthState]);

return (
<DashboardCard>
<DashboardCardHeader>
<DashboardCardTitle>Cluster Health</DashboardCardTitle>
<DashboardCardTitleSeeAll title="Subsystem health">
<SubsystemHealth
k8sHealth={k8sHealthState}
kubevirtHealth={kubevirtHealthState}
cephHealth={cephHealthState}
LoadingComponent={LoadingComponent}
/>
</DashboardCardTitleSeeAll>
</DashboardCardHeader>
<DashboardCardBody isLoading={!(k8sHealth && kubevirtHealth && cephHealth)} LoadingComponent={LoadingComponent}>
<HealthBody>
<HealthItem state={healthState.state} message={healthState.message} details={healthState.details} />
</HealthBody>
</DashboardCardBody>
</DashboardCard>
);
};

Health.defaultProps = {
loaded: false,
k8sHealth: null,
kubevirtHealth: null,
cephHealth: null,
LoadingComponent: InlineLoading,
};

Health.propTypes = {
data: PropTypes.object.isRequired,
loaded: PropTypes.bool,
k8sHealth: PropTypes.object,
kubevirtHealth: PropTypes.object,
cephHealth: PropTypes.object,
LoadingComponent: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
};

const HealthConnected = () => <ClusterOverviewContextGenericConsumer Component={Health} dataPath="healthData" />;

export default HealthConnected;
export const HealthConnected = () => (
<ClusterOverviewContext.Consumer>{props => <Health {...props} />}</ClusterOverviewContext.Consumer>
);
40 changes: 36 additions & 4 deletions src/components/ClusterOverview/Health/fixtures/Health.fixture.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,48 @@
import { Health } from '../Health';

export const healthData = {
data: {
healthy: false,
message: 'Error message',
k8sHealth: {
response: 'ok',
},
cephHealth: {
result: [
{
value: [null, 0],
},
],
},
kubevirtHealth: {
apiserver: {
connectivity: 'ok',
},
},
};

export const healthDataErrors = {
k8sHealth: {
response: 'error',
},
cephHealth: {
result: [
{
value: [null, 0],
},
],
},
kubevirtHealth: {
apiserver: {
connectivity: 'error',
},
},
loaded: true,
};

export default [
{
component: Health,
props: { ...healthData },
},
{
component: Health,
props: { ...healthDataErrors },
},
];
5 changes: 5 additions & 0 deletions src/components/ClusterOverview/Health/tests/Health.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import { Health } from '../Health';
import { default as HealthFixtures } from '../fixtures/Health.fixture';

const testHealthOverview = () => <Health {...HealthFixtures[0].props} />;
const testHealthErrorsOverview = () => <Health {...HealthFixtures[1].props} />;

describe('<Health />', () => {
it('renders correctly', () => {
const component = render(testHealthOverview());
expect(component).toMatchSnapshot();
});
it('renders multiple erros correctly', () => {
const component = render(testHealthErrorsOverview());
expect(component).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,93 @@ exports[`<Health /> renders correctly 1`] = `
>
Cluster Health
</h2>
<button
class="btn btn-link"
type="button"
>
See all
</button>
</div>
<div
class="card-pf-body kubevirt-health__body"
class="card-pf-body"
>
<div
class="kubevirt-health__icon--error kubevirt-health__icon"
>
<span
aria-hidden="true"
class="fa fa-exclamation-circle"
/>
<div>
<div
class="kubevirt-health__item"
>
<div
class="kubevirt-health__icon kubevirt-health__icon--ok"
>
<span
aria-hidden="true"
class="fa fa-check-circle"
/>
</div>
<div
class="kubevirt-health__message"
>
<span
class="kubevirt-health__text"
>
Cluster is healthy
</span>
</div>
</div>
</div>
<span
class="kubevirt-health__text"
</div>
</div>
`;

exports[`<Health /> renders multiple erros correctly 1`] = `
<div
class="card-pf kubevirt-dashboard__card"
>
<div
class="card-pf-heading kubevirt-dashboard__card-heading"
>
<h2
class="card-pf-title kubevirt-dashboard__card-title"
>
Cluster Health
</h2>
<button
class="btn btn-link"
type="button"
>
Error message
</span>
See all
</button>
</div>
<div
class="card-pf-body"
>
<div>
<div
class="kubevirt-health__item"
>
<div
class="kubevirt-health__icon kubevirt-health__icon--error"
>
<span
aria-hidden="true"
class="fa fa-exclamation-circle"
/>
</div>
<div
class="kubevirt-health__message"
>
<span
class="kubevirt-health__text"
>
Multiple errors
</span>
<div
class="kubevirt-health__text kubevirt-health__subtitle"
>
Cluster health is degrated
</div>
</div>
</div>
</div>
</div>
</div>
`;
Loading