Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Extracted from [email protected] (sha: 8401539d6b53)
  • Loading branch information
dfunckt committed Oct 25, 2018
0 parents commit 3bc2cbf
Show file tree
Hide file tree
Showing 84 changed files with 10,330 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.git
automation
build
config/env
dist
node_modules
49 changes: 49 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Numerous always-ignore extensions
*.diff
*.err
*.orig
*.log
*.rej
*.swo
*.swp
*.zip
*.vi
*~
*.sass-cache
.#*

# OS or Editor folders
.DS_Store
._*
Thumbs.db
.cache
.project
.settings
.tmproj
*.esproj
nbproject
*.sublime-project
*.sublime-workspace
.fasttest
.vscode

# Komodo
*.komodoproject
.komodotools

# Folders to ignore
.idea
node_modules
build
dist

# Node environment
config/env

# Startup cache files
/.ts-node
/.fast-boot.json
/.coffee
/.pinejs-cache.json
/.resin.sbvr
/.resin-init.sql
7 changes: 7 additions & 0 deletions .resinci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
docker:
builds:
- path: .
dockerfile: Dockerfile
docker_repo: balena/open-balena-api
publish: true
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Change Log

All notable changes to this project will be documented in this file
automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
This project adheres to [Semantic Versioning](http://semver.org/).

## v0.0.1 - 2018-02-20

* Initial commit
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM balena/open-balena-base:v4.4.2

EXPOSE 80

COPY package.json package-lock.json /usr/src/app/
RUN npm ci --unsafe-perm --production && npm cache clean --force

COPY . /usr/src/app

RUN npx tsc --noEmit

COPY config/services/ /etc/systemd/system/

RUN systemctl enable open-balena-api.service
661 changes: 661 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

Empty file added README.md
Empty file.
13 changes: 13 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"models": [{
"modelName": "resin",
"modelFile": "./src/resin.sbvr",
"initSqlPath": "./src/resin-init.sql",
"apiRoot": "resin"
}],
"users": [{
"username": "guest",
"password": " ",
"permissions": []
}]
}
39 changes: 39 additions & 0 deletions config/confd_env_backend/conf.d/env.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
[template]
src = "env.tmpl"
dest = "/usr/src/app/config/env"
keys = [
"API_VPN_SERVICE_API_KEY",
"AUTH_RESINOS_REGISTRY_CODE",
"COOKIE_SESSION_SECRET",
"DB_HOST",
"DB_PASSWORD",
"DB_PORT",
"DB_USER",
"DELTA_HOST",
"HOST",
"IMAGE_MAKER_URL",
"IMAGE_STORAGE_BUCKET",
"IMAGE_STORAGE_ENDPOINT",
"IMAGE_STORAGE_FORCE_PATH_STYLE",
"IMAGE_STORAGE_PREFIX",
"JSON_WEB_TOKEN_EXPIRY_MINUTES",
"JSON_WEB_TOKEN_SECRET",
"MIXPANEL_TOKEN",
"PRODUCTION_MODE",
"PUBNUB_PUBLISH_KEY",
"PUBNUB_SUBSCRIBE_KEY",
"REDIS_HOST",
"REDIS_PORT",
"REGISTRY2_HOST",
"REGISTRY_HOST",
"SENTRY_DSN",
"TOKEN_AUTH_BUILDER_TOKEN",
"TOKEN_AUTH_CERT_ISSUER",
"TOKEN_AUTH_CERT_KEY",
"TOKEN_AUTH_CERT_KID",
"TOKEN_AUTH_CERT_PUB",
"TOKEN_AUTH_JWT_ALGO",
"VPN_HOST",
"VPN_PORT",
"VPN_SERVICE_API_KEY",
]
48 changes: 48 additions & 0 deletions config/confd_env_backend/templates/env.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
API_HOST={{getenv "HOST"}}
API_VPN_SERVICE_API_KEY={{getenv "API_VPN_SERVICE_API_KEY"}}
COOKIE_SESSION_SECRET={{getenv "COOKIE_SESSION_SECRET"}}
DATABASE_URL=postgres://{{getenv "DB_USER"}}:{{getenv "DB_PASSWORD"}}@{{getenv "DB_HOST"}}:{{getenv "DB_PORT"}}/resin
DB_HOST={{getenv "DB_HOST"}}
DB_PASSWORD={{getenv "DB_PASSWORD"}}
DB_POOL_SIZE=60
DB_PORT={{getenv "DB_PORT"}}
DB_USER={{getenv "DB_USER"}}
DEBUG={{if ne (getenv "PRODUCTION_MODE") "true"}}true{{end}}
DELTA_HOST={{getenv "DELTA_HOST"}}
EXTERNAL_HTTP_TIMEOUT_MS=25000
HOST={{getenv "HOST"}}
IMAGE_MAKER_URL=https://{{getenv "IMAGE_MAKER_URL"}}
IMAGE_STORAGE_BUCKET={{getenv "IMAGE_STORAGE_BUCKET"}}
IMAGE_STORAGE_ENDPOINT={{getenv "IMAGE_STORAGE_ENDPOINT"}}
IMAGE_STORAGE_FORCE_PATH_STYLE={{if getenv "IMAGE_STORAGE_FORCE_PATH_STYLE"}}{{getenv "IMAGE_STORAGE_FORCE_PATH_STYLE"}}{{else}}false{{end}}
IMAGE_STORAGE_PREFIX={{if getenv "IMAGE_STORAGE_PREFIX"}}{{getenv "IMAGE_STORAGE_PREFIX"}}{{else}}images{{end}}
JSON_WEB_TOKEN_EXPIRY_MINUTES={{getenv "JSON_WEB_TOKEN_EXPIRY_MINUTES"}}
JSON_WEB_TOKEN_SECRET='{{getenv "JSON_WEB_TOKEN_SECRET"}}'
MAX_CONNECTIONS=75
MIXPANEL_TOKEN={{getenv "MIXPANEL_TOKEN"}}
NODE_ENV={{if eq (getenv "PRODUCTION_MODE") "true"}}production{{else}}development{{end}}
NODE_EXTRA_CA_CERTS={{if getenv "BALENA_ROOT_CA"}}/etc/ssl/certs/balenaRootCA.pem{{end}}
NUM_WORKERS={{if ne (getenv "PRODUCTION_MODE") "true"}}1{{end}}
PG_SCHEMA=public
PORT=80
PRODUCTION_MODE={{getenv "PRODUCTION_MODE"}}
PROFILING_MODE=false
PUBNUB_PUBLISH_KEY={{getenv "PUBNUB_PUBLISH_KEY"}}
PUBNUB_SUBSCRIBE_KEY={{getenv "PUBNUB_SUBSCRIBE_KEY"}}
REDIS_HOST={{getenv "REDIS_HOST"}}
REDIS_PORT={{getenv "REDIS_PORT"}}
REGISTRY2_HOST={{getenv "REGISTRY2_HOST"}}
REGISTRY_HOST={{getenv "REGISTRY_HOST"}}
SENTRY_DSN={{getenv "SENTRY_DSN"}}
TOKEN_AUTH_BUILDER_TOKEN='{{getenv "TOKEN_AUTH_BUILDER_TOKEN"}}'
TOKEN_AUTH_CERT_ISSUER='{{getenv "TOKEN_AUTH_CERT_ISSUER"}}'
TOKEN_AUTH_CERT_KEY='{{getenv "TOKEN_AUTH_CERT_KEY"}}'
TOKEN_AUTH_CERT_KID='{{getenv "TOKEN_AUTH_CERT_KID"}}'
TOKEN_AUTH_CERT_PUB='{{getenv "TOKEN_AUTH_CERT_PUB"}}'
TOKEN_AUTH_JWT_ALGO='{{getenv "TOKEN_AUTH_JWT_ALGO"}}'
TRANSACTION_TIMEOUT_MS=30000
UV_THREADPOOL_SIZE=128
VPN_HOST={{getenv "VPN_HOST"}}
VPN_PORT={{getenv "VPN_PORT"}}
VPN_SERVICE_API_KEY={{getenv "VPN_SERVICE_API_KEY"}}
{{if getenv "AUTH_RESINOS_REGISTRY_CODE"}}AUTH_RESINOS_REGISTRY_CODE={{getenv "AUTH_RESINOS_REGISTRY_CODE"}}{{end}}
16 changes: 16 additions & 0 deletions config/services/open-balena-api.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[Unit]
Description=open-balena-api
Requires=confd.service balena-root-ca.service
After=confd.service balena-root-ca.service

