open-consul/ui-v2/app/utils/components/discovery-chain/index.js

106 lines
3.4 KiB
JavaScript

const getNodesByType = function(nodes = {}, type) {
return Object.values(nodes).filter(item => item.Type === type);
};
const findResolver = function(resolvers, service, nspace = 'default', dc) {
if (typeof resolvers[service] === 'undefined') {
resolvers[service] = {
ID: `${service}.${nspace}.${dc}`,
Name: service,
Children: [],
};
}
return resolvers[service];
};
export const getAlternateServices = function(targets, a) {
let type;
const Targets = targets.map(function(b) {
// TODO: this isn't going to work past namespace for services
// with dots in the name, but by the time that becomes an issue
// we might have more data from the endpoint so we don't have to guess
// right now the backend also doesn't support dots in service names
const [aRev, bRev] = [a, b].map(item => item.split('.').reverse());
const types = ['Datacenter', 'Namespace', 'Service', 'Subset'];
return bRev.find(function(item, i) {
const res = item !== aRev[i];
if (res) {
type = types[i];
}
return res;
});
});
return {
Type: type,
Targets: Targets,
};
};
export const getSplitters = function(nodes) {
return getNodesByType(nodes, 'splitter').map(function(item) {
// Splitters need IDs adding so we can find them in the DOM later
item.ID = `splitter:${item.Name}`;
return item;
});
};
export const getRoutes = function(nodes, uid) {
return getNodesByType(nodes, 'router').reduce(function(prev, item) {
return prev.concat(
item.Routes.map(function(route, i) {
// Routes also have IDs added via createRoute
return createRoute(route, item.Name, uid);
})
);
}, []);
};
export const getResolvers = function(dc, nspace = 'default', targets = {}, nodes = {}) {
const resolvers = {};
Object.values(targets).forEach(target => {
const node = nodes[`resolver:${target.ID}`];
const resolver = findResolver(resolvers, target.Service, nspace, dc);
// We use this to figure out whether this target is a redirect target
const alternate = getAlternateServices([target.ID], `service.${nspace}.${dc}`);
let failovers;
// Figure out the failover type
if (typeof node.Resolver.Failover !== 'undefined') {
failovers = getAlternateServices(node.Resolver.Failover.Targets, target.ID);
}
switch (true) {
// This target is a redirect
case alternate.Type !== 'Service':
resolver.Children.push({
Redirect: true,
ID: target.ID,
Name: target[alternate.Type],
});
break;
// This target is a Subset
case typeof target.ServiceSubset !== 'undefined':
resolver.Children.push({
Subset: true,
ID: target.ID,
Name: target.ServiceSubset,
Filter: target.Subset.Filter,
...(typeof failovers !== 'undefined'
? {
Failover: failovers,
}
: {}),
});
break;
// This target is just normal service that might have failovers
default:
if (typeof failovers !== 'undefined') {
resolver.Failover = failovers;
}
}
});
return Object.values(resolvers);
};
export const createRoute = function(route, router, uid) {
return {
...route,
Default: typeof route.Definition.Match === 'undefined',
ID: `route:${router}-${uid(route.Definition)}`,
};
};