2018-01-11 22:26:42 +02:00
|
|
|
import React, { Fragment } from 'react';
|
2018-01-17 22:11:42 +02:00
|
|
|
import { compose, graphql } from 'react-apollo';
|
2018-01-11 22:26:42 +02:00
|
|
|
import ReduxForm from 'declarative-redux-form';
|
|
|
|
import { destroy } from 'redux-form';
|
|
|
|
import { connect } from 'react-redux';
|
|
|
|
import get from 'lodash.get';
|
|
|
|
import { Margin, Padding } from 'styled-components-spacing';
|
|
|
|
import Flex from 'styled-flex-component';
|
|
|
|
import { set } from 'react-redux-values';
|
2018-01-17 22:11:42 +02:00
|
|
|
import punycode from 'punycode';
|
2018-01-11 22:26:42 +02:00
|
|
|
import remcalc from 'remcalc';
|
|
|
|
|
|
|
|
import {
|
|
|
|
CnsIcon,
|
|
|
|
P,
|
|
|
|
Card,
|
|
|
|
H3,
|
|
|
|
Button,
|
|
|
|
FormGroup,
|
|
|
|
FormLabel,
|
|
|
|
Toggle,
|
|
|
|
Divider,
|
2018-01-17 22:11:42 +02:00
|
|
|
TagList,
|
|
|
|
StatusLoader
|
2018-01-11 22:26:42 +02:00
|
|
|
} from 'joyent-ui-toolkit';
|
|
|
|
|
2018-01-17 22:11:42 +02:00
|
|
|
import getAccount from '../../graphql/get-account.gql';
|
|
|
|
|
2018-01-11 22:26:42 +02:00
|
|
|
import {
|
|
|
|
Hostname,
|
|
|
|
Header,
|
|
|
|
AddServiceForm,
|
|
|
|
HostnamesHeader
|
|
|
|
} from '@components/create-instance/cns';
|
2018-01-08 17:13:05 +02:00
|
|
|
|
2018-01-11 22:26:42 +02:00
|
|
|
import Title from '@components/create-instance/title';
|
|
|
|
import Tag from '@components/instances/tags';
|
2018-01-15 19:23:32 +02:00
|
|
|
import Description from '@components/create-instance/description';
|
2018-01-11 22:26:42 +02:00
|
|
|
|
|
|
|
const CNS_FORM = 'create-instance-cns';
|
|
|
|
|
|
|
|
const CNSContainer = ({
|
|
|
|
submitted,
|
|
|
|
expanded,
|
|
|
|
proceeded,
|
2018-01-08 17:13:05 +02:00
|
|
|
serviceNames = [],
|
2018-01-11 22:26:42 +02:00
|
|
|
instanceName,
|
|
|
|
cnsEnabled = true,
|
|
|
|
hostnames = [],
|
|
|
|
handleNext,
|
|
|
|
handleEdit,
|
|
|
|
handleToggleCnsEnabled,
|
|
|
|
handleAddService,
|
2018-01-17 22:11:42 +02:00
|
|
|
handleRemoveService,
|
|
|
|
loading
|
2018-01-11 22:26:42 +02:00
|
|
|
}) => (
|
|
|
|
<Fragment>
|
2018-01-18 16:46:49 +02:00
|
|
|
<Title onClick={!expanded && !proceeded && handleEdit} icon={<CnsIcon />}>
|
|
|
|
Container Name Service
|
|
|
|
</Title>
|
2018-01-11 22:26:42 +02:00
|
|
|
{expanded ? (
|
2018-01-15 19:23:32 +02:00
|
|
|
<Description>
|
|
|
|
Triton CNS is used to automatically update hostnames for your
|
|
|
|
instances*. You can serve multiple instances (with multiple IP
|
|
|
|
addresses) under the same hostname by matching the CNS service names.{' '}
|
|
|
|
<a
|
|
|
|
href="https://docs.joyent.com/private-cloud/install/cns"
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
>
|
|
|
|
Read the docs
|
|
|
|
</a>
|
|
|
|
</Description>
|
2018-01-11 22:26:42 +02:00
|
|
|
) : null}
|
2018-01-16 13:54:22 +02:00
|
|
|
<div>
|
|
|
|
{expanded && cnsEnabled ? (
|
|
|
|
<Card>
|
|
|
|
<Padding all={4} bottom={0}>
|
|
|
|
<Header />
|
2018-01-17 22:11:42 +02:00
|
|
|
{loading ? (
|
|
|
|
<Margin all={2}>
|
|
|
|
{' '}
|
|
|
|
<StatusLoader />
|
|
|
|
</Margin>
|
|
|
|
) : (
|
|
|
|
<Flex column>
|
|
|
|
{hostnames
|
|
|
|
.filter(({ service }) => !service)
|
|
|
|
.map(({ value, ...hostname }) => (
|
|
|
|
<Hostname key={value} value={value} {...hostname} />
|
|
|
|
))}
|
|
|
|
</Flex>
|
|
|
|
)}
|
2018-01-16 13:54:22 +02:00
|
|
|
<Divider height={remcalc(1)} />
|
|
|
|
<Margin top={4}>
|
2018-01-17 22:11:42 +02:00
|
|
|
<HostnamesHeader />
|
2018-01-16 13:54:22 +02:00
|
|
|
{serviceNames.length ? (
|
2018-01-17 22:11:42 +02:00
|
|
|
<Margin bottom={3}>
|
2018-01-16 13:54:22 +02:00
|
|
|
<FormLabel>Existing CNS service name(s)</FormLabel>
|
2018-01-17 22:11:42 +02:00
|
|
|
<Margin top={1}>
|
2018-01-16 13:54:22 +02:00
|
|
|
<TagList>
|
|
|
|
{serviceNames.map((value, index) => (
|
|
|
|
<Tag
|
|
|
|
active
|
|
|
|
key={index}
|
|
|
|
value={value}
|
|
|
|
onRemoveClick={() => handleRemoveService(index)}
|
|
|
|
/>
|
|
|
|
))}
|
|
|
|
</TagList>
|
|
|
|
</Margin>
|
2018-01-11 22:26:42 +02:00
|
|
|
</Margin>
|
2018-01-16 13:54:22 +02:00
|
|
|
) : null}
|
|
|
|
<ReduxForm
|
|
|
|
form={`${CNS_FORM}-new-service`}
|
|
|
|
destroyOnUnmount={false}
|
|
|
|
forceUnregisterOnUnmount={true}
|
|
|
|
onSubmit={handleAddService}
|
|
|
|
>
|
|
|
|
{props => <AddServiceForm {...props} />}
|
|
|
|
</ReduxForm>
|
|
|
|
<Margin top={4}>
|
|
|
|
<Flex column>
|
|
|
|
{hostnames
|
|
|
|
.filter(({ service }) => service)
|
|
|
|
.map(({ value, ...hostname }) => (
|
|
|
|
<Hostname key={value} value={value} {...hostname} />
|
|
|
|
))}
|
|
|
|
</Flex>
|
2018-01-11 22:26:42 +02:00
|
|
|
</Margin>
|
|
|
|
</Margin>
|
2018-01-16 13:54:22 +02:00
|
|
|
</Padding>
|
|
|
|
</Card>
|
|
|
|
) : null}
|
|
|
|
{expanded ? (
|
|
|
|
<Fragment>
|
|
|
|
<Margin bottom={4} top={4}>
|
|
|
|
<FormGroup name="cns-enabled">
|
|
|
|
<Flex alignCenter>
|
|
|
|
<FormLabel>Disabled CNS</FormLabel>
|
|
|
|
<Toggle checked={cnsEnabled} onChange={handleToggleCnsEnabled}>
|
|
|
|
Enabled CNS
|
|
|
|
</Toggle>
|
|
|
|
</Flex>
|
|
|
|
</FormGroup>
|
2018-01-11 22:26:42 +02:00
|
|
|
</Margin>
|
2018-01-16 13:54:22 +02:00
|
|
|
<Margin bottom={4}>
|
|
|
|
<P>
|
2018-01-17 22:11:42 +02:00
|
|
|
*All hostnames listed here will be confirmed after deployment.
|
2018-01-16 13:54:22 +02:00
|
|
|
</P>
|
|
|
|
</Margin>
|
|
|
|
<Margin bottom={4}>
|
|
|
|
<Button type="button" onClick={handleNext}>
|
|
|
|
Next
|
|
|
|
</Button>
|
|
|
|
</Margin>
|
|
|
|
</Fragment>
|
|
|
|
) : null}
|
|
|
|
{proceeded && !expanded ? (
|
|
|
|
<Fragment>
|
|
|
|
<Margin bottom={4}>
|
|
|
|
<H3>{cnsEnabled ? 'CNS Enabled' : 'CNS Not Enabled'}</H3>
|
|
|
|
</Margin>
|
2018-01-17 22:11:42 +02:00
|
|
|
{cnsEnabled && serviceNames.length ? (
|
2018-01-16 13:54:22 +02:00
|
|
|
<Fragment>
|
|
|
|
<FormLabel>Existing CNS service name(s)</FormLabel>
|
|
|
|
<Margin top={0.5}>
|
|
|
|
<TagList>
|
|
|
|
{serviceNames.map((value, index) => (
|
|
|
|
<Tag key={index} value={value} />
|
|
|
|
))}
|
|
|
|
</TagList>
|
|
|
|
</Margin>
|
|
|
|
</Fragment>
|
|
|
|
) : null}
|
|
|
|
<Margin bottom={4}>
|
|
|
|
<Button type="button" onClick={handleEdit} secondary>
|
|
|
|
Edit
|
|
|
|
</Button>
|
|
|
|
</Margin>
|
|
|
|
</Fragment>
|
|
|
|
) : null}
|
|
|
|
</div>
|
2018-01-11 22:26:42 +02:00
|
|
|
</Fragment>
|
|
|
|
);
|
|
|
|
|
|
|
|
export default compose(
|
2018-01-17 22:11:42 +02:00
|
|
|
graphql(getAccount, {
|
|
|
|
props: ({ data: { loading, account: { id } = [] } }) => ({
|
|
|
|
loading,
|
|
|
|
id
|
|
|
|
})
|
|
|
|
}),
|
|
|
|
connect(({ form, values }, { id }) => {
|
2018-01-11 22:26:42 +02:00
|
|
|
const instanceName = get(
|
|
|
|
form,
|
|
|
|
'create-instance-name.values.name',
|
|
|
|
'<instance-name>'
|
|
|
|
);
|
2018-01-08 17:13:05 +02:00
|
|
|
|
2018-01-11 22:26:42 +02:00
|
|
|
const serviceNames = get(values, `${CNS_FORM}-services`, []);
|
|
|
|
|
2018-01-17 22:11:42 +02:00
|
|
|
// REPLACE WITH DATA CENTER
|
2018-01-11 22:26:42 +02:00
|
|
|
const dataCenter = 'us-east-1';
|
|
|
|
|
|
|
|
const hostnames = [
|
|
|
|
{
|
2018-01-17 22:11:42 +02:00
|
|
|
values: [`${instanceName}.inst.${id}.${dataCenter}.triton.zone`],
|
2018-01-11 22:26:42 +02:00
|
|
|
public: true
|
|
|
|
},
|
|
|
|
{
|
2018-01-17 22:11:42 +02:00
|
|
|
values: [`${instanceName}.inst.${id}.${dataCenter}.cns.joyent.com`]
|
2018-01-11 22:26:42 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
values: [],
|
|
|
|
public: true,
|
|
|
|
service: true
|
|
|
|
},
|
|
|
|
{
|
|
|
|
values: [],
|
|
|
|
service: true
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
2018-01-08 17:13:05 +02:00
|
|
|
hostnames.forEach(hostname => {
|
2018-01-11 22:26:42 +02:00
|
|
|
if (!hostname.service) {
|
|
|
|
return hostname;
|
|
|
|
}
|
|
|
|
|
2018-01-08 17:13:05 +02:00
|
|
|
serviceNames.forEach(name => {
|
2018-01-11 22:26:42 +02:00
|
|
|
const postfix = hostname.public ? '.triton.zone' : '.cns.joyent.com';
|
2018-01-17 22:11:42 +02:00
|
|
|
const value = `${name}.svc.${id}.${dataCenter}${postfix}`;
|
2018-01-11 22:26:42 +02:00
|
|
|
hostname.values.push(value);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
return {
|
|
|
|
cnsEnabled: get(values, `${CNS_FORM}-enabled`, true),
|
|
|
|
instanceName,
|
|
|
|
proceeded: get(values, `${CNS_FORM}-proceeded`, false),
|
|
|
|
hostnames,
|
|
|
|
serviceNames
|
|
|
|
};
|
|
|
|
}),
|
|
|
|
connect(null, (dispatch, { history, cnsEnabled, serviceNames = [] }) => ({
|
|
|
|
handleNext: () => {
|
|
|
|
dispatch(set({ name: `${CNS_FORM}-proceeded`, value: true }));
|
|
|
|
return history.push(`/instances/~create/affinity`);
|
|
|
|
},
|
|
|
|
handleEdit: () => history.push(`/instances/~create/cns`),
|
|
|
|
handleToggleCnsEnabled: ({ target }) =>
|
|
|
|
dispatch(set({ name: `${CNS_FORM}-enabled`, value: !cnsEnabled })),
|
|
|
|
handleAddService: ({ name }) => {
|
2018-01-08 17:13:05 +02:00
|
|
|
const serviceName = punycode
|
|
|
|
.encode(name.toLowerCase().replace(/\s/g, '-'))
|
|
|
|
.replace(/\-$/, '');
|
|
|
|
|
2018-01-11 22:26:42 +02:00
|
|
|
dispatch([
|
|
|
|
destroy(`${CNS_FORM}-new-service`),
|
|
|
|
set({
|
|
|
|
name: `${CNS_FORM}-services`,
|
2018-01-17 22:11:42 +02:00
|
|
|
value: serviceNames.concat(serviceName)
|
2018-01-11 22:26:42 +02:00
|
|
|
})
|
|
|
|
]);
|
|
|
|
},
|
|
|
|
handleRemoveService: index => {
|
|
|
|
serviceNames.splice(index, 1);
|
|
|
|
|
|
|
|
return dispatch(
|
|
|
|
set({ name: `${CNS_FORM}-services`, value: serviceNames.slice() })
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
)(CNSContainer);
|