chore: detach cloudapi-gql

related: #842
This commit is contained in:
Sérgio Ramos 2017-11-02 16:03:31 +00:00 committed by Sérgio Ramos
parent 8a0a0a4457
commit d8f0dec487
34 changed files with 2 additions and 2111 deletions

View File

@ -4,13 +4,7 @@ module.exports = {
'scope-enum': [
2,
'always',
[
'ui-toolkit',
'my-joy-beta',
'cloudapi-gql',
'boilerplate',
'create-instance'
]
['ui-toolkit', 'my-joy-beta', 'boilerplate', 'create-instance']
]
}
};

View File

@ -19,9 +19,6 @@
"test-ci": "lerna run test-ci",
"test": "lerna run test",
"clean": "lerna clean --yes",
"bootstrap": "lerna bootstrap",
"dev": "lerna run dev --stream --parallel --scope my-joy-beta --scope cloudapi-gql",
"start": "lerna run start --stream --parallel --scope my-joy-beta --scope cloudapi-gql",
"commitmsg": "commitlint -e",
"precommit": "cross-env CI=1 redrun -s lint-staged format-staged",
"postinstall": "lerna run prepublish",
@ -66,10 +63,7 @@
"staged-git-files": "0.0.4",
"yargs": "^10.0.3"
},
"workspaces": [
"packages/*",
"prototypes/*"
],
"workspaces": ["packages/*", "prototypes/*"],
"resolutions": {
"lodash": "4.17.4",
"lodash.keys": "4.2.0",

View File

@ -1,3 +0,0 @@
.nyc_output
coverage
doc

View File

@ -1,15 +0,0 @@
{
"extends": "joyent-portal",
"plugins": ["graphql"],
"rules": {
"jsx-a11y/href-no-hash": 0,
"graphql/template-strings": ["error", {
"env": "apollo"
}],
"graphql/named-operations": ["error"],
"graphql/required-fields": ["error", {
"requiredFields": ["id"]
}],
"graphql/capitalized-type-name": ["error"]
}
}

View File

@ -1 +0,0 @@
doc

View File

@ -1,8 +0,0 @@
{
"schemaPath": "src/schema/schema.graphql",
"extensions": {
"endpoints": {
"dev": "http://localhost:4000/graphql"
}
}
}

View File

@ -1,10 +0,0 @@
{
"libs": [
"ecmascript"
],
"plugins": {
"doc_comment": true,
"local-scope": true,
"node": true
}
}

View File

@ -1,53 +0,0 @@
# cloudapi-gql
[![License: MPL 2.0](https://img.shields.io/badge/License-MPL%202.0-brightgreen.svg)](https://opensource.org/licenses/MPL-2.0)
[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg)](https://github.com/RichardLitt/standard-readme)
Server that exposes [CloudApi](https://apidocs.joyent.com/cloudapi/) through
[GraphQL](http://graphql.org).
## Table of Contents
* [Install](#install)
* [Usage](#usage)
* [Todo](#todo)
* [License](#license)
## Install
```
yarn add cloudapi-gql
```
## Usage
```
yarn run start
```
* [GraphiQL](http://0.0.0.0:4000/graphiql)
* [Graphidoc](http://0.0.0.0:4000/doc)
* [Voyager](http://0.0.0.0:4000/voyager)
* [Playground](http://0.0.0.0:4000/playground)
![](https://cldup.com/StGgfIbD3N.png) ![](https://cldup.com/fhpul_AJ13.png)
![](https://cldup.com/A-VwSbvWBe.png) ![](https://cldup.com/08P360Skhx.png)
```
yarn run faker
```
* [GraphQL Faker Interactive Editor](http://0.0.0.0:9002/editor)
* [GraphQL Faker API](http://0.0.0.0:9002/graphql)
![](https://cldup.com/VWadVMorQ0.png)
## Todo
* [ ] Finish missing connections, transforms, and mutations
* [ ] remove node-triton dependency
* [ ] support multiple users on the same server
## License
MPL-2.0

View File

@ -1,56 +0,0 @@
{
"name": "cloudapi-gql",
"version": "2.0.0",
"license": "MPL-2.0",
"repository": "github:yldio/joyent-portal",
"main": "src/schema/index.js",
"scripts": {
"lint": "eslint . --fix --ext .js --ext .graphql",
"fmt":
"prettier --write --single-quote src/**/*.js src/*.js src/**/*.graphql",
"test": "echo 0",
"test-ci": "echo 0",
"start": "PORT=4000 node src/server.js",
"dev": "CORS=1 PORT=4000 nodemon src/server.js",
"fake": "graphql-faker ./src/schema/schema.graphql -p 4000",
"prepublish": "echo 0",
"graphdoc": "graphdoc -s ./src/schema/schema.graphql -o ./doc --force",
"faker": "graphql-faker ./src/schema/schema.graphql"
},
"dependencies": {
"@2fd/graphdoc": "^2.4.0",
"apollo-errors": "^1.5.1",
"apollo-server-hapi": "^1.1.7",
"apr-awaitify": "^1.0.4",
"boom": "^6.0.0",
"bunyan": "^1.8.12",
"dotenv": "^4.0.0",
"execa": "^0.8.0",
"force-array": "^3.1.0",
"good": "^7.3.0",
"good-console": "^6.4.0",
"good-squeeze": "^5.0.2",
"graphql-playground": "^1.0.33",
"graphql-tools": "^2.6.1",
"graphql-voyager": "^1.0.0-rc.9",
"hapi": "^16.6.2",
"hasha": "^3.0.0",
"inert": "^4.2.1",
"lodash.get": "^4.4.2",
"node-fetch": "^1.7.3",
"smartdc-auth": "^2.5.6",
"triton": "^5.4.0"
},
"devDependencies": {
"graphql-faker": "^1.5.0",
"eslint": "^4.9.0",
"eslint-config-joyent-portal": "^3.2.0",
"eslint-plugin-graphql": "^1.4.0-1",
"graphql-faker": "^1.5.0",
"nodemon": "^1.12.1",
"prettier": "^1.7.4"
},
"nodemonConfig": {
"ignore": ["doc/*"]
}
}

View File

@ -1,4 +0,0 @@
const request = require('./request');
module.exports.get = () => request('getAccount');
module.exports.update = ctx => request('updateAccount', ctx);

View File

@ -1,3 +0,0 @@
const { fetch } = require('./request');
module.exports = () => fetch('/:login/config');

View File

@ -1,5 +0,0 @@
const request = require('./request');
module.exports = () => request('listDatacenters');
// this method is useless since it only "returns an HTTP redirect to your client, where the datacenter url is in the Location header"
// module.exports.get = ({ name }) => request.fetch(`/:login/datacenters/${name}`);

View File

@ -1,16 +0,0 @@
{
"BadRequest": "You sent bad HTTP",
"InternalError": "Something went wrong in Triton",
"InUseError": "The object is in use and cannot be operated on",
"InvalidArgument": "You sent bad arguments or a bad value for an argument",
"InvalidCredentials": "Authentication failed",
"InvalidHeader": "You sent a bad HTTP header",
"InvalidVersion": "You sent a bad Api-Version string",
"MissingParameter": "You didn't send a required parameter",
"NotAuthorized": "You don't have access to the requested resource",
"RequestThrottled": "You were throttled",
"RequestTooLarge": "You sent too much request data",
"RequestMoved": "HTTP Redirect",
"ResourceNotFound": "What you asked for wasn't found",
"UnknownError": "Something completely unexpected happened!"
}

View File

@ -1,11 +0,0 @@
const request = require('./request');
module.exports.list = () => request('listFirewallRules', {});
module.exports.listByMachine = ctx => request('listMachineFirewallRules', ctx);
module.exports.listMachines = ctx => request('listFirewallRuleMachines', ctx);
module.exports.get = ({ id }) => request('getFirewallRule', id);
module.exports.create = ctx => request('createFirewallRule', ctx);
module.exports.update = ctx => request('updateFirewallRule', ctx);
module.exports.enable = ctx => request('enableFirewallRule', ctx);
module.exports.disable = ctx => request('disableFirewallRule', ctx);
module.exports.destroy = ctx => request('deleteFirewallRule', ctx);

View File

@ -1,15 +0,0 @@
const request = require('./request');
const transform = ({ os, type, state, ...rest }) =>
Object.assign(rest, {
type: type ? type.toLowerCase() : type,
os: os ? os.toLowerCase() : os,
state: state ? state.toLowerCase() : state
});
module.exports.list = ctx => request('listImages', transform(ctx));
module.exports.get = ctx => request('getImage', ctx);
module.exports.destroy = uuid => request('deleteImage', uuid);
module.exports.export = uuid => request('deleteImage', uuid);
module.exports.create = ctx => request('createImageFromMachine', ctx);
module.exports.update = ctx => request('UpdateImage', ctx);

View File

@ -1,17 +0,0 @@
module.exports = {
account: require('./account'),
keys: require('./keys'),
users: require('./users'),
roles: require('./roles'),
policies: require('./policies'),
config: require('./config'),
datacenters: require('./datacenters'),
services: require('./services'),
images: require('./images'),
packages: require('./packages'),
machines: require('./machines'),
firewall: require('./firewall-rules'),
vlans: require('./vlans'),
networks: require('./networks'),
nics: require('./nics')
};

View File

@ -1,19 +0,0 @@
const forceArray = require('force-array');
const hasha = require('hasha');
module.exports.toKeyValue = r =>
r &&
Object.keys(r).map(name => ({
id: hasha(JSON.stringify({ name, value: r[name] })),
name,
value: r[name]
}));
module.exports.fromKeyValue = kvs =>
forceArray(kvs).reduce(
(rest, { name, value }) =>
Object.assign(rest, {
[name]: value
}),
{}
);

View File

@ -1,25 +0,0 @@
const { fetch, client } = require('./request');
const { principal } = client;
const getLoginPrefix = user =>
user && principal.account !== user
? `:login/users/${user}`
: principal.user && principal.user.length
? `:login/users/${principal.user}`
: ':login';
module.exports.list = (opts = {}) =>
fetch(`/${getLoginPrefix(opts.login)}/keys`);
module.exports.get = ({ login, name }) =>
fetch(`/${getLoginPrefix(login)}/keys/${name}`);
module.exports.create = ({ login, name, key }) =>
fetch(`/${getLoginPrefix(login)}/keys`, {
method: 'POST',
body: { name, key }
});
module.exports.destroy = ({ login, name }) =>
fetch(`/${getLoginPrefix(login)}/keys/${name}`, { method: 'DELETE' });

View File

@ -1,47 +0,0 @@
const request = require('./request');
const snapshots = {
list: ctx => request('listMachineSnapshots', ctx),
get: ctx => request('getMachineSnapshot', ctx),
create: ctx => request('createMachineSnapshot', ctx),
destroy: ctx => request('deleteMachineSnapshot', ctx)
};
const metadata = {
list: ({ id }) => request.fetch(`/:login/machines/${id}/metadata`),
get: ({ id, key }) => request.fetch(`/:login/machines/${id}/metadata/${key}`),
destroy: ctx => request('', ctx)
};
const firewall = {
enable: ctx => request('enableMachineFirewall', ctx),
disable: ctx => request('disableMachineFirewall', ctx)
};
const tags = {
list: ctx => request('listMachineTags', ctx),
get: ctx => request('getMachineTag', ctx),
add: ctx => request('addMachineTags', ctx),
replace: ctx => request('replaceMachineTags', ctx),
destroy: ctx =>
request(ctx.tag ? 'deleteMachineTag' : 'deleteMachineTags', ctx)
};
module.exports.list = ctx => request('listMachines', ctx);
module.exports.get = ctx => request('getMachine', ctx);
module.exports.create = ctx => request('createMachine', ctx);
module.exports.stop = ctx => request('stopMachine', ctx);
module.exports.start = uuid => request('startMachine', uuid);
module.exports.startFromSnapshot = ctx =>
request('startMachineFromSnapshot', ctx);
module.exports.reboot = ctx => request('rebootMachine', ctx);
module.exports.resize = ({ id, ...rest }) =>
request.fetch(`/:login/machines/${id}?action=resize?package=${rest.package}`);
module.exports.rename = ctx => request('', ctx);
module.exports.destroy = ctx => request('deleteMachine', ctx);
module.exports.audit = ({ id }) => request('machineAudit', id);
module.exports.snapshots = snapshots;
module.exports.metadata = metadata;
module.exports.firewall = firewall;
module.exports.tags = tags;

View File

@ -1,9 +0,0 @@
const request = require('./request');
// lists all networks, including fabric networks
module.exports.list = () => request('listNetworks');
module.exports.get = ({ id }) => request('getNetwork', id);
// create fabric network
module.exports.create = () => request('');
// destroy fabric network
module.exports.destroy = () => request('');

View File

@ -1,6 +0,0 @@
const request = require('./request');
module.exports.list = () => request('listNics');
module.exports.get = ctx => request('getNic', ctx);
module.exports.add = ctx => request('');
module.exports.destroy = ctx => request('');

View File

@ -1,5 +0,0 @@
const request = require('./request');
module.exports.list = ctx => request('listPackages', ctx);
module.exports.get = ({ id, name }) =>
request.fetch(`/:login/packages/${id || name}`);

View File

@ -1,23 +0,0 @@
const request = require('./request');
// const aperture = require('aperture');
// const { config } = require('aperture-config');
//
// const parser = aperture.createParser({
// types: aperture.types,
// typeTable: config.typeTable
// });
// .then(policies =>
// policies.map(({ rules, ...policy }) =>
// Object.assign(policy, {
// rules: Object.assign(rules.map(parser.parse.bind(parser)), {
// str: rule
// })
// })
// )
// );
module.exports.list = () => request('listPolicies');
module.exports.get = ctx => request('getPolicy', ctx);
module.exports.create = ctx => request('createPolicy', ctx);
module.exports.update = ctx => request('updatePolicy', ctx);
module.exports.destroy = ctx => request('deletePolicy', ctx);

View File

@ -1,108 +0,0 @@
const { createError } = require('apollo-errors');
const awaitify = require('apr-awaitify');
const auth = require('smartdc-auth');
const cloudapi = require('triton/lib/cloudapi2');
const bunyan = require('bunyan');
const fetch = require('node-fetch');
const url = require('url');
const pkg = require('../../package.json');
const credentials = require('../credentials');
const errors = require('./errors.json');
const STATUSES = [
400,
401,
403,
404,
405,
406,
409,
413,
415,
420,
449,
500,
503
];
const ERRORS = Object.keys(errors).reduce(
(errs, code) =>
Object.assign(errs, {
[code]: createError(code, { message: errors[code] })
}),
{}
);
const log = bunyan.createLogger({
name: pkg.name
});
const client = cloudapi.createClient({
log,
url: credentials.url,
account: credentials.account,
user: credentials.user,
sign: auth.cliSigner({
log,
keyId: credentials.keyId,
user: credentials.account,
subuser: credentials.user
})
});
const { _path, _getAuthHeaders, account, url: host } = client;
const getAuthHeaders = awaitify(_getAuthHeaders.bind(client));
module.exports = (method, args) => {
return new Promise((resolve, reject) => {
const fn = client[method].bind(client);
const cb = (err, res) => {
if (err) {
return reject(err);
}
resolve(res);
};
return args ? fn(args, cb) : fn(cb);
});
};
module.exports.client = client;
module.exports.fetch = async (_pathanme, reqOpts = {}) => {
const method = (reqOpts.method || 'get').toUpperCase();
const pathname = _path.call(client, _pathanme.replace(/:login/, account));
const headers = await getAuthHeaders(method, pathname);
const href = url.format({
protocol: 'https',
host: host.replace(/^https:\/\//, ''),
pathname
});
return fetch(
href,
Object.assign(reqOpts, {
method,
headers: Object.assign({}, reqOpts.headers, headers)
})
)
.then(async response => [response.status, await response.json()])
.then(([status, body]) => {
// eslint-disable-next-line no-implicit-coercion
if (~STATUSES.indexOf(status)) {
const { code, message } = body;
const CustomError = ERRORS[code] || ERRORS.UnknownError;
throw new CustomError({
message,
data: { pathname, body: reqOpts.body }
});
}
return body;
});
};

View File

@ -1,21 +0,0 @@
const request = require('./request');
module.exports.list = () => request('listRoles');
module.exports.get = ({ id, name }) =>
request.fetch(`/:login/roles/${id || name}`);
module.exports.create = ctx => request('createRole', ctx);
module.exports.set = ctx => {
const id = ctx.id ? `/${ctx.id}` : '';
const resource = `/${request.client.account}/${ctx.resource}${id}`;
return request('setRoleTags', {
roleTags: ctx.role,
resource
});
};
module.exports.update = ctx => request('updateRole', ctx);
module.exports.destroy = ctx => request('deleteRole', ctx);

View File

@ -1,3 +0,0 @@
const request = require('./request');
module.exports = () => request('listServices');

View File

@ -1,7 +0,0 @@
const request = require('./request');
module.exports.list = () => request('listUsers');
module.exports.get = ctx => request('getUser', ctx);
module.exports.create = ctx => request('createUser', ctx);
module.exports.destroy = ctx => request('deleteUser', ctx);
module.exports.update = ctx => request('updateUser', ctx);

View File

@ -1,21 +0,0 @@
const { fetch } = require('./request');
module.exports.list = () => fetch('/:login/fabrics/default/vlans');
module.exports.get = ({ id }) => fetch(`/:login/fabrics/default/vlans/${id}`);
module.exports.create = ctx =>
fetch(`/:login/fabrics/default/vlans`, {
method: 'POST',
body: ctx
});
module.exports.update = ({ id, ...rest }) =>
fetch(`/:login/fabrics/default/vlans/${id}`, {
method: 'PUT',
body: Object.assign({ id }, rest)
});
module.exports.destroy = ({ id }) =>
fetch(`/:login/fabrics/default/vlans/${id}`, {
method: 'DELETE'
});

View File

@ -1,28 +0,0 @@
const path = require('path');
const json = (() => {
try {
const res = require('dotenv').config({
path: path.join(__dirname, '../.env'),
silent: true
});
if (res.error) {
throw res.error;
}
} catch (err) {
try {
return require('../credentials.json');
} catch (err) {
return {};
}
}
return {};
})();
module.exports = {
url: process.env.SDC_URL || json.SDC_URL || json.url || '',
account: process.env.SDC_ACCOUNT || json.SDC_ACCOUNT || json.account || '',
user: process.env.SDC_USER || json.SDC_USER || json.user || '',
keyId: process.env.SDC_KEY_ID || json.SDC_KEY_ID || json.keyId || ''
};

View File

@ -1,17 +0,0 @@
const path = require('path');
const { makeExecutableSchema } = require('graphql-tools');
const { readFileSync } = require('fs');
const resolvers = require('./resolvers');
const typeDefs = readFileSync(
path.join(__dirname, './schema.graphql'),
'utf-8'
);
module.exports = makeExecutableSchema({
typeDefs,
resolvers
});
module.exports.typeDefs = typeDefs;
module.exports.resolvers = resolvers;

View File

@ -1,264 +0,0 @@
const { toKeyValue, fromKeyValue } = require('../api/key-value');
const api = require('../api');
const forceArray = require('force-array');
const get = require('lodash.get');
const resolvers = {
Query: {
account: () => api.account.get(),
keys: (root, { login, name }) =>
name
? api.keys.get({ login, name }).then(key => [key])
: api.keys.list({ login, name }),
key: (root, { login, name }) => api.keys.get({ login, name }),
users: (root, { id }) =>
id ? api.users.get({ id }).then(user => [user]) : api.users.list(),
user: (root, { id }) => api.users.get({ id }),
roles: (root, { id, name }) =>
id || name
? api.roles.get({ id, name }).then(role => [role])
: api.roles.list(),
role: (root, { id, name }) => api.roles.get({ id, name }),
policies: (root, { id }) =>
id
? api.policies.get({ id }).then(policy => [policy])
: api.policies.list(),
policy: (root, { id }) => api.policies.get({ id }),
config: () => api.config().then(toKeyValue),
datacenters: () =>
api.datacenters().then(dcs =>
Object.keys(dcs).map(name => ({
name,
url: dcs[name]
}))
),
services: () => api.services().then(toKeyValue),
images: (root, { id, ...rest }) =>
id
? api.images.get({ id }).then(image => [image])
: api.images.list(rest),
image: (root, { id }) => api.images.get({ id }),
packages: (root, { id, ...rest }) =>
id
? api.packages.get({ id }).then(pkg => [pkg])
: api.packages.list(rest),
package: (root, { id, name }) => api.packages.get({ id, name }),
machines: (root, { id, brand, state, tags, ...rest }, _, ctx) =>
id
? api.machines.get({ id }).then(machine => [machine])
: api.machines
.list(
Object.assign(rest, {
brand: brand ? brand.toLowerCase() : brand,
state: state ? state.toLowerCase() : state,
tags: fromKeyValue(tags)
})
)
.then(machines => {
const field = forceArray(ctx.fieldNodes)
.filter(({ name }) => name.value === 'machines')
.shift();
if (!field) {
return machines;
}
const prop = get(field, 'selectionSet.selections', [])
.filter(({ name }) => name.value === 'dns_names')
.shift();
if (!prop) {
return machines;
}
return machines.map(({ id }) => api.machines.get({ id }));
}),
machine: (root, { id }) => api.machines.get({ id }),
snapshots: (root, { name, machine }) =>
name
? api.machines.snapshots
.get({ id: machine, name })
.then(snapshot => [snapshot])
: api.machines.snapshots.list({ id: machine }),
snapshot: (root, { name, machine }) =>
api.machines.snapshots.get({ name, id: machine }),
metadata: (root, { machine, name, ...rest }) =>
name
? api.machines.metadata
.get(Object.assign(rest, { id: machine, key: name }))
.then(value => toKeyValue({ [name]: value }))
: api.machines.metadata.list({ id: machine }).then(toKeyValue),
metadataValue: (root, { name, machine }) =>
api.machines.metadata
.get({ key: name, id: machine })
.then(value => toKeyValue({ [name]: value }).shift()),
tags: (root, { machine, name }) =>
name
? api.machines.tags
.get({ id: machine, tag: name })
.then(value => toKeyValue({ [name]: value }))
: api.machines.tags.list({ id: machine }).then(toKeyValue),
tag: (root, { machine, name }) =>
api.machines.tags
.get({ id: machine, tag: name })
.then(value => toKeyValue({ [name]: value }).shift()),
actions: (root, { machine }) => api.machines.audit({ id: machine }),
// eslint-disable-next-line camelcase
firewall_rules: (root, { machine, id }) =>
id
? api.firewall.get({ id })
: machine
? api.firewall.listByMachine({ id: machine })
: api.firewall.list(),
// eslint-disable-next-line camelcase
firewall_rule: (root, { id }) => api.firewall.get({ id }),
vlans: (root, { id }) => (id ? api.vlans.get({ id }) : api.vlans.list()),
vlan: (root, { id }) => api.vlans.get({ id }),
networks: (root, { id, vlan }) =>
id ? api.networks.get({ id, vlan }) : api.networks.list({ vlan }),
network: (root, { id, vlan }) => api.networks.get({ id, vlan }),
nics: (root, { machine, mac }) =>
mac ? api.nics.get({ machine, mac }) : api.nics.list({ machine }),
nic: (root, { machine, mac }) => api.nics.get({ machine, mac })
},
User: {
keys: ({ login }, { name }) => resolvers.Query.keys(null, { login, name })
},
Machine: {
brand: ({ brand }) => (brand ? brand.toUpperCase() : brand),
state: ({ state }) => (state ? state.toUpperCase() : state),
image: ({ image }) => resolvers.Query.image(null, { id: image }),
// eslint-disable-next-line camelcase
primary_ip: ({ primaryIp }) => primaryIp,
tags: ({ id }, { name }) =>
resolvers.Query.tags(null, { machine: id, name }),
metadata: ({ id }, { name }) =>
resolvers.Query.metadata(null, { machine: id, name }),
networks: ({ networks }) =>
Promise.all(networks.map(id => resolvers.Query.network(null, { id }))),
// eslint-disable-next-line camelcase
package: root => resolvers.Query.package(null, { name: root.package }),
snapshots: ({ id }, { name }) =>
resolvers.Query.snapshots(null, { machine: id, name }),
// eslint-disable-next-line camelcase
firewall_rules: ({ id: machine }, { id }) =>
resolvers.Query.firewall_rules(null, { machine, id }),
actions: ({ id }) => resolvers.Query.actions(null, { machine: id })
},
Image: {
os: ({ os }) => (os ? os.toUpperCase() : os),
state: ({ state }) => (state ? state.toUpperCase() : state),
type: ({ type }) => (type ? type.toUpperCase() : type)
},
Action: {
name: ({ action }) => action,
parameters: ({ parameters }) => toKeyValue(parameters)
},
Caller: {
type: ({ type }) => (type ? type.toUpperCase() : type),
// eslint-disable-next-line camelcase
key_id: ({ keyId }) => keyId
},
FirewallRule: {
machines: ({ id }) => api.firewall.listMachines({ id })
},
Snapshot: {
state: ({ state }) => (state ? state.toUpperCase() : state)
},
ImageError: {
code: ({ code }) => (code ? code.toUpperCase() : code)
},
ImageFile: {
compression: ({ compression }) =>
compression ? compression.toUpperCase() : compression
},
Mutation: {
stopMachine: (root, { id }) =>
api.machines.stop(id).then(() => resolvers.Query.machine(null, { id })),
startMachine: (root, { id }) =>
api.machines.start(id).then(() => resolvers.Query.machine(null, { id })),
rebootMachine: (root, { id }) =>
api.machines.reboot(id).then(() => resolvers.Query.machine(null, { id })),
resizeMachine: (root, { id, ...args }) =>
api.machines
.resize({ id, package: args.package })
.then(() => resolvers.Query.machine(null, { id })),
enableMachineFirewall: (root, { id }) =>
api.machines.firewall
.enable(id)
.then(() => resolvers.Query.machine(null, { id })),
disableMachineFirewall: (root, { id }) =>
api.machines.firewall
.disable(id)
.then(() => resolvers.Query.machine(null, { id })),
createMachineSnapshot: (root, { id, name }) =>
api.machines.snapshots
.create({ id, name })
.then(() => resolvers.Query.snapshots(null, { machine: id, name })),
startMachineFromSnapshot: (root, { id, name }) =>
api.machines.snapshots
.startFromSnapshot({ id, name })
.then(() => resolvers.Query.machine(null, { id })),
deleteMachineSnapshot: async (root, { id, snapshot: name }) => {
const snapshot = await api.machines.snapshots.get({ id, name });
await api.machines.snapshots.destroy({ id, name });
return snapshot;
}
}
};
module.exports = resolvers;

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +0,0 @@
const { hapi: Voyager } = require('graphql-voyager/middleware');
const { hapi: Playground } = require('graphql-playground/middleware');
const { graphqlHapi, graphiqlHapi } = require('apollo-server-hapi');
const { formatError } = require('apollo-errors');
const Hapi = require('hapi');
const Good = require('good');
const Path = require('path');
const Inert = require('inert');
const Execa = require('execa');
const schema = require('./schema');
const { CORS, PORT } = process.env;
const server = new Hapi.Server({
debug: {
log: ['error'],
request: ['error']
}
});
const handlerError = err => {
if (err) {
// eslint-disable-next-line no-console
console.error(err);
process.exit(1);
}
};
// compile docs
// eslint-disable-next-line new-cap
Execa('npm', ['run', 'graphdoc']).catch(handlerError);
server.connection({
port: PORT,
routes: {
files: {
relativeTo: Path.join(__dirname, './../doc')
}
}
});
server.register(
[
{
register: Good,
options: {
reporters: {
console: [
{
module: 'good-squeeze',
name: 'Squeeze',
args: [{ log: '*', response: '*' }]
},
{
module: 'good-console'
},
'stdout'
]
}
}
},
Inert,
{
register: graphqlHapi,
options: {
path: '/graphql',
graphqlOptions: {
formatError,
schema
},
route: {
cors: Boolean(CORS)
}
}
},
{
register: graphiqlHapi,
options: {
path: '/graphiql',
graphiqlOptions: {
endpointURL: '/graphql'
}
}
},
{
register: Playground,
options: {
path: '/playground',
endpointUrl: '/graphql'
}
},
{
register: Voyager,
options: {
path: '/voyager',
endpointUrl: '/graphql'
}
}
],
err => {
handlerError(err);
server.route({
method: 'GET',
path: '/doc/{param*}',
handler: {
directory: {
path: '.',
redirectToSlash: true,
index: true
}
}
});
server.start(err => {
handlerError(err);
// eslint-disable-next-line no-console
console.log(`server started at http://0.0.0.0:${server.info.port}`);
});
}
);