[Service]
StandardOutput=journal+console
StandardError=journal+console
WorkingDirectory=/usr/src/app
EnvironmentFile=/usr/src/app/config/env
ExecStart=/usr/src/app/entry.sh
Restart=always
SyslogIdentifier=api

[Install]
WantedBy=basic.target
11 changes: 11 additions & 0 deletions entry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

if [ "$PRODUCTION_MODE" == "true" ]; then
exec node index.js
else
exec ./node_modules/.bin/supervisor \
--no-restart-on error \
--extensions js,node,coffee,sbvr,json,sql,pegjs,ts \
--watch src \
--exec node index.js
fi
84 changes: 84 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const numWorkers = process.env.NUM_WORKERS || require('os').cpus().length
if (numWorkers > 1) {
const cluster = require('cluster')
if (cluster.isMaster) {
console.log(`Forking ${numWorkers} workers`)
for (let i = 0; i < numWorkers; i++) {
console.log(`Forking worker ${i}`)
cluster.fork(process.env)
}

cluster.on('exit', (worker) => {
console.log('Worker ' + worker.id + ' died, replacing it')
cluster.fork(process.env)
})
return
}
}

// Use fast-boot to cache require lookups, speeding up startup
require('fast-boot').start({
cacheFile: '.fast-boot.json'
})

