From 2fa362fddcb3666c1d1f113999a3a17316f78430 Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Thu, 28 Mar 2019 09:22:45 -0400 Subject: [PATCH 01/19] Fix for issue #144, added Target Server commands --- README.md | 54 +++++++++++++++++++++++++++++++++++++++- lib/commands/commands.js | 12 +++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c92ebf6..83ccf51 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,8 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default * [getKVMentry](#getKVMentry) * [deletekvmmap](#deletekvmmap) * [deleteKVMentry](#deleteKVMentry) +* [createTargetServer](#createTargetServer) +* [deleteTargetServer](#deleteTargetServer) ## deploynodeapp @@ -926,6 +928,56 @@ for organization name, all of which are required. `--environment -e` (required) The environment to target. +## Target Server Operations + +### createTargetServer + +Creates a Target Server with the given name. + +#### Example +Create Target Server named "test-target" with SSL enabled. + + apigeetool createTargetServer -N -o $ORG -e $ENV --targetServerName test-target --targetHost httpbin.org --targetPort 443 --targetSSL true + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--environment -e` (required) The environment to target. +`--targetServerName` (required) The name of the Target Server to be created. +`--targetHost` (required) The hostname of the target. +`--targetPort` (required) The port number of the target. +`--targetSSL` (optional) Whether or not SSL is configured, defaults to none. +`--targetEnabled` (optional) Whether or not the Target Server itself is enabled, defaults to true. + +### deleteTargetServer + +Deletes a Target Server with the given name. + +#### Example +Delete Target Server named "test-target". + + apigeetool deleteTargetServer -N -o $ORG -e $ENV --targetServerName test-target + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--environment -e` (required) The environment to target. +`--targetServerName` (required) The name of the Target Server to be deleted. + # SDK Reference You could use apigeetool as an SDK to orchestrate tasks that you want to perform with Edge, for eg, deploying an api proxy or running tests etc. @@ -1073,7 +1125,7 @@ Create App Key in Edge opts.developerId = DEVELOPER_EMAIL; opts.appName = APP_NAME; opts.apiProducts = PRODUCT_NAME; - + sdk.createAppKey(opts) .then(function(result){ //create key/secret success diff --git a/lib/commands/commands.js b/lib/commands/commands.js index a572689..35dd8b7 100644 --- a/lib/commands/commands.js +++ b/lib/commands/commands.js @@ -7,6 +7,18 @@ var Table = require('cli-table'); var options = require('../options'); var Commands = { + createTargetServer: { + description: 'Create a Target Server', + load: function() { + return require('./create-TargetServer'); + } + }, + deleteTargetServer: { + description: 'Delete a Target Server', + load: function() { + return require('./delete-TargetServer'); + } + }, createkvmmap: { description: 'Create a KVM map', load: function() { From f8f32c7454f995a4a7d95e26adfd22292744f035 Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Tue, 17 Sep 2019 13:27:38 -0400 Subject: [PATCH 02/19] Fixes for issues 158,159,160,161,162,163, improved local and remote tests --- README.md | 82 +-- lib/cli.js | 8 +- lib/commands/attachFlowHook.js | 49 ++ lib/commands/commands.js | 30 + lib/commands/create-TargetServer.js | 9 +- lib/commands/delete-TargetServer.js | 3 +- lib/commands/detachFlowHook.js | 40 ++ lib/commands/get-TargetServer.js | 38 ++ lib/commands/getFlowHook.js | 40 ++ lib/commands/list-TargetServers.js | 32 + lib/defaults.js | 26 +- lib/main.js | 29 +- lib/options.js | 45 +- lib/promisesdk.js | 39 +- remotetests/remotetest.js | 994 ++++++++++++++++------------ test/testoptions.js | 27 +- 16 files changed, 991 insertions(+), 500 deletions(-) create mode 100644 lib/commands/attachFlowHook.js create mode 100644 lib/commands/detachFlowHook.js create mode 100644 lib/commands/get-TargetServer.js create mode 100644 lib/commands/getFlowHook.js create mode 100644 lib/commands/list-TargetServers.js diff --git a/README.md b/README.md index 83ccf51..b311f41 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,12 @@ This is a tool for deploying API proxies and Node.js applications to the Apigee You must have an account on Apigee Edge to perform any `apigeetool` functions. These functions include: -* deploying an API proxy to Edge, -* undeploying an API proxy from Edge, +* deploying an API proxy or shared flow to Edge, +* undeploying an API proxy or shared flow from Edge, * deploying Node.js apps to Edge, -* listing deployed API proxies on Edge, -* retrieving deployed proxies and apps from Edge, -* deleting proxy definitions from Edge, and +* listing deployed API proxies or shared flows on Edge, +* retrieving deployed proxies or shared flows from Edge, +* deleting proxy or shared flow definitions from Edge, and * retreiving log messages from Node.js apps deployed to Edge. * create or delete an API product in Edge * create or delete a Developer in Edge @@ -34,6 +34,7 @@ You must have an account on Apigee Edge to perform any `apigeetool` functions. T * create or delete a Cache resource in Edge * create, retrieve or delete a KVM Map in Edge * create, retrieve or delete a KVM Entry in Edge +* attach, detach, or get a FlowHook You need to be familiar with basic concepts and features of Apigee Edge such as API proxies, organizations, and environments. @@ -70,9 +71,6 @@ trusted TLS certificate. (optional) Limit for the maximum number of operations performed concurrently. Currently this only affects file uploads in the `deploynodeapp` command. Defaults to 4. -`--json -j` -(optional) Formats the command's response as a JSON object. - `--organization -o` (required) The name of the organization to deploy to. May be set as an environment variable APIGEE_ORGANIZATION. @@ -93,37 +91,41 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default # Command reference and examples -* [deploynodeapp](#deploynodeapp) -* [deployhostedtarget](#deployhostedtarget) -* [deployproxy](#deployproxy) -* [undeploy](#undeploy) -* [listdeployments](#listdeployments) -* [fetchproxy](#fetchproxy) -* [getlogs](#getlogs) -* [delete](#delete) -* [deploySharedflow](#deploySharedflow) -* [undeploySharedflow](#undeploySharedflow) -* [listSharedflowDeployments](#listSharedflowDeployments) -* [fetchSharedflow](#fetchSharedflow) -* [deleteSharedflow](#deleteSharedflow) +* [addEntryToKVM](#addEntryToKVM) +* [attachFlowHook](#attachFlowHook) +* [createappkey](#createappkey) +* [createapp](#createapp) +* [createcache](#createcache) * [createdeveloper](#createdeveloper) -* [deletedeveloper](#deletedeveloper) +* [createKVMmap](#createKVMmap) * [createproduct](#createproduct) -* [deleteproduct](#deleteproduct) -* [createapp](#createapp) +* [createTargetServer](#createTargetServer) * [deleteapp](#deleteapp) -* [createappkey](#createappkey) -* [createcache](#createcache) * [deletecache](#deletecache) -* [createkvmmap](#createkvmmap) -* [addEntryToKVM](#addEntryToKVM) -* [getkvmmap](#getkvmmap) -* [getKVMentry](#getKVMentry) -* [deletekvmmap](#deletekvmmap) +* [deletedeveloper](#deletedeveloper) * [deleteKVMentry](#deleteKVMentry) -* [createTargetServer](#createTargetServer) +* [deleteKVMmap](#deleteKVMmap) +* [deleteproduct](#deleteproduct) +* [deleteSharedflow](#deleteSharedflow) * [deleteTargetServer](#deleteTargetServer) - +* [delete](#delete) +* [deployhostedtarget](#deployhostedtarget) +* [deploynodeapp](#deploynodeapp) +* [deployproxy](#deployproxy) +* [deploySharedflow](#deploySharedflow) +* [detachFlowHook](#detachFlowHook) +* [fetchproxy](#fetchproxy) +* [fetchSharedflow](#fetchSharedflow) +* [getFlowHook](#getFlowHook) +* [getKVMentry](#getKVMentry) +* [getKVMmap](#getKVMmap) +* [getlogs](#getlogs) +* [getTargetServer](#getTargetServer) +* [listdeployments](#listdeployments) +* [listSharedflowDeployments](#listSharedflowDeployments) +* [listTargetServers](#listTargetServers) +* [undeploySharedflow](#undeploySharedflow) +* [undeploy](#undeploy) ## deploynodeapp @@ -701,14 +703,14 @@ When the `--organization` and `--environment` options are present, the operation When the `--organization` and `--api` options are present, the operation will correspond to the API-scoped KVM. -### createkvmmap +### createKVMmap Creates a map in the Apigee KVM with the given name. #### Example Create KVM map named "test-map" - apigeetool createkvmmap -u sdoe@example.com -o sdoe -e test --mapName test-map + apigeetool createKVMmap -u sdoe@example.com -o sdoe -e test --mapName test-map #### Required parameters @@ -771,7 +773,7 @@ for organization name, all of which are required. `--api -n` (optional) The API to target for an API-scoped KVM operation. -### getkvmmap +### getKVMmap Retrieves an entire KVM map with all of its entries, by name. @@ -779,7 +781,7 @@ Retrieves an entire KVM map with all of its entries, by name. Get map named "test-map". - apigeetool getkvmmap -u sdoe@example.com -o sdoe -e test --mapName test-map + apigeetool getKVMmap -u sdoe@example.com -o sdoe -e test --mapName test-map #### Required parameters @@ -836,7 +838,7 @@ for organization name, all of which are required. `--api -n` (optional) The API to target for an API-scoped KVM operation. -### deletekvmmap +### deleteKVMmap Deletes an entire map from the Apigee KVM along with all of its entries. @@ -844,7 +846,7 @@ Deletes an entire map from the Apigee KVM along with all of its entries. Delete map named "test-map". - apigeetool deletekvmmap -u sdoe@example.com -o sdoe -e test --mapName test-map + apigeetool deleteKVMmap -u sdoe@example.com -o sdoe -e test --mapName test-map #### Required parameters @@ -875,7 +877,7 @@ Deletes a single entry by name from an Apigee KVM map. Delete entry named "test1" from the map named "test-map". - apigeetool deletekvmmap -u sdoe@example.com -o sdoe -e test --mapName test-map --entryName test1 + apigeetool deleteKVMmmap -u sdoe@example.com -o sdoe -e test --mapName test-map --entryName test1 #### Required parameters diff --git a/lib/cli.js b/lib/cli.js index 4c48857..6fd37e6 100755 --- a/lib/cli.js +++ b/lib/cli.js @@ -64,11 +64,9 @@ function runCommand() { } process.exit(6); } - if (!opts.json && commandModule.format) { - console.log(commandModule.format(result)); - } else { - console.log(JSON.stringify(result)); - } + + console.log(result); + process.exit(0); }); } diff --git a/lib/commands/attachFlowHook.js b/lib/commands/attachFlowHook.js new file mode 100644 index 0000000..e8d5dc4 --- /dev/null +++ b/lib/commands/attachFlowHook.js @@ -0,0 +1,49 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + environment: { + name: 'Environment', + shortOption: 'e', + required: true + }, + flowHookName: { + name: 'Flow hook name', + required: true + }, + sharedFlowName: { + name: 'Shared Flow name', + required: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('attachFlowHook: %j', opts); + } + var payload = { + "continueOnError" : true, + "sharedFlow" : opts.sharedFlowName + } + if(opts.targetSSL){ + payload.sSLInfo = {enabled: true} + } + + var uri = util.format('%s/v1/o/%s/e/%s/flowhooks/%s', opts.baseuri, opts.organization, opts.environment, opts.flowHookName); + var requestOpts = { + uri: uri, + method:'POST', + body: payload, + json:true + } + command_utils.run('attachFlowHook',opts, requestOpts, cb) +}; diff --git a/lib/commands/commands.js b/lib/commands/commands.js index 35dd8b7..ef91c22 100644 --- a/lib/commands/commands.js +++ b/lib/commands/commands.js @@ -7,12 +7,42 @@ var Table = require('cli-table'); var options = require('../options'); var Commands = { + attachFlowHook: { + description: 'Attach a Shared Flow to a Flow Hook', + load: function() { + return require('./attachFlowHook'); + } + }, + detachFlowHook: { + description: 'Detach a Shared Flow from a Flow Hook', + load: function() { + return require('./detachFlowHook'); + } + }, + getFlowHook: { + description: 'Get the Shared Flow attached to a Flow Hook', + load: function() { + return require('./getFlowHook'); + } + }, + listTargetServers: { + description: 'List Target Servers', + load: function() { + return require('./list-TargetServers'); + } + }, createTargetServer: { description: 'Create a Target Server', load: function() { return require('./create-TargetServer'); } }, + getTargetServer: { + description: 'Get a Target Server', + load: function() { + return require('./get-TargetServer'); + } + }, deleteTargetServer: { description: 'Delete a Target Server', load: function() { diff --git a/lib/commands/create-TargetServer.js b/lib/commands/create-TargetServer.js index cfa8c6f..6996552 100644 --- a/lib/commands/create-TargetServer.js +++ b/lib/commands/create-TargetServer.js @@ -16,18 +16,21 @@ var descriptor = defaults.defaultDescriptor({ }, targetServerName: { name: 'Target Server Name', - required: true + required: true, + prompt: true }, targetHost: { name: 'Target Host', - required: true + required: true, + prompt: true }, targetEnabled: { name: 'Target Enabled' }, targetPort: { name: 'Target Port', - required: true + required: true, + prompt: true }, targetSSL:{ name: 'SSL Info' diff --git a/lib/commands/delete-TargetServer.js b/lib/commands/delete-TargetServer.js index 35751ea..029ac37 100644 --- a/lib/commands/delete-TargetServer.js +++ b/lib/commands/delete-TargetServer.js @@ -16,7 +16,8 @@ var descriptor = defaults.defaultDescriptor({ }, targetServerName: { name: 'Target Server Name', - required: true + required: true, + prompt: true } }); diff --git a/lib/commands/detachFlowHook.js b/lib/commands/detachFlowHook.js new file mode 100644 index 0000000..f31e5e6 --- /dev/null +++ b/lib/commands/detachFlowHook.js @@ -0,0 +1,40 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + environment: { + name: 'Environment', + shortOption: 'e', + required: true + }, + flowHookName: { + name: 'Flow hook name', + required: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('detachFlowHook: %j', opts); + } + if(opts.targetSSL){ + payload.sSLInfo = {enabled: true} + } + + var uri = util.format('%s/v1/o/%s/e/%s/flowhooks/%s', opts.baseuri, opts.organization, opts.environment, opts.flowHookName); + var requestOpts = { + uri: uri, + method:'DELETE', + json:true + } + command_utils.run('detachFlowHook',opts, requestOpts, cb) +}; diff --git a/lib/commands/get-TargetServer.js b/lib/commands/get-TargetServer.js new file mode 100644 index 0000000..8a9cf6e --- /dev/null +++ b/lib/commands/get-TargetServer.js @@ -0,0 +1,38 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + environment: { + name: 'Environment', + shortOption: 'e', + required: true, + prompt: true + }, + targetServerName: { + name: 'Target Server Name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('getTargetServer: %j', opts); + } + var uri = util.format('%s/v1/o/%s/e/%s/targetservers/%s', opts.baseuri, opts.organization, opts.environment,opts.targetServerName); + var requestOptions = { + uri: uri, + method:'GET', + json:false + } + command_utils.run('getTargetServer', opts,requestOptions,cb) +}; diff --git a/lib/commands/getFlowHook.js b/lib/commands/getFlowHook.js new file mode 100644 index 0000000..d8e6696 --- /dev/null +++ b/lib/commands/getFlowHook.js @@ -0,0 +1,40 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + environment: { + name: 'Environment', + shortOption: 'e', + required: true + }, + flowHookName: { + name: 'Flow hook name', + required: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('getFlowHook: %j', opts); + } + if(opts.targetSSL){ + payload.sSLInfo = {enabled: true} + } + + var uri = util.format('%s/v1/o/%s/e/%s/flowhooks/%s', opts.baseuri, opts.organization, opts.environment, opts.flowHookName); + var requestOpts = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('getFlowHook',opts, requestOpts, cb) +}; diff --git a/lib/commands/list-TargetServers.js b/lib/commands/list-TargetServers.js new file mode 100644 index 0000000..00ccd50 --- /dev/null +++ b/lib/commands/list-TargetServers.js @@ -0,0 +1,32 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + environment: { + name: 'Environment', + shortOption: 'e', + required: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('listTargetServers: %j', opts); + } + var uri = util.format('%s/v1/o/%s/e/%s/targetservers', opts.baseuri, opts.organization, opts.environment); + var requestOptions = { + uri: uri, + method:'GET', + json:false + } + command_utils.run('listTargetServers', opts,requestOptions,cb) +}; diff --git a/lib/defaults.js b/lib/defaults.js index 1843765..c25a082 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -14,17 +14,20 @@ var DefaultDescriptor = { help: { name: 'Help', shortOption: 'h', + scope: 'default', toggle: true }, username: { name: 'Username', shortOption: 'u', + scope: 'default', required: true, prompt: true }, password: { name: 'Password', shortOption: 'p', + scope: 'default', required: true, prompt: true, secure: true @@ -32,6 +35,7 @@ var DefaultDescriptor = { header: { name: 'Header', shortOption: 'H', + scope: 'default', required: false, prompt: false, multiple: true @@ -39,51 +43,55 @@ var DefaultDescriptor = { token: { name: 'Token', shortOption: 't', - required: true, + scope: 'default', + required: false, prompt: false }, netrc: { name: 'netrc', shortOption: 'N', + scope: 'default', required: false, toggle: true }, organization: { name: 'Organization', shortOption: 'o', + scope: 'default', required: true }, baseuri: { name: 'Base URI', - shortOption: 'L' + shortOption: 'L', + scope: 'default' }, debug: { name: 'Debug', shortOption: 'D', - toggle: true + scope: 'default', + toggle: true, }, verbose: { name: 'Verbose', shortOption: 'V', - toggle: true - }, - json: { - name: 'JSON', - shortOption: 'j', + scope: 'default', toggle: true }, cafile: { name: 'CA file', - shortOption: 'c' + shortOption: 'c', + scope: 'default' }, insecure: { name: 'insecure', shortOption: 'k', + scope: 'default', toggle: true }, asynclimit: { name: 'Async limit', shortOption: 'a', + scope: 'default', type: 'int' } }; diff --git a/lib/main.js b/lib/main.js index 82d89b6..e775425 100644 --- a/lib/main.js +++ b/lib/main.js @@ -98,11 +98,21 @@ ApigeeTool.deleteApp = function(opts,cb){ runCommand(cmd, opts, cb); }; +ApigeeTool.listTargetServers = function(opts, cb) { + var cmd = require('./commands/list-TargetServers'); + runCommand(cmd, opts, cb); +}; + ApigeeTool.createTargetServer = function(opts, cb) { var cmd = require('./commands/create-TargetServer'); runCommand(cmd, opts, cb); }; +ApigeeTool.getTargetServer = function (opts, cb) { + var cmd = require('./commands/get-TargetServer.js'); + runCommand(cmd, opts, cb); +}; + ApigeeTool.deleteTargetServer = function(opts,cb){ var cmd = require('./commands/delete-TargetServer'); runCommand(cmd, opts, cb); @@ -113,8 +123,8 @@ ApigeeTool.createKVM = function(opts, cb) { runCommand(cmd, opts, cb); }; -ApigeeTool.getkvmmap = function(opts, cb) { - var cmd = require('./commands/getkvmmap'); +ApigeeTool.getKVMmap = function(opts, cb) { + var cmd = require('./commands/getKVMmap'); runCommand(cmd, opts, cb); }; @@ -163,6 +173,21 @@ ApigeeTool.deleteSharedflow = function (opts, cb) { runCommand(cmd, opts, cb); }; +ApigeeTool.attachFlowHook = function (opts, cb) { + var cmd = require('./commands/attachFlowHook.js'); + runCommand(cmd, opts, cb); +}; + +ApigeeTool.detachFlowHook = function (opts, cb) { + var cmd = require('./commands/detachFlowHook.js'); + runCommand(cmd, opts, cb); +}; + +ApigeeTool.getFlowHook = function (opts, cb) { + var cmd = require('./commands/getFlowHook.js'); + runCommand(cmd, opts, cb); +}; + function runCommand(cmd, opts, cb) { options.validate(opts, cmd.descriptor, function(err) { if (err) { diff --git a/lib/options.js b/lib/options.js index 4da1735..8dc0da4 100644 --- a/lib/options.js +++ b/lib/options.js @@ -47,8 +47,9 @@ module.exports.getopts = function(argv, start, descriptor) { } else { badArg(argv[i]); } + } else { + badArg(argv[i]); } - } else { var shortArg = /^-([A-Za-z])/.exec(argv[i]); @@ -124,27 +125,33 @@ module.exports.validate = function(opts, descriptor, cb) { function checkProperty(opts, descriptor, propName, done) { var desc = descriptor[propName]; + // console.log( "DEBUG " + desc.required + " " + opts[propName] + " " + opts.prompt + " " + desc.prompt + " " + propName); + // console.log( "DEBUG OPTs" + JSON.stringify(opts) ); if (desc === null || desc === undefined) { done(new Error(util.format('Invalid property %s', propName))); return; } - if (desc.required && !opts[propName] && (!opts.prompt && desc.prompt)) { - if (opts.interactive) { - var pn = (desc.name ? desc.name : propName); - prompt(pn, desc.secure, function(err, val) { - if (err) { - done(err); - } else { - if (desc.secure === true) { - opts[propName] = new SecureValue(val); + if (desc.required && !opts[propName]) { + if (desc.prompt && !opts.prompt ) { + if (opts.interactive) { + var pn = (desc.name ? desc.name : propName); + prompt(pn, desc.secure, function(err, val) { + if (err) { + done(err); } else { - opts[propName] = val; + if (desc.secure === true) { + opts[propName] = new SecureValue(val); + } else { + opts[propName] = val; + } + done(); } - done(); - } - }); + }); + } else { + done(new Error(util.format('Missing required option "%s"', propName))); + } } else { - done(new Error(util.format('Missing required option "%s"', propName))); + done(new Error(util.format('Missing required option with no prompt "%s"', propName))); } } else { if (opts[propName] && (desc.secure === true)) { @@ -207,9 +214,13 @@ module.exports.getHelp = function(descriptor) { var tab = new Table(TableFormat); _.each(_.sortBy(_.pairs(descriptor)), function(d) { - tab.push([d[0], + tab.push([ + d[0], (d[1].shortOption ? '-' + d[1].shortOption : ''), - ((d[1].required && !d[1].prompt) ? '(required)': '(optional)')]); + ((d[1].required && !d[1].prompt) ? '(required)': '(optional)'), + ((d[1].name ? d[1].name : 'undefined')), + ((d[1].scope == 'default') ? '' : '(command specific)') + ]); }); return tab.toString(); diff --git a/lib/promisesdk.js b/lib/promisesdk.js index 2d9be0c..c2501b1 100644 --- a/lib/promisesdk.js +++ b/lib/promisesdk.js @@ -161,6 +161,13 @@ ApigeeTool.deleteDeveloper = function(opts){ return cb.promise } +ApigeeTool.listTargetServers = function(opts) { + var cb = q.defer() + var cmd = require('./commands/list-TargetServers'); + runCommand(cmd, opts, cb); + return cb.promise +}; + ApigeeTool.createTargetServer = function(opts) { var cb = q.defer() var cmd = require('./commands/create-TargetServer'); @@ -168,6 +175,13 @@ ApigeeTool.createTargetServer = function(opts) { return cb.promise }; +ApigeeTool.getTargetServer = function(opts) { + var cb = q.defer() + var cmd = require('./commands/get-TargetServer'); + runCommand(cmd, opts, cb); + return cb.promise +}; + ApigeeTool.deleteTargetServer = function(opts){ var cb = q.defer() var cmd = require('./commands/delete-TargetServer'); @@ -197,9 +211,9 @@ ApigeeTool.getKVMentry = function(opts) { return cb.promise } -ApigeeTool.getkvmmap = function(opts) { +ApigeeTool.getKVMmap = function(opts) { var cb = q.defer() - var cmd = require('./commands/getkvmmap'); + var cmd = require('./commands/getKVMmap'); runCommand(cmd, opts, cb); return cb.promise } @@ -232,6 +246,27 @@ ApigeeTool.createAppKey = function(opts) { return cb.promise } +ApigeeTool.attachFlowHook = function(opts) { + var cb = q.defer() + var cmd = require('./commands/attachFlowHook'); + runCommand(cmd, opts, cb); + return cb.promise +} + +ApigeeTool.detachFlowHook = function(opts) { + var cb = q.defer() + var cmd = require('./commands/detachFlowHook'); + runCommand(cmd, opts, cb); + return cb.promise +} + +ApigeeTool.getFlowHook = function(opts) { + var cb = q.defer() + var cmd = require('./commands/getFlowHook'); + runCommand(cmd, opts, cb); + return cb.promise +} + function runCommand(cmd, opts, cb) { options.validate(opts, cmd.descriptor, function(err) { if (err) { diff --git a/remotetests/remotetest.js b/remotetests/remotetest.js index 9f735c5..047805c 100644 --- a/remotetests/remotetest.js +++ b/remotetests/remotetest.js @@ -26,9 +26,9 @@ var MAP_NAME_ENCRYPTED = 'apigee-cli-test-kvm-encrypted'; var SHARED_FLOW_NAME = 'apigee-cli-sf'; var verbose = false; +/* These tests need some TLC, they don't run successfully */ describe('Remote Tests', function() { this.timeout(REASONABLE_TIMEOUT); - var deployedRevision; var deployedUri; @@ -44,7 +44,7 @@ describe('Remote Tests', function() { done(); }); }); - + it('Deploy Apigee Proxy with Promise SDK', function(done) { var opts = baseOpts(); opts.api = APIGEE_PROXY_NAME; @@ -73,149 +73,151 @@ describe('Remote Tests', function() { done(err); }) }); +}); - describe('Products / Developers', function() { - - it('Create Product', function(done){ - var opts = baseOpts() ; - var displayName = 'custom name'; - opts.productName = APIGEE_PRODUCT_NAME; - opts.productDesc = 'abc123'; - opts.displayName = displayName; - opts.proxies = APIGEE_PROXY_NAME; - opts.quota = '1'; - opts.quotaInterval = '1'; - opts.quotaTimeUnit = 'minute'; - - var sdk = apigeetool.getPromiseSDK() - - sdk.createProduct(opts) - .then(function(result){ - try { - assert.equal(result.displayName, displayName); - done(); - } catch (e) { - done(e); - } - },function(err){ - done(err) - }) ; - }); +describe('Products / Developers', function() { + this.timeout(REASONABLE_TIMEOUT); - it('Create Private Product', function(done){ - var opts = baseOpts() ; - var displayName = 'custom name'; - opts.productName = APIGEE_PRIVATE_PRODUCT_NAME; - opts.productDesc = 'abc123'; - opts.displayName = displayName; - opts.proxies = APIGEE_PROXY_NAME; - opts.quota = '1'; - opts.quotaInterval = '1'; - opts.quotaTimeUnit = 'minute'; - opts.attributes = [ {"name": "access", "value": "private"} ]; - var sdk = apigeetool.getPromiseSDK() - - sdk.createProduct(opts) - .then(function(result){ - try { - assert.equal(result.displayName, displayName); - assert.equal(result.attributes.length, 1); - assert.equal(result.attributes[0].name, 'access'); - assert.equal(result.attributes[0].value, 'private'); - done(); - } catch (e) { - done(e); - } - },function(err){ - done(err) - }) ; - }); + it('Create Product', function(done){ + var opts = baseOpts() ; + var displayName = 'custom name'; + opts.productName = APIGEE_PRODUCT_NAME; + opts.productDesc = 'abc123'; + opts.displayName = displayName; + opts.proxies = APIGEE_PROXY_NAME; + opts.quota = '1'; + opts.quotaInterval = '1'; + opts.quotaTimeUnit = 'minute'; + opts.approvalType = "auto"; - it('Create Developer' , function(done){ - var opts = baseOpts() - opts.email = DEVELOPER_EMAIL - opts.firstName = 'Test' - opts.lastName = 'Test1' - opts.userName = 'runningFromTest123' - - var sdk = apigeetool.getPromiseSDK() - - sdk.createDeveloper(opts) - .then(function(result){ - done() - },function(err){ - done(err) - }) ; - }); + var sdk = apigeetool.getPromiseSDK() - it('Create App' , function(done){ - var opts = baseOpts() - opts.name = APP_NAME - opts.apiproducts = APIGEE_PRODUCT_NAME - opts.email = DEVELOPER_EMAIL + sdk.createProduct(opts) + .then(function(result){ + try { + assert.equal(result.displayName, displayName); + done(); + } catch (e) { + done(e); + } + },function(err){ + done(err) + }) ; + }); - var sdk = apigeetool.getPromiseSDK() + it('Create Private Product', function(done){ + var opts = baseOpts() ; + var displayName = 'custom name'; + opts.productName = APIGEE_PRIVATE_PRODUCT_NAME; + opts.productDesc = 'abc123'; + opts.displayName = displayName; + opts.proxies = APIGEE_PROXY_NAME; + opts.quota = '1'; + opts.quotaInterval = '1'; + opts.quotaTimeUnit = 'minute'; + opts.attributes = [ {"name": "access", "value": "private"} ]; + var sdk = apigeetool.getPromiseSDK() - sdk.createApp(opts) - .then(function(result){ - done() - },function(err){ - done(err) - }) ; - }); + sdk.createProduct(opts) + .then(function(result){ + try { + assert.equal(result.displayName, displayName); + assert.equal(result.attributes.length, 1); + assert.equal(result.attributes[0].name, 'access'); + assert.equal(result.attributes[0].value, 'private'); + done(); + } catch (e) { + done(e); + } + },function(err){ + done(err) + }) ; + }); - it('Delete App' , function(done){ - var opts = baseOpts() - opts.email = DEVELOPER_EMAIL - opts.name = APP_NAME - var sdk = apigeetool.getPromiseSDK() - sdk.deleteApp(opts) - .then(function(result){ - done() - },function(err){ - done(err) - }) ; - }); + it('Create Developer' , function(done){ + var opts = baseOpts() + opts.email = DEVELOPER_EMAIL + opts.firstName = 'Test' + opts.lastName = 'Test1' + opts.userName = 'runningFromTest123' - it('Delete Developer' , function(done){ - var opts = baseOpts() - opts.email = DEVELOPER_EMAIL - var sdk = apigeetool.getPromiseSDK() - sdk.deleteDeveloper(opts) - .then(function(result){ - done() - },function(err){ - done(err) - }) ; - }); + var sdk = apigeetool.getPromiseSDK() - it('Delete API Product',function(done){ - var opts = baseOpts() ; - opts.productName = APIGEE_PRODUCT_NAME - - var sdk = apigeetool.getPromiseSDK() - - sdk.deleteProduct(opts) - .then(function(result){ - done() - },function(err){ - done(err) - }) ; - }); + sdk.createDeveloper(opts) + .then(function(result){ + done() + },function(err){ + done(err) + }) ; + }); - it('Delete API private Product',function(done){ - var opts = baseOpts() ; - opts.productName = APIGEE_PRIVATE_PRODUCT_NAME - - var sdk = apigeetool.getPromiseSDK() - - sdk.deleteProduct(opts) - .then(function(result){ - done() - },function(err){ - done(err) - }) ; - }); + it('Create App' , function(done){ + var opts = baseOpts() + opts.name = APP_NAME + opts.apiproducts = APIGEE_PRODUCT_NAME + opts.email = DEVELOPER_EMAIL + + var sdk = apigeetool.getPromiseSDK() + + sdk.createApp(opts) + .then(function(result){ + done() + },function(err){ + done(err) + }); + }); + + it('Delete App' , function(done){ + var opts = baseOpts() + opts.email = DEVELOPER_EMAIL + opts.name = APP_NAME + var sdk = apigeetool.getPromiseSDK() + sdk.deleteApp(opts) + .then(function(result){ + done() + },function(err){ + done(err) + }) ; + }); + + it('Delete Developer' , function(done){ + var opts = baseOpts() + opts.email = DEVELOPER_EMAIL + var sdk = apigeetool.getPromiseSDK() + sdk.deleteDeveloper(opts) + .then(function(result){ + done() + },function(err){ + done(err) + }) ; + }); + + it('Delete API Product',function(done){ + var opts = baseOpts() ; + opts.productName = APIGEE_PRODUCT_NAME + + var sdk = apigeetool.getPromiseSDK() + + sdk.deleteProduct(opts) + .then(function(result){ + done() + },function(err){ + done(err) + }) ; + }); + + it('Delete API private Product',function(done){ + var opts = baseOpts() ; + opts.productName = APIGEE_PRIVATE_PRODUCT_NAME + + var sdk = apigeetool.getPromiseSDK() + + sdk.deleteProduct(opts) + .then(function(result){ + done() + },function(err){ + done(err) + }) ; }); it('Deploy Apigee Proxy', function(done) { @@ -648,162 +650,165 @@ describe('Remote Tests', function() { } }); }); +}); - describe('Hosted Target', function() { +describe('Hosted Target', function() { - it('Deploy Hosted Targets App', function(done) { - var opts = baseOpts(); - opts.api = HOSTED_TARGETS_PROXY_NAME; - opts.directory = path.join(__dirname, '../test/fixtures/hellohostedtargets'); - opts.main = 'server.js'; - opts['base-path'] = '/cli-hosted-targets-test'; + it('Deploy Hosted Targets App', function(done) { + var opts = baseOpts(); + opts.api = HOSTED_TARGETS_PROXY_NAME; + opts.directory = path.join(__dirname, '../test/fixtures/hellohostedtargets'); + opts.main = 'server.js'; + opts['base-path'] = '/cli-hosted-targets-test'; - apigeetool.deployHostedTarget(opts, function(err, result) { - if (verbose) { - console.log('Deploy result = %j', result); - } - if (err) { - done(err); - } else { - try { - if(Array.isArray(result)) result = result[0] - assert.equal(result.name, HOSTED_TARGETS_PROXY_NAME); - assert.equal(result.environment, config.environment); - assert.equal(result.state, 'deployed'); - //it will be 2 for remote testing public cloud/ http & https - assert.equal(result.uris.length, 2); - assert(typeof result.revision === 'number'); - deployedRevision = result.revision; - deployedUri = result.uris[0]; - setTimeout(done, 10000); - } catch (e) { - done(e); - } + apigeetool.deployHostedTarget(opts, function(err, result) { + if (verbose) { + console.log('Deploy result = %j', result); + } + if (err) { + done(err); + } else { + try { + if(Array.isArray(result)) result = result[0] + assert.equal(result.name, HOSTED_TARGETS_PROXY_NAME); + assert.equal(result.environment, config.environment); + assert.equal(result.state, 'deployed'); + //it will be 2 for remote testing public cloud/ http & https + assert.equal(result.uris.length, 2); + assert(typeof result.revision === 'number'); + deployedRevision = result.revision; + deployedUri = result.uris[0]; + setTimeout(done, 10000); + } catch (e) { + done(e); } - }); + } }); + }); - it('List Deployments by app', function(done) { - var opts = baseOpts(); - delete opts.environment; - opts.api = HOSTED_TARGETS_PROXY_NAME; - opts.long = true; - - apigeetool.listDeployments(opts, function(err, result) { - if (verbose) { - console.log('List result = %j', result); - } - if (err) { - done(err); - } else { - var deployment = _.find(result.deployments, function(d) { - return (d.name === HOSTED_TARGETS_PROXY_NAME); - }); - try { - assert.equal(deployment.name, HOSTED_TARGETS_PROXY_NAME); - assert.equal(deployment.environment, config.environment); - assert.equal(deployment.state, 'deployed'); - assert.equal(deployment.revision, deployedRevision); - assert.equal(deployment.uris.length, 2); - assert.equal(deployment.uris[0], deployedUri); - done(); - } catch (e) { - done(e); - } - } - }); - }); + it('List Deployments by app', function(done) { + var opts = baseOpts(); + delete opts.environment; + opts.api = HOSTED_TARGETS_PROXY_NAME; + opts.long = true; - it('Verify deployed URI', function(done) { + apigeetool.listDeployments(opts, function(err, result) { if (verbose) { - console.log('Testing %s', deployedUri); + console.log('List result = %j', result); } - request(deployedUri, function(err, resp, body) { - if (err) { - console.error(err, resp.statusCode, body); - done(err); - } else { - try { - assert.equal(resp.statusCode, 200); - done(); - } catch (e) { - done(e); - } + if (err) { + done(err); + } else { + var deployment = _.find(result.deployments, function(d) { + return (d.name === HOSTED_TARGETS_PROXY_NAME); + }); + try { + assert.equal(deployment.name, HOSTED_TARGETS_PROXY_NAME); + assert.equal(deployment.environment, config.environment); + assert.equal(deployment.state, 'deployed'); + assert.equal(deployment.revision, deployedRevision); + assert.equal(deployment.uris.length, 2); + assert.equal(deployment.uris[0], deployedUri); + done(); + } catch (e) { + done(e); } - }); + } }); + }); - it('Check build logs from deployed URI', function(done) { - var opts = baseOpts(); - opts['hosted-build'] = true; - opts.api = HOSTED_TARGETS_PROXY_NAME; - - var logStream = new stream.PassThrough(); - logStream.setEncoding('utf8'); - opts.stream = logStream; - apigeetool.getLogs(opts, function(err) { - assert.ifError(err); - - var allLogs = ''; - logStream.on('data', function(chunk) { - allLogs += chunk; - }); - logStream.on('end', function() { - assert(/DONE/.test(allLogs)); + it('Verify deployed URI', function(done) { + if (verbose) { + console.log('Testing %s', deployedUri); + } + request(deployedUri, function(err, resp, body) { + if (err) { + console.error(err, resp.statusCode, body); + done(err); + } else { + try { + assert.equal(resp.statusCode, 200); done(); - }); + } catch (e) { + done(e); + } + } + }); + }); + + it('Check build logs from deployed URI', function(done) { + var opts = baseOpts(); + opts['hosted-build'] = true; + opts.api = HOSTED_TARGETS_PROXY_NAME; + + var logStream = new stream.PassThrough(); + logStream.setEncoding('utf8'); + opts.stream = logStream; + apigeetool.getLogs(opts, function(err) { + assert.ifError(err); + + var allLogs = ''; + logStream.on('data', function(chunk) { + allLogs += chunk; + }); + logStream.on('end', function() { + assert(/DONE/.test(allLogs)); + done(); }); }); + }); - it('Check runtime logs from deployed URI', function(done) { - var opts = baseOpts(); - opts['hosted-runtime'] = true; - opts.api = HOSTED_TARGETS_PROXY_NAME; + it('Check runtime logs from deployed URI', function(done) { + var opts = baseOpts(); + opts['hosted-runtime'] = true; + opts.api = HOSTED_TARGETS_PROXY_NAME; - var logStream = new stream.PassThrough(); - logStream.setEncoding('utf8'); - opts.stream = logStream; + var logStream = new stream.PassThrough(); + logStream.setEncoding('utf8'); + opts.stream = logStream; - apigeetool.getLogs(opts, function(err) { - assert.ifError(err); + apigeetool.getLogs(opts, function(err) { + assert.ifError(err); - var allLogs = ''; - logStream.on('data', function(chunk) { - allLogs += chunk; - }); - logStream.on('end', function() { - //Validate runtime logs - assert(/Node HTTP server is listening/.test(allLogs)); - done(); - }); + var allLogs = ''; + logStream.on('data', function(chunk) { + allLogs += chunk; + }); + logStream.on('end', function() { + //Validate runtime logs + assert(/Node HTTP server is listening/.test(allLogs)); + done(); }); }); + }); - it('Undeploy Hosted Targets App Without Revision', function(done) { - var opts = baseOpts(); - opts.api = HOSTED_TARGETS_PROXY_NAME; + it('Undeploy Hosted Targets App Without Revision', function(done) { + var opts = baseOpts(); + opts.api = HOSTED_TARGETS_PROXY_NAME; - apigeetool.undeploy(opts, function(err, result) { - if (verbose) { - console.log('Undeploy result = %j', result); - } - if (err) { - done(err); - } else { - try { - assert.equal(result.name, HOSTED_TARGETS_PROXY_NAME); - assert.equal(result.environment, config.environment); - assert.equal(result.state, 'undeployed'); - assert.equal(result.revision, deployedRevision); - done(); - } catch (e) { - done(e); - } + apigeetool.undeploy(opts, function(err, result) { + if (verbose) { + console.log('Undeploy result = %j', result); + } + if (err) { + done(err); + } else { + try { + assert.equal(result.name, HOSTED_TARGETS_PROXY_NAME); + assert.equal(result.environment, config.environment); + assert.equal(result.state, 'undeployed'); + assert.equal(result.revision, deployedRevision); + done(); + } catch (e) { + done(e); } - }); + } }); - }); // end hosted target tests + }); +}); // end hosted target tests +/* End of tests that need TLC */ +describe('Caches', function() { it('Create an Cache Resource',function(done){ var opts = baseOpts(); opts.cache = CACHE_RESOURCE_NAME; @@ -833,9 +838,30 @@ describe('Remote Tests', function() { } }); }); +}); // end cache tests + +describe('Target Servers', function() { + this.timeout(REASONABLE_TIMEOUT); + + it('List Target Servers SDK',function(done){ + var opts = baseOpts(); + opts.environment = config.environment; + apigeetool.getPromiseSDK() + .listTargetServers(opts) + .then(function(res){ + if (verbose) { + console.log('List Target Servers result = %j', res); + } + done() + },function(err){ + console.log(err) + done(err) + }) + }); - it('Create Target Server',function(done){ + it('Create Target Server SDK',function(done){ var opts = baseOpts(); + opts.environment = config.environment; opts.targetServerName = TARGET_SERVER_NAME; opts.targetHost = 'localhost'; opts.targetEnabled = true; @@ -844,20 +870,98 @@ describe('Remote Tests', function() { opts.environment = config.environment; apigeetool.getPromiseSDK() .createTargetServer(opts) - .then(function(){done()}, - function(err){ - console.log(err) - done(err)}) + .then(function(res){ + if (verbose) { + console.log('Create Target Server result = %j', res); + } + done() + },function(err){ + console.log(err) + done(err) + }) }); - it('Delete Target Server',function(done){ + it('Get Target Server SDK',function(done){ var opts = baseOpts(); + opts.environment = config.environment; opts.targetServerName = TARGET_SERVER_NAME; + apigeetool.getPromiseSDK() + .getTargetServer(opts) + .then(function(res){ + if (verbose) { + console.log('Get Target Server result = %j', res); + } + done() + },function(err){ + console.log(err) + done(err) + }) + }); + + it('Delete Target Server SDK',function(done){ + var opts = baseOpts(); opts.environment = config.environment; + opts.targetServerName = TARGET_SERVER_NAME; + apigeetool.getPromiseSDK() + .deleteTargetServer(opts) + .then(function(res){ + if (verbose) { + console.log('Delete Target Server result = %j', res); + } + done() + },function(err){ + console.log(err) + done(err) + }) + }); + +}); // end target server tests - apigeetool.deleteTargetServer(opts,function(err,result) { +describe('KVM', function() { + it('Create KVM',function(done){ + var opts = baseOpts(); + opts.mapName = MAP_NAME; + opts.environment = config.environment; + apigeetool.getPromiseSDK() + .createKVM(opts) + .then(function(res){ + if (verbose) { + console.log('Create KVM result = %j', res); + } + done() + },function(err){ + console.log(err) + done(err) + }) + }); + + it('Create Encrypted KVM',function(done){ + var opts = baseOpts(); + opts.mapName = MAP_NAME_ENCRYPTED; + opts.environment = config.environment; + opts.encrypted = true; + apigeetool.getPromiseSDK() + .createKVM(opts) + .then(function(res){ + if (!res.encrypted) { + return done(new Error('Map was not encrypted')); + } else if (verbose) { + console.log('Create KVM result = %j', res); + } + done(); + }, function(err){ + console.log(err) + done(err) + }) + }); + + it('Delete Encrypted KVM',function(done){ + var opts = baseOpts(); + opts.mapName = MAP_NAME_ENCRYPTED; + opts.environment = config.environment; + apigeetool.deleteKVM(opts,function(err,result) { if (verbose) { - console.log('Delete TargetServer result = %j', result); + console.log('Delete Encrypted KVM result = %j', result); } if (err) { done(err); @@ -867,175 +971,233 @@ describe('Remote Tests', function() { }); }); - describe('KVM', function() { - it('Create KVM',function(done){ - var opts = baseOpts(); - opts.mapName = MAP_NAME; - opts.environment = config.environment; - apigeetool.getPromiseSDK() - .createKVM(opts) - .then(function(){done()}, - function(err){ - console.log(err) - done(err)}) + it('Add Entry to KVM',function(done){ + // This will not work for non-cps orgs + var opts = baseOpts(); + opts.mapName = MAP_NAME; + opts.environment = config.environment; + opts.entryName = 'test'; + opts.entryValue = 'test1'; + apigeetool.getPromiseSDK() + .addEntryToKVM(opts) + .then(function(res){ + if (verbose) { + console.log('Add Entry to KVM result = %j', res); + } + done() + },function(err){ + console.log(err) + done(err) + }) + }); + + it('Get KVM Entry', function(done) { + var opts = baseOpts(); + opts.mapName = MAP_NAME; + opts.environment = config.environment; + opts.entryName = 'test'; + apigeetool.getPromiseSDK() + .getKVMentry(opts) + .then(function(body){ + if (verbose) { + console.log('Get KVM Entry result = %j', body); + } + assert.equal(body.value, 'test1') + done() + }, + function(err) { + console.log(err); + done(err); + }) + }); + + it('Get KVM Map', function(done) { + var opts = baseOpts(); + opts.mapName = MAP_NAME; + opts.environment = config.environment; + apigeetool.getPromiseSDK() + .getKVMmap(opts) + .then(function(body){ + if (verbose) { + console.log('Get KVM Map result = %j', body); + } + assert.equal(body.entry.length, 1) + done() + }, + function(err) { + console.log(err); + done(err); + }) + }); + + it('Delete KVM Entry', function(done) { + var opts = baseOpts(); + opts.mapName = MAP_NAME; + opts.environment = config.environment; + opts.entryName = 'test'; + apigeetool.getPromiseSDK() + .deleteKVMentry(opts) + .then(function(body){ + if (verbose) { + console.log('Get KVM Map result = %j', body); + } + assert.equal(body.value, 'test1') + done() + }, + function(err) { + console.log(err); + done(err); + }) + }); + + it('Delete KVM',function(done){ + var opts = baseOpts(); + opts.mapName = MAP_NAME; + opts.environment = config.environment; + apigeetool.deleteKVM(opts,function(err,result) { + if (verbose) { + console.log('Delete KVM result = %j', result); + } + if (err) { + done(err); + } else { + done() + } }); + }); +}); // end KVM tests - it('Create Encrypted KVM',function(done){ - var opts = baseOpts(); - opts.mapName = MAP_NAME_ENCRYPTED; - opts.environment = config.environment; - opts.encrypted = true; - apigeetool.getPromiseSDK() - .createKVM(opts) - .then(function(res){ - if (!res.encrypted) { - return done(new Error('Map was not encrypted')); +describe('SharedFlows and FlowHooks', function() { + this.timeout(REASONABLE_TIMEOUT); + it('Deploy SharedFlow', function (done) { + var opts = baseOpts(); + var deployedRevision; + opts.name = SHARED_FLOW_NAME; + opts.directory = path.join(__dirname, '../test/fixtures/employees-sf'); + apigeetool.deploySharedflow(opts, function (err, result) { + if (verbose) { + console.log('Deploy result = %j', result); + } + if (err) { + done(err); + } else { + try { + if (Array.isArray(result)) { + result = result[0] } + assert.equal(result.name, SHARED_FLOW_NAME); + assert.equal(result.environment, config.environment); + assert.equal(result.state, 'deployed'); + // assert.equal(result.uris.length, 1); + assert(typeof result.revision === 'number'); + deployedRevision = result.revision; + // deployedUri = result.uris[0]; done(); - }, function(err){ - console.log(err) - done(err) - }) - }); - - it('Add Entry to KVM',function(done){ - // This will not work for non-cps orgs - var opts = baseOpts(); - opts.mapName = MAP_NAME; - opts.environment = config.environment; - opts.entryName = 'test'; - opts.entryValue = 'test1'; - apigeetool.getPromiseSDK() - .addEntryToKVM(opts) - .then(function(){done()}, - function(err){ - console.log(err); - done(err)}) + } catch (e) { + done(e); + } + } }); + }); - it('Get KVM Entry', function(done) { - var opts = baseOpts(); - opts.mapName = MAP_NAME; - opts.environment = config.environment; - opts.entryName = 'test'; - apigeetool.getPromiseSDK() - .getKVMentry(opts) - .then(function(body){ - assert.equal(body.value, 'test1') - done() - }, - function(err) { - console.log(err); - done(err); - }) - }) + it('listSharedflowDeployments'); // Until MGMT-3671 is merged, will not work - it('Get KVM Map', function(done) { - var opts = baseOpts(); - opts.mapName = MAP_NAME; - opts.environment = config.environment; - apigeetool.getPromiseSDK() - .getkvmmap(opts) - .then(function(body){ - assert.equal(body.entry.length, 1) - done() - }, - function(err) { - console.log(err); - done(err); - }) - }) + it('fetchSharedflow'); - it('Delete KVM Entry', function(done) { - var opts = baseOpts(); - opts.mapName = MAP_NAME; - opts.environment = config.environment; - opts.entryName = 'test'; - apigeetool.getPromiseSDK() - .deleteKVMentry(opts) - .then(function(body){ - assert.equal(body.value, 'test1') - done() - }, - function(err) { - console.log(err); - done(err); - }) - }) + var prevSharedFlow; + it('getPreviousSharedFlow', function(done) { + var opts = baseOpts(); + opts.flowHookName = "PreProxyFlowHook"; - it('Delete KVM',function(done){ - var opts = baseOpts(); - opts.mapName = MAP_NAME; - opts.environment = config.environment; - apigeetool.deleteKVM(opts,function(err,result) { - if (verbose) { - console.log('Delete KVM result = %j', result); - } - if (err) { - done(err); - } else { - done() + apigeetool.getFlowHook(opts, function(err, result) { + if (verbose) { + console.log('getFlowhook result = %j', result); + } + if (err) { + done(err); + } else { + if( result.sharedFlow ) { + prevSharedFlow = result.sharedFlow; } - }); + done(); + } }); - }) + }); + it('attachFlowhook', function(done) { + var opts = baseOpts(); + opts.flowHookName = "PreProxyFlowHook"; + opts.sharedFlowName = SHARED_FLOW_NAME; - describe('SharedFlows', function() { - it('Deploy SharedFlow', function (done) { - var opts = baseOpts(); - opts.name = SHARED_FLOW_NAME; - opts.directory = path.join(__dirname, '../test/fixtures/employees-sf'); - apigeetool.deploySharedflow(opts, function (err, result) { - if (verbose) { - console.log('Deploy result = %j', result); - } - if (err) { - done(err); - } else { - try { - if (Array.isArray(result)) { - result = result[0] - } - assert.equal(result.name, SHARED_FLOW_NAME); - assert.equal(result.environment, config.environment); - assert.equal(result.state, 'deployed'); - // assert.equal(result.uris.length, 1); - assert(typeof result.revision === 'number'); - deployedRevision = result.revision; - // deployedUri = result.uris[0]; - done(); - } catch (e) { - done(e); - } - } - }); + apigeetool.attachFlowHook(opts, function(err, result) { + if (verbose) { + console.log('attachFlowHook result = %j', result); + } + if (err) { + done(err); + } else { + done(); + } }); + }); - it('listSharedflowDeployments'); // Until MGMT-3671 is merged, will not work + it('detachFlowHook', function(done) { + var opts = baseOpts(); + opts.flowHookName = "PreProxyFlowHook"; - it('fetchSharedflow'); + apigeetool.detachFlowHook(opts, function(err, result) { + if (verbose) { + console.log('detachFlowHook result = %j', result); + } + if (err) { + done(err); + } else { + done(); + } + }); + }); - it('undeploySharedflow', function(done) { + it('re-attachFlowHook', function(done) { + if( prevSharedFlow ) { var opts = baseOpts(); - opts.name = SHARED_FLOW_NAME; + opts.flowHookName = "PreProxyFlowHook"; + opts.sharedFlowName = prevSharedFlow; - apigeetool.undeploySharedflow(opts, function(err, result) { + apigeetool.attachFlowHook(opts, function(err, result) { + if (verbose) { + console.log('prevSharedFlow ' + prevSharedFlow ); + console.log('re-attachFlowHook result = %j', result); + } if (err) { done(err); - } else { // If response is non-200 it throws an Error + } else { done(); } }); - }); + } else { + done(); + } + }); - it('deleteSharedflow', function(done) { - var opts = baseOpts(); - opts.name = SHARED_FLOW_NAME; - apigeetool.deleteSharedflow(opts, done); + it('undeploySharedflow', function(done) { + var opts = baseOpts(); + opts.name = SHARED_FLOW_NAME; + + apigeetool.undeploySharedflow(opts, function(err, result) { + if (err) { + done(err); + } else { // If response is non-200 it throws an Error + done(); + } }); - }) -}); + }); + + it('deleteSharedflow', function(done) { + var opts = baseOpts(); + opts.name = SHARED_FLOW_NAME; + apigeetool.deleteSharedflow(opts, done); + }); +}); // end shared flow and flow hook tests function baseOpts() { var o = { diff --git a/test/testoptions.js b/test/testoptions.js index 05b0956..ac2bfbf 100644 --- a/test/testoptions.js +++ b/test/testoptions.js @@ -31,7 +31,21 @@ describe('Options parsing test', function(done) { bar: { required: false, prompt: false }, baz: { required: true, prompt: true } }; - var opts = { foo: 1, bar: 'baz'}; + var opts = { foo: 1, bar: 'value'}; + options.validate(opts, desc, function(err) { + assert(err); + assert(/Missing required option/.test(err.message)); + done(); + }); + }); + + it('Test missing option prompt false', function(done) { + var desc = { + foo: {}, + ping: { required: false, prompt: false }, + pong: { required: true, prompt: false } + }; + var opts = { foo: 1, ping: 1}; options.validate(opts, desc, function(err) { assert(err); assert(/Missing required option/.test(err.message)); @@ -101,13 +115,16 @@ describe('Options parsing test', function(done) { it('Test command-line help', function() { var desc = { - foo: {}, - bar: { required: false, shortOption: 'b' }, - baz: { required: true } + foo: { }, + ping: { name: 'Ping', required: false, prompt: false }, + pong: { name: 'Pong', required: true, prompt: false } }; + var opts = { ping: 1, pong: 'value'}; var help = options.getHelp(desc); - //console.log('Help is:' + help); + // console.log('Help is: ' + help); + assert.notEqual( help, undefined ); }); + it('Test command-line toggle', function() { var desc = { foo: {}, From db6ebe7bcf4d1dd2d27a7f27a81c4110ef4c3e83 Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Fri, 20 Sep 2019 14:53:04 -0400 Subject: [PATCH 03/19] Fixed issue #165, all remotetests run correctly and leave no remnants --- .gitignore | 3 +- README.md | 17 +- lib/cli.js | 4 +- lib/commands/assignUserRole.js | 41 ++++ lib/commands/attachFlowHook.js | 6 +- lib/commands/command-utils.js | 2 +- lib/commands/commands.js | 60 ++++++ lib/commands/createRole.js | 39 ++++ lib/commands/delete-TargetServer.js | 2 +- lib/commands/deleteRole.js | 32 +++ lib/commands/fetchproxy.js | 2 +- lib/commands/fetchsharedflow.js | 2 +- lib/commands/get-TargetServer.js | 2 +- lib/commands/getRole.js | 32 +++ lib/commands/getRolePermissions.js | 32 +++ lib/commands/getRoleUsers.js | 33 +++ lib/commands/getRoles.js | 27 +++ lib/commands/list-TargetServers.js | 2 +- lib/commands/listsharedflowdeployments.js | 4 - lib/commands/removeUserRole.js | 38 ++++ lib/commands/setRolePermissions.js | 45 ++++ lib/commands/verifyUserRole.js | 38 ++++ lib/main.js | 41 ++++ lib/promisesdk.js | 61 ++++++ remotetests/remotetest.js | 244 +++++++++++++++++++++- remotetests/testconfig-sample.js | 10 +- 26 files changed, 792 insertions(+), 27 deletions(-) create mode 100644 lib/commands/assignUserRole.js create mode 100644 lib/commands/createRole.js create mode 100644 lib/commands/deleteRole.js create mode 100644 lib/commands/getRole.js create mode 100644 lib/commands/getRolePermissions.js create mode 100644 lib/commands/getRoleUsers.js create mode 100644 lib/commands/getRoles.js create mode 100644 lib/commands/removeUserRole.js create mode 100644 lib/commands/setRolePermissions.js create mode 100644 lib/commands/verifyUserRole.js diff --git a/.gitignore b/.gitignore index 8946080..6bbc147 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules +remotetests/testconfig.js testdir.zip test.zip -*.tgz \ No newline at end of file +*.tgz diff --git a/README.md b/README.md index b311f41..6a3552b 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,9 @@ You must have an account on Apigee Edge to perform any `apigeetool` functions. T * create, retrieve or delete a KVM Map in Edge * create, retrieve or delete a KVM Entry in Edge * attach, detach, or get a FlowHook +* list, create, get, delete Roles +* assign, remove, verify Users for a Role +* get all Users in a Role You need to be familiar with basic concepts and features of Apigee Edge such as API proxies, organizations, and environments. @@ -92,13 +95,15 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default # Command reference and examples * [addEntryToKVM](#addEntryToKVM) +* [assignUserRole](#assignUserRole) * [attachFlowHook](#attachFlowHook) * [createappkey](#createappkey) * [createapp](#createapp) * [createcache](#createcache) * [createdeveloper](#createdeveloper) * [createKVMmap](#createKVMmap) -* [createproduct](#createproduct) +* [createProduct](#createproduct) +* [createRole](#createRole) * [createTargetServer](#createTargetServer) * [deleteapp](#deleteapp) * [deletecache](#deletecache) @@ -106,6 +111,7 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default * [deleteKVMentry](#deleteKVMentry) * [deleteKVMmap](#deleteKVMmap) * [deleteproduct](#deleteproduct) +* [deleteRole](#deleteRole) * [deleteSharedflow](#deleteSharedflow) * [deleteTargetServer](#deleteTargetServer) * [delete](#delete) @@ -120,12 +126,19 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default * [getKVMentry](#getKVMentry) * [getKVMmap](#getKVMmap) * [getlogs](#getlogs) +* [getRoles](#getRoles) +* [getRole](#getRole) +* [getRolePermissions](#getRolePermissions) +* [getRoleUsers](#getRoleUsers) * [getTargetServer](#getTargetServer) * [listdeployments](#listdeployments) * [listSharedflowDeployments](#listSharedflowDeployments) * [listTargetServers](#listTargetServers) +* [removeUserRole](#removeUserRole) +* [setRolePermissions](#setRolePermissions) * [undeploySharedflow](#undeploySharedflow) * [undeploy](#undeploy) +* [verifyUserRole](#verifyUserRole) ## deploynodeapp @@ -1048,7 +1061,7 @@ Delete a Developer in Edge //developer delete failed }) ; -## Create Product +## Create Product Creates a new API Product in Edge diff --git a/lib/cli.js b/lib/cli.js index 6fd37e6..888d756 100755 --- a/lib/cli.js +++ b/lib/cli.js @@ -65,7 +65,9 @@ function runCommand() { process.exit(6); } - console.log(result); + console.log(JSON.stringify(result)); + // Raw + // console.log(result); process.exit(0); }); diff --git a/lib/commands/assignUserRole.js b/lib/commands/assignUserRole.js new file mode 100644 index 0000000..014aced --- /dev/null +++ b/lib/commands/assignUserRole.js @@ -0,0 +1,41 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + }, + email: { + name: 'Developer email', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('assignUserRole: %j', opts); + } + + var formData = util.format('id=%s', encodeURIComponent(opts.email)); + var uri = util.format('%s/v1/o/%s/userroles/%s/users', opts.baseuri, opts.organization, opts.roleName); + var requestOptions = { + uri: uri, + method:'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: formData, + json:true + } + command_utils.run('assignUserRole', opts,requestOptions,cb) +}; diff --git a/lib/commands/attachFlowHook.js b/lib/commands/attachFlowHook.js index e8d5dc4..14cd3d9 100644 --- a/lib/commands/attachFlowHook.js +++ b/lib/commands/attachFlowHook.js @@ -16,11 +16,13 @@ var descriptor = defaults.defaultDescriptor({ }, flowHookName: { name: 'Flow hook name', - required: true + required: true, + prompt: true }, sharedFlowName: { name: 'Shared Flow name', - required: true + required: true, + prompt: true } }); diff --git a/lib/commands/command-utils.js b/lib/commands/command-utils.js index e999af4..c8ef829 100644 --- a/lib/commands/command-utils.js +++ b/lib/commands/command-utils.js @@ -11,7 +11,7 @@ module.exports.run = function(command, opts, requestOpts,done){ var jsonBody = body if(err){ done(err) - }else if (res.statusCode == 200 || res.statusCode == 201) { + }else if (res.statusCode == 200 || res.statusCode == 201 || res.statusCode == 204) { if (opts.verbose) { console.log(command + ' successful'); } diff --git a/lib/commands/commands.js b/lib/commands/commands.js index ef91c22..92e5f9a 100644 --- a/lib/commands/commands.js +++ b/lib/commands/commands.js @@ -216,6 +216,66 @@ var Commands = { load: function () { return require('./deployExistingRevision'); } + }, + getRoles: { + description: "Get list of roles in an organziation", + load: function () { + return require('./getRoles'); + } + }, + createRole: { + description: "Create a userrole in an organziation", + load: function () { + return require('./createRole'); + } + }, + getRole: { + description: "Get a userrole in an organziation", + load: function () { + return require('./getRole'); + } + }, + deleteRole: { + description: "Delete a userrole in an organziation", + load: function () { + return require('./deleteRole'); + } + }, + getRolePermissions: { + description: "Get resource permissions for a role", + load: function () { + return require('./getRolePermissions'); + } + }, + setRolePermissions: { + description: "Set resource permissions for a role", + load: function () { + return require('./setRolePermissions'); + } + }, + assignUserRole: { + description: "Assign user to a role", + load: function () { + return require('./assignUserRole'); + } + }, + removeUserRole: { + description: "Remove user from a role", + load: function () { + return require('./removeUserRole'); + } + }, + verifyUserRole: { + description: "Verify a user is in a role", + load: function () { + return require('./verifyUserRole'); + } + }, + getRoleUsers: { + description: "Get users in role", + load: function () { + return require('./getRoleUsers'); + } } }; diff --git a/lib/commands/createRole.js b/lib/commands/createRole.js new file mode 100644 index 0000000..fe56346 --- /dev/null +++ b/lib/commands/createRole.js @@ -0,0 +1,39 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('createRole: %j', opts); + } + var payload = { + "role" : [ + {"name" : opts.roleName} + ] + }; + + var uri = util.format('%s/v1/o/%s/userroles', opts.baseuri, opts.organization); + var requestOptions = { + uri: uri, + method:'POST', + body: payload, + json:true + } + command_utils.run('createRole', opts,requestOptions,cb) +}; diff --git a/lib/commands/delete-TargetServer.js b/lib/commands/delete-TargetServer.js index 029ac37..5e273e5 100644 --- a/lib/commands/delete-TargetServer.js +++ b/lib/commands/delete-TargetServer.js @@ -31,7 +31,7 @@ module.exports.run = function(opts, cb) { var requestOptions = { uri: uri, method:'DELETE', - json:false + json:true } command_utils.run('deleteTargetServer', opts,requestOptions,cb) }; diff --git a/lib/commands/deleteRole.js b/lib/commands/deleteRole.js new file mode 100644 index 0000000..99623ba --- /dev/null +++ b/lib/commands/deleteRole.js @@ -0,0 +1,32 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('deleteRole: %j', opts); + } + var uri = util.format('%s/v1/o/%s/userroles/%s', opts.baseuri, opts.organization, opts.roleName); + var requestOptions = { + uri: uri, + method:'DELETE', + json:true + } + command_utils.run('deleteRole', opts,requestOptions,cb) +}; diff --git a/lib/commands/fetchproxy.js b/lib/commands/fetchproxy.js index 65b996a..ec982d7 100644 --- a/lib/commands/fetchproxy.js +++ b/lib/commands/fetchproxy.js @@ -69,7 +69,7 @@ module.exports.run = function(opts, cb) { console.log( "Error text: " + err ); } else { - console.log( 'Save file: ' + f ); + if (opts.verbose) { console.log('Save file: ' + f); } } cb(err); }); diff --git a/lib/commands/fetchsharedflow.js b/lib/commands/fetchsharedflow.js index be7746f..73578ac 100644 --- a/lib/commands/fetchsharedflow.js +++ b/lib/commands/fetchsharedflow.js @@ -71,7 +71,7 @@ module.exports.run = function (opts, cb) { console.log("Error text: " + err); } else { - console.log('Save file: ' + f); + if (opts.verbose) { console.log('Save file: ' + f); } } cb(err); }); diff --git a/lib/commands/get-TargetServer.js b/lib/commands/get-TargetServer.js index 8a9cf6e..03ddd63 100644 --- a/lib/commands/get-TargetServer.js +++ b/lib/commands/get-TargetServer.js @@ -32,7 +32,7 @@ module.exports.run = function(opts, cb) { var requestOptions = { uri: uri, method:'GET', - json:false + json:true } command_utils.run('getTargetServer', opts,requestOptions,cb) }; diff --git a/lib/commands/getRole.js b/lib/commands/getRole.js new file mode 100644 index 0000000..8c9b4cc --- /dev/null +++ b/lib/commands/getRole.js @@ -0,0 +1,32 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('getRole: %j', opts); + } + var uri = util.format('%s/v1/o/%s/userroles/%s', opts.baseuri, opts.organization, opts.roleName); + var requestOptions = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('getRole', opts,requestOptions,cb) +}; diff --git a/lib/commands/getRolePermissions.js b/lib/commands/getRolePermissions.js new file mode 100644 index 0000000..86cdb2c --- /dev/null +++ b/lib/commands/getRolePermissions.js @@ -0,0 +1,32 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('getRolePermissions: %j', opts); + } + var uri = util.format('%s/v1/o/%s/userroles/%s/permissions', opts.baseuri, opts.organization, opts.roleName); + var requestOptions = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('getRolePermissions', opts,requestOptions,cb) +}; diff --git a/lib/commands/getRoleUsers.js b/lib/commands/getRoleUsers.js new file mode 100644 index 0000000..10e760b --- /dev/null +++ b/lib/commands/getRoleUsers.js @@ -0,0 +1,33 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('getRoleUsers: %j', opts); + } + + var uri = util.format('%s/v1/o/%s/userroles/%s/users', opts.baseuri, opts.organization, opts.roleName); + var requestOptions = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('getRoleUsers', opts,requestOptions,cb) +}; diff --git a/lib/commands/getRoles.js b/lib/commands/getRoles.js new file mode 100644 index 0000000..0765301 --- /dev/null +++ b/lib/commands/getRoles.js @@ -0,0 +1,27 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('getRoles: %j', opts); + } + var uri = util.format('%s/v1/o/%s/userroles', opts.baseuri, opts.organization); + var requestOptions = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('getRoles', opts,requestOptions,cb) +}; diff --git a/lib/commands/list-TargetServers.js b/lib/commands/list-TargetServers.js index 00ccd50..fe53bdc 100644 --- a/lib/commands/list-TargetServers.js +++ b/lib/commands/list-TargetServers.js @@ -26,7 +26,7 @@ module.exports.run = function(opts, cb) { var requestOptions = { uri: uri, method:'GET', - json:false + json:true } command_utils.run('listTargetServers', opts,requestOptions,cb) }; diff --git a/lib/commands/listsharedflowdeployments.js b/lib/commands/listsharedflowdeployments.js index 4ed009e..67c6234 100644 --- a/lib/commands/listsharedflowdeployments.js +++ b/lib/commands/listsharedflowdeployments.js @@ -17,10 +17,6 @@ var descriptor = defaults.defaultDescriptor({ name: 'Environment', shortOption: 'e' }, - revision: { - name: 'Revision', - shortOption: 'r' - }, long: { name: 'Long', shortOption: 'l', diff --git a/lib/commands/removeUserRole.js b/lib/commands/removeUserRole.js new file mode 100644 index 0000000..2fcff92 --- /dev/null +++ b/lib/commands/removeUserRole.js @@ -0,0 +1,38 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + }, + email: { + name: 'Developer email', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('removeUserRole: %j', opts); + } + + var uri = util.format('%s/v1/o/%s/userroles/%s/users/%s', opts.baseuri, opts.organization, opts.roleName, opts.email ); + var requestOptions = { + uri: uri, + method:'DELETE', + json:true + } + command_utils.run('removeUserRole', opts,requestOptions,cb) +}; diff --git a/lib/commands/setRolePermissions.js b/lib/commands/setRolePermissions.js new file mode 100644 index 0000000..79f47aa --- /dev/null +++ b/lib/commands/setRolePermissions.js @@ -0,0 +1,45 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + }, + permissions: { + name: 'Permissions array for path and verbs', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('setRolePermissions: %j', opts); + } + + if( opts.permissions ) { + var permissions = JSON.parse(opts.permissions); + } + var payload = { + "resourcePermission" : permissions + }; + var uri = util.format('%s/v1/o/%s/userroles/%s/resourcepermissions', opts.baseuri, opts.organization, opts.roleName); + var requestOptions = { + uri: uri, + method:'POST', + body: payload, + json:true + } + command_utils.run('setRolePermissions', opts,requestOptions,cb) +}; diff --git a/lib/commands/verifyUserRole.js b/lib/commands/verifyUserRole.js new file mode 100644 index 0000000..a960f66 --- /dev/null +++ b/lib/commands/verifyUserRole.js @@ -0,0 +1,38 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + }, + email: { + name: 'EMail for the user', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('verifyUserRole: %j', opts); + } + + var uri = util.format('%s/v1/o/%s/userroles/%s/users/%s', opts.baseuri, opts.organization, opts.roleName, opts.email ); + var requestOptions = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('verifyUserRole', opts,requestOptions,cb) +}; diff --git a/lib/main.js b/lib/main.js index e775425..78d9924 100644 --- a/lib/main.js +++ b/lib/main.js @@ -188,6 +188,47 @@ ApigeeTool.getFlowHook = function (opts, cb) { runCommand(cmd, opts, cb); }; +ApigeeTool.getRoles = function (opts, cb) { + var cmd = require('./commands/getRoles.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.getRole = function (opts, cb) { + var cmd = require('./commands/getRole.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.createRole = function (opts, cb) { + var cmd = require('./commands/createRole.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.deleteRole = function (opts, cb) { + var cmd = require('./commands/deleteRole.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.getRolePermissions = function (opts, cb) { + var cmd = require('./commands/getRolePermissions.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.setRolePermissions = function (opts, cb) { + var cmd = require('./commands/setRolePermissions.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.assignUserRole = function (opts, cb) { + var cmd = require('./commands/assignUserRole.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.removeUserRole = function (opts, cb) { + var cmd = require('./commands/removeUserRole.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.verifyUserRole = function (opts, cb) { + var cmd = require('./commands/verifyUserRole.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.getRoleUsers = function (opts, cb) { + var cmd = require('./commands/getRoleUsers.js'); + runCommand(cmd, opts, cb); +}; + function runCommand(cmd, opts, cb) { options.validate(opts, cmd.descriptor, function(err) { if (err) { diff --git a/lib/promisesdk.js b/lib/promisesdk.js index c2501b1..6ac73df 100644 --- a/lib/promisesdk.js +++ b/lib/promisesdk.js @@ -267,6 +267,67 @@ ApigeeTool.getFlowHook = function(opts) { return cb.promise } +ApigeeTool.getRoles = function(opts) { + var cb = q.defer() + var cmd = require('./commands/getRoles'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.createRole = function(opts) { + var cb = q.defer() + var cmd = require('./commands/createRole'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.getRole = function(opts) { + var cb = q.defer() + var cmd = require('./commands/getRole'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.deleteRole = function(opts) { + var cb = q.defer() + var cmd = require('./commands/deleteRole'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.setRolePermissions = function(opts) { + var cb = q.defer() + var cmd = require('./commands/setRolePermissions'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.getRolePermissions = function(opts) { + var cb = q.defer() + var cmd = require('./commands/getRolePermissions'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.assignUserRole = function(opts) { + var cb = q.defer() + var cmd = require('./commands/assignUserRole'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.removeUserRole = function(opts) { + var cb = q.defer() + var cmd = require('./commands/removeUserRole'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.verifyUserRole = function(opts) { + var cb = q.defer() + var cmd = require('./commands/verifyUserRole'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.getRoleUsers = function(opts) { + var cb = q.defer() + var cmd = require('./commands/getRoleUsers'); + runCommand(cmd, opts, cb); + return cb.promise +} + function runCommand(cmd, opts, cb) { options.validate(opts, cmd.descriptor, function(err) { if (err) { diff --git a/remotetests/remotetest.js b/remotetests/remotetest.js index 047805c..65cfd72 100644 --- a/remotetests/remotetest.js +++ b/remotetests/remotetest.js @@ -24,9 +24,16 @@ var TARGET_SERVER_NAME = 'apigee-cli-test-servername'; var MAP_NAME = 'apigee-cli-test-kvm'; var MAP_NAME_ENCRYPTED = 'apigee-cli-test-kvm-encrypted'; var SHARED_FLOW_NAME = 'apigee-cli-sf'; +var ROLE_NAME = 'apigee-cli-test-role'; var verbose = false; +var deployedRevision; +var deployedUri; +var prevSharedFlow; + +// Run all using: mocha remotetests +// Run all "describe" tests using: mocha remotetests --grep "SharedFlows and FlowHooks" +// Run one "it" test using: mocha remotetests --grep "fetchSharedflow" -/* These tests need some TLC, they don't run successfully */ describe('Remote Tests', function() { this.timeout(REASONABLE_TIMEOUT); var deployedRevision; @@ -39,13 +46,13 @@ describe('Remote Tests', function() { opts.environment = config.environment; apigeetool.deleteKVM(opts,function(err,result) { if (verbose) { - console.log('Delete KVM result = %j', result); + console.log('Delete envrypted KVM result = %j', result); } done(); }); }); - it('Deploy Apigee Proxy with Promise SDK', function(done) { + it('Deploy Apigee Proxy', function(done) { var opts = baseOpts(); opts.api = APIGEE_PROXY_NAME; opts.directory = path.join(__dirname, '../test/fixtures/employees'); @@ -116,6 +123,7 @@ describe('Products / Developers', function() { opts.quotaInterval = '1'; opts.quotaTimeUnit = 'minute'; opts.attributes = [ {"name": "access", "value": "private"} ]; + opts.approvalType = "auto"; var sdk = apigeetool.getPromiseSDK() sdk.createProduct(opts) @@ -154,7 +162,7 @@ describe('Products / Developers', function() { it('Create App' , function(done){ var opts = baseOpts() opts.name = APP_NAME - opts.apiproducts = APIGEE_PRODUCT_NAME + opts.apiProducts = APIGEE_PRODUCT_NAME opts.email = DEVELOPER_EMAIL var sdk = apigeetool.getPromiseSDK() @@ -470,6 +478,36 @@ describe('Products / Developers', function() { }); }); + it('Fetch proxy', function(done) { + var opts = baseOpts(); + opts.api = APIGEE_PROXY_NAME; + opts.revision = deployedRevision; + + apigeetool.fetchProxy(opts, function(err, result) { + if (verbose) { + console.log('Fetch proxy result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Delete proxy', function(done) { + var opts = baseOpts(); + opts.api = APIGEE_PROXY_NAME; + + apigeetool.delete(opts, function(err, result) { + if (verbose) { + console.log('Delete proxy result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + +}); + +describe('Node.js Apps', function() { + this.timeout(REASONABLE_TIMEOUT); + it('Deploy Node.js App', function(done) { var opts = baseOpts(); opts.api = NODE_PROXY_NAME; @@ -650,9 +688,23 @@ describe('Products / Developers', function() { } }); }); -}); + + it('Delete node proxy', function(done) { + var opts = baseOpts(); + opts.api = NODE_PROXY_NAME; + + apigeetool.delete(opts, function(err, result) { + if (verbose) { + console.log('Delete node proxy result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + +}); // End Node.js Apps describe('Hosted Target', function() { + this.timeout(REASONABLE_TIMEOUT); it('Deploy Hosted Targets App', function(done) { var opts = baseOpts(); @@ -805,8 +857,20 @@ describe('Hosted Target', function() { } }); }); + + it('Delete hosted target proxy', function(done) { + var opts = baseOpts(); + opts.api = HOSTED_TARGETS_PROXY_NAME; + + apigeetool.delete(opts, function(err, result) { + if (verbose) { + console.log('Delete hosted target proxy result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + }); // end hosted target tests -/* End of tests that need TLC */ describe('Caches', function() { it('Create an Cache Resource',function(done){ @@ -1100,11 +1164,37 @@ describe('SharedFlows and FlowHooks', function() { }); }); - it('listSharedflowDeployments'); // Until MGMT-3671 is merged, will not work + it('listSharedflowDeployments', function(done) { + var opts = baseOpts(); + opts.sharedFlowName = SHARED_FLOW_NAME; + opts.revision = 1; + + apigeetool.listSharedflowDeployments(opts, function(err, result) { + if (verbose) { + console.log('listSharedflowDeployments result = %j', result); + } + if (err) { + done(err); + } else { done(); } + }); + }); + - it('fetchSharedflow'); + it('fetchSharedflow', function(done) { + var opts = baseOpts(); + opts.name = SHARED_FLOW_NAME; + opts.revision = 1 + + apigeetool.fetchSharedflow(opts, function(err, result) { + if (verbose) { + console.log('fetchSharedflow result = %j', result); + } + if (err) { + done(err); + } else { done(); } + }); + }); - var prevSharedFlow; it('getPreviousSharedFlow', function(done) { var opts = baseOpts(); opts.flowHookName = "PreProxyFlowHook"; @@ -1199,6 +1289,142 @@ describe('SharedFlows and FlowHooks', function() { }); }); // end shared flow and flow hook tests +describe('User Roles and Permissions', function() { + this.timeout(REASONABLE_TIMEOUT); + + it('Create Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + + apigeetool.createRole(opts, function (err, result) { + if (verbose) { + console.log('Create Role result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Get Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + + apigeetool.getRole(opts, function (err, result) { + if (verbose) { + console.log('Get Role result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Get Roles', function (done) { + var opts = baseOpts(); + + apigeetool.getRoles(opts, function (err, result) { + if (verbose) { + console.log('Get Roles result = %j', result); + } + if (err) { done(err); } else { + assert.equal( result.includes(ROLE_NAME), true ); + done(); + } + }); + }); + + it('Set Role Permissions', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + opts.permissions = '[{"path":"/userroles","permissions":["get"]}]'; + + apigeetool.setRolePermissions(opts, function (err, result) { + if (verbose) { + console.log('Set Role Permissions result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Get Role Permissions', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + + apigeetool.getRolePermissions(opts, function (err, result) { + if (verbose) { + console.log('Get Role Permissions result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Assign User to Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + opts.email = config.useremail; + + apigeetool.assignUserRole(opts, function (err, result) { + if (verbose) { + console.log('Assign User to Role result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Verify User in Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + opts.email = config.useremail; + + apigeetool.verifyUserRole(opts, function (err, result) { + if (verbose) { + console.log('Verify User in Role result = %j', result); + } + if (err) { done(err); } else { + assert.equal( result.emailId, opts.email); + done(); + } + }); + }); + + it('Verify access allowed', function (done) { + var opts = baseOpts(); + opts.netrc = false; + opts.username = config.useremail; + opts.password = config.userpassword; + apigeetool.getRoles(opts, function (err, result) { + if (verbose) { + console.log('Verify access allowed result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + + it('Remove User from Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + opts.email = config.useremail; + + apigeetool.removeUserRole(opts, function (err, result) { + if (verbose) { + console.log('Remove User from Role result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Delete Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + + apigeetool.deleteRole(opts, function (err, result) { + if (verbose) { + console.log('Delete Role result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + +}); + function baseOpts() { var o = { organization: config.organization, diff --git a/remotetests/testconfig-sample.js b/remotetests/testconfig-sample.js index 3b5b4b4..d967b46 100644 --- a/remotetests/testconfig-sample.js +++ b/remotetests/testconfig-sample.js @@ -10,11 +10,17 @@ module.exports = { // The user name to authenticate with for the Apigee management API username: '', // The password for that user name - password: '' + password: '', // comment the username and password and uncomment the following to use .netrc // netrc: true - + debug: false, + verbose: false, + + // Developer must exist or be added to org before tests + useremail: 'someone+tester@google.com', + userpassword: 'Supersecret123' + // Uncomment for the management API URI of your local Apigee environment // Leave commented to test using the Apigee cloud. //baseuri: 'http://mgmt:8080' From 5fa6049369d629f81768702b5885eb928f4599c2 Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Fri, 20 Sep 2019 17:15:03 -0400 Subject: [PATCH 04/19] Fix #165 - plus additional issues 158,160,161,and 163 --- README.md | 19 +-- lib/commands/assignUserRole.js | 41 ----- lib/commands/attachFlowHook.js | 51 ------ lib/commands/commands.js | 90 ----------- lib/commands/createRole.js | 39 ----- lib/commands/deleteRole.js | 32 ---- lib/commands/detachFlowHook.js | 40 ----- lib/commands/get-TargetServer.js | 38 ----- lib/commands/getFlowHook.js | 40 ----- lib/commands/getRole.js | 32 ---- lib/commands/getRolePermissions.js | 32 ---- lib/commands/getRoleUsers.js | 33 ---- lib/commands/getRoles.js | 27 ---- lib/commands/list-TargetServers.js | 32 ---- lib/commands/removeUserRole.js | 38 ----- lib/commands/setRolePermissions.js | 45 ------ lib/commands/verifyUserRole.js | 38 ----- lib/promisesdk.js | 97 ----------- package-lock.json | 2 +- remotetests/remotetest.js | 249 +---------------------------- 20 files changed, 4 insertions(+), 1011 deletions(-) delete mode 100644 lib/commands/assignUserRole.js delete mode 100644 lib/commands/attachFlowHook.js delete mode 100644 lib/commands/createRole.js delete mode 100644 lib/commands/deleteRole.js delete mode 100644 lib/commands/detachFlowHook.js delete mode 100644 lib/commands/get-TargetServer.js delete mode 100644 lib/commands/getFlowHook.js delete mode 100644 lib/commands/getRole.js delete mode 100644 lib/commands/getRolePermissions.js delete mode 100644 lib/commands/getRoleUsers.js delete mode 100644 lib/commands/getRoles.js delete mode 100644 lib/commands/list-TargetServers.js delete mode 100644 lib/commands/removeUserRole.js delete mode 100644 lib/commands/setRolePermissions.js delete mode 100644 lib/commands/verifyUserRole.js diff --git a/README.md b/README.md index 6a3552b..bbc0302 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,7 @@ You must have an account on Apigee Edge to perform any `apigeetool` functions. T * create or delete a Cache resource in Edge * create, retrieve or delete a KVM Map in Edge * create, retrieve or delete a KVM Entry in Edge -* attach, detach, or get a FlowHook -* list, create, get, delete Roles -* assign, remove, verify Users for a Role -* get all Users in a Role +* create, delete Target Servers You need to be familiar with basic concepts and features of Apigee Edge such as API proxies, organizations, and environments. @@ -95,15 +92,12 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default # Command reference and examples * [addEntryToKVM](#addEntryToKVM) -* [assignUserRole](#assignUserRole) -* [attachFlowHook](#attachFlowHook) * [createappkey](#createappkey) * [createapp](#createapp) * [createcache](#createcache) * [createdeveloper](#createdeveloper) * [createKVMmap](#createKVMmap) * [createProduct](#createproduct) -* [createRole](#createRole) * [createTargetServer](#createTargetServer) * [deleteapp](#deleteapp) * [deletecache](#deletecache) @@ -111,7 +105,6 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default * [deleteKVMentry](#deleteKVMentry) * [deleteKVMmap](#deleteKVMmap) * [deleteproduct](#deleteproduct) -* [deleteRole](#deleteRole) * [deleteSharedflow](#deleteSharedflow) * [deleteTargetServer](#deleteTargetServer) * [delete](#delete) @@ -122,23 +115,13 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default * [detachFlowHook](#detachFlowHook) * [fetchproxy](#fetchproxy) * [fetchSharedflow](#fetchSharedflow) -* [getFlowHook](#getFlowHook) * [getKVMentry](#getKVMentry) * [getKVMmap](#getKVMmap) * [getlogs](#getlogs) -* [getRoles](#getRoles) -* [getRole](#getRole) -* [getRolePermissions](#getRolePermissions) -* [getRoleUsers](#getRoleUsers) -* [getTargetServer](#getTargetServer) * [listdeployments](#listdeployments) * [listSharedflowDeployments](#listSharedflowDeployments) -* [listTargetServers](#listTargetServers) -* [removeUserRole](#removeUserRole) -* [setRolePermissions](#setRolePermissions) * [undeploySharedflow](#undeploySharedflow) * [undeploy](#undeploy) -* [verifyUserRole](#verifyUserRole) ## deploynodeapp diff --git a/lib/commands/assignUserRole.js b/lib/commands/assignUserRole.js deleted file mode 100644 index 014aced..0000000 --- a/lib/commands/assignUserRole.js +++ /dev/null @@ -1,41 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - roleName: { - name: 'Role Name', - required: true, - prompt: true - }, - email: { - name: 'Developer email', - required: true, - prompt: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('assignUserRole: %j', opts); - } - - var formData = util.format('id=%s', encodeURIComponent(opts.email)); - var uri = util.format('%s/v1/o/%s/userroles/%s/users', opts.baseuri, opts.organization, opts.roleName); - var requestOptions = { - uri: uri, - method:'POST', - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - body: formData, - json:true - } - command_utils.run('assignUserRole', opts,requestOptions,cb) -}; diff --git a/lib/commands/attachFlowHook.js b/lib/commands/attachFlowHook.js deleted file mode 100644 index 14cd3d9..0000000 --- a/lib/commands/attachFlowHook.js +++ /dev/null @@ -1,51 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - environment: { - name: 'Environment', - shortOption: 'e', - required: true - }, - flowHookName: { - name: 'Flow hook name', - required: true, - prompt: true - }, - sharedFlowName: { - name: 'Shared Flow name', - required: true, - prompt: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('attachFlowHook: %j', opts); - } - var payload = { - "continueOnError" : true, - "sharedFlow" : opts.sharedFlowName - } - if(opts.targetSSL){ - payload.sSLInfo = {enabled: true} - } - - var uri = util.format('%s/v1/o/%s/e/%s/flowhooks/%s', opts.baseuri, opts.organization, opts.environment, opts.flowHookName); - var requestOpts = { - uri: uri, - method:'POST', - body: payload, - json:true - } - command_utils.run('attachFlowHook',opts, requestOpts, cb) -}; diff --git a/lib/commands/commands.js b/lib/commands/commands.js index 92e5f9a..35dd8b7 100644 --- a/lib/commands/commands.js +++ b/lib/commands/commands.js @@ -7,42 +7,12 @@ var Table = require('cli-table'); var options = require('../options'); var Commands = { - attachFlowHook: { - description: 'Attach a Shared Flow to a Flow Hook', - load: function() { - return require('./attachFlowHook'); - } - }, - detachFlowHook: { - description: 'Detach a Shared Flow from a Flow Hook', - load: function() { - return require('./detachFlowHook'); - } - }, - getFlowHook: { - description: 'Get the Shared Flow attached to a Flow Hook', - load: function() { - return require('./getFlowHook'); - } - }, - listTargetServers: { - description: 'List Target Servers', - load: function() { - return require('./list-TargetServers'); - } - }, createTargetServer: { description: 'Create a Target Server', load: function() { return require('./create-TargetServer'); } }, - getTargetServer: { - description: 'Get a Target Server', - load: function() { - return require('./get-TargetServer'); - } - }, deleteTargetServer: { description: 'Delete a Target Server', load: function() { @@ -216,66 +186,6 @@ var Commands = { load: function () { return require('./deployExistingRevision'); } - }, - getRoles: { - description: "Get list of roles in an organziation", - load: function () { - return require('./getRoles'); - } - }, - createRole: { - description: "Create a userrole in an organziation", - load: function () { - return require('./createRole'); - } - }, - getRole: { - description: "Get a userrole in an organziation", - load: function () { - return require('./getRole'); - } - }, - deleteRole: { - description: "Delete a userrole in an organziation", - load: function () { - return require('./deleteRole'); - } - }, - getRolePermissions: { - description: "Get resource permissions for a role", - load: function () { - return require('./getRolePermissions'); - } - }, - setRolePermissions: { - description: "Set resource permissions for a role", - load: function () { - return require('./setRolePermissions'); - } - }, - assignUserRole: { - description: "Assign user to a role", - load: function () { - return require('./assignUserRole'); - } - }, - removeUserRole: { - description: "Remove user from a role", - load: function () { - return require('./removeUserRole'); - } - }, - verifyUserRole: { - description: "Verify a user is in a role", - load: function () { - return require('./verifyUserRole'); - } - }, - getRoleUsers: { - description: "Get users in role", - load: function () { - return require('./getRoleUsers'); - } } }; diff --git a/lib/commands/createRole.js b/lib/commands/createRole.js deleted file mode 100644 index fe56346..0000000 --- a/lib/commands/createRole.js +++ /dev/null @@ -1,39 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - roleName: { - name: 'Role Name', - required: true, - prompt: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('createRole: %j', opts); - } - var payload = { - "role" : [ - {"name" : opts.roleName} - ] - }; - - var uri = util.format('%s/v1/o/%s/userroles', opts.baseuri, opts.organization); - var requestOptions = { - uri: uri, - method:'POST', - body: payload, - json:true - } - command_utils.run('createRole', opts,requestOptions,cb) -}; diff --git a/lib/commands/deleteRole.js b/lib/commands/deleteRole.js deleted file mode 100644 index 99623ba..0000000 --- a/lib/commands/deleteRole.js +++ /dev/null @@ -1,32 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - roleName: { - name: 'Role Name', - required: true, - prompt: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('deleteRole: %j', opts); - } - var uri = util.format('%s/v1/o/%s/userroles/%s', opts.baseuri, opts.organization, opts.roleName); - var requestOptions = { - uri: uri, - method:'DELETE', - json:true - } - command_utils.run('deleteRole', opts,requestOptions,cb) -}; diff --git a/lib/commands/detachFlowHook.js b/lib/commands/detachFlowHook.js deleted file mode 100644 index f31e5e6..0000000 --- a/lib/commands/detachFlowHook.js +++ /dev/null @@ -1,40 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - environment: { - name: 'Environment', - shortOption: 'e', - required: true - }, - flowHookName: { - name: 'Flow hook name', - required: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('detachFlowHook: %j', opts); - } - if(opts.targetSSL){ - payload.sSLInfo = {enabled: true} - } - - var uri = util.format('%s/v1/o/%s/e/%s/flowhooks/%s', opts.baseuri, opts.organization, opts.environment, opts.flowHookName); - var requestOpts = { - uri: uri, - method:'DELETE', - json:true - } - command_utils.run('detachFlowHook',opts, requestOpts, cb) -}; diff --git a/lib/commands/get-TargetServer.js b/lib/commands/get-TargetServer.js deleted file mode 100644 index 03ddd63..0000000 --- a/lib/commands/get-TargetServer.js +++ /dev/null @@ -1,38 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - environment: { - name: 'Environment', - shortOption: 'e', - required: true, - prompt: true - }, - targetServerName: { - name: 'Target Server Name', - required: true, - prompt: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('getTargetServer: %j', opts); - } - var uri = util.format('%s/v1/o/%s/e/%s/targetservers/%s', opts.baseuri, opts.organization, opts.environment,opts.targetServerName); - var requestOptions = { - uri: uri, - method:'GET', - json:true - } - command_utils.run('getTargetServer', opts,requestOptions,cb) -}; diff --git a/lib/commands/getFlowHook.js b/lib/commands/getFlowHook.js deleted file mode 100644 index d8e6696..0000000 --- a/lib/commands/getFlowHook.js +++ /dev/null @@ -1,40 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - environment: { - name: 'Environment', - shortOption: 'e', - required: true - }, - flowHookName: { - name: 'Flow hook name', - required: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('getFlowHook: %j', opts); - } - if(opts.targetSSL){ - payload.sSLInfo = {enabled: true} - } - - var uri = util.format('%s/v1/o/%s/e/%s/flowhooks/%s', opts.baseuri, opts.organization, opts.environment, opts.flowHookName); - var requestOpts = { - uri: uri, - method:'GET', - json:true - } - command_utils.run('getFlowHook',opts, requestOpts, cb) -}; diff --git a/lib/commands/getRole.js b/lib/commands/getRole.js deleted file mode 100644 index 8c9b4cc..0000000 --- a/lib/commands/getRole.js +++ /dev/null @@ -1,32 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - roleName: { - name: 'Role Name', - required: true, - prompt: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('getRole: %j', opts); - } - var uri = util.format('%s/v1/o/%s/userroles/%s', opts.baseuri, opts.organization, opts.roleName); - var requestOptions = { - uri: uri, - method:'GET', - json:true - } - command_utils.run('getRole', opts,requestOptions,cb) -}; diff --git a/lib/commands/getRolePermissions.js b/lib/commands/getRolePermissions.js deleted file mode 100644 index 86cdb2c..0000000 --- a/lib/commands/getRolePermissions.js +++ /dev/null @@ -1,32 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - roleName: { - name: 'Role Name', - required: true, - prompt: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('getRolePermissions: %j', opts); - } - var uri = util.format('%s/v1/o/%s/userroles/%s/permissions', opts.baseuri, opts.organization, opts.roleName); - var requestOptions = { - uri: uri, - method:'GET', - json:true - } - command_utils.run('getRolePermissions', opts,requestOptions,cb) -}; diff --git a/lib/commands/getRoleUsers.js b/lib/commands/getRoleUsers.js deleted file mode 100644 index 10e760b..0000000 --- a/lib/commands/getRoleUsers.js +++ /dev/null @@ -1,33 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - roleName: { - name: 'Role Name', - required: true, - prompt: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('getRoleUsers: %j', opts); - } - - var uri = util.format('%s/v1/o/%s/userroles/%s/users', opts.baseuri, opts.organization, opts.roleName); - var requestOptions = { - uri: uri, - method:'GET', - json:true - } - command_utils.run('getRoleUsers', opts,requestOptions,cb) -}; diff --git a/lib/commands/getRoles.js b/lib/commands/getRoles.js deleted file mode 100644 index 0765301..0000000 --- a/lib/commands/getRoles.js +++ /dev/null @@ -1,27 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('getRoles: %j', opts); - } - var uri = util.format('%s/v1/o/%s/userroles', opts.baseuri, opts.organization); - var requestOptions = { - uri: uri, - method:'GET', - json:true - } - command_utils.run('getRoles', opts,requestOptions,cb) -}; diff --git a/lib/commands/list-TargetServers.js b/lib/commands/list-TargetServers.js deleted file mode 100644 index fe53bdc..0000000 --- a/lib/commands/list-TargetServers.js +++ /dev/null @@ -1,32 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - environment: { - name: 'Environment', - shortOption: 'e', - required: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('listTargetServers: %j', opts); - } - var uri = util.format('%s/v1/o/%s/e/%s/targetservers', opts.baseuri, opts.organization, opts.environment); - var requestOptions = { - uri: uri, - method:'GET', - json:true - } - command_utils.run('listTargetServers', opts,requestOptions,cb) -}; diff --git a/lib/commands/removeUserRole.js b/lib/commands/removeUserRole.js deleted file mode 100644 index 2fcff92..0000000 --- a/lib/commands/removeUserRole.js +++ /dev/null @@ -1,38 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - roleName: { - name: 'Role Name', - required: true, - prompt: true - }, - email: { - name: 'Developer email', - required: true, - prompt: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('removeUserRole: %j', opts); - } - - var uri = util.format('%s/v1/o/%s/userroles/%s/users/%s', opts.baseuri, opts.organization, opts.roleName, opts.email ); - var requestOptions = { - uri: uri, - method:'DELETE', - json:true - } - command_utils.run('removeUserRole', opts,requestOptions,cb) -}; diff --git a/lib/commands/setRolePermissions.js b/lib/commands/setRolePermissions.js deleted file mode 100644 index 79f47aa..0000000 --- a/lib/commands/setRolePermissions.js +++ /dev/null @@ -1,45 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - roleName: { - name: 'Role Name', - required: true, - prompt: true - }, - permissions: { - name: 'Permissions array for path and verbs', - required: true, - prompt: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('setRolePermissions: %j', opts); - } - - if( opts.permissions ) { - var permissions = JSON.parse(opts.permissions); - } - var payload = { - "resourcePermission" : permissions - }; - var uri = util.format('%s/v1/o/%s/userroles/%s/resourcepermissions', opts.baseuri, opts.organization, opts.roleName); - var requestOptions = { - uri: uri, - method:'POST', - body: payload, - json:true - } - command_utils.run('setRolePermissions', opts,requestOptions,cb) -}; diff --git a/lib/commands/verifyUserRole.js b/lib/commands/verifyUserRole.js deleted file mode 100644 index a960f66..0000000 --- a/lib/commands/verifyUserRole.js +++ /dev/null @@ -1,38 +0,0 @@ -/* jshint node: true */ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); - -var defaults = require('../defaults'); -var options = require('../options'); -var command_utils = require('./command-utils') - -var descriptor = defaults.defaultDescriptor({ - roleName: { - name: 'Role Name', - required: true, - prompt: true - }, - email: { - name: 'EMail for the user', - required: true, - prompt: true - } -}); - -module.exports.descriptor = descriptor; - -module.exports.run = function(opts, cb) { - if (opts.debug) { - console.log('verifyUserRole: %j', opts); - } - - var uri = util.format('%s/v1/o/%s/userroles/%s/users/%s', opts.baseuri, opts.organization, opts.roleName, opts.email ); - var requestOptions = { - uri: uri, - method:'GET', - json:true - } - command_utils.run('verifyUserRole', opts,requestOptions,cb) -}; diff --git a/lib/promisesdk.js b/lib/promisesdk.js index 6ac73df..6daa79b 100644 --- a/lib/promisesdk.js +++ b/lib/promisesdk.js @@ -161,13 +161,6 @@ ApigeeTool.deleteDeveloper = function(opts){ return cb.promise } -ApigeeTool.listTargetServers = function(opts) { - var cb = q.defer() - var cmd = require('./commands/list-TargetServers'); - runCommand(cmd, opts, cb); - return cb.promise -}; - ApigeeTool.createTargetServer = function(opts) { var cb = q.defer() var cmd = require('./commands/create-TargetServer'); @@ -175,13 +168,6 @@ ApigeeTool.createTargetServer = function(opts) { return cb.promise }; -ApigeeTool.getTargetServer = function(opts) { - var cb = q.defer() - var cmd = require('./commands/get-TargetServer'); - runCommand(cmd, opts, cb); - return cb.promise -}; - ApigeeTool.deleteTargetServer = function(opts){ var cb = q.defer() var cmd = require('./commands/delete-TargetServer'); @@ -189,7 +175,6 @@ ApigeeTool.deleteTargetServer = function(opts){ return cb.promise } - ApigeeTool.createKVM = function(opts) { var cb = q.defer() var cmd = require('./commands/create-KVM'); @@ -246,88 +231,6 @@ ApigeeTool.createAppKey = function(opts) { return cb.promise } -ApigeeTool.attachFlowHook = function(opts) { - var cb = q.defer() - var cmd = require('./commands/attachFlowHook'); - runCommand(cmd, opts, cb); - return cb.promise -} - -ApigeeTool.detachFlowHook = function(opts) { - var cb = q.defer() - var cmd = require('./commands/detachFlowHook'); - runCommand(cmd, opts, cb); - return cb.promise -} - -ApigeeTool.getFlowHook = function(opts) { - var cb = q.defer() - var cmd = require('./commands/getFlowHook'); - runCommand(cmd, opts, cb); - return cb.promise -} - -ApigeeTool.getRoles = function(opts) { - var cb = q.defer() - var cmd = require('./commands/getRoles'); - runCommand(cmd, opts, cb); - return cb.promise -} -ApigeeTool.createRole = function(opts) { - var cb = q.defer() - var cmd = require('./commands/createRole'); - runCommand(cmd, opts, cb); - return cb.promise -} -ApigeeTool.getRole = function(opts) { - var cb = q.defer() - var cmd = require('./commands/getRole'); - runCommand(cmd, opts, cb); - return cb.promise -} -ApigeeTool.deleteRole = function(opts) { - var cb = q.defer() - var cmd = require('./commands/deleteRole'); - runCommand(cmd, opts, cb); - return cb.promise -} -ApigeeTool.setRolePermissions = function(opts) { - var cb = q.defer() - var cmd = require('./commands/setRolePermissions'); - runCommand(cmd, opts, cb); - return cb.promise -} -ApigeeTool.getRolePermissions = function(opts) { - var cb = q.defer() - var cmd = require('./commands/getRolePermissions'); - runCommand(cmd, opts, cb); - return cb.promise -} -ApigeeTool.assignUserRole = function(opts) { - var cb = q.defer() - var cmd = require('./commands/assignUserRole'); - runCommand(cmd, opts, cb); - return cb.promise -} -ApigeeTool.removeUserRole = function(opts) { - var cb = q.defer() - var cmd = require('./commands/removeUserRole'); - runCommand(cmd, opts, cb); - return cb.promise -} -ApigeeTool.verifyUserRole = function(opts) { - var cb = q.defer() - var cmd = require('./commands/verifyUserRole'); - runCommand(cmd, opts, cb); - return cb.promise -} -ApigeeTool.getRoleUsers = function(opts) { - var cb = q.defer() - var cmd = require('./commands/getRoleUsers'); - runCommand(cmd, opts, cb); - return cb.promise -} - function runCommand(cmd, opts, cb) { options.validate(opts, cmd.descriptor, function(err) { if (err) { diff --git a/package-lock.json b/package-lock.json index 04f851b..4ddd3ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "apigeetool", - "version": "0.9.0", + "version": "0.12.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/remotetests/remotetest.js b/remotetests/remotetest.js index 65cfd72..baa5464 100644 --- a/remotetests/remotetest.js +++ b/remotetests/remotetest.js @@ -24,11 +24,9 @@ var TARGET_SERVER_NAME = 'apigee-cli-test-servername'; var MAP_NAME = 'apigee-cli-test-kvm'; var MAP_NAME_ENCRYPTED = 'apigee-cli-test-kvm-encrypted'; var SHARED_FLOW_NAME = 'apigee-cli-sf'; -var ROLE_NAME = 'apigee-cli-test-role'; var verbose = false; var deployedRevision; var deployedUri; -var prevSharedFlow; // Run all using: mocha remotetests // Run all "describe" tests using: mocha remotetests --grep "SharedFlows and FlowHooks" @@ -907,22 +905,6 @@ describe('Caches', function() { describe('Target Servers', function() { this.timeout(REASONABLE_TIMEOUT); - it('List Target Servers SDK',function(done){ - var opts = baseOpts(); - opts.environment = config.environment; - apigeetool.getPromiseSDK() - .listTargetServers(opts) - .then(function(res){ - if (verbose) { - console.log('List Target Servers result = %j', res); - } - done() - },function(err){ - console.log(err) - done(err) - }) - }); - it('Create Target Server SDK',function(done){ var opts = baseOpts(); opts.environment = config.environment; @@ -945,23 +927,6 @@ describe('Target Servers', function() { }) }); - it('Get Target Server SDK',function(done){ - var opts = baseOpts(); - opts.environment = config.environment; - opts.targetServerName = TARGET_SERVER_NAME; - apigeetool.getPromiseSDK() - .getTargetServer(opts) - .then(function(res){ - if (verbose) { - console.log('Get Target Server result = %j', res); - } - done() - },function(err){ - console.log(err) - done(err) - }) - }); - it('Delete Target Server SDK',function(done){ var opts = baseOpts(); opts.environment = config.environment; @@ -1131,7 +1096,7 @@ describe('KVM', function() { }); }); // end KVM tests -describe('SharedFlows and FlowHooks', function() { +describe('SharedFlows', function() { this.timeout(REASONABLE_TIMEOUT); it('Deploy SharedFlow', function (done) { var opts = baseOpts(); @@ -1195,80 +1160,6 @@ describe('SharedFlows and FlowHooks', function() { }); }); - it('getPreviousSharedFlow', function(done) { - var opts = baseOpts(); - opts.flowHookName = "PreProxyFlowHook"; - - apigeetool.getFlowHook(opts, function(err, result) { - if (verbose) { - console.log('getFlowhook result = %j', result); - } - if (err) { - done(err); - } else { - if( result.sharedFlow ) { - prevSharedFlow = result.sharedFlow; - } - done(); - } - }); - }); - - it('attachFlowhook', function(done) { - var opts = baseOpts(); - opts.flowHookName = "PreProxyFlowHook"; - opts.sharedFlowName = SHARED_FLOW_NAME; - - apigeetool.attachFlowHook(opts, function(err, result) { - if (verbose) { - console.log('attachFlowHook result = %j', result); - } - if (err) { - done(err); - } else { - done(); - } - }); - }); - - it('detachFlowHook', function(done) { - var opts = baseOpts(); - opts.flowHookName = "PreProxyFlowHook"; - - apigeetool.detachFlowHook(opts, function(err, result) { - if (verbose) { - console.log('detachFlowHook result = %j', result); - } - if (err) { - done(err); - } else { - done(); - } - }); - }); - - it('re-attachFlowHook', function(done) { - if( prevSharedFlow ) { - var opts = baseOpts(); - opts.flowHookName = "PreProxyFlowHook"; - opts.sharedFlowName = prevSharedFlow; - - apigeetool.attachFlowHook(opts, function(err, result) { - if (verbose) { - console.log('prevSharedFlow ' + prevSharedFlow ); - console.log('re-attachFlowHook result = %j', result); - } - if (err) { - done(err); - } else { - done(); - } - }); - } else { - done(); - } - }); - it('undeploySharedflow', function(done) { var opts = baseOpts(); opts.name = SHARED_FLOW_NAME; @@ -1287,143 +1178,7 @@ describe('SharedFlows and FlowHooks', function() { opts.name = SHARED_FLOW_NAME; apigeetool.deleteSharedflow(opts, done); }); -}); // end shared flow and flow hook tests - -describe('User Roles and Permissions', function() { - this.timeout(REASONABLE_TIMEOUT); - - it('Create Role', function (done) { - var opts = baseOpts(); - opts.roleName = ROLE_NAME; - - apigeetool.createRole(opts, function (err, result) { - if (verbose) { - console.log('Create Role result = %j', result); - } - if (err) { done(err); } else { done(); } - }); - }); - - it('Get Role', function (done) { - var opts = baseOpts(); - opts.roleName = ROLE_NAME; - - apigeetool.getRole(opts, function (err, result) { - if (verbose) { - console.log('Get Role result = %j', result); - } - if (err) { done(err); } else { done(); } - }); - }); - - it('Get Roles', function (done) { - var opts = baseOpts(); - - apigeetool.getRoles(opts, function (err, result) { - if (verbose) { - console.log('Get Roles result = %j', result); - } - if (err) { done(err); } else { - assert.equal( result.includes(ROLE_NAME), true ); - done(); - } - }); - }); - - it('Set Role Permissions', function (done) { - var opts = baseOpts(); - opts.roleName = ROLE_NAME; - opts.permissions = '[{"path":"/userroles","permissions":["get"]}]'; - - apigeetool.setRolePermissions(opts, function (err, result) { - if (verbose) { - console.log('Set Role Permissions result = %j', result); - } - if (err) { done(err); } else { done(); } - }); - }); - - it('Get Role Permissions', function (done) { - var opts = baseOpts(); - opts.roleName = ROLE_NAME; - - apigeetool.getRolePermissions(opts, function (err, result) { - if (verbose) { - console.log('Get Role Permissions result = %j', result); - } - if (err) { done(err); } else { done(); } - }); - }); - - it('Assign User to Role', function (done) { - var opts = baseOpts(); - opts.roleName = ROLE_NAME; - opts.email = config.useremail; - - apigeetool.assignUserRole(opts, function (err, result) { - if (verbose) { - console.log('Assign User to Role result = %j', result); - } - if (err) { done(err); } else { done(); } - }); - }); - - it('Verify User in Role', function (done) { - var opts = baseOpts(); - opts.roleName = ROLE_NAME; - opts.email = config.useremail; - - apigeetool.verifyUserRole(opts, function (err, result) { - if (verbose) { - console.log('Verify User in Role result = %j', result); - } - if (err) { done(err); } else { - assert.equal( result.emailId, opts.email); - done(); - } - }); - }); - - it('Verify access allowed', function (done) { - var opts = baseOpts(); - opts.netrc = false; - opts.username = config.useremail; - opts.password = config.userpassword; - apigeetool.getRoles(opts, function (err, result) { - if (verbose) { - console.log('Verify access allowed result = %j', result); - } - if (err) { done(err); } else { done(); } - }); - }); - - - it('Remove User from Role', function (done) { - var opts = baseOpts(); - opts.roleName = ROLE_NAME; - opts.email = config.useremail; - - apigeetool.removeUserRole(opts, function (err, result) { - if (verbose) { - console.log('Remove User from Role result = %j', result); - } - if (err) { done(err); } else { done(); } - }); - }); - - it('Delete Role', function (done) { - var opts = baseOpts(); - opts.roleName = ROLE_NAME; - - apigeetool.deleteRole(opts, function (err, result) { - if (verbose) { - console.log('Delete Role result = %j', result); - } - if (err) { done(err); } else { done(); } - }); - }); - -}); +}); // end shared flow tests function baseOpts() { var o = { From a9a44858d7d01da3100e3dca2035d9aa498cb71f Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Fri, 20 Sep 2019 18:02:57 -0400 Subject: [PATCH 05/19] Fix #165 - plus additional issues 158,160,161,and 163 --- .gitignore | 3 +- lib/cli.js | 10 +- lib/commands/command-utils.js | 2 +- lib/commands/create-TargetServer.js | 9 +- lib/commands/delete-TargetServer.js | 5 +- lib/commands/fetchproxy.js | 2 +- lib/commands/fetchsharedflow.js | 2 +- lib/commands/listsharedflowdeployments.js | 4 - lib/promisesdk.js | 5 +- package-lock.json | 2 +- remotetests/remotetest.js | 993 +++++++++++++--------- remotetests/testconfig-sample.js | 10 +- 12 files changed, 598 insertions(+), 449 deletions(-) diff --git a/.gitignore b/.gitignore index 8946080..6bbc147 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules +remotetests/testconfig.js testdir.zip test.zip -*.tgz \ No newline at end of file +*.tgz diff --git a/lib/cli.js b/lib/cli.js index 4c48857..888d756 100755 --- a/lib/cli.js +++ b/lib/cli.js @@ -64,11 +64,11 @@ function runCommand() { } process.exit(6); } - if (!opts.json && commandModule.format) { - console.log(commandModule.format(result)); - } else { - console.log(JSON.stringify(result)); - } + + console.log(JSON.stringify(result)); + // Raw + // console.log(result); + process.exit(0); }); } diff --git a/lib/commands/command-utils.js b/lib/commands/command-utils.js index e999af4..c8ef829 100644 --- a/lib/commands/command-utils.js +++ b/lib/commands/command-utils.js @@ -11,7 +11,7 @@ module.exports.run = function(command, opts, requestOpts,done){ var jsonBody = body if(err){ done(err) - }else if (res.statusCode == 200 || res.statusCode == 201) { + }else if (res.statusCode == 200 || res.statusCode == 201 || res.statusCode == 204) { if (opts.verbose) { console.log(command + ' successful'); } diff --git a/lib/commands/create-TargetServer.js b/lib/commands/create-TargetServer.js index cfa8c6f..6996552 100644 --- a/lib/commands/create-TargetServer.js +++ b/lib/commands/create-TargetServer.js @@ -16,18 +16,21 @@ var descriptor = defaults.defaultDescriptor({ }, targetServerName: { name: 'Target Server Name', - required: true + required: true, + prompt: true }, targetHost: { name: 'Target Host', - required: true + required: true, + prompt: true }, targetEnabled: { name: 'Target Enabled' }, targetPort: { name: 'Target Port', - required: true + required: true, + prompt: true }, targetSSL:{ name: 'SSL Info' diff --git a/lib/commands/delete-TargetServer.js b/lib/commands/delete-TargetServer.js index 35751ea..5e273e5 100644 --- a/lib/commands/delete-TargetServer.js +++ b/lib/commands/delete-TargetServer.js @@ -16,7 +16,8 @@ var descriptor = defaults.defaultDescriptor({ }, targetServerName: { name: 'Target Server Name', - required: true + required: true, + prompt: true } }); @@ -30,7 +31,7 @@ module.exports.run = function(opts, cb) { var requestOptions = { uri: uri, method:'DELETE', - json:false + json:true } command_utils.run('deleteTargetServer', opts,requestOptions,cb) }; diff --git a/lib/commands/fetchproxy.js b/lib/commands/fetchproxy.js index 65b996a..ec982d7 100644 --- a/lib/commands/fetchproxy.js +++ b/lib/commands/fetchproxy.js @@ -69,7 +69,7 @@ module.exports.run = function(opts, cb) { console.log( "Error text: " + err ); } else { - console.log( 'Save file: ' + f ); + if (opts.verbose) { console.log('Save file: ' + f); } } cb(err); }); diff --git a/lib/commands/fetchsharedflow.js b/lib/commands/fetchsharedflow.js index be7746f..73578ac 100644 --- a/lib/commands/fetchsharedflow.js +++ b/lib/commands/fetchsharedflow.js @@ -71,7 +71,7 @@ module.exports.run = function (opts, cb) { console.log("Error text: " + err); } else { - console.log('Save file: ' + f); + if (opts.verbose) { console.log('Save file: ' + f); } } cb(err); }); diff --git a/lib/commands/listsharedflowdeployments.js b/lib/commands/listsharedflowdeployments.js index 4ed009e..67c6234 100644 --- a/lib/commands/listsharedflowdeployments.js +++ b/lib/commands/listsharedflowdeployments.js @@ -17,10 +17,6 @@ var descriptor = defaults.defaultDescriptor({ name: 'Environment', shortOption: 'e' }, - revision: { - name: 'Revision', - shortOption: 'r' - }, long: { name: 'Long', shortOption: 'l', diff --git a/lib/promisesdk.js b/lib/promisesdk.js index 2d9be0c..6daa79b 100644 --- a/lib/promisesdk.js +++ b/lib/promisesdk.js @@ -175,7 +175,6 @@ ApigeeTool.deleteTargetServer = function(opts){ return cb.promise } - ApigeeTool.createKVM = function(opts) { var cb = q.defer() var cmd = require('./commands/create-KVM'); @@ -197,9 +196,9 @@ ApigeeTool.getKVMentry = function(opts) { return cb.promise } -ApigeeTool.getkvmmap = function(opts) { +ApigeeTool.getKVMmap = function(opts) { var cb = q.defer() - var cmd = require('./commands/getkvmmap'); + var cmd = require('./commands/getKVMmap'); runCommand(cmd, opts, cb); return cb.promise } diff --git a/package-lock.json b/package-lock.json index 04f851b..4ddd3ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "apigeetool", - "version": "0.9.0", + "version": "0.12.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/remotetests/remotetest.js b/remotetests/remotetest.js index 9f735c5..baa5464 100644 --- a/remotetests/remotetest.js +++ b/remotetests/remotetest.js @@ -25,10 +25,15 @@ var MAP_NAME = 'apigee-cli-test-kvm'; var MAP_NAME_ENCRYPTED = 'apigee-cli-test-kvm-encrypted'; var SHARED_FLOW_NAME = 'apigee-cli-sf'; var verbose = false; +var deployedRevision; +var deployedUri; + +// Run all using: mocha remotetests +// Run all "describe" tests using: mocha remotetests --grep "SharedFlows and FlowHooks" +// Run one "it" test using: mocha remotetests --grep "fetchSharedflow" describe('Remote Tests', function() { this.timeout(REASONABLE_TIMEOUT); - var deployedRevision; var deployedUri; @@ -39,13 +44,13 @@ describe('Remote Tests', function() { opts.environment = config.environment; apigeetool.deleteKVM(opts,function(err,result) { if (verbose) { - console.log('Delete KVM result = %j', result); + console.log('Delete envrypted KVM result = %j', result); } done(); }); }); - - it('Deploy Apigee Proxy with Promise SDK', function(done) { + + it('Deploy Apigee Proxy', function(done) { var opts = baseOpts(); opts.api = APIGEE_PROXY_NAME; opts.directory = path.join(__dirname, '../test/fixtures/employees'); @@ -73,149 +78,152 @@ describe('Remote Tests', function() { done(err); }) }); +}); - describe('Products / Developers', function() { - - it('Create Product', function(done){ - var opts = baseOpts() ; - var displayName = 'custom name'; - opts.productName = APIGEE_PRODUCT_NAME; - opts.productDesc = 'abc123'; - opts.displayName = displayName; - opts.proxies = APIGEE_PROXY_NAME; - opts.quota = '1'; - opts.quotaInterval = '1'; - opts.quotaTimeUnit = 'minute'; - - var sdk = apigeetool.getPromiseSDK() - - sdk.createProduct(opts) - .then(function(result){ - try { - assert.equal(result.displayName, displayName); - done(); - } catch (e) { - done(e); - } - },function(err){ - done(err) - }) ; - }); +describe('Products / Developers', function() { + this.timeout(REASONABLE_TIMEOUT); - it('Create Private Product', function(done){ - var opts = baseOpts() ; - var displayName = 'custom name'; - opts.productName = APIGEE_PRIVATE_PRODUCT_NAME; - opts.productDesc = 'abc123'; - opts.displayName = displayName; - opts.proxies = APIGEE_PROXY_NAME; - opts.quota = '1'; - opts.quotaInterval = '1'; - opts.quotaTimeUnit = 'minute'; - opts.attributes = [ {"name": "access", "value": "private"} ]; - var sdk = apigeetool.getPromiseSDK() - - sdk.createProduct(opts) - .then(function(result){ - try { - assert.equal(result.displayName, displayName); - assert.equal(result.attributes.length, 1); - assert.equal(result.attributes[0].name, 'access'); - assert.equal(result.attributes[0].value, 'private'); - done(); - } catch (e) { - done(e); - } - },function(err){ - done(err) - }) ; - }); + it('Create Product', function(done){ + var opts = baseOpts() ; + var displayName = 'custom name'; + opts.productName = APIGEE_PRODUCT_NAME; + opts.productDesc = 'abc123'; + opts.displayName = displayName; + opts.proxies = APIGEE_PROXY_NAME; + opts.quota = '1'; + opts.quotaInterval = '1'; + opts.quotaTimeUnit = 'minute'; + opts.approvalType = "auto"; - it('Create Developer' , function(done){ - var opts = baseOpts() - opts.email = DEVELOPER_EMAIL - opts.firstName = 'Test' - opts.lastName = 'Test1' - opts.userName = 'runningFromTest123' - - var sdk = apigeetool.getPromiseSDK() - - sdk.createDeveloper(opts) - .then(function(result){ - done() - },function(err){ - done(err) - }) ; - }); + var sdk = apigeetool.getPromiseSDK() - it('Create App' , function(done){ - var opts = baseOpts() - opts.name = APP_NAME - opts.apiproducts = APIGEE_PRODUCT_NAME - opts.email = DEVELOPER_EMAIL + sdk.createProduct(opts) + .then(function(result){ + try { + assert.equal(result.displayName, displayName); + done(); + } catch (e) { + done(e); + } + },function(err){ + done(err) + }) ; + }); - var sdk = apigeetool.getPromiseSDK() + it('Create Private Product', function(done){ + var opts = baseOpts() ; + var displayName = 'custom name'; + opts.productName = APIGEE_PRIVATE_PRODUCT_NAME; + opts.productDesc = 'abc123'; + opts.displayName = displayName; + opts.proxies = APIGEE_PROXY_NAME; + opts.quota = '1'; + opts.quotaInterval = '1'; + opts.quotaTimeUnit = 'minute'; + opts.attributes = [ {"name": "access", "value": "private"} ]; + opts.approvalType = "auto"; + var sdk = apigeetool.getPromiseSDK() - sdk.createApp(opts) - .then(function(result){ - done() - },function(err){ - done(err) - }) ; - }); + sdk.createProduct(opts) + .then(function(result){ + try { + assert.equal(result.displayName, displayName); + assert.equal(result.attributes.length, 1); + assert.equal(result.attributes[0].name, 'access'); + assert.equal(result.attributes[0].value, 'private'); + done(); + } catch (e) { + done(e); + } + },function(err){ + done(err) + }) ; + }); - it('Delete App' , function(done){ - var opts = baseOpts() - opts.email = DEVELOPER_EMAIL - opts.name = APP_NAME - var sdk = apigeetool.getPromiseSDK() - sdk.deleteApp(opts) - .then(function(result){ - done() - },function(err){ - done(err) - }) ; - }); + it('Create Developer' , function(done){ + var opts = baseOpts() + opts.email = DEVELOPER_EMAIL + opts.firstName = 'Test' + opts.lastName = 'Test1' + opts.userName = 'runningFromTest123' - it('Delete Developer' , function(done){ - var opts = baseOpts() - opts.email = DEVELOPER_EMAIL - var sdk = apigeetool.getPromiseSDK() - sdk.deleteDeveloper(opts) - .then(function(result){ - done() - },function(err){ - done(err) - }) ; - }); + var sdk = apigeetool.getPromiseSDK() - it('Delete API Product',function(done){ - var opts = baseOpts() ; - opts.productName = APIGEE_PRODUCT_NAME - - var sdk = apigeetool.getPromiseSDK() - - sdk.deleteProduct(opts) - .then(function(result){ - done() - },function(err){ - done(err) - }) ; - }); + sdk.createDeveloper(opts) + .then(function(result){ + done() + },function(err){ + done(err) + }) ; + }); - it('Delete API private Product',function(done){ - var opts = baseOpts() ; - opts.productName = APIGEE_PRIVATE_PRODUCT_NAME - - var sdk = apigeetool.getPromiseSDK() - - sdk.deleteProduct(opts) - .then(function(result){ - done() - },function(err){ - done(err) - }) ; - }); + it('Create App' , function(done){ + var opts = baseOpts() + opts.name = APP_NAME + opts.apiProducts = APIGEE_PRODUCT_NAME + opts.email = DEVELOPER_EMAIL + + var sdk = apigeetool.getPromiseSDK() + + sdk.createApp(opts) + .then(function(result){ + done() + },function(err){ + done(err) + }); + }); + + it('Delete App' , function(done){ + var opts = baseOpts() + opts.email = DEVELOPER_EMAIL + opts.name = APP_NAME + var sdk = apigeetool.getPromiseSDK() + sdk.deleteApp(opts) + .then(function(result){ + done() + },function(err){ + done(err) + }) ; + }); + + it('Delete Developer' , function(done){ + var opts = baseOpts() + opts.email = DEVELOPER_EMAIL + var sdk = apigeetool.getPromiseSDK() + sdk.deleteDeveloper(opts) + .then(function(result){ + done() + },function(err){ + done(err) + }) ; + }); + + it('Delete API Product',function(done){ + var opts = baseOpts() ; + opts.productName = APIGEE_PRODUCT_NAME + + var sdk = apigeetool.getPromiseSDK() + + sdk.deleteProduct(opts) + .then(function(result){ + done() + },function(err){ + done(err) + }) ; + }); + + it('Delete API private Product',function(done){ + var opts = baseOpts() ; + opts.productName = APIGEE_PRIVATE_PRODUCT_NAME + + var sdk = apigeetool.getPromiseSDK() + + sdk.deleteProduct(opts) + .then(function(result){ + done() + },function(err){ + done(err) + }) ; }); it('Deploy Apigee Proxy', function(done) { @@ -468,6 +476,36 @@ describe('Remote Tests', function() { }); }); + it('Fetch proxy', function(done) { + var opts = baseOpts(); + opts.api = APIGEE_PROXY_NAME; + opts.revision = deployedRevision; + + apigeetool.fetchProxy(opts, function(err, result) { + if (verbose) { + console.log('Fetch proxy result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Delete proxy', function(done) { + var opts = baseOpts(); + opts.api = APIGEE_PROXY_NAME; + + apigeetool.delete(opts, function(err, result) { + if (verbose) { + console.log('Delete proxy result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + +}); + +describe('Node.js Apps', function() { + this.timeout(REASONABLE_TIMEOUT); + it('Deploy Node.js App', function(done) { var opts = baseOpts(); opts.api = NODE_PROXY_NAME; @@ -649,161 +687,190 @@ describe('Remote Tests', function() { }); }); - describe('Hosted Target', function() { - - it('Deploy Hosted Targets App', function(done) { - var opts = baseOpts(); - opts.api = HOSTED_TARGETS_PROXY_NAME; - opts.directory = path.join(__dirname, '../test/fixtures/hellohostedtargets'); - opts.main = 'server.js'; - opts['base-path'] = '/cli-hosted-targets-test'; + it('Delete node proxy', function(done) { + var opts = baseOpts(); + opts.api = NODE_PROXY_NAME; - apigeetool.deployHostedTarget(opts, function(err, result) { - if (verbose) { - console.log('Deploy result = %j', result); - } - if (err) { - done(err); - } else { - try { - if(Array.isArray(result)) result = result[0] - assert.equal(result.name, HOSTED_TARGETS_PROXY_NAME); - assert.equal(result.environment, config.environment); - assert.equal(result.state, 'deployed'); - //it will be 2 for remote testing public cloud/ http & https - assert.equal(result.uris.length, 2); - assert(typeof result.revision === 'number'); - deployedRevision = result.revision; - deployedUri = result.uris[0]; - setTimeout(done, 10000); - } catch (e) { - done(e); - } - } - }); + apigeetool.delete(opts, function(err, result) { + if (verbose) { + console.log('Delete node proxy result = %j', result); + } + if (err) { done(err); } else { done(); } }); + }); - it('List Deployments by app', function(done) { - var opts = baseOpts(); - delete opts.environment; - opts.api = HOSTED_TARGETS_PROXY_NAME; - opts.long = true; +}); // End Node.js Apps - apigeetool.listDeployments(opts, function(err, result) { - if (verbose) { - console.log('List result = %j', result); - } - if (err) { - done(err); - } else { - var deployment = _.find(result.deployments, function(d) { - return (d.name === HOSTED_TARGETS_PROXY_NAME); - }); - try { - assert.equal(deployment.name, HOSTED_TARGETS_PROXY_NAME); - assert.equal(deployment.environment, config.environment); - assert.equal(deployment.state, 'deployed'); - assert.equal(deployment.revision, deployedRevision); - assert.equal(deployment.uris.length, 2); - assert.equal(deployment.uris[0], deployedUri); - done(); - } catch (e) { - done(e); - } +describe('Hosted Target', function() { + this.timeout(REASONABLE_TIMEOUT); + + it('Deploy Hosted Targets App', function(done) { + var opts = baseOpts(); + opts.api = HOSTED_TARGETS_PROXY_NAME; + opts.directory = path.join(__dirname, '../test/fixtures/hellohostedtargets'); + opts.main = 'server.js'; + opts['base-path'] = '/cli-hosted-targets-test'; + + apigeetool.deployHostedTarget(opts, function(err, result) { + if (verbose) { + console.log('Deploy result = %j', result); + } + if (err) { + done(err); + } else { + try { + if(Array.isArray(result)) result = result[0] + assert.equal(result.name, HOSTED_TARGETS_PROXY_NAME); + assert.equal(result.environment, config.environment); + assert.equal(result.state, 'deployed'); + //it will be 2 for remote testing public cloud/ http & https + assert.equal(result.uris.length, 2); + assert(typeof result.revision === 'number'); + deployedRevision = result.revision; + deployedUri = result.uris[0]; + setTimeout(done, 10000); + } catch (e) { + done(e); } - }); + } }); + }); - it('Verify deployed URI', function(done) { + it('List Deployments by app', function(done) { + var opts = baseOpts(); + delete opts.environment; + opts.api = HOSTED_TARGETS_PROXY_NAME; + opts.long = true; + + apigeetool.listDeployments(opts, function(err, result) { if (verbose) { - console.log('Testing %s', deployedUri); + console.log('List result = %j', result); } - request(deployedUri, function(err, resp, body) { - if (err) { - console.error(err, resp.statusCode, body); - done(err); - } else { - try { - assert.equal(resp.statusCode, 200); - done(); - } catch (e) { - done(e); - } + if (err) { + done(err); + } else { + var deployment = _.find(result.deployments, function(d) { + return (d.name === HOSTED_TARGETS_PROXY_NAME); + }); + try { + assert.equal(deployment.name, HOSTED_TARGETS_PROXY_NAME); + assert.equal(deployment.environment, config.environment); + assert.equal(deployment.state, 'deployed'); + assert.equal(deployment.revision, deployedRevision); + assert.equal(deployment.uris.length, 2); + assert.equal(deployment.uris[0], deployedUri); + done(); + } catch (e) { + done(e); } - }); + } }); + }); - it('Check build logs from deployed URI', function(done) { - var opts = baseOpts(); - opts['hosted-build'] = true; - opts.api = HOSTED_TARGETS_PROXY_NAME; + it('Verify deployed URI', function(done) { + if (verbose) { + console.log('Testing %s', deployedUri); + } + request(deployedUri, function(err, resp, body) { + if (err) { + console.error(err, resp.statusCode, body); + done(err); + } else { + try { + assert.equal(resp.statusCode, 200); + done(); + } catch (e) { + done(e); + } + } + }); + }); - var logStream = new stream.PassThrough(); - logStream.setEncoding('utf8'); - opts.stream = logStream; - apigeetool.getLogs(opts, function(err) { - assert.ifError(err); + it('Check build logs from deployed URI', function(done) { + var opts = baseOpts(); + opts['hosted-build'] = true; + opts.api = HOSTED_TARGETS_PROXY_NAME; - var allLogs = ''; - logStream.on('data', function(chunk) { - allLogs += chunk; - }); - logStream.on('end', function() { - assert(/DONE/.test(allLogs)); - done(); - }); + var logStream = new stream.PassThrough(); + logStream.setEncoding('utf8'); + opts.stream = logStream; + apigeetool.getLogs(opts, function(err) { + assert.ifError(err); + + var allLogs = ''; + logStream.on('data', function(chunk) { + allLogs += chunk; + }); + logStream.on('end', function() { + assert(/DONE/.test(allLogs)); + done(); }); }); + }); - it('Check runtime logs from deployed URI', function(done) { - var opts = baseOpts(); - opts['hosted-runtime'] = true; - opts.api = HOSTED_TARGETS_PROXY_NAME; + it('Check runtime logs from deployed URI', function(done) { + var opts = baseOpts(); + opts['hosted-runtime'] = true; + opts.api = HOSTED_TARGETS_PROXY_NAME; - var logStream = new stream.PassThrough(); - logStream.setEncoding('utf8'); - opts.stream = logStream; + var logStream = new stream.PassThrough(); + logStream.setEncoding('utf8'); + opts.stream = logStream; - apigeetool.getLogs(opts, function(err) { - assert.ifError(err); + apigeetool.getLogs(opts, function(err) { + assert.ifError(err); - var allLogs = ''; - logStream.on('data', function(chunk) { - allLogs += chunk; - }); - logStream.on('end', function() { - //Validate runtime logs - assert(/Node HTTP server is listening/.test(allLogs)); - done(); - }); + var allLogs = ''; + logStream.on('data', function(chunk) { + allLogs += chunk; + }); + logStream.on('end', function() { + //Validate runtime logs + assert(/Node HTTP server is listening/.test(allLogs)); + done(); }); }); + }); - it('Undeploy Hosted Targets App Without Revision', function(done) { - var opts = baseOpts(); - opts.api = HOSTED_TARGETS_PROXY_NAME; + it('Undeploy Hosted Targets App Without Revision', function(done) { + var opts = baseOpts(); + opts.api = HOSTED_TARGETS_PROXY_NAME; - apigeetool.undeploy(opts, function(err, result) { - if (verbose) { - console.log('Undeploy result = %j', result); - } - if (err) { - done(err); - } else { - try { - assert.equal(result.name, HOSTED_TARGETS_PROXY_NAME); - assert.equal(result.environment, config.environment); - assert.equal(result.state, 'undeployed'); - assert.equal(result.revision, deployedRevision); - done(); - } catch (e) { - done(e); - } + apigeetool.undeploy(opts, function(err, result) { + if (verbose) { + console.log('Undeploy result = %j', result); + } + if (err) { + done(err); + } else { + try { + assert.equal(result.name, HOSTED_TARGETS_PROXY_NAME); + assert.equal(result.environment, config.environment); + assert.equal(result.state, 'undeployed'); + assert.equal(result.revision, deployedRevision); + done(); + } catch (e) { + done(e); } - }); + } }); - }); // end hosted target tests + }); + + it('Delete hosted target proxy', function(done) { + var opts = baseOpts(); + opts.api = HOSTED_TARGETS_PROXY_NAME; + apigeetool.delete(opts, function(err, result) { + if (verbose) { + console.log('Delete hosted target proxy result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + +}); // end hosted target tests + +describe('Caches', function() { it('Create an Cache Resource',function(done){ var opts = baseOpts(); opts.cache = CACHE_RESOURCE_NAME; @@ -833,9 +900,14 @@ describe('Remote Tests', function() { } }); }); +}); // end cache tests + +describe('Target Servers', function() { + this.timeout(REASONABLE_TIMEOUT); - it('Create Target Server',function(done){ + it('Create Target Server SDK',function(done){ var opts = baseOpts(); + opts.environment = config.environment; opts.targetServerName = TARGET_SERVER_NAME; opts.targetHost = 'localhost'; opts.targetEnabled = true; @@ -844,20 +916,81 @@ describe('Remote Tests', function() { opts.environment = config.environment; apigeetool.getPromiseSDK() .createTargetServer(opts) - .then(function(){done()}, - function(err){ - console.log(err) - done(err)}) + .then(function(res){ + if (verbose) { + console.log('Create Target Server result = %j', res); + } + done() + },function(err){ + console.log(err) + done(err) + }) }); - it('Delete Target Server',function(done){ + it('Delete Target Server SDK',function(done){ var opts = baseOpts(); + opts.environment = config.environment; opts.targetServerName = TARGET_SERVER_NAME; + apigeetool.getPromiseSDK() + .deleteTargetServer(opts) + .then(function(res){ + if (verbose) { + console.log('Delete Target Server result = %j', res); + } + done() + },function(err){ + console.log(err) + done(err) + }) + }); + +}); // end target server tests + +describe('KVM', function() { + it('Create KVM',function(done){ + var opts = baseOpts(); + opts.mapName = MAP_NAME; opts.environment = config.environment; + apigeetool.getPromiseSDK() + .createKVM(opts) + .then(function(res){ + if (verbose) { + console.log('Create KVM result = %j', res); + } + done() + },function(err){ + console.log(err) + done(err) + }) + }); + + it('Create Encrypted KVM',function(done){ + var opts = baseOpts(); + opts.mapName = MAP_NAME_ENCRYPTED; + opts.environment = config.environment; + opts.encrypted = true; + apigeetool.getPromiseSDK() + .createKVM(opts) + .then(function(res){ + if (!res.encrypted) { + return done(new Error('Map was not encrypted')); + } else if (verbose) { + console.log('Create KVM result = %j', res); + } + done(); + }, function(err){ + console.log(err) + done(err) + }) + }); - apigeetool.deleteTargetServer(opts,function(err,result) { + it('Delete Encrypted KVM',function(done){ + var opts = baseOpts(); + opts.mapName = MAP_NAME_ENCRYPTED; + opts.environment = config.environment; + apigeetool.deleteKVM(opts,function(err,result) { if (verbose) { - console.log('Delete TargetServer result = %j', result); + console.log('Delete Encrypted KVM result = %j', result); } if (err) { done(err); @@ -867,175 +1000,185 @@ describe('Remote Tests', function() { }); }); - describe('KVM', function() { - it('Create KVM',function(done){ - var opts = baseOpts(); - opts.mapName = MAP_NAME; - opts.environment = config.environment; - apigeetool.getPromiseSDK() - .createKVM(opts) - .then(function(){done()}, - function(err){ - console.log(err) - done(err)}) - }); - - it('Create Encrypted KVM',function(done){ - var opts = baseOpts(); - opts.mapName = MAP_NAME_ENCRYPTED; - opts.environment = config.environment; - opts.encrypted = true; - apigeetool.getPromiseSDK() - .createKVM(opts) - .then(function(res){ - if (!res.encrypted) { - return done(new Error('Map was not encrypted')); - } - done(); - }, function(err){ - console.log(err) - done(err) - }) - }); - - it('Add Entry to KVM',function(done){ - // This will not work for non-cps orgs - var opts = baseOpts(); - opts.mapName = MAP_NAME; - opts.environment = config.environment; - opts.entryName = 'test'; - opts.entryValue = 'test1'; - apigeetool.getPromiseSDK() - .addEntryToKVM(opts) - .then(function(){done()}, - function(err){ - console.log(err); - done(err)}) - }); - - it('Get KVM Entry', function(done) { - var opts = baseOpts(); - opts.mapName = MAP_NAME; - opts.environment = config.environment; - opts.entryName = 'test'; - apigeetool.getPromiseSDK() - .getKVMentry(opts) - .then(function(body){ - assert.equal(body.value, 'test1') - done() - }, - function(err) { - console.log(err); - done(err); - }) - }) - - it('Get KVM Map', function(done) { - var opts = baseOpts(); - opts.mapName = MAP_NAME; - opts.environment = config.environment; - apigeetool.getPromiseSDK() - .getkvmmap(opts) - .then(function(body){ - assert.equal(body.entry.length, 1) - done() - }, - function(err) { - console.log(err); - done(err); - }) - }) - - it('Delete KVM Entry', function(done) { - var opts = baseOpts(); - opts.mapName = MAP_NAME; - opts.environment = config.environment; - opts.entryName = 'test'; - apigeetool.getPromiseSDK() - .deleteKVMentry(opts) - .then(function(body){ - assert.equal(body.value, 'test1') - done() - }, - function(err) { - console.log(err); - done(err); - }) - }) - - it('Delete KVM',function(done){ - var opts = baseOpts(); - opts.mapName = MAP_NAME; - opts.environment = config.environment; - apigeetool.deleteKVM(opts,function(err,result) { + it('Add Entry to KVM',function(done){ + // This will not work for non-cps orgs + var opts = baseOpts(); + opts.mapName = MAP_NAME; + opts.environment = config.environment; + opts.entryName = 'test'; + opts.entryValue = 'test1'; + apigeetool.getPromiseSDK() + .addEntryToKVM(opts) + .then(function(res){ if (verbose) { - console.log('Delete KVM result = %j', result); + console.log('Add Entry to KVM result = %j', res); } - if (err) { - done(err); - } else { - done() + done() + },function(err){ + console.log(err) + done(err) + }) + }); + + it('Get KVM Entry', function(done) { + var opts = baseOpts(); + opts.mapName = MAP_NAME; + opts.environment = config.environment; + opts.entryName = 'test'; + apigeetool.getPromiseSDK() + .getKVMentry(opts) + .then(function(body){ + if (verbose) { + console.log('Get KVM Entry result = %j', body); } - }); - }); - }) + assert.equal(body.value, 'test1') + done() + }, + function(err) { + console.log(err); + done(err); + }) + }); + it('Get KVM Map', function(done) { + var opts = baseOpts(); + opts.mapName = MAP_NAME; + opts.environment = config.environment; + apigeetool.getPromiseSDK() + .getKVMmap(opts) + .then(function(body){ + if (verbose) { + console.log('Get KVM Map result = %j', body); + } + assert.equal(body.entry.length, 1) + done() + }, + function(err) { + console.log(err); + done(err); + }) + }); - describe('SharedFlows', function() { - it('Deploy SharedFlow', function (done) { - var opts = baseOpts(); - opts.name = SHARED_FLOW_NAME; - opts.directory = path.join(__dirname, '../test/fixtures/employees-sf'); - apigeetool.deploySharedflow(opts, function (err, result) { + it('Delete KVM Entry', function(done) { + var opts = baseOpts(); + opts.mapName = MAP_NAME; + opts.environment = config.environment; + opts.entryName = 'test'; + apigeetool.getPromiseSDK() + .deleteKVMentry(opts) + .then(function(body){ if (verbose) { - console.log('Deploy result = %j', result); + console.log('Get KVM Map result = %j', body); } - if (err) { - done(err); - } else { - try { - if (Array.isArray(result)) { - result = result[0] - } - assert.equal(result.name, SHARED_FLOW_NAME); - assert.equal(result.environment, config.environment); - assert.equal(result.state, 'deployed'); - // assert.equal(result.uris.length, 1); - assert(typeof result.revision === 'number'); - deployedRevision = result.revision; - // deployedUri = result.uris[0]; - done(); - } catch (e) { - done(e); + assert.equal(body.value, 'test1') + done() + }, + function(err) { + console.log(err); + done(err); + }) + }); + + it('Delete KVM',function(done){ + var opts = baseOpts(); + opts.mapName = MAP_NAME; + opts.environment = config.environment; + apigeetool.deleteKVM(opts,function(err,result) { + if (verbose) { + console.log('Delete KVM result = %j', result); + } + if (err) { + done(err); + } else { + done() + } + }); + }); +}); // end KVM tests + +describe('SharedFlows', function() { + this.timeout(REASONABLE_TIMEOUT); + it('Deploy SharedFlow', function (done) { + var opts = baseOpts(); + var deployedRevision; + opts.name = SHARED_FLOW_NAME; + opts.directory = path.join(__dirname, '../test/fixtures/employees-sf'); + apigeetool.deploySharedflow(opts, function (err, result) { + if (verbose) { + console.log('Deploy result = %j', result); + } + if (err) { + done(err); + } else { + try { + if (Array.isArray(result)) { + result = result[0] } + assert.equal(result.name, SHARED_FLOW_NAME); + assert.equal(result.environment, config.environment); + assert.equal(result.state, 'deployed'); + // assert.equal(result.uris.length, 1); + assert(typeof result.revision === 'number'); + deployedRevision = result.revision; + // deployedUri = result.uris[0]; + done(); + } catch (e) { + done(e); } - }); + } }); + }); - it('listSharedflowDeployments'); // Until MGMT-3671 is merged, will not work + it('listSharedflowDeployments', function(done) { + var opts = baseOpts(); + opts.sharedFlowName = SHARED_FLOW_NAME; + opts.revision = 1; - it('fetchSharedflow'); + apigeetool.listSharedflowDeployments(opts, function(err, result) { + if (verbose) { + console.log('listSharedflowDeployments result = %j', result); + } + if (err) { + done(err); + } else { done(); } + }); + }); - it('undeploySharedflow', function(done) { - var opts = baseOpts(); - opts.name = SHARED_FLOW_NAME; - apigeetool.undeploySharedflow(opts, function(err, result) { - if (err) { - done(err); - } else { // If response is non-200 it throws an Error - done(); - } - }); + it('fetchSharedflow', function(done) { + var opts = baseOpts(); + opts.name = SHARED_FLOW_NAME; + opts.revision = 1 + + apigeetool.fetchSharedflow(opts, function(err, result) { + if (verbose) { + console.log('fetchSharedflow result = %j', result); + } + if (err) { + done(err); + } else { done(); } }); + }); + + it('undeploySharedflow', function(done) { + var opts = baseOpts(); + opts.name = SHARED_FLOW_NAME; - it('deleteSharedflow', function(done) { - var opts = baseOpts(); - opts.name = SHARED_FLOW_NAME; - apigeetool.deleteSharedflow(opts, done); + apigeetool.undeploySharedflow(opts, function(err, result) { + if (err) { + done(err); + } else { // If response is non-200 it throws an Error + done(); + } }); - }) -}); + }); + + it('deleteSharedflow', function(done) { + var opts = baseOpts(); + opts.name = SHARED_FLOW_NAME; + apigeetool.deleteSharedflow(opts, done); + }); +}); // end shared flow tests function baseOpts() { var o = { diff --git a/remotetests/testconfig-sample.js b/remotetests/testconfig-sample.js index 3b5b4b4..d967b46 100644 --- a/remotetests/testconfig-sample.js +++ b/remotetests/testconfig-sample.js @@ -10,11 +10,17 @@ module.exports = { // The user name to authenticate with for the Apigee management API username: '', // The password for that user name - password: '' + password: '', // comment the username and password and uncomment the following to use .netrc // netrc: true - + debug: false, + verbose: false, + + // Developer must exist or be added to org before tests + useremail: 'someone+tester@google.com', + userpassword: 'Supersecret123' + // Uncomment for the management API URI of your local Apigee environment // Leave commented to test using the Apigee cloud. //baseuri: 'http://mgmt:8080' From f4459afc2d4a9f23dadd09f2abba2009af4630bc Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Mon, 23 Sep 2019 13:40:08 -0400 Subject: [PATCH 06/19] Synced with key and cert file changes --- README.md | 6 +++ lib/defaults.js | 18 +++++++++ lib/main.js | 66 ------------------------------- package.json | 2 +- remotetests/remotetest.js | 36 +++++------------ test/testoptions.js | 82 +++++++++++++++++++++++++++++++++++++-- 6 files changed, 113 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index bbc0302..cbeeeb6 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,12 @@ this tool: Multiple file names may be comma-separated. Use this to communicate with an installation of Apigee Edge that uses a custom certificate for API calls. +`--keyfile -K` +(optional) The name of the PEM file that represents the private key in a mutual auth connection. + +`--certfile -C` +(optional) The name of the PEM file that represents the certificate in a mutual auth connection. + `--debug -D` (optional) Prints additional information about the deployment, including router and message processor IDs. diff --git a/lib/defaults.js b/lib/defaults.js index c25a082..254c180 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -82,6 +82,16 @@ var DefaultDescriptor = { shortOption: 'c', scope: 'default' }, + keyfile: { + name: 'Key file', + shortOption: 'K', + scope: 'default' + }, + certfile: { + name: 'Cert file', + shortOption: 'C', + scope: 'default' + }, insecure: { name: 'insecure', shortOption: 'k', @@ -197,6 +207,14 @@ module.exports.defaultRequest = function(opts) { ro.agentOptions.ca = ca; } + if (opts.keyfile) { + ro.key = fs.readFileSync(opts.keyfile); + } + + if (opts.certfile) { + ro.cert = fs.readFileSync(opts.certfile); + } + if (opts.insecure) { ro.agentOptions.rejectUnauthorized = false; // Skips certificate validation diff --git a/lib/main.js b/lib/main.js index 78d9924..570631a 100644 --- a/lib/main.js +++ b/lib/main.js @@ -98,21 +98,11 @@ ApigeeTool.deleteApp = function(opts,cb){ runCommand(cmd, opts, cb); }; -ApigeeTool.listTargetServers = function(opts, cb) { - var cmd = require('./commands/list-TargetServers'); - runCommand(cmd, opts, cb); -}; - ApigeeTool.createTargetServer = function(opts, cb) { var cmd = require('./commands/create-TargetServer'); runCommand(cmd, opts, cb); }; -ApigeeTool.getTargetServer = function (opts, cb) { - var cmd = require('./commands/get-TargetServer.js'); - runCommand(cmd, opts, cb); -}; - ApigeeTool.deleteTargetServer = function(opts,cb){ var cmd = require('./commands/delete-TargetServer'); runCommand(cmd, opts, cb); @@ -173,62 +163,6 @@ ApigeeTool.deleteSharedflow = function (opts, cb) { runCommand(cmd, opts, cb); }; -ApigeeTool.attachFlowHook = function (opts, cb) { - var cmd = require('./commands/attachFlowHook.js'); - runCommand(cmd, opts, cb); -}; - -ApigeeTool.detachFlowHook = function (opts, cb) { - var cmd = require('./commands/detachFlowHook.js'); - runCommand(cmd, opts, cb); -}; - -ApigeeTool.getFlowHook = function (opts, cb) { - var cmd = require('./commands/getFlowHook.js'); - runCommand(cmd, opts, cb); -}; - -ApigeeTool.getRoles = function (opts, cb) { - var cmd = require('./commands/getRoles.js'); - runCommand(cmd, opts, cb); -}; -ApigeeTool.getRole = function (opts, cb) { - var cmd = require('./commands/getRole.js'); - runCommand(cmd, opts, cb); -}; -ApigeeTool.createRole = function (opts, cb) { - var cmd = require('./commands/createRole.js'); - runCommand(cmd, opts, cb); -}; -ApigeeTool.deleteRole = function (opts, cb) { - var cmd = require('./commands/deleteRole.js'); - runCommand(cmd, opts, cb); -}; -ApigeeTool.getRolePermissions = function (opts, cb) { - var cmd = require('./commands/getRolePermissions.js'); - runCommand(cmd, opts, cb); -}; -ApigeeTool.setRolePermissions = function (opts, cb) { - var cmd = require('./commands/setRolePermissions.js'); - runCommand(cmd, opts, cb); -}; -ApigeeTool.assignUserRole = function (opts, cb) { - var cmd = require('./commands/assignUserRole.js'); - runCommand(cmd, opts, cb); -}; -ApigeeTool.removeUserRole = function (opts, cb) { - var cmd = require('./commands/removeUserRole.js'); - runCommand(cmd, opts, cb); -}; -ApigeeTool.verifyUserRole = function (opts, cb) { - var cmd = require('./commands/verifyUserRole.js'); - runCommand(cmd, opts, cb); -}; -ApigeeTool.getRoleUsers = function (opts, cb) { - var cmd = require('./commands/getRoleUsers.js'); - runCommand(cmd, opts, cb); -}; - function runCommand(cmd, opts, cb) { options.validate(opts, cmd.descriptor, function(err) { if (err) { diff --git a/package.json b/package.json index ca443e9..0ea331e 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "apigeetool": "./lib/cli.js" }, "scripts": { - "test": "mocha -R spec", + "test": "jasmine test/testoptions.js", "remotetest": "mocha -R spec remotetests" }, "keywords": [ diff --git a/remotetests/remotetest.js b/remotetests/remotetest.js index baa5464..a7a305c 100644 --- a/remotetests/remotetest.js +++ b/remotetests/remotetest.js @@ -31,24 +31,10 @@ var deployedUri; // Run all using: mocha remotetests // Run all "describe" tests using: mocha remotetests --grep "SharedFlows and FlowHooks" // Run one "it" test using: mocha remotetests --grep "fetchSharedflow" +// To see tests use 'grep " it" remotetest.j' -describe('Remote Tests', function() { +describe('Remote Tests', function() { // it this.timeout(REASONABLE_TIMEOUT); - var deployedRevision; - var deployedUri; - - after(function(done) { - // cleanup encrypted kvm - var opts = baseOpts(); - opts.mapName = MAP_NAME_ENCRYPTED; - opts.environment = config.environment; - apigeetool.deleteKVM(opts,function(err,result) { - if (verbose) { - console.log('Delete envrypted KVM result = %j', result); - } - done(); - }); - }); it('Deploy Apigee Proxy', function(done) { var opts = baseOpts(); @@ -78,11 +64,7 @@ describe('Remote Tests', function() { done(err); }) }); -}); - -describe('Products / Developers', function() { - this.timeout(REASONABLE_TIMEOUT); - + it('Create Product', function(done){ var opts = baseOpts() ; var displayName = 'custom name'; @@ -503,7 +485,7 @@ describe('Products / Developers', function() { }); -describe('Node.js Apps', function() { +describe('Node.js Apps', function() { // it this.timeout(REASONABLE_TIMEOUT); it('Deploy Node.js App', function(done) { @@ -701,7 +683,7 @@ describe('Node.js Apps', function() { }); // End Node.js Apps -describe('Hosted Target', function() { +describe('Hosted Target', function() { // it this.timeout(REASONABLE_TIMEOUT); it('Deploy Hosted Targets App', function(done) { @@ -870,7 +852,7 @@ describe('Hosted Target', function() { }); // end hosted target tests -describe('Caches', function() { +describe('Caches', function() { // it it('Create an Cache Resource',function(done){ var opts = baseOpts(); opts.cache = CACHE_RESOURCE_NAME; @@ -902,7 +884,7 @@ describe('Caches', function() { }); }); // end cache tests -describe('Target Servers', function() { +describe('Target Servers', function() { // it this.timeout(REASONABLE_TIMEOUT); it('Create Target Server SDK',function(done){ @@ -946,7 +928,7 @@ describe('Target Servers', function() { }); // end target server tests -describe('KVM', function() { +describe('KVM', function() { // it it('Create KVM',function(done){ var opts = baseOpts(); opts.mapName = MAP_NAME; @@ -1096,7 +1078,7 @@ describe('KVM', function() { }); }); // end KVM tests -describe('SharedFlows', function() { +describe('SharedFlows', function() { // it this.timeout(REASONABLE_TIMEOUT); it('Deploy SharedFlow', function (done) { var opts = baseOpts(); diff --git a/test/testoptions.js b/test/testoptions.js index ac2bfbf..321e3fb 100644 --- a/test/testoptions.js +++ b/test/testoptions.js @@ -2,8 +2,21 @@ var assert = require('assert'); var util = require('util'); var options = require('../lib/options'); +var defaults = require('../lib/defaults'); +var fs = require('fs'); +var request = require('request'); -describe('Options parsing test', function(done) { +describe('Options parsing test', function() { + beforeAll(function () { + spyOn(fs, 'readFileSync').and.returnValue(Buffer.from('abc')); + spyOn(request, 'defaults'); + }); + + afterEach(function () { + fs.readFileSync.calls.reset(); + request.defaults.calls.reset(); + }); + it('Test no descriptor', function(done) { var desc = {}; var opts = { foo: 1, bar: 'baz'}; @@ -31,7 +44,7 @@ describe('Options parsing test', function(done) { bar: { required: false, prompt: false }, baz: { required: true, prompt: true } }; - var opts = { foo: 1, bar: 'value'}; + var opts = { foo: 1, bar: 'baz'}; options.validate(opts, desc, function(err) { assert(err); assert(/Missing required option/.test(err.message)); @@ -121,7 +134,7 @@ describe('Options parsing test', function(done) { }; var opts = { ping: 1, pong: 'value'}; var help = options.getHelp(desc); - // console.log('Help is: ' + help); + //console.log('Help is:' + help); assert.notEqual( help, undefined ); }); @@ -135,6 +148,69 @@ describe('Options parsing test', function(done) { assert.equal(opts.foo, 'bar'); assert.equal(opts.toggle, true); }); + + // the prior test demonstrates the ability to set any command + // line switch, with a value or as a boolean; so, this test + // will validate the switches are acted upon correctly + it('Test setting the --keyfile/--certfile options', function() { + // set up starting variables + var desc = { + keyfile: { shortOption: 'K', name: 'Key file' }, + certfile: { shortOption: 'C', name: 'Cert file' }, + }; + var argv = [ '-K', 'key.pem', '--certfile', 'cert.pem' ]; + // initiate spys + // spyOn(fs, 'readFileSync').and.returnValue(Buffer.from('abc')); + // spyOn(request, 'defaults'); + + var opts = options.getopts(argv, 0, desc); + // validate the short option is working + assert.equal(opts.keyfile, 'key.pem'); + // validate the long option is working + assert.equal(opts.certfile, 'cert.pem'); + + // validate the changed defaults.js code reads the .pem files + // and sets up the request options object with the file buffers + var rqst = defaults.defaultRequest(opts); + // validate the files is read when the options is set + expect(fs.readFileSync).toHaveBeenCalledWith('key.pem'); + expect(fs.readFileSync).toHaveBeenCalledWith('cert.pem'); + // validate the request's default request object is constructed with key/cert buffers + expect(request.defaults).toHaveBeenCalledWith( + { + 'auth': {}, + 'json': true, + 'headers': {}, + 'agentOptions': {}, + 'key': Buffer.from('abc'), + 'cert': Buffer.from('abc') + }); + }); + + // negative case, i.e. the additional options are not included as + // part of the command line switches + it('Test omitting the --keyfile/--certfile options', function() { + // set up starting variables + var desc = { + keyfile: { shortOption: 'K', name: 'Key file' }, + certfile: { shortOption: 'C', name: 'Cert file' }, + }; + var argv = [ ]; + // initiate spys + // spyOn(fs, 'readFileSync').and.returnValue(Buffer.from('abc')); + // spyOn(request, 'defaults'); + + var opts = options.getopts(argv, 0, desc); + // validate the options were not set + assert.equal(opts.keyfile, undefined); + assert.equal(opts.certfile, undefined); + + // validate the undefined options don't attempt a file read + var rqst = defaults.defaultRequest(opts); + // validate the files is read when the options is set + expect(fs.readFileSync).not.toHaveBeenCalled(); + }); + it('Test secure value', function() { var sv = new options.SecureValue('foobar'); assert.notEqual(util.format('%s', sv), 'foobar'); From 4b45e36b2e793ba23a1232522f338eb5fe0f0e75 Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Mon, 23 Sep 2019 14:58:50 -0400 Subject: [PATCH 07/19] Made key and cert file options default --- lib/defaults.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/defaults.js b/lib/defaults.js index d937b13..254c180 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -92,14 +92,6 @@ var DefaultDescriptor = { shortOption: 'C', scope: 'default' }, - keyfile: { - name: 'Key file', - shortOption: 'K' - }, - certfile: { - name: 'Cert file', - shortOption: 'C' - }, insecure: { name: 'insecure', shortOption: 'k', From a010f426b6a2dee93b6c1045a7287627a61032ab Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Tue, 24 Sep 2019 11:59:47 -0400 Subject: [PATCH 08/19] Implemented Issue #159 - Flow Hooks --- README.md | 83 ++++++++++++++++++++++++- lib/commands/attachFlowHook.js | 52 ++++++++++++++++ lib/commands/commands.js | 18 ++++++ lib/commands/detachFlowHook.js | 42 +++++++++++++ lib/commands/fetchsharedflow.js | 3 +- lib/commands/getFlowHook.js | 42 +++++++++++++ lib/main.js | 15 +++++ lib/promisesdk.js | 21 +++++++ remotetests/remotetest.js | 107 +++++++++++++++++++++++++++++--- 9 files changed, 370 insertions(+), 13 deletions(-) create mode 100644 lib/commands/attachFlowHook.js create mode 100644 lib/commands/detachFlowHook.js create mode 100644 lib/commands/getFlowHook.js diff --git a/README.md b/README.md index cbeeeb6..8e56de6 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ You must have an account on Apigee Edge to perform any `apigeetool` functions. T * create, retrieve or delete a KVM Map in Edge * create, retrieve or delete a KVM Entry in Edge * create, delete Target Servers +* attach, detach, or get a FlowHook You need to be familiar with basic concepts and features of Apigee Edge such as API proxies, organizations, and environments. @@ -98,6 +99,7 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default # Command reference and examples * [addEntryToKVM](#addEntryToKVM) +* [attachFlowHook](#attachFlowHook) * [createappkey](#createappkey) * [createapp](#createapp) * [createcache](#createcache) @@ -118,9 +120,10 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default * [deploynodeapp](#deploynodeapp) * [deployproxy](#deployproxy) * [deploySharedflow](#deploySharedflow) -* [detachFlowHook](#detachFlowHook) +* [detachFlowHook](#detachFlowHook) * [fetchproxy](#fetchproxy) * [fetchSharedflow](#fetchSharedflow) +* [getFlowHook](#getFlowHook) * [getKVMentry](#getKVMentry) * [getKVMmap](#getKVMmap) * [getlogs](#getlogs) @@ -572,7 +575,7 @@ for organization name, all of which are required. ## undeploySharedflow -Undeploys a named API proxy or Node.js app deployed on Apigee Edge. +Undeploys a SharedFlow deployed on Apigee Edge. #### Example @@ -982,6 +985,82 @@ the "-u" and "-p" parameters for username and password or preferably -N for .net `--environment -e` (required) The environment to target. `--targetServerName` (required) The name of the Target Server to be deleted. +## FlowHook Operations + +Operations on the pre-defined FlowHook names: + +* PreProxyFlowHook +* PreTargetFlowHook +* PostTargetFlowHook +* PostProxyFlowHook + +### attachFlowHook + +Attach a deployed SharedFlow to one of the [named FlowHooks](#FlowHook Operations). + +#### Example +Attach SharedFlow "GetLogValues" to "PreProxyFlowHook". + + apigeetool attachFlowHook -N -o $ORG -e $ENV --flowHookName PreProxyFlowHook --sharedFlowName GetLogValues + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--environment -e` (required) The environment to target. +`--flowHookName` (required) The pre-defined name of the FlowHook. +`--sharedFlowName` (required) The name of a deployed SharedFlow. + +### detachFlowHook + +Detach a SharedFlow from one of the [named FlowHooks](#FlowHook Operations). + +#### Example +Detach "PreProxyFlowHook". + + apigeetool detachFlowHook -N -o $ORG -e $ENV --flowHookName PreProxyFlowHook + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--environment -e` (required) The environment to target. +`--flowHookName` (required) The pre-defined name of the FlowHook. + +### getFlowHook + +Get the SharedFlow currently attached to one of the [named FlowHooks](#FlowHook Operations). + +#### Example +Detach "PreProxyFlowHook". + + apigeetool getFlowHook -N -o $ORG -e $ENV --flowHookName PreProxyFlowHook + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--environment -e` (required) The environment to target. +`--flowHookName` (required) The pre-defined name of the FlowHook. + # SDK Reference You could use apigeetool as an SDK to orchestrate tasks that you want to perform with Edge, for eg, deploying an api proxy or running tests etc. diff --git a/lib/commands/attachFlowHook.js b/lib/commands/attachFlowHook.js new file mode 100644 index 0000000..3d113d7 --- /dev/null +++ b/lib/commands/attachFlowHook.js @@ -0,0 +1,52 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + environment: { + name: 'Environment', + shortOption: 'e', + required: true, + prompt: true + }, + flowHookName: { + name: 'One of: PreProxyFlowHook\n PreTargetFlowHook\n PostTargetFlowHook\n PostProxyFlowHook', + required: true, + prompt: true + }, + sharedFlowName: { + name: 'Shared Flow name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('attachFlowHook: %j', opts); + } + var payload = { + "continueOnError" : true, + "sharedFlow" : opts.sharedFlowName + } + if(opts.targetSSL){ + payload.sSLInfo = {enabled: true} + } + + var uri = util.format('%s/v1/o/%s/e/%s/flowhooks/%s', opts.baseuri, opts.organization, opts.environment, opts.flowHookName); + var requestOpts = { + uri: uri, + method:'POST', + body: payload, + json:true + } + command_utils.run('attachFlowHook',opts, requestOpts, cb) +}; diff --git a/lib/commands/commands.js b/lib/commands/commands.js index 35dd8b7..abc275b 100644 --- a/lib/commands/commands.js +++ b/lib/commands/commands.js @@ -7,6 +7,24 @@ var Table = require('cli-table'); var options = require('../options'); var Commands = { + attachFlowHook: { + description: 'Attach a Shared Flow to a Flow Hook', + load: function() { + return require('./attachFlowHook'); + } + }, + detachFlowHook: { + description: 'Detach a Shared Flow from a Flow Hook', + load: function() { + return require('./detachFlowHook'); + } + }, + getFlowHook: { + description: 'Get the Shared Flow attached to a Flow Hook', + load: function() { + return require('./getFlowHook'); + } + }, createTargetServer: { description: 'Create a Target Server', load: function() { diff --git a/lib/commands/detachFlowHook.js b/lib/commands/detachFlowHook.js new file mode 100644 index 0000000..4de2d49 --- /dev/null +++ b/lib/commands/detachFlowHook.js @@ -0,0 +1,42 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + environment: { + name: 'Environment', + shortOption: 'e', + required: true, + prompt: true + }, + flowHookName: { + name: 'One of: PreProxyFlowHook\n PreTargetFlowHook\n PostTargetFlowHook\n PostProxyFlowHook', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('detachFlowHook: %j', opts); + } + if(opts.targetSSL){ + payload.sSLInfo = {enabled: true} + } + + var uri = util.format('%s/v1/o/%s/e/%s/flowhooks/%s', opts.baseuri, opts.organization, opts.environment, opts.flowHookName); + var requestOpts = { + uri: uri, + method:'DELETE', + json:true + } + command_utils.run('detachFlowHook',opts, requestOpts, cb) +}; diff --git a/lib/commands/fetchsharedflow.js b/lib/commands/fetchsharedflow.js index 73578ac..e6147f1 100644 --- a/lib/commands/fetchsharedflow.js +++ b/lib/commands/fetchsharedflow.js @@ -69,11 +69,12 @@ module.exports.run = function (opts, cb) { if (err) { console.log("Failed to write file: " + f); console.log("Error text: " + err); + cb(err); } else { if (opts.verbose) { console.log('Save file: ' + f); } + cb(undefined, res.statusCode + " - wrote: " + f); } - cb(err); }); } } diff --git a/lib/commands/getFlowHook.js b/lib/commands/getFlowHook.js new file mode 100644 index 0000000..4a7e2c0 --- /dev/null +++ b/lib/commands/getFlowHook.js @@ -0,0 +1,42 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + environment: { + name: 'Environment', + shortOption: 'e', + required: true, + prompt: true + }, + flowHookName: { + name: 'One of: PreProxyFlowHook\n PreTargetFlowHook\n PostTargetFlowHook\n PostProxyFlowHook', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('getFlowHook: %j', opts); + } + if(opts.targetSSL){ + payload.sSLInfo = {enabled: true} + } + + var uri = util.format('%s/v1/o/%s/e/%s/flowhooks/%s', opts.baseuri, opts.organization, opts.environment, opts.flowHookName); + var requestOpts = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('getFlowHook',opts, requestOpts, cb) +}; diff --git a/lib/main.js b/lib/main.js index 570631a..f079970 100644 --- a/lib/main.js +++ b/lib/main.js @@ -163,6 +163,21 @@ ApigeeTool.deleteSharedflow = function (opts, cb) { runCommand(cmd, opts, cb); }; +ApigeeTool.attachFlowHook = function (opts, cb) { + var cmd = require('./commands/attachFlowHook.js'); + runCommand(cmd, opts, cb); +}; + +ApigeeTool.detachFlowHook = function (opts, cb) { + var cmd = require('./commands/detachFlowHook.js'); + runCommand(cmd, opts, cb); +}; + +ApigeeTool.getFlowHook = function (opts, cb) { + var cmd = require('./commands/getFlowHook.js'); + runCommand(cmd, opts, cb); +}; + function runCommand(cmd, opts, cb) { options.validate(opts, cmd.descriptor, function(err) { if (err) { diff --git a/lib/promisesdk.js b/lib/promisesdk.js index 6daa79b..60c7c07 100644 --- a/lib/promisesdk.js +++ b/lib/promisesdk.js @@ -231,6 +231,27 @@ ApigeeTool.createAppKey = function(opts) { return cb.promise } +ApigeeTool.attachFlowHook = function(opts) { + var cb = q.defer() + var cmd = require('./commands/attachFlowHook'); + runCommand(cmd, opts, cb); + return cb.promise +} + +ApigeeTool.detachFlowHook = function(opts) { + var cb = q.defer() + var cmd = require('./commands/detachFlowHook'); + runCommand(cmd, opts, cb); + return cb.promise +} + +ApigeeTool.getFlowHook = function(opts) { + var cb = q.defer() + var cmd = require('./commands/getFlowHook'); + runCommand(cmd, opts, cb); + return cb.promise +} + function runCommand(cmd, opts, cb) { options.validate(opts, cmd.descriptor, function(err) { if (err) { diff --git a/remotetests/remotetest.js b/remotetests/remotetest.js index 3022f7f..f3bd93c 100644 --- a/remotetests/remotetest.js +++ b/remotetests/remotetest.js @@ -27,10 +27,11 @@ var SHARED_FLOW_NAME = 'apigee-cli-sf'; var verbose = false; var deployedRevision; var deployedUri; +var prevSharedFlow; // Run all using: mocha remotetests // Run all "describe" tests using: mocha remotetests --grep "SharedFlows and FlowHooks" -// Run one "it" test using: mocha remotetests --grep "fetchSharedflow" +// Run one "it" test using: mocha remotetests --grep "fetchSharedFlow" // To see tests use 'grep " it" remotetest.j' describe('Remote Tests', function() { // it @@ -1079,7 +1080,7 @@ describe('KVM', function() { // it }); }); // end KVM tests -describe('SharedFlows', function() { // it +describe('SharedFlows and FlowHooks', function() { // it this.timeout(REASONABLE_TIMEOUT); it('Deploy SharedFlow', function (done) { var opts = baseOpts(); @@ -1112,30 +1113,42 @@ describe('SharedFlows', function() { // it }); }); - it('listSharedflowDeployments', function(done) { + it('listSharedFlowDeployments', function(done) { var opts = baseOpts(); - opts.sharedFlowName = SHARED_FLOW_NAME; + delete opts.environment; + opts.name = SHARED_FLOW_NAME; opts.revision = 1; apigeetool.listSharedflowDeployments(opts, function(err, result) { if (verbose) { - console.log('listSharedflowDeployments result = %j', result); + console.log('listSharedFlowDeployments result = %j', result); } if (err) { done(err); - } else { done(); } + } else { + try { + result = result.deployments[0]; + assert.equal(result.name, SHARED_FLOW_NAME); + assert.equal(result.environment, config.environment); + assert.equal(result.state, 'deployed'); + assert(typeof result.revision === 'number'); + done(); + } catch (e) { + done(e); + } + } }); }); - it('fetchSharedflow', function(done) { + it('fetchSharedFlow', function(done) { var opts = baseOpts(); opts.name = SHARED_FLOW_NAME; opts.revision = 1 apigeetool.fetchSharedflow(opts, function(err, result) { if (verbose) { - console.log('fetchSharedflow result = %j', result); + console.log('fetchSharedFlow result: %j', result); } if (err) { done(err); @@ -1143,7 +1156,81 @@ describe('SharedFlows', function() { // it }); }); - it('undeploySharedflow', function(done) { + it('getPreviousSharedFlow', function(done) { + var opts = baseOpts(); + opts.flowHookName = "PreProxyFlowHook"; + + apigeetool.getFlowHook(opts, function(err, result) { + if (verbose) { + console.log('getPreviousSharedFlow result = %j', result); + } + if (err) { + done(err); + } else { + if( result.sharedFlow ) { + prevSharedFlow = result.sharedFlow; + } + done(); + } + }); + }); + + it('attachFlowHook', function(done) { + var opts = baseOpts(); + opts.flowHookName = "PreProxyFlowHook"; + opts.sharedFlowName = SHARED_FLOW_NAME; + + apigeetool.attachFlowHook(opts, function(err, result) { + if (verbose) { + console.log('attachFlowHook result = %j', result); + } + if (err) { + done(err); + } else { + done(); + } + }); + }); + + it('detachFlowHook', function(done) { + var opts = baseOpts(); + opts.flowHookName = "PreProxyFlowHook"; + + apigeetool.detachFlowHook(opts, function(err, result) { + if (verbose) { + console.log('detachFlowHook result = %j', result); + } + if (err) { + done(err); + } else { + done(); + } + }); + }); + + it('re-attachFlowHook', function(done) { + if( prevSharedFlow ) { + var opts = baseOpts(); + opts.flowHookName = "PreProxyFlowHook"; + opts.sharedFlowName = prevSharedFlow; + + apigeetool.attachFlowHook(opts, function(err, result) { + if (verbose) { + console.log('prevSharedFlow ' + prevSharedFlow ); + console.log('re-attachFlowHook result = %j', result); + } + if (err) { + done(err); + } else { + done(); + } + }); + } else { + done(); + } + }); + + it('undeploySharedFlow', function(done) { var opts = baseOpts(); opts.name = SHARED_FLOW_NAME; @@ -1156,7 +1243,7 @@ describe('SharedFlows', function() { // it }); }); - it('deleteSharedflow', function(done) { + it('deleteSharedFlow', function(done) { var opts = baseOpts(); opts.name = SHARED_FLOW_NAME; apigeetool.deleteSharedflow(opts, done); From d11585f8d3d6fd022fb4a437a7a73d70c5b8d2ec Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Tue, 24 Sep 2019 13:19:54 -0400 Subject: [PATCH 09/19] Implemented Issue #162 - Target Server Get and List --- README.md | 47 +++++++++++++- lib/commands/commands.js | 12 ++++ lib/commands/create-TargetServer.js | 3 +- lib/commands/delete-TargetServer.js | 3 +- lib/commands/get-TargetServer.js | 38 +++++++++++ lib/commands/list-TargetServers.js | 33 ++++++++++ lib/main.js | 10 +++ lib/promisesdk.js | 14 +++++ remotetests/remotetest.js | 98 ++++++++++++++++++++++------- 9 files changed, 233 insertions(+), 25 deletions(-) create mode 100644 lib/commands/get-TargetServer.js create mode 100644 lib/commands/list-TargetServers.js diff --git a/README.md b/README.md index 8e56de6..c3874c4 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,8 @@ You must have an account on Apigee Edge to perform any `apigeetool` functions. T * create or delete a Cache resource in Edge * create, retrieve or delete a KVM Map in Edge * create, retrieve or delete a KVM Entry in Edge -* create, delete Target Servers * attach, detach, or get a FlowHook +* create, get, delete, list Target Servers You need to be familiar with basic concepts and features of Apigee Edge such as API proxies, organizations, and environments. @@ -127,8 +127,10 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default * [getKVMentry](#getKVMentry) * [getKVMmap](#getKVMmap) * [getlogs](#getlogs) +* [getTargetServer](#getTargetServer) * [listdeployments](#listdeployments) * [listSharedflowDeployments](#listSharedflowDeployments) +* [listTargetServers](#listTargetServers) * [undeploySharedflow](#undeploySharedflow) * [undeploy](#undeploy) @@ -985,6 +987,49 @@ the "-u" and "-p" parameters for username and password or preferably -N for .net `--environment -e` (required) The environment to target. `--targetServerName` (required) The name of the Target Server to be deleted. +### getTargetServer + +Get details for a Target Server with the given name. + +#### Example +Get Target Server named "test-target". + + apigeetool getTargetServer -N -o $ORG -e $ENV --targetServerName test-target + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--environment -e` (required) The environment to target. +`--targetServerName` (required) The name of the Target Server to be deleted. + +### listTargetServers + +List Target Servers in a given environment. + +#### Example +List Target Servers. + + apigeetool listTargetServers -N -o $ORG -e $ENV + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--environment -e` (required) The environment to target. + ## FlowHook Operations Operations on the pre-defined FlowHook names: diff --git a/lib/commands/commands.js b/lib/commands/commands.js index abc275b..7e18485 100644 --- a/lib/commands/commands.js +++ b/lib/commands/commands.js @@ -37,6 +37,18 @@ var Commands = { return require('./delete-TargetServer'); } }, + getTargetServer: { + description: 'Get a Target Server', + load: function() { + return require('./get-TargetServer'); + } + }, + listTargetServers: { + description: 'List Target Servers', + load: function() { + return require('./list-TargetServers'); + } + }, createkvmmap: { description: 'Create a KVM map', load: function() { diff --git a/lib/commands/create-TargetServer.js b/lib/commands/create-TargetServer.js index 6996552..9721306 100644 --- a/lib/commands/create-TargetServer.js +++ b/lib/commands/create-TargetServer.js @@ -12,7 +12,8 @@ var descriptor = defaults.defaultDescriptor({ environment: { name: 'Environment', shortOption: 'e', - required: true + required: true, + prompt: true }, targetServerName: { name: 'Target Server Name', diff --git a/lib/commands/delete-TargetServer.js b/lib/commands/delete-TargetServer.js index 5e273e5..a2a4fa2 100644 --- a/lib/commands/delete-TargetServer.js +++ b/lib/commands/delete-TargetServer.js @@ -12,7 +12,8 @@ var descriptor = defaults.defaultDescriptor({ environment: { name: 'Environment', shortOption: 'e', - required: true + required: true, + prompt: true }, targetServerName: { name: 'Target Server Name', diff --git a/lib/commands/get-TargetServer.js b/lib/commands/get-TargetServer.js new file mode 100644 index 0000000..03ddd63 --- /dev/null +++ b/lib/commands/get-TargetServer.js @@ -0,0 +1,38 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + environment: { + name: 'Environment', + shortOption: 'e', + required: true, + prompt: true + }, + targetServerName: { + name: 'Target Server Name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('getTargetServer: %j', opts); + } + var uri = util.format('%s/v1/o/%s/e/%s/targetservers/%s', opts.baseuri, opts.organization, opts.environment,opts.targetServerName); + var requestOptions = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('getTargetServer', opts,requestOptions,cb) +}; diff --git a/lib/commands/list-TargetServers.js b/lib/commands/list-TargetServers.js new file mode 100644 index 0000000..32a72e5 --- /dev/null +++ b/lib/commands/list-TargetServers.js @@ -0,0 +1,33 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + environment: { + name: 'Environment', + shortOption: 'e', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('listTargetServers: %j', opts); + } + var uri = util.format('%s/v1/o/%s/e/%s/targetservers', opts.baseuri, opts.organization, opts.environment); + var requestOptions = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('listTargetServers', opts,requestOptions,cb) +}; diff --git a/lib/main.js b/lib/main.js index f079970..6f23738 100644 --- a/lib/main.js +++ b/lib/main.js @@ -103,11 +103,21 @@ ApigeeTool.createTargetServer = function(opts, cb) { runCommand(cmd, opts, cb); }; +ApigeeTool.getTargetServer = function (opts, cb) { + var cmd = require('./commands/get-TargetServer.js'); + runCommand(cmd, opts, cb); +}; + ApigeeTool.deleteTargetServer = function(opts,cb){ var cmd = require('./commands/delete-TargetServer'); runCommand(cmd, opts, cb); }; +ApigeeTool.listTargetServers = function(opts, cb) { + var cmd = require('./commands/list-TargetServers'); + runCommand(cmd, opts, cb); +}; + ApigeeTool.createKVM = function(opts, cb) { var cmd = require('./commands/create-KVM'); runCommand(cmd, opts, cb); diff --git a/lib/promisesdk.js b/lib/promisesdk.js index 60c7c07..226edf4 100644 --- a/lib/promisesdk.js +++ b/lib/promisesdk.js @@ -175,6 +175,20 @@ ApigeeTool.deleteTargetServer = function(opts){ return cb.promise } +ApigeeTool.getTargetServer = function(opts) { + var cb = q.defer() + var cmd = require('./commands/get-TargetServer'); + runCommand(cmd, opts, cb); + return cb.promise +}; + +ApigeeTool.listTargetServers = function(opts) { + var cb = q.defer() + var cmd = require('./commands/list-TargetServers'); + runCommand(cmd, opts, cb); + return cb.promise +}; + ApigeeTool.createKVM = function(opts) { var cb = q.defer() var cmd = require('./commands/create-KVM'); diff --git a/remotetests/remotetest.js b/remotetests/remotetest.js index f3bd93c..d54ef18 100644 --- a/remotetests/remotetest.js +++ b/remotetests/remotetest.js @@ -889,7 +889,7 @@ describe('Caches', function() { // it describe('Target Servers', function() { // it this.timeout(REASONABLE_TIMEOUT); - it('Create Target Server SDK',function(done){ + it('Create Target Server',function(done){ var opts = baseOpts(); opts.environment = config.environment; opts.targetServerName = TARGET_SERVER_NAME; @@ -897,35 +897,89 @@ describe('Target Servers', function() { // it opts.targetEnabled = true; opts.targetPort = 443; opts.targetSSL=true; + opts.environment = config.environment + + apigeetool.createTargetServer(opts, function(err, result) { + if (verbose) { + console.log('Create Target Server result = %j', result); + } + if (err) { + done(err); + } else { + try { + assert.equal(result.name,TARGET_SERVER_NAME); + assert.equal(result.port,443); + assert.equal(result.isEnabled,true); + done(); + } catch (e) { + done(e); + } + } + }); + }); + + it('List Target Servers',function(done){ + var opts = baseOpts(); opts.environment = config.environment; - apigeetool.getPromiseSDK() - .createTargetServer(opts) - .then(function(res){ - if (verbose) { - console.log('Create Target Server result = %j', res); + apigeetool.listTargetServers(opts, function(err, result) { + if (verbose) { + console.log('List Target Servers result = %j', result); + } + if (err) { + done(err); + } else { + try { + assert.equal(result.includes(TARGET_SERVER_NAME),true); + done(); + } catch (e) { + done(e); } - done() - },function(err){ - console.log(err) - done(err) - }) + } + }); }); - it('Delete Target Server SDK',function(done){ + it('Get Target Server',function(done){ var opts = baseOpts(); opts.environment = config.environment; opts.targetServerName = TARGET_SERVER_NAME; - apigeetool.getPromiseSDK() - .deleteTargetServer(opts) - .then(function(res){ - if (verbose) { - console.log('Delete Target Server result = %j', res); + apigeetool.getTargetServer(opts, function(err, result) { + if (verbose) { + console.log('Get Target Server result = %j', result); + } + if (err) { + done(err); + } else { + try { + assert.equal(result.name,TARGET_SERVER_NAME); + assert.equal(result.port,443); + assert.equal(result.isEnabled,true); + done(); + } catch (e) { + done(e); } - done() - },function(err){ - console.log(err) - done(err) - }) + } + }); + }); + + it('Delete Target Server',function(done){ + var opts = baseOpts(); + opts.environment = config.environment; + opts.targetServerName = TARGET_SERVER_NAME; + apigeetool.deleteTargetServer(opts, function(err, result) { + if (verbose) { + console.log('Delete Target Server result = %j', result); + } + if (err) { + done(err); + } else { + try { + assert.equal(result.name,TARGET_SERVER_NAME); + done(); + } catch (e) { + done(e); + } + } + }); }); }); // end target server tests From 20fbd150573702ff95213111f5d0cc9f001449b3 Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Tue, 24 Sep 2019 17:13:12 -0400 Subject: [PATCH 10/19] Implemented Issue #167 - Roles, Permissions and User assignment --- README.md | 236 +++++++++++++++++++++++++++++ lib/commands/assignUserRole.js | 41 +++++ lib/commands/commands.js | 60 ++++++++ lib/commands/createRole.js | 39 +++++ lib/commands/deleteRole.js | 32 ++++ lib/commands/getRole.js | 32 ++++ lib/commands/getRolePermissions.js | 32 ++++ lib/commands/listRoleUsers.js | 33 ++++ lib/commands/listRoles.js | 27 ++++ lib/commands/removeUserRole.js | 38 +++++ lib/commands/setRolePermissions.js | 45 ++++++ lib/commands/verifyUserRole.js | 38 +++++ lib/main.js | 41 +++++ lib/promisesdk.js | 61 ++++++++ remotetests/remotetest.js | 151 ++++++++++++++++++ 15 files changed, 906 insertions(+) create mode 100644 lib/commands/assignUserRole.js create mode 100644 lib/commands/createRole.js create mode 100644 lib/commands/deleteRole.js create mode 100644 lib/commands/getRole.js create mode 100644 lib/commands/getRolePermissions.js create mode 100644 lib/commands/listRoleUsers.js create mode 100644 lib/commands/listRoles.js create mode 100644 lib/commands/removeUserRole.js create mode 100644 lib/commands/setRolePermissions.js create mode 100644 lib/commands/verifyUserRole.js diff --git a/README.md b/README.md index c3874c4..0cd0371 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,10 @@ You must have an account on Apigee Edge to perform any `apigeetool` functions. T * create, retrieve or delete a KVM Entry in Edge * attach, detach, or get a FlowHook * create, get, delete, list Target Servers +* create, get, delete, List Roles +* get, set Role Permisions +* assign, remove, verify Users for a Role +* list all Users in a Role You need to be familiar with basic concepts and features of Apigee Edge such as API proxies, organizations, and environments. @@ -99,6 +103,7 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default # Command reference and examples * [addEntryToKVM](#addEntryToKVM) +* [assignUserRole](#assignUserRole) * [attachFlowHook](#attachFlowHook) * [createappkey](#createappkey) * [createapp](#createapp) @@ -106,6 +111,7 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default * [createdeveloper](#createdeveloper) * [createKVMmap](#createKVMmap) * [createProduct](#createproduct) +* [createRole](#createRole) * [createTargetServer](#createTargetServer) * [deleteapp](#deleteapp) * [deletecache](#deletecache) @@ -113,6 +119,7 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default * [deleteKVMentry](#deleteKVMentry) * [deleteKVMmap](#deleteKVMmap) * [deleteproduct](#deleteproduct) +* [deleteRole](#deleteRole) * [deleteSharedflow](#deleteSharedflow) * [deleteTargetServer](#deleteTargetServer) * [delete](#delete) @@ -127,12 +134,19 @@ Currently this only affects file uploads in the `deploynodeapp` command. Default * [getKVMentry](#getKVMentry) * [getKVMmap](#getKVMmap) * [getlogs](#getlogs) +* [getRole](#getRole) +* [getRolePermissions](#getRolePermissions) * [getTargetServer](#getTargetServer) * [listdeployments](#listdeployments) +* [listRoles](#listRoles) +* [listRoleUsers](#listRoleUsers) * [listSharedflowDeployments](#listSharedflowDeployments) * [listTargetServers](#listTargetServers) +* [removeUserRole](#removeUserRole) +* [setRolePermissions](#setRolePermissions) * [undeploySharedflow](#undeploySharedflow) * [undeploy](#undeploy) +* [verifyUserRole](#verifyUserRole) ## deploynodeapp @@ -1106,6 +1120,228 @@ the "-u" and "-p" parameters for username and password or preferably -N for .net `--environment -e` (required) The environment to target. `--flowHookName` (required) The pre-defined name of the FlowHook. +## Roles and Permissions Operations + +Operations on Roles, Permissions and User assignment. The general flow is: + +* Create a role +* Assign Permissions to the Role +* Assign the Role to a User + +### createRole + +Create a role. + +#### Example +Create role "AllowGetUserRoles". + + apigeetool createRole -N -o $ORG --roleName AllowGetUserRoles + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--roleName` (required) The name for the role. + +### getRole + +Get a role. + +#### Example +Get role "AllowGetUserRoles". + + apigeetool getRole -N -o $ORG --roleName AllowGetUserRoles + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--roleName` (required) The name for the role. + +### deleteRole + +Delete a role. + +#### Example +Delete role "AllowGetUserRoles". + + apigeetool deleteRole -N -o $ORG --roleName AllowGetUserRoles + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--roleName` (required) The name for the role. + +### listRoles + +List roles. + +#### Example +List roles. + + apigeetool listRoles -N -o $ORG + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. + +### setRolePermissions + +Set Role Permissions for a Role. + +#### Example +Set Permissions on Role "AllowGetUserRoles" to allow access to list Roles. + + apigeetool setRolePermissions -N -o $ORG --roleName AllowGetUserRoles --permissions '[{"path":"/userroles","permissions":["get"]}]' + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--roleName` (required) The name for the role. +`--permissions` Permissions array for path and verbs. + +### getRolePermissions + +Get Role Permissions for a Role. + +#### Example +Get Permissions on Role "AllowGetUserRoles". + + apigeetool getRolePermissions -N -o $ORG --roleName AllowGetUserRoles + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--roleName` (required) The name for the role. + +### assignUserRole + +Assign existing User to a Role. NOTE: User must already exist in Edge. + +#### Example +Assign "somedeveloper@any.com" to Role "AllowGetUserRoles". + + apigeetool assignUserRole -N -o $ORG --email "somedeveloper@any.com" --roleName AllowGetUserRoles + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--email` (required) Email for an existing User in Edge. +`--roleName` (required) The name for the role. + +### removeUserRole + +Remove existing User from a Role. + +#### Example +Remove "somedeveloper@any.com" from Role "AllowGetUserRoles". + + apigeetool removeUserRole -N -o $ORG --email "somedeveloper@any.com" --roleName AllowGetUserRoles + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--email` (required) Email for an existing User in Edge. +`--roleName` (required) The name for the role. + +### verifyUserRole + +Verify User assigned to a Role. + +#### Example +Verify "somedeveloper@any.com" assigned to Role "AllowGetUserRoles". + + apigeetool verifyUserRole -N -o $ORG --email "somedeveloper@any.com" --roleName AllowGetUserRoles + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--email` (required) Email for an existing User in Edge. +`--roleName` (required) The name for the role. + +### listRoleUsers + +Get Users assigned to a Role. + +#### Example +List Users assigned to Role "AllowGetUserRoles". + + apigeetool listRoleUsers -N -o $ORG --roleName AllowGetUserRoles + +#### Required parameters + +The following parameters are required. However, if any are left unspecified +on the command line, and if apigeetool is running in an interactive shell, +then apigeetool will prompt for them. + +See [Common Parameters](#commonargs) for a list of additional parameters, including +the "-u" and "-p" parameters for username and password or preferably -N for .netrc usage. + +`--organization -o` (required) The organization to target. +`--email` (required) Email for an existing User in Edge. +`--roleName` (required) The name for the role. + # SDK Reference You could use apigeetool as an SDK to orchestrate tasks that you want to perform with Edge, for eg, deploying an api proxy or running tests etc. diff --git a/lib/commands/assignUserRole.js b/lib/commands/assignUserRole.js new file mode 100644 index 0000000..014aced --- /dev/null +++ b/lib/commands/assignUserRole.js @@ -0,0 +1,41 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + }, + email: { + name: 'Developer email', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('assignUserRole: %j', opts); + } + + var formData = util.format('id=%s', encodeURIComponent(opts.email)); + var uri = util.format('%s/v1/o/%s/userroles/%s/users', opts.baseuri, opts.organization, opts.roleName); + var requestOptions = { + uri: uri, + method:'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: formData, + json:true + } + command_utils.run('assignUserRole', opts,requestOptions,cb) +}; diff --git a/lib/commands/commands.js b/lib/commands/commands.js index 7e18485..26445fb 100644 --- a/lib/commands/commands.js +++ b/lib/commands/commands.js @@ -216,6 +216,66 @@ var Commands = { load: function () { return require('./deployExistingRevision'); } + }, + listRoles: { + description: "List roles in an organziation", + load: function () { + return require('./listRoles'); + } + }, + createRole: { + description: "Create a userrole in an organziation", + load: function () { + return require('./createRole'); + } + }, + getRole: { + description: "Get a userrole in an organziation", + load: function () { + return require('./getRole'); + } + }, + deleteRole: { + description: "Delete a userrole in an organziation", + load: function () { + return require('./deleteRole'); + } + }, + getRolePermissions: { + description: "Get resource permissions for a role", + load: function () { + return require('./getRolePermissions'); + } + }, + setRolePermissions: { + description: "Set resource permissions for a role", + load: function () { + return require('./setRolePermissions'); + } + }, + assignUserRole: { + description: "Assign user to a role", + load: function () { + return require('./assignUserRole'); + } + }, + removeUserRole: { + description: "Remove user from a role", + load: function () { + return require('./removeUserRole'); + } + }, + verifyUserRole: { + description: "Verify a user is in a role", + load: function () { + return require('./verifyUserRole'); + } + }, + listRoleUsers: { + description: "List users in role", + load: function () { + return require('./listRoleUsers'); + } } }; diff --git a/lib/commands/createRole.js b/lib/commands/createRole.js new file mode 100644 index 0000000..fe56346 --- /dev/null +++ b/lib/commands/createRole.js @@ -0,0 +1,39 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('createRole: %j', opts); + } + var payload = { + "role" : [ + {"name" : opts.roleName} + ] + }; + + var uri = util.format('%s/v1/o/%s/userroles', opts.baseuri, opts.organization); + var requestOptions = { + uri: uri, + method:'POST', + body: payload, + json:true + } + command_utils.run('createRole', opts,requestOptions,cb) +}; diff --git a/lib/commands/deleteRole.js b/lib/commands/deleteRole.js new file mode 100644 index 0000000..99623ba --- /dev/null +++ b/lib/commands/deleteRole.js @@ -0,0 +1,32 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('deleteRole: %j', opts); + } + var uri = util.format('%s/v1/o/%s/userroles/%s', opts.baseuri, opts.organization, opts.roleName); + var requestOptions = { + uri: uri, + method:'DELETE', + json:true + } + command_utils.run('deleteRole', opts,requestOptions,cb) +}; diff --git a/lib/commands/getRole.js b/lib/commands/getRole.js new file mode 100644 index 0000000..8c9b4cc --- /dev/null +++ b/lib/commands/getRole.js @@ -0,0 +1,32 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('getRole: %j', opts); + } + var uri = util.format('%s/v1/o/%s/userroles/%s', opts.baseuri, opts.organization, opts.roleName); + var requestOptions = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('getRole', opts,requestOptions,cb) +}; diff --git a/lib/commands/getRolePermissions.js b/lib/commands/getRolePermissions.js new file mode 100644 index 0000000..86cdb2c --- /dev/null +++ b/lib/commands/getRolePermissions.js @@ -0,0 +1,32 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('getRolePermissions: %j', opts); + } + var uri = util.format('%s/v1/o/%s/userroles/%s/permissions', opts.baseuri, opts.organization, opts.roleName); + var requestOptions = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('getRolePermissions', opts,requestOptions,cb) +}; diff --git a/lib/commands/listRoleUsers.js b/lib/commands/listRoleUsers.js new file mode 100644 index 0000000..10e760b --- /dev/null +++ b/lib/commands/listRoleUsers.js @@ -0,0 +1,33 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('getRoleUsers: %j', opts); + } + + var uri = util.format('%s/v1/o/%s/userroles/%s/users', opts.baseuri, opts.organization, opts.roleName); + var requestOptions = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('getRoleUsers', opts,requestOptions,cb) +}; diff --git a/lib/commands/listRoles.js b/lib/commands/listRoles.js new file mode 100644 index 0000000..df4e062 --- /dev/null +++ b/lib/commands/listRoles.js @@ -0,0 +1,27 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('listRoles: %j', opts); + } + var uri = util.format('%s/v1/o/%s/userroles', opts.baseuri, opts.organization); + var requestOptions = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('listRoles', opts,requestOptions,cb) +}; diff --git a/lib/commands/removeUserRole.js b/lib/commands/removeUserRole.js new file mode 100644 index 0000000..2fcff92 --- /dev/null +++ b/lib/commands/removeUserRole.js @@ -0,0 +1,38 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + }, + email: { + name: 'Developer email', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('removeUserRole: %j', opts); + } + + var uri = util.format('%s/v1/o/%s/userroles/%s/users/%s', opts.baseuri, opts.organization, opts.roleName, opts.email ); + var requestOptions = { + uri: uri, + method:'DELETE', + json:true + } + command_utils.run('removeUserRole', opts,requestOptions,cb) +}; diff --git a/lib/commands/setRolePermissions.js b/lib/commands/setRolePermissions.js new file mode 100644 index 0000000..79f47aa --- /dev/null +++ b/lib/commands/setRolePermissions.js @@ -0,0 +1,45 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + }, + permissions: { + name: 'Permissions array for path and verbs', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('setRolePermissions: %j', opts); + } + + if( opts.permissions ) { + var permissions = JSON.parse(opts.permissions); + } + var payload = { + "resourcePermission" : permissions + }; + var uri = util.format('%s/v1/o/%s/userroles/%s/resourcepermissions', opts.baseuri, opts.organization, opts.roleName); + var requestOptions = { + uri: uri, + method:'POST', + body: payload, + json:true + } + command_utils.run('setRolePermissions', opts,requestOptions,cb) +}; diff --git a/lib/commands/verifyUserRole.js b/lib/commands/verifyUserRole.js new file mode 100644 index 0000000..a960f66 --- /dev/null +++ b/lib/commands/verifyUserRole.js @@ -0,0 +1,38 @@ +/* jshint node: true */ +'use strict'; + +var util = require('util'); +var _ = require('underscore'); + +var defaults = require('../defaults'); +var options = require('../options'); +var command_utils = require('./command-utils') + +var descriptor = defaults.defaultDescriptor({ + roleName: { + name: 'Role Name', + required: true, + prompt: true + }, + email: { + name: 'EMail for the user', + required: true, + prompt: true + } +}); + +module.exports.descriptor = descriptor; + +module.exports.run = function(opts, cb) { + if (opts.debug) { + console.log('verifyUserRole: %j', opts); + } + + var uri = util.format('%s/v1/o/%s/userroles/%s/users/%s', opts.baseuri, opts.organization, opts.roleName, opts.email ); + var requestOptions = { + uri: uri, + method:'GET', + json:true + } + command_utils.run('verifyUserRole', opts,requestOptions,cb) +}; diff --git a/lib/main.js b/lib/main.js index 6f23738..f81dffb 100644 --- a/lib/main.js +++ b/lib/main.js @@ -188,6 +188,47 @@ ApigeeTool.getFlowHook = function (opts, cb) { runCommand(cmd, opts, cb); }; +ApigeeTool.listRoles = function (opts, cb) { + var cmd = require('./commands/listRoles.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.getRole = function (opts, cb) { + var cmd = require('./commands/getRole.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.createRole = function (opts, cb) { + var cmd = require('./commands/createRole.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.deleteRole = function (opts, cb) { + var cmd = require('./commands/deleteRole.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.getRolePermissions = function (opts, cb) { + var cmd = require('./commands/getRolePermissions.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.setRolePermissions = function (opts, cb) { + var cmd = require('./commands/setRolePermissions.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.assignUserRole = function (opts, cb) { + var cmd = require('./commands/assignUserRole.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.removeUserRole = function (opts, cb) { + var cmd = require('./commands/removeUserRole.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.verifyUserRole = function (opts, cb) { + var cmd = require('./commands/verifyUserRole.js'); + runCommand(cmd, opts, cb); +}; +ApigeeTool.listRoleUsers = function (opts, cb) { + var cmd = require('./commands/listRoleUsers.js'); + runCommand(cmd, opts, cb); +}; + function runCommand(cmd, opts, cb) { options.validate(opts, cmd.descriptor, function(err) { if (err) { diff --git a/lib/promisesdk.js b/lib/promisesdk.js index 226edf4..e80fe43 100644 --- a/lib/promisesdk.js +++ b/lib/promisesdk.js @@ -266,6 +266,67 @@ ApigeeTool.getFlowHook = function(opts) { return cb.promise } +ApigeeTool.listRoles = function(opts) { + var cb = q.defer() + var cmd = require('./commands/listRoles'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.createRole = function(opts) { + var cb = q.defer() + var cmd = require('./commands/createRole'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.getRole = function(opts) { + var cb = q.defer() + var cmd = require('./commands/getRole'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.deleteRole = function(opts) { + var cb = q.defer() + var cmd = require('./commands/deleteRole'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.setRolePermissions = function(opts) { + var cb = q.defer() + var cmd = require('./commands/setRolePermissions'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.getRolePermissions = function(opts) { + var cb = q.defer() + var cmd = require('./commands/getRolePermissions'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.assignUserRole = function(opts) { + var cb = q.defer() + var cmd = require('./commands/assignUserRole'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.removeUserRole = function(opts) { + var cb = q.defer() + var cmd = require('./commands/removeUserRole'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.verifyUserRole = function(opts) { + var cb = q.defer() + var cmd = require('./commands/verifyUserRole'); + runCommand(cmd, opts, cb); + return cb.promise +} +ApigeeTool.listRoleUsers = function(opts) { + var cb = q.defer() + var cmd = require('./commands/listRoleUsers'); + runCommand(cmd, opts, cb); + return cb.promise +} + function runCommand(cmd, opts, cb) { options.validate(opts, cmd.descriptor, function(err) { if (err) { diff --git a/remotetests/remotetest.js b/remotetests/remotetest.js index d54ef18..d639913 100644 --- a/remotetests/remotetest.js +++ b/remotetests/remotetest.js @@ -24,6 +24,7 @@ var TARGET_SERVER_NAME = 'apigee-cli-test-servername'; var MAP_NAME = 'apigee-cli-test-kvm'; var MAP_NAME_ENCRYPTED = 'apigee-cli-test-kvm-encrypted'; var SHARED_FLOW_NAME = 'apigee-cli-sf'; +var ROLE_NAME = 'apigee-cli-test-role'; var verbose = false; var deployedRevision; var deployedUri; @@ -1304,6 +1305,156 @@ describe('SharedFlows and FlowHooks', function() { // it }); }); // end shared flow tests +describe('User Roles and Permissions', function() { // it + this.timeout(REASONABLE_TIMEOUT); + + it('Create Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + + apigeetool.createRole(opts, function (err, result) { + if (verbose) { + console.log('Create Role result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Get Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + + apigeetool.getRole(opts, function (err, result) { + if (verbose) { + console.log('Get Role result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('List Roles', function (done) { + var opts = baseOpts(); + + apigeetool.listRoles(opts, function (err, result) { + if (verbose) { + console.log('List Roles result = %j', result); + } + if (err) { done(err); } else { + assert.equal( result.includes(ROLE_NAME), true ); + done(); + } + }); + }); + + it('Set Role Permissions', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + opts.permissions = '[{"path":"/userroles","permissions":["get"]}]'; + + apigeetool.setRolePermissions(opts, function (err, result) { + if (verbose) { + console.log('Set Role Permissions result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Get Role Permissions', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + + apigeetool.getRolePermissions(opts, function (err, result) { + if (verbose) { + console.log('Get Role Permissions result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Assign User to Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + opts.email = config.useremail; + + apigeetool.assignUserRole(opts, function (err, result) { + if (verbose) { + console.log('Assign User to Role result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Verify User in Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + opts.email = config.useremail; + + apigeetool.verifyUserRole(opts, function (err, result) { + if (verbose) { + console.log('Verify User in Role result = %j', result); + } + if (err) { done(err); } else { + assert.equal( result.emailId, opts.email); + done(); + } + }); + }); + + it('List Users in a Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + opts.email = config.useremail; + + apigeetool.listRoleUsers(opts, function (err, result) { + if (verbose) { + console.log('List Users in a Role result = %j', result); + } + if (err) { done(err); } else { + assert.equal( result.includes(opts.email), true); + done(); + } + }); + }); + + it('Verify access allowed', function (done) { + var opts = baseOpts(); + opts.netrc = false; + opts.username = config.useremail; + opts.password = config.userpassword; + apigeetool.listRoles(opts, function (err, result) { + if (verbose) { + console.log('Verify access allowed for user %s result = %j', config.useremail, result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Remove User from Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + opts.email = config.useremail; + + apigeetool.removeUserRole(opts, function (err, result) { + if (verbose) { + console.log('Remove User from Role result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); + + it('Delete Role', function (done) { + var opts = baseOpts(); + opts.roleName = ROLE_NAME; + + apigeetool.deleteRole(opts, function (err, result) { + if (verbose) { + console.log('Delete Role result = %j', result); + } + if (err) { done(err); } else { done(); } + }); + }); +}); // End User Roles and Permissions + function baseOpts() { var o = { organization: config.organization, From 473fa73269a0c4a60de43e061506d37938f860bd Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Wed, 25 Sep 2019 07:49:03 -0400 Subject: [PATCH 11/19] Updated version to 0.13 and devDependency for Jasmine --- package-lock.json | 34 +++++++++++++++++++++++++++++++++- package.json | 3 ++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4ddd3ea..29aa493 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "apigeetool", - "version": "0.12.0", + "version": "0.13.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -616,6 +616,38 @@ "resolved": "http://repo.nwie.net/nexus/repository/npm/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "jasmine": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.5.0.tgz", + "integrity": "sha512-DYypSryORqzsGoMazemIHUfMkXM7I7easFaxAvNM3Mr6Xz3Fy36TupTrAOxZWN8MVKEU5xECv22J4tUQf3uBzQ==", + "dev": true, + "requires": { + "glob": "^7.1.4", + "jasmine-core": "~3.5.0" + }, + "dependencies": { + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "jasmine-core": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.5.0.tgz", + "integrity": "sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==", + "dev": true + }, "jsbn": { "version": "0.1.1", "resolved": "http://repo.nwie.net/nexus/repository/npm/jsbn/-/jsbn-0.1.1.tgz", diff --git a/package.json b/package.json index 0ea331e..32438b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "apigeetool", - "version": "0.12.0", + "version": "0.13.0", "description": "A CLI for Apigee Edge", "main": "lib/main.js", "bin": { @@ -38,6 +38,7 @@ "devDependencies": { "connect": "^3.4.0", "express": "^4.13.3", + "jasmine": "^3.5.0", "mocha": "^5.2.0" }, "repository": { From ace2d5a5d915ede1ac316fb3a846ea9257d6fdd9 Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Wed, 25 Sep 2019 10:18:54 -0400 Subject: [PATCH 12/19] npm audit fix --- package-lock.json | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 29aa493..374be77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -487,9 +487,9 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fstream": { - "version": "1.0.11", - "resolved": "http://repo.nwie.net/nexus/repository/npm/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", "requires": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", @@ -509,6 +509,7 @@ "version": "7.1.2", "resolved": "http://repo.nwie.net/nexus/repository/npm/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1063,11 +1064,26 @@ } }, "rimraf": { - "version": "2.6.2", - "resolved": "http://repo.nwie.net/nexus/repository/npm/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "safe-buffer": { From fc75c94eca23e3d1edd3223812b5eb324abaa47f Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Fri, 11 Oct 2019 13:46:02 -0400 Subject: [PATCH 13/19] Adding --json option back --- README.md | 3 +++ lib/cli.js | 8 +++++--- lib/defaults.js | 5 +++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0cd0371..d36cb56 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,9 @@ trusted TLS certificate. (optional) Limit for the maximum number of operations performed concurrently. Currently this only affects file uploads in the `deploynodeapp` command. Defaults to 4. +`--json -j` +(optional) Formats the command's response as a JSON object. + `--organization -o` (required) The name of the organization to deploy to. May be set as an environment variable APIGEE_ORGANIZATION. diff --git a/lib/cli.js b/lib/cli.js index 888d756..c86675b 100755 --- a/lib/cli.js +++ b/lib/cli.js @@ -65,9 +65,11 @@ function runCommand() { process.exit(6); } - console.log(JSON.stringify(result)); - // Raw - // console.log(result); + if (!opts.json && commandModule.format) { + console.log(commandModule.format(result)); + } else { + console.log(JSON.stringify(result)); + } process.exit(0); }); diff --git a/lib/defaults.js b/lib/defaults.js index 254c180..1ed0ec2 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -77,6 +77,11 @@ var DefaultDescriptor = { scope: 'default', toggle: true }, + json: { + name: 'JSON', + shortOption: 'j', + toggle: true + }, cafile: { name: 'CA file', shortOption: 'c', From 9587b5b23ae53e1c3549eaeea96467dc21009eb8 Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Tue, 22 Oct 2019 13:26:14 -0400 Subject: [PATCH 14/19] Fix issue #173 regression --- lib/defaults.js | 7 ++++--- lib/options.js | 38 +++++++++++++++++--------------------- package-lock.json | 2 +- package.json | 2 +- test/testoptions.js | 13 ------------- 5 files changed, 23 insertions(+), 39 deletions(-) diff --git a/lib/defaults.js b/lib/defaults.js index 1ed0ec2..c5fb69a 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -18,14 +18,14 @@ var DefaultDescriptor = { toggle: true }, username: { - name: 'Username', + name: 'Username or -t or -N', shortOption: 'u', scope: 'default', required: true, prompt: true }, password: { - name: 'Password', + name: 'Password or -t or -N', shortOption: 'p', scope: 'default', required: true, @@ -58,7 +58,8 @@ var DefaultDescriptor = { name: 'Organization', shortOption: 'o', scope: 'default', - required: true + required: true, + prompt: true }, baseuri: { name: 'Base URI', diff --git a/lib/options.js b/lib/options.js index 8dc0da4..d199a2e 100644 --- a/lib/options.js +++ b/lib/options.js @@ -125,33 +125,29 @@ module.exports.validate = function(opts, descriptor, cb) { function checkProperty(opts, descriptor, propName, done) { var desc = descriptor[propName]; - // console.log( "DEBUG " + desc.required + " " + opts[propName] + " " + opts.prompt + " " + desc.prompt + " " + propName); - // console.log( "DEBUG OPTs" + JSON.stringify(opts) ); + // console.log( "DEBUG COND " + propName + " " + desc.required + " " + !opts[propName] + " " + !opts.prompt + " " + desc.prompt); + // console.log( "DEBUG OPTs" + JSON.stringify(opts) + "\n"); if (desc === null || desc === undefined) { done(new Error(util.format('Invalid property %s', propName))); return; } - if (desc.required && !opts[propName]) { - if (desc.prompt && !opts.prompt ) { - if (opts.interactive) { - var pn = (desc.name ? desc.name : propName); - prompt(pn, desc.secure, function(err, val) { - if (err) { - done(err); + if (desc.required && !opts[propName] && (!opts.prompt && desc.prompt)) { + if (opts.interactive) { + var pn = (desc.name ? desc.name : propName); + prompt(pn, desc.secure, function(err, val) { + if (err) { + done(err); + } else { + if (desc.secure === true) { + opts[propName] = new SecureValue(val); } else { - if (desc.secure === true) { - opts[propName] = new SecureValue(val); - } else { - opts[propName] = val; - } - done(); + opts[propName] = val; } - }); - } else { - done(new Error(util.format('Missing required option "%s"', propName))); - } + done(); + } + }); } else { - done(new Error(util.format('Missing required option with no prompt "%s"', propName))); + done(new Error(util.format('Missing required option "%s"', propName))); } } else { if (opts[propName] && (desc.secure === true)) { @@ -217,7 +213,7 @@ module.exports.getHelp = function(descriptor) { tab.push([ d[0], (d[1].shortOption ? '-' + d[1].shortOption : ''), - ((d[1].required && !d[1].prompt) ? '(required)': '(optional)'), + ((d[1].required) ? '(required)': '(optional)'), ((d[1].name ? d[1].name : 'undefined')), ((d[1].scope == 'default') ? '' : '(command specific)') ]); diff --git a/package-lock.json b/package-lock.json index 374be77..63952e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "apigeetool", - "version": "0.13.0", + "version": "0.14.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 299436f..65dfedf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "apigeetool", - "version": "0.14.1", + "version": "0.14.2", "description": "A CLI for Apigee Edge", "main": "lib/main.js", "bin": { diff --git a/test/testoptions.js b/test/testoptions.js index 6ce2a13..62b7671 100644 --- a/test/testoptions.js +++ b/test/testoptions.js @@ -52,19 +52,6 @@ describe('Options parsing test', function() { }); }); - it('Test missing option prompt false', function(done) { - var desc = { - foo: {}, - ping: { required: false, prompt: false }, - pong: { required: true, prompt: false } - }; - var opts = { foo: 1, ping: 1}; - options.validate(opts, desc, function(err) { - assert(err); - assert(/Missing required option/.test(err.message)); - done(); - }); - }); it('Test nothing and missing stuff', function(done) { var desc = { foo: {}, From 34918b7b842105b1965216c7fea06df54ffcd014 Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Wed, 23 Oct 2019 10:16:53 -0400 Subject: [PATCH 15/19] Adjusted help output for -t and -N overrides --- lib/defaults.js | 9 +++++---- lib/options.js | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/defaults.js b/lib/defaults.js index c5fb69a..7d74f76 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -18,14 +18,14 @@ var DefaultDescriptor = { toggle: true }, username: { - name: 'Username or -t or -N', + name: 'Username', shortOption: 'u', scope: 'default', required: true, prompt: true }, password: { - name: 'Password or -t or -N', + name: 'Password', shortOption: 'p', scope: 'default', required: true, @@ -48,7 +48,7 @@ var DefaultDescriptor = { prompt: false }, netrc: { - name: 'netrc', + name: 'Netrc', shortOption: 'N', scope: 'default', required: false, @@ -81,6 +81,7 @@ var DefaultDescriptor = { json: { name: 'JSON', shortOption: 'j', + scope: 'default', toggle: true }, cafile: { @@ -99,7 +100,7 @@ var DefaultDescriptor = { scope: 'default' }, insecure: { - name: 'insecure', + name: 'Insecure', shortOption: 'k', scope: 'default', toggle: true diff --git a/lib/options.js b/lib/options.js index d199a2e..095e4b6 100644 --- a/lib/options.js +++ b/lib/options.js @@ -215,7 +215,7 @@ module.exports.getHelp = function(descriptor) { (d[1].shortOption ? '-' + d[1].shortOption : ''), ((d[1].required) ? '(required)': '(optional)'), ((d[1].name ? d[1].name : 'undefined')), - ((d[1].scope == 'default') ? '' : '(command specific)') + ((d[1].scope == 'default') ? ((d[1].shortOption == 't' || d[1].shortOption == 'N') ? '(overrides -p/-u)' : '') : '(command specific)') ]); }); From 4f4f7b337b38360d08fb9da1034a572f300e0547 Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Wed, 23 Oct 2019 12:43:48 -0400 Subject: [PATCH 16/19] Removed out-of-scope changes --- lib/defaults.js | 8 +++----- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/defaults.js b/lib/defaults.js index 7d74f76..1ed0ec2 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -48,7 +48,7 @@ var DefaultDescriptor = { prompt: false }, netrc: { - name: 'Netrc', + name: 'netrc', shortOption: 'N', scope: 'default', required: false, @@ -58,8 +58,7 @@ var DefaultDescriptor = { name: 'Organization', shortOption: 'o', scope: 'default', - required: true, - prompt: true + required: true }, baseuri: { name: 'Base URI', @@ -81,7 +80,6 @@ var DefaultDescriptor = { json: { name: 'JSON', shortOption: 'j', - scope: 'default', toggle: true }, cafile: { @@ -100,7 +98,7 @@ var DefaultDescriptor = { scope: 'default' }, insecure: { - name: 'Insecure', + name: 'insecure', shortOption: 'k', scope: 'default', toggle: true diff --git a/package-lock.json b/package-lock.json index 63952e4..c62a2ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "apigeetool", - "version": "0.14.2", + "version": "0.14.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 65dfedf..299436f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "apigeetool", - "version": "0.14.2", + "version": "0.14.1", "description": "A CLI for Apigee Edge", "main": "lib/main.js", "bin": { From 06d71085f690977a39e372adcb6e0e8fa929946c Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Thu, 23 Apr 2020 08:08:58 -0400 Subject: [PATCH 17/19] Parameterized Deployment Delay, default=0 --- lib/commands/deployExistingRevision.js | 17 +++++++++++++---- lib/commands/deployhostedtarget.js | 6 ++++++ lib/commands/deployproxy.js | 20 +++++++++++++++----- lib/commands/deploysharedflow.js | 20 +++++++++++++++----- lib/deploycommon.js | 12 ++++++++---- package-lock.json | 2 +- 6 files changed, 58 insertions(+), 19 deletions(-) diff --git a/lib/commands/deployExistingRevision.js b/lib/commands/deployExistingRevision.js index e8806db..9f22eb8 100644 --- a/lib/commands/deployExistingRevision.js +++ b/lib/commands/deployExistingRevision.js @@ -9,7 +9,7 @@ var defaults = require('../defaults'); var options = require('../options'); var parseDeployments = require('./parsedeployments'); -var DeploymentDelay = 60; +var DefaultDeploymentDelay = 0; var descriptor = defaults.defaultDescriptor({ api: { name: 'API Name', @@ -28,6 +28,12 @@ var descriptor = defaults.defaultDescriptor({ shortOption: 'r', required: true, prompt: true + }, + deploymentDelay: { + name: 'DeploymentDelay (default=' + DefaultDeploymentDelay + ")", + shortOption: 'z', + required: false, + prompt: true } }); module.exports.descriptor = descriptor; @@ -74,9 +80,12 @@ module.exports.run = function(opts, cb) { } function deployProxy(opts, request, done) { + if( !opts.deploymentDelay ) { + opts.deploymentDelay = DefaultDeploymentDelay; + } if (opts.verbose) { - console.log('Deploying revision %d of %s to %s', opts.revision, - opts.api, opts.environments); + console.log('Deploying revision %d of %s to %s, delaying %s', + opts.revision, opts.api, opts.environments, opts.deploymentDelay); } var environments = opts.environments.split(','); @@ -87,7 +96,7 @@ function deployProxy(opts, request, done) { opts.baseuri, opts.organization, environment, opts.api, opts.revision); if (opts.debug) { console.log('Going to POST to %s', uri); } - var deployCmd = util.format('action=deploy&override=true&delay=%d', DeploymentDelay); + var deployCmd = util.format('action=deploy&override=true&delay=%d', opts.deploymentDelay); if (opts['base-path']) { deployCmd = util.format('%s&basepath=%s', deployCmd, opts['base-path']); } diff --git a/lib/commands/deployhostedtarget.js b/lib/commands/deployhostedtarget.js index 97a7ce7..faae05f 100644 --- a/lib/commands/deployhostedtarget.js +++ b/lib/commands/deployhostedtarget.js @@ -69,6 +69,12 @@ var descriptor = defaults.defaultDescriptor({ name: 'Upload Modules', shortOption: 'U', toggle: true + }, + deploymentDelay: { + name: 'DeploymentDelay (default=0)', + shortOption: 'z', + required: false, + prompt: true } }); module.exports.descriptor = descriptor; diff --git a/lib/commands/deployproxy.js b/lib/commands/deployproxy.js index d0d124c..d9e9e6d 100644 --- a/lib/commands/deployproxy.js +++ b/lib/commands/deployproxy.js @@ -20,7 +20,7 @@ var cleanResults = require('../utils').cleanResults; var ProxyBase = 'apiproxy'; var XmlExp = /(.+)\.xml$/i; -var DeploymentDelay = 60; +var DefaultDeploymentDelay = 0; var BASE_PATH_REGEXP = /]*>(.*?)<\/BasePath>/; // By default, do not run NPM remotely @@ -71,7 +71,13 @@ var descriptor = defaults.defaultDescriptor({ name: 'Wait N seconds after importing proxy before deploying', shortOption: 'W', required: false - } + }, + deploymentDelay: { + name: 'DeploymentDelay (default=' + DefaultDeploymentDelay + ")", + shortOption: 'z', + required: false, + prompt: true + } }); module.exports.descriptor = descriptor; @@ -693,9 +699,13 @@ function deployProxy(opts, request, done) { return; } + if( !opts.deploymentDelay ) { + opts.deploymentDelay = DefaultDeploymentDelay; + } + if (opts.verbose) { - console.log('Deploying revision %d of %s to %s', opts.deploymentVersion, - opts.api, opts.environments); + console.log('Deploying revision %d of %s to %s, delaying %s', + opts.deploymentVersion, opts.api, opts.environments, opts.deploymentDelay); } var environments = opts.environments.split(','); @@ -706,7 +716,7 @@ function deployProxy(opts, request, done) { opts.baseuri, opts.organization, environment, opts.api, opts.deploymentVersion); if (opts.debug) { console.log('Going to POST to %s', uri); } - var deployCmd = util.format('action=deploy&override=true&delay=%d', DeploymentDelay); + var deployCmd = util.format('action=deploy&override=true&delay=%d', opts.deploymentDelay); if (opts['base-path']) { deployCmd = util.format('%s&basepath=%s', deployCmd, opts['base-path']); } diff --git a/lib/commands/deploysharedflow.js b/lib/commands/deploysharedflow.js index 4b32b89..f2c5242 100644 --- a/lib/commands/deploysharedflow.js +++ b/lib/commands/deploysharedflow.js @@ -17,7 +17,7 @@ var parseDeployments = require('./parsedeployments'); var SharedFlowBase = 'sharedflowbundle'; var XmlExp = /(.+)\.xml$/i; -var DeploymentDelay = 60; +var DefaultDeploymentDelay = 0; var descriptor = defaults.defaultDescriptor({ name: { @@ -39,7 +39,13 @@ var descriptor = defaults.defaultDescriptor({ name: 'Import Only', shortOption: 'i', toggle: true - } + }, + deploymentDelay: { + name: 'DeploymentDelay (default=' + DefaultDeploymentDelay + ")", + shortOption: 'z', + required: false, + prompt: true + } }); module.exports.descriptor = descriptor; @@ -434,9 +440,13 @@ function deploySharedFlow(opts, request, done) { return; } + if( !opts.deploymentDelay ) { + opts.deploymentDelay = DefaultDeploymentDelay; + } + if (opts.verbose) { - console.log('Deploying revision %d of %s to %s', opts.deploymentVersion, - opts.name, opts.environments); + console.log('Deploying revision %d of %s to %s, delaying %s', + opts.deploymentVersion, opts.name, opts.environments, opts.deploymentDelay); } var environments = opts.environments.split(','); @@ -449,7 +459,7 @@ function deploySharedFlow(opts, request, done) { console.log('Going to POST to %s', uri); } - var deployCmd = util.format('action=deploy&override=true&delay=%d', DeploymentDelay); + var deployCmd = util.format('action=deploy&override=true&delay=%d', opts.deploymentDelay); if (opts['base-path']) { deployCmd = util.format('%s&basepath=%s', deployCmd, opts['base-path']); } diff --git a/lib/deploycommon.js b/lib/deploycommon.js index a500a94..8b9c316 100644 --- a/lib/deploycommon.js +++ b/lib/deploycommon.js @@ -16,7 +16,7 @@ tmp.setGracefulCleanup(); var ziputils = require('./ziputils'); -var DeploymentDelay = 60 +var DefaultDeploymentDelay = 0; var ProxyBase = 'apiproxy'; module.exports.createApiProxy = function(opts, request, done) { @@ -104,9 +104,13 @@ module.exports.deployProxy = function(opts, request, done) { return; } + if( !opts.deploymentDelay ) { + opts.deploymentDelay = DefaultDeploymentDelay; + } + if (opts.verbose) { - console.log('Deploying revision %d of %s to %s', opts.deploymentVersion, - opts.api, opts.environments); + console.log('Deploying revision %d of %s to %s, delaying %s', + opts.deploymentVersion, opts.api, opts.environments, opts.deploymentDelay); } var environments = opts.environments.split(','); @@ -120,7 +124,7 @@ module.exports.deployProxy = function(opts, request, done) { if (opts.debug) { console.log('Going to POST to %s', uri); } // Unlike "deployproxy" command, ignore the base path here, because we baked it into the proxy definition. - var deployCmd = util.format('action=deploy&override=true&delay=%d', DeploymentDelay); + var deployCmd = util.format('action=deploy&override=true&delay=%d', opts.deploymentDelay); if (opts.debug) { console.log('Going go send command %s', deployCmd); } diff --git a/package-lock.json b/package-lock.json index c62a2ca..63952e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "apigeetool", - "version": "0.14.1", + "version": "0.14.2", "lockfileVersion": 1, "requires": true, "dependencies": { From b870d40318e3689cf75372ad25e2caf5b6cabf09 Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Wed, 13 May 2020 09:16:55 -0400 Subject: [PATCH 18/19] Updated to version 0.14.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 65dfedf..604c1e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "apigeetool", - "version": "0.14.2", + "version": "0.14.3", "description": "A CLI for Apigee Edge", "main": "lib/main.js", "bin": { From 84eb9bd5dda9844d1a66f8abc7be9bea7c044849 Mon Sep 17 00:00:00 2001 From: Kurt Googler Kanaskie Date: Wed, 13 May 2020 16:49:11 -0400 Subject: [PATCH 19/19] Restored default to 60, changed option to -Z, --zeroDowntimeDelay --- lib/commands/deployhostedtarget.js | 6 +++--- lib/commands/deployproxy.js | 26 +++++++++++++------------- lib/commands/deploysharedflow.js | 24 ++++++++++++------------ lib/deploycommon.js | 12 ++++++------ 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/lib/commands/deployhostedtarget.js b/lib/commands/deployhostedtarget.js index faae05f..4fa66be 100644 --- a/lib/commands/deployhostedtarget.js +++ b/lib/commands/deployhostedtarget.js @@ -70,9 +70,9 @@ var descriptor = defaults.defaultDescriptor({ shortOption: 'U', toggle: true }, - deploymentDelay: { - name: 'DeploymentDelay (default=0)', - shortOption: 'z', + zeroDowntimeDelay: { + name: 'Delay N seconds for zero downtime deployment (default=60)', + shortOption: 'Z', required: false, prompt: true } diff --git a/lib/commands/deployproxy.js b/lib/commands/deployproxy.js index d9e9e6d..77222c9 100644 --- a/lib/commands/deployproxy.js +++ b/lib/commands/deployproxy.js @@ -20,7 +20,7 @@ var cleanResults = require('../utils').cleanResults; var ProxyBase = 'apiproxy'; var XmlExp = /(.+)\.xml$/i; -var DefaultDeploymentDelay = 0; +var DefaultZeroDowntimeDelay = 60; var BASE_PATH_REGEXP = /]*>(.*?)<\/BasePath>/; // By default, do not run NPM remotely @@ -72,12 +72,12 @@ var descriptor = defaults.defaultDescriptor({ shortOption: 'W', required: false }, - deploymentDelay: { - name: 'DeploymentDelay (default=' + DefaultDeploymentDelay + ")", - shortOption: 'z', - required: false, - prompt: true - } + zeroDowntimeDelay: { + name: 'Delay N seconds for zero downtime deployment (default=' + DefaultZeroDowntimeDelay + ")", + shortOption: 'Z', + required: false, + prompt: true + } }); module.exports.descriptor = descriptor; @@ -699,13 +699,13 @@ function deployProxy(opts, request, done) { return; } - if( !opts.deploymentDelay ) { - opts.deploymentDelay = DefaultDeploymentDelay; + if( !opts.zeroDowntimeDelay ) { + opts.zeroDowntimeDelay = DefaultZeroDowntimeDelay; } if (opts.verbose) { - console.log('Deploying revision %d of %s to %s, delaying %s', - opts.deploymentVersion, opts.api, opts.environments, opts.deploymentDelay); + console.log('Deploying revision %d of %s to %s, delaying %s seconds for zero downtime deployment.', + opts.deploymentVersion, opts.api, opts.environments, opts.zeroDowntimeDelay); } var environments = opts.environments.split(','); @@ -716,7 +716,7 @@ function deployProxy(opts, request, done) { opts.baseuri, opts.organization, environment, opts.api, opts.deploymentVersion); if (opts.debug) { console.log('Going to POST to %s', uri); } - var deployCmd = util.format('action=deploy&override=true&delay=%d', opts.deploymentDelay); + var deployCmd = util.format('action=deploy&override=true&delay=%d', opts.zeroDowntimeDelay); if (opts['base-path']) { deployCmd = util.format('%s&basepath=%s', deployCmd, opts['base-path']); } @@ -763,7 +763,7 @@ function deployProxy(opts, request, done) { tasks[env] = deployToEnvironment.bind(this, env); }); - if (opts.verbose) { console.log('Delaying deployment for %d seconds', opts.waitAfterImportDelay); } + if (opts.verbose) { console.log('Waiting %d seconds after import to deploy', opts.waitAfterImportDelay); } setTimeout(function () { async.parallel(tasks, done); }, opts.waitAfterImportDelay*1000); diff --git a/lib/commands/deploysharedflow.js b/lib/commands/deploysharedflow.js index f2c5242..a86667a 100644 --- a/lib/commands/deploysharedflow.js +++ b/lib/commands/deploysharedflow.js @@ -17,7 +17,7 @@ var parseDeployments = require('./parsedeployments'); var SharedFlowBase = 'sharedflowbundle'; var XmlExp = /(.+)\.xml$/i; -var DefaultDeploymentDelay = 0; +var DefaultZeroDowntimeDelay = 60; var descriptor = defaults.defaultDescriptor({ name: { @@ -40,12 +40,12 @@ var descriptor = defaults.defaultDescriptor({ shortOption: 'i', toggle: true }, - deploymentDelay: { - name: 'DeploymentDelay (default=' + DefaultDeploymentDelay + ")", - shortOption: 'z', - required: false, - prompt: true - } + zeroDowntimeDelay: { + name: 'Delay N seconds for zero downtime deployment (default=' + DefaultZeroDowntimeDelay + ")", + shortOption: 'Z', + required: false, + prompt: true + } }); module.exports.descriptor = descriptor; @@ -440,13 +440,13 @@ function deploySharedFlow(opts, request, done) { return; } - if( !opts.deploymentDelay ) { - opts.deploymentDelay = DefaultDeploymentDelay; + if( !opts.zeroDowntimeDelay ) { + opts.zeroDowntimeDelay = DefaultZeroDowntimeDelay; } if (opts.verbose) { - console.log('Deploying revision %d of %s to %s, delaying %s', - opts.deploymentVersion, opts.name, opts.environments, opts.deploymentDelay); + console.log('Deploying revision %d of %s to %s, delaying %s seconds for zero downtime deployment.', + opts.deploymentVersion, opts.name, opts.environments, opts.zeroDowntimeDelay); } var environments = opts.environments.split(','); @@ -459,7 +459,7 @@ function deploySharedFlow(opts, request, done) { console.log('Going to POST to %s', uri); } - var deployCmd = util.format('action=deploy&override=true&delay=%d', opts.deploymentDelay); + var deployCmd = util.format('action=deploy&override=true&delay=%d', opts.zeroDowntimeDelay); if (opts['base-path']) { deployCmd = util.format('%s&basepath=%s', deployCmd, opts['base-path']); } diff --git a/lib/deploycommon.js b/lib/deploycommon.js index 8b9c316..680c5e3 100644 --- a/lib/deploycommon.js +++ b/lib/deploycommon.js @@ -16,7 +16,7 @@ tmp.setGracefulCleanup(); var ziputils = require('./ziputils'); -var DefaultDeploymentDelay = 0; +var DefaultZeroDowntimeDelay = 60; var ProxyBase = 'apiproxy'; module.exports.createApiProxy = function(opts, request, done) { @@ -104,13 +104,13 @@ module.exports.deployProxy = function(opts, request, done) { return; } - if( !opts.deploymentDelay ) { - opts.deploymentDelay = DefaultDeploymentDelay; + if( !opts.zeroDowntimeDelay ) { + opts.zeroDowntimeDelay = DefaultZeroDowntimeDelay; } if (opts.verbose) { - console.log('Deploying revision %d of %s to %s, delaying %s', - opts.deploymentVersion, opts.api, opts.environments, opts.deploymentDelay); + console.log('Deploying revision %d of %s to %s, delaying %s seconds for zero downtime deployment.', + opts.deploymentVersion, opts.api, opts.environments, opts.zeroDowntimeDelay); } var environments = opts.environments.split(','); @@ -124,7 +124,7 @@ module.exports.deployProxy = function(opts, request, done) { if (opts.debug) { console.log('Going to POST to %s', uri); } // Unlike "deployproxy" command, ignore the base path here, because we baked it into the proxy definition. - var deployCmd = util.format('action=deploy&override=true&delay=%d', opts.deploymentDelay); + var deployCmd = util.format('action=deploy&override=true&delay=%d', opts.zeroDowntimeDelay); if (opts.debug) { console.log('Going go send command %s', deployCmd); }