style: lint

This commit is contained in:
Sérgio Ramos 2017-07-26 15:28:14 +01:00
parent e8600b2c0d
commit b865a1d118
47 changed files with 1700 additions and 1358 deletions

View File

@ -1,17 +1,24 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'styled-components';
import { ModalHeading, ModalText, Button } from 'joyent-ui-toolkit'; import { ModalHeading, ModalText, Button } from 'joyent-ui-toolkit';
const DeploymentGroupDelete = ({ deploymentGroup, onCancelClick, onConfirmClick }) => const DeploymentGroupDelete = ({
deploymentGroup,
onCancelClick,
onConfirmClick
}) =>
<div> <div>
<ModalHeading> <ModalHeading>
Deleting a deployment group: <br /> {deploymentGroup.name} Deleting a deployment group: <br /> {deploymentGroup.name}
</ModalHeading> </ModalHeading>
<ModalText marginBottom="3"> <ModalText marginBottom="3">
Deleting a deployment group will also remove all of the services and instances associated with that deployment group. Are you sure you want to continue? Deleting a deployment group will also remove all of the services and
instances associated with that deployment group. Are you sure you want to
continue?
</ModalText> </ModalText>
<Button onClick={onCancelClick} secondary>Cancel</Button> <Button onClick={onCancelClick} secondary>
Cancel
</Button>
<Button onClick={onConfirmClick}>Delete deployment group</Button> <Button onClick={onConfirmClick}>Delete deployment group</Button>
</div>; </div>;

View File

