diff --git a/packages/cp-frontend/src/components/services/list-item.js b/packages/cp-frontend/src/components/services/list-item.js
index 1c4dba0c..e122741b 100644
--- a/packages/cp-frontend/src/components/services/list-item.js
+++ b/packages/cp-frontend/src/components/services/list-item.js
@@ -16,7 +16,7 @@ import {
Anchor
} from 'joyent-ui-toolkit';
-import { InstancesIcon, HealthyIcon, P } from 'joyent-ui-toolkit';
+import { InstancesIcon, HealthyIcon, UnhealthyIcon, P } from 'joyent-ui-toolkit';
import Status from './status';
@@ -97,6 +97,20 @@ const ServiceListItem = ({
;
+ const healthyInfo = service.instancesHealthy
+ ? }
+ iconPosition='left'
+ label='Healthy'
+ color='dark'
+ />
+ : }
+ iconPosition='left'
+ label='Unhealthy'
+ color='dark'
+ />
+
const view = children
?
{children}
@@ -106,12 +120,7 @@ const ServiceListItem = ({
{isChild && subtitle}
- }
- iconPosition="left"
- label="Healthy"
- color="dark"
- />
+ {healthyInfo}
;
diff --git a/packages/cp-frontend/src/graphql/Instances.gql b/packages/cp-frontend/src/graphql/Instances.gql
index 3def1dd3..4b03dd5b 100644
--- a/packages/cp-frontend/src/graphql/Instances.gql
+++ b/packages/cp-frontend/src/graphql/Instances.gql
@@ -10,6 +10,7 @@ query Instances($deploymentGroupSlug: String!, $serviceSlug: String) {
id
name
status
+ healthy
}
}
}
diff --git a/packages/cp-frontend/src/graphql/Services.gql b/packages/cp-frontend/src/graphql/Services.gql
index 5ceeed6e..c446b232 100644
--- a/packages/cp-frontend/src/graphql/Services.gql
+++ b/packages/cp-frontend/src/graphql/Services.gql
@@ -11,6 +11,7 @@ query Services($deploymentGroupSlug: String!){
instances {
id
status
+ healthy
}
}
}
diff --git a/packages/cp-frontend/src/graphql/ServicesDeleteMutation.gql b/packages/cp-frontend/src/graphql/ServicesDeleteMutation.gql
index 6e62f6a3..ab4bb2c7 100644
--- a/packages/cp-frontend/src/graphql/ServicesDeleteMutation.gql
+++ b/packages/cp-frontend/src/graphql/ServicesDeleteMutation.gql
@@ -6,6 +6,7 @@ mutation DeleteServices($ids: [ID]!) {
instances {
id
status
+ healthy
}
}
}
diff --git a/packages/cp-frontend/src/graphql/ServicesStartMutation.gql b/packages/cp-frontend/src/graphql/ServicesStartMutation.gql
index 31ae80a9..1354a530 100644
--- a/packages/cp-frontend/src/graphql/ServicesStartMutation.gql
+++ b/packages/cp-frontend/src/graphql/ServicesStartMutation.gql
@@ -6,6 +6,7 @@ mutation StartServices($ids: [ID]!) {
instances {
id
status
+ healthy
}
}
}
diff --git a/packages/cp-frontend/src/graphql/ServicesStopMutation.gql b/packages/cp-frontend/src/graphql/ServicesStopMutation.gql
index 9f4149ca..ab00ad7b 100644
--- a/packages/cp-frontend/src/graphql/ServicesStopMutation.gql
+++ b/packages/cp-frontend/src/graphql/ServicesStopMutation.gql
@@ -6,6 +6,7 @@ mutation StopServices($ids: [ID]!) {
instances {
id
status
+ healthy
}
}
}
diff --git a/packages/cp-frontend/src/state/selectors.js b/packages/cp-frontend/src/state/selectors.js
index 0bdfd9c7..9770b73c 100644
--- a/packages/cp-frontend/src/state/selectors.js
+++ b/packages/cp-frontend/src/state/selectors.js
@@ -105,16 +105,26 @@ const getInstancesActive = instanceStatuses => {
);
};
+const getInstancesHealthy = instances => {
+ return instances.reduce(
+ (healthy, instance) =>
+ instance.healthy === 'HEALTHY' ? healthy : false,
+ true
+ );
+};
+
const getService = (service, index) => {
const instanceStatuses = getInstanceStatuses(service);
const instancesActive = getInstancesActive(instanceStatuses);
+ const instancesHealthy = getInstancesHealthy(service.instances);
const transitionalStatus = transitionalServiceStatuses.indexOf(service.status) !== -1;
return ({
index,
...service,
instanceStatuses,
instancesActive,
+ instancesHealthy,
transitionalStatus,
isConsul: service.slug === 'consul'
});
diff --git a/packages/cp-gql-mock-server/src/data.json b/packages/cp-gql-mock-server/src/data.json
index 7849d3fc..d9f2cdd2 100644
--- a/packages/cp-gql-mock-server/src/data.json
+++ b/packages/cp-gql-mock-server/src/data.json
@@ -113,77 +113,88 @@
"name": "wordpress_01",
"serviceId": "be227788-74f1-4e5b-a85f-b5c71cbae8d8",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
- "status": "RUNNING"
+ "status": "RUNNING",
+ "healthy": "HEALTHY"
},
{
"id": "0db6db53-de6f-4378-839e-5d5b452fbaf2",
"name": "nfs_01",
"serviceId": "6a0eee76-c019-413b-9d5f-44712b55b993",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
- "status": "RUNNING"
+ "status": "RUNNING",
+ "healthy": "HEALTHY"
},
{
"id": "250c8a6c-7d02-49a9-8abd-e1c22773041d",
"name": "consul",
"serviceId": "97c68055-db88-45c9-ad49-f26da4264777",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
- "status": "RUNNING"
+ "status": "RUNNING",
+ "healthy": "UNHEALTHY"
},
{
"id": "2c921f3a-8bc3-4f57-9cd7-789ebae72061",
"name": "memcache_01",
"serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
- "status": "RUNNING"
+ "status": "RUNNING",
+ "healthy": "HEALTHY"
},
{
"id": "68d3046e-8e34-4f5d-a0e5-db3795a250fd",
"name": "memcache_02",
"serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
- "status": "RUNNING"
+ "status": "RUNNING",
+ "healthy": "HEALTHY"
},
{
"id": "2ea99763-3b44-4179-8393-d66d94961051",
"name": "memcache_03",
"serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
- "status": "RUNNING"
+ "status": "RUNNING",
+ "healthy": "HEALTHY"
},
{
"id": "25f6bc62-63b8-4959-908e-1f6d7ff6341d",
"name": "memcache_04",
"serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
- "status": "RUNNING"
+ "status": "RUNNING",
+ "healthy": "HEALTHY"
},
{
"id": "8be01042-0281-4a77-a357-25979e87bf3d",
"name": "memcache_05",
"serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
- "status": "RUNNING"
+ "status": "RUNNING",
+ "healthy": "HEALTHY"
},
{
"id": "3d652e9d-73e8-4a6f-8171-84fa83740662",
"name": "nginx",
"serviceId": "081a792c-47e0-4439-924b-2efa9788ae9e",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
- "status": "RUNNING"
+ "status": "RUNNING",
+ "healthy": "HEALTHY"
},
{
"id": "c3ec7633-a02b-4615-86a0-9e6faeaae94b",
"name": "percona-primary",
"serviceId": "9572d367-c4ae-4fb1-8ad5-f5e3830e7034",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
- "status": "RUNNING"
+ "status": "RUNNING",
+ "healthy": "UNHEALTHY"
},
{
"id": "c2b5fec2-31e2-41a7-b7fc-cd0bb1822e76",
"name": "percona-secondary",
"serviceId": "c8411ef0-ab39-42cb-a704-d20b170eff31",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
- "status": "RUNNING"
+ "status": "RUNNING",
+ "healthy": "HEALTHY"
}
]
}
diff --git a/packages/ui-toolkit/src/icons/index.js b/packages/ui-toolkit/src/icons/index.js
index b11b14f8..63a0dd2a 100644
--- a/packages/ui-toolkit/src/icons/index.js
+++ b/packages/ui-toolkit/src/icons/index.js
@@ -5,3 +5,4 @@ export { default as ArrowIcon } from './arrow';
export { default as TickIcon } from './tick';
export { default as InstancesIcon } from './instances';
export { default as HealthyIcon } from './healthy';
+export { default as UnhealthyIcon } from './unhealthy';
diff --git a/packages/ui-toolkit/src/icons/unhealthy.js b/packages/ui-toolkit/src/icons/unhealthy.js
new file mode 100644
index 00000000..9c4f8670
--- /dev/null
+++ b/packages/ui-toolkit/src/icons/unhealthy.js
@@ -0,0 +1,7 @@
+import Baseline from '../baseline';
+// eslint-disable-next-line no-unused-vars
+import React from 'react';
+
+import UnhealthyIcon from './svg/icon_error_failure.svg';
+
+export default Baseline(UnhealthyIcon);
diff --git a/packages/ui-toolkit/src/index.js b/packages/ui-toolkit/src/index.js
index d939556a..c341b118 100644
--- a/packages/ui-toolkit/src/index.js
+++ b/packages/ui-toolkit/src/index.js
@@ -100,5 +100,6 @@ export {
MinusIcon,
ArrowIcon,
InstancesIcon,
- HealthyIcon
+ HealthyIcon,
+ UnhealthyIcon
} from './icons';
diff --git a/packages/ui-toolkit/src/topology/index.js b/packages/ui-toolkit/src/topology/index.js
index 32cec7a0..2894caa1 100644
--- a/packages/ui-toolkit/src/topology/index.js
+++ b/packages/ui-toolkit/src/topology/index.js
@@ -14,7 +14,7 @@ import { getNodeRect, calculateLineLayout } from './functions';
const StyledSvg = Svg.extend`
width: 100%;
- height: 1400px;
+ height: 1000px;
`;
/**
@@ -194,7 +194,7 @@ class Topology extends React.Component {
return {
width: windowWidth - 2 * 24,
- height: 1400
+ height: 1000
};
}
diff --git a/packages/ui-toolkit/src/topology/node/info.js b/packages/ui-toolkit/src/topology/node/info.js
index 69b7f0db..76f755a1 100644
--- a/packages/ui-toolkit/src/topology/node/info.js
+++ b/packages/ui-toolkit/src/topology/node/info.js
@@ -8,6 +8,7 @@ import InstancesIcon from './icon-instances.svg';
import { Point } from '../prop-types';
import { GraphText, GraphHealthyCircle } from './shapes';
import HeartIcon from './icon-heart.svg';
+import { HealthyIcon, UnhealthyIcon } from '../../icons';
const StyledInstancesIcon = styled(InstancesIcon)`
fill: ${props => props.theme.white};
@@ -39,7 +40,7 @@ const GraphNodeInfo = ({ data, pos }) => {
datacenter,
instances,
instanceStatuses,
- healthy,
+ instancesHealthy,
isConsul,
instancesActive,
transitionalStatus,
@@ -59,11 +60,13 @@ const GraphNodeInfo = ({ data, pos }) => {
);
+ const healthy = instancesHealthy
+ ? : ;
+
return (
-
-
+ { healthy }
@@ -86,14 +89,7 @@ const GraphNodeInfo = ({ data, pos }) => {
GraphNodeInfo.propTypes = {
data: PropTypes.object.isRequired,
- pos: Point.isRequired/*,
- datacenter: PropTypes.string,
- healthy: PropTypes.bool,
- instances: PropTypes.array,
- instanceStatuses: PropTypes.array,
- pos: Point.isRequired,
- isConsul: PropTypes.bool,
- instancesActive: PropTypes.bool*/
+ pos: Point.isRequired
};
export default Baseline(GraphNodeInfo);
diff --git a/packages/ui-toolkit/src/topology/simulation.js b/packages/ui-toolkit/src/topology/simulation.js
index 040e54e4..51b30ec9 100644
--- a/packages/ui-toolkit/src/topology/simulation.js
+++ b/packages/ui-toolkit/src/topology/simulation.js
@@ -41,20 +41,15 @@ const createLinks = services =>
const createSimulation = (services, svgSize, animationTicks = 0) => {
// This is not going to work given that as well as the d3 layout stuff, other things might be at play too
// We should pass two objects to the components - one for positioning and one for data
- console.log('createSimulation services = ', services);
- console.log('createSimulation services.length = ', services.length);
const nodes = services.map((service, index) => {
- console.log('createSimulation services.map service.id = ', service.id);
- console.log('createSimulation services.map service.connected = ', service.connected);
return ({
id: service.id,
index
})
});
- console.log('createSimulation nodes = ', nodes);
- console.log('createSimulation nodes.length = ', nodes.length);
+
const links = createLinks(services);
- console.log('createSimulation links = ', links);
+
const { width, height } = svgSize;
const nodeRadius = rectRadius(Constants.nodeSizeWithChildren);
@@ -65,7 +60,6 @@ const createSimulation = (services, svgSize, animationTicks = 0) => {
.force('center', forceCenter(width / 2, height / 2));
forcePlayAnimation(simulation, animationTicks);
- console.log('createSimulation nodes = ', nodes);
return {
nodes,