parent
8a0a0a4457
commit
d8f0dec487
@ -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']
|
||||
]
|
||||
}
|
||||
};
|
||||
|
@ -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",
|
||||
|
@ -1,3 +0,0 @@
|
||||
.nyc_output
|
||||
coverage
|
||||
doc
|
@ -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"]
|
||||
}
|
||||
}
|
1
packages/cloudapi-gql/.gitignore
vendored
1
packages/cloudapi-gql/.gitignore
vendored
@ -1 +0,0 @@
|
||||
doc
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"schemaPath": "src/schema/schema.graphql",
|
||||
"extensions": {
|
||||
"endpoints": {
|
||||
"dev": "http://localhost:4000/graphql"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"libs": [
|
||||
"ecmascript"
|
||||
],
|
||||
"plugins": {
|
||||
"doc_comment": true,
|
||||
"local-scope": true,
|
||||
"node": true
|
||||
}
|
||||
}
|
@ -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
|
@ -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/*"]
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
const request = require('./request');
|
||||
|
||||
module.exports.get = () => request('getAccount');
|
||||
module.exports.update = ctx => request('updateAccount', ctx);
|
@ -1,3 +0,0 @@
|
||||
const { fetch } = require('./request');
|
||||
|
||||
module.exports = () => fetch('/:login/config');
|
@ -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}`);
|
@ -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!"
|
||||
}
|
@ -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);
|
@ -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);
|
@ -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')
|
||||
};
|
@ -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
|
||||
}),
|
||||
{}
|
||||
);
|
@ -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' });
|
@ -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;
|
@ -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('');
|
@ -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('');
|
@ -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}`);
|
@ -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);
|
@ -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;
|
||||
});
|
||||
};
|
@ -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);
|
@ -1,3 +0,0 @@
|
||||
const request = require('./request');
|
||||
|
||||
module.exports = () => request('listServices');
|
@ -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);
|
@ -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'
|
||||
});
|
@ -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 || ''
|
||||
};
|
@ -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;
|
@ -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
@ -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}`);
|
||||
});
|
||||
}
|
||||
);
|
Loading…
Reference in New Issue
Block a user