Skip to content

Commit

Permalink
Add /os/v2/config endpoint for config.json migration
Browse files Browse the repository at this point in the history
  • Loading branch information
cywang117 committed Sep 4, 2023
1 parent 8261937 commit 010bd7a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 15 deletions.
54 changes: 39 additions & 15 deletions src/features/os-config/index.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,51 @@
import type { Application, RequestHandler } from 'express';
import type { Application } from 'express';

import {
DEVICE_CONFIG_OPENVPN_CA,
DEVICE_CONFIG_OPENVPN_CONFIG,
DEVICE_CONFIG_SSH_AUTHORIZED_KEYS,
LOGS_HOST,
} from '../../lib/config';
import { b64decode } from '../../lib/utils';

const getOsConfiguration: RequestHandler = (_req, res) => {
res.json({
services: {
openvpn: {
config: DEVICE_CONFIG_OPENVPN_CONFIG,
ca: b64decode(DEVICE_CONFIG_OPENVPN_CA),
},
ssh: {
authorized_keys: DEVICE_CONFIG_SSH_AUTHORIZED_KEYS,
},
},
schema_version: '1.0.0',
});
// OS service configurations
const services = {
openvpn: {
config: DEVICE_CONFIG_OPENVPN_CONFIG,
ca: b64decode(DEVICE_CONFIG_OPENVPN_CA),
},
ssh: {
authorized_keys: DEVICE_CONFIG_SSH_AUTHORIZED_KEYS,
},
};

// Config.json migrations: changes should be evaluated for security risks before applying.
//
// - A field with a value of `null` tells os-config that the value will be deleted from config.json.
// - A field with a value of non-null tells os-config that the value will be updated to the new value if it's different.
// - Delete takes precedence over update.
// - A field not found in the whitelist of the os-config schema will be ignored.
const config = {
overrides: {
logsEndpoint: LOGS_HOST != null ? `https://${LOGS_HOST}` : null,
},
};

export const setup = (app: Application) => {
app.get('/os/v1/config/', getOsConfiguration);
app.get('/os/v1/config/', (_req, res) => {
res.json({
services,
schema_version: '1.0.0',
});
});
// This endpoint no longer sees the need to include a schema_version in the response, as os-configs
// that query it all follow the v2 os-config schema. The contract between os-config and this endpoint
// is that os-config should be compatible with all minor changes to `config` as defined above. `config`
// refers to config.json migrations required by the API.
app.get('/os/v2/config', (_req, res) => {
res.json({
services,
config,
});
});
};
34 changes: 34 additions & 0 deletions test/22_os-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { expect } from 'chai';

import { supertest } from './test-lib/supertest';
import { LOGS_HOST } from '../src/lib/config';

describe('OS configuration endpoints', () => {
describe('/os/v1/config', () => {
it('should return a valid JSON response', async () => {
const { body } = await supertest().get('/os/v1/config').expect(200);

expect(body)
.to.have.property('services')
.that.has.all.keys('openvpn', 'ssh');
expect(body).to.have.property('schema_version').that.equals('1.0.0');
});
});

describe('/os/v2/config', () => {
it('should return a valid JSON response', async () => {
const { body } = await supertest().get('/os/v2/config').expect(200);

expect(body)
.to.have.property('services')
.that.has.all.keys('openvpn', 'ssh');
expect(body)
.to.have.property('config')
.that.deep.equals({
overrides: {
logsEndpoint: LOGS_HOST ? `https://${LOGS_HOST}` : null,
},
});
});
});
});

0 comments on commit 010bd7a

Please sign in to comment.