aboutsummaryrefslogtreecommitdiffstats
path: root/ui/imports/api
diff options
context:
space:
mode:
Diffstat (limited to 'ui/imports/api')
-rw-r--r--ui/imports/api/accounts/methods.js196
-rw-r--r--ui/imports/api/accounts/server/publications.js29
-rw-r--r--ui/imports/api/attributes_for_hover_on_data/attributes_for_hover_on_data.js12
-rw-r--r--ui/imports/api/attributes_for_hover_on_data/methods.js8
-rw-r--r--ui/imports/api/attributes_for_hover_on_data/server/publications.js25
-rw-r--r--ui/imports/api/clique-constraints/clique-constraints.js48
-rw-r--r--ui/imports/api/clique-constraints/methods.js99
-rw-r--r--ui/imports/api/clique-constraints/server/publications.js30
-rw-r--r--ui/imports/api/clique-types/clique-types.js107
-rw-r--r--ui/imports/api/clique-types/methods.js108
-rw-r--r--ui/imports/api/clique-types/server/publications.js34
-rw-r--r--ui/imports/api/cliques/cliques.js12
-rw-r--r--ui/imports/api/cliques/methods.js8
-rw-r--r--ui/imports/api/cliques/server/publications.js33
-rw-r--r--ui/imports/api/constants/constants.js22
-rw-r--r--ui/imports/api/constants/data/distributions.js64
-rw-r--r--ui/imports/api/constants/data/env-types.js15
-rw-r--r--ui/imports/api/constants/data/environment-monitoring-types.js12
-rw-r--r--ui/imports/api/constants/data/environment-provision-types.js21
-rw-r--r--ui/imports/api/constants/data/log-levels.js27
-rw-r--r--ui/imports/api/constants/data/mechanism-drivers.js24
-rw-r--r--ui/imports/api/constants/data/message-source-systems.js15
-rw-r--r--ui/imports/api/constants/data/network-plugins.js15
-rw-r--r--ui/imports/api/constants/data/object-types-for-links.js39
-rw-r--r--ui/imports/api/constants/data/scans-statuses.js30
-rw-r--r--ui/imports/api/constants/data/type-drivers.js24
-rw-r--r--ui/imports/api/constants/server/publications.js16
-rw-r--r--ui/imports/api/environments/configuration-groups/aci-configuration.js29
-rw-r--r--ui/imports/api/environments/configuration-groups/amqp-configuration.js29
-rw-r--r--ui/imports/api/environments/configuration-groups/cli-configuration.js69
-rw-r--r--ui/imports/api/environments/configuration-groups/monitoring-configuration.js119
-rw-r--r--ui/imports/api/environments/configuration-groups/mysql-configuration.js33
-rw-r--r--ui/imports/api/environments/configuration-groups/nfv-provider-configuration.js25
-rw-r--r--ui/imports/api/environments/configuration-groups/open-stack-configuration.js30
-rw-r--r--ui/imports/api/environments/environments.js457
-rw-r--r--ui/imports/api/environments/methods.js154
-rw-r--r--ui/imports/api/environments/server/publications.js102
-rw-r--r--ui/imports/api/inventories/inventories.js11
-rw-r--r--ui/imports/api/inventories/server/methods.js151
-rw-r--r--ui/imports/api/inventories/server/publications.js250
-rw-r--r--ui/imports/api/link-types/link-types.js86
-rw-r--r--ui/imports/api/link-types/methods.js114
-rw-r--r--ui/imports/api/link-types/server/publications.js46
-rw-r--r--ui/imports/api/links/links.js11
-rw-r--r--ui/imports/api/links/methods.js8
-rw-r--r--ui/imports/api/links/server/publications.js32
-rw-r--r--ui/imports/api/messages/messages.js125
-rw-r--r--ui/imports/api/messages/methods.js8
-rw-r--r--ui/imports/api/messages/server/methods.js49
-rw-r--r--ui/imports/api/messages/server/publications.js98
-rw-r--r--ui/imports/api/migrations/migrations.js20
-rw-r--r--ui/imports/api/scans/methods.js55
-rw-r--r--ui/imports/api/scans/scans.js159
-rw-r--r--ui/imports/api/scans/server/methods.js44
-rw-r--r--ui/imports/api/scans/server/publications.js82
-rw-r--r--ui/imports/api/scheduled-scans/methods.js131
-rw-r--r--ui/imports/api/scheduled-scans/scheduled-scans.js91
-rw-r--r--ui/imports/api/scheduled-scans/server/methods.js27
-rw-r--r--ui/imports/api/scheduled-scans/server/publications.js60
-rw-r--r--ui/imports/api/simple-schema.init.js13
-rw-r--r--ui/imports/api/statistics/helpers.js64
-rw-r--r--ui/imports/api/statistics/methods.js159
-rw-r--r--ui/imports/api/statistics/server/publications.js52
-rw-r--r--ui/imports/api/statistics/statistics.js14
-rw-r--r--ui/imports/api/supported_environments/methods.js8
-rw-r--r--ui/imports/api/supported_environments/server/publications.js17
-rw-r--r--ui/imports/api/supported_environments/supported_environments.js49
67 files changed, 4154 insertions, 0 deletions
diff --git a/ui/imports/api/accounts/methods.js b/ui/imports/api/accounts/methods.js
new file mode 100644
index 0000000..4e1c40a
--- /dev/null
+++ b/ui/imports/api/accounts/methods.js
@@ -0,0 +1,196 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { ValidatedMethod } from 'meteor/mdg:validated-method';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import * as R from 'ramda';
+import { Roles } from 'meteor/alanning:roles';
+import { Environments } from '/imports/api/environments/environments';
+
+let userSchema = new SimpleSchema({
+ _id: { type: String },
+ username: { type: String },
+ password: { type: String },
+ viewEnvs: { type: [ String ] },
+ editEnvs: { type: [ String ] },
+});
+
+export const insert = new ValidatedMethod({
+ name: 'accounts.insert',
+ validate: userSchema
+ .pick([
+ 'username',
+ 'password',
+ 'viewEnvs',
+ 'viewEnvs.$',
+ 'editEnvs',
+ 'editEnvs.$',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ username,
+ password,
+ viewEnvs,
+ editEnvs,
+ }) {
+ if (! Roles.userIsInRole(Meteor.userId(), 'manage-users', Roles.GLOBAL_GROUP)) {
+ throw new Meteor.Error('unauthorized for removing users');
+ }
+
+ let userId = Accounts.createUser({
+ username: username,
+ password: password
+ });
+
+ addRole(viewEnvs, 'view-env', userId);
+ addRole(editEnvs, 'edit-env', userId);
+ }
+});
+
+
+
+export const update = new ValidatedMethod({
+ name: 'accounts.update',
+ validate: userSchema
+ .pick([
+ '_id',
+ // 'password',
+ 'viewEnvs',
+ 'viewEnvs.$',
+ 'editEnvs',
+ 'editEnvs.$',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ _id,
+ //_password,
+ viewEnvs,
+ editEnvs,
+ }) {
+ console.log('accounts - methods - update - start');
+ //throw new Meteor.Error('unimplemented');
+ if (! Roles.userIsInRole(Meteor.userId(), 'manage-users', Roles.GLOBAL_GROUP)) {
+ throw new Meteor.Error('unauthorized for updating users');
+ }
+
+ /*
+ let item = Meteor.users.findOne({ _id: _id });
+ console.log('user for update: ', item);
+
+ item = R.merge(R.pick([
+ 'password',
+ ], item), {
+ password
+ });
+ */
+
+ /*
+ let item = {
+ //password
+ };
+
+ Meteor.users.update({ _id: _id }, { $set: item });
+ */
+
+ let currentViewEnvs = R.map((env) => {
+ return env.name;
+ }, Environments.find({ 'auth.view-env': { $in: [ _id ] }}).fetch());
+
+ let viewEnvsForDelete = R.difference(currentViewEnvs, viewEnvs);
+ let viewEnvsForAdd = R.difference(viewEnvs, currentViewEnvs);
+
+ removeRole(viewEnvsForDelete, 'view-env', _id);
+ addRole(viewEnvsForAdd, 'view-env', _id);
+
+ //
+
+ let currentEditEnvs = R.map((env) => {
+ return env.name;
+ }, Environments.find({ 'auth.edit-env': { $in: [ _id ] }}).fetch());
+
+ let editEnvsForDelete = R.difference(currentEditEnvs, editEnvs);
+ let editEnvsForAdd = R.difference(editEnvs, currentEditEnvs);
+
+ removeRole(editEnvsForDelete, 'edit-env', _id);
+ addRole(editEnvsForAdd, 'edit-env', _id);
+
+ console.log('accounts - methods - update - end');
+ }
+});
+
+export const remove = new ValidatedMethod({
+ name: 'accounts.remove',
+ validate: userSchema
+ .pick([
+ '_id',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ _id
+ }) {
+ if (! Roles.userIsInRole(Meteor.userId(), 'manage-users', Roles.GLOBAL_GROUP)) {
+ throw new Meteor.Error('unauthorized for removing users');
+ }
+
+ let user = Meteor.users.findOne({ _id: _id });
+ console.log('user for remove: ', user);
+
+ Meteor.users.remove({ _id: _id });
+ }
+});
+
+function removeRole(rolesForRemoval, roleName, userId) {
+ R.forEach((envName) => {
+ let env = Environments.findOne({ name: envName });
+ let auth = env.auth;
+ if (R.isNil(auth)) { auth = { }; }
+ if (R.isNil(R.path([roleName], auth))) {
+ auth = R.assoc(roleName, [], auth);
+ }
+ auth = R.assoc(roleName, R.reject(R.equals(userId), auth[roleName]), auth);
+
+ updateEnv(auth, env);
+ //let newEnv = R.merge(env, { auth: auth });
+
+ }, rolesForRemoval);
+}
+
+function addRole(rolesForAdd, roleName, userId) {
+ R.forEach((envName) => {
+ let env = Environments.findOne({ name: envName });
+ let auth = env.auth;
+ if (R.isNil(auth)) { auth = { }; }
+ if (R.isNil(R.path([roleName], auth))) {
+ auth = R.assoc(roleName, [], auth);
+ }
+ auth = R.assoc(roleName, R.append(userId, auth[roleName]), auth);
+
+ updateEnv(auth, env);
+ //let newEnv = R.merge(env, { auth: auth });
+
+ }, rolesForAdd);
+}
+
+function updateEnv(auth, env) {
+ console.log('update env. set: ' + R.toString(auth));
+ try {
+ Environments.update(env._id, {
+ $set: {
+ auth: auth,
+ configuration: env.configuration,
+ //distribution: distribution,
+ //name: name,
+ type_drivers: env.type_drivers,
+ mechanism_drivers: env.mechanism_drivers,
+ listen: env.listen,
+ enable_monitoring: env.enable_monitoring,
+ }
+ });
+ } catch(e) {
+ console.error('error in update: ' + R.toString(e));
+ throw new Meteor.Error('enviornment update error',
+ `unable to update ACL for environment - ${env.name}. Please check envrironment info. ${e.message}`);
+ }
+}
diff --git a/ui/imports/api/accounts/server/publications.js b/ui/imports/api/accounts/server/publications.js
new file mode 100644
index 0000000..47718d3
--- /dev/null
+++ b/ui/imports/api/accounts/server/publications.js
@@ -0,0 +1,29 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+//import * as R from 'ramda';
+//import { Environments } from '/imports/api/environments/environments';
+//import { Roles } from 'meteor/alanning:roles';
+
+Meteor.publish('users', function () {
+ console.log('server subscribtion to: users');
+ /*
+ let that = this;
+
+ let query = {};
+
+ if (! Roles.userIsInRole(that.userId, 'manage-users', 'default-group')) {
+ query = {
+ _id: that.userId
+ };
+ }
+ */
+
+ return Meteor.users.find({});
+});
diff --git a/ui/imports/api/attributes_for_hover_on_data/attributes_for_hover_on_data.js b/ui/imports/api/attributes_for_hover_on_data/attributes_for_hover_on_data.js
new file mode 100644
index 0000000..ec2f6cd
--- /dev/null
+++ b/ui/imports/api/attributes_for_hover_on_data/attributes_for_hover_on_data.js
@@ -0,0 +1,12 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+
+export const NodeHoverAttr = new Mongo.Collection(
+ 'attributes_for_hover_on_data', { idGeneration: 'MONGO' });
diff --git a/ui/imports/api/attributes_for_hover_on_data/methods.js b/ui/imports/api/attributes_for_hover_on_data/methods.js
new file mode 100644
index 0000000..1eda375
--- /dev/null
+++ b/ui/imports/api/attributes_for_hover_on_data/methods.js
@@ -0,0 +1,8 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/ui/imports/api/attributes_for_hover_on_data/server/publications.js b/ui/imports/api/attributes_for_hover_on_data/server/publications.js
new file mode 100644
index 0000000..bc42d58
--- /dev/null
+++ b/ui/imports/api/attributes_for_hover_on_data/server/publications.js
@@ -0,0 +1,25 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+
+import { NodeHoverAttr } from '../attributes_for_hover_on_data.js';
+
+Meteor.publish('attributes_for_hover_on_data', function () {
+ console.log('server subscribtion to: attributes_for_hover_on_data');
+ //return Inventory.find({$where: 'this.id_path.match('^/WebEX-Mirantis@Cisco/')'});
+ return NodeHoverAttr.find({});
+});
+
+Meteor.publish('attributes_for_hover_on_data?type', function (type) {
+ console.log('server subscribtion to: attributes_for_hover_on_data?type');
+ console.log('- type: ' + type);
+
+ //return Inventory.find({$where: 'this.id_path.match('^/WebEX-Mirantis@Cisco/')'});
+ return NodeHoverAttr.find({ 'type': type});
+});
diff --git a/ui/imports/api/clique-constraints/clique-constraints.js b/ui/imports/api/clique-constraints/clique-constraints.js
new file mode 100644
index 0000000..8641715
--- /dev/null
+++ b/ui/imports/api/clique-constraints/clique-constraints.js
@@ -0,0 +1,48 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import * as R from 'ramda';
+import { Constants } from '/imports/api/constants/constants';
+
+export const CliqueConstraints = new Mongo.Collection(
+ 'clique_constraints', { idGeneration: 'MONGO' });
+
+let schema = {
+ _id: { type: { _str: { type: String, regEx: SimpleSchema.RegEx.Id } } },
+
+ focal_point_type: {
+ type: String,
+ custom: function () {
+ let that = this;
+ let values = Constants.findOne({ name: 'object_types_for_links' }).data;
+
+ if (R.isNil(R.find(R.propEq('value', that.value), values))) {
+ return 'notAllowed';
+ }
+ }
+ },
+
+ constraints: {
+ type: [String],
+ minCount: 1,
+ custom: function () {
+ let that = this;
+ let objectTypes = Constants.findOne({ name: 'object_types_for_links' }).data;
+
+ let findResult = R.intersection(that.value, R.pluck('value', objectTypes));
+ if (findResult.length !== that.value.length) { return 'notAllowed'; }
+
+ return;
+ },
+ },
+};
+
+CliqueConstraints.schema = new SimpleSchema(schema);
+CliqueConstraints.attachSchema(CliqueConstraints.schema);
diff --git a/ui/imports/api/clique-constraints/methods.js b/ui/imports/api/clique-constraints/methods.js
new file mode 100644
index 0000000..c9ae997
--- /dev/null
+++ b/ui/imports/api/clique-constraints/methods.js
@@ -0,0 +1,99 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { ValidatedMethod } from 'meteor/mdg:validated-method';
+import * as R from 'ramda';
+import { Roles } from 'meteor/alanning:roles';
+
+import { CliqueConstraints } from './clique-constraints';
+
+export const insert = new ValidatedMethod({
+ name: 'clique_constraints.insert',
+ validate: CliqueConstraints.simpleSchema()
+ .pick([
+// 'environment',
+ 'focal_point_type',
+ 'constraints',
+ 'constraints.$',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ // environment,
+ focal_point_type,
+ constraints,
+ }) {
+ if (! Roles.userIsInRole(Meteor.userId(), 'manage-clique-constraints', Roles.GLOBAL_GROUP)) {
+ throw new Meteor.Error('unauthorized for inserting clique constraints');
+ }
+
+ let cliqueConstraint = CliqueConstraints.schema.clean({});
+
+ cliqueConstraint = R.merge(cliqueConstraint, {
+ // environment,
+ focal_point_type,
+ constraints,
+ });
+
+ CliqueConstraints.insert(cliqueConstraint);
+ }
+});
+
+export const remove = new ValidatedMethod({
+ name: 'clique_constraints.remove',
+ validate: CliqueConstraints.simpleSchema()
+ .pick([
+ '_id',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ _id
+ }) {
+ if (! Roles.userIsInRole(Meteor.userId(), 'manage-clique-constraints', Roles.DEFAULT_GROUP)) {
+ throw new Meteor.Error('unauthorized for removing clique constraints');
+ }
+
+ let cliqueConstraint = CliqueConstraints.findOne({ _id: _id });
+ console.log('clique constraint for remove: ', cliqueConstraint);
+
+ CliqueConstraints.remove({ _id: _id });
+ }
+});
+
+export const update = new ValidatedMethod({
+ name: 'clique_constraints.update',
+ validate: CliqueConstraints.simpleSchema()
+ .pick([
+ '_id',
+ 'focal_point_type',
+ 'constraints',
+ 'constraints.$',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ _id,
+ focal_point_type,
+ constraints,
+ }) {
+
+ if (! Roles.userIsInRole(Meteor.userId(), 'manage-clique-constraints', Roles.DEFAULT_GROUP)) {
+ throw new Meteor.Error('unauthorized for removing clique constraints');
+ }
+
+ let item = CliqueConstraints.findOne({ _id: _id });
+ console.log('clique constraints for update: ', item);
+ console.log('current user', Meteor.userId());
+
+ item = R.merge(
+ R.pick([
+ 'focal_point_type',
+ 'constraints',
+ ], item), {
+ focal_point_type,
+ constraints,
+ });
+
+ CliqueConstraints.update({ _id: _id }, { $set: item });
+ }
+});
diff --git a/ui/imports/api/clique-constraints/server/publications.js b/ui/imports/api/clique-constraints/server/publications.js
new file mode 100644
index 0000000..6e4ae1a
--- /dev/null
+++ b/ui/imports/api/clique-constraints/server/publications.js
@@ -0,0 +1,30 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+
+import { CliqueConstraints } from '../clique-constraints.js';
+
+Meteor.publish('clique_constraints', function () {
+ console.log('server subscribtion: clique_constraints');
+
+ //let that = this;
+
+ let query = {};
+ return CliqueConstraints.find(query);
+});
+
+Meteor.publish('clique_constraints?_id', function (_id) {
+ console.log('server subscribtion: clique_constraints?_id');
+ console.log(_id);
+
+ //let that = this;
+
+ let query = { _id: _id };
+ return CliqueConstraints.find(query);
+});
diff --git a/ui/imports/api/clique-types/clique-types.js b/ui/imports/api/clique-types/clique-types.js
new file mode 100644
index 0000000..852c319
--- /dev/null
+++ b/ui/imports/api/clique-types/clique-types.js
@@ -0,0 +1,107 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import * as R from 'ramda';
+import { Constants } from '/imports/api/constants/constants';
+import { Environments } from '/imports/api/environments/environments';
+import { LinkTypes } from '/imports/api/link-types/link-types';
+
+export const CliqueTypes = new Mongo.Collection(
+ 'clique_types', { idGeneration: 'MONGO' });
+
+let schema = {
+ _id: { type: { _str: { type: String, regEx: SimpleSchema.RegEx.Id } } },
+
+ environment: {
+ type: String,
+ custom: function () {
+ let that = this;
+ let env = Environments.findOne({ name: that.value });
+
+ if (R.isNil(env)) {
+ return 'notAllowed';
+ }
+ }
+ },
+
+ focal_point_type: {
+ type: String,
+ custom: function () {
+ let that = this;
+ let values = Constants.findOne({ name: 'object_types_for_links' }).data;
+
+ if (R.isNil(R.find(R.propEq('value', that.value), values))) {
+ return 'notAllowed';
+ }
+ }
+ },
+
+ link_types: {
+ type: [String],
+ minCount: 1,
+ custom: function () {
+ let that = this;
+ let findResult = R.all(function (pLinkType) {
+ if (R.isNil(LinkTypes.findOne({ type: pLinkType }))) {
+ return false;
+ }
+
+ return true;
+ }, that.value);
+
+ if (! findResult) { return 'notAllowed'; }
+
+ return;
+ },
+ },
+
+ name: {
+ type: String
+ },
+};
+
+let simpleSchema = new SimpleSchema(schema);
+
+simpleSchema.addValidator(function () {
+ let that = this;
+
+ let existing = CliqueTypes.findOne({
+ environment: that.field('environment').value,
+ focal_point_type: that.field('focal_point_type').value
+ });
+
+ if (R.allPass([
+ R.pipe(R.isNil, R.not),
+ R.pipe(R.propEq('_id', that.docId), R.not)
+ ])(existing)) {
+
+ return 'alreadyExists';
+ }
+});
+
+simpleSchema.addValidator(function () {
+ let that = this;
+
+ let existing = CliqueTypes.findOne({
+ environment: that.field('environment').value,
+ name: that.field('name').value
+ });
+
+ if (R.allPass([
+ R.pipe(R.isNil, R.not),
+ R.pipe(R.propEq('_id', that.docId), R.not)
+ ])(existing)) {
+
+ return 'alreadyExists';
+ }
+});
+
+CliqueTypes.schema = simpleSchema;
+CliqueTypes.attachSchema(CliqueTypes.schema);
diff --git a/ui/imports/api/clique-types/methods.js b/ui/imports/api/clique-types/methods.js
new file mode 100644
index 0000000..a62c22f
--- /dev/null
+++ b/ui/imports/api/clique-types/methods.js
@@ -0,0 +1,108 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { ValidatedMethod } from 'meteor/mdg:validated-method';
+import * as R from 'ramda';
+import { Roles } from 'meteor/alanning:roles';
+
+import { CliqueTypes } from './clique-types';
+
+export const insert = new ValidatedMethod({
+ name: 'clique_types.insert',
+ validate: CliqueTypes.simpleSchema()
+ .pick([
+ 'environment',
+ 'focal_point_type',
+ 'link_types',
+ 'link_types.$',
+ 'name',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ environment,
+ focal_point_type,
+ link_types,
+ name,
+ }) {
+ if (! Roles.userIsInRole(Meteor.userId(), 'manage-clique-types', Roles.DEFAULT_GROUP)) {
+ throw new Meteor.Error('unauthorized for adding clique type');
+ }
+
+ let cliqueType = CliqueTypes.schema.clean({});
+
+ cliqueType = R.merge(cliqueType, {
+ environment,
+ focal_point_type,
+ link_types,
+ name,
+ });
+
+ CliqueTypes.insert(cliqueType);
+ }
+});
+
+export const remove = new ValidatedMethod({
+ name: 'clique_types.remove',
+ validate: CliqueTypes.simpleSchema()
+ .pick([
+ '_id',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ _id
+ }) {
+
+ if (! Roles.userIsInRole(Meteor.userId(), 'manage-clique-types', Roles.DEFAULT_GROUP)) {
+ throw new Meteor.Error('unauthorized for removing clique type');
+ }
+
+ let cliqueType = CliqueTypes.findOne({ _id: _id });
+ console.log('clique type for remove: ', cliqueType);
+
+ CliqueTypes.remove({ _id: _id });
+ }
+});
+
+export const update = new ValidatedMethod({
+ name: 'clique_types.update',
+ validate: CliqueTypes.simpleSchema()
+ .pick([
+ '_id',
+ 'environment',
+ 'focal_point_type',
+ 'link_types',
+ 'link_types.$',
+ 'name',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ _id,
+ environment,
+ focal_point_type,
+ link_types,
+ name,
+ }) {
+ if (! Roles.userIsInRole(Meteor.userId(), 'manage-clique-types', Roles.DEFAULT_GROUP)) {
+ throw new Meteor.Error('unauthorized for updating clique type');
+ }
+
+ let cliqueType = CliqueTypes.findOne({ _id: _id });
+ console.log('clique type for remove: ', cliqueType);
+
+ cliqueType = R.merge(R.pick([
+ 'environment',
+ 'focal_point_type',
+ 'link_types',
+ 'name', ],
+ cliqueType), {
+ environment,
+ focal_point_type,
+ link_types,
+ name,
+ });
+
+ CliqueTypes.update({ _id: _id }, { $set: cliqueType });
+ }
+});
diff --git a/ui/imports/api/clique-types/server/publications.js b/ui/imports/api/clique-types/server/publications.js
new file mode 100644
index 0000000..95274b9
--- /dev/null
+++ b/ui/imports/api/clique-types/server/publications.js
@@ -0,0 +1,34 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+import * as R from 'ramda';
+
+import { CliqueTypes } from '../clique-types.js';
+
+Meteor.publish('clique_types?env*', function (env) {
+ console.log('server subscribtion: clique_types?env*');
+ console.log(env);
+
+ //let that = this;
+
+ let query = {};
+ if (! R.isNil(env)) { query = R.assoc('environment', env, query); }
+ console.log('-query: ', query);
+ return CliqueTypes.find(query);
+});
+
+Meteor.publish('clique_types?_id', function (_id) {
+ console.log('server subscribtion: clique_types?_id');
+ console.log(_id);
+
+ //let that = this;
+
+ let query = { _id: _id };
+ return CliqueTypes.find(query);
+});
diff --git a/ui/imports/api/cliques/cliques.js b/ui/imports/api/cliques/cliques.js
new file mode 100644
index 0000000..78fb7ad
--- /dev/null
+++ b/ui/imports/api/cliques/cliques.js
@@ -0,0 +1,12 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+
+export const Cliques = new Mongo.Collection(
+ 'cliques', { idGeneration: 'MONGO' });
diff --git a/ui/imports/api/cliques/methods.js b/ui/imports/api/cliques/methods.js
new file mode 100644
index 0000000..1eda375
--- /dev/null
+++ b/ui/imports/api/cliques/methods.js
@@ -0,0 +1,8 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/ui/imports/api/cliques/server/publications.js b/ui/imports/api/cliques/server/publications.js
new file mode 100644
index 0000000..16a4644
--- /dev/null
+++ b/ui/imports/api/cliques/server/publications.js
@@ -0,0 +1,33 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+
+import { Cliques } from '../cliques.js';
+
+Meteor.publish('cliques', function () {
+ console.log('server subscribtion to: cliques');
+ //return Inventory.find({$where: 'this.id_path.match('^/WebEX-Mirantis@Cisco/')'});
+ return Cliques.find({});
+});
+
+Meteor.publish('cliques?focal_point', function (objId) {
+ var query = {
+ focal_point: new Mongo.ObjectID(objId)
+ };
+/*
+ var counterName = 'inventory?env+type!counter?env=' + env + '&type=' + type;
+
+ console.log('server subscribing to counter: ' + counterName);
+ Counts.publish(this, counterName, Inventory.find(query));
+*/
+
+ console.log('server subscribtion to: cliques?focal_point');
+ console.log('- focal_point: ' + objId);
+ return Cliques.find(query);
+});
diff --git a/ui/imports/api/constants/constants.js b/ui/imports/api/constants/constants.js
new file mode 100644
index 0000000..b3f0407
--- /dev/null
+++ b/ui/imports/api/constants/constants.js
@@ -0,0 +1,22 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+//import * as R from 'ramda';
+
+export const Constants = new Mongo.Collection('constants', { idGeneration: 'MONGO' });
+
+let schema = {
+ _id: { type: { _str: { type: String, regEx: SimpleSchema.RegEx.Id } } },
+ name: { type: String },
+ data: { type: [Object], blackbox: true },
+};
+
+Constants.schema = schema;
+Constants.attachSchema(schema);
diff --git a/ui/imports/api/constants/data/distributions.js b/ui/imports/api/constants/data/distributions.js
new file mode 100644
index 0000000..97ecdb4
--- /dev/null
+++ b/ui/imports/api/constants/data/distributions.js
@@ -0,0 +1,64 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+export const Distributions = [{
+ label: 'Mirantis-6.0',
+ value: 'Mirantis-6.0',
+}, {
+ label: 'Mirantis-7.0',
+ value: 'Mirantis-7.0',
+}, {
+ label: 'Mirantis-8.0',
+ value: 'Mirantis-8.0',
+}, {
+ label: 'Mirantis-9.0',
+ value: 'Mirantis-9.0',
+}, {
+ label: 'RDO-Mitaka',
+ value: 'RDO-Mitaka',
+}, {
+ label: 'RDO-Liberty',
+ value: 'RDO-Liberty',
+}, {
+ label: 'RDO-Juno',
+ value: 'RDO-Juno',
+}, {
+ label: 'RDO-kilo',
+ value: 'RDO-kilo',
+}, {
+ label: 'devstack-liberty',
+ value: 'devstack-liberty',
+}, {
+ label: 'Canonical-icehouse',
+ value: 'Canonical-icehouse',
+}, {
+ label: 'Canonical-juno',
+ value: 'Canonical-juno',
+}, {
+ label: 'Canonical-liberty',
+ value: 'Canonical-liberty',
+}, {
+ label: 'Canonical-mitaka',
+ value: 'Canonical-mitaka',
+}, {
+ label: 'Apex-Mitaka',
+ value: 'Apex-Mitaka',
+}, {
+ label: 'Devstack-Mitaka',
+ value: 'Devstack-Mitaka',
+}, {
+ label: 'packstack-7.0.0-0.10.dev1682',
+ value: 'packstack-7.0.0-0.10.dev1682',
+}, {
+ label: 'Stratoscale-v2.1.6',
+ value: 'Stratoscale-v2.1.6',
+}, {
+ label: 'Mirantis-9.1',
+ value: 'Mirantis-9.1',
+}
+];
diff --git a/ui/imports/api/constants/data/env-types.js b/ui/imports/api/constants/data/env-types.js
new file mode 100644
index 0000000..00b0aaf
--- /dev/null
+++ b/ui/imports/api/constants/data/env-types.js
@@ -0,0 +1,15 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+export const EnvTypes = [{
+ label: 'Production',
+ value: 'production',
+}, {
+ label: 'Development',
+ value: 'development',
+}];
diff --git a/ui/imports/api/constants/data/environment-monitoring-types.js b/ui/imports/api/constants/data/environment-monitoring-types.js
new file mode 100644
index 0000000..e3a573a
--- /dev/null
+++ b/ui/imports/api/constants/data/environment-monitoring-types.js
@@ -0,0 +1,12 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+export const EnvironmentMonitoringTypes = [{
+ label: 'Sensu',
+ value: 'Sensu',
+}];
diff --git a/ui/imports/api/constants/data/environment-provision-types.js b/ui/imports/api/constants/data/environment-provision-types.js
new file mode 100644
index 0000000..5139266
--- /dev/null
+++ b/ui/imports/api/constants/data/environment-provision-types.js
@@ -0,0 +1,21 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+export const EnvProvisionTypes = [{
+ label: 'None',
+ value: 'None',
+}, {
+ label: 'Deploy',
+ value: 'Deploy',
+}, {
+ label: 'Files',
+ value: 'Files',
+}, {
+ label: 'DB',
+ value: 'DB',
+}];
diff --git a/ui/imports/api/constants/data/log-levels.js b/ui/imports/api/constants/data/log-levels.js
new file mode 100644
index 0000000..dee6b6d
--- /dev/null
+++ b/ui/imports/api/constants/data/log-levels.js
@@ -0,0 +1,27 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+export const LogLevels = [{
+ label: 'CRITICAL',
+ value: 'critical',
+}, {
+ label: 'ERROR',
+ value: 'error',
+}, {
+ label: 'WARNING',
+ value: 'warning',
+}, {
+ label: 'INFO',
+ value: 'info',
+}, {
+ label: 'DEBUG',
+ value: 'debug',
+}, {
+ label: 'NOTSET',
+ value: 'notset',
+}];
diff --git a/ui/imports/api/constants/data/mechanism-drivers.js b/ui/imports/api/constants/data/mechanism-drivers.js
new file mode 100644
index 0000000..afa8b01
--- /dev/null
+++ b/ui/imports/api/constants/data/mechanism-drivers.js
@@ -0,0 +1,24 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+export const MechanismDrivers = [{
+ 'label' : 'ovs',
+ 'value' : 'ovs'
+}, {
+ 'label' : 'vpp',
+ 'value' : 'vpp'
+}, {
+ 'label' : 'lxb',
+ 'value' : 'lxb'
+}, {
+ 'label' : 'Arista',
+ 'value' : 'Arista'
+}, {
+ 'label' : 'Nexus',
+ 'value' : 'Nexus'
+}];
diff --git a/ui/imports/api/constants/data/message-source-systems.js b/ui/imports/api/constants/data/message-source-systems.js
new file mode 100644
index 0000000..77ec901
--- /dev/null
+++ b/ui/imports/api/constants/data/message-source-systems.js
@@ -0,0 +1,15 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+export const MessageSourceSystems = [{
+ label: 'OpenStack',
+ value: 'OpenStack',
+}, {
+ label: 'OSDNA_Sensu',
+ value: 'OSDNA_Sensu',
+}];
diff --git a/ui/imports/api/constants/data/network-plugins.js b/ui/imports/api/constants/data/network-plugins.js
new file mode 100644
index 0000000..c89be26
--- /dev/null
+++ b/ui/imports/api/constants/data/network-plugins.js
@@ -0,0 +1,15 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+export const NetworkPlugins = [{
+ label: 'OVS',
+ value: 'OVS',
+}, {
+ label: 'VPP',
+ value: 'VPP',
+}];
diff --git a/ui/imports/api/constants/data/object-types-for-links.js b/ui/imports/api/constants/data/object-types-for-links.js
new file mode 100644
index 0000000..35f1805
--- /dev/null
+++ b/ui/imports/api/constants/data/object-types-for-links.js
@@ -0,0 +1,39 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+export const ObjectTypesForLinks = [{
+ label: 'vnic',
+ value: 'vnic',
+}, {
+ label: 'vconnector',
+ value: 'vconnector',
+}, {
+ label: 'vedge',
+ value: 'vedge',
+}, {
+ label: 'instance',
+ value: 'instance',
+}, {
+ label: 'vservice',
+ value: 'vservice',
+}, {
+ label: 'pnic',
+ value: 'pnic',
+}, {
+ label: 'network',
+ value: 'network',
+}, {
+ label: 'port',
+ value: 'port',
+}, {
+ label: 'otep',
+ value: 'otep',
+}, {
+ label: 'agent',
+ value: 'agent',
+}];
diff --git a/ui/imports/api/constants/data/scans-statuses.js b/ui/imports/api/constants/data/scans-statuses.js
new file mode 100644
index 0000000..778f256
--- /dev/null
+++ b/ui/imports/api/constants/data/scans-statuses.js
@@ -0,0 +1,30 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+export const Statuses = [{
+ value: 'draft',
+ label: 'Draft',
+}, {
+ value: 'pending',
+ label: 'Pending',
+}, {
+ value: 'running',
+ label: 'Running',
+}, {
+ value: 'completed',
+ label: 'Completed',
+}, {
+ value: 'failed',
+ label: 'Failed',
+}, {
+ value: 'aborted',
+ label: 'Aborted',
+}
+];
+
+export const StatusesInOperation = ['pending', 'running'];
diff --git a/ui/imports/api/constants/data/type-drivers.js b/ui/imports/api/constants/data/type-drivers.js
new file mode 100644
index 0000000..efc7f7d
--- /dev/null
+++ b/ui/imports/api/constants/data/type-drivers.js
@@ -0,0 +1,24 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+export const TypeDrivers = [{
+ 'label' : 'local',
+ 'value' : 'local'
+}, {
+ 'label' : 'vlan',
+ 'value' : 'vlan'
+}, {
+ 'label' : 'vxlan',
+ 'value' : 'vxlan'
+}, {
+ 'label' : 'gre',
+ 'value' : 'gre'
+}, {
+ 'label' : 'flat',
+ 'value' : 'flat'
+}];
diff --git a/ui/imports/api/constants/server/publications.js b/ui/imports/api/constants/server/publications.js
new file mode 100644
index 0000000..3ace17f
--- /dev/null
+++ b/ui/imports/api/constants/server/publications.js
@@ -0,0 +1,16 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+
+import { Constants } from '../constants.js';
+
+Meteor.publish('constants', function () {
+ console.log('server subscribtion to: constants');
+ return Constants.find({});
+});
diff --git a/ui/imports/api/environments/configuration-groups/aci-configuration.js b/ui/imports/api/environments/configuration-groups/aci-configuration.js
new file mode 100644
index 0000000..10b749e
--- /dev/null
+++ b/ui/imports/api/environments/configuration-groups/aci-configuration.js
@@ -0,0 +1,29 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+
+export const AciSchema = new SimpleSchema({
+ name: {
+ type: String,
+ autoValue: function () { return 'ACI'; }
+ },
+ host: {
+ type: String,
+ regEx: SimpleSchema.RegEx.IP,
+ defaultValue: '10.56.0.104',
+ },
+ user: {
+ type: String,
+ defaultValue: 'admin'
+ },
+ pwd: {
+ type: String,
+ defaultValue: 'C1sco12345'
+ },
+});
diff --git a/ui/imports/api/environments/configuration-groups/amqp-configuration.js b/ui/imports/api/environments/configuration-groups/amqp-configuration.js
new file mode 100644
index 0000000..83a15cf
--- /dev/null
+++ b/ui/imports/api/environments/configuration-groups/amqp-configuration.js
@@ -0,0 +1,29 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import { portRegEx } from '/imports/lib/general-regex';
+
+export const AMQPSchema = new SimpleSchema({
+ name: { type: String, autoValue: function () { return 'AMQP'; } },
+ host: {
+ type: String,
+ regEx: SimpleSchema.RegEx.IP,
+ defaultValue: '10.0.0.1',
+ },
+ port: {
+ type: String,
+ regEx: portRegEx,
+ defaultValue: '5673',
+ },
+ user: {
+ type: String,
+ defaultValue: 'rabbitmquser'
+ },
+ password: { type: String },
+});
diff --git a/ui/imports/api/environments/configuration-groups/cli-configuration.js b/ui/imports/api/environments/configuration-groups/cli-configuration.js
new file mode 100644
index 0000000..c651359
--- /dev/null
+++ b/ui/imports/api/environments/configuration-groups/cli-configuration.js
@@ -0,0 +1,69 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import * as R from 'ramda';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import { pathRegEx } from '/imports/lib/general-regex';
+
+export const CLISchema = new SimpleSchema({
+ name: { type: String, autoValue: function () { return 'CLI'; } },
+ host: {
+ type: String,
+ defaultValue: '10.0.0.1'
+ },
+ key: {
+ type: String,
+ regEx: pathRegEx,
+ optional: true
+ },
+ user: {
+ type: String,
+ defaultValue: 'sshuser'
+ },
+ pwd: {
+ type: String,
+ optional: true
+ },
+});
+
+CLISchema.addValidator(function () {
+ let that = this;
+
+ let conf = {};
+ if (isConfEmpty(conf)) {
+ return;
+ }
+
+ let validationResult = R.find((validationFn) => {
+ return validationFn(that).isError;
+ }, [ keyPasswordValidation ]);
+
+ if (R.isNil(validationResult)) { return; }
+
+ throw validationResult(that);
+});
+
+function keyPasswordValidation(schemaItem) {
+ let password = schemaItem.field('pwd');
+ let key = schemaItem.field('key');
+
+ if (key.value || password.value) { return { isError: false }; }
+
+ return {
+ isError: true,
+ type: 'subGroupError',
+ data: [],
+ message: 'Master Host Group: At least one required: key or password'
+ };
+}
+
+function isConfEmpty(conf) {
+ return R.find((key) => {
+ return !(R.isNil(conf[key]));
+ }, R.keys(conf));
+}
diff --git a/ui/imports/api/environments/configuration-groups/monitoring-configuration.js b/ui/imports/api/environments/configuration-groups/monitoring-configuration.js
new file mode 100644
index 0000000..2b27f8a
--- /dev/null
+++ b/ui/imports/api/environments/configuration-groups/monitoring-configuration.js
@@ -0,0 +1,119 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import * as R from 'ramda';
+import { Constants } from '/imports/api/constants/constants';
+import { portRegEx } from '/imports/lib/general-regex';
+import { hostnameRegex } from '/imports/lib/general-regex';
+import { ipAddressRegex } from '/imports/lib/general-regex';
+import { pathRegEx } from '/imports/lib/general-regex';
+
+export const MonitoringSchema = new SimpleSchema({
+ name: { type: String, autoValue: function () { return 'Monitoring'; } },
+ //app_path: { type: String, autoValue: function () { return '/etc/calipso/monitoring'; } },
+
+ config_folder: {
+ type: String,
+ defaultValue: '/local_dir/sensu_config',
+ regEx: pathRegEx,
+ },
+
+ env_type: {
+ type: String,
+ defaultValue: 'production',
+ custom: function () {
+ let that = this;
+ let EnvTypesRec = Constants.findOne({ name: 'env_types' });
+
+ if (R.isNil(EnvTypesRec.data)) { return 'notAllowed'; }
+ let EnvTypes = EnvTypesRec.data;
+
+ if (R.isNil(R.find(R.propEq('value', that.value), EnvTypes))) {
+ return 'notAllowed';
+ }
+ },
+ },
+
+ rabbitmq_port: {
+ type: String,
+ defaultValue: '5671',
+ regEx: portRegEx,
+ },
+
+ rabbitmq_user: {
+ type: String,
+ defaultValue: 'sensu'
+ },
+
+ rabbitmq_pass: { type: String },
+
+ server_ip: {
+ type: String,
+ regEx: new RegExp(hostnameRegex.source + '|' + ipAddressRegex.soure),
+ defaultValue: '10.0.0.1',
+ },
+
+ server_name: {
+ type: String,
+ defaultValue: 'sensu_server',
+ },
+
+ type: {
+ type: String,
+ defaultValue: 'Sensu',
+ custom: function () {
+ let that = this;
+ let values = Constants.findOne({ name: 'environment_monitoring_types' }).data;
+
+ if (R.isNil(values)) { return 'notAllowed'; }
+
+ if (R.isNil(R.find(R.propEq('value', that.value), values))) {
+ return 'notAllowed';
+ }
+ },
+ },
+
+ provision: {
+ type: String,
+ defaultValue: 'None',
+ custom: function () {
+ let that = this;
+ let values = Constants.findOne({ name: 'environment_provision_types' }).data;
+
+ if (R.isNil(values)) { return 'notAllowed'; }
+
+ if (R.isNil(R.find(R.propEq('value', that.value), values))) {
+ return 'notAllowed';
+ }
+ },
+ },
+
+ ssh_port: {
+ type: String,
+ defaultValue: '20022',
+ optional: true
+ },
+
+ ssh_user: {
+ type: String,
+ defaultValue: 'root',
+ optional: true
+ },
+
+ ssh_password: {
+ type: String,
+ defaultValue: 'calipso',
+ optional: true
+ },
+
+ api_port: {
+ type: Number,
+ defaultValue: 4567,
+ },
+});
diff --git a/ui/imports/api/environments/configuration-groups/mysql-configuration.js b/ui/imports/api/environments/configuration-groups/mysql-configuration.js
new file mode 100644
index 0000000..1921432
--- /dev/null
+++ b/ui/imports/api/environments/configuration-groups/mysql-configuration.js
@@ -0,0 +1,33 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import { portRegEx } from '/imports/lib/general-regex';
+
+export const MysqlSchema = new SimpleSchema({
+ name: {
+ type: String,
+ autoValue: function () { return 'mysql'; }
+ },
+ host: {
+ type: String,
+ regEx: SimpleSchema.RegEx.IP,
+ defaultValue: '10.0.0.1'
+ },
+ password: { type: String },
+ port: {
+ type: String,
+ regEx: portRegEx,
+ defaultValue: '3307'
+ },
+ user: {
+ type: String,
+ min: 3,
+ defaultValue: 'mysqluser'
+ },
+});
diff --git a/ui/imports/api/environments/configuration-groups/nfv-provider-configuration.js b/ui/imports/api/environments/configuration-groups/nfv-provider-configuration.js
new file mode 100644
index 0000000..3638e3b
--- /dev/null
+++ b/ui/imports/api/environments/configuration-groups/nfv-provider-configuration.js
@@ -0,0 +1,25 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import { portRegEx } from '/imports/lib/general-regex';
+
+export const NfvProviderSchema = new SimpleSchema({
+ name: { type: String, autoValue: function () { return 'NFV_provider'; } },
+ host: {
+ type: String,
+ regEx: SimpleSchema.RegEx.IP,
+ },
+ nfv_token: { type: String },
+ port: {
+ type: String,
+ regEx: portRegEx
+ },
+ user: { type: String },
+ pwd: { type: String },
+});
diff --git a/ui/imports/api/environments/configuration-groups/open-stack-configuration.js b/ui/imports/api/environments/configuration-groups/open-stack-configuration.js
new file mode 100644
index 0000000..a0d710f
--- /dev/null
+++ b/ui/imports/api/environments/configuration-groups/open-stack-configuration.js
@@ -0,0 +1,30 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import { portRegEx } from '/imports/lib/general-regex';
+
+export const OpenStackSchema = new SimpleSchema({
+ name: { type: String, autoValue: function () { return 'OpenStack'; } },
+ host: {
+ type: String,
+ regEx: SimpleSchema.RegEx.IP,
+ defaultValue: '10.0.0.1',
+ },
+ admin_token: { type: String },
+ port: {
+ type: String,
+ regEx: portRegEx,
+ defaultValue: '5000',
+ },
+ user: {
+ type: String,
+ defaultValue: 'adminuser'
+ },
+ pwd: { type: String },
+});
diff --git a/ui/imports/api/environments/environments.js b/ui/imports/api/environments/environments.js
new file mode 100644
index 0000000..d616960
--- /dev/null
+++ b/ui/imports/api/environments/environments.js
@@ -0,0 +1,457 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import * as R from 'ramda';
+import { Constants } from '/imports/api/constants/constants';
+import { MysqlSchema } from './configuration-groups/mysql-configuration';
+import { OpenStackSchema } from './configuration-groups/open-stack-configuration';
+import { MonitoringSchema } from './configuration-groups/monitoring-configuration';
+import { CLISchema } from './configuration-groups/cli-configuration';
+import { AMQPSchema } from './configuration-groups/amqp-configuration';
+//import { NfvProviderSchema } from './configuration-groups/nfv-provider-configuration';
+import { AciSchema } from './configuration-groups/aci-configuration';
+import {
+ isMonitoringSupported,
+ isListeningSupported,
+} from '/imports/api/supported_environments/supported_environments';
+
+export const Environments = new Mongo.Collection(
+ 'environments_config', { idGeneration: 'MONGO' });
+
+export const requiredConfGroups = [
+ 'mysql',
+ 'OpenStack',
+ 'CLI',
+];
+
+export const optionalConfGroups = [
+ // 'NFV_provider',
+ 'AMQP',
+ 'Monitoring',
+ 'ACI',
+];
+
+let simpleSchema = new SimpleSchema({
+ _id: { type: { _str: { type: String, regEx: SimpleSchema.RegEx.Id } } },
+ auth: {
+ type: Object,
+ blackbox: true,
+ defaultValue: {
+ 'view-env': [
+ ],
+ 'edit-env': [
+ ]
+ }
+ },
+ configuration: {
+ type: [Object],
+ blackbox: true,
+ autoValue: function () {
+ console.log('start - autovalue - environment - configuration');
+ //console.log(this);
+ let that = this;
+
+ if (that.isSet) {
+ let confGroups = that.value;
+
+ let {
+ isMonitoringSupportedRes,
+ isListeningSupportedRes,
+ enable_monitoring,
+ listen
+ } = extractCalcEnvSupportedRelatedValues(that);
+ let dbNode = getDbNode(that);
+ let aci = extractValue('aci', that, dbNode);
+
+ if (enable_monitoring && isMonitoringSupportedRes) {
+ if (! R.find(R.propEq('name', 'Monitoring'), confGroups)) {
+ confGroups = R.append(createNewConfGroup('Monitoring'), confGroups);
+ }
+ } else {
+ console.log('env - configurations - autovalue - monitoring not supported');
+ confGroups = R.reject(R.propEq('name', 'Monitoring'), confGroups);
+ }
+
+ if (listen && isListeningSupportedRes) {
+ if (! R.find(R.propEq('name', 'AMQP'), confGroups)) {
+ confGroups = R.append(createNewConfGroup('AMQP'), confGroups);
+ }
+ } else {
+ console.log('env - configurations - autovalue - listening not supported');
+ confGroups = R.reject(R.propEq('name', 'AMQP'), confGroups);
+ }
+
+ if (aci) {
+ if (! R.find(R.propEq('name', 'ACI'), confGroups)) {
+ confGroups = R.append(createNewConfGroup('ACI'), confGroups);
+ }
+ } else {
+ console.log('env - configurations - autovalue - aci not requested');
+ confGroups = R.reject(R.propEq('name', 'ACI'), confGroups);
+ }
+
+ confGroups = cleanOptionalGroups(confGroups, optionalConfGroups);
+ console.log('env - configurations - autovalue - after clean optional groups');
+
+ let newValue = R.map(function(confGroup) {
+ let schema = getSchemaForGroupName(confGroup.name);
+ return schema.clean(confGroup);
+ }, confGroups);
+
+ console.log('end - autovalue - environment - configurations');
+ console.log(newValue);
+ return newValue;
+
+ } else {
+ console.log('env - configurations - autovalue - is not set');
+ let newValue = R.map((confName) => {
+ let schema = getSchemaForGroupName(confName);
+ return schema.clean({});
+ }, requiredConfGroups);
+ console.log('end - autovalue - environment - configurations');
+ console.log(newValue);
+ return newValue;
+ }
+ },
+ custom: function () {
+ console.log('start - custom - environment - configurations');
+ //console.log(this);
+ let that = this;
+ let configurationGroups = that.value;
+
+ let subErrors = [];
+
+ let {
+ isMonitoringSupportedRes,
+ isListeningSupportedRes,
+ enable_monitoring,
+ listen
+ } = extractCalcEnvSupportedRelatedValues(that);
+
+ let requiredConfGroupsTemp = R.clone(requiredConfGroups);
+ if (enable_monitoring && isMonitoringSupportedRes) {
+ requiredConfGroupsTemp = R.append('Monitoring', requiredConfGroupsTemp);
+ }
+ if (listen && isListeningSupportedRes) {
+ requiredConfGroupsTemp = R.append('AMQP', requiredConfGroupsTemp);
+ }
+
+ console.log('env - configurations - custom - after mon & listen check');
+
+ let invalidResult = R.find(function(groupName) {
+ subErrors = checkGroup(groupName, configurationGroups, true);
+ if (subErrors.length > 0) { return true; }
+ return false;
+ }, requiredConfGroupsTemp);
+
+ console.log(`env - configurations - custom - after require groups check`);
+
+ if (R.isNil(invalidResult)) {
+ invalidResult = R.find(function(groupName) {
+ subErrors = checkGroup(groupName, configurationGroups, false);
+ if (subErrors.length > 0) { return true; }
+ return false;
+ }, optionalConfGroups);
+ }
+
+ console.log(`env - configurations - custom - after optional groups check`);
+
+ if (! R.isNil(invalidResult)) {
+ console.log(`env - configrations - custom - invalid result end: ${R.toString(subErrors)}`);
+ throw {
+ isError: true,
+ type: 'subGroupError',
+ data: subErrors,
+ message: constructSubGroupErrorMessage(subErrors)
+ };
+ }
+ },
+
+ },
+ user: {
+ type: String,
+ },
+ distribution: {
+ type: String,
+ defaultValue: 'Mirantis-8.0',
+ custom: function () {
+ let that = this;
+ let constsDist = Constants.findOne({ name: 'distributions' });
+
+ if (R.isNil(constsDist.data)) { return 'notAllowed'; }
+ let distributions = constsDist.data;
+
+ if (R.isNil(R.find(R.propEq('value', that.value), distributions))) {
+ return 'notAllowed';
+ }
+ },
+ },
+ last_scanned: {
+ type: String, defaultValue: ''
+ },
+ name: {
+ type: String,
+ defaultValue: 'MyEnvironmentName',
+ min: 6,
+ },
+ type_drivers: {
+ type: String,
+ defaultValue: 'gre',
+ custom: function () {
+ let that = this;
+ let TypeDriversRec = Constants.findOne({ name: 'type_drivers' });
+
+ if (R.isNil(TypeDriversRec.data)) { return 'notAllowed'; }
+ let TypeDrivers = TypeDriversRec.data;
+
+ if (R.isNil(R.find(R.propEq('value', that.value), TypeDrivers))) {
+ return 'notAllowed';
+ }
+ },
+ },
+
+ mechanism_drivers: {
+ type: [String],
+ defaultValue: ['ovs'],
+ minCount: 1,
+ custom: function () {
+ let that = this;
+ let consts = Constants.findOne({ name: 'mechanism_drivers' });
+
+ if (R.isNil(consts.data)) { return 'notAllowed'; }
+ let mechanismDrivers = consts.data;
+
+ let result = R.find((driver) => {
+ if (R.find(R.propEq('value', driver), mechanismDrivers)) {
+ return false;
+ }
+ return true;
+ }, that.value);
+
+ if (result) { return 'notAllowed'; }
+
+ },
+ },
+
+ operational: {
+ type: String,
+ allowedValues: ['stopped', 'running', 'error'],
+ defaultValue: 'stopped'
+ },
+
+ scanned: { type: Boolean, defaultValue: false },
+
+ type: {
+ type: String,
+ autoValue: function () {
+ return 'environment';
+ },
+ },
+
+ app_path: {
+ type: String,
+ autoValue: function () {
+ return '/home/scan/calipso_prod/app';
+ }
+ },
+
+ listen: {
+ type: Boolean,
+ autoValue: function () {
+ console.log('env - listen - autoValue - start');
+ let that = this;
+ let newValue = that.value;
+ console.log(`- current value: ${R.toString(newValue)}`);
+
+ let { isListeningSupportedRes } = extractCalcEnvSupportedRelatedValues(that);
+
+ if (!isListeningSupportedRes) {
+ console.log('* listening not supported');
+ console.log(`* ${R.toString(isListeningSupportedRes)}`);
+ newValue = false;
+ }
+
+ return newValue;
+ },
+ },
+
+ enable_monitoring: {
+ type: Boolean,
+ autoValue: function () {
+ console.log('env - enable_monitoring - autoValue - start');
+ let that = this;
+ let newValue = that.value;
+ console.log(`- current value: ${R.toString(newValue)}`);
+
+ let { isMonitoringSupportedRes } = extractCalcEnvSupportedRelatedValues(that);
+
+ if (!isMonitoringSupportedRes) {
+ console.log('* monitoring not supported');
+ console.log(`* ${R.toString(isMonitoringSupportedRes)}`);
+ newValue = false;
+ }
+
+ return newValue;
+ },
+ },
+ aci: {
+ type: Boolean,
+ defaultValue: false,
+ },
+});
+
+/*
+simpleSchema.addValidator(function () {
+ //let that = this;
+});
+*/
+
+// Bug in simple schema. cant add custom message to instance specific
+// schema.
+// https://github.com/aldeed/meteor-simple-schema/issues/559
+// Version 2 fixes it but it is rc.
+//Environments.schema.messages({
+SimpleSchema.messages({
+ confGroupInvalid: 'Configuration group is invalid.'
+});
+
+Environments.schema = simpleSchema;
+Environments.attachSchema(Environments.schema);
+
+function getSchemaForGroupName(groupName) {
+ switch (groupName) {
+ case 'mysql':
+ return MysqlSchema;
+ case 'OpenStack':
+ return OpenStackSchema;
+ case 'CLI':
+ return CLISchema;
+ case 'AMQP':
+ return AMQPSchema;
+// case 'NFV_provider':
+// return NfvProviderSchema;
+ case 'ACI':
+ return AciSchema;
+ case 'Monitoring':
+ return MonitoringSchema;
+ default:
+ throw 'group name is not recognized. group: ' + groupName;
+ }
+}
+
+function constructSubGroupErrorMessage(errors) {
+ let message = 'Validation errors on sub groups:';
+ message = message + R.reduce((acc, item) => {
+ return acc + '\n- ' + item.group + ': ' + item.message;
+ }, '', errors);
+
+ return message;
+}
+
+function checkGroup(groupName, configurationGroups, groupRequired) {
+ let subErrors = [];
+ let confGroup = R.find(R.propEq('name', groupName), configurationGroups);
+
+ if (R.isNil(confGroup)) {
+ if (groupRequired) {
+ subErrors = R.append({
+ field: 'configuration',
+ group: groupName,
+ message: 'group ' + groupName + ' is required'
+ }, subErrors);
+ }
+ return subErrors;
+ }
+
+ let validationContext = getSchemaForGroupName(groupName).newContext();
+
+ if (! validationContext.validate(confGroup)) {
+ subErrors = R.reduce(function (acc, invalidField) {
+ return R.append({
+ field: invalidField,
+ group: groupName,
+ message: validationContext.keyErrorMessage(invalidField.name),
+ }, acc);
+ }, [], validationContext.invalidKeys());
+
+ return subErrors;
+ }
+
+ return subErrors;
+}
+
+export function createNewConfGroup(groupName) {
+ let schema = getSchemaForGroupName(groupName);
+ return schema.clean({});
+}
+
+function cleanOptionalGroups(confGroups, optionalConfGroups) {
+ return R.filter((conf) => {
+ if (R.contains(conf.name, optionalConfGroups)) {
+ return !isConfEmpty(conf);
+ }
+
+ return true;
+ }, confGroups);
+}
+
+function isConfEmpty(conf) {
+ return ! R.any((key) => {
+ if (key === 'name') { return false; } // We ignore the key 'name'. It is a 'type' key.
+ let val = conf[key];
+ return ! ( R.isNil(val) || R.isEmpty(val));
+ })(R.keys(conf));
+}
+
+function extractValue(name, schemaValidator, dbNode) {
+ console.log('env - extract value');
+ console.log(`-name: ${R.toString(name)}`);
+ //console.log(`-schemaValidator: ${R.toString(schemaValidator)}`);
+ console.log(`-dbNode: ${R.toString(dbNode)}`);
+
+ let field = schemaValidator.field(name);
+ let value = field.value;
+
+ console.log(`extract value - schema value: ${R.toString(value)}`);
+
+ if (R.isNil(field.value) && !field.isSet && dbNode) {
+ console.log(`extract value - db value: ${R.toString(dbNode[name])}`);
+ value = dbNode[name];
+ }
+
+ console.log(`extract value - result: ${R.toString(value)}`);
+ return value;
+}
+
+function getDbNode(schemaHelper) {
+ let _id = R.defaultTo(schemaHelper.docId, R.path(['value'], schemaHelper.field('_id')));
+ let dbNode = R.defaultTo(null, Environments.findOne({ _id: _id }));
+ return dbNode;
+}
+
+function extractCalcEnvSupportedRelatedValues(schemaHelper) {
+ let dbNode = getDbNode(schemaHelper);
+
+ let dist = extractValue('distribution', schemaHelper, dbNode);
+ let typeDrivers = extractValue('type_drivers', schemaHelper, dbNode);
+ let mechDrivers = extractValue('mechanism_drivers', schemaHelper, dbNode);
+ let enable_monitoring = extractValue('enable_monitoring', schemaHelper, dbNode);
+ let listen = extractValue('listen', schemaHelper, dbNode);
+
+ let isMonitoringSupportedRes = isMonitoringSupported(dist, typeDrivers, mechDrivers);
+ let isListeningSupportedRes = isListeningSupported(dist, typeDrivers, mechDrivers);
+
+ return {
+ enable_monitoring,
+ listen,
+ isMonitoringSupportedRes,
+ isListeningSupportedRes,
+ };
+}
diff --git a/ui/imports/api/environments/methods.js b/ui/imports/api/environments/methods.js
new file mode 100644
index 0000000..22a1e8b
--- /dev/null
+++ b/ui/imports/api/environments/methods.js
@@ -0,0 +1,154 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+//import { Meteor } from 'meteor/meteor';
+import * as R from 'ramda';
+import { ValidatedMethod } from 'meteor/mdg:validated-method';
+
+//import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+
+import { Environments } from './environments';
+import { Inventory } from '/imports/api/inventories/inventories';
+import { Links } from '/imports/api/links/links';
+import { Cliques } from '/imports/api/cliques/cliques';
+import { CliqueTypes } from '/imports/api/clique-types/clique-types';
+import { Messages } from '/imports/api/messages/messages';
+import { Scans } from '/imports/api/scans/scans';
+import { Roles } from 'meteor/alanning:roles';
+
+export const insert = new ValidatedMethod({
+ name: 'environments.insert',
+ validate: Environments.simpleSchema()
+ .pick([
+ 'configuration',
+ 'configuration.$',
+ 'distribution',
+ 'name',
+ 'type_drivers',
+ 'mechanism_drivers',
+ 'mechanism_drivers.$',
+ 'listen',
+ 'enable_monitoring',
+ 'aci',
+ ]).validator({ clean: true, filter: false }),
+ //validate: null,
+ run({
+ configuration,
+ distribution,
+ name,
+ type_drivers,
+ mechanism_drivers,
+ listen,
+ enable_monitoring,
+ aci,
+ }) {
+ // todo: create clean object instance.
+ let environment = Environments.schema.clean({
+ user: Meteor.userId()
+ });
+
+ let auth = {
+ 'view-env': [
+ Meteor.userId()
+ ],
+ 'edit-env': [
+ Meteor.userId()
+ ]
+ };
+
+ environment = R.merge(environment, {
+ configuration,
+ distribution,
+ name,
+ type_drivers,
+ mechanism_drivers,
+ listen,
+ enable_monitoring,
+ auth,
+ aci,
+ });
+
+ Environments.insert(environment);
+ },
+});
+
+export const update = new ValidatedMethod({
+ name: 'environments.update',
+ validate: Environments.simpleSchema().pick([
+ '_id',
+ 'configuration',
+ 'configuration.$',
+ //'distribution',
+ //'name',
+ 'type_drivers',
+ 'mechanism_drivers',
+ 'mechanism_drivers.$',
+ 'listen',
+ 'enable_monitoring',
+ 'aci',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ _id,
+ configuration,
+ //distribution,
+ //name,
+ type_drivers,
+ mechanism_drivers,
+ listen,
+ enable_monitoring,
+ aci,
+ }) {
+ let env = Environments.findOne({ _id: _id });
+
+ if (! Roles.userIsInRole(Meteor.userId(), 'edit-env', 'default-group')) {
+ if (! R.contains(Meteor.userId(), R.path(['auth', 'edit-env'], env) )) {
+ throw new Meteor.Error('not-auth', 'unauthorized for updating env');
+ }
+ }
+
+ Environments.update(_id, {
+ $set: {
+ configuration: configuration,
+ //distribution: distribution,
+ //name: name,
+ type_drivers,
+ mechanism_drivers,
+ listen,
+ enable_monitoring,
+ aci,
+ },
+ });
+ }
+});
+
+export const remove = new ValidatedMethod({
+ name: 'environments.remove',
+ validate: Environments.simpleSchema().pick([
+ '_id',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ _id,
+ }) {
+ const env = Environments.findOne({ _id: _id });
+ console.log('environment for remove: ', env);
+
+ if (! Roles.userIsInRole(Meteor.userId(), 'edit-env', 'default-group')) {
+ if (! R.contains(Meteor.userId(), R.path(['auth', 'edit-env'], env) )) {
+ throw new Meteor.Error('not-auth', 'unauthorized for updating env');
+ }
+ }
+
+ Inventory.remove({ environment: env.name });
+ Links.remove({ environment: env.name });
+ Cliques.remove({ environment: env.name });
+ CliqueTypes.remove({ environment: env.name });
+ Messages.remove({ environment: env.name });
+ Scans.remove({ environment: env.name });
+ Environments.remove({ _id: _id });
+ }
+});
diff --git a/ui/imports/api/environments/server/publications.js b/ui/imports/api/environments/server/publications.js
new file mode 100644
index 0000000..667ee8e
--- /dev/null
+++ b/ui/imports/api/environments/server/publications.js
@@ -0,0 +1,102 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+import * as R from 'ramda';
+import { Roles } from 'meteor/alanning:roles';
+
+import { Environments } from '../environments.js';
+
+Meteor.publish('environments_config', function () {
+ console.log('server subscribtion to: environments_config');
+ let userId = this.userId;
+
+ let query = {
+ type: 'environment',
+ };
+
+ if (! Roles.userIsInRole(userId, 'view-env', null)) {
+ query = R.merge(query, {
+ 'auth.view-env': {
+ $in: [ userId ]
+ }
+ });
+ }
+
+ console.log('-query: ', R.toString(query));
+ return Environments.find(query);
+});
+
+const subsEnvViewEnvUserId = 'environments.view-env&userId';
+Meteor.publish(subsEnvViewEnvUserId, function (userId) {
+ console.log(`subscription - ${subsEnvViewEnvUserId} `);
+ console.log(`-userId: ${R.toString(userId)}`);
+
+ let query = {};
+
+ let currentUser = this.userId;
+ if (! Roles.userIsInRole(currentUser, 'manage-users', Roles.GLOBAL_GROUP)) {
+ console.log(`* error: unauth`);
+ console.log(`- currentUser: ${R.toString(currentUser)}`);
+ this.error('unauthorized for this subscription');
+ return;
+ }
+
+ query = R.merge(query, {
+ 'auth.view-env': {
+ $in: [ userId ]
+ }
+ });
+
+ console.log(`* query: ${R.toString(query)}`);
+ return Environments.find(query);
+});
+
+const subsEnvEditEnvUserId = 'environments.edit-env&userId';
+Meteor.publish(subsEnvEditEnvUserId, function (userId) {
+ console.log(`subscription - ${subsEnvEditEnvUserId} `);
+ console.log(`-userId: ${R.toString(userId)}`);
+ let query = {};
+
+ let currentUser = this.userId;
+ if (! Roles.userIsInRole(currentUser, 'manage-users', Roles.GLOBAL_GROUP)) {
+ console.log(`* error: unauth`);
+ console.log(`- currentUser: ${R.toString(currentUser)}`);
+ this.error('unauthorized for this subscription');
+ return;
+ }
+
+ query = R.merge(query, {
+ 'auth.edit-env': {
+ $in: [ userId ]
+ }
+ });
+
+ console.log(`* query: ${R.toString(query)}`);
+ return Environments.find(query);
+});
+
+Meteor.publish('environments?name', function (name) {
+ console.log('server subscribtion to: environments?name=' + name.toString());
+ let query = {
+ name: name,
+ user: this.userId
+ };
+ return Environments.find(query);
+});
+
+Meteor.publish('environments?_id', function (_id) {
+ console.log('server subscribtion to: environments?_id');
+ console.log('-_id: ', R.toString(_id));
+
+ let query = {
+ _id: _id,
+ user: this.userId
+ };
+ return Environments.find(query);
+});
diff --git a/ui/imports/api/inventories/inventories.js b/ui/imports/api/inventories/inventories.js
new file mode 100644
index 0000000..114f5ef
--- /dev/null
+++ b/ui/imports/api/inventories/inventories.js
@@ -0,0 +1,11 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+
+export const Inventory = new Mongo.Collection('inventory', { idGeneration: 'MONGO' });
diff --git a/ui/imports/api/inventories/server/methods.js b/ui/imports/api/inventories/server/methods.js
new file mode 100644
index 0000000..ec2f27d
--- /dev/null
+++ b/ui/imports/api/inventories/server/methods.js
@@ -0,0 +1,151 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { check } from 'meteor/check';
+import * as R from 'ramda';
+import { Inventory } from '../inventories';
+import { Environments } from '/imports/api/environments/environments';
+import { regexEscape } from '/imports/lib/regex-utils';
+import { NodeHoverAttr } from '/imports/api/attributes_for_hover_on_data/attributes_for_hover_on_data';
+const AUTO_COMPLETE_RESULTS_LIMIT = 15;
+
+Meteor.methods({
+ 'inventorySearch': function(searchTerm, envId, opCounter) {
+ console.log('inventorySearch');
+ console.log('searchTerm', R.toString(searchTerm));
+ console.log('envId', R.toString(envId));
+ console.log('opCounter', R.toString(opCounter));
+
+ this.unblock();
+
+ if (R.anyPass([R.isNil, R.isEmpty])(searchTerm)) {
+ return {
+ searchResults: [],
+ opCounter: opCounter
+ };
+ }
+
+ let searchExp = new RegExp(regexEscape(searchTerm), 'i');
+
+ let query = {
+ name: searchExp
+ };
+
+ if (! R.isNil(envId)) {
+ let env = Environments.findOne({ _id: envId });
+ query = R.merge(query, {
+ environment: env.name
+ });
+ }
+
+ let searchResults = Inventory.find(query, {
+ limit: AUTO_COMPLETE_RESULTS_LIMIT
+ }).fetch();
+
+ searchResults = R.map((inventory) => {
+ console.log('search result');
+ console.log(R.toString(inventory));
+
+ let itemEnv = Environments.findOne({ name: inventory.environment });
+
+ return R.merge(inventory, {
+ _envId: itemEnv._id
+ });
+ }, searchResults);
+
+ return {
+ opCounter: opCounter,
+ searchResults: searchResults,
+ };
+ },
+
+ 'expandNodePath': function(nodeId) {
+ console.log('method server: expandNodePath', R.toString(nodeId));
+
+ //check(nodeId, MongoI);
+ this.unblock();
+
+ let node = Inventory.findOne({ _id: nodeId });
+ if (R.isNil(node)) {
+ console.log('method server: expandNodePath - no node');
+ return null;
+ }
+
+ let idList = R.pipe(R.split('/'), R.drop(2))(node.id_path);
+ let result = R.map((partId) => {
+ return Inventory.findOne({ environment: node.environment, id: partId });
+ }, idList);
+
+ console.log('method server: expandNodePath - results', result);
+ return result;
+ },
+
+ 'inventoryFindNode?type&env&name': function(type, envName, nodeName) {
+ console.log('method server: inventoryFindNode',
+ R.toString(type), R.toString(envName), R.toString(nodeName));
+
+ check(envName, String);
+ check(nodeName, String);
+ this.unblock();
+
+ let query = { type: type, environment: envName, name: nodeName };
+ let node = Inventory.findOne(query);
+
+ return {
+ node: node
+ };
+ },
+
+ 'inventoryFindNode?env&id': function (envName, nodeId) {
+ console.log('method server: inventoryFindNode?env&id',
+ R.toString(envName), R.toString(nodeId));
+
+ check(envName, String);
+ check(nodeId, String);
+ this.unblock();
+
+ let query = { environment: envName, id: nodeId };
+ let node = Inventory.findOne(query);
+
+ return {
+ node: node
+ };
+ },
+
+ 'inventoryFindNode?DataAndAttrs': function (nodeId) {
+ console.log(`method server: inventoryFindNode?DataAndAttrs. ${R.toString(nodeId)}`);
+ //check(nodeId, ObjectId);
+ this.unblock();
+
+ let query = { _id: nodeId };
+ let node = Inventory.findOne(query);
+ let attrsDefs = NodeHoverAttr.findOne({ 'type': node.type });
+ let attributes = calcAttrsForNode(node, attrsDefs);
+
+ return {
+ node: node,
+ nodeName: node.name,
+ attributes: attributes
+ };
+ },
+});
+
+function calcAttrsForNode(node, attrsDefsRec) {
+ if (R.isNil(attrsDefsRec)) {
+ return [];
+ }
+
+ let attrsDefs = attrsDefsRec.attributes;
+
+ return R.reduce((acc, attrDef) => {
+ return R.ifElse(R.isNil,
+ R.always(acc),
+ (attrVal) => R.append(R.assoc(attrDef, attrVal, {}), acc)
+ )(R.prop(attrDef, node));
+ }, [], attrsDefs);
+}
diff --git a/ui/imports/api/inventories/server/publications.js b/ui/imports/api/inventories/server/publications.js
new file mode 100644
index 0000000..f35ff30
--- /dev/null
+++ b/ui/imports/api/inventories/server/publications.js
@@ -0,0 +1,250 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+import { Counts } from 'meteor/tmeasday:publish-counts';
+import { check } from 'meteor/check';
+import * as R from 'ramda';
+
+import { Inventory } from '../inventories.js';
+import { regexEscape } from '/imports/lib/regex-utils';
+
+Meteor.publish('inventory', function () {
+ console.log('server subscribtion to: inventory');
+ //return Inventory.find({$where: 'this.id_path.match('^/WebEX-Mirantis@Cisco/')'});
+ //return Inventory.find({ 'show_in_tree': true });
+ return Inventory.find({});
+});
+
+Meteor.publish('inventory?_id', function (_id) {
+ console.log('server subscribtion to: inventory?_id');
+ console.log('_id:', R.toString(_id));
+
+ return Inventory.find({ _id: _id });
+});
+
+Meteor.publish('inventory?id', function (id) {
+ console.log('server subscribtion to: inventory?id');
+ return Inventory.find({id: id});
+});
+
+Meteor.publish('inventory?env&id', function (env, id) {
+ console.log('server subscribtion to: inventory?env&id');
+ console.log(`-env: ${R.toString(env)}`);
+ console.log(`-id: ${R.toString(id)}`);
+
+ return Inventory.find({environment: env, id: id});
+});
+
+Meteor.publish('inventory?id_path', function (id_path) {
+ console.log('server subscribtion to: inventory?id_path');
+ return Inventory.find({id_path: id_path});
+});
+
+Meteor.publish('inventory?name&env&type', function (name, env, type) {
+ console.log('server subscribtion to: inventory?name&env&type');
+ console.log('-name:', R.toString(name));
+ console.log('-env:', R.toString(env));
+ console.log('-type:', R.toString(type));
+
+ let query = {
+ name: name,
+ environment: env,
+ type: type
+ };
+
+ console.log('query', R.toString(query));
+ return Inventory.find(query);
+});
+
+Meteor.publish('inventory?_id-in', function (idsList) {
+ var query = {
+ _id: { $in: idsList }
+ };
+ /*
+ var counterName = 'inventory?env+type!counter?env=' + env + '&type=' + type;
+
+ console.log('server subscribing to counter: ' + counterName);
+ Counts.publish(this, counterName, Inventory.find(query));
+ */
+ console.log('server subscribtion to: inventory?_id-in');
+ console.log('- id-in: ' + idsList);
+
+ return Inventory.find(query);
+});
+
+Meteor.publish('inventory?env+type', function (env, type) {
+ var query = {
+ environment: env,
+ type: type
+ };
+ var counterName = 'inventory?env+type!counter?env=' + env + '&type=' + type;
+
+ console.log('server subscribing to counter: ' + counterName);
+ Counts.publish(this, counterName, Inventory.find(query));
+
+ console.log('server subscribtion to: inventory-by-env-and-type');
+ console.log('-env: ' + env);
+ console.log('-type: ' + type);
+
+ return Inventory.find(query);
+});
+
+Meteor.publish('inventory?env&binding:host_id&type', function (env, host_id, type) {
+ var query = {
+ environment: env,
+ 'binding:host_id': host_id,
+ type: type
+ };
+ console.log('server subscribtion to: inventory?env&binding:host_id&type');
+ console.log('-env: ' + env);
+ console.log('-binding:host_id: ' + host_id);
+ console.log('-type: ' + type);
+
+ return Inventory.find(query);
+});
+
+Meteor.publish('inventory?env+name', function (env, name) {
+ var query = {
+ name: name,
+ environment: env
+ };
+
+ console.log('server subscribtion to: inventory?env+name');
+ console.log('- name: ' + name);
+ console.log('- env: ' + env);
+
+ return Inventory.find(query);
+});
+
+Meteor.publish('inventory?type+host', function (type, host) {
+ var query = {
+ type: type,
+ host: host
+ };
+/*
+ var counterName = 'inventory?env+type!counter?env=' + env + '&type=' + type;
+
+ console.log('server subscribing to counter: ' + counterName);
+ Counts.publish(this, counterName, Inventory.find(query));
+*/
+
+ console.log('server subscribtion to: inventory?type+host');
+ console.log('- type: ' + type);
+ console.log('- host: ' + host);
+ return Inventory.find(query);
+});
+
+Meteor.publish('inventory?id_path_start&type', function (id_path, type) {
+ check(id_path, String);
+ check(type, String);
+
+ let idPathExp = new RegExp(`^${regexEscape(id_path)}`);
+
+ let query = {
+ id_path: idPathExp,
+ type: type
+ };
+
+ var counterName = 'inventory?id_path_start&type!counter?id_path_start=' +
+ id_path + '&type=' + type;
+
+ console.log('server subscribing to counter: ' + counterName);
+ Counts.publish(this, counterName, Inventory.find(query));
+
+ console.log('server subscribtion to: inventory?id_path_start&type');
+ console.log('-id_path_start: ' + id_path);
+ console.log('-type: ' + type);
+ return Inventory.find(query);
+});
+
+
+Meteor.publish('inventory.children', function (id, type, name, env) {
+ console.log('server subscribtion to: inventory.children');
+ console.log('node id: ' + R.toString(id));
+ console.log('node type: ' + R.toString(type));
+ console.log('node name: ' + R.toString(name));
+ console.log('node env: ' + R.toString(env));
+
+ let query = {
+ $or:
+ [
+ {
+ environment: env,
+ parent_id: id
+ },
+ ]
+ };
+
+ if (R.equals('host_ref', type)) {
+ let realParent = Inventory.findOne({
+ name: name,
+ environment: env,
+ type: 'host'
+ });
+
+ query = R.merge(query, {
+ $or: R.append({
+ environment: env,
+ parent_id: realParent.id
+ }, query.$or)
+ });
+ }
+
+ console.log('query: ', R.toString(query));
+
+ return Inventory.find(query);
+});
+
+Meteor.publish('inventory.first-child', function (id, type, name, env) {
+ console.log('server subscribing to: inventory.first-child');
+ console.log('node id: ' + R.toString(id));
+ console.log('node type: ' + R.toString(type));
+ console.log('node name: ' + R.toString(name));
+ console.log('node env: ' + R.toString(env));
+
+ var counterName = 'inventory.first-child!counter!id=' + id;
+ var query = {
+ $or: [
+ {
+ environment: env,
+ parent_id: id
+ }
+ ]
+ };
+
+ if (R.equals('host_ref', type)) {
+ let realParent = Inventory.findOne({
+ name: name,
+ environment: env,
+ type: 'host'
+ });
+
+ query = R.merge(query, {
+ $or: R.append({
+ environment: env,
+ parent_id: realParent.id
+ }, query.$or)
+ });
+ }
+
+ Counts.publish(this, counterName, Inventory.find(query, { limit: 1 }));
+ console.log('server subscribing to counter: ' + counterName);
+
+// todo: eyaltask: all criteria
+ console.log('query: ', R.toString(query));
+ return Inventory.find(query, { limit: 1 });
+});
+
+Meteor.publish('inventoryByEnv', function (env) {
+ console.log('server subscribtion to: inventoryByEnv');
+ //return Inventory.find({$where: 'this.id_path.match('^/WebEX-Mirantis@Cisco/')'});
+ //return Inventory.find({ 'show_in_tree': true });
+ return Inventory.find({'environment':env});
+});
+
diff --git a/ui/imports/api/link-types/link-types.js b/ui/imports/api/link-types/link-types.js
new file mode 100644
index 0000000..94d6ddd
--- /dev/null
+++ b/ui/imports/api/link-types/link-types.js
@@ -0,0 +1,86 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import * as R from 'ramda';
+import { Constants } from '/imports/api/constants/constants';
+//import { Environments } from '/imports/api/environments/environments';
+
+export const LinkTypes = new Mongo.Collection(
+ 'link_types', { idGeneration: 'MONGO' });
+
+let schema = {
+ _id: { type: { _str: { type: String, regEx: SimpleSchema.RegEx.Id } } },
+ description: {
+ type: String
+ },
+ type: {
+ type: String
+ },
+ endPointA: {
+ type: String,
+ custom: function () {
+ let that = this;
+ let values = Constants.findOne({ name: 'object_types_for_links' }).data;
+
+ if (R.isNil(R.find(R.propEq('value', that.value), values))) {
+ return 'notAllowed';
+ }
+ }
+ },
+ endPointB: {
+ type: String,
+ custom: function () {
+ let that = this;
+ let values = Constants.findOne({ name: 'object_types_for_links' }).data;
+
+ if (R.isNil(R.find(R.propEq('value', that.value), values))) {
+ return 'notAllowed';
+ }
+ }
+ }
+};
+
+let simpleSchema = new SimpleSchema(schema);
+
+simpleSchema.addValidator(function () {
+ let that = this;
+
+ let existing = LinkTypes.findOne({
+ _id: { $ne: that.docId },
+ endPointA: that.field('endPointA').value,
+ endPointB: that.field('endPointB').value
+ });
+
+ if (R.allPass([
+ R.pipe(R.isNil, R.not),
+ R.pipe(R.propEq('_id', that.docId), R.not)
+ ])(existing)) {
+
+ return 'alreadyExists';
+ }
+
+ existing = LinkTypes.findOne({
+ _id: { $ne: that.docId },
+ endPointA: that.field('endPointB').value,
+ endPointB: that.field('endPointA').value
+ });
+
+ if (R.allPass([
+ R.pipe(R.isNil, R.not),
+ R.pipe(R.propEq('_id', that.docId), R.not)
+ ])(existing)) {
+
+ return 'alreadyExists';
+ }
+});
+
+LinkTypes.schema = simpleSchema;
+
+LinkTypes.attachSchema(LinkTypes.schema);
diff --git a/ui/imports/api/link-types/methods.js b/ui/imports/api/link-types/methods.js
new file mode 100644
index 0000000..846c28b
--- /dev/null
+++ b/ui/imports/api/link-types/methods.js
@@ -0,0 +1,114 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { ValidatedMethod } from 'meteor/mdg:validated-method';
+import * as R from 'ramda';
+import { Roles } from 'meteor/alanning:roles';
+
+import { LinkTypes } from './link-types';
+
+export const insert = new ValidatedMethod({
+ name: 'links_types.insert',
+ validate: LinkTypes.simpleSchema()
+ .pick([
+ //'environment',
+ 'description',
+ 'endPointA',
+ 'endPointB',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ //environment,
+ description,
+ endPointA,
+ endPointB
+ }) {
+ if (! Roles.userIsInRole(Meteor.userId(), 'manage-link-types', Roles.GLOBAL_GROUP)) {
+ throw new Meteor.Error('unauthorized for inserting link type');
+ }
+
+ let linkType = LinkTypes.schema.clean({
+ });
+
+ let type = calcTypeFromEndPoints(endPointA, endPointB);
+
+ linkType = R.merge(linkType, {
+ description,
+ endPointA,
+ endPointB,
+ type
+ });
+
+ LinkTypes.insert(linkType);
+ }
+});
+
+export const remove = new ValidatedMethod({
+ name: 'links_types.remove',
+ validate: LinkTypes.simpleSchema()
+ .pick([
+ '_id',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ _id
+ }) {
+ if (! Roles.userIsInRole(Meteor.userId(), 'manage-link-types', Roles.DEFAULT_GROUP)) {
+ throw new Meteor.Error('unauthorized for removing link type');
+ }
+
+ let linkType = LinkTypes.findOne({ _id: _id });
+ console.log('link type for remove: ', linkType);
+ console.log('current user', Meteor.userId());
+
+ LinkTypes.remove({ _id: _id });
+ }
+});
+
+export const update = new ValidatedMethod({
+ name: 'links_types.update',
+ validate: LinkTypes.simpleSchema()
+ .pick([
+ '_id',
+ 'description',
+ 'endPointA',
+ 'endPointB',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ _id,
+ description,
+ endPointA,
+ endPointB
+ }) {
+ if (! Roles.userIsInRole(Meteor.userId(), 'manage-link-types', Roles.DEFAULT_GROUP)) {
+ throw new Meteor.Error('unauthorized for updating link type');
+ }
+
+ let linkType = LinkTypes.findOne({ _id: _id });
+ console.log('link type for update: ', linkType);
+ console.log('current user', Meteor.userId());
+
+ let type = calcTypeFromEndPoints(endPointA, endPointB);
+
+ linkType = R.merge(R.pick([
+ 'description',
+ 'endPointA',
+ 'endPointB',
+ 'type'
+ ], linkType), {
+ description,
+ endPointA,
+ endPointB,
+ type
+ });
+
+ LinkTypes.update({ _id: _id }, { $set: linkType });
+ }
+});
+
+function calcTypeFromEndPoints(endPointA, endPointB) {
+ return `${endPointA}-${endPointB}`;
+}
diff --git a/ui/imports/api/link-types/server/publications.js b/ui/imports/api/link-types/server/publications.js
new file mode 100644
index 0000000..6c6278f
--- /dev/null
+++ b/ui/imports/api/link-types/server/publications.js
@@ -0,0 +1,46 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+import * as R from 'ramda';
+
+import { LinkTypes } from '../link-types.js';
+
+Meteor.publish('link_types', function () {
+ console.log('server subscribtion: link_types');
+
+ //let that = this;
+
+ let query = {};
+ return LinkTypes.find(query);
+});
+
+Meteor.publish('link_types?env*', function (env) {
+ console.log('server subscribtion: link_types?env*');
+ console.log(env);
+
+ //let that = this;
+
+ let query = {};
+ if (! R.isNil(env)) { query = R.assoc('environment', env, query); }
+ console.log('-query: ', query);
+ return LinkTypes.find(query);
+});
+
+Meteor.publish('link_types?_id', function (_id) {
+ console.log('server subscribtion: link_types?_id');
+ console.log(_id);
+
+ //let that = this;
+
+ let query = {
+ _id: _id,
+ };
+ console.log('-query: ', query);
+ return LinkTypes.find(query);
+});
diff --git a/ui/imports/api/links/links.js b/ui/imports/api/links/links.js
new file mode 100644
index 0000000..2baf58c
--- /dev/null
+++ b/ui/imports/api/links/links.js
@@ -0,0 +1,11 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+
+export const Links = new Mongo.Collection('links', { idGeneration: 'MONGO' });
diff --git a/ui/imports/api/links/methods.js b/ui/imports/api/links/methods.js
new file mode 100644
index 0000000..1eda375
--- /dev/null
+++ b/ui/imports/api/links/methods.js
@@ -0,0 +1,8 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/ui/imports/api/links/server/publications.js b/ui/imports/api/links/server/publications.js
new file mode 100644
index 0000000..78d0c26
--- /dev/null
+++ b/ui/imports/api/links/server/publications.js
@@ -0,0 +1,32 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+import { Links } from '../links.js';
+
+Meteor.publish('links', function () {
+ console.log('server subscribtion to: links');
+ //return Inventory.find({$where: 'this.id_path.match('^/WebEX-Mirantis@Cisco/')'});
+ return Links.find({});
+});
+
+Meteor.publish('links?_id-in', function (idsList) {
+ var query = {
+ _id: { $in: idsList}
+ };
+/*
+ var counterName = 'inventory?env+type!counter?env=' + env + '&type=' + type;
+
+ console.log('server subscribing to counter: ' + counterName);
+ Counts.publish(this, counterName, Inventory.find(query));
+*/
+
+ console.log('server subscribtion to: links?_id-in');
+ console.log('- _id-in: ' + idsList);
+ return Links.find(query);
+});
diff --git a/ui/imports/api/messages/messages.js b/ui/imports/api/messages/messages.js
new file mode 100644
index 0000000..5a028b0
--- /dev/null
+++ b/ui/imports/api/messages/messages.js
@@ -0,0 +1,125 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import * as R from 'ramda';
+import { Environments } from '/imports/api/environments/environments';
+import { Constants } from '/imports/api/constants/constants';
+
+export const Messages = new Mongo.Collection('messages', { idGeneration: 'MONGO' });
+
+let schema = {
+ _id: { type: { _str: { type: String, regEx: SimpleSchema.RegEx.Id } } },
+
+ environment: {
+ type: String,
+ custom: function () {
+ let that = this;
+ let env = Environments.findOne({ name: that.value });
+
+ if (R.isNil(env)) {
+ return 'notAllowed';
+ }
+ }
+ },
+
+ id: {
+ type: String
+ },
+
+ viewed: {
+ type: Boolean,
+ defaultValue: false
+ },
+
+ display_context: {
+ type: String
+ },
+
+ message: {
+ type: Object,
+ blackbox: true
+ },
+
+ source_system: {
+ type: String,
+ custom: function () {
+ let that = this;
+ let values = Constants.findOne({ name: 'message_source_systems' }).data;
+
+ if (R.isNil(R.find(R.propEq('value', that.value), values))) {
+ return 'notAllowed';
+ }
+ }
+ },
+
+ level: {
+ type: String
+ },
+
+ timestamp: {
+ type: Date
+ },
+
+ related_object_type: {
+ type: String
+ },
+
+ related_object: {
+ type: String
+ },
+
+ scan_id: {
+ type: Date
+ }
+};
+
+let simpleSchema = new SimpleSchema(schema);
+
+Messages.schema = simpleSchema;
+Messages.attachSchema(Messages.schema);
+
+export function calcIconForMessageLevel(level) {
+ switch (level) {
+ case 'info':
+ return 'notifications';
+ case 'warning':
+ return 'warning';
+ case 'error':
+ return 'error';
+ default:
+ return 'notifications';
+ }
+}
+
+export function lastMessageTimestamp (level, envName) {
+ let query = { level: level };
+ query = R.ifElse(R.isNil, R.always(query), R.assoc('environment', R.__, query))(envName);
+
+ let message = Messages.findOne(query, {
+ sort: { timestamp: -1 }
+ });
+
+ let res = R.path(['timestamp'], message);
+ if (R.isNil(res)) { return null; }
+ return (res instanceof String) ? res : res.toString();
+}
+
+export function calcColorClassForMessagesInfoBox(level) {
+ switch (level) {
+ case 'info':
+ return 'green-text';
+ case 'warning':
+ return 'orange-text';
+ case 'error':
+ return 'red-text';
+ default:
+ return 'green-text';
+ }
+}
diff --git a/ui/imports/api/messages/methods.js b/ui/imports/api/messages/methods.js
new file mode 100644
index 0000000..1eda375
--- /dev/null
+++ b/ui/imports/api/messages/methods.js
@@ -0,0 +1,8 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/ui/imports/api/messages/server/methods.js b/ui/imports/api/messages/server/methods.js
new file mode 100644
index 0000000..119e6b0
--- /dev/null
+++ b/ui/imports/api/messages/server/methods.js
@@ -0,0 +1,49 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import * as R from 'ramda';
+import { Messages } from '/imports/api/messages/messages';
+
+Meteor.methods({
+ 'messages/get?level&env&page&amountPerPage&sortField&sortDirection': function (
+ level, env, page, amountPerPage, sortField, sortDirection) {
+
+ logMethodCall('messages/get?level&env&page&amountPerPage&sortField&sortDirection',
+ {level, env, page, amountPerPage});
+
+ this.unblock();
+
+ let skip = (page - 1) * amountPerPage;
+
+ let query = {};
+ let sortParams = {};
+
+ query = R.ifElse(R.isNil, R.always(query),R.assoc('environment', R.__, query))(env);
+ query = R.ifElse(R.isNil, R.always(query),R.assoc('level', R.__, query))(level);
+
+ sortParams = R.ifElse(R.isNil, R.always(sortParams),
+ R.assoc(R.__, sortDirection, sortParams))(sortField);
+
+ console.log('sort params:', sortParams);
+
+ let qParams = {
+ limit: amountPerPage,
+ skip: skip,
+ sort: sortParams,
+ };
+
+ return Messages.find(query, qParams).fetch();
+ }
+});
+
+function logMethodCall(name, args) {
+ console.log(`method call: ${name}`);
+ R.forEachObjIndexed((value, key) => {
+ console.log(`${key}: ${R.toString(value)}`);
+ }, args);
+}
diff --git a/ui/imports/api/messages/server/publications.js b/ui/imports/api/messages/server/publications.js
new file mode 100644
index 0000000..13c7c50
--- /dev/null
+++ b/ui/imports/api/messages/server/publications.js
@@ -0,0 +1,98 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+//import { Counts } from 'meteor/tmeasday:publish-counts';
+import { Counter } from 'meteor/natestrauser:publish-performant-counts';
+import { Messages } from '../messages.js';
+import * as R from 'ramda';
+
+Meteor.publish('messages', function () {
+ console.log('server subscribtion to: messages');
+ //return Inventory.find({$where: 'this.id_path.match('^/WebEX-Mirantis@Cisco/')'});
+ //return Inventory.find({ 'show_in_tree': true });
+ return Messages.find({});
+});
+
+Meteor.publish('messages?_id', function (_id) {
+ console.log('server subscribtion to: messages?_id');
+ console.log('_id', _id);
+
+ let query = { _id: _id };
+ return Messages.find(query);
+});
+
+Meteor.publish('messages?level', function (level) {
+ var query = {
+ level: level
+ };
+
+ /*
+ var counterName = 'messages?level!counter?' +
+ 'level=' + level;
+
+ console.log('server subscription to: ' + counterName);
+ Counts.publish(this, counterName, Messages.find(query));
+ */
+
+ console.log('server subscribtion to: messages?level');
+ console.log('- level: ' + level);
+ return Messages.find(query);
+});
+
+Meteor.publish('messages?env+level', function (env, level) {
+ var query = {
+ environment: env,
+ level: level
+ };
+ /*
+ var counterName = 'messages?env+level!counter?env=' +
+ env + '&level=' + level;
+
+ console.log('server subscription to: messages - counter');
+ console.log(' - name: ' + counterName);
+ Counts.publish(this, counterName, Messages.find(query));
+ */
+
+ console.log('server subscribtion to: messages');
+ console.log('- env: ' + env);
+ console.log('- level: ' + level);
+ return Messages.find(query);
+});
+
+Meteor.publish('messages/count', function () {
+ const counterName = `messages/count`;
+ console.log(`subscribe - counter: ${counterName}`);
+
+ return new Counter(counterName, Messages.find({ }));
+});
+
+Meteor.publish('messages/count?env', function (env) {
+ const counterName = `messages/count?env`;
+ console.log(`subscribe - counter: ${counterName}`);
+
+ let query = {};
+ query = R.ifElse(R.isNil, R.always(query), R.assoc('environment', R.__, query))(env);
+ return new Counter(counterName, Messages.find(query));
+});
+
+Meteor.publish('messages/count?level', function (level) {
+ const counterName = `messages/count?level=${level}`;
+ console.log(`subscribe - counter: ${counterName}`);
+
+ return new Counter(counterName, Messages.find({ level: level }));
+});
+
+Meteor.publish('messages/count?level&env', function (level, env) {
+ const counterName = `messages/count?level=${level}&env=${env}`;
+ console.log(`subscribe - counter: ${counterName}`);
+
+ let query = { level: level };
+ query = R.ifElse(R.isNil, R.always(query), R.assoc('environment', R.__, query))(env);
+
+ return new Counter(counterName, Messages.find(query)); });
diff --git a/ui/imports/api/migrations/migrations.js b/ui/imports/api/migrations/migrations.js
new file mode 100644
index 0000000..79411b1
--- /dev/null
+++ b/ui/imports/api/migrations/migrations.js
@@ -0,0 +1,20 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { CliqueTypes } from '/imports/api/clique-types/clique-types';
+
+Migrations.add({
+ version: 1,
+ up: () => {
+ console.log('migrating: add clique type constaints for env+name, env+focal_point_type');
+ CliqueTypes._ensureIndex({ environment: 1, name: 1 });
+ CliqueTypes._ensureIndex({ environment: 1, focal_point_type: 1 });
+ },
+ down: () => {
+ }
+});
diff --git a/ui/imports/api/scans/methods.js b/ui/imports/api/scans/methods.js
new file mode 100644
index 0000000..82af820
--- /dev/null
+++ b/ui/imports/api/scans/methods.js
@@ -0,0 +1,55 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { ValidatedMethod } from 'meteor/mdg:validated-method';
+import * as R from 'ramda';
+
+import { Scans } from './scans';
+
+export const insert = new ValidatedMethod({
+ name: 'scans.insert',
+ validate: Scans.simpleSchema()
+ .pick([
+ 'environment',
+ 'object_id',
+ 'log_level',
+ 'clear',
+ 'loglevel',
+ 'scan_only_inventory',
+ 'scan_only_links',
+ 'scan_only_cliques',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ environment,
+ object_id,
+ log_level,
+ clear,
+ loglevel,
+ scan_only_inventory,
+ scan_only_links,
+ scan_only_cliques,
+ }) {
+ let scan = Scans.schema.clean({
+ status: 'pending'
+ });
+ scan = R.merge(scan, {
+ environment,
+ object_id,
+ log_level,
+ clear,
+ loglevel,
+ scan_only_inventory,
+ scan_only_links,
+ scan_only_cliques,
+ submit_timestamp: Date.now()
+ });
+
+ Scans.insert(scan);
+ },
+
+});
diff --git a/ui/imports/api/scans/scans.js b/ui/imports/api/scans/scans.js
new file mode 100644
index 0000000..857c2ea
--- /dev/null
+++ b/ui/imports/api/scans/scans.js
@@ -0,0 +1,159 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import * as R from 'ramda';
+
+import { Constants } from '/imports/api/constants/constants';
+import { StatusesInOperation } from '/imports/api/constants/data/scans-statuses';
+
+export const Scans = new Mongo.Collection('scans', { idGeneration: 'MONGO' });
+
+Scans.schemaRelated = {
+ environment: {
+ label: 'Environment',
+ description: 'Name of environment to scan',
+ disabled: true,
+ },
+ status: {
+ label: 'Status',
+ description: 'Scan lifecycle status',
+ subtype: 'select',
+ options: 'scans_statuses',
+ disabled: true,
+ },
+ object_id: {
+ label: 'Scan specific object',
+ description: 'Object ID',
+ },
+ log_level: {
+ label: 'Log level',
+ description: 'logging level',
+ subtype: 'select',
+ options: 'log_levels',
+ },
+ clear: {
+ label: 'Clear data',
+ description: 'clear all data prior to scanning',
+ },
+ scan_only_inventory: {
+ label: 'Scan only inventory',
+ description: 'do only scan to inventory',
+ },
+ scan_only_links: {
+ label: 'Scan only links',
+ description: 'do only links creation',
+ },
+ scan_only_cliques: {
+ label: 'Scan only cliques',
+ description: 'do only cliques creation',
+ },
+};
+
+Scans.scansOnlyFields = ['scan_only_inventory', 'scan_only_links', 'scan_only_cliques'];
+
+let schema = {
+ _id: { type: { _str: { type: String, regEx: SimpleSchema.RegEx.Id } } },
+ environment: {
+ type: String
+ },
+ status: {
+ type: String,
+ defaultValue: 'draft',
+ custom: function () {
+ let that = this;
+ let statuses = Constants.findOne({ name: 'scans_statuses' }).data;
+
+ if (R.isNil(R.find(R.propEq('value', that.value), statuses))) {
+ return 'notAllowed';
+ }
+ },
+ },
+ object_id: {
+ type: String,
+ optional: true,
+ },
+ log_level: {
+ type: String,
+ defaultValue: 'warning',
+ custom: function () {
+ let that = this;
+ let logLevels = Constants.findOne({ name: 'log_levels' }).data;
+
+ if (R.isNil(R.find(R.propEq('value', that.value), logLevels))) {
+ return 'notAllowed';
+ }
+ },
+ },
+ clear: {
+ type: Boolean,
+ defaultValue: true,
+ },
+ scan_only_inventory: {
+ type: Boolean,
+ defaultValue: false,
+ },
+ scan_only_links: {
+ type: Boolean,
+ defaultValue: false,
+ },
+ scan_only_cliques: {
+ type: Boolean,
+ defaultValue: false,
+ },
+ submit_timestamp: {
+ type: Date,
+ defaultValue: null
+ },
+
+};
+
+Scans.schema = new SimpleSchema(schema);
+Scans.schema.addValidator(function () {
+ let that = this;
+ let env = that.field('environment').value;
+
+ let currentScansCount = Scans.find({
+ environment: env,
+ status: { $in: StatusesInOperation }
+ }).count();
+
+ if (currentScansCount > 0) {
+ throw {
+ isError: true,
+ type: 'notUinque',
+ data: [],
+ message: 'There is already a scan in progress.'
+ };
+ }
+
+ let scanOnlyFields = R.filter( f => that.field(f).value, Scans.scansOnlyFields);
+
+ if(scanOnlyFields.length > 1) {
+ throw {
+ isError: true,
+ type: 'conflict',
+ data: scanOnlyFields,
+ message: 'Only one of the scan only fields can be selected'
+ };
+ }
+
+});
+
+Scans.attachSchema(Scans.schema);
+
+Scans.schemaRelated = R.mapObjIndexed((relatedItem, key) => {
+ return R.merge(relatedItem, {
+ type: schema[key].type
+ });
+
+}, Scans.schemaRelated);
+
+export const subsScansEnvPageAmountSorted = 'scans?env*&page&amount&sortField&sortDirection';
+export const subsScansEnvPageAmountSortedCounter = `${subsScansEnvPageAmountSorted}!counter`;
diff --git a/ui/imports/api/scans/server/methods.js b/ui/imports/api/scans/server/methods.js
new file mode 100644
index 0000000..0fe43c2
--- /dev/null
+++ b/ui/imports/api/scans/server/methods.js
@@ -0,0 +1,44 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { check } from 'meteor/check';
+import * as R from 'ramda';
+import { Scans } from '../scans';
+import { Environments } from '/imports/api/environments/environments';
+
+Meteor.methods({
+ 'scansFind?start-timestamp-before': function (startTimestamp) {
+ console.log('method server: scanFind?start-timestamp-before',
+ R.toString(startTimestamp));
+
+ check(startTimestamp, Date);
+ this.unblock();
+
+ let query = { start_timestamp: { $lt: startTimestamp }};
+ let scan = Scans.findOne(query, {
+ sort: { start_timestamp: -1 }
+ });
+
+ let environment = R.ifElse(
+ R.isNil,
+ R.always(null),
+ (scan) => {
+ console.log('finding environment:', scan.environment);
+ let env = Environments.findOne({ name: scan.environment });
+ console.log('found env:', env);
+ return env;
+ })(scan);
+
+ console.log('found scan', scan);
+
+ return {
+ environment: environment,
+ scan: scan,
+ };
+ },
+});
diff --git a/ui/imports/api/scans/server/publications.js b/ui/imports/api/scans/server/publications.js
new file mode 100644
index 0000000..774fe3d
--- /dev/null
+++ b/ui/imports/api/scans/server/publications.js
@@ -0,0 +1,82 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+import * as R from 'ramda';
+import { Counts } from 'meteor/tmeasday:publish-counts';
+
+import { Scans,
+ subsScansEnvPageAmountSorted,
+ subsScansEnvPageAmountSortedCounter,
+} from '../scans.js';
+
+Meteor.publish('scans?env', function (env_name) {
+ console.log('server subscribtion: scans?env');
+ console.log(env_name);
+
+ return Scans.find({
+ environment: env_name,
+ });
+});
+
+Meteor.publish('scans?env*', function (env) {
+ console.log('server subscribtion: scans?env*');
+ console.log(env);
+
+ //let that = this;
+
+ let query = {};
+ if (! R.isNil(env)) { query = R.assoc('environment', env, query); }
+ console.log('-query: ', query);
+ return Scans.find(query);
+});
+
+Meteor.publish(subsScansEnvPageAmountSorted, function (
+ env, page, amountPerPage, sortField, sortDirection) {
+
+ console.log(`server subscribtion: ${subsScansEnvPageAmountSorted}`);
+ console.log(env);
+ console.log('page: ', page);
+ console.log('amount: ', amountPerPage);
+ console.log('sortField: ', sortField, R.isNil(sortField));
+ console.log('sortDirection: ', sortDirection);
+
+ let skip = (page - 1) * amountPerPage;
+
+ let query = {};
+ if (! R.isNil(env)) { query = R.assoc('environment', env, query); }
+ console.log('-query: ', query);
+ let sortParams = {};
+
+ sortParams = R.ifElse(R.isNil, R.always(sortParams),
+ R.assoc(R.__, sortDirection, sortParams))(sortField);
+
+ console.log('sort params:', sortParams);
+
+ let qParams = {
+ limit: amountPerPage,
+ skip: skip,
+ sort: sortParams,
+ };
+
+ Counts.publish(this, subsScansEnvPageAmountSortedCounter, Scans.find(query), {
+ noReady: true
+ });
+
+ return Scans.find(query, qParams);
+});
+
+Meteor.publish('scans?id', function (id) {
+ console.log('server subscribtion: scans?id');
+ console.log('-id: ', id);
+
+ //let that = this;
+
+ let query = { _id: id };
+ return Scans.find(query);
+});
diff --git a/ui/imports/api/scheduled-scans/methods.js b/ui/imports/api/scheduled-scans/methods.js
new file mode 100644
index 0000000..22f8110
--- /dev/null
+++ b/ui/imports/api/scheduled-scans/methods.js
@@ -0,0 +1,131 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { ValidatedMethod } from 'meteor/mdg:validated-method';
+import * as R from 'ramda';
+
+import { ScheduledScans } from './scheduled-scans';
+
+export const insert = new ValidatedMethod({
+ name: 'scheduled-scans.insert',
+ validate: ScheduledScans.simpleSchema()
+ .pick([
+ 'environment',
+ 'object_id',
+ 'log_level',
+ 'clear',
+ 'loglevel',
+ 'scan_only_inventory',
+ 'scan_only_links',
+ 'scan_only_cliques',
+ 'freq',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ environment,
+ object_id,
+ log_level,
+ clear,
+ loglevel,
+ scan_only_inventory,
+ scan_only_links,
+ scan_only_cliques,
+ freq,
+ }) {
+ let scan = ScheduledScans.schema.clean({ });
+
+ scan = R.merge(scan, {
+ environment,
+ object_id,
+ log_level,
+ clear,
+ loglevel,
+ scan_only_inventory,
+ scan_only_links,
+ scan_only_cliques,
+ freq,
+ submit_timestamp: Date.now()
+ });
+
+ ScheduledScans.insert(scan);
+ },
+
+});
+
+export const update = new ValidatedMethod({
+ name: 'scheduled_scans.update',
+ validate: ScheduledScans.simpleSchema()
+ .pick([
+ '_id',
+ 'environment',
+ 'object_id',
+ 'log_level',
+ 'clear',
+ 'loglevel',
+ 'scan_only_inventory',
+ 'scan_only_links',
+ 'scan_only_cliques',
+ 'freq',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ _id,
+ environment,
+ object_id,
+ log_level,
+ clear,
+ loglevel,
+ scan_only_inventory,
+ scan_only_links,
+ scan_only_cliques,
+ freq,
+ }) {
+ let item = ScheduledScans.findOne({ _id: _id });
+ console.log('scheduled scan for update: ', item);
+
+ item = R.merge(R.pick([
+ 'environment',
+ 'object_id',
+ 'log_level',
+ 'clear',
+ 'loglevel',
+ 'scan_only_inventory',
+ 'scan_only_links',
+ 'scan_only_cliques',
+ 'submit_timestamp',
+ 'freq',
+ ], item), {
+ environment,
+ object_id,
+ log_level,
+ clear,
+ loglevel,
+ scan_only_inventory,
+ scan_only_links,
+ scan_only_cliques,
+ freq,
+ submit_timestamp: Date.now()
+ });
+
+ ScheduledScans.update({ _id: _id }, { $set: item });
+ }
+});
+
+export const remove = new ValidatedMethod({
+ name: 'scheduled_scans.remove',
+ validate: ScheduledScans.simpleSchema()
+ .pick([
+ '_id',
+ ]).validator({ clean: true, filter: false }),
+ run({
+ _id
+ }) {
+ let item = ScheduledScans.findOne({ _id: _id });
+ console.log('scheduled scan for remove: ', item);
+
+ ScheduledScans.remove({ _id: _id });
+ }
+});
diff --git a/ui/imports/api/scheduled-scans/scheduled-scans.js b/ui/imports/api/scheduled-scans/scheduled-scans.js
new file mode 100644
index 0000000..66ae5d1
--- /dev/null
+++ b/ui/imports/api/scheduled-scans/scheduled-scans.js
@@ -0,0 +1,91 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+import { Constants } from '/imports/api/constants/constants';
+import * as R from 'ramda';
+
+export const ScheduledScans = new Mongo.Collection('scheduled_scans', { idGeneration: 'MONGO' });
+
+export const scansOnlyFields = ['scan_only_inventory', 'scan_only_links', 'scan_only_cliques'];
+
+let schema = new SimpleSchema({
+ _id: { type: { _str: { type: String, regEx: SimpleSchema.RegEx.Id } } },
+ environment: {
+ type: String
+ },
+ object_id: {
+ type: String,
+ optional: true,
+ },
+ log_level: {
+ type: String,
+ defaultValue: 'warning',
+ custom: function () {
+ let that = this;
+ let logLevels = Constants.findOne({ name: 'log_levels' }).data;
+
+ if (R.isNil(R.find(R.propEq('value', that.value), logLevels))) {
+ return 'notAllowed';
+ }
+ },
+ },
+ clear: {
+ type: Boolean,
+ defaultValue: true,
+ },
+ scan_only_inventory: {
+ type: Boolean,
+ defaultValue: true,
+ },
+ scan_only_links: {
+ type: Boolean,
+ defaultValue: false,
+ },
+ scan_only_cliques: {
+ type: Boolean,
+ defaultValue: false,
+ },
+ freq: {
+ type: String,
+ defaultValue: 'WEEKLY',
+ },
+ submit_timestamp: {
+ type: Date,
+ defaultValue: null
+ },
+ scheduled_timestamp: {
+ type: Date,
+ defaultValue: null,
+ optional: true,
+ }
+});
+
+schema.addValidator(function () {
+ let that = this;
+ let currentScansOnlyFields =
+ R.reject( f => that.field(f).value == false, scansOnlyFields);
+
+ if(currentScansOnlyFields.length > 1) {
+ throw {
+ isError: true,
+ type: 'conflict',
+ data: currentScansOnlyFields,
+ message: `Only one of the scan only fields can be selected. ${R.toString(currentScansOnlyFields)}`
+ };
+ }
+});
+
+ScheduledScans.schema = schema;
+ScheduledScans.attachSchema(ScheduledScans.schema);
+
+export const subsScheduledScansPageAmountSorted = 'scheduled_scans?page&amount&sortField&sortDirection';
+export const subsScheduledScansPageAmountSortedCounter = `${subsScheduledScansPageAmountSorted}!counter`;
+
+export const subsScheduledScansId = 'scheduled_scans?_id';
diff --git a/ui/imports/api/scheduled-scans/server/methods.js b/ui/imports/api/scheduled-scans/server/methods.js
new file mode 100644
index 0000000..17ed990
--- /dev/null
+++ b/ui/imports/api/scheduled-scans/server/methods.js
@@ -0,0 +1,27 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { check } from 'meteor/check';
+import * as R from 'ramda';
+import { ScheduledScans } from '../scheduled-scans';
+
+Meteor.methods({
+ 'scheduledScansFind?env': function (env) {
+ console.log('method server: scheduledScansFind?env', R.toString(env));
+
+ check(env, String);
+ this.unblock();
+
+ let query = { environment: env };
+ let scheduledScan = ScheduledScans.findOne(query, {});
+
+ return {
+ item: scheduledScan
+ };
+ }
+});
diff --git a/ui/imports/api/scheduled-scans/server/publications.js b/ui/imports/api/scheduled-scans/server/publications.js
new file mode 100644
index 0000000..97acc21
--- /dev/null
+++ b/ui/imports/api/scheduled-scans/server/publications.js
@@ -0,0 +1,60 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+import * as R from 'ramda';
+import { Counts } from 'meteor/tmeasday:publish-counts';
+
+import { ScheduledScans,
+ subsScheduledScansPageAmountSorted,
+ subsScheduledScansPageAmountSortedCounter,
+ subsScheduledScansId,
+} from '../scheduled-scans.js';
+
+Meteor.publish(subsScheduledScansPageAmountSorted, function (
+ page, amountPerPage, sortField, sortDirection) {
+
+ console.log(`server subscribtion: ${subsScheduledScansPageAmountSorted}`);
+ console.log('page: ', page);
+ console.log('amount: ', amountPerPage);
+ console.log('sortField: ', sortField, R.isNil(sortField));
+ console.log('sortDirection: ', sortDirection);
+
+ let skip = (page - 1) * amountPerPage;
+
+ let query = {};
+ console.log('-query: ', query);
+ let sortParams = {};
+
+ sortParams = R.ifElse(R.isNil, R.always(sortParams),
+ R.assoc(R.__, sortDirection, sortParams))(sortField);
+
+ console.log('sort params:', sortParams);
+
+ let qParams = {
+ limit: amountPerPage,
+ skip: skip,
+ sort: sortParams,
+ };
+
+ Counts.publish(this, subsScheduledScansPageAmountSortedCounter, ScheduledScans.find(query), {
+ noReady: true
+ });
+
+ return ScheduledScans.find(query, qParams);
+});
+
+Meteor.publish(subsScheduledScansId, function (_id) {
+ console.log(`server subscribtion: ${subsScheduledScansId}`);
+ console.log('-id: ', _id);
+
+ //let that = this;
+
+ let query = { _id: _id };
+ return ScheduledScans.find(query);
+});
diff --git a/ui/imports/api/simple-schema.init.js b/ui/imports/api/simple-schema.init.js
new file mode 100644
index 0000000..4f5addb
--- /dev/null
+++ b/ui/imports/api/simple-schema.init.js
@@ -0,0 +1,13 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+
+SimpleSchema.messages({
+ 'alreadyExists': 'item already exists'
+});
diff --git a/ui/imports/api/statistics/helpers.js b/ui/imports/api/statistics/helpers.js
new file mode 100644
index 0000000..7cb78e8
--- /dev/null
+++ b/ui/imports/api/statistics/helpers.js
@@ -0,0 +1,64 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import * as R from 'ramda';
+
+export function createGraphQuerySchema(
+ env,
+ object_id,
+ type,
+ flowType,
+ timeStart,
+ timeEnd,
+ sourceMacAddress,
+ destinationMacAddress,
+ sourceIPv4Address,
+ destinationIPv4Address) {
+
+ let schema = {
+ environment: env,
+ object_id: object_id,
+ type: type,
+ flowType: flowType,
+ /*
+ averageArrivalNanoSeconds: {
+ $gte: timeStart,
+ //$lt: timeEnd
+ }
+ */
+ data_arrival_avg: {
+ $gte: timeStart,
+ }
+ };
+
+ if (! R.isNil(timeEnd)) {
+ //schema = R.assocPath(['averageArrivalNanoSeconds', '$lt'], timeEnd, schema);
+ schema = R.assocPath(['data_arrival_avg', '$lt'], timeEnd, schema);
+ }
+
+ switch (flowType) {
+ case 'L2':
+ schema = R.merge(schema, {
+ sourceMacAddress: sourceMacAddress,
+ destinationMacAddress: destinationMacAddress
+ });
+ break;
+
+ case 'L3':
+ schema = R.merge(schema, {
+ sourceIPv4Address: sourceIPv4Address,
+ destinationIPv4Address: destinationIPv4Address
+ });
+ break;
+
+ default:
+ break;
+ }
+
+ return schema;
+}
diff --git a/ui/imports/api/statistics/methods.js b/ui/imports/api/statistics/methods.js
new file mode 100644
index 0000000..23a216d
--- /dev/null
+++ b/ui/imports/api/statistics/methods.js
@@ -0,0 +1,159 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import * as R from 'ramda';
+import { Statistics } from './statistics';
+import { createGraphQuerySchema } from './helpers';
+
+Meteor.methods({
+ 'statistics.flowTypes?env&object_id&type'({ env, object_id, type}) {
+ console.log('subscribe: statistics.flowTypes?env&object_id&type');
+ console.log(`- env: ${env}`);
+ console.log(`- object_id: ${object_id}`);
+ console.log(`- type: ${type}`);
+
+ let pipeline = [{
+ $match: {
+ environment: env,
+ object_id: object_id,
+ type: type
+ }
+ }, {
+ $group: {
+ _id: { flowType: '$flowType' },
+ flowType: { $first: '$flowType' }
+ }
+ }];
+
+ return Statistics.aggregate(pipeline);
+ },
+
+ 'statistics.srcMacAddresses?env&object_id&type&flowType'(
+ { env, object_id, type, flowType }) {
+
+ let pipeline = [{
+ $match: {
+ environment: env,
+ object_id: object_id,
+ type: type,
+ flowType: flowType
+ }
+ }, {
+ $group: {
+ _id: { sourceMacAddress: '$sourceMacAddress' },
+ sourceMacAddress: { $first: '$sourceMacAddress' }
+ }
+ }];
+
+ return Statistics.aggregate(pipeline);
+ },
+
+ 'statistics.dstMacAddresses?env&object_id&type&flowType'(
+ { env, object_id, type, flowType }) {
+
+ let pipeline = [{
+ $match: {
+ environment: env,
+ object_id: object_id,
+ type: type,
+ flowType: flowType
+ }
+ }, {
+ $group: {
+ _id: { destinationMacAddress: '$destinationMacAddress' },
+ destinationMacAddress: { $first: '$destinationMacAddress' }
+ }
+ }];
+
+ return Statistics.aggregate(pipeline);
+ },
+
+ 'statistics.srcIPv4Addresses?env&object_id&type&flow_typw'(
+ { env, object_id, type, flowType }) {
+ let pipeline = [{
+ $match: {
+ environment: env,
+ object_id: object_id,
+ type: type,
+ flowType: flowType
+ }
+ }, {
+ $group: {
+ _id: { sourceIPv4Address: '$sourceIPv4Address' },
+ sourceIPv4Address: { $first: '$sourceIPv4Address' }
+ }
+ }];
+
+ return Statistics.aggregate(pipeline);
+ },
+
+ 'statistics.dstIPv4Addresses?env&object_id&type&flowType'(
+ { env, object_id, type, flowType }) {
+ let pipeline = [{
+ $match: {
+ environment: env,
+ object_id: object_id,
+ type: type,
+ flowType: flowType
+ }
+ }, {
+ $group: {
+ _id: { destinationIPv4Address: '$destinationIPv4Addres' },
+ destinationIPv4Address: { $first: '$destinationIPv4Addres' }
+ }
+ }];
+
+ return Statistics.aggregate(pipeline);
+ },
+
+ 'statistics!graph-frames'({
+ env,
+ object_id,
+ type,
+ flowType,
+ timeStart,
+ timeEnd,
+ sourceMacAddress,
+ destinationMacAddress,
+ sourceIPv4Address,
+ destinationIPv4Address
+ }) {
+ let schema = createGraphQuerySchema(
+ env,
+ object_id,
+ type,
+ flowType,
+ timeStart,
+ timeEnd,
+ sourceMacAddress,
+ destinationMacAddress,
+ sourceIPv4Address,
+ destinationIPv4Address);
+
+ console.log('statistics!graph-frames');
+ console.log(`- env: ${env}`);
+ console.log(`- object_id: ${object_id}`);
+ console.log(`- type: ${type}`);
+ console.log(`- flowType: ${flowType}`);
+ console.log(`- timeStart: ${timeStart}`);
+ console.log(`- timeEnd: ${timeEnd}`);
+ console.log(`- sourceMacAddress: ${sourceMacAddress}`);
+ console.log(`- destinationMacAddress: ${destinationMacAddress}`);
+ console.log(`- sourceIPv4Address: ${sourceIPv4Address}`);
+ console.log(`- destinationIPv4Address: ${destinationIPv4Address}`);
+
+ //let data = Statistics.find(schema).fetch();
+ let data = Statistics.findOne(schema);
+ console.log(`- averageArrivalNanoSeconds: ${R.path([0, 'averageArrivalNanoSeconds'], data)}`);
+
+ return data;
+ }
+});
+
+
+
diff --git a/ui/imports/api/statistics/server/publications.js b/ui/imports/api/statistics/server/publications.js
new file mode 100644
index 0000000..f69be56
--- /dev/null
+++ b/ui/imports/api/statistics/server/publications.js
@@ -0,0 +1,52 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+//import { Counts } from 'meteor/tmeasday:publish-counts';
+import { Statistics } from '../statistics.js';
+import { createGraphQuerySchema } from '../helpers';
+
+Meteor.publish('statistics!graph-frames', function ({
+ env,
+ object_id,
+ type,
+ flowType,
+ timeStart,
+ sourceMacAddress,
+ destinationMacAddress,
+ sourceIPv4Address,
+ destinationIPv4Address
+}) {
+ console.log('server subscribe: statistics?graph-frames');
+
+ let schema = createGraphQuerySchema(
+ env,
+ object_id,
+ type,
+ flowType,
+ timeStart,
+ null,
+ sourceMacAddress,
+ destinationMacAddress,
+ sourceIPv4Address,
+ destinationIPv4Address);
+
+ console.log('statistics!graph-frames');
+ console.log(`- env: ${env}`);
+ console.log(`- object_id: ${object_id}`);
+ console.log(`- type: ${type}`);
+ console.log(`- flowType: ${flowType}`);
+ console.log(`- timeStart: ${timeStart}`);
+ console.log(`- sourceMacAddress: ${sourceMacAddress}`);
+ console.log(`- destinationMacAddress: ${destinationMacAddress}`);
+ console.log(`- sourceIPv4Address: ${sourceIPv4Address}`);
+ console.log(`- destinationIPv4Address: ${destinationIPv4Address}`);
+
+ return Statistics.find(schema);
+});
+
diff --git a/ui/imports/api/statistics/statistics.js b/ui/imports/api/statistics/statistics.js
new file mode 100644
index 0000000..3391933
--- /dev/null
+++ b/ui/imports/api/statistics/statistics.js
@@ -0,0 +1,14 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+//import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+//import * as R from 'ramda';
+
+export const Statistics = new Mongo.Collection(
+ 'statistics', { idGeneration: 'MONGO' });
diff --git a/ui/imports/api/supported_environments/methods.js b/ui/imports/api/supported_environments/methods.js
new file mode 100644
index 0000000..1eda375
--- /dev/null
+++ b/ui/imports/api/supported_environments/methods.js
@@ -0,0 +1,8 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/ui/imports/api/supported_environments/server/publications.js b/ui/imports/api/supported_environments/server/publications.js
new file mode 100644
index 0000000..8fef880
--- /dev/null
+++ b/ui/imports/api/supported_environments/server/publications.js
@@ -0,0 +1,17 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Meteor } from 'meteor/meteor';
+import { SupportedEnvironments,
+ subsNameSupportedEnvs
+} from '../supported_environments.js';
+
+Meteor.publish(subsNameSupportedEnvs, function () {
+ console.log(`server subscribtion to: ${subsNameSupportedEnvs}`);
+ return SupportedEnvironments.find({});
+});
diff --git a/ui/imports/api/supported_environments/supported_environments.js b/ui/imports/api/supported_environments/supported_environments.js
new file mode 100644
index 0000000..55c5745
--- /dev/null
+++ b/ui/imports/api/supported_environments/supported_environments.js
@@ -0,0 +1,49 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others /
+// /
+// All rights reserved. This program and the accompanying materials /
+// are made available under the terms of the Apache License, Version 2.0 /
+// which accompanies this distribution, and is available at /
+// http://www.apache.org/licenses/LICENSE-2.0 /
+/////////////////////////////////////////////////////////////////////////////////////////
+import { Mongo } from 'meteor/mongo';
+import * as R from 'ramda';
+
+export const SupportedEnvironments = new Mongo.Collection(
+ 'supported_environments', { idGeneration: 'MONGO' });
+
+export const subsNameSupportedEnvs = 'supported-environments';
+
+export function isMonitoringSupported(distribution, type_drivers, mechanism_drivers) {
+ console.log('isMonitoringSupported');
+ console.log(`distribution: ${R.toString(distribution)}`);
+ console.log(`type_drivers: ${R.toString(type_drivers)}`);
+ console.log(`mechanism_drivers: ${R.toString(mechanism_drivers)}`);
+
+ let result = SupportedEnvironments.find({
+ 'environment.distribution': distribution,
+ 'environment.type_drivers': type_drivers,
+ 'environment.mechanism_drivers': { $in: mechanism_drivers },
+ 'features.monitoring': true
+ }).count() > 0;
+
+ console.log(`result: ${R.toString(result)}`);
+ return result;
+}
+
+export function isListeningSupported(distribution, type_drivers, mechanism_drivers) {
+ console.log('isListeningSupported');
+ console.log(`distribution: ${R.toString(distribution)}`);
+ console.log(`type_drivers: ${R.toString(type_drivers)}`);
+ console.log(`mechanism_drivers: ${R.toString(mechanism_drivers)}`);
+
+ let result = SupportedEnvironments.find({
+ 'environment.distribution': distribution,
+ 'environment.type_drivers': type_drivers,
+ 'environment.mechanism_drivers': { $in: mechanism_drivers },
+ 'features.listening': true
+ }).count() > 0;
+
+ console.log(`result: ${R.toString(result)}`);
+ return result;
+}