feat(my-joy-beta): create instance submit
fixes #989 # Conflicts: # packages/my-joy-beta/src/containers/create-instance/index.js
This commit is contained in:
parent
54d4b61250
commit
9432bfd1a3
@ -11,7 +11,7 @@ const Values = (
|
|||||||
<Margin right={1}>
|
<Margin right={1}>
|
||||||
<Select embedded>
|
<Select embedded>
|
||||||
<option value="equalling">equalling</option>
|
<option value="equalling">equalling</option>
|
||||||
<option value="!equalling">not equalling</option>
|
<option value="not-equalling">not equalling</option>
|
||||||
<option value="containing">containing</option>
|
<option value="containing">containing</option>
|
||||||
<option value="starting">starting with</option>
|
<option value="starting">starting with</option>
|
||||||
<option value="ending">ending with</option>
|
<option value="ending">ending with</option>
|
||||||
@ -51,9 +51,6 @@ export const Rule = rule => (
|
|||||||
</FormGroup>
|
</FormGroup>
|
||||||
{rule['rule-type'] === 'tag' ? (
|
{rule['rule-type'] === 'tag' ? (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<FormGroup name="rule-instance-tag-key-pattern" field={Field}>
|
|
||||||
{Values}
|
|
||||||
</FormGroup>
|
|
||||||
<FormGroup name="rule-instance-tag-key" field={Field}>
|
<FormGroup name="rule-instance-tag-key" field={Field}>
|
||||||
<Input small embedded type="text" required placeholder="key" />
|
<Input small embedded type="text" required placeholder="key" />
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -50,7 +50,7 @@ const parsePartial = (p, index) => {
|
|||||||
|
|
||||||
return <Tag key={index} name={name} value={value} />;
|
return <Tag key={index} name={name} value={value} />;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const Rule = ({ enabled, rule_obj }) => {
|
const Rule = ({ enabled, rule_obj }) => {
|
||||||
const { action, protocol } = rule_obj;
|
const { action, protocol } = rule_obj;
|
||||||
@ -65,23 +65,27 @@ const Rule = ({ enabled, rule_obj }) => {
|
|||||||
<Col xs={3}>
|
<Col xs={3}>
|
||||||
<Flex justifyStart alignCenter contentStretch>
|
<Flex justifyStart alignCenter contentStretch>
|
||||||
<FlexItem>
|
<FlexItem>
|
||||||
<b>From:{' '}</b>
|
<b>From: </b>
|
||||||
|
</FlexItem>
|
||||||
|
<FlexItem grow={1}>
|
||||||
|
<TagList>{froms}</TagList>
|
||||||
</FlexItem>
|
</FlexItem>
|
||||||
<FlexItem grow={1}><TagList>{froms}</TagList></FlexItem>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={3}>
|
<Col xs={3}>
|
||||||
<Flex justifyStart alignCenter contentStretch>
|
<Flex justifyStart alignCenter contentStretch>
|
||||||
<FlexItem>
|
<FlexItem>
|
||||||
<b>To:{' '}</b>
|
<b>To: </b>
|
||||||
|
</FlexItem>
|
||||||
|
<FlexItem grow={1}>
|
||||||
|
<TagList>{tos}</TagList>
|
||||||
</FlexItem>
|
</FlexItem>
|
||||||
<FlexItem grow={1}><TagList>{tos}</TagList></FlexItem>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={2}>
|
<Col xs={2}>
|
||||||
<Flex justifyStart alignCenter contentStretch>
|
<Flex justifyStart alignCenter contentStretch>
|
||||||
<FlexItem>
|
<FlexItem>
|
||||||
<b>Protocol:{' '}</b>
|
<b>Protocol: </b>
|
||||||
</FlexItem>
|
</FlexItem>
|
||||||
<FlexItem grow={1}>{protocol.name}</FlexItem>
|
<FlexItem grow={1}>{protocol.name}</FlexItem>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -89,7 +93,7 @@ const Rule = ({ enabled, rule_obj }) => {
|
|||||||
<Col xs={2}>
|
<Col xs={2}>
|
||||||
<Flex justifyStart alignCenter contentStretch>
|
<Flex justifyStart alignCenter contentStretch>
|
||||||
<FlexItem>
|
<FlexItem>
|
||||||
<b>Ports:{' '}</b>
|
<b>Ports: </b>
|
||||||
</FlexItem>
|
</FlexItem>
|
||||||
<FlexItem grow={1}>{protocol.targets.join(';')}</FlexItem>
|
<FlexItem grow={1}>{protocol.targets.join(';')}</FlexItem>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -97,7 +101,7 @@ const Rule = ({ enabled, rule_obj }) => {
|
|||||||
<Col xs={2}>
|
<Col xs={2}>
|
||||||
<Flex justifyStart alignCenter contentStretch>
|
<Flex justifyStart alignCenter contentStretch>
|
||||||
<FlexItem>
|
<FlexItem>
|
||||||
<b>Action:{' '}</b>
|
<b>Action: </b>
|
||||||
</FlexItem>
|
</FlexItem>
|
||||||
<FlexItem grow={1}>{constantCase(action)}</FlexItem>
|
<FlexItem grow={1}>{constantCase(action)}</FlexItem>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -58,8 +58,7 @@ const Firewall = ({
|
|||||||
tagRules={tagRules}
|
tagRules={tagRules}
|
||||||
enabled={enabled}
|
enabled={enabled}
|
||||||
/>
|
/>
|
||||||
) : null
|
) : null}
|
||||||
}
|
|
||||||
</ReduxForm>
|
</ReduxForm>
|
||||||
) : null}
|
) : null}
|
||||||
{proceeded && !expanded ? (
|
{proceeded && !expanded ? (
|
||||||
@ -85,6 +84,7 @@ export default compose(
|
|||||||
connect(
|
connect(
|
||||||
({ form, values }, ownProps) => ({
|
({ form, values }, ownProps) => ({
|
||||||
...ownProps,
|
...ownProps,
|
||||||
|
proceeded: get(values, 'create-instance-firewall-proceeded', false),
|
||||||
enabled: get(form, `${FORM_NAME}.values.enabled`, false),
|
enabled: get(form, `${FORM_NAME}.values.enabled`, false),
|
||||||
showInactive: get(form, `${FORM_NAME}.values.show-inactive`, false),
|
showInactive: get(form, `${FORM_NAME}.values.show-inactive`, false),
|
||||||
tags: get(values, 'create-instance-tags', [])
|
tags: get(values, 'create-instance-tags', [])
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Margin } from 'styled-components-spacing';
|
import { Margin } from 'styled-components-spacing';
|
||||||
|
import ReduxForm from 'declarative-redux-form';
|
||||||
|
import { stopSubmit, destroy } from 'redux-form';
|
||||||
import remcalc from 'remcalc';
|
import remcalc from 'remcalc';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { graphql, compose } from 'react-apollo';
|
||||||
|
import intercept from 'apr-intercept';
|
||||||
|
import constantCase from 'constant-case';
|
||||||
|
import get from 'lodash.get';
|
||||||
|
import omit from 'lodash.omit';
|
||||||
|
import uniqBy from 'lodash.uniqby';
|
||||||
|
|
||||||
import { ViewContainer, H2, Button, Divider } from 'joyent-ui-toolkit';
|
import { ViewContainer, H2, Button, Divider } from 'joyent-ui-toolkit';
|
||||||
|
|
||||||
@ -13,8 +22,10 @@ import Networks from '@containers/create-instance/networks';
|
|||||||
import Firewall from '@containers/create-instance/firewall';
|
import Firewall from '@containers/create-instance/firewall';
|
||||||
import CNS from '@containers/create-instance/cns';
|
import CNS from '@containers/create-instance/cns';
|
||||||
import Affinity from '@containers/create-instance/affinity';
|
import Affinity from '@containers/create-instance/affinity';
|
||||||
|
import CreateInstanceMutation from '@graphql/create-instance.gql';
|
||||||
|
import parseError from '@state/parse-error';
|
||||||
|
|
||||||
export default ({ step, ...props }) => (
|
const CreateInstance = ({ step, handleSubmit, ...props }) => (
|
||||||
<ViewContainer>
|
<ViewContainer>
|
||||||
<Margin top={4} bottom={4}>
|
<Margin top={4} bottom={4}>
|
||||||
<H2>Create Instances</H2>
|
<H2>Create Instances</H2>
|
||||||
@ -50,9 +61,157 @@ export default ({ step, ...props }) => (
|
|||||||
<Divider height={remcalc(1)} />
|
<Divider height={remcalc(1)} />
|
||||||
) : null}
|
) : null}
|
||||||
<Margin top={7} bottom={10}>
|
<Margin top={7} bottom={10}>
|
||||||
<Button disabled={step !== 'done'} onClick={() => console.log('DONE')}>
|
<ReduxForm form="create-instance" onSubmit={handleSubmit}>
|
||||||
Deploy
|
{({ handleSubmit, submitting }) => (
|
||||||
</Button>
|
<form onSubmit={handleSubmit}>
|
||||||
|
<Button disabled={step !== 'done'} loading={submitting}>
|
||||||
|
Deploy
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
</ReduxForm>
|
||||||
</Margin>
|
</Margin>
|
||||||
</ViewContainer>
|
</ViewContainer>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export default compose(
|
||||||
|
graphql(CreateInstanceMutation, { name: 'createInstance' }),
|
||||||
|
connect(({ form, values }, ownProps) => {
|
||||||
|
const name = get(
|
||||||
|
form,
|
||||||
|
'create-instance-name.values.name',
|
||||||
|
'<instance-name>'
|
||||||
|
);
|
||||||
|
|
||||||
|
const firewall = get(
|
||||||
|
form,
|
||||||
|
'CREATE-INSTANCE-FIREWALL.values.enabled',
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
const image = get(
|
||||||
|
form,
|
||||||
|
'create-instance-image.values.image',
|
||||||
|
'<instance-image>'
|
||||||
|
);
|
||||||
|
|
||||||
|
const pkg = get(
|
||||||
|
form,
|
||||||
|
'create-instance-package.values.package',
|
||||||
|
'<instance-image>'
|
||||||
|
);
|
||||||
|
|
||||||
|
const networks = get(
|
||||||
|
form,
|
||||||
|
'CREATE-INSTANCE-NETWORKS.values',
|
||||||
|
'<instance-image>'
|
||||||
|
);
|
||||||
|
|
||||||
|
const metadata = get(values, 'create-instance-metadata', []);
|
||||||
|
const receivedTags = get(values, 'create-instance-tags', []);
|
||||||
|
const affinity = get(values, 'create-instance-affinity', []);
|
||||||
|
const cns = get(values, 'create-instance-cns-enabled', true);
|
||||||
|
const cnsServices = get(values, 'create-instance-cns-services', null);
|
||||||
|
|
||||||
|
const tags = receivedTags.map(a => omit(a, 'expanded'));
|
||||||
|
|
||||||
|
tags.push({ name: 'triton.cns.disable', value: !cns });
|
||||||
|
|
||||||
|
if (cnsServices && cns) {
|
||||||
|
tags.push({ name: 'triton.cns.services', value: cnsServices.join(',') });
|
||||||
|
}
|
||||||
|
|
||||||
|
const affRules = affinity
|
||||||
|
.map(aff => ({
|
||||||
|
conditional: aff['rule-instance-conditional'],
|
||||||
|
placement: aff['rule-instance-placement'],
|
||||||
|
identity: aff['rule-type'],
|
||||||
|
key: aff['rule-instance-tag-key'],
|
||||||
|
pattern: aff['rule-instance-tag-value-pattern'],
|
||||||
|
value:
|
||||||
|
aff['rule-type'] === 'name'
|
||||||
|
? aff['rule-instance-name']
|
||||||
|
: aff['rule-instance-tag-value']
|
||||||
|
}))
|
||||||
|
.map(({ conditional, placement, identity, key, pattern, value }) => {
|
||||||
|
const type = constantCase(
|
||||||
|
`${conditional}_${placement === 'same' ? 'equal' : 'not_equal'}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const patterns = {
|
||||||
|
equalling: value => value,
|
||||||
|
'not-equalling': `/^!${value}$/`,
|
||||||
|
containing: `/${value}/`,
|
||||||
|
starting: `/^${value}/`,
|
||||||
|
ending: `/${value}$/`
|
||||||
|
};
|
||||||
|
|
||||||
|
const _key = identity === 'name' ? 'instance' : key;
|
||||||
|
const _value = patterns[pattern](value);
|
||||||
|
|
||||||
|
return {
|
||||||
|
type,
|
||||||
|
key: _key,
|
||||||
|
value: _value
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
forms: Object.keys(form), // improve this
|
||||||
|
name: name.toLowerCase(),
|
||||||
|
pkg,
|
||||||
|
image,
|
||||||
|
affinity: affRules,
|
||||||
|
metadata: metadata.map(a => omit(a, 'expanded')),
|
||||||
|
tags: uniqBy(tags, 'name'),
|
||||||
|
firewall_enabled: firewall,
|
||||||
|
networks: Object.keys(networks).filter(network => networks[network])
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
connect(null, (dispatch, ownProps) => {
|
||||||
|
const {
|
||||||
|
name,
|
||||||
|
pkg,
|
||||||
|
image,
|
||||||
|
affinity,
|
||||||
|
metadata,
|
||||||
|
tags,
|
||||||
|
firewall_enabled,
|
||||||
|
networks,
|
||||||
|
forms,
|
||||||
|
createInstance,
|
||||||
|
history
|
||||||
|
} = ownProps;
|
||||||
|
|
||||||
|
return {
|
||||||
|
handleSubmit: async () => {
|
||||||
|
const [err, res] = await intercept(
|
||||||
|
createInstance({
|
||||||
|
variables: {
|
||||||
|
name,
|
||||||
|
package: pkg,
|
||||||
|
image,
|
||||||
|
affinity,
|
||||||
|
metadata,
|
||||||
|
tags,
|
||||||
|
firewall_enabled,
|
||||||
|
networks
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
return dispatch(
|
||||||
|
stopSubmit(TABLE_FORM_NAME, {
|
||||||
|
_error: parseError(err)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(forms.map(name => destroy(name)));
|
||||||
|
|
||||||
|
history.push(`/instances/${res.data.createMachine.name}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})
|
||||||
|
)(CreateInstance);
|
||||||
|
@ -150,7 +150,6 @@ const Snapshots = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withRouter,
|
|
||||||
graphql(StartSnapshot, { name: 'start' }),
|
graphql(StartSnapshot, { name: 'start' }),
|
||||||
graphql(RemoveSnapshot, { name: 'remove' }),
|
graphql(RemoveSnapshot, { name: 'remove' }),
|
||||||
graphql(CreateSnapshotMutation, { name: 'createSnapshot' }),
|
graphql(CreateSnapshotMutation, { name: 'createSnapshot' }),
|
||||||
|
40
packages/my-joy-beta/src/graphql/create-instance.gql
Normal file
40
packages/my-joy-beta/src/graphql/create-instance.gql
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
mutation createInstance(
|
||||||
|
$name: String!
|
||||||
|
$package: ID!
|
||||||
|
$image: ID!
|
||||||
|
$networks: [ID]
|
||||||
|
$affinity: [AffinityRule]
|
||||||
|
$metadata: [KeyValueInput]
|
||||||
|
$tags: [KeyValueInput]
|
||||||
|
$firewall_enabled: Boolean
|
||||||
|
) {
|
||||||
|
createMachine(
|
||||||
|
name: $name
|
||||||
|
package: $package
|
||||||
|
image: $image
|
||||||
|
networks: $networks
|
||||||
|
affinity: $affinity
|
||||||
|
metadata: $metadata
|
||||||
|
tags: $tags
|
||||||
|
firewall_enabled: $firewall_enabled
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
state
|
||||||
|
brand
|
||||||
|
name
|
||||||
|
created
|
||||||
|
updated
|
||||||
|
primary_ip
|
||||||
|
ips
|
||||||
|
docker
|
||||||
|
dns_names
|
||||||
|
compute_node
|
||||||
|
image {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
package {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user