diff --git a/.meteor/versions b/.meteor/versions index 4d9d359526..a4f8a8f7e1 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -22,7 +22,6 @@ boilerplate-generator@1.0.3 bootstrap@0.3.1 bruz:github-api@0.2.4_1 brylie:api-umbrella@0.2.4 -brylie:api-umbrella@0.2.3 callback-hook@1.0.3 cfs:access-point@0.1.49 cfs:base-package@0.0.30 diff --git a/client/subscriptions.js b/client/subscriptions.js index 1a590361e9..64fbd2fe34 100644 --- a/client/subscriptions.js +++ b/client/subscriptions.js @@ -1 +1,2 @@ Meteor.subscribe('apiUmbrellaUsers'); +Meteor.subscribe('apiBackends'); diff --git a/client/views/api_backends/api_backends.html b/client/views/api_backends/api_backends.html new file mode 100644 index 0000000000..4012998a4a --- /dev/null +++ b/client/views/api_backends/api_backends.html @@ -0,0 +1,42 @@ + diff --git a/collections/backend.js b/collections/backend.js new file mode 100644 index 0000000000..490edc517e --- /dev/null +++ b/collections/backend.js @@ -0,0 +1,269 @@ +ApiBackends = new Mongo.Collection('apiBackends'); + +ApiBackendsSchema = new SimpleSchema({ + id: { + type: String, + optional: true +}, + name: { + type: String, + optional: true + }, + sort_order: { + type: Number, + optional: true + }, + backend_protocol: { + type: String, + optional: true, + allowedValues: [ + 'http', + 'https' + ], + label: 'Backend protocol' + }, + backend_host: { + type: String, + optional: true + }, + backend_port: { + type: Number, + optional: true + }, + frontend_host: { + type: String, + optional: true + }, + balance_algorithm: { + type: String, + optional: true + }, + server: { + type: [Object], + optional: true, + label: 'Host' + }, + "server.$.backend_host": { + type: String, + optional: true + }, + "server.$.backend_port": { + type: String, + optional: true, + regEx: /^[0-9]{2,5}$/ + }, + matching: { + type: [Object], + optional: true, + }, + "matching.$.frontend_prefix": { + label: 'Frontend Prefix', + optional: true, + type: String + }, + "matching.$.backend_prefix": { + label: 'Backend Prefix', + optional: true, + type: String, + regEx: /^[a-z0-9A-Z_]{3,15}$/ + }, + duration: { + type: Number, + optional: true, + label: 'Duration' + }, + accuracy:{ + type: Number, + optional: true + }, + limit_by: { + type: String, + optional: true + }, + limit: { + type: Number, + optional: true + }, + distributed: { + type: Boolean, + optional: true + }, + response_headers: { + type: Boolean, + optional: true + }, + matcher_type: { + type: String, + optional: true + }, + http_method: { + type: String, + optional: true + }, + frontend_matcher: { + type: String, + optional: true + }, + backend_replacement: { + type: String, + optional: true + }, + matcher: { + type: String, + optional: true + }, + http_method: { + type: String, + optional: true + }, + from: { + type: String, + optional: true + }, + to: { + type: String, + optional: true + }, + set_headers: { + type: String, + optional: true, + min: 20, + max: 1000, + autoform: { + rows: 2 + }, + label: 'Set Headers' + }, + append_query_string: { + type: String, + optional: true, + label: 'Append Query String Parameters' + }, + http_basic_auth: { + type: String, + optional: true, + label: 'HTTP Basic Authentication' + }, + require_https: { + type: String, + optional: true, + allowedValues: [ + 'Inherit (default - optional)', + 'Optional - HTTPS is optional', + 'Required - HTTPS is mandatory' + ], + label: 'HTTPS Requirements' + }, + require_https_transition_start_at: { + type: Date, + optional: true + }, + disable_api_key: { + type: Boolean, + optional: true + }, + api_key_verification_level: { + type: String, + optional: true, + allowedValues: [ + 'Inherit (default - required)', + 'Required - API keys are mandatory', + 'Disabled - API keys are optional' + ], + label: 'API Key Checks' + }, + api_key_verification_transition_start_at: { + type: Date, + optional: true + }, + required_roles: { + type: Array, + minCount: 1, + maxCount: 3, + optional: true, + label: 'Required Roles', + autoform: { + options: [ + { + label: 'api-umbrella-contact-form', + value: 'api-umbrella-contact-form' + }, + { + label: 'api-umbrella-key-creator', + value: 'api-umbrella-key-creator' + }, + { + label: 'write_access', + value: 'write_access' + } + ] + } + }, + "required_roles.$": { + type: String, + optional: true + }, + rate_limit_mode: { + type: String, + optional: true, + allowedValues: [ + 'Default rate limits', + 'Custom rate limits', + 'Unlimited requests' + ], + label: 'Rate limit' + }, + anonymous_rate_limit_behavior: { + type: String, + optional: true + }, + authenticated_rate_limit_behavior: { + type: String, + optional: true + }, + pass_api_key_header: { + type: Boolean, + optional: true, + defaultValue: false, + label: 'Via HTTP header' + }, + pass_api_key_query_param: { + type: Boolean, + optional: true, + defaultValue: false, + label: 'Via GET query parameter' + }, + error_templates: { +// type: [Object] + type: String, + optional: true + }, + error_data: { +// type: [Object] + type: String, + optional: true + }, + created_at: { + type: Date, + optional: true + }, + created_by: { + type: String, + optional: true + }, + updated_at: { + type: Date, + optional: true + }, + updated_by: { + type: String, + optional: true + }, + version: { + type: Number, + optional: true + } +}); + +ApiBackends.attachSchema(ApiBackendsSchema); + diff --git a/lib/_config/adminConfig.coffee b/lib/_config/adminConfig.coffee index 9fdb782095..40d618ac51 100644 --- a/lib/_config/adminConfig.coffee +++ b/lib/_config/adminConfig.coffee @@ -19,6 +19,14 @@ {label: 'Last Name',name:'last_name'} ] } + ApiBackends: { + color: 'blue' + icon: 'gear' + tableColumns: [ + {label: 'Name', name: 'name'} + {label: 'Backend Host', name: 'backend_host'} + ] + } ApiUmbrellaAdmins: { color: 'blue' icon: 'user-md' @@ -32,9 +40,9 @@ icon: 'comments' auxCollections: ['Posts'] tableColumns: [ - {label: 'Content';name:'content'} - {label:'Post';name:'doc',collection: 'Posts',collection_property:'title'} - {label:'User',name:'owner',collection:'Users'} + {label: 'Content', name:'content'} + {label:'Post', name:'doc',collection: 'Posts',collection_property:'title'} + {label:'User', name:'owner',collection:'Users'} ] } dashboard: diff --git a/lib/router/main.coffee b/lib/router/main.coffee index 0fabeb41e0..78a7ccf9e4 100644 --- a/lib/router/main.coffee +++ b/lib/router/main.coffee @@ -3,6 +3,10 @@ Router.map -> path: "/" layoutTemplate: "homeLayout" + @route "apiBackends", + path: "/apibackends" + layoutTemplate: "homeLayout" + @route "dashboard", path: "/dashboard" waitOn: -> diff --git a/server/methods/apiBackends.js b/server/methods/apiBackends.js new file mode 100644 index 0000000000..0661bec116 --- /dev/null +++ b/server/methods/apiBackends.js @@ -0,0 +1,20 @@ +Meteor.methods({ + "syncApiBackends":function () { + // Check if API Umbrella settings are available + if (Meteor.settings.api_umbrella) { + // Get API Backends from API Umbrella instance + var response = apiUmbrellaWeb.adminApi.v1.apiBackends.getApiBackends(); + var apiBackends = response.data.data; + + _.each(apiBackends, function (item) { + // Get existing API Backend + var existingApiBackend = ApiBackends.findOne({'id': item.id}); + + // If API Backend doesn't exist in collection, insert into collection + if (! existingApiBackend ) { + ApiBackends.insert(item); + }; + }); + }; + } +}); diff --git a/server/publish/apiBackends.js b/server/publish/apiBackends.js new file mode 100644 index 0000000000..8b07e9975b --- /dev/null +++ b/server/publish/apiBackends.js @@ -0,0 +1,3 @@ +Meteor.publish('apiBackends', function () { + return ApiBackends.find(); +}); diff --git a/server/startup.js b/server/startup.js index 359e92c631..f4e31019c3 100644 --- a/server/startup.js +++ b/server/startup.js @@ -1,15 +1,18 @@ Meteor.startup(function () { // Check if API Umbrella settings are available SyncedCron.add({ - name: 'Sync API Umbrella Users', + name: 'Sync API Umbrella Users and API Backends', schedule: function(parser) { // parser is a later.parse object return parser.text('every 1 day'); }, job: function() { Meteor.call("syncApiUmbrellaUsers"); + Meteor.call("syncApiBackends"); } }); + Meteor.call("syncApiUmbrellaUsers"); + Meteor.call("syncApiBackends"); }); SyncedCron.start();