// Support `require()` of *.coffee files
process.env.COFFEE_CACHE_DIR = '.coffee'
require('coffee-cache')

// Support `require()` of *.ts files
process.env.TS_NODE_CACHE_DIRECTORY = '.ts-node'
require('ts-node/register/transpile-only')

const _ = require('lodash')
const express = require('express')
const { setup } = require('./src')

function onInitMiddleware(app) {
const { forwardRequests } = require('./src/platform/versions')
forwardRequests(app, 'v4', 'resin')
}

function onInitModel() {
const { runInTransaction, updateOrInsertModel } = require('./src/platform')
const appTypes = require('./src/lib/application-types')
const insert = _.cloneDeep(appTypes.Default)
const filter = { slug: insert.slug }
delete insert.slug
return runInTransaction(tx =>
updateOrInsertModel('application_type', filter, insert, tx)
)
}

function onInitHooks() {
const { runInTransaction } = require('./src/platform')
const { createAll } = require('./src/platform/permissions')
const auth = require('./src/lib/auth')
const permissionNames = _.uniq(
_.flatMap(auth.ROLES)
.concat(_.flatMap(auth.KEYS, 'permissions')),
)
return runInTransaction(tx =>
createAll(tx, permissionNames, auth.ROLES, auth.KEYS, {})
)
}

const app = express()
app.enable('trust proxy')

setup(app, {
configPath: __dirname + '/config.json',
version: require('./package.json').version,
onInitMiddleware,
onInitModel,
onInitHooks,
})
.then(({ startServer, runFromCommandLine }) => {
if (process.argv.length > 2) {
return runFromCommandLine()
}
return startServer(process.env.PORT || 1337)
})
.catch(err => {
console.error('Failed to initialize:', err)
process.exit(1)
})
73 changes: 73 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"name": "@balena/open-balena-api",
"private": true,
"description": "Internet of things, Made Simple",
"version": "0.0.1",
"repository": {
"type": "git",
"url": "https://github.com/balena-io/open-balena-api"
},
"dependencies": {
"@resin.io/device-types": "^10.4.1",
"@resin/pinejs": "^9.0.2",
"@types/basic-auth": "^1.1.2",
"@types/bluebird": "^3.5.23",
"@types/cookie-session": "^2.0.36",
"@types/express": "^4.0.37",
"@types/express-brute": "0.0.35",
"@types/express-brute-redis": "0.0.0",
"@types/ip": "0.0.31",
"@types/jsonwebtoken": "^7.2.7",
"@types/lodash": "4.14.106",
"@types/morgan": "^1.7.35",
"@types/node": "^8.10.36",
"@types/node-uuid": "0.0.28",
"@types/passport-jwt": "^3.0.1",
"@types/randomstring": "^1.1.6",
"@types/raven": "^2.1.2",
"@types/redis": "^2.8.7",
"@types/request": "^2.47.1",
"array-sort": "^1.0.0",
"avsc": "^5.4.6",
"aws-sdk": "^2.342.0",
"basic-auth": "^2.0.1",
"bluebird": "^3.5.2",
"body-parser": "^1.18.3",
"coffee-cache": "^1.0.2",
"coffee-script": "~1.12.6",
"compression": "^1.7.3",
"cookie-parser": "^1.4.1",
"cookie-session": "^1.0.0",
"express": "^4.16.4",
"express-brute": "^1.0.1",
"express-brute-redis": "0.0.1",
"fast-boot": "^1.0.7",
"ip": "^1.0.1",
"ipaddr.js": "^1.3.0",
"jsonwebtoken": "^8.2.2",
"lodash": "^4.17.10",
"memoizee": "^0.4.14",
"method-override": "^2.3.5",
"morgan": "^1.9.1",
"ndjson": "1.5.0",
"node-uuid": "~1.4.0",
"passport": "^0.4.0",
"passport-jwt": "^4.0.0",
"pubnub": "^4.21.6",
"randomstring": "^1.1.5",
"raven": "^2.6.4",
"redis": "^2.8.0",
"request": "^2.85.0",
"resin-device-config": "^4.2.0",
"resin-semver": "^1.4.0",
"supervisor": "^0.12.0",
"thirty-two": "^1.0.0",
"ts-node": "^6.0.3",
"typed-error": "^2.0.0",
"typescript": "^3.1.3"
},
"optionalDependencies": {},
"engines": {
"node": ">=8.0"
}
}
18 changes: 18 additions & 0 deletions src/commands/create-superuser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as _express from 'express';

import { runInTransaction } from '../platform';
import { registerUser } from '../platform/auth';

function usage() {
return 'create-superuser USERNAME EMAIL PASSWORD';
}

export function execute(_app: _express.Application, args: string[]) {
const [username, email, password] = args;
if (username == null || email == null || password == null) {
throw new Error(usage());
}
return runInTransaction(tx =>
registerUser({ username, email, password }, tx),
);
}
Loading

0 comments on commit 3bc2cbf

Please sign in to comment.