docker-graphql initial commit
This commit is contained in:
parent
e48a42559f
commit
4e73cc4ea6
1
.gitignore
vendored
1
.gitignore
vendored
@ -150,6 +150,7 @@ $RECYCLE.BIN/
|
||||
*.postcss.js
|
||||
|
||||
/cloudapi-graphql/credentials.json
|
||||
/docker-graphql/config.json
|
||||
tap-xunit
|
||||
/ui/dist
|
||||
|
||||
|
27
docker-graphql/.eslintrc
Normal file
27
docker-graphql/.eslintrc
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"prettier"
|
||||
],
|
||||
"plugins": [
|
||||
"prettier"
|
||||
],
|
||||
"rules": {
|
||||
"no-console": 0,
|
||||
"prettier/prettier": ["error", {
|
||||
"useTabs": false,
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": true,
|
||||
"jsxBracketSameLine": false,
|
||||
"parser": "flow",
|
||||
"semi": true
|
||||
}]
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true
|
||||
}
|
||||
}
|
50
docker-graphql/.gitignore
vendored
Normal file
50
docker-graphql/.gitignore
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
jspm_packages
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Vim files:
|
||||
*.sw*
|
||||
|
||||
# Mac OS dirty files
|
||||
.DS_Store
|
1
docker-graphql/Dockerfile
Normal file
1
docker-graphql/Dockerfile
Normal file
@ -0,0 +1 @@
|
||||
FROM quay.io/yldio/alpine-node-containerpilot:6.9.4-3
|
54
docker-graphql/Makefile
Normal file
54
docker-graphql/Makefile
Normal file
@ -0,0 +1,54 @@
|
||||
NAME := $(lastword $(subst /, ,$(CURDIR)))
|
||||
|
||||
bindir := $(shell yarn bin)
|
||||
AVA := $(bindir)/ava
|
||||
NYC := $(bindir)/nyc
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
yarn install --prefer-offline
|
||||
|
||||
.PHONY: install-production
|
||||
install-production:
|
||||
yarn install --production --pure-lockfile --prefer-offline
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -rf node_modules
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
$(AVA) $(TEST_ARGS)
|
||||
|
||||
XUNIT_DIR := ${CIRCLE_TEST_REPORTS}/tap-xunit
|
||||
XUNIT := $(bindir)/tap-xunit
|
||||
XUNIT_OUTPUT := >> ${CIRCLE_TEST_REPORTS}/tap-xunit/xunit-$(NAME)
|
||||
.PHONY: test-ci
|
||||
test-ci:
|
||||
mkdir -p $(XUNIT_DIR)
|
||||
$(NYC) $(AVA) -t | $(XUNIT) $(XUNIT_OUTPUT).xml
|
||||
|
||||
.PHONY: start
|
||||
start:
|
||||
yarn run start
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
docker build -t quay.io/yldio/joyent-dashboard-$(NAME):$(CIRCLE_BRANCH) .
|
||||
|
||||
.PHONY: push
|
||||
push:
|
||||
docker push quay.io/yldio/joyent-dashboard-$(NAME)
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
$(bindir)/eslint .
|
||||
|
||||
.PHONY: lint-ci
|
||||
lint-ci:
|
||||
mkdir -p $(XUNIT_DIR)
|
||||
-$(bindir)/eslint . --format tap | $(XUNIT) $(XUNIT_OUTPUT)-lint.xml
|
||||
|
||||
.PHONY: licence-check
|
||||
licence-check:
|
||||
../node_modules/.bin/license-to-fail ../licence.js
|
1
docker-graphql/README.md
Normal file
1
docker-graphql/README.md
Normal file
@ -0,0 +1 @@
|
||||
WIP
|
38
docker-graphql/etc/containerpilot.json
Normal file
38
docker-graphql/etc/containerpilot.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"consul": "{{ .CONSUL }}:8500",
|
||||
"services": [{
|
||||
"name": "joyent-portal-docker-graphql",
|
||||
"port": 5000,
|
||||
"health": "/usr/bin/curl -o /dev/null --fail -s http://localhost:4000/graphql",
|
||||
"poll": 3,
|
||||
"ttl": 10
|
||||
}],
|
||||
"telemetry": {
|
||||
"port": 9090,
|
||||
"sensors": [{
|
||||
"name": "graphql_memory_percent",
|
||||
"help": "percentage of memory used",
|
||||
"type": "gauge",
|
||||
"poll": 5,
|
||||
"check": ["/bin/sensors", "memory"]
|
||||
}, {
|
||||
"name": "graphql_cpu_load",
|
||||
"help": "cpu load",
|
||||
"type": "gauge",
|
||||
"poll": 5,
|
||||
"check": ["/bin/sensors", "cpu"]
|
||||
}, {
|
||||
"name": "graphql_disk_capacity",
|
||||
"help": "disk capacity",
|
||||
"type": "gauge",
|
||||
"poll": 60,
|
||||
"check": ["/bin/sensors", "diskcapacity"]
|
||||
}, {
|
||||
"name": "graphql_disk_usage",
|
||||
"help": "disk usage",
|
||||
"type": "gauge",
|
||||
"poll": 60,
|
||||
"check": ["/bin/sensors", "diskusage"]
|
||||
}]
|
||||
}
|
||||
}
|
30
docker-graphql/package.json
Normal file
30
docker-graphql/package.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "docker-graphql",
|
||||
"private": true,
|
||||
"license": "MPL-2.0",
|
||||
"version": "1.0.0",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
"lint": "eslint src --fix",
|
||||
"start": "node src/index.js",
|
||||
"test": "make test"
|
||||
},
|
||||
"dependencies": {
|
||||
"dockerode": "^2.4.3",
|
||||
"dotenv": "^4.0.0",
|
||||
"express": "^4.15.2",
|
||||
"express-graphql": "^0.6.4",
|
||||
"graphql": "^0.9.3",
|
||||
"pascal-case": "^2.0.1",
|
||||
"upper-case": "^1.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ava": "^0.19.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-prettier": "^1.7.0",
|
||||
"eslint-plugin-prettier": "^2.0.1",
|
||||
"nyc": "^10.2.0",
|
||||
"prettier": "^1.2.2",
|
||||
"tap-xunit": "^1.7.0"
|
||||
}
|
||||
}
|
16
docker-graphql/src/api/client.js
Normal file
16
docker-graphql/src/api/client.js
Normal file
@ -0,0 +1,16 @@
|
||||
const Docker = require('dockerode');
|
||||
const url = require('url');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const config = require('../config');
|
||||
const location = url.parse(config.host);
|
||||
|
||||
module.exports = new Docker({
|
||||
host: location.hostname,
|
||||
port: Number(location.port),
|
||||
ca: fs.readFileSync(path.join(config.cert, 'ca.pem')),
|
||||
cert: fs.readFileSync(path.join(config.cert, 'cert.pem')),
|
||||
key: fs.readFileSync(path.join(config.cert, 'key.pem')),
|
||||
version: 'v1.24'
|
||||
});
|
28
docker-graphql/src/api/containers.js
Normal file
28
docker-graphql/src/api/containers.js
Normal file
@ -0,0 +1,28 @@
|
||||
const client = require('./client');
|
||||
|
||||
// https://docs.docker.com/engine/api/v1.24/#list-containers
|
||||
module.exports.list = () => client.listContainers();
|
||||
|
||||
module.exports.create = () => null;
|
||||
module.exports.inspect = () => null;
|
||||
module.exports.ps = () => null;
|
||||
module.exports.logs = () => null;
|
||||
module.exports.stats = () => null;
|
||||
module.exports.changes = () => null;
|
||||
module.exports['export'] = () => null;
|
||||
module.exports.resize = () => null;
|
||||
module.exports.start = () => null;
|
||||
module.exports.stop = () => null;
|
||||
module.exports.restart = () => null;
|
||||
module.exports.kill = () => null;
|
||||
module.exports.update = () => null;
|
||||
module.exports.rename = () => null;
|
||||
module.exports.pause = () => null;
|
||||
module.exports.unpause = () => null;
|
||||
module.exports.attach = () => null;
|
||||
module.exports.wait = () => null;
|
||||
module.exports.remove = () => null;
|
||||
module.exports.archive = () => null;
|
||||
module.exports.pause = () => null;
|
||||
module.exports.exec = () => null;
|
||||
module.exports.pause = () => null;
|
3
docker-graphql/src/api/index.js
Normal file
3
docker-graphql/src/api/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
containers: require('./containers')
|
||||
};
|
47
docker-graphql/src/config.js
Normal file
47
docker-graphql/src/config.js
Normal file
@ -0,0 +1,47 @@
|
||||
const json = (() => {
|
||||
try {
|
||||
const res = require('dotenv').config({
|
||||
path: '../.env',
|
||||
silent: true
|
||||
});
|
||||
|
||||
if (res.error) {
|
||||
throw res.error;
|
||||
}
|
||||
} catch (err) {
|
||||
try {
|
||||
return require('../config.json');
|
||||
} catch (err) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
})();
|
||||
|
||||
module.exports = {
|
||||
cert: (
|
||||
process.env.DOCKER_CERT_PATH ||
|
||||
json.DOCKER_CERT_PATH ||
|
||||
json.cert ||
|
||||
''
|
||||
),
|
||||
host: (
|
||||
process.env.DOCKER_HOST ||
|
||||
json.DOCKER_HOST ||
|
||||
json.host ||
|
||||
''
|
||||
),
|
||||
tls_verify: (
|
||||
process.env.DOCKER_TLS_VERIFY ||
|
||||
json.DOCKER_TLS_VERIFY ||
|
||||
json.tls_verify ||
|
||||
''
|
||||
),
|
||||
timeout: (
|
||||
process.env.DOCKER_CLIENT_TIMEOUT ||
|
||||
json.DOCKER_CLIENT_TIMEOUT ||
|
||||
json.timeout ||
|
||||
''
|
||||
)
|
||||
};
|
8
docker-graphql/src/endpoint.js
Normal file
8
docker-graphql/src/endpoint.js
Normal file
@ -0,0 +1,8 @@
|
||||
const graphqlHTTP = require('express-graphql');
|
||||
const schema = require('./schema');
|
||||
|
||||
module.exports = graphqlHTTP(() => ({
|
||||
schema: schema,
|
||||
graphiql: true,
|
||||
pretty: true
|
||||
}));
|
14
docker-graphql/src/index.js
Normal file
14
docker-graphql/src/index.js
Normal file
@ -0,0 +1,14 @@
|
||||
const express = require('express');
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use('/graphql', require('./endpoint'));
|
||||
|
||||
const server = app.listen(4010, err => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
throw err;
|
||||
}
|
||||
|
||||
console.log(`Listening at http://0.0.0.0:${server.address().port}/graphql`);
|
||||
});
|
9
docker-graphql/src/schema/index.js
Normal file
9
docker-graphql/src/schema/index.js
Normal file
@ -0,0 +1,9 @@
|
||||
const graphql = require('graphql');
|
||||
const mutation = require('./mutations');
|
||||
const query = require('./queries');
|
||||
|
||||
const { GraphQLSchema } = graphql;
|
||||
|
||||
module.exports = new GraphQLSchema({
|
||||
query
|
||||
});
|
17
docker-graphql/src/schema/mutations/index.js
Normal file
17
docker-graphql/src/schema/mutations/index.js
Normal file
@ -0,0 +1,17 @@
|
||||
const { GraphQLObjectType } = require('graphql');
|
||||
|
||||
module.exports = new GraphQLObjectType({
|
||||
name: 'RootMutationType',
|
||||
fields: {}
|
||||
// fields: Object.assign(
|
||||
// // require('./account'),
|
||||
// // require('./keys'),
|
||||
// // require('./users'),
|
||||
// // require('./roles'),
|
||||
// // require('./policies'),
|
||||
// // require('./machines'),
|
||||
// // require('./images'),
|
||||
// // require('./firewall-rules'),
|
||||
// // require('./snapshots')
|
||||
// )
|
||||
});
|
55
docker-graphql/src/schema/queries/containers.js
Normal file
55
docker-graphql/src/schema/queries/containers.js
Normal file
@ -0,0 +1,55 @@
|
||||
const graphql = require('graphql');
|
||||
const DynamicObjectType = require('../types/dynamic-object');
|
||||
const ContainerType = require('../types/container');
|
||||
const api = require('../../api');
|
||||
|
||||
const { GraphQLInt, GraphQLList, GraphQLString, GraphQLID, GraphQLBoolean } = graphql;
|
||||
|
||||
module.exports = {
|
||||
type: new GraphQLList(ContainerType),
|
||||
args: {
|
||||
all: {
|
||||
type: GraphQLBoolean,
|
||||
description: 'Show all containers. Only running containers are shown by default (i.e., this defaults to false)',
|
||||
resolve: root => !!root.all
|
||||
},
|
||||
limit: {
|
||||
type: GraphQLInt,
|
||||
description: 'Show `limit` last created containers, include non-running ones'
|
||||
},
|
||||
since: {
|
||||
type: GraphQLID,
|
||||
description: 'Show only containers created since `id`, include non-running ones'
|
||||
},
|
||||
before: {
|
||||
type: GraphQLID,
|
||||
description: 'Show only containers created before `id`, include non-running ones'
|
||||
},
|
||||
size: {
|
||||
type: GraphQLBoolean,
|
||||
description: 'Show the containers sizes'
|
||||
},
|
||||
filters: {
|
||||
type: DynamicObjectType,
|
||||
description: 'Filters to process on the containers list'
|
||||
}
|
||||
},
|
||||
resolve(root, args) {
|
||||
const { list, inspect } = api.containers;
|
||||
|
||||
return list(args);
|
||||
//
|
||||
// const { after, first } = args;
|
||||
//
|
||||
// const newArgs = Object.assign(args, {
|
||||
// limit: first,
|
||||
// offset: after
|
||||
// });
|
||||
//
|
||||
// return args.id
|
||||
// ? get({
|
||||
// id: args.id
|
||||
// }).then(machine => [machine])
|
||||
// : list(newArgs);
|
||||
}
|
||||
};
|
8
docker-graphql/src/schema/queries/index.js
Normal file
8
docker-graphql/src/schema/queries/index.js
Normal file
@ -0,0 +1,8 @@
|
||||
const { GraphQLObjectType } = require('graphql');
|
||||
|
||||
module.exports = new GraphQLObjectType({
|
||||
name: 'RootQueryType',
|
||||
fields: {
|
||||
containers: require('./containers')
|
||||
}
|
||||
});
|
49
docker-graphql/src/schema/types/container.js
Normal file
49
docker-graphql/src/schema/types/container.js
Normal file
@ -0,0 +1,49 @@
|
||||
const DynamicObjectType = require('./dynamic-object');
|
||||
const fromPascalCase = require('./from-pascal-case');
|
||||
const PortType = require('./port');
|
||||
|
||||
const {
|
||||
GraphQLString,
|
||||
GraphQLObjectType,
|
||||
GraphQLInt,
|
||||
GraphQLList,
|
||||
GraphQLID
|
||||
} = require('graphql');
|
||||
|
||||
module.exports = new GraphQLObjectType({
|
||||
name: 'ContainerType',
|
||||
fields: {
|
||||
id: {
|
||||
type: GraphQLID,
|
||||
resolve: fromPascalCase
|
||||
},
|
||||
created: {
|
||||
type: GraphQLInt,
|
||||
resolve: fromPascalCase
|
||||
},
|
||||
command: {
|
||||
type: GraphQLString,
|
||||
resolve: fromPascalCase
|
||||
},
|
||||
names: {
|
||||
type: new GraphQLList(GraphQLString),
|
||||
resolve: fromPascalCase
|
||||
},
|
||||
status: {
|
||||
type: GraphQLString,
|
||||
resolve: fromPascalCase
|
||||
},
|
||||
image: {
|
||||
type: GraphQLString,
|
||||
resolve: fromPascalCase
|
||||
},
|
||||
labels: {
|
||||
type: DynamicObjectType,
|
||||
resolve: fromPascalCase
|
||||
},
|
||||
ports: {
|
||||
type: new GraphQLList(PortType),
|
||||
resolve: fromPascalCase
|
||||
}
|
||||
}
|
||||
});
|
41
docker-graphql/src/schema/types/dynamic-object.js
Normal file
41
docker-graphql/src/schema/types/dynamic-object.js
Normal file
@ -0,0 +1,41 @@
|
||||
const { GraphQLScalarType, Kind } = require('graphql');
|
||||
|
||||
const kinds = {
|
||||
[Kind.STRING]: ast => {
|
||||
return ast.value;
|
||||
},
|
||||
[Kind.BOOLEAN]: ast => {
|
||||
return kinds[Kind.STRING](ast);
|
||||
},
|
||||
[Kind.INT]: ast => {
|
||||
return Number(ast.value);
|
||||
},
|
||||
[Kind.FLOAT]: ast => {
|
||||
return kinds[Kind.INT](ast);
|
||||
},
|
||||
[Kind.OBJECT]: ast => {
|
||||
const value = Object.create(null);
|
||||
ast.fields.forEach(field => {
|
||||
value[field.name.value] = parseLiteral(field.value);
|
||||
});
|
||||
|
||||
return value;
|
||||
},
|
||||
[Kind.LIST]: ast => {
|
||||
return ast.values.map(parseLiteral);
|
||||
}
|
||||
};
|
||||
|
||||
// https://github.com/taion/graphql-type-json/blob/master/src/index.js
|
||||
const parseLiteral = ast => {
|
||||
const kind = kinds[ast.kind];
|
||||
return kind ? kinds[ast.kind](ast) : null;
|
||||
};
|
||||
|
||||
// from http://stackoverflow.com/a/34229603
|
||||
module.exports = new GraphQLScalarType({
|
||||
name: 'DynamicObjectType',
|
||||
serialize: v => v,
|
||||
parseValue: v => v,
|
||||
parseLiteral: parseLiteral
|
||||
});
|
4
docker-graphql/src/schema/types/from-pascal-case.js
Normal file
4
docker-graphql/src/schema/types/from-pascal-case.js
Normal file
@ -0,0 +1,4 @@
|
||||
const pascalCase = require('pascal-case');
|
||||
const upperCase = require('upper-case');
|
||||
|
||||
module.exports = (root, ctx, req, { fieldName }) => root[pascalCase(fieldName)] || root[upperCase(fieldName)];
|
25
docker-graphql/src/schema/types/port.js
Normal file
25
docker-graphql/src/schema/types/port.js
Normal file
@ -0,0 +1,25 @@
|
||||
const { GraphQLString, GraphQLObjectType, GraphQLInt } = require('graphql');
|
||||
const DynamicObjectType = require('./dynamic-object');
|
||||
const fromPascalCase = require('./from-pascal-case');
|
||||
|
||||
module.exports = new GraphQLObjectType({
|
||||
name: 'PortType',
|
||||
fields: {
|
||||
ip: {
|
||||
type: GraphQLString,
|
||||
resolve: fromPascalCase
|
||||
},
|
||||
privatePort: {
|
||||
type: GraphQLInt,
|
||||
resolve: fromPascalCase
|
||||
},
|
||||
publicPort: {
|
||||
type: GraphQLInt,
|
||||
resolve: fromPascalCase
|
||||
},
|
||||
type: {
|
||||
type: GraphQLString,
|
||||
resolve: fromPascalCase
|
||||
}
|
||||
}
|
||||
});
|
0
docker-graphql/static/.gitkeep
Normal file
0
docker-graphql/static/.gitkeep
Normal file
7
docker-graphql/test/noop.test.js
Normal file
7
docker-graphql/test/noop.test.js
Normal file
@ -0,0 +1,7 @@
|
||||
// TODO: REMOVE, JUST FOR AN EXAMPLE
|
||||
|
||||
const test = require('ava');
|
||||
|
||||
test('foo', t => {
|
||||
t.pass();
|
||||
});
|
4051
docker-graphql/yarn.lock
Normal file
4051
docker-graphql/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user