commit
be1124ac68
2 changed files with 263 additions and 0 deletions
@ -0,0 +1,244 @@ |
|||
#!/usr/bin/env node
|
|||
|
|||
'use strict'; |
|||
|
|||
var program = require('commander'); |
|||
var http = require('https'); |
|||
var faker = require('faker'); |
|||
|
|||
program |
|||
.usage("<command> [options]") |
|||
.description("Valid commands are : create, cleanup") |
|||
.option("-t, --token <access_token>", "The 3scale Access Token") |
|||
.option("-h, --host <host>", "The 3scale Admin host (ex: acme-admin.3scale.net) ") |
|||
.option("-a, --applications <n>", "The number of applications to create in each account", parseInt) |
|||
.option("-c, --accounts <n>", "The number of accounts to create", parseInt) |
|||
.option("-u, --users <n>", "The number of users to create in each account", parseInt) |
|||
.option("-v, --verbose", "Be verbose") |
|||
.option("-l, --loghttp", "Log HTTP requests") |
|||
.parse(process.argv); |
|||
|
|||
|
|||
// Optional arguments
|
|||
var n_applications = program.applications || 0; |
|||
var n_accounts = program.accounts || 0; |
|||
var n_users = program.users || 0; |
|||
var trace_http = (program.loghttp != null); |
|||
var verbose = (program.verbose != null); |
|||
|
|||
// Mandatory arguments
|
|||
var action = program.args.length > 0 ? program.args[0] : ""; |
|||
var host = program.host |
|||
var access_token = program.token; |
|||
|
|||
// The available application plans
|
|||
var plans = []; |
|||
|
|||
|
|||
function check_mandatory_options() { |
|||
if (program.host == null || program.host == "") { |
|||
console.error("The --host option is mandatory !"); |
|||
process.exit(1); |
|||
} |
|||
if (program.token == null || program.token == "") { |
|||
console.error("The --token option is mandatory !"); |
|||
process.exit(1); |
|||
} |
|||
} |
|||
|
|||
if (action == "create") { |
|||
check_mandatory_options(); |
|||
do_http("GET", "/admin/api/application_plans.json", {}, process_plans); |
|||
} else if (action == "cleanup") { |
|||
check_mandatory_options(); |
|||
do_http("GET", "/admin/api/accounts.json", {}, delete_accounts); |
|||
} else { |
|||
console.log("Valid commands are : create, cleanup"); |
|||
} |
|||
|
|||
|
|||
|
|||
function do_http(method, path, params, callback) { |
|||
var options = { |
|||
host: host, |
|||
method: method, |
|||
path: path |
|||
}; |
|||
|
|||
var encoded_params = ""; |
|||
if (params != null) { |
|||
var tuples = []; |
|||
for (var key in params) { |
|||
if (params.hasOwnProperty(key)) { |
|||
tuples.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key])); |
|||
} |
|||
} |
|||
encoded_params = tuples.join("&"); |
|||
} |
|||
|
|||
if (trace_http) { |
|||
console.log(options.method + " " + options.path + "?access_token=<HIDDEN>" + ((method == "POST" || method == "PUT") ? "" : "&" + encoded_params)); |
|||
} |
|||
|
|||
options.path += "?access_token=" + access_token; |
|||
if (method == "GET") { |
|||
options.path += "&" + encoded_params; |
|||
} |
|||
var req = http.request(options, function(response) { |
|||
var data = ''; |
|||
|
|||
//another chunk of data has been recieved, so append it to `str`
|
|||
response.on('data', function (chunk) { |
|||
data += chunk; |
|||
}); |
|||
|
|||
//the whole response has been recieved, so we just print it out here
|
|||
response.on('end', function () { |
|||
var json_response = JSON.parse(data); |
|||
callback(json_response); |
|||
}); |
|||
}); |
|||
|
|||
req.on('error', function (e) { |
|||
// General error, i.e.
|
|||
// - ECONNRESET - server closed the socket unexpectedly
|
|||
// - ECONNREFUSED - server did not listen
|
|||
// - HPE_INVALID_VERSION
|
|||
// - HPE_INVALID_STATUS
|
|||
// - ... (other HPE_* codes) - server returned garbage
|
|||
console.log(e); |
|||
}); |
|||
req.on('timeout', function () { |
|||
// Timeout happend. Server received request, but not handled it
|
|||
// (i.e. doesn't send any response or it took to long).
|
|||
// You don't know what happend.
|
|||
// It will emit 'error' message as well (with ECONNRESET code).
|
|||
|
|||
console.log('timeout'); |
|||
req.abort(); |
|||
}); |
|||
|
|||
if (method == "POST" || method == "PUT") { |
|||
req.write(encoded_params); |
|||
if (trace_http) { |
|||
console.log(encoded_params); |
|||
console.log(); |
|||
} |
|||
} |
|||
|
|||
req.end(); |
|||
} |
|||
|
|||
function get_a_user() { |
|||
var first_name = faker.name.firstName(); |
|||
var last_name = faker.name.lastName(); |
|||
return { |
|||
username: faker.internet.userName(first_name, last_name), |
|||
email: faker.internet.email(first_name, last_name, "example.test"), |
|||
password: faker.internet.password(), |
|||
name: faker.name.findName(first_name, last_name), |
|||
"x-created-by": "script" |
|||
}; |
|||
} |
|||
|
|||
function get_an_application() { |
|||
return { |
|||
name: faker.commerce.productName(), |
|||
description: faker.company.catchPhrase(), |
|||
"x-created-by": "script" |
|||
}; |
|||
} |
|||
|
|||
function get_an_account() { |
|||
return { |
|||
org_name: faker.company.companyName(), |
|||
"x-created-by": "script" |
|||
}; |
|||
} |
|||
|
|||
function process_plans(json) { |
|||
for (var i in json.plans) { |
|||
var plan = json.plans[i].application_plan; |
|||
if (verbose) { |
|||
console.log("Found an application plan : " + plan.name); |
|||
} |
|||
plans.push(plan.id); |
|||
} |
|||
|
|||
if (verbose) { |
|||
console.log("Creating %j accounts...", n_accounts); |
|||
} |
|||
for (var i = 0; i < n_accounts; i++) { |
|||
var options = get_a_user(); |
|||
options.org_name = get_an_account().org_name; |
|||
|
|||
do_http("POST", "/admin/api/signup.json", options, activate_account); |
|||
} |
|||
} |
|||
|
|||
function activate_account(json) { |
|||
log(json); |
|||
|
|||
if (json.account.state == "created") { |
|||
do_http("PUT", "/admin/api/accounts/"+encodeURIComponent(json.account.id)+"/approve.json", {}, create_account_inner_objects); |
|||
} else { |
|||
create_account_inner_objects(json); |
|||
} |
|||
} |
|||
|
|||
function create_account_inner_objects(json) { |
|||
create_applications(json); |
|||
create_users(json); |
|||
} |
|||
|
|||
function log(object, action) { |
|||
if (verbose) { |
|||
action = action || "create"; |
|||
var type = "unknown"; |
|||
for (var key in object) { |
|||
if (object.hasOwnProperty(key)) { |
|||
type = key; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
var name = object[type].name || object[type].username || object[type].org_name || "unknown"; |
|||
console.log("Just "+action+"d a '"+type+"' with id = "+object[type].id + " and name = "+name); |
|||
} |
|||
} |
|||
|
|||
function create_applications(json) { |
|||
for (var i = 0; i < n_applications; i++) { |
|||
var options = get_an_application(); |
|||
options.plan_id = plans[Math.floor(Math.random()*plans.length)]; // pick a plan at random
|
|||
|
|||
do_http("POST", "/admin/api/accounts/"+encodeURIComponent(json.account.id)+"/applications.json", options, log); |
|||
} |
|||
} |
|||
|
|||
function create_users(json) { |
|||
for (var i = 0; i < n_users; i++) { |
|||
var options = get_a_user(); |
|||
|
|||
do_http("POST", "/admin/api/accounts/"+encodeURIComponent(json.account.id)+"/users.json", options, (json_user) => { activate_user(json_user, json.account.id); }); |
|||
} |
|||
} |
|||
|
|||
function activate_user(json, account_id) { |
|||
log(json); |
|||
if (json.user.state == "pending") { |
|||
do_http("PUT", "/admin/api/accounts/"+encodeURIComponent(account_id)+"/users/"+encodeURIComponent(json.user.id)+"/activate.json", {}, (json) => {}); |
|||
} |
|||
} |
|||
|
|||
function delete_accounts(json) { |
|||
for (var i in json.accounts) { |
|||
var account = json.accounts[i]; |
|||
if (account.account["x-created-by"] == "script") { |
|||
delete_account(account); |
|||
} |
|||
} |
|||
} |
|||
function delete_account(json) { |
|||
do_http("DELETE", "/admin/api/accounts/"+encodeURIComponent(json.account.id)+".json", {}, () => {log(json, "delete");}); |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
{ |
|||
"name": "3scale-account-merger", |
|||
"version": "0.1.0", |
|||
"description": "", |
|||
"main": "index.js", |
|||
"scripts": { |
|||
"test": "echo \"Error: no test specified\" && exit 1" |
|||
}, |
|||
"author": "Nicolas MASSE", |
|||
"license": "MIT", |
|||
"bin": { |
|||
"3scale-loader": "./index.js" |
|||
}, |
|||
"dependencies": { |
|||
"commander": "^2.9.0", |
|||
"faker": "^4.1.0" |
|||
}, |
|||
"repository": "https://github.com/nmasse-itix/3scale-loader.git" |
|||
} |
|||
Loading…
Reference in new issue