@ -109,7 +109,9 @@ const InstanceCard = ({
<StyledCard collapsed={true} key={instance.uuid}> <StyledCard collapsed={true} key={instance.uuid}>
<CardView> <CardView>
<CardMeta onClick={toggleCollapsed}> <CardMeta onClick={toggleCollapsed}>
<CardTitle>{instance.name}</CardTitle> <CardTitle>
{instance.name}
</CardTitle>
<CardDescription> <CardDescription>
<StatusBadge status={instance.status} /> <StatusBadge status={instance.status} />
</CardDescription> </CardDescription>

View File

@ -135,8 +135,12 @@ export const Name = ({ handleSubmit, onCancel, dirty }) =>
</Col> </Col>
</Row> </Row>
<ButtonsRow> <ButtonsRow>
<Button onClick={onCancel} secondary>Cancel</Button> <Button onClick={onCancel} secondary>
<Button type="submit" disabled={!dirty}>Next</Button> Cancel
</Button>
<Button type="submit" disabled={!dirty}>
Next
</Button>
</ButtonsRow> </ButtonsRow>
</form>; </form>;
@ -150,7 +154,9 @@ export const Manifest = ({
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<Field name="manifest" defaultValue={defaultValue} component={MEditor} /> <Field name="manifest" defaultValue={defaultValue} component={MEditor} />
<ButtonsRow> <ButtonsRow>
<Button onClick={onCancel} secondary>Cancel</Button> <Button onClick={onCancel} secondary>
Cancel
</Button>
<Button <Button
disabled={!(dirty || !loading || defaultValue.length)} disabled={!(dirty || !loading || defaultValue.length)}
type="submit" type="submit"
@ -213,8 +219,12 @@ export const Environment = ({
<Field name="environment" defaultValue={defaultValue} component={EEditor} /> <Field name="environment" defaultValue={defaultValue} component={EEditor} />
<Files files={files} onRemoveFile={onRemoveFile} loading={loading} /> <Files files={files} onRemoveFile={onRemoveFile} loading={loading} />
<ButtonsRow> <ButtonsRow>
<Button onClick={onCancel} secondary>Cancel</Button> <Button onClick={onCancel} secondary>
<Button type="button" onClick={onAddFile} secondary>Add File</Button> Cancel
</Button>
<Button type="button" onClick={onAddFile} secondary>
Add File
</Button>
<Button <Button
disabled={!(dirty || !loading || defaultValue.length)} disabled={!(dirty || !loading || defaultValue.length)}
type="submit" type="submit"
@ -228,10 +238,18 @@ export const Review = ({ handleSubmit, onCancel, dirty, ...state }) => {
const serviceList = forceArray(state.services).map(({ name, config }) => const serviceList = forceArray(state.services).map(({ name, config }) =>
<ServiceCard key={name}> <ServiceCard key={name}>
<Dl> <Dl>
<dt><ServiceName>{name}</ServiceName></dt> <dt>
<dt><ImageTitle>Image:</ImageTitle> <Image>{config.image}</Image></dt> <ServiceName>
{name}
</ServiceName>
</dt>
<dt>
<ImageTitle>Image:</ImageTitle> <Image>{config.image}</Image>
</dt>
{config.environment.length {config.environment.length
? <dt><ImageTitle>Environment:</ImageTitle></dt> ? <dt>
<ImageTitle>Environment:</ImageTitle>
</dt>
: undefined} : undefined}
{config.environment.length {config.environment.length
? <SimpleTable ? <SimpleTable

View File

@ -4,7 +4,11 @@ import PropTypes from 'prop-types';
import { P } from 'joyent-ui-toolkit'; import { P } from 'joyent-ui-toolkit';
const ErrorMessage = ({ message = "Ooops, there's been an error!!!" }) => { const ErrorMessage = ({ message = "Ooops, there's been an error!!!" }) => {
return <P>{message}</P>; return (
<P>
{message}
</P>
);
}; };
ErrorMessage.propTypes = { ErrorMessage.propTypes = {

View File

@ -23,11 +23,18 @@ const BreadcrumbContainer = styled.div`
const getBreadcrumbItems = (...links) => const getBreadcrumbItems = (...links) =>
forceArray(links).map(({ pathname, name }, i) => { forceArray(links).map(({ pathname, name }, i) => {
const item = i + 1 >= links.length const item =
? name i + 1 >= links.length
: <BreadcrumbLink to={pathname}>{name}</BreadcrumbLink>; ? name
: <BreadcrumbLink to={pathname}>
{name}
</BreadcrumbLink>;
return <BreadcrumbItem key={name}>{item}</BreadcrumbItem>; return (
<BreadcrumbItem key={name}>
{item}
</BreadcrumbItem>
);
}); });
const NavBreadcrumb = ({ links = [] }) => const NavBreadcrumb = ({ links = [] }) =>

View File

@ -19,8 +19,12 @@ const NavHeader = ({ datacenter, username }) =>
<StyledLogo src={Logo} /> <StyledLogo src={Logo} />
</Link> </Link>
</HeaderBrand> </HeaderBrand>
<HeaderItem>{datacenter}</HeaderItem> <HeaderItem>
<HeaderItem>{username}</HeaderItem> {datacenter}
</HeaderItem>
<HeaderItem>
{username}
</HeaderItem>
</Header>; </Header>;
NavHeader.propTypes = { NavHeader.propTypes = {

View File

@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'styled-components';
import { ModalHeading, ModalText, Button } from 'joyent-ui-toolkit'; import { ModalHeading, ModalText, Button } from 'joyent-ui-toolkit';
const propTypes = { const propTypes = {
@ -15,10 +14,12 @@ const ServiceDelete = ({ service, onCancelClick, onConfirmClick }) =>
Deleting a service: <br /> {service.name} Deleting a service: <br /> {service.name}
</ModalHeading> </ModalHeading>
<ModalText marginBottom="3"> <ModalText marginBottom="3">
Deleting a service can lead to irreverasable loss of data and failures Deleting a service can lead to irreverasable loss of data and failures in
in your application. Are you sure you want to continue? your application. Are you sure you want to continue?
</ModalText> </ModalText>
<Button onClick={onCancelClick} secondary>Cancel</Button> <Button onClick={onCancelClick} secondary>
Cancel
</Button>
<Button onClick={onConfirmClick}>Delete service</Button> <Button onClick={onConfirmClick}>Delete service</Button>
</div>; </div>;

View File

@ -1,7 +1,5 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'styled-components';
import unitcalc from 'unitcalc';
import { ModalHeading, ModalText, Button } from 'joyent-ui-toolkit'; import { ModalHeading, ModalText, Button } from 'joyent-ui-toolkit';
import { import {
@ -19,8 +17,13 @@ const ServiceScale = ({
pristine pristine
}) => }) =>
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<ModalHeading>Scaling a service: <br />{service.name}</ModalHeading> <ModalHeading>
<ModalText>Choose how many instances of a service you want to have running.</ModalText> Scaling a service: <br />
{service.name}
</ModalHeading>
<ModalText>
Choose how many instances of a service you want to have running.
</ModalText>
<FormGroup <FormGroup
name="replicas" name="replicas"
normalize={NumberInputNormalize({ minValue: 1 })} normalize={NumberInputNormalize({ minValue: 1 })}
@ -29,7 +32,9 @@ const ServiceScale = ({
<FormMeta /> <FormMeta />
<NumberInput minValue={1} /> <NumberInput minValue={1} />
</FormGroup> </FormGroup>
<Button secondary onClick={onCancelClick}>Cancel</Button> <Button secondary onClick={onCancelClick}>
Cancel
</Button>
<Button type="submit" disabled={pristine || invalid} secondary> <Button type="submit" disabled={pristine || invalid} secondary>
Scale Scale
</Button> </Button>

View File

@ -5,7 +5,6 @@ import styled from 'styled-components';
import { import {
Card, Card,
CardView, CardView,
CardMeta,
CardTitle, CardTitle,
CardSubTitle, CardSubTitle,
CardDescription, CardDescription,
@ -16,7 +15,11 @@ import {
Anchor Anchor
} from 'joyent-ui-toolkit'; } from 'joyent-ui-toolkit';
import { InstancesIcon, HealthyIcon, UnhealthyIcon, P } from 'joyent-ui-toolkit'; import {
InstancesIcon,
HealthyIcon,
UnhealthyIcon
} from 'joyent-ui-toolkit';
import Status from './status'; import Status from './status';
@ -37,7 +40,6 @@ const ServiceListItem = ({
service = {}, service = {},
isChild = false isChild = false
}) => { }) => {
const children = service.children const children = service.children
? service.children.map(service => ? service.children.map(service =>
<ServiceListItem <ServiceListItem
@ -101,16 +103,16 @@ const ServiceListItem = ({
const healthyInfo = service.instancesHealthy const healthyInfo = service.instancesHealthy
? <CardInfo ? <CardInfo
icon={<HealthyIcon />} icon={<HealthyIcon />}
iconPosition='left' iconPosition="left"
label='Healthy' label="Healthy"
color='dark' color="dark"
/> />
: <CardInfo : <CardInfo
icon={<UnhealthyIcon />} icon={<UnhealthyIcon />}
iconPosition='left' iconPosition="left"
label='Unhealthy' label="Unhealthy"
color='dark' color="dark"
/> />;
const view = children const view = children
? <CardGroupView> ? <CardGroupView>

View File

@ -55,22 +55,34 @@ const ServicesQuickActions = ({
: instance.status; : instance.status;
}, null); }, null);
const startService = status === 'RUNNING' const startService =
? null status === 'RUNNING'
: <TooltipButton onClick={handleStartClick} disabled={disabled}>Start</TooltipButton>; ? null
: <TooltipButton onClick={handleStartClick} disabled={disabled}>
Start
</TooltipButton>;
const stopService = status === 'STOPPED' const stopService =
? null status === 'STOPPED'
: <TooltipButton onClick={handleStopClick} disabled={disabled}>Stop</TooltipButton>; ? null
: <TooltipButton onClick={handleStopClick} disabled={disabled}>
Stop
</TooltipButton>;
return ( return (
<Tooltip {...p} onBlur={onBlur}> <Tooltip {...p} onBlur={onBlur}>
<TooltipButton onClick={handleScaleClick} disabled={disabled}>Scale</TooltipButton> <TooltipButton onClick={handleScaleClick} disabled={disabled}>
<TooltipButton onClick={handleRestartClick} disabled={disabled}>Restart</TooltipButton> Scale
</TooltipButton>
<TooltipButton onClick={handleRestartClick} disabled={disabled}>
Restart
</TooltipButton>
{startService} {startService}
{stopService} {stopService}
<TooltipDivider /> <TooltipDivider />
<TooltipButton onClick={handleDeleteClick} disabled={disabled}>Delete</TooltipButton> <TooltipButton onClick={handleDeleteClick} disabled={disabled}>
Delete
</TooltipButton>
</Tooltip> </Tooltip>
); );
}; };

View File

@ -24,8 +24,7 @@ const StyledTransitionalStatus = StyledStatus.extend`
`; `;
const ServiceStatus = ({ service }) => { const ServiceStatus = ({ service }) => {
const getInstanceStatuses = instanceStatuses =>
const getInstanceStatuses = (instanceStatuses) =>
instanceStatuses.map((instanceStatus, index) => { instanceStatuses.map((instanceStatus, index) => {
const { status, count } = instanceStatus; const { status, count } = instanceStatus;
@ -39,19 +38,15 @@ const ServiceStatus = ({ service }) => {
}); });
return service.transitionalStatus return service.transitionalStatus
? ( ? <StyledStatusContainer>
<StyledStatusContainer>
<StatusLoader /> <StatusLoader />
<StyledTransitionalStatus> <StyledTransitionalStatus>
{ service.status ? service.status.toLowerCase() : '' } {service.status ? service.status.toLowerCase() : ''}
</StyledTransitionalStatus> </StyledTransitionalStatus>
</StyledStatusContainer> </StyledStatusContainer>
) : <StyledStatusContainer>
: (
<StyledStatusContainer>
{getInstanceStatuses(service.instanceStatuses)} {getInstanceStatuses(service.instanceStatuses)}
</StyledStatusContainer> </StyledStatusContainer>;
);
}; };
ServiceStatus.propTypes = { ServiceStatus.propTypes = {

View File

@ -19,7 +19,10 @@ export default ({
<LayoutContainer> <LayoutContainer>
<H2>Creating deployment group</H2> <H2>Creating deployment group</H2>
{loading && <DeploymentGroupsLoading />} {loading && <DeploymentGroupsLoading />}
{error && <span>{error.toString()}</span>} {error &&
<span>
{error.toString()}
</span>}
<Progress stage={stage} create /> <Progress stage={stage} create />
<ManifestEditOrCreate <ManifestEditOrCreate
manifest={manifest} manifest={manifest}

View File

@ -44,7 +44,10 @@ class DeploymentGroupImport extends Component {
<LayoutContainer> <LayoutContainer>
<H2>Importing deployment group</H2> <H2>Importing deployment group</H2>
{loading && <DeploymentGroupsLoading />} {loading && <DeploymentGroupsLoading />}
{error && <span>{error.toString()}</span>} {error &&
<span>
{error.toString()}
</span>}
</LayoutContainer> </LayoutContainer>
); );
} }

View File

@ -12,7 +12,7 @@ import { ErrorMessage } from '@components/messaging';
import { DeploymentGroupsLoading } from '@components/deployment-groups'; import { DeploymentGroupsLoading } from '@components/deployment-groups';
import DeploymentGroupsQuery from '@graphql/DeploymentGroups.gql'; import DeploymentGroupsQuery from '@graphql/DeploymentGroups.gql';
import DeploymentGroupsImportableQuery from '@graphql/DeploymentGroupsImportable.gql'; import DeploymentGroupsImportableQuery from '@graphql/DeploymentGroupsImportable.gql';
import { H2, H3, Small, IconButton, BinIcon, Button } from 'joyent-ui-toolkit'; import { H2, H3, Small, IconButton, BinIcon } from 'joyent-ui-toolkit';
const Title = H2.extend` const Title = H2.extend`
margin-top: ${remcalc(2)}; margin-top: ${remcalc(2)};
@ -122,7 +122,9 @@ const DeploymentGroupList = ({
<Col xs={12} sm={4} md={3} lg={3} key={slug}> <Col xs={12} sm={4} md={3} lg={3} key={slug}>
<Box> <Box>
<StyledLink to={`${match.path}/${slug}`}> <StyledLink to={`${match.path}/${slug}`}>
<ServiceTitle>{name}</ServiceTitle> <ServiceTitle>
{name}
</ServiceTitle>
</StyledLink> </StyledLink>
<StyledIconButton to={`${match.url}/${slug}/delete`}> <StyledIconButton to={`${match.url}/${slug}/delete`}>
<BinIcon /> <BinIcon />
@ -146,7 +148,9 @@ const DeploymentGroupList = ({
<BoxCreate> <BoxCreate>
<StyledCreateLink to={`${match.path}/~import/${slug}`}> <StyledCreateLink to={`${match.path}/~import/${slug}`}>
<Oval>&#10549;</Oval> <Oval>&#10549;</Oval>
<CreateTitle>{name}</CreateTitle> <CreateTitle>
{name}
</CreateTitle>
</StyledCreateLink> </StyledCreateLink>
</BoxCreate> </BoxCreate>
</Col> </Col>
@ -181,9 +185,10 @@ export default compose(
pollInterval: 1000 pollInterval: 1000
}, },
props: ({ data: { deploymentGroups, loading, error } }) => ({ props: ({ data: { deploymentGroups, loading, error } }) => ({
deploymentGroups: deploymentGroups && deploymentGroups.length deploymentGroups:
? deploymentGroups.filter(dg => dg.status !== 'DELETED') deploymentGroups && deploymentGroups.length
: null, ? deploymentGroups.filter(dg => dg.status !== 'DELETED')
: null,
loading, loading,
error error
}) })

View File

@ -63,12 +63,13 @@ const InstanceListGql = graphql(InstancesQuery, {
}; };
}, },
props: ({ data: { deploymentGroup, loading, error } }) => ({ props: ({ data: { deploymentGroup, loading, error } }) => ({
instances: deploymentGroup && deploymentGroup.services instances:
? deploymentGroup.services.reduce( deploymentGroup && deploymentGroup.services
(instances, service) => instances.concat(service.instances), ? deploymentGroup.services.reduce(
[] (instances, service) => instances.concat(service.instances),
) []
: null, )
: null,
loading, loading,
error error
}) })

View File

@ -357,7 +357,11 @@ class DeploymentGroupEditOrCreate extends Component {
const { error, defaultStage, manifestStage } = this.state; const { error, defaultStage, manifestStage } = this.state;
if (error) { if (error) {
return <span>{error}</span>; return (
<span>
{error}
</span>
);
} }
const { match, create } = this.props; const { match, create } = this.props;

View File

@ -22,28 +22,33 @@ const Manifest = ({
}) => { }) => {
const stage = match.params.stage; const stage = match.params.stage;
const _loading = !loading ? null : <DeploymentGroupsLoading />; const _loading = !loading ? null : <DeploymentGroupsLoading />;
const _error = !error ? null : <span>{error.toString()}</span>; const _error = !error
const _view = loading || !deploymentGroup
? null ? null
: <ManifestEditOrCreate : <span>
manifest={manifest} {error.toString()}
environment={environment} </span>;
deploymentGroup={deploymentGroup}
edit
/>;
const _notice = !error && const _view =
loading || !deploymentGroup
? null
: <ManifestEditOrCreate
manifest={manifest}
environment={environment}
deploymentGroup={deploymentGroup}
edit
/>;
const _notice =
!error &&
!loading && !loading &&
deploymentGroup && deploymentGroup &&
deploymentGroup.imported && deploymentGroup.imported &&
!manifest !manifest
? <span> ? <span>
Since this DeploymentGroup was imported, it doesn&#x27;t have the Since this DeploymentGroup was imported, it doesn&#x27;t have the
initial initial manifest
manifest </span>
</span> : null;
: null;
return ( return (
<LayoutContainer> <LayoutContainer>
@ -78,7 +83,9 @@ export default compose(
slug: props.match.params.deploymentGroup slug: props.match.params.deploymentGroup
} }
}), }),
props: ({ data: { deploymentGroups, loading, error, startPolling, stopPolling } }) => { props: ({
data: { deploymentGroups, loading, error, startPolling, stopPolling }
}) => {
const dgs = forceArray(deploymentGroups); const dgs = forceArray(deploymentGroups);
if (!dgs.length) { if (!dgs.length) {

View File

@ -2,8 +2,8 @@ import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Menu as MenuComponent } from '@components/navigation'; import { Menu as MenuComponent } from '@components/navigation';
const Menu = ({match, sections}) => { const Menu = ({ match, sections }) => {
if(!sections || !sections.length) { if (!sections || !sections.length) {
return null; return null;
} }
@ -13,8 +13,8 @@ const Menu = ({match, sections}) => {
pathname: `${match.url}/${section.pathname}` pathname: `${match.url}/${section.pathname}`
}; };
}); });
return <MenuComponent links={sectionsWithPathnames} /> ; return <MenuComponent links={sectionsWithPathnames} />;
} };
const ConnectedMenu = connect( const ConnectedMenu = connect(
(state, ownProps) => { (state, ownProps) => {

View File

@ -14,11 +14,12 @@ export default graphql(InstancesQuery, {
}; };
}, },
props: ({ data: { deploymentGroup, loading, error } }) => ({ props: ({ data: { deploymentGroup, loading, error } }) => ({
service: deploymentGroup && service:
deploymentGroup &&
deploymentGroup.services && deploymentGroup.services &&
deploymentGroup.services.length deploymentGroup.services.length
? deploymentGroup.services[0] ? deploymentGroup.services[0]
: null, : null,
loading, loading,
error error
}) })

View File

@ -70,8 +70,8 @@ class ServiceList extends Component {
const position = { const position = {
left: left:
buttonRect.left - buttonRect.left -
listRect.left + listRect.left +
(buttonRect.right - buttonRect.left) / 2, (buttonRect.right - buttonRect.left) / 2,
top: buttonRect.bottom - listRect.top top: buttonRect.bottom - listRect.top
}; };

View File

@ -1,16 +1,13 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Col, Row } from 'react-styled-flexboxgrid'; import { Col, Row } from 'react-styled-flexboxgrid';
import styled from 'styled-components';
import remcalc from 'remcalc'; import remcalc from 'remcalc';
import unitcalc from 'unitcalc'; import unitcalc from 'unitcalc';
import { LayoutContainer } from '@components/layout'; import { LayoutContainer } from '@components/layout';
import { import {
Button,
H2, H2,
FormGroup, FormGroup,
Input,
Toggle, Toggle,
ToggleList, ToggleList,
Legend Legend
@ -26,18 +23,6 @@ const PaddedRow = Row.extend`
margin-bottom: ${remcalc(18)} margin-bottom: ${remcalc(18)}
`; `;
const StyledForm = FormGroup.extend`
width: 60%;
float: left;
margin: 0;
`;
const StyledFilter = styled(Input)`
margin: 0;
`;
const handleAddService = () => console.log('Adding a service...');
const ServicesMenu = ({ location, history: { push } }) => { const ServicesMenu = ({ location, history: { push } }) => {
const toggleValue = location.pathname.split('-').pop(); const toggleValue = location.pathname.split('-').pop();
@ -58,8 +43,12 @@ const ServicesMenu = ({ location, history: { push } }) => {
<FormGroup name="service-view" value={toggleValue}> <FormGroup name="service-view" value={toggleValue}>
<StyledLegend>View</StyledLegend> <StyledLegend>View</StyledLegend>
<ToggleList> <ToggleList>
<Toggle value="list" onChange={handleToggle}>List</Toggle> <Toggle value="list" onChange={handleToggle}>
<Toggle value="topology" onChange={handleToggle}>Topology</Toggle> List
</Toggle>
<Toggle value="topology" onChange={handleToggle}>
Topology
</Toggle>
</ToggleList> </ToggleList>
</FormGroup> </FormGroup>
</Col> </Col>

View File

@ -1,7 +1,21 @@
#import "./ServiceInfo.gql" #import "./ServiceInfo.gql"
query config($deploymentGroupName: String!, $type: ManifestType!, $format: ManifestFormat!, $environment: String!, $files: [KeyValueInput]!, $raw: String!) { query config(
config(deploymentGroupName: $deploymentGroupName, type: $type, format: $format, environment: $environment, files: $files, raw: $raw) { $deploymentGroupName: String!
$type: ManifestType!
$format: ManifestFormat!
$environment: String!
$files: [KeyValueInput]!
$raw: String!
) {
config(
deploymentGroupName: $deploymentGroupName
type: $type
format: $format
environment: $environment
files: $files
raw: $raw
) {
...ServiceInfo ...ServiceInfo
config { config {
id id

View File

@ -1,5 +1,19 @@
mutation provisionManifest($deploymentGroupId: ID!, $type: ManifestType!, $format: ManifestFormat!, $environment: String!, $files: [KeyValueInput]!, $raw: String!) { mutation provisionManifest(
provisionManifest(deploymentGroupId: $deploymentGroupId, type: $type, format: $format, environment: $environment, files: $files, raw: $raw) { $deploymentGroupId: ID!
$type: ManifestType!
$format: ManifestFormat!
$environment: String!
$files: [KeyValueInput]!
$raw: String!
) {
provisionManifest(
deploymentGroupId: $deploymentGroupId
type: $type
format: $format
environment: $environment
files: $files
raw: $raw
) {
scale { scale {
serviceName serviceName
replicas replicas

View File

@ -1,7 +1,7 @@
#import "./DeploymentGroupInfo.gql" #import "./DeploymentGroupInfo.gql"
#import "./ServiceInfo.gql" #import "./ServiceInfo.gql"
query Services($deploymentGroupSlug: String!){ query Services($deploymentGroupSlug: String!) {
deploymentGroup(slug: $deploymentGroupSlug) { deploymentGroup(slug: $deploymentGroupSlug) {
...DeploymentGroupInfo ...DeploymentGroupInfo
services { services {

View File

@ -19,9 +19,7 @@ import {
ServicesMenu ServicesMenu
} from '@containers/services'; } from '@containers/services';
import { import { DeploymentGroupDelete } from '@containers/deployment-group';
DeploymentGroupDelete
} from '@containers/deployment-group';
const Container = styled.div` const Container = styled.div`
display: flex; display: flex;
@ -46,7 +44,6 @@ const serviceRedirect = p =>
const Router = ( const Router = (
<BrowserRouter> <BrowserRouter>
<Container> <Container>
<Route path="/" component={Header} /> <Route path="/" component={Header} />
<Switch> <Switch>
@ -70,12 +67,16 @@ const Router = (
path="/deployment-groups/:deploymentGroup/services/:service" path="/deployment-groups/:deploymentGroup/services/:service"
component={Menu} component={Menu}
/> />
<Route path="/deployment-groups/:deploymentGroup" component={Menu} /> <Route path="/deployment-groups/:deploymentGroup" component={Menu} />
</Switch> </Switch>
<Route path="/" exact component={rootRedirect} /> <Route path="/" exact component={rootRedirect} />
<Route path="/deployment-groups" exact component={DeploymentGroupList} /> <Route path="/deployment-groups" exact component={DeploymentGroupList} />
<Route path="/deployment-groups/:deploymentGroup/delete" exact component={DeploymentGroupList} /> <Route
path="/deployment-groups/:deploymentGroup/delete"
exact
component={DeploymentGroupList}
/>
<Route <Route
path="/deployment-groups/:deploymentGroup" path="/deployment-groups/:deploymentGroup"
@ -168,7 +169,6 @@ const Router = (
exact exact
component={ServiceDelete} component={ServiceDelete}
/> />
</Container> </Container>
</BrowserRouter> </BrowserRouter>
); );

View File

@ -6,10 +6,11 @@ export default handleActions(
[toggleServicesQuickActions.toString()]: (state, action) => { [toggleServicesQuickActions.toString()]: (state, action) => {
const { position, service, show } = action.payload; const { position, service, show } = action.payload;
const s = show === undefined const s =
? !state.services.quickActions.service || show === undefined
? !state.services.quickActions.service ||
service.id !== state.services.quickActions.service.id service.id !== state.services.quickActions.service.id
: show; : show;
const quickActions = s const quickActions = s
? { ? {

View File

@ -13,7 +13,7 @@ const deploymentGroupBySlug = deploymentGroupSlug =>
? Object.keys(apollo.data).reduce( ? Object.keys(apollo.data).reduce(
(dg, k) => (dg, k) =>
apollo.data[k].__typename === 'DeploymentGroup' && apollo.data[k].__typename === 'DeploymentGroup' &&
apollo.data[k].slug === deploymentGroupSlug apollo.data[k].slug === deploymentGroupSlug
? apollo.data[k] ? apollo.data[k]
: dg, : dg,
null null
@ -29,7 +29,7 @@ const serviceBySlug = serviceSlug =>
? Object.keys(apollo.data).reduce( ? Object.keys(apollo.data).reduce(
(s, k) => (s, k) =>
apollo.data[k].__typename === 'Service' && apollo.data[k].__typename === 'Service' &&
apollo.data[k].slug === serviceSlug apollo.data[k].slug === serviceSlug
? apollo.data[k] ? apollo.data[k]
: s, : s,
null null
@ -56,9 +56,6 @@ const instancesByServiceId = serviceId =>
// Apollo gql utils // // Apollo gql utils //
const findService = (services, uuid) =>
services.reduce((service, s) => (s.uuid === uuid ? s : service), null);
const activeInstanceStatuses = [ const activeInstanceStatuses = [
'PROVISIONING', 'PROVISIONING',
'READY', 'READY',
@ -77,7 +74,6 @@ const transitionalServiceStatuses = [
]; ];
const getInstanceStatuses = service => { const getInstanceStatuses = service => {
const instanceStatuses = service.instances.reduce((statuses, instance) => { const instanceStatuses = service.instances.reduce((statuses, instance) => {
// if (instance.status !== 'RUNNING') { // if (instance.status !== 'RUNNING') {
if (statuses[instance.status]) { if (statuses[instance.status]) {
@ -107,36 +103,34 @@ const getInstancesActive = instanceStatuses => {
const getInstancesHealthy = instances => { const getInstancesHealthy = instances => {
return instances.reduce( return instances.reduce(
(healthy, instance) => (healthy, instance) => (instance.healthy === 'HEALTHY' ? healthy : false),
instance.healthy === 'HEALTHY' ? healthy : false, true
true
); );
}; };
const getService = (service, index) => { const getService = (service, index) => {
const instanceStatuses = getInstanceStatuses(service); const instanceStatuses = getInstanceStatuses(service);
const instancesActive = getInstancesActive(instanceStatuses); const instancesActive = getInstancesActive(instanceStatuses);
const instancesHealthy = getInstancesHealthy(service.instances); const instancesHealthy = getInstancesHealthy(service.instances);
const transitionalStatus = transitionalServiceStatuses.indexOf(service.status) !== -1; const transitionalStatus =
return ({ transitionalServiceStatuses.indexOf(service.status) !== -1;
index, return {
...service, index,
instanceStatuses, ...service,
instancesActive, instanceStatuses,
instancesHealthy, instancesActive,
transitionalStatus, instancesHealthy,
isConsul: service.slug === 'consul' transitionalStatus,
}); isConsul: service.slug === 'consul'
};
}; };
const processServices = services => { const processServices = services => {
return forceArray(services).reduce((ss, s, i) => { return forceArray(services).reduce((ss, s, i) => {
if (s.status !== 'DELETED') {
if(s.status !== 'DELETED') {
const service = getService(s, i); const service = getService(s, i);
if(s.branches && s.branches.length) { if (s.branches && s.branches.length) {
service.children = processServices(s.branches) service.children = processServices(s.branches);
} }
ss.push(service); ss.push(service);
} }
@ -148,24 +142,28 @@ const processServices = services => {
const processServicesForTopology = services => { const processServicesForTopology = services => {
const processedServices = processServices(services); const processedServices = processServices(services);
const connectedServices = processedServices.reduce( const connectedServices = processedServices.reduce((connections, service) => {
(connections, service) => { if (!service.connections || !service.connections.length) {
if(!service.connections || !service.connections.length) { return connections;
return connections; }
}
const existingConnections = service.connections.reduce((connections, connection) => { const existingConnections = service.connections.reduce(
const connectionExists = processedServices.filter(ps => ps.id === connection).length; (connections, connection) => {
if(connectionExists) { const connectionExists = processedServices.filter(
ps => ps.id === connection
).length;
if (connectionExists) {
connections.push(connection); connections.push(connection);
} }
return connections; return connections;
}, []); },
[]
);
return existingConnections.length return existingConnections.length
? connections.concat(existingConnections).concat(service.id) ? connections.concat(existingConnections).concat(service.id)
: connections : connections;
}, []); }, []);
return processedServices.map(service => ({ return processedServices.map(service => ({
...service, ...service,

View File

@ -4,13 +4,14 @@ import { ApolloClient, createNetworkInterface } from 'react-apollo';
import state from './state'; import state from './state';
import { ui } from './reducers'; import { ui } from './reducers';
const GLOBAL = typeof window === 'object' const GLOBAL =
? window typeof window === 'object'
: { ? window
location: { : {
hostname: '0.0.0.0' location: {
} hostname: '0.0.0.0'
}; }
};
const GQL_PORT = process.env.REACT_APP_GQL_PORT || 80; const GQL_PORT = process.env.REACT_APP_GQL_PORT || 80;
const GQL_HOSTNAME = const GQL_HOSTNAME =

View File

@ -10,6 +10,12 @@ import Header from '@components/navigation/header';
import { Router } from './mocks'; import { Router } from './mocks';
it('renders <Header /> without throwing', () => { it('renders <Header /> without throwing', () => {
const tree = renderer.create(<Router><Header /></Router>).toJSON(); const tree = renderer
.create(
<Router>
<Header />
</Router>
)
.toJSON();
expect(tree).toMatchStyledComponentsSnapshot(); expect(tree).toMatchStyledComponentsSnapshot();
}); });

View File

@ -1,4 +1,7 @@
import React from 'react'; import React from 'react';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
export default ({ children }) => <MemoryRouter>{children}</MemoryRouter>; export default ({ children }) =>
<MemoryRouter>
{children}
</MemoryRouter>;

View File

@ -3,4 +3,6 @@ import { client, store } from '@state/store';
import { ApolloProvider } from 'react-apollo'; import { ApolloProvider } from 'react-apollo';
export default ({ children }) => export default ({ children }) =>
<ApolloProvider client={client} store={store}>{children}</ApolloProvider>; <ApolloProvider client={client} store={store}>
{children}
</ApolloProvider>;

View File

@ -3,4 +3,6 @@ import { ThemeProvider } from 'styled-components';
import { theme } from 'joyent-ui-toolkit'; import { theme } from 'joyent-ui-toolkit';
export default ({ children }) => export default ({ children }) =>
<ThemeProvider theme={theme}>{children}</ThemeProvider>; <ThemeProvider theme={theme}>
{children}
</ThemeProvider>;

View File

@ -46,12 +46,8 @@
"tap-xunit": "^1.7.0" "tap-xunit": "^1.7.0"
}, },
"ava": { "ava": {
"files": [ "files": ["test/*.js"],
"test/*.js" "source": ["src/*.js"],
],
"source": [
"src/*.js"
],
"failFast": true "failFast": true
} }
} }

View File

@ -156,20 +156,17 @@ const deleteDeploymentGroup = options => {
) )
) )
) )
.then(() => { .then(() =>
const deploymentGroup = deploymentGroups Object.assign({}, deploymentGroups.filter(dg => dg.id === dgId).shift(), {
.filter(dg => dg.id === dgId) status: 'DELETING'
.shift(); })
deploymentGroup.status = 'DELETING'; );
return deploymentGroup;
return { deploymentGroupId: dgId };
return getDeploymentGroups({ id: dgId });
});
const timeout = setTimeout(() => { setTimeout(() => {
const deploymentGroup = deploymentGroups const deploymentGroup = deploymentGroups
.filter(dg => dg.id === dgId) .filter(dg => dg.id === dgId)
.shift(); .shift();
deploymentGroup.status = 'DELETED'; deploymentGroup.status = 'DELETED';
}, 5000); }, 5000);
@ -328,9 +325,10 @@ const handleStatusUpdateRequest = (
instancesStatus instancesStatus
) => { ) => {
// this is what we need to delay // this is what we need to delay
const timeout = setTimeout(() => { setTimeout(() => {
updateServiceAndInstancesStatus(serviceId, serviceStatus, instancesStatus); updateServiceAndInstancesStatus(serviceId, serviceStatus, instancesStatus);
}, 5000); }, 5000);
// this is what we'll need to return // this is what we'll need to return
return updateServiceAndInstancesStatus( return updateServiceAndInstancesStatus(
serviceId, serviceId,

View File

@ -31,10 +31,6 @@ const getClient = () =>
}) })
}); });
const close = () => {
client.resetStore();
};
server.stdout.on('data', d => { server.stdout.on('data', d => {
if (/server started at /.test(d)) { if (/server started at /.test(d)) {
resolve(client); resolve(client);
@ -281,7 +277,7 @@ test('should delete DeploymentGroup', async t => {
t.snapshot(JSON.stringify(fDgsBefore.data, null, 2)); t.snapshot(JSON.stringify(fDgsBefore.data, null, 2));
t.snapshot(JSON.stringify(fDgsDirectBefore.data, null, 2)); t.snapshot(JSON.stringify(fDgsDirectBefore.data, null, 2));
const deleted = await client.mutate({ await client.mutate({
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
mutation: gql(await fetchTag('delete-deployment-group')), mutation: gql(await fetchTag('delete-deployment-group')),
variables: { variables: {
@ -396,7 +392,7 @@ test('should scale up', async t => {
} }
}); });
const scale = await client.mutate({ await client.mutate({
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
mutation: gql(await fetchTag('scale')), mutation: gql(await fetchTag('scale')),
variables: { variables: {
@ -456,7 +452,7 @@ test('should scale down', async t => {
} }
}); });
const scaleUp = await client.mutate({ await client.mutate({
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
mutation: gql(await fetchTag('scale')), mutation: gql(await fetchTag('scale')),
variables: { variables: {
@ -475,7 +471,7 @@ test('should scale down', async t => {
} }
}); });
const scaleDown = await client.mutate({ await client.mutate({
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
mutation: gql(await fetchTag('scale')), mutation: gql(await fetchTag('scale')),
variables: { variables: {
@ -520,7 +516,7 @@ test("should delete Service's", async t => {
} }
}); });
const provision = await client.mutate({ await client.mutate({
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
mutation: gql(await fetchTag('provision-manifest')), mutation: gql(await fetchTag('provision-manifest')),
variables: { variables: {
@ -590,7 +586,7 @@ test("should restart Service's", async t => {
} }
}); });
const provision = await client.mutate({ await client.mutate({
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
mutation: gql(await fetchTag('provision-manifest')), mutation: gql(await fetchTag('provision-manifest')),
variables: { variables: {
@ -669,7 +665,7 @@ test("should stop Service's", async t => {
} }
}); });
const provision = await client.mutate({ await client.mutate({
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
mutation: gql(await fetchTag('provision-manifest')), mutation: gql(await fetchTag('provision-manifest')),
variables: { variables: {
@ -748,7 +744,7 @@ test("should start Service's", async t => {
} }
}); });
const provision = await client.mutate({ await client.mutate({
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
mutation: gql(await fetchTag('provision-manifest')), mutation: gql(await fetchTag('provision-manifest')),
variables: { variables: {

View File

@ -1,11 +1,5 @@
mutation scale( mutation scale($serviceId: ID!, $replicas: Int!) {
$serviceId: ID! scale(serviceId: $serviceId, replicas: $replicas) {
$replicas: Int!
) {
scale(
serviceId: $serviceId
replicas: $replicas
) {
id id
} }
} }

View File

@ -23,12 +23,17 @@ module.exports = class DockerComposeClient extends EventEmitter {
} }
provision({ projectName, environment, manifest, files }, cb) { provision({ projectName, environment, manifest, files }, cb) {
this._invoke('up', { this._invoke(
// eslint-disable-next-line camelcase 'up',
project_name: projectName, {
files, // eslint-disable-next-line camelcase
environment project_name: projectName,
}, manifest, cb); files,
environment
},
manifest,
cb
);
} }
scale({ projectName, services, environment, manifest, files }, cb) { scale({ projectName, services, environment, manifest, files }, cb) {

View File

@ -1,6 +1,6 @@
import React from 'react'; // import React from 'react';
import renderer from 'react-test-renderer'; // import renderer from 'react-test-renderer';
import ManifestEditor from '../src/index'; // import ManifestEditor from '../src/index';
// It('renders <ManifestEditor /> correctly', () => { // It('renders <ManifestEditor /> correctly', () => {
// const tree = renderer.create(<ManifestEditor />).toJSON(); // const tree = renderer.create(<ManifestEditor />).toJSON();

View File

@ -63,17 +63,13 @@
"jest": { "jest": {
"testEnvironment": "jsdom", "testEnvironment": "jsdom",
"testRegex": "test/index.js", "testRegex": "test/index.js",
"setupFiles": [ "setupFiles": ["<rootDir>/node_modules/react-scripts/config/polyfills.js"],
"<rootDir>/node_modules/react-scripts/config/polyfills.js"
],
"testEnvironment": "node", "testEnvironment": "node",
"transform": { "transform": {
"^.+\\.(js|jsx)$": "<rootDir>/node_modules/react-scripts/config/jest/babelTransform.js", "^.+\\.(js|jsx)$": "<rootDir>/node_modules/react-scripts/config/jest/babelTransform.js",
"^(?!.*\\.(js|jsx|css|json)$)": "<rootDir>/node_modules/react-scripts/config/jest/fileTransform.js" "^(?!.*\\.(js|jsx|css|json)$)": "<rootDir>/node_modules/react-scripts/config/jest/fileTransform.js"
}, },
"transformIgnorePatterns": [ "transformIgnorePatterns": ["[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$"],
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$"
],
"rootDir": "." "rootDir": "."
} }
} }

View File

@ -18,9 +18,7 @@
"jsnext:main": "dist/pseudo-json-ast.es.js", "jsnext:main": "dist/pseudo-json-ast.es.js",
"module": "dist/pseudo-json-ast.es.js", "module": "dist/pseudo-json-ast.es.js",
"entry": "src/index.js", "entry": "src/index.js",
"files": [ "files": ["dist"],
"dist"
],
"scripts": { "scripts": {
"lint": "eslint . --fix", "lint": "eslint . --fix",
"lint-ci": "eslint . --format junit --output-file $CIRCLE_TEST_REPORTS/lint/pseudo-json-ast.xml", "lint-ci": "eslint . --format junit --output-file $CIRCLE_TEST_REPORTS/lint/pseudo-json-ast.xml",
@ -56,9 +54,7 @@
}, },
"ava": { "ava": {
"tap": true, "tap": true,
"require": [ "require": ["babel-register"],
"babel-register"
],
"babel": "inherit" "babel": "inherit"
} }
} }

View File

@ -20,9 +20,7 @@
"jsnext:main": "dist/pseudo-yaml-ast.es.js", "jsnext:main": "dist/pseudo-yaml-ast.es.js",
"module": "dist/pseudo-yaml-ast.es.js", "module": "dist/pseudo-yaml-ast.es.js",
"entry": "src/index.js", "entry": "src/index.js",
"files": [ "files": ["dist"],
"dist"
],
"scripts": { "scripts": {
"lint": "eslint . --fix", "lint": "eslint . --fix",
"lint-ci": "eslint . --format junit --output-file $CIRCLE_TEST_REPORTS/lint/pseudo-yaml-ast.xml", "lint-ci": "eslint . --format junit --output-file $CIRCLE_TEST_REPORTS/lint/pseudo-yaml-ast.xml",
@ -58,9 +56,7 @@
}, },
"ava": { "ava": {
"tap": true, "tap": true,
"require": [ "require": ["babel-register"],
"babel-register"
],
"babel": "inherit" "babel": "inherit"
} }
} }

View File

@ -3,14 +3,7 @@
"version": "1.0.8", "version": "1.0.8",
"license": "MPL-2.0", "license": "MPL-2.0",
"description": "Calculate the `rem`'s from `px` values", "description": "Calculate the `rem`'s from `px` values",
"keywords": [ "keywords": ["calc", "rem", "em", "px", "pixels", "pixel"],
"calc",
"rem",
"em",
"px",
"pixels",
"pixel"
],
"repository": "github:yldio/joyent-portal", "repository": "github:yldio/joyent-portal",
"main": "dist/remcalc.umd.js", "main": "dist/remcalc.umd.js",
"jsnext:main": "dist/remcalc.es.js", "jsnext:main": "dist/remcalc.es.js",
@ -56,17 +49,13 @@
], ],
"env": { "env": {
"test": { "test": {
"plugins": [ "plugins": ["istanbul"]
"istanbul"
]
} }
} }
}, },
"ava": { "ava": {
"tap": true, "tap": true,
"require": [ "require": ["babel-register"],
"babel-register"
],
"babel": "inherit" "babel": "inherit"
} }
} }

View File

@ -3,10 +3,7 @@
"version": "1.0.8", "version": "1.0.8",
"license": "MPL-2.0", "license": "MPL-2.0",
"description": "Generate a random alpha string", "description": "Generate a random alpha string",
"keywords": [ "keywords": ["random", "alphabetical"],
"random",
"alphabetical"
],
"repository": "github:yldio/joyent-portal", "repository": "github:yldio/joyent-portal",
"main": "dist/rnd-id.umd.js", "main": "dist/rnd-id.umd.js",
"jsnext:main": "dist/rnd-id.es.js", "jsnext:main": "dist/rnd-id.es.js",
@ -49,17 +46,13 @@
], ],
"env": { "env": {
"test": { "test": {
"plugins": [ "plugins": ["istanbul"]
"istanbul"
]
} }
} }
}, },
"ava": { "ava": {
"tap": true, "tap": true,
"require": [ "require": ["babel-register"],
"babel-register"
],
"babel": "inherit" "babel": "inherit"
} }
} }

View File

@ -62,17 +62,13 @@
], ],
"env": { "env": {
"test": { "test": {
"plugins": [ "plugins": ["istanbul"]
"istanbul"
]
} }
} }
}, },
"ava": { "ava": {
"tap": true, "tap": true,
"require": [ "require": ["babel-register"],
"babel-register"
],
"babel": "inherit" "babel": "inherit"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,118 +1,147 @@
[{ [
"uuid": "081a792c-47e0-4439-924b-2efa9788ae9e", {
"id": "nginx", "uuid": "081a792c-47e0-4439-924b-2efa9788ae9e",
"name": "Nginx", "id": "nginx",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "name": "Nginx",
"instances": [""], "project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"metrics": [{ "instances": [""],
"name": "CPU", "metrics": [
"value": "50%" {
}, { "name": "CPU",
"name": "Memory", "value": "50%"
"value": "20%" },
}, { {
"name": "Network", "name": "Memory",
"value": "2.9Kb/sec" "value": "20%"
}], },
"connections": [ {
"be227788-74f1-4e5b-a85f-b5c71cbae8d8" "name": "Network",
], "value": "2.9Kb/sec"
"healthy": true, }
"datacentres": 1 ],
}, { "connections": ["be227788-74f1-4e5b-a85f-b5c71cbae8d8"],
"uuid": "be227788-74f1-4e5b-a85f-b5c71cbae8d8", "healthy": true,
"id": "wordpress", "datacentres": 1
"name": "Wordpress", },
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401", {
"instances": ["", ""], "uuid": "be227788-74f1-4e5b-a85f-b5c71cbae8d8",
"metrics": [{ "id": "wordpress",
"name": "CPU", "name": "Wordpress",
"value": "50%" "project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
}, { "instances": ["", ""],
"name": "Memory", "metrics": [
"value": "20%" {
}, { "name": "CPU",
"name": "Network", "value": "50%"
"value": "2.9Kb/sec" },
}], {
"connections": [ "name": "Memory",
"6a0eee76-c019-413b-9d5f-44712b55b993", "value": "20%"
"6d31aff4-de1e-4042-a983-fbd23d5c530c", },
"4ee4103e-1a52-4099-a48e-01588f597c70" {
], "name": "Network",
"healthy": true, "value": "2.9Kb/sec"
"datacentres": 2 }
}, { ],
"uuid": "6a0eee76-c019-413b-9d5f-44712b55b993", "connections": [
"id": "nfs", "6a0eee76-c019-413b-9d5f-44712b55b993",
"name": "NFS", "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "4ee4103e-1a52-4099-a48e-01588f597c70"
"instances": ["", ""], ],
"metrics": [{ "healthy": true,
"name": "CPU", "datacentres": 2
"value": "50%" },
}, { {
"name": "Memory", "uuid": "6a0eee76-c019-413b-9d5f-44712b55b993",
"value": "20%" "id": "nfs",
}, { "name": "NFS",
"name": "Network", "project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"value": "2.9Kb/sec" "instances": ["", ""],
}], "metrics": [
"healthy": true, {
"datacentres": 2 "name": "CPU",
}, { "value": "50%"
"uuid": "6d31aff4-de1e-4042-a983-fbd23d5c530c", },
"id": "memcached", {
"name": "Memcached", "name": "Memory",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "value": "20%"
"instances": ["", ""], },
"metrics": [{ {
"name": "CPU", "name": "Network",
"value": "50%" "value": "2.9Kb/sec"
}, { }
"name": "Memory", ],
"value": "20%" "healthy": true,
}, { "datacentres": 2
"name": "Network", },
"value": "2.9Kb/sec" {
}], "uuid": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"healthy": true, "id": "memcached",
"datacentres": 2 "name": "Memcached",
}, { "project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"uuid": "4ee4103e-1a52-4099-a48e-01588f597c70", "instances": ["", ""],
"id": "percona", "metrics": [
"name": "Percona", {
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "name": "CPU",
"instances": ["", ""], "value": "50%"
"metrics": [{ },
"name": "CPU", {
"value": "50%" "name": "Memory",
}, { "value": "20%"
"name": "Memory", },
"value": "20%" {
}, { "name": "Network",
"name": "Network", "value": "2.9Kb/sec"
"value": "2.9Kb/sec" }
}], ],
"healthy": true, "healthy": true,
"datacentres": 1 "datacentres": 2
}, { },
"uuid": "97c68055-db88-45c9-ad49-f26da4264777", {
"id": "consul", "uuid": "4ee4103e-1a52-4099-a48e-01588f597c70",
"name": "Consul", "id": "percona",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "name": "Percona",
"instances": ["", ""], "project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"isConsul": true, "instances": ["", ""],
"metrics": [{ "metrics": [
"name": "CPU", {
"value": "50%" "name": "CPU",
}, { "value": "50%"
"name": "Memory", },
"value": "20%" {
}, { "name": "Memory",
"name": "Network", "value": "20%"
"value": "2.9Kb/sec" },
}], {
"healthy": true, "name": "Network",
"datacentres": 2 "value": "2.9Kb/sec"
}] }
],
"healthy": true,
"datacentres": 1
},
{
"uuid": "97c68055-db88-45c9-ad49-f26da4264777",
"id": "consul",
"name": "Consul",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"instances": ["", ""],
"isConsul": true,
"metrics": [
{
"name": "CPU",
"value": "50%"
},
{
"name": "Memory",
"value": "20%"
},
{
"name": "Network",
"value": "2.9Kb/sec"
}
],
"healthy": true,
"datacentres": 2
}
]

View File

@ -57,17 +57,13 @@
], ],
"env": { "env": {
"test": { "test": {
"plugins": [ "plugins": ["istanbul"]
"istanbul"
]
} }
} }
}, },
"ava": { "ava": {
"tap": true, "tap": true,
"require": [ "require": ["babel-register"],
"babel-register"
],
"babel": "inherit" "babel": "inherit"
} }
} }