183 lines
4.4 KiB
JavaScript
183 lines
4.4 KiB
JavaScript
import { createSelector } from 'reselect';
|
|
import forceArray from 'force-array';
|
|
|
|
const apollo = state => state.apollo;
|
|
|
|
// Redux selectors //
|
|
|
|
const deploymentGroupBySlug = deploymentGroupSlug =>
|
|
createSelector(
|
|
[apollo],
|
|
apollo =>
|
|
apollo && apollo.data
|
|
? Object.keys(apollo.data).reduce(
|
|
(dg, k) =>
|
|
apollo.data[k].__typename === 'DeploymentGroup' &&
|
|
apollo.data[k].slug === deploymentGroupSlug
|
|
? apollo.data[k]
|
|
: dg,
|
|
null
|
|
)
|
|
: null
|
|
);
|
|
|
|
const serviceBySlug = serviceSlug =>
|
|
createSelector(
|
|
[apollo],
|
|
apollo =>
|
|
apollo && apollo.data
|
|
? Object.keys(apollo.data).reduce(
|
|
(s, k) =>
|
|
apollo.data[k].__typename === 'Service' &&
|
|
apollo.data[k].slug === serviceSlug
|
|
? apollo.data[k]
|
|
: s,
|
|
null
|
|
)
|
|
: null
|
|
);
|
|
|
|
const instancesByServiceId = serviceId =>
|
|
createSelector(
|
|
[apollo],
|
|
apollo =>
|
|
apollo && apollo.data
|
|
? Object.keys(apollo.data).reduce((is, i, k) => {
|
|
if (
|
|
apollo.data[k].__typename === 'Instance' &&
|
|
apollo.data[k].service === serviceId
|
|
) {
|
|
is.push(apollo.data[k]);
|
|
}
|
|
return is;
|
|
}, [])
|
|
: null
|
|
);
|
|
|
|
// Apollo gql utils //
|
|
|
|
const findService = (services, uuid) =>
|
|
services.reduce((service, s) => (s.uuid === uuid ? s : service), null);
|
|
|
|
const activeInstanceStatuses = [
|
|
'PROVISIONING',
|
|
'READY',
|
|
'ACTIVE',
|
|
'RUNNING',
|
|
'STOPPING',
|
|
'INCOMPLETE'
|
|
];
|
|
|
|
const transitionalServiceStatuses = [
|
|
'PROVISIONING',
|
|
'SCALING',
|
|
'STOPPING',
|
|
'DELETING',
|
|
'RESTARTING'
|
|
];
|
|
|
|
const getInstanceStatuses = service => {
|
|
|
|
const instanceStatuses = service.instances.reduce((statuses, instance) => {
|
|
// if (instance.status !== 'RUNNING') {
|
|
if (statuses[instance.status]) {
|
|
statuses[instance.status]++;
|
|
} else {
|
|
statuses[instance.status] = 1;
|
|
}
|
|
// }
|
|
return statuses;
|
|
}, {});
|
|
|
|
return Object.keys(instanceStatuses).map(status => ({
|
|
status,
|
|
count: instanceStatuses[status]
|
|
}));
|
|
};
|
|
|
|
const getInstancesActive = instanceStatuses => {
|
|
return instanceStatuses.reduce(
|
|
(active, instanceStatus) =>
|
|
activeInstanceStatuses.indexOf(instanceStatus.status) === -1
|
|
? active
|
|
: true,
|
|
false
|
|
);
|
|
};
|
|
|
|
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'
|
|
});
|
|
};
|
|
|
|
const processServices = services => {
|
|
return forceArray(services).reduce((ss, s, i) => {
|
|
|
|
if(s.status !== 'DELETED') {
|
|
const service = getService(s, i);
|
|
if(s.branches && s.branches.length) {
|
|
service.children = processServices(s.branches)
|
|
}
|
|
ss.push(service);
|
|
}
|
|
|
|
return ss;
|
|
}, []);
|
|
};
|
|
|
|
const processServicesForTopology = services => {
|
|
const processedServices = processServices(services);
|
|
|
|
const connectedServices = processedServices.reduce(
|
|
(connections, service) => {
|
|
if(!service.connections || !service.connections.length) {
|
|
return connections;
|
|
}
|
|
|
|
const existingConnections = service.connections.reduce((connections, connection) => {
|
|
const connectionExists = processedServices.filter(ps => ps.id === connection).length;
|
|
if(connectionExists) {
|
|
connections.push(connection);
|
|
}
|
|
return connections;
|
|
}, []);
|
|
|
|
return existingConnections.length
|
|
? connections.concat(existingConnections).concat(service.id)
|
|
: connections
|
|
}, []);
|
|
|
|
return processedServices.map(service => ({
|
|
...service,
|
|
connected: connectedServices.indexOf(service.id) !== -1
|
|
}));
|
|
};
|
|
|
|
export {
|
|
deploymentGroupBySlug as deploymentGroupBySlugSelector,
|
|
serviceBySlug as serviceBySlugSelector,
|
|
processServices,
|
|
processServicesForTopology,
|
|
instancesByServiceId
|
|
};
|