Skip to content
This repository was archived by the owner on Oct 22, 2018. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,31 @@
},
"dependencies": {
"amqplib": "^0.5.2",
"aws-sdk": "^2.166.0",
"aws-sdk": "^2.263.1",
"azure-entities": "^4.0.0",
"debug": "^3.1.0",
"eslint-config-taskcluster": "^3.0.0",
"lodash": "^4.15.0",
"pulse-publisher": "^10.0.0",
"request": "^2.83.0",
"eslint-config-taskcluster": "^3.1.0",
"lodash": "^4.17.10",
"pulse-publisher": "^10.0.1",
"request": "^2.87.0",
"request-promise": "^4.2.2",
"slugid": "^1.1.0",
"slugid": "^2.0.0",
"taskcluster-client": "^11.0.0",
"taskcluster-lib-api": "12.0.0",
"taskcluster-lib-api": "12.0.2",
"taskcluster-lib-app": "^10.0.0",
"taskcluster-lib-azure": "^10.0.0",
"taskcluster-lib-docs": "^10.0.0",
"taskcluster-lib-iterate": "^10.0.0",
"taskcluster-lib-loader": "^10.0.0",
"taskcluster-lib-monitor": "^10.0.0",
"taskcluster-lib-scopes": "^10.0.0",
"taskcluster-lib-validate": "^11.0.1",
"typed-env-config": "^1.1.0"
"taskcluster-lib-validate": "^11.0.2",
"typed-env-config": "^2.0.0"
},
"devDependencies": {
"mocha": "^4.0.1",
"sinon": "^4.1.3",
"taskcluster-lib-testing": "^10.0.0"
"mocha": "^5.2.0",
"sinon": "^6.0.1",
"taskcluster-lib-testing": "^11.3.0"
},
"engine-strict": true,
"engines": {
Expand Down
40 changes: 0 additions & 40 deletions schemas/v1/exchanges-response.yml

This file was deleted.

34 changes: 1 addition & 33 deletions schemas/v1/list-namespaces-response.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,7 @@ properties:
description: |
List of namespaces.
type: array
items:
title: "Namespace"
description: |
Representation of the namespace
type: object
properties:
namespace:
title: "Name"
type: string
description: |
The namespace's name
expires:
description: |
Date-time after which the username, and all associated queues and
exchanges, should be deleted.
type: string
format: date-time
created:
description: Date-time at which this namespace was first claimed.
type: string
format: date-time
contact:
type: string
format: email
description: |
E-mail address that will reach people who can address problems with runaway queue length.
The service will send warning notifications to this address before forcibly deleting the
queue. If omitted, no warnings will be given.
additionalProperties: false
required:
- namespace
- created
- expires
items: {$ref: "namespace.json#"}
continuationToken:
title: "Continuation Token"
type: string
Expand Down
32 changes: 8 additions & 24 deletions schemas/v1/namespace-response.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
$schema: http://json-schema.org/draft-06/schema#
title: "Namespace Creation Response"
title: "Namespace Claim Response"
description: |
Namespace creation response
Namespace claim response
type: object
properties:
namespace:
type: string
title: Namespace
description: The name of the namespace created
created:
description: Date-time at which this namespace was first claimed.
type: string
format: date-time
namespace: {$ref: "namespace.json#/properties/namespace"}
created: {$ref: "namespace.json#/properties/created"}
expires: {$ref: "namespace.json#/properties/expires"}
connectionString:
type: string
title: AMQP URL
Expand All @@ -24,21 +19,10 @@ properties:
password will become invalid a short time after this.
type: string
format: date-time
expires:
description: |
Date-time after which the username, and all associated queues and
exchanges, should be deleted.
type: string
format: date-time
contact:
type: string
format: email
description: |
E-mail address that will reach people who can address problems with runaway queue length.
The service will send warning notifications to this address before forcibly deleting the
queue. If omitted, no warnings will be given.
additionalProperties: false
required:
- namespace
- created
- expires
- connectionString

- reclaimAt
8 changes: 0 additions & 8 deletions schemas/v1/namespace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,8 @@ properties:
description: Date-time at which this namespace was first claimed.
type: string
format: date-time
contact:
type: string
format: email
description: |
E-mail address that will reach people who can address problems with runaway queue length.
The service will send warning notifications to this address before forcibly deleting the
queue.
additionalProperties: false
required:
- namespace
- created
- expires
- contact
27 changes: 0 additions & 27 deletions schemas/v1/rabbit-overview.yml

This file was deleted.

1 change: 0 additions & 1 deletion src/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ Namespace.prototype.json = function({cfg, includePassword}) {
namespace: this.namespace,
created: this.created.toJSON(),
expires: this.expires.toJSON(),
contact: this.contact.length > 0 ? this.contact : undefined,
};
if (includePassword) {
// calculate the reclaimAt as half the rotation interval past the
Expand Down
75 changes: 16 additions & 59 deletions src/v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ let builder = new APIBuilder({
].join('\n'),
serviceName: 'pulse',
version: 'v1',
params: {
namespace: function(namespace) {
if (namespace.length > 64 || !/^[A-Za-z0-9_-]+$/.test(namespace)) {
return 'Invalid namespace provided. Namespaces must be at most 64 bytes and contain only [A-Za-z-0-9_:-]';
}
const prefix = this.cfg.app.namespacePrefix;
if (prefix && !namespace.startsWith(prefix)) {
return `Invalid namespace provided. Namespaces must begin with '${prefix}'`;
}
return false;
},
},
context: [
'cfg',
'rabbitManager',
Expand All @@ -30,31 +42,12 @@ let builder = new APIBuilder({

module.exports = builder;

builder.declare({
method: 'get',
route: '/overview',
name: 'overview',
title: 'Rabbit Overview',
output: 'rabbit-overview.json',
stability: 'experimental',
description: [
'Get an overview of the Rabbit cluster.',
].join('\n'),
}, async function(req, res) {
res.reply(
_.pick(
await this.rabbitManager.overview(),
['rabbitmq_version', 'cluster_name', 'management_version']
)
);
});

builder.declare({
method: 'get',
route: '/namespaces',
name: 'listNamespaces',
stability: 'experimental',
output: 'list-namespaces-response.json',
output: 'list-namespaces-response.yml',
title: 'List Namespaces',
query: {
limit: /[0-9]+/,
Expand Down Expand Up @@ -92,7 +85,7 @@ builder.declare({
route: '/namespace/:namespace',
name: 'namespace',
title: 'Get a namespace',
output: 'namespace.json',
output: 'namespace.yml',
stability: 'experimental',
description: [
'Get public information about a single namespace. This is the same information',
Expand All @@ -101,10 +94,6 @@ builder.declare({
}, async function(req, res) {
let {namespace} = req.params;

if (!isNamespaceValid(namespace, this.cfg)) {
return invalidNamespaceResponse(req, res, this.cfg);
}

let ns = await this.Namespace.load({namespace}, true);
if (!ns) {
return res.reportError('ResourceNotFound', 'No such namespace', {});
Expand All @@ -117,8 +106,8 @@ builder.declare({
route: '/namespace/:namespace',
name: 'claimNamespace',
title: 'Claim a namespace',
input: 'namespace-request.json',
output: 'namespace-response.json',
input: 'namespace-request.yml',
output: 'namespace-response.yml',
scopes: {AllOf:
['pulse:namespace:<namespace>'],
},
Expand All @@ -145,10 +134,6 @@ builder.declare({
// involve abusing pulse), but we can solve this problem if and when we have
// it.

if (!isNamespaceValid(namespace, this.cfg)) {
return invalidNamespaceResponse(req, res, this.cfg);
}

let expires = req.body.expires ? new Date(req.body.expires) : taskcluster.fromNow('4 hours');
let contact = req.body.contact || '';
let newNamespace = await maintenance.claim({
Expand All @@ -161,31 +146,3 @@ builder.declare({
});
res.reply(newNamespace.json({cfg: this.cfg, includePassword: true}));
});

/**
* Report an InvalidNamspeace error to the user
*/
function invalidNamespaceResponse(request, response, cfg) {
let msg = ['Invalid namespace provided. Namespaces must:'];
msg.push('* be at most 64 bytes');
msg.push('* contain only [A-Za-z-0-9_:-]');
if (cfg.app.namespacePrefix) {
msg.push(`* begin with "${cfg.app.namespacePrefix}"`);
}
return response.reportError('InvalidNamespace', msg.join('\n'), {});
}

/**
* Check whether this is a valid namespace name, considering both hard-coded
* limits and the configurable required prefix
*/
function isNamespaceValid(namespace, cfg) {
if (namespace.length > 64 || !/^[A-Za-z0-9_-]+$/.test(namespace)) {
return false;
}
const prefix = cfg.app.namespacePrefix;
if (prefix && !namespace.startsWith(prefix)) {
return false;
}
return true;
}
7 changes: 2 additions & 5 deletions test/api_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ helper.secrets.mockSuite('API', ['taskcluster'], function(mock, skipping) {
helper.withEntities(mock, skipping);
helper.withServer(mock, skipping);

test('overview runs without error', async function() {
await helper.client().overview();
});

test('ping', async function() {
await helper.client().ping();
});
Expand Down Expand Up @@ -122,7 +118,8 @@ helper.secrets.mockSuite('API', ['taskcluster'], function(mock, skipping) {
expires,
contact: 'newperson@a.com',
});
assert(b.contact === 'newperson@a.com');
// contact info isn't returned (ever)
assert(!b.contact);
});

test('entry creation', async () => {
Expand Down
Loading