103 Commits
database ... p2

Author SHA1 Message Date
Manuel Romero
b88e356536 Scenarios edit from admin 2020-05-04 13:41:36 +02:00
Manuel Romero
9292bba09a Admin sections pills 2020-05-04 12:32:57 +02:00
Manuel Romero
8b1e978e7c Merge branch 'master' into p2 2020-05-04 11:08:13 +02:00
Manuel Romero
24b1252911 fix start vms 2020-05-04 09:22:05 +02:00
Manuel Romero
edece4f91c Scenarios in admin 2020-05-03 21:53:36 +02:00
Manuel Romero
b84d6631b3 Merge branch 'master' into p2 2020-04-30 16:27:17 +02:00
Manuel Romero
73a427bb09 Disable scenarios 2020-04-30 15:34:06 +02:00
Manuel Romero
0063e27bb2 only populates for user 2020-04-30 13:25:59 +02:00
Manuel Romero
24708f2bd8 Api-docs only for admins 2020-04-30 13:14:00 +02:00
Manuel Romero
317266e09a getById instead of getSingle 2020-04-30 13:08:00 +02:00
Manuel Romero
a9ad3d34f9 user model less methods 2020-04-30 13:02:41 +02:00
Manuel Romero
2b2554e4f7 Security on provisions 2020-04-30 12:56:27 +02:00
Manuel Romero
343c14d846 Improvements 2020-04-30 12:46:31 +02:00
Manuel Romero
fd158a2e56 paging provisions 2020-04-29 16:14:11 +02:00
Manuel Romero
dd542457de polish ui 2020-04-29 13:59:32 +02:00
Manuel Romero
74cacd2854 Info 2020-04-28 14:06:29 +02:00
Manuel Romero
5fada4feed Also fixed send email 2020-04-28 14:00:44 +02:00
Manuel Romero
4ef3df4d1d info showing new sizing 2020-04-28 12:53:17 +02:00
Manuel Romero
d7ba6dca3b Change order 2020-04-28 11:28:29 +02:00
Manuel Romero
0702c2a058 Test fix 2020-04-28 11:13:22 +02:00
Manuel Romero
3fb9c3b522 ImageID 2020-04-28 10:58:35 +02:00
Manuel Romero
22d7b724a1 No needed field 2020-04-28 10:08:37 +02:00
Manuel Romero
9a627d4927 New way to size provisions 2020-04-28 10:05:32 +02:00
Manuel Romero
c8fddfe18d Adding more comples provision details for vms 2020-04-27 18:17:00 +02:00
Manuel Romero
805a93dc60 Using vmImage 2020-04-27 12:20:03 +02:00
Manuel Romero
f65391ef6d fix destroy 2020-04-27 12:01:35 +02:00
Manuel Romero
6ed9bedae0 UI and provision with Image 2020-04-27 12:00:35 +02:00
Manuel Romero
6b4757df36 Green text 2020-04-26 11:11:24 +02:00
Manuel Romero
e1970e716b More tooltips 2020-04-26 11:04:14 +02:00
Manuel Romero
b996cf004c Adding provision description 2020-04-26 10:58:08 +02:00
Manuel Romero
92f325a67b les logs 2020-04-25 11:15:16 +02:00
Manuel Romero
81919c8e9d Add notification 2020-04-25 11:10:01 +02:00
Manuel Romero
2a3eccfe30 fix 2020-04-24 15:51:51 +02:00
Manuel Romero
14158d3f60 fix scenarios model 2020-04-24 15:23:19 +02:00
Manuel Romero
fbec2def38 remove no needed templates 2020-04-24 13:58:37 +02:00
Manuel Romero
b610a376f1 Name gen image 2020-04-24 13:40:17 +02:00
Manuel Romero
d9f7eff0f2 Set random image name 2020-04-24 13:30:20 +02:00
Manuel Romero
8399f18e11 Default values 2020-04-24 13:25:42 +02:00
Manuel Romero
067dc2c7da newImageName field 2020-04-24 13:21:27 +02:00
Manuel Romero
a7f8c42983 faq typos 2020-04-24 13:19:52 +02:00
Manuel Romero
8d041ee600 Create image 2020-04-24 13:18:53 +02:00
Manuel Romero
186fb52ac1 fix 2020-04-23 11:01:55 +02:00
Manuel Romero
2814c92a2e stop5 2020-04-23 10:47:19 +02:00
Manuel Romero
fb5abbdee0 process stop and destroy 2020-04-23 10:38:54 +02:00
Manuel Romero
6c29373a0f Destroy email to actual owner 2020-04-23 09:42:23 +02:00
Manuel Romero
ece1183e55 Typo 2020-04-22 16:37:21 +02:00
Manuel Romero
54973c7306 Typo 2020-04-22 16:35:59 +02:00
Manuel Romero
cd99761892 using stoppedFrom 2020-04-22 16:27:35 +02:00
Manuel Romero
e764eac338 stoppedFrom in provision model 2020-04-22 16:10:02 +02:00
Manuel Romero
663e1f577d stoppedFrom 2020-04-22 16:07:36 +02:00
Manuel Romero
2b29df5164 fix 2020-04-22 16:02:27 +02:00
Manuel Romero
a6dc7dacdd Autodestroy 2020-04-22 15:36:02 +02:00
Manuel Romero
818114a701 faq local 2020-04-21 18:12:43 +02:00
Manuel Romero
a42eb85772 fix 2020-04-20 13:19:36 +02:00
Manuel Romero
130e0d8de9 fix 2020-04-20 13:18:47 +02:00
Manuel Romero
8a770ec0fa fix 2020-04-20 13:18:14 +02:00
Manuel Romero
7d15711bb2 fixes 2020-04-20 13:16:41 +02:00
Manuel Romero
39e3d777bc fix 2020-04-20 13:07:16 +02:00
Manuel Romero
8b6dac3216 new faq 2020-04-19 12:06:17 +02:00
Manuel Romero
9f412be93c new faq 2020-04-19 12:02:14 +02:00
Manuel Romero
0b43901c11 Do not show auto stop time if is deleted 2020-04-19 11:32:27 +02:00
Manuel Romero
c15fa47244 faq 2020-04-17 11:20:41 +02:00
Manuel Romero
8de21b4bbf faq 2020-04-17 11:11:47 +02:00
Manuel Romero
3c3e987c62 readme 2020-04-17 10:01:52 +02:00
Manuel Romero
f2d2d740d7 Test faq 2020-04-17 10:00:41 +02:00
Manuel Romero
8ff19f260a SOme fixes to docker-compose yaml 2020-04-17 09:58:07 +02:00
Manuel Romero
5a8056adee Adding FAQ 2020-04-17 09:48:20 +02:00
Manuel Romero
665871ba78 is real 2020-04-16 17:17:13 +02:00
Manuel Romero
1e937414d3 Extend pendingNextAction to null 2020-04-16 17:04:10 +02:00
Manuel Romero
356e1a3827 Notifications 2020-04-16 17:01:35 +02:00
Manuel Romero
98f1f1c08f Param RUNNING_PERIOD 2020-04-16 14:39:40 +02:00
Manuel Romero
c7f50a776b Negative time 2020-04-16 14:17:02 +02:00
Manuel Romero
a7b7551b52 Vms auto stop in admin 2020-04-16 13:39:15 +02:00
Manuel Romero
8123a7a850 Do not show destroy in admin 2020-04-16 13:13:30 +02:00
Manuel Romero
7fbb3318e9 Fixed runnign from created 2020-04-16 12:54:20 +02:00
Manuel Romero
379f373b86 fix typo 2020-04-16 12:46:21 +02:00
Manuel Romero
30825a6271 Not async 2020-04-16 12:28:49 +02:00
Manuel Romero
45ad35308e fix 2020-04-16 11:58:32 +02:00
Manuel Romero
b2fe88b6c7 Deallocate/start async functions 2020-04-16 11:44:13 +02:00
Manuel Romero
a8f111c463 Time to stop 2020-04-16 11:12:09 +02:00
Manuel Romero
70e5113ef9 sendemail 2020-04-15 18:34:01 +02:00
Manuel Romero
fae6276267 fix 2020-04-15 18:06:47 +02:00
Manuel Romero
ad08d71da1 Extend button 2020-04-15 17:13:28 +02:00
Manuel Romero
fd29c6c3ca checkstop 2020-04-15 16:10:12 +02:00
Manuel Romero
c1caefc207 Time running 2020-04-15 14:20:00 +02:00
Manuel Romero
5149a2c5e1 fix timeRunning 2020-04-15 10:40:11 +02:00
Manuel Romero
cb51334761 time running 2020-04-15 09:08:57 +02:00
Manuel Romero
45281587f7 stop5.js 2020-04-08 18:50:15 +02:00
Manuel Romero
1131a8607d new version 2020-04-08 16:49:07 +02:00
Manuel Romero
1ced9bbc9e trigger CDCI 2020-04-08 16:44:31 +02:00
Manuel Romero
353355a101 Added API Key authentication to API 2020-04-08 16:12:21 +02:00
Manuel Romero
ca081f0bdd Some enhancements 2020-04-08 15:02:21 +02:00
Manuel Romero
629c2a03da Using openapi300 2020-04-08 13:02:45 +02:00
Manuel Romero
ab15a02d54 Admin scenario 2020-04-07 16:45:26 +02:00
Manuel Romero
17a93838f9 More UI stuff 2020-04-07 16:16:11 +02:00
Manuel Romero
e3802d2af2 build 2020-04-07 10:09:10 +02:00
Manuel Romero
7cbe9dbf90 Fix message 2020-04-02 10:51:43 +02:00
Manuel Romero
6c60ccd08f appgw link if provisioned 2020-04-02 10:40:37 +02:00
Manuel Romero
14daf2fa8e Fix 2020-04-02 08:06:33 +02:00
Manuel Romero
0744654d3e Adding isWafPolicyAppGw 2020-04-02 08:02:03 +02:00
Manuel Romero
0ae75f82dc Confirm modal 2020-03-29 22:25:10 +02:00
Manuel Romero
872f07f043 delete old String fields and set index 2020-03-28 15:59:39 +01:00
Manuel Romero
19c22fbfec disable databse transform 2020-03-28 15:42:54 +01:00
139 changed files with 4242 additions and 1419 deletions

View File

@@ -12,6 +12,7 @@
}
```
## Run it
```shell
@@ -54,8 +55,7 @@ UI: http://localhost:8081
Basic-Auth: qlik / Qlik1234
Database: qmi
http://localhost:8081/db/qmi/
Database: qmicloud
## API / Swagger API-DOCS
It shows available endpoints

View File

@@ -27,18 +27,23 @@
"src/assets"
],
"styles": [
"src/styles.scss",
"node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss",
"node_modules/@fortawesome/fontawesome-free/scss/solid.scss",
"node_modules/@fortawesome/fontawesome-free/scss/regular.scss",
"node_modules/@fortawesome/fontawesome-free/scss/brands.scss",
"node_modules/angular-bootstrap-md/assets/scss/bootstrap/bootstrap.scss",
"node_modules/angular-bootstrap-md/assets/scss/mdb.scss",
"node_modules/animate.css/animate.css"
"node_modules/animate.css/animate.css",
"node_modules/prismjs/themes/prism.css",
"src/styles.scss"
],
"scripts": [
"node_modules/chart.js/dist/Chart.js",
"node_modules/hammerjs/hammer.min.js"
"node_modules/hammerjs/hammer.min.js",
"node_modules/marked/lib/marked.js",
"node_modules/prismjs/prism.js",
"node_modules/prismjs/plugins/line-highlight/prism-line-highlight.js",
"node_modules/prismjs/plugins/line-numbers/prism-line-numbers.js"
]
},
"configurations": {

View File

@@ -10,118 +10,42 @@ var __metadata = (this && this.__metadata) || function (k, v) {
import { Component } from '@angular/core';
import { UsersService } from '../services/users.service';
import { ProvisionsService } from '../services/provisions.service';
import { timer } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { AuthGuard } from '../services/auth.guard';
import { ScenariosService } from '../services/scenarios.service';
var AdminComponent = /** @class */ (function () {
function AdminComponent(_usersService, _provisionsService, _auth) {
var _this = this;
function AdminComponent(_usersService, _provisionsService, _scenariosService) {
this._usersService = _usersService;
this._provisionsService = _provisionsService;
this._auth = _auth;
this.logShow = false;
this.logstype = 'provision';
this.selectedprov = null;
this._auth.getUserInfo().subscribe(function (value) {
_this.currentUser = value;
});
this._scenariosService = _scenariosService;
this.filter = {
showDestroyed: false
};
}
AdminComponent.prototype._fillUser = function (pair) {
var _this = this;
pair['0'].forEach(function (prov) {
var foundDes = _this.users.filter(function (u) {
return u._id.toString() === prov.userId.toString();
});
if (foundDes.length) {
prov.user = foundDes[0].displayName;
}
});
};
AdminComponent.prototype._getUsers = function () {
};
AdminComponent.prototype.ngOnInit = function () {
var _this = this;
this._usersService.getUsers().subscribe(function (res) {
_this.users = res;
_this.subscription = timer(0, 5000).pipe(switchMap(function () { return _this._provisionsService.getCombinedProvisionsAdmin(); })).subscribe(function (pair) {
_this._provisionsService.composePair(pair);
_this._fillUser(pair);
_this.destroys = pair[1];
_this.provisions = pair[0];
});
});
};
AdminComponent.prototype._refresh = function () {
var _this = this;
this.instantSubs = this._provisionsService.getCombinedProvisionsAdmin().subscribe(function (pair) {
_this._provisionsService.composePair(pair);
_this._fillUser(pair);
_this.destroys = pair[1];
_this.provisions = pair[0];
_this.instantSubs.unsubscribe();
var usersSub = this._usersService.getUsers().subscribe(function (res) {
usersSub.unsubscribe();
_this.users = res.results;
});
};
/*private _refresh(): void {
this.provisions = null;
var instantSubs = this._provisionsService.getProvisionsAdmin(this.filterParams).subscribe( provisions=>{
instantSubs.unsubscribe();
this._process(provisions.results);
});
}*/
AdminComponent.prototype.ngOnDestroy = function () {
this.subscription.unsubscribe();
if (this.instantSubs) {
this.instantSubs.unsubscribe();
if (this.subscription) {
this.subscription.unsubscribe();
}
};
AdminComponent.prototype.del = function (provision) {
var _this = this;
this._provisionsService.delProvision(provision._id.toString(), provision.userId).subscribe(function (res) {
console.log("Done!", res);
_this._refresh();
});
};
AdminComponent.prototype.destroy = function (provision) {
var _this = this;
this._provisionsService.newDestroy({ "id": provision._id.toString() }, provision.userId).subscribe(function (res) {
console.log("Done!", res);
_this._refresh();
});
};
AdminComponent.prototype.showLogs = function ($event, provision, type) {
$event.preventDefault();
$event.stopPropagation();
this.logstype = type;
this.logShow = false;
this.selectedprov = provision;
this.logShow = true;
};
AdminComponent.prototype.onLogsClose = function ($event) {
this.selectedprov = null;
this.logShow = false;
};
AdminComponent.prototype.onStartProvision = function ($event) {
console.log("onStartProvision");
this._refresh();
};
AdminComponent.prototype.setAdmin = function (user) {
var _this = this;
this._usersService.updateUser(user._id, { "role": "admin" }).subscribe(function (res1) {
console.log("Updated", res1);
_this._usersService.getUsers().subscribe(function (res) {
_this.users = res;
});
});
};
AdminComponent.prototype.removeAdmin = function (user) {
var _this = this;
this._usersService.updateUser(user._id, { "role": null }).subscribe(function (res1) {
console.log("Updated", res1);
_this._usersService.getUsers().subscribe(function (res) {
_this.users = res;
});
});
};
AdminComponent = __decorate([
Component({
selector: 'app-admin',
templateUrl: './admin.component.html',
styleUrls: ['./admin.component.scss']
}),
__metadata("design:paramtypes", [UsersService, ProvisionsService, AuthGuard])
__metadata("design:paramtypes", [UsersService, ProvisionsService, ScenariosService])
], AdminComponent);
return AdminComponent;
}());

View File

@@ -1 +1 @@
{"version":3,"file":"admin.component.js","sourceRoot":"","sources":["../../../../../src/app/admin/admin.component.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"admin.component.js","sourceRoot":"","sources":["../../../../../src/app/admin/admin.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAU,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAOjE;IAaE,wBAAqB,aAA2B,EAAU,kBAAqC,EAAU,iBAAmC;QAAvH,kBAAa,GAAb,aAAa,CAAc;QAAU,uBAAkB,GAAlB,kBAAkB,CAAmB;QAAU,sBAAiB,GAAjB,iBAAiB,CAAkB;QAL5I,WAAM,GAAG;YACP,aAAa,EAAG,KAAK;SACtB,CAAC;IAG+I,CAAC;IAIlJ,iCAAQ,GAAR;QAAA,iBAOC;QALC,IAAI,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAE,UAAA,GAAG;YACzD,QAAQ,CAAC,WAAW,EAAE,CAAC;YACvB,KAAI,CAAC,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC;QAC3B,CAAC,CAAC,CAAC;IAEL,CAAC;IAED;;;;;;OAMG;IAEH,oCAAW,GAAX;QACE,IAAK,IAAI,CAAC,YAAY,EAAG;YACvB,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;SACjC;IACH,CAAC;IAtCU,cAAc;QAL1B,SAAS,CAAC;YACT,QAAQ,EAAE,WAAW;YACrB,WAAW,EAAE,wBAAwB;YACrC,SAAS,EAAE,CAAC,wBAAwB,CAAC;SACtC,CAAC;yCAcoC,YAAY,EAA8B,iBAAiB,EAA6B,gBAAgB;OAbjI,cAAc,CAiD1B;IAAD,qBAAC;CAAA,AAjDD,IAiDC;SAjDY,cAAc"}

View File

@@ -0,0 +1,43 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Component, ViewChild, ElementRef } from '@angular/core';
import { AlertService } from '../services/alert.service';
var AlertComponent = /** @class */ (function () {
function AlertComponent(_alertService) {
this._alertService = _alertService;
this.alert = null;
}
AlertComponent.prototype.ngOnInit = function () {
this.subscription = this._alertService.getAlertEmitter().subscribe(function (data) {
this.alert = data;
}.bind(this));
};
AlertComponent.prototype.ngOnDestroy = function () {
this.subscription.unsubscribe();
};
AlertComponent.prototype.closeAlert = function () {
this.alert = null;
};
__decorate([
ViewChild('qmialert', { static: true }),
__metadata("design:type", ElementRef)
], AlertComponent.prototype, "alertEl", void 0);
AlertComponent = __decorate([
Component({
selector: 'qmi-alert',
templateUrl: './alert.component.html',
styleUrls: ['./alert.component.scss']
}),
__metadata("design:paramtypes", [AlertService])
], AlertComponent);
return AlertComponent;
}());
export { AlertComponent };
//# sourceMappingURL=alert.component.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"alert.component.js","sourceRoot":"","sources":["../../../../../src/app/alert/alert.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAqB,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAQzD;IAME,wBAAoB,aAA2B;QAA3B,kBAAa,GAAb,aAAa,CAAc;QAF/C,UAAK,GAAS,IAAI,CAAC;IAE+B,CAAC;IAEnD,iCAAQ,GAAR;QACE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,CAAC,SAAS,CAAC,UAAS,IAAI;YAC5E,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACtB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChB,CAAC;IAED,oCAAW,GAAX;QACE,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;IAClC,CAAC;IAED,mCAAU,GAAV;QACI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACtB,CAAC;IAlBwC;QAAxC,SAAS,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;kCAAU,UAAU;mDAAC;IAFlD,cAAc;QAL1B,SAAS,CAAC;YACT,QAAQ,EAAE,WAAW;YACrB,WAAW,EAAE,wBAAwB;YACrC,SAAS,EAAE,CAAC,wBAAwB,CAAC;SACtC,CAAC;yCAOmC,YAAY;OANpC,cAAc,CAsB1B;IAAD,qBAAC;CAAA,AAtBD,IAsBC;SAtBY,cAAc"}

View File

@@ -0,0 +1,40 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Component } from '@angular/core';
import { MDBModalRef } from 'angular-bootstrap-md';
import { Subject } from 'rxjs';
var ModalConfirmComponent = /** @class */ (function () {
function ModalConfirmComponent(modalRef) {
this.modalRef = modalRef;
this.action = new Subject();
}
ModalConfirmComponent.prototype.ngOnInit = function () {
if (!this.info.buttonColor) {
this.info.buttonColor = "danger";
}
};
ModalConfirmComponent.prototype.ngOnDestroy = function () {
};
ModalConfirmComponent.prototype.confirm = function () {
this.action.next();
this.modalRef.hide();
};
ModalConfirmComponent = __decorate([
Component({
selector: 'qmi-modalconfirm',
templateUrl: './confirm.component.html',
styleUrls: ['./confirm.component.scss']
}),
__metadata("design:paramtypes", [MDBModalRef])
], ModalConfirmComponent);
return ModalConfirmComponent;
}());
export { ModalConfirmComponent };
//# sourceMappingURL=confirm.component.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"confirm.component.js","sourceRoot":"","sources":["../../../../../src/app/alert/confirm.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAA4B,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAO/B;IAKE,+BAAoB,QAAqB;QAArB,aAAQ,GAAR,QAAQ,CAAa;QAFzC,WAAM,GAAiB,IAAI,OAAO,EAAE,CAAC;IAEQ,CAAC;IAE9C,wCAAQ,GAAR;QACE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YAC1B,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;SAClC;IACH,CAAC;IAED,2CAAW,GAAX;IAEA,CAAC;IAED,uCAAO,GAAP;QACI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACnB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IApBU,qBAAqB;QALjC,SAAS,CAAC;YACT,QAAQ,EAAE,kBAAkB;YAC5B,WAAW,EAAE,0BAA0B;YACvC,SAAS,EAAE,CAAC,0BAA0B,CAAC;SACxC,CAAC;yCAM8B,WAAW;OAL9B,qBAAqB,CAsBjC;IAAD,4BAAC;CAAA,AAtBD,IAsBC;SAtBY,qBAAqB"}

View File

@@ -0,0 +1,31 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Component } from '@angular/core';
import { MDBModalRef } from 'angular-bootstrap-md';
var ModalInfoComponent = /** @class */ (function () {
function ModalInfoComponent(modalRef) {
this.modalRef = modalRef;
}
ModalInfoComponent.prototype.ngOnInit = function () {
};
ModalInfoComponent.prototype.ngOnDestroy = function () {
};
ModalInfoComponent = __decorate([
Component({
selector: 'qmi-modalinfo',
templateUrl: './modalinfo.component.html',
styleUrls: ['./modalinfo.component.scss']
}),
__metadata("design:paramtypes", [MDBModalRef])
], ModalInfoComponent);
return ModalInfoComponent;
}());
export { ModalInfoComponent };
//# sourceMappingURL=modalinfo.component.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"modalinfo.component.js","sourceRoot":"","sources":["../../../../../src/app/alert/modalinfo.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAA4B,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAOnD;IAIE,4BAAoB,QAAqB;QAArB,aAAQ,GAAR,QAAQ,CAAa;IAAI,CAAC;IAE9C,qCAAQ,GAAR;IAEA,CAAC;IAED,wCAAW,GAAX;IAEA,CAAC;IAZU,kBAAkB;QAL9B,SAAS,CAAC;YACT,QAAQ,EAAE,eAAe;YACzB,WAAW,EAAE,4BAA4B;YACzC,SAAS,EAAE,CAAC,4BAA4B,CAAC;SAC1C,CAAC;yCAK8B,WAAW;OAJ9B,kBAAkB,CAc9B;IAAD,yBAAC;CAAA,AAdD,IAcC;SAdY,kBAAkB"}

View File

@@ -0,0 +1,93 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Component } from '@angular/core';
import { MDBModalRef } from 'angular-bootstrap-md';
import { Subject } from 'rxjs';
import { ScenariosService } from '../services/scenarios.service';
var NewProvisionConfirmComponent = /** @class */ (function () {
function NewProvisionConfirmComponent(modalRef, _scenariosService) {
this.modalRef = modalRef;
this._scenariosService = _scenariosService;
this.action = new Subject();
this.sendData = {
description: "",
servers: null
};
this.selectedProductVersion = {};
this.selectedVmType = {};
this.selectedNodeCount = {};
this.servers = {};
}
NewProvisionConfirmComponent.prototype.ngOnInit = function () {
var _this = this;
this.vmTypesSub = this._scenariosService.getScenarioVmtypes().subscribe(function (res) {
_this.vmTypes = res.results;
if (_this.scenario.availableProductVersions.length) {
_this.scenario.availableProductVersions.forEach(function (server) {
if (server.vmTypeDefault) {
_this.selectedVmType[server.index] = server.vmTypeDefault;
}
if (server.nodeCount) {
_this.selectedNodeCount[server.index] = server.nodeCount;
}
if (server.versions && server.versions.length) {
var lastIndex = server.versions.length - 1;
_this.selectedProductVersion[server.index] = server.productVersionDefault ? server.productVersionDefault : server.versions[lastIndex].name;
}
});
}
_this.vmTypesSub.unsubscribe();
});
};
NewProvisionConfirmComponent.prototype.ngOnDestroy = function () {
};
NewProvisionConfirmComponent.prototype.confirm = function () {
var _this = this;
if (!this.sendData.description || this.sendData.description.trim() === "") {
return;
}
this.sendData.servers = {};
var _loop_1 = function (key) {
if (!this_1.sendData.servers[key]) {
this_1.sendData.servers[key] = {};
}
if (this_1.selectedVmType[key]) {
this_1.sendData.servers[key].vmType = this_1.selectedVmType[key];
}
if (this_1.selectedNodeCount[key]) {
this_1.sendData.servers[key].nodeCount = this_1.selectedNodeCount[key];
}
this_1.scenario.availableProductVersions.forEach(function (server) {
server.versions.forEach(function (v) {
if (v.name === _this.selectedProductVersion[key]) {
_this.sendData.servers[key].version = v;
}
});
});
};
var this_1 = this;
for (var key in this.selectedVmType) {
_loop_1(key);
}
this.action.next(this.sendData);
this.modalRef.hide();
};
NewProvisionConfirmComponent = __decorate([
Component({
selector: 'qmi-new-provision',
templateUrl: './new-provision.component.html',
styleUrls: ['./new-provision.component.scss']
}),
__metadata("design:paramtypes", [MDBModalRef, ScenariosService])
], NewProvisionConfirmComponent);
return NewProvisionConfirmComponent;
}());
export { NewProvisionConfirmComponent };
//# sourceMappingURL=new-provision.component.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"new-provision.component.js","sourceRoot":"","sources":["../../../../../src/app/alert/new-provision.component.ts"],"names":[],"mappings":"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"}

View File

@@ -10,8 +10,10 @@ import { ProvisionsComponent } from './provisions/provisions.component';
import { AdminComponent } from './admin/admin.component';
import { HomeComponent } from './home/home.component';
import { AuthGuard } from './services/auth.guard';
import { FaqComponent } from './faq/faq.component';
var routes = [
{ path: 'home', component: HomeComponent },
{ path: 'faq', component: FaqComponent },
{ path: 'provisions', component: ProvisionsComponent, canActivate: [AuthGuard] },
{ path: 'admin', component: AdminComponent, canActivate: [AuthGuard] },
{ path: '',

View File

@@ -1 +1 @@
{"version":3,"file":"app-routing.module.js","sourceRoot":"","sources":["../../../../src/app/app-routing.module.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAU,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAQ,mCAAmC,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAQ,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAQ,uBAAuB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,IAAM,MAAM,GAAW;IACrB,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAC;IACzC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,mBAAmB,EAAE,WAAW,EAAE,CAAC,SAAS,CAAC,EAAC;IAC/E,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,SAAS,CAAC,EAAC;IACrE,EAAE,IAAI,EAAE,EAAE;QACR,UAAU,EAAE,OAAO;QACnB,SAAS,EAAE,MAAM;KAClB;IACD,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE;CACpC,CAAC;AAMF;IAAA;IAAgC,CAAC;IAApB,gBAAgB;QAJ5B,QAAQ,CAAC;YACR,OAAO,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACvC,OAAO,EAAE,CAAC,YAAY,CAAC;SACxB,CAAC;OACW,gBAAgB,CAAI;IAAD,uBAAC;CAAA,AAAjC,IAAiC;SAApB,gBAAgB"}
{"version":3,"file":"app-routing.module.js","sourceRoot":"","sources":["../../../../src/app/app-routing.module.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAU,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAQ,mCAAmC,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAQ,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAQ,uBAAuB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,IAAM,MAAM,GAAW;IACrB,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAC;IACzC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAC;IACvC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,mBAAmB,EAAE,WAAW,EAAE,CAAC,SAAS,CAAC,EAAC;IAC/E,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,SAAS,CAAC,EAAC;IACrE,EAAE,IAAI,EAAE,EAAE;QACR,UAAU,EAAE,OAAO;QACnB,SAAS,EAAE,MAAM;KAClB;IACD,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE;CACpC,CAAC;AAMF;IAAA;IAAgC,CAAC;IAApB,gBAAgB;QAJ5B,QAAQ,CAAC;YACR,OAAO,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACvC,OAAO,EAAE,CAAC,YAAY,CAAC;SACxB,CAAC;OACW,gBAAgB,CAAI;IAAD,uBAAC;CAAA,AAAjC,IAAiC;SAApB,gBAAgB"}

View File

@@ -15,11 +15,32 @@ import { AuthGuard } from './services/auth.guard';
import { ProvisionsService } from './services/provisions.service';
import { ScenariosService } from './services/scenarios.service';
import { UsersService } from './services/users.service';
import { HttpClientModule } from '@angular/common/http';
import { MDBBootstrapModule } from 'angular-bootstrap-md';
import { MarkdownModule, MarkedRenderer } from 'ngx-markdown';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { LogsComponent } from './logs/logs.component';
import { ScenariosComponent } from './scenarios/scenarios.component';
import { AdminComponent } from './admin/admin.component';
import { PopoverconfirmComponent } from './popoverconfirm/popoverconfirm.component';
import { FormsModule } from '@angular/forms';
import { MyHttpInterceptor } from './interceptors/http.interceptor';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { TableAdminComponent } from './tables/table-admin.component';
import { TableUsersComponent } from './tables/table-users.component';
import { AlertComponent } from './alert/alert.component';
import { AlertService } from './services/alert.service';
import { ModalInfoComponent } from './alert/modalinfo.component';
import { ModalConfirmComponent } from './alert/confirm.component';
import { FilterPipe } from './filter.pipe';
import { FaqComponent } from './faq/faq.component';
import { NewProvisionConfirmComponent } from './alert/new-provision.component';
export function markedOptions() {
var renderer = new MarkedRenderer();
renderer.blockquote = function (text) {
return '<blockquote class="blockquote"><p>' + text + '</p></blockquote>';
};
return { renderer: renderer };
}
var AppModule = /** @class */ (function () {
function AppModule() {
}
@@ -32,15 +53,35 @@ var AppModule = /** @class */ (function () {
LogsComponent,
ScenariosComponent,
AdminComponent,
PopoverconfirmComponent
PopoverconfirmComponent,
TableAdminComponent,
TableUsersComponent,
AlertComponent,
ModalInfoComponent,
ModalConfirmComponent,
FilterPipe,
FaqComponent,
NewProvisionConfirmComponent
],
imports: [
BrowserModule,
AppRoutingModule,
UiModule,
HttpClientModule
HttpClientModule,
FormsModule,
MDBBootstrapModule.forRoot(),
MarkdownModule.forRoot({
loader: HttpClient
}),
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: MyHttpInterceptor, multi: true },
ProvisionsService,
ScenariosService,
UsersService,
AlertService,
AuthGuard
],
providers: [ProvisionsService, ScenariosService, UsersService, AuthGuard],
bootstrap: [AppComponent]
})
], AppModule);

View File

@@ -1 +1 @@
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../../../../src/app/app.module.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AAqBpF;IAAA;IAAyB,CAAC;IAAb,SAAS;QAnBrB,QAAQ,CAAC;YACR,YAAY,EAAE;gBACZ,YAAY;gBACZ,aAAa;gBACb,mBAAmB;gBACnB,aAAa;gBACb,kBAAkB;gBAClB,cAAc;gBACd,uBAAuB;aACxB;YACD,OAAO,EAAE;gBACP,aAAa;gBACb,gBAAgB;gBAChB,QAAQ;gBACR,gBAAgB;aACjB;YACD,SAAS,EAAE,CAAC,iBAAiB,EAAE,gBAAgB,EAAE,YAAY,EAAE,SAAS,CAAC;YACzE,SAAS,EAAE,CAAC,YAAY,CAAC;SAC1B,CAAC;OACW,SAAS,CAAI;IAAD,gBAAC;CAAA,AAA1B,IAA0B;SAAb,SAAS"}
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../../../../src/app/app.module.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,33 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Component } from '@angular/core';
var FaqComponent = /** @class */ (function () {
function FaqComponent() {
}
FaqComponent.prototype.ngOnInit = function () {
};
FaqComponent.prototype.onLoad = function (event) {
console.log("nice", event);
};
FaqComponent.prototype.onError = function (event) {
console.log("error", event);
};
FaqComponent = __decorate([
Component({
selector: 'app-faq-component',
templateUrl: './faq.component.html',
styleUrls: ['./faq.component.scss']
}),
__metadata("design:paramtypes", [])
], FaqComponent);
return FaqComponent;
}());
export { FaqComponent };
//# sourceMappingURL=faq.component.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"faq.component.js","sourceRoot":"","sources":["../../../../../src/app/faq/faq.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAU,MAAM,eAAe,CAAC;AAOlD;IAEE;IAAgB,CAAC;IAEjB,+BAAQ,GAAR;IACA,CAAC;IAED,6BAAM,GAAN,UAAO,KAAK;QACV,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,8BAAO,GAAP,UAAQ,KAAK;QACX,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;IAbU,YAAY;QALxB,SAAS,CAAC;YACT,QAAQ,EAAE,mBAAmB;YAC7B,WAAW,EAAE,sBAAsB;YACnC,SAAS,EAAE,CAAC,sBAAsB,CAAC;SACpC,CAAC;;OACW,YAAY,CAexB;IAAD,mBAAC;CAAA,AAfD,IAeC;SAfY,YAAY"}

View File

@@ -0,0 +1,21 @@
import { async, TestBed } from '@angular/core/testing';
import { FaqComponent } from './faq.component';
describe('FaqComponentComponent', function () {
var component;
var fixture;
beforeEach(async(function () {
TestBed.configureTestingModule({
declarations: [FaqComponent]
})
.compileComponents();
}));
beforeEach(function () {
fixture = TestBed.createComponent(FaqComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', function () {
expect(component).toBeTruthy();
});
});
//# sourceMappingURL=faq.component.spec.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"faq.component.spec.js","sourceRoot":"","sources":["../../../../../src/app/faq/faq.component.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAoB,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,QAAQ,CAAC,uBAAuB,EAAE;IAChC,IAAI,SAAuB,CAAC;IAC5B,IAAI,OAAuC,CAAC;IAE5C,UAAU,CAAC,KAAK,CAAC;QACf,OAAO,CAAC,sBAAsB,CAAC;YAC7B,YAAY,EAAE,CAAE,YAAY,CAAE;SAC/B,CAAC;aACD,iBAAiB,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC,CAAC;IAEJ,UAAU,CAAC;QACT,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QAChD,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC;QACtC,OAAO,CAAC,aAAa,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,eAAe,EAAE;QAClB,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}

31
dist/out-tsc/src/app/filter.pipe.js vendored Normal file
View File

@@ -0,0 +1,31 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { Pipe } from '@angular/core';
var FilterPipe = /** @class */ (function () {
function FilterPipe() {
}
FilterPipe.prototype.transform = function (items, searchText) {
if (!items) {
return [];
}
if (!searchText) {
return items;
}
searchText = searchText.toLocaleLowerCase();
return items.filter(function (it) {
return JSON.stringify(it).toLocaleLowerCase().includes(searchText);
});
};
FilterPipe = __decorate([
Pipe({
name: 'filter'
})
], FilterPipe);
return FilterPipe;
}());
export { FilterPipe };
//# sourceMappingURL=filter.pipe.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"filter.pipe.js","sourceRoot":"","sources":["../../../../src/app/filter.pipe.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,IAAI,EAAiB,MAAM,eAAe,CAAC;AAKpD;IAAA;IAeA,CAAC;IAdC,8BAAS,GAAT,UAAU,KAAY,EAAE,UAAkB;QAExC,IAAI,CAAC,KAAK,EAAE;YACV,OAAO,EAAE,CAAC;SACX;QACD,IAAI,CAAC,UAAU,EAAE;YACf,OAAO,KAAK,CAAC;SACd;QACD,UAAU,GAAG,UAAU,CAAC,iBAAiB,EAAE,CAAC;QAE5C,OAAO,KAAK,CAAC,MAAM,CAAC,UAAA,EAAE;YACpB,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;IACL,CAAC;IAdU,UAAU;QAHtB,IAAI,CAAC;YACJ,IAAI,EAAE,QAAQ;SACf,CAAC;OACW,UAAU,CAetB;IAAD,iBAAC;CAAA,AAfD,IAeC;SAfY,UAAU"}

View File

@@ -0,0 +1,8 @@
import { FilterPipe } from './filter.pipe';
describe('FilterPipe', function () {
it('create an instance', function () {
var pipe = new FilterPipe();
expect(pipe).toBeTruthy();
});
});
//# sourceMappingURL=filter.pipe.spec.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"filter.pipe.spec.js","sourceRoot":"","sources":["../../../../src/app/filter.pipe.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,QAAQ,CAAC,YAAY,EAAE;IACrB,EAAE,CAAC,oBAAoB,EAAE;QACvB,IAAM,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}

View File

@@ -23,6 +23,9 @@ var HomeComponent = /** @class */ (function () {
HomeComponent.prototype.ngOnDestroy = function () {
this.subs.unsubscribe();
};
HomeComponent.prototype.popupConfirm = function () {
console.log("Confirmed");
};
HomeComponent = __decorate([
Component({
selector: 'app-home',

View File

@@ -1 +1 @@
{"version":3,"file":"home.component.js","sourceRoot":"","sources":["../../../../../src/app/home/home.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAU,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AASnD;IAKE,uBAAqB,KAAgB;QAArC,iBAKC;QALoB,UAAK,GAAL,KAAK,CAAW;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,SAAS,CAAE,UAAA,KAAK;YACnD,KAAI,CAAC,IAAI,GAAG,KAAK,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAI,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,gCAAQ,GAAR;IAEA,CAAC;IAED,mCAAW,GAAX;QACE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAC1B,CAAC;IAlBU,aAAa;QANzB,SAAS,CAAC;YACT,QAAQ,EAAE,UAAU;YACpB,WAAW,EAAE,uBAAuB;YACpC,SAAS,EAAE,CAAC,uBAAuB,CAAC;YACpC,SAAS,EAAE,EAAE;SACd,CAAC;yCAM4B,SAAS;OAL1B,aAAa,CAoBzB;IAAD,oBAAC;CAAA,AApBD,IAoBC;SApBY,aAAa"}
{"version":3,"file":"home.component.js","sourceRoot":"","sources":["../../../../../src/app/home/home.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAU,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AASnD;IAKE,uBAAqB,KAAgB;QAArC,iBAKC;QALoB,UAAK,GAAL,KAAK,CAAW;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,SAAS,CAAE,UAAA,KAAK;YACnD,KAAI,CAAC,IAAI,GAAG,KAAK,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAI,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,gCAAQ,GAAR;IAEA,CAAC;IAED,mCAAW,GAAX;QACE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAC1B,CAAC;IAED,oCAAY,GAAZ;QACE,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC3B,CAAC;IAtBU,aAAa;QANzB,SAAS,CAAC;YACT,QAAQ,EAAE,UAAU;YACpB,WAAW,EAAE,uBAAuB;YACpC,SAAS,EAAE,CAAC,uBAAuB,CAAC;YACpC,SAAS,EAAE,EAAE;SACd,CAAC;yCAM4B,SAAS;OAL1B,aAAa,CAwBzB;IAAD,oBAAC;CAAA,AAxBD,IAwBC;SAxBY,aAAa"}

View File

@@ -0,0 +1,40 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { tap } from 'rxjs/operators';
import { Router } from '@angular/router';
import { AuthGuard } from '../services/auth.guard';
var MyHttpInterceptor = /** @class */ (function () {
function MyHttpInterceptor(router, _auth) {
this.router = router;
this._auth = _auth;
}
MyHttpInterceptor.prototype.intercept = function (request, next) {
var _this = this;
return next.handle(request).pipe(tap(function () { }, function (err) {
if (err instanceof HttpErrorResponse) {
if (err.status !== 401) {
return;
}
console.log("Interceptor error 401!!");
_this._auth.clearUser();
_this.router.navigate(['home']);
}
}));
};
MyHttpInterceptor = __decorate([
Injectable(),
__metadata("design:paramtypes", [Router, AuthGuard])
], MyHttpInterceptor);
return MyHttpInterceptor;
}());
export { MyHttpInterceptor };
//# sourceMappingURL=http.interceptor.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"http.interceptor.js","sourceRoot":"","sources":["../../../../../src/app/interceptors/http.interceptor.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAKL,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAC,GAAG,EAAC,MAAM,gBAAgB,CAAC;AACnC,OAAO,EAAC,MAAM,EAAC,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGnD;IAEE,2BAAoB,MAAc,EAAU,KAAgB;QAAxC,WAAM,GAAN,MAAM,CAAQ;QAAU,UAAK,GAAL,KAAK,CAAW;IAAG,CAAC;IAEhE,qCAAS,GAAT,UAAU,OAAyB,EAAE,IAAiB;QAAtD,iBAcC;QAZC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAE,GAAG,CAAC,cAAO,CAAC,EAC5C,UAAC,GAAQ;YAET,IAAI,GAAG,YAAY,iBAAiB,EAAE;gBACpC,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE;oBACvB,OAAO;iBACP;gBACD,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;gBACvC,KAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBACvB,KAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;aAChC;QACH,CAAC,CAAC,CAAC,CAAC;IACN,CAAC;IAlBU,iBAAiB;QAD7B,UAAU,EAAE;yCAGiB,MAAM,EAAiB,SAAS;OAFjD,iBAAiB,CAmB7B;IAAD,wBAAC;CAAA,AAnBD,IAmBC;SAnBY,iBAAiB"}

View File

@@ -20,7 +20,6 @@ var LogsComponent = /** @class */ (function () {
LogsComponent.prototype.onClick = function (targetElement) {
var clickedInside = this.insideElement.nativeElement.contains(targetElement);
if (!clickedInside) {
console.log('outside clicked');
this.onClose.emit(false);
}
};
@@ -33,20 +32,45 @@ var LogsComponent = /** @class */ (function () {
});
}
else if (this.type === "destroy") {
this.sub = timer(0, 5000).pipe(switchMap(function () { return _this._provisionsService.getDestroyLogs(_this.selectedprov.destroyId); })).subscribe(function (content) {
this.sub = timer(0, 5000).pipe(switchMap(function () { return _this._provisionsService.getDestroyLogs(_this.selectedprov.destroy._id); })).subscribe(function (content) {
_this.content = content;
});
}
}
};
LogsComponent.prototype.ngOnInit = function () {
this.refresh();
LogsComponent.prototype.ngOnInit = function () { };
LogsComponent.prototype.ngOnChanges = function (changes) {
var _this = this;
this.content = null;
if (this.sub) {
this.sub.unsubscribe();
this.sub = null;
}
if (changes.show && changes.show.currentValue) {
if (this.type === "provision") {
this.sub = timer(0, 5000).pipe(switchMap(function () { return _this._provisionsService.getProvisionLogs(_this.selectedprov._id); })).subscribe(function (content) {
_this.content = content;
});
}
else if (this.type === "destroy") {
this.sub = timer(0, 5000).pipe(switchMap(function () { return _this._provisionsService.getDestroyLogs(_this.selectedprov.destroy._id); })).subscribe(function (content) {
_this.content = content;
});
}
}
};
LogsComponent.prototype.ngOnDestroy = function () {
this.sub.unsubscribe();
if (this.sub) {
this.sub.unsubscribe();
this.sub = null;
}
};
LogsComponent.prototype.close = function () {
this.sub.unsubscribe();
this.content = null;
if (this.sub) {
this.sub.unsubscribe();
this.sub = null;
}
this.onClose.emit(false);
};
__decorate([
@@ -59,6 +83,10 @@ var LogsComponent = /** @class */ (function () {
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", void 0)
], LogsComponent.prototype, "onClick", null);
__decorate([
Input(),
__metadata("design:type", Object)
], LogsComponent.prototype, "show", void 0);
__decorate([
Input(),
__metadata("design:type", Object)

View File

@@ -1 +1 @@
{"version":3,"file":"logs.component.js","sourceRoot":"","sources":["../../../../../src/app/logs/logs.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAU,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACxG,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAgB,KAAK,EAAC,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAO3C;IAgBE,uBAAoB,kBAAqC;QAArC,uBAAkB,GAAlB,kBAAkB,CAAmB;QAHzD,YAAO,GAAW,IAAI,CAAC;QAOb,YAAO,GAAG,IAAI,YAAY,EAAE,CAAC;IAJsB,CAAC;IAXvD,+BAAO,GAAd,UAAe,aAAa;QAC1B,IAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAC/E,IAAI,CAAC,aAAa,EAAE;YAClB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;YAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SAC1B;IACH,CAAC;IAWD,+BAAO,GAAP;QAAA,iBAYC;QAXC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAC;YAChB,IAAK,IAAI,CAAC,IAAI,KAAK,WAAW,EAAG;gBAC/B,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAE,SAAS,CAAC,cAAM,OAAA,KAAI,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,KAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAA/D,CAA+D,CAAE,CAAE,CAAC,SAAS,CAAC,UAAA,OAAO;oBACnI,KAAI,CAAC,OAAO,GAAG,OAAO,CAAC;gBACzB,CAAC,CAAC,CAAC;aACJ;iBAAM,IAAK,IAAI,CAAC,IAAI,KAAK,SAAS,EAAG;gBACpC,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAE,SAAS,CAAC,cAAM,OAAA,KAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,KAAI,CAAC,YAAY,CAAC,SAAS,CAAC,EAAnE,CAAmE,CAAE,CAAE,CAAC,SAAS,CAAC,UAAA,OAAO;oBACvI,KAAI,CAAC,OAAO,GAAG,OAAO,CAAC;gBACzB,CAAC,CAAC,CAAA;aACH;SACF;IACH,CAAC;IACD,gCAAQ,GAAR;QACE,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,mCAAW,GAAX;QACE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;IACzB,CAAC;IAED,6BAAK,GAAL;QACE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QACvB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IA5C2B;QAA3B,SAAS,CAAC,eAAe,CAAC;;wDAAe;IAG1C;QAFC,YAAY,CAAC,gBAAgB,EAAE,CAAC,eAAe,CAAC,CAAC;;;;gDAQjD;IAOQ;QAAR,KAAK,EAAE;;uDAAc;IACb;QAAR,KAAK,EAAE;;+CAAM;IACJ;QAAT,MAAM,EAAE;;kDAA8B;IApB5B,aAAa;QALzB,SAAS,CAAC;YACT,QAAQ,EAAE,UAAU;YACpB,WAAW,EAAE,uBAAuB;YACpC,SAAS,EAAE,CAAC,uBAAuB,CAAC;SACrC,CAAC;yCAiBwC,iBAAiB;OAhB9C,aAAa,CAgDzB;IAAD,oBAAC;CAAA,AAhDD,IAgDC;SAhDY,aAAa"}
{"version":3,"file":"logs.component.js","sourceRoot":"","sources":["../../../../../src/app/logs/logs.component.ts"],"names":[],"mappings":"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"}

View File

@@ -7,37 +7,63 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Component, ElementRef } from '@angular/core';
import * as leonardoui from 'leonardo-ui';
import { Component, ElementRef, EventEmitter, ViewChild, Input, Output } from '@angular/core';
var PopoverconfirmComponent = /** @class */ (function () {
function PopoverconfirmComponent(myElement) {
this.onConfirm = new EventEmitter();
this.element = myElement;
}
PopoverconfirmComponent.prototype.open = function () {
console.log("myElement", this.element);
console.log("open popover", leonardoui);
/*this.popover = leonardoui.popover( {
content: this.element[0],
closeOnEscape: true,
dock: "bottom",
alignTo: this.element
} );
console.log("this.popover", this.popover);
}
ngOnInit() {
}
ok(): void {
this.popover.close();
}
cancel(): void {
this.popover.close();
}
}
var viewportOffset = this.element.nativeElement.getBoundingClientRect();
var top = viewportOffset.top;
var left = viewportOffset.left;
this.popovercontent.nativeElement.style.display = 'block';
this.popovercontent.nativeElement.style.position = 'absolute';
if (this.dock.indexOf('left') !== -1) {
this.left = -this.popovercontent.nativeElement.offsetWidth;
}
else if (this.dock.indexOf('right') !== -1) {
this.left = this.element.nativeElement.offsetWidth;
}
this.top = 0;
if (this.dock.indexOf('top') !== -1) {
this.top = -this.popovercontent.nativeElement.offsetHeight;
}
else if (this.dock.indexOf('bottom') !== -1) {
this.top = this.element.nativeElement.offsetHeight;
}
this.popovercontent.nativeElement.style.top = (top + this.top) + 'px';
this.popovercontent.nativeElement.style.left = (left + this.left) + 'px';
};
PopoverconfirmComponent.prototype.ngOnInit = function () {
};
PopoverconfirmComponent.prototype.ok = function () {
this.popovercontent.nativeElement.style.display = 'none';
this.onConfirm.emit(true);
};
PopoverconfirmComponent.prototype.cancel = function () {
this.popovercontent.nativeElement.style.display = 'none';
};
__decorate([
ViewChild('popovercontent'),
__metadata("design:type", ElementRef)
], PopoverconfirmComponent.prototype, "popovercontent", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], PopoverconfirmComponent.prototype, "dock", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], PopoverconfirmComponent.prototype, "buttonConfig", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], PopoverconfirmComponent.prototype, "popupConfig", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PopoverconfirmComponent.prototype, "onConfirm", void 0);
PopoverconfirmComponent = __decorate([
Component({
selector: 'app-popoverconfirm',
@@ -49,25 +75,4 @@ var PopoverconfirmComponent = /** @class */ (function () {
return PopoverconfirmComponent;
}());
export { PopoverconfirmComponent };
/*this.popover = leonardoui.popover( {
content: this.element[0],
closeOnEscape: true,
dock: "bottom",
alignTo: this.element
} );
console.log("this.popover", this.popover);
}
ngOnInit() {
}
ok(): void {
this.popover.close();
}
cancel(): void {
this.popover.close();
}
}
//# sourceMappingURL=popoverconfirm.component.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"popoverconfirm.component.js","sourceRoot":"","sources":["../../../../../src/app/popoverconfirm/popoverconfirm.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAU,UAAU,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,KAAK,UAAU,MAAM,aAAa,CAAC;AAO1C;IAKE,iCAAa,SAAqB;QAChC,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;IAC3B,CAAC;IAED,sCAAI,GAAJ;QACE,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QACxC;;;;;;;;;;;;;;;;;;;;QAoBJ;IAAA,CAAC,AArB2C;IAX/B,uBAAuB;QALnC,SAAS,CAAC;YACT,QAAQ,EAAE,oBAAoB;YAC9B,WAAW,EAAE,iCAAiC;YAC9C,SAAS,EAAE,CAAC,iCAAiC,CAAC;SAC/C,CAAC;yCAMwB,UAAU;OALvB,uBAAuB,CAWQ;IAqB5C,8BAAC;CArB2C,AAX5C,IAW4C;SAX/B,uBAAuB;AAYhC;;;;;;;;;;;;;;;;;;;;AAoBJ"}
{"version":3,"file":"popoverconfirm.component.js","sourceRoot":"","sources":["../../../../../src/app/popoverconfirm/popoverconfirm.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAU,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AAOpH;IAOE,iCAAa,SAAqB;QAQxB,cAAS,GAAG,IAAI,YAAY,EAAE,CAAC;QAPvC,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;IAC3B,CAAC;IAWD,sCAAI,GAAJ;QACE,IAAI,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,qBAAqB,EAAE,CAAC;QACxE,IAAI,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC;QAC7B,IAAI,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC;QAE/B,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;QAC1D,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;QAE9D,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;YACpC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,WAAW,CAAC;SAC5D;aAAM,IAAK,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAG;YAC9C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC;SACpD;QAED,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACb,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE;YACnC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,YAAY,CAAC;SAC5D;aAAM,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE;YAC7C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC;SACpD;QAED,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QACtE,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAE3E,CAAC;IAED,0CAAQ,GAAR;IACA,CAAC;IAED,oCAAE,GAAF;QACE,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QACzD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,wCAAM,GAAN;QACE,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;IAC3D,CAAC;IAnDD;QADC,SAAS,CAAC,gBAAgB,CAAC;kCACH,UAAU;mEAAC;IAM3B;QAAR,KAAK,EAAE;;yDAAM;IACL;QAAR,KAAK,EAAE;;iEAAc;IACb;QAAR,KAAK,EAAE;;gEAAa;IAEX;QAAT,MAAM,EAAE;;8DAAgC;IAf9B,uBAAuB;QALnC,SAAS,CAAC;YACT,QAAQ,EAAE,oBAAoB;YAC9B,WAAW,EAAE,iCAAiC;YAC9C,SAAS,EAAE,CAAC,iCAAiC,CAAC;SAC/C,CAAC;yCAQwB,UAAU;OAPvB,uBAAuB,CAyDnC;IAAD,8BAAC;CAAA,AAzDD,IAyDC;SAzDY,uBAAuB"}

View File

@@ -12,33 +12,53 @@ import { ProvisionsService } from '../services/provisions.service';
import { timer } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { AuthGuard } from '../services/auth.guard';
import { ScenariosService } from '../services/scenarios.service';
import { AlertService } from '../services/alert.service';
import { MDBModalService } from 'angular-bootstrap-md';
import { ModalInfoComponent } from '../alert/modalinfo.component';
import { ModalConfirmComponent } from '../alert/confirm.component';
var ProvisionsComponent = /** @class */ (function () {
function ProvisionsComponent(_provisionsService, _auth) {
function ProvisionsComponent(modalService, _alertService, _provisionsService, _scenariosService, _auth) {
var _this = this;
this.modalService = modalService;
this._alertService = _alertService;
this._provisionsService = _provisionsService;
this._scenariosService = _scenariosService;
this._auth = _auth;
this.logShow = false;
this.logstype = 'provision';
this.selectedprov = null;
this._auth.getUserInfo().subscribe(function (value) {
_this._userId = value._id;
_this._userId = value ? value._id : null;
});
}
ProvisionsComponent.prototype._refresh = function () {
var _this = this;
this.instantSubs = this._provisionsService.getCombinedProvisions(this._userId).subscribe(function (pair) {
_this._provisionsService.composePair(pair);
_this.destroys = pair[1];
_this.provisions = pair[0];
this.instantSubs = this._provisionsService.getProvisionsByUser(this._userId).subscribe(function (provisions) {
provisions = provisions.results;
provisions.forEach(function (p) {
p._scenario = _this.scenarios.filter(function (s) { return s.name === p.scenario; });
_this._provisionsService.timeRunning(p);
});
_this.provisions = provisions.filter(function (p) { return !p.destroy || !p.destroy.status || p.destroy.status !== 'destroyed'; });
_this.destroys = provisions.filter(function (p) { return p.destroy && p.destroy.status === 'destroyed'; });
_this.instantSubs.unsubscribe();
});
};
ProvisionsComponent.prototype.ngOnInit = function () {
var _this = this;
this.subscription = timer(0, 5000).pipe(switchMap(function () { return _this._provisionsService.getCombinedProvisions(_this._userId); })).subscribe(function (pair) {
_this._provisionsService.composePair(pair);
_this.destroys = pair[1];
_this.provisions = pair[0];
this.scenariosSub = this._scenariosService.getScenariosAll().subscribe(function (res) {
_this.scenarios = res.results;
_this.scenariosSub.unsubscribe();
_this.subscription = timer(0, 8000).pipe(switchMap(function () { return _this._provisionsService.getProvisionsByUser(_this._userId); })).subscribe(function (provisions) {
provisions = provisions.results;
provisions.forEach(function (p) {
p._scenario = _this.scenarios.filter(function (s) { return s.name === p.scenario; });
_this._provisionsService.timeRunning(p);
});
_this.provisions = provisions.filter(function (p) { return !p.destroy || !p.destroy.status || p.destroy.status !== 'destroyed'; });
_this.destroys = provisions.filter(function (p) { return p.destroy && p.destroy.status === 'destroyed'; });
});
});
};
ProvisionsComponent.prototype.ngOnDestroy = function () {
@@ -47,18 +67,107 @@ var ProvisionsComponent = /** @class */ (function () {
this.instantSubs.unsubscribe();
}
};
ProvisionsComponent.prototype.setModal = function (provision, frame) {
frame.show();
this._provisionsService.setSelectedProv(provision);
};
ProvisionsComponent.prototype.del = function (provision) {
var _this = this;
this._provisionsService.delProvision(provision._id.toString(), this._userId).subscribe(function (res) {
console.log("Done!", res);
_this._refresh();
_this._alertService.showAlert({
type: 'alert-primary',
text: "Provision entry '" + provision.scenario + "' was deleted from your history"
});
});
};
ProvisionsComponent.prototype.destroy = function (provision) {
ProvisionsComponent.prototype.openConfirmDestroyModal = function (provision) {
var _this = this;
this._provisionsService.newDestroy({ "id": provision._id.toString() }, this._userId).subscribe(function (res) {
console.log("Done!", res);
_this._refresh();
var modalRef = this.modalService.show(ModalConfirmComponent, {
class: 'modal-sm modal-notify modal-danger',
containerClass: '',
data: {
info: {
title: 'Confirm destroy this provision?',
icon: 'times-circle'
}
}
});
var sub = modalRef.content.action.subscribe(function (result) {
sub.unsubscribe();
_this._provisionsService.newDestroy(provision._id.toString(), _this._userId).subscribe(function (res) {
_this._refresh();
_this._alertService.showAlert({
type: 'alert-primary',
text: "Provision of scenario '" + provision.scenario + "' is going to be destroyed"
});
});
});
};
ProvisionsComponent.prototype.openConfirmStopModal = function (provision) {
var _this = this;
var modalRef = this.modalService.show(ModalConfirmComponent, {
class: 'modal-sm modal-notify modal-info',
containerClass: '',
data: {
info: {
title: 'Confirm Stop VMs?',
icon: 'stop',
buttonColor: 'grey'
}
}
});
var sub = modalRef.content.action.subscribe(function (result) {
sub.unsubscribe();
_this._stopVms(provision);
});
};
ProvisionsComponent.prototype.openConfirmStartModal = function (provision) {
var _this = this;
var modalRef = this.modalService.show(ModalConfirmComponent, {
class: 'modal-sm modal-notify modal-info',
containerClass: '',
data: {
info: {
title: 'Confirm Start VMs?',
icon: 'play',
buttonColor: 'grey'
}
}
});
var sub = modalRef.content.action.subscribe(function (result) {
sub.unsubscribe();
_this._startVms(provision);
});
};
ProvisionsComponent.prototype._startVms = function (provision) {
var _this = this;
this._provisionsService.startVms(provision._id.toString(), this._userId).subscribe(function (res) {
provision.statusVms = res.statusVms;
_this._alertService.showAlert({
type: 'alert-primary',
text: "Starting all VMs for scenario '" + provision.scenario + "'..."
});
});
};
ProvisionsComponent.prototype._stopVms = function (provision) {
var _this = this;
this._provisionsService.stopVms(provision._id.toString(), this._userId).subscribe(function (res) {
provision.statusVms = res.statusVms;
_this._alertService.showAlert({
type: 'alert-primary',
text: "Stopping all VMs for scenario '" + provision.scenario + "'..."
});
});
};
ProvisionsComponent.prototype.extend = function (provision) {
var _this = this;
this._provisionsService.extend(provision._id.toString(), this._userId).subscribe(function (res) {
provision.countExtend = res.countExtend;
_this._alertService.showAlert({
type: 'alert-primary',
text: "Running period extended another " + _this._provisionsService.RUNNING_PERIOD + " days (from now) for provision '" + provision.scenario + "'"
});
});
};
ProvisionsComponent.prototype.showLogs = function ($event, provision, type) {
@@ -69,12 +178,24 @@ var ProvisionsComponent = /** @class */ (function () {
this.selectedprov = provision;
this.logShow = true;
};
ProvisionsComponent.prototype.onLogsClose = function ($event) {
ProvisionsComponent.prototype.openModal = function (provision) {
this.modalService.show(ModalInfoComponent, {
class: 'modal-lg',
containerClass: '',
data: {
info: provision
}
});
};
ProvisionsComponent.prototype.onLogsClose = function () {
this.selectedprov = null;
this.logShow = false;
};
ProvisionsComponent.prototype.onStartProvision = function ($event) {
console.log("onStartProvision");
ProvisionsComponent.prototype.onStartProvision = function (scenario) {
this._alertService.showAlert({
type: 'alert-primary',
text: "Scenario '" + scenario.name + "' is going to be provisioned. Scroll up to your Provisions to watch out progress."
});
this._refresh();
};
ProvisionsComponent = __decorate([
@@ -84,7 +205,7 @@ var ProvisionsComponent = /** @class */ (function () {
styleUrls: ['./provisions.component.scss'],
providers: [ProvisionsService]
}),
__metadata("design:paramtypes", [ProvisionsService, AuthGuard])
__metadata("design:paramtypes", [MDBModalService, AlertService, ProvisionsService, ScenariosService, AuthGuard])
], ProvisionsComponent);
return ProvisionsComponent;
}());

File diff suppressed because one or more lines are too long

View File

@@ -11,28 +11,53 @@ import { Component, Output, EventEmitter } from '@angular/core';
import { ProvisionsService } from '../services/provisions.service';
import { ScenariosService } from '../services/scenarios.service';
import { AuthGuard } from '../services/auth.guard';
import { NewProvisionConfirmComponent } from '../alert/new-provision.component';
import { MDBModalService } from 'angular-bootstrap-md';
var ScenariosComponent = /** @class */ (function () {
function ScenariosComponent(_provisionsService, _scenariosService, _auth) {
function ScenariosComponent(modalService, _provisionsService, _scenariosService, _auth) {
var _this = this;
this.modalService = modalService;
this._provisionsService = _provisionsService;
this._scenariosService = _scenariosService;
this._auth = _auth;
this.onStartProvision = new EventEmitter();
this._auth.getUserInfo().subscribe(function (value) {
_this._userId = value._id;
_this.user = value;
});
}
ScenariosComponent.prototype.ngOnInit = function () {
var _this = this;
this._scenariosService.getScenarios().subscribe(function (res) {
_this.scenarios = res;
this.scenariosSub = this._scenariosService.getScenarios().subscribe(function (res) {
_this.scenarios = res.results;
_this.scenariosSub.unsubscribe();
console.log("scenarios", _this.scenarios);
});
};
ScenariosComponent.prototype.provision = function (scenario) {
ScenariosComponent.prototype.ngOnDestroy = function () { };
ScenariosComponent.prototype.openNewProvisionConfirmModal = function (scenario) {
var _this = this;
this._provisionsService.newProvision({ "scenario": scenario.name }, this._userId).subscribe(function (res) {
console.log("Done!", res);
_this.onStartProvision.emit();
console.log("scenario", scenario);
var modalRef = this.modalService.show(NewProvisionConfirmComponent, {
class: 'modal-md modal-notify',
containerClass: '',
data: {
scenario: scenario
}
});
var sub = modalRef.content.action.subscribe(function (data) {
sub.unsubscribe();
var postData = {
scenario: scenario.name,
description: data.description
};
if (data.servers) {
postData["vmImage"] = data.servers;
}
console.log("postData", postData);
_this._provisionsService.newProvision(postData, _this.user._id).subscribe(function (res) {
console.log("Done!", res);
_this.onStartProvision.emit(scenario);
});
});
};
__decorate([
@@ -45,7 +70,7 @@ var ScenariosComponent = /** @class */ (function () {
templateUrl: './scenarios.component.html',
styleUrls: ['./scenarios.component.scss']
}),
__metadata("design:paramtypes", [ProvisionsService, ScenariosService, AuthGuard])
__metadata("design:paramtypes", [MDBModalService, ProvisionsService, ScenariosService, AuthGuard])
], ScenariosComponent);
return ScenariosComponent;
}());

View File

@@ -1 +1 @@
{"version":3,"file":"scenarios.component.js","sourceRoot":"","sources":["../../../../../src/app/scenarios/scenarios.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAU,YAAY,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAOnD;IAEE,4BAAoB,kBAAqC,EAAU,iBAAmC,EAAU,KAAgB;QAAhI,iBAIC;QAJmB,uBAAkB,GAAlB,kBAAkB,CAAmB;QAAU,sBAAiB,GAAjB,iBAAiB,CAAkB;QAAU,UAAK,GAAL,KAAK,CAAW;QAMtH,qBAAgB,GAAG,IAAI,YAAY,EAAE,CAAC;QAL9C,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,SAAS,CAAE,UAAA,KAAK;YACvC,KAAI,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC;IAOD,qCAAQ,GAAR;QAAA,iBAIC;QAHC,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,CAAC,SAAS,CAAE,UAAA,GAAG;YAClD,KAAI,CAAC,SAAS,GAAG,GAAG,CAAC;QACvB,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,sCAAS,GAAT,UAAU,QAAQ;QAAlB,iBAKC;QAJC,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,EAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,CAAE,UAAA,GAAG;YAC5F,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAC1B,KAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAA;IACJ,CAAC;IAhBS;QAAT,MAAM,EAAE;;gEAAuC;IARrC,kBAAkB;QAL9B,SAAS,CAAC;YACT,QAAQ,EAAE,eAAe;YACzB,WAAW,EAAE,4BAA4B;YACzC,SAAS,EAAE,CAAC,4BAA4B,CAAC;SAC1C,CAAC;yCAGwC,iBAAiB,EAA6B,gBAAgB,EAAiB,SAAS;OAFrH,kBAAkB,CA0B9B;IAAD,yBAAC;CAAA,AA1BD,IA0BC;SA1BY,kBAAkB"}
{"version":3,"file":"scenarios.component.js","sourceRoot":"","sources":["../../../../../src/app/scenarios/scenarios.component.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,36 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Injectable, EventEmitter } from '@angular/core';
var AlertService = /** @class */ (function () {
function AlertService() {
this.alertEmitter = new EventEmitter();
}
AlertService.prototype.showAlert = function (alert) {
this.alertEmitter.emit(alert);
if (this.to) {
clearTimeout(this.to);
}
this.to = setTimeout(function () {
this.alertEmitter.emit(null);
}.bind(this), 5000);
};
AlertService.prototype.getAlertEmitter = function () {
return this.alertEmitter;
};
AlertService = __decorate([
Injectable({
providedIn: 'root'
}),
__metadata("design:paramtypes", [])
], AlertService);
return AlertService;
}());
export { AlertService };
//# sourceMappingURL=alert.service.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"alert.service.js","sourceRoot":"","sources":["../../../../../src/app/services/alert.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAKzD;IAIE;QAFA,iBAAY,GAAG,IAAI,YAAY,EAAE,CAAC;IAElB,CAAC;IAGjB,gCAAS,GAAT,UAAU,KAAK;QACb,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAK,IAAI,CAAC,EAAE,EAAG;YACb,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACvB;QACD,IAAI,CAAC,EAAE,GAAG,UAAU,CAAE;YAClB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IACvB,CAAC;IAED,sCAAe,GAAf;QACE,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAnBU,YAAY;QAHxB,UAAU,CAAC;YACV,UAAU,EAAE,MAAM;SACnB,CAAC;;OACW,YAAY,CAqBxB;IAAD,mBAAC;CAAA,AArBD,IAqBC;SArBY,YAAY"}

View File

@@ -12,30 +12,32 @@ import { Router } from '@angular/router';
import { of, BehaviorSubject } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
import { UsersService } from './users.service';
var AuthGuard = /** @class */ (function () {
// Inject Router so we can hand off the user to the Login Page
function AuthGuard(httpClient, router) {
var _this = this;
function AuthGuard(_userService, httpClient, router) {
this._userService = _userService;
this.httpClient = httpClient;
this.router = router;
this.userInfo = new BehaviorSubject(null);
this.getMe().subscribe(function (value) {
_this.userInfo.next(value);
localStorage.setItem("user", JSON.stringify(value));
});
var user = localStorage.getItem("user");
this.userInfo.next(JSON.parse(user));
}
AuthGuard.prototype.canActivate = function (route) {
var _this = this;
return this.getMe().pipe(map(function (res) {
console.log("CanActivate?");
return this._userService.getMe().pipe(map(function (res) {
localStorage.setItem("user", JSON.stringify(res));
_this.userInfo.next(res);
return true;
}), catchError(function (err) {
_this.userInfo.next(null);
_this.clearUser();
return of(false);
}));
};
AuthGuard.prototype.getMe = function () {
return this.httpClient.get('/api/users/me');
AuthGuard.prototype.clearUser = function () {
localStorage.setItem("user", null);
this.userInfo.next(null);
};
AuthGuard.prototype.getUserInfo = function () {
return this.userInfo;
@@ -44,7 +46,7 @@ var AuthGuard = /** @class */ (function () {
Injectable({
providedIn: 'root'
}),
__metadata("design:paramtypes", [HttpClient, Router])
__metadata("design:paramtypes", [UsersService, HttpClient, Router])
], AuthGuard);
return AuthGuard;
}());

View File

@@ -1 +1 @@
{"version":3,"file":"auth.guard.js","sourceRoot":"","sources":["../../../../../src/app/services/auth.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAA4D,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEnG,OAAO,EAAE,EAAE,EAAc,eAAe,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAMlD;IAIE,+DAA+D;IAC/D,mBAAoB,UAAsB,EAAU,MAAc;QAAlE,iBAOC;QAPmB,eAAU,GAAV,UAAU,CAAY;QAAU,WAAM,GAAN,MAAM,CAAQ;QAH1D,aAAQ,GAAyB,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;QAKjE,IAAI,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,UAAA,KAAK;YAC1B,KAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IAEL,CAAC;IAED,+BAAW,GAAX,UAAY,KAA6B;QAAzC,iBAWC;QAVC,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CACtB,GAAG,CAAC,UAAA,GAAG;YACL,KAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,EACF,UAAU,CAAC,UAAC,GAAG;YACb,KAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,yBAAK,GAAL;QACE,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC9C,CAAC;IAED,+BAAW,GAAX;QACE,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAjCU,SAAS;QAHrB,UAAU,CAAC;YACV,UAAU,EAAE,MAAM;SACnB,CAAC;yCAMgC,UAAU,EAAkB,MAAM;OALvD,SAAS,CAkCrB;IAAD,gBAAC;CAAA,AAlCD,IAkCC;SAlCY,SAAS"}
{"version":3,"file":"auth.guard.js","sourceRoot":"","sources":["../../../../../src/app/services/auth.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAA4D,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEnG,OAAO,EAAE,EAAE,EAAc,eAAe,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAM/C;IAIE,+DAA+D;IAC/D,mBAAoB,YAA0B,EAAU,UAAsB,EAAU,MAAc;QAAlF,iBAAY,GAAZ,YAAY,CAAc;QAAU,eAAU,GAAV,UAAU,CAAY;QAAU,WAAM,GAAN,MAAM,CAAQ;QAH9F,aAAQ,GAAyB,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;QAIjE,IAAI,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,+BAAW,GAAX,UAAY,KAA6B;QAAzC,iBAaC;QAZC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,CACnC,GAAG,CAAC,UAAA,GAAG;YACL,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAClD,KAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,EACF,UAAU,CAAC,UAAC,GAAG;YACb,KAAI,CAAC,SAAS,EAAE,CAAC;YACjB,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAID,6BAAS,GAAT;QACE,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,+BAAW,GAAX;QACE,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAlCU,SAAS;QAHrB,UAAU,CAAC;YACV,UAAU,EAAE,MAAM;SACnB,CAAC;yCAMkC,YAAY,EAAsB,UAAU,EAAkB,MAAM;OAL3F,SAAS,CAmCrB;IAAD,gBAAC;CAAA,AAnCD,IAmCC;SAnCY,SAAS"}

View File

@@ -8,57 +8,92 @@ var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { forkJoin } from 'rxjs';
import { HttpClient, HttpParams } from '@angular/common/http';
import { environment } from '../../environments/environment.prod';
import * as moment from 'moment';
var ProvisionsService = /** @class */ (function () {
function ProvisionsService(httpClient) {
this.httpClient = httpClient;
this.RUNNING_PERIOD = 4;
}
ProvisionsService.prototype.getProvisionsAdmin = function () {
return this.httpClient.get("/api/provisions");
ProvisionsService.prototype.getProvisionsAdmin = function (filter) {
// Initialize Params Object
var params = new HttpParams();
if (filter) {
params = params.append("filter", JSON.stringify(filter));
}
return this.httpClient.get(environment.apiVersionPath + "/provisions", { params: params });
};
ProvisionsService.prototype.getProvisionsByUser = function (userId) {
return this.httpClient.get(environment.apiVersionPath + "/users/" + userId + "/provisions");
};
ProvisionsService.prototype.getDestroyProvisionsAdmin = function () {
return this.httpClient.get("/api/destroyprovisions");
};
ProvisionsService.prototype.getProvisions = function (userId) {
return this.httpClient.get("/api/users/" + userId + "/provisions");
return this.httpClient.get(environment.apiVersionPath + "/destroyprovisions");
};
ProvisionsService.prototype.newProvision = function (body, userId) {
return this.httpClient.post("/api/users/" + userId + "/provisions", body);
return this.httpClient.post(environment.apiVersionPath + "/users/" + userId + "/provisions", body);
};
ProvisionsService.prototype.delProvision = function (id, userId) {
return this.httpClient.delete("/api/users/" + userId + "/provisions/" + id);
return this.httpClient.delete(environment.apiVersionPath + "/users/" + userId + "/provisions/" + id);
};
ProvisionsService.prototype.newDestroy = function (body, userId) {
return this.httpClient.post("/api/users/" + userId + "/destroyprovisions", body);
ProvisionsService.prototype.newDestroy = function (id, userId) {
return this.httpClient.post(environment.apiVersionPath + "/users/" + userId + "/provisions/" + id + "/destroy", null);
};
ProvisionsService.prototype.getDestroyProvisions = function (userId) {
return this.httpClient.get("/api/users/" + userId + "/destroyprovisions");
};
ProvisionsService.prototype.getCombinedProvisions = function (userId) {
return forkJoin(this.getProvisions(userId), this.getDestroyProvisions(userId));
};
ProvisionsService.prototype.getCombinedProvisionsAdmin = function () {
return forkJoin(this.getProvisionsAdmin(), this.getDestroyProvisionsAdmin());
return this.httpClient.get(environment.apiVersionPath + "/users/" + userId + "/destroyprovisions");
};
/*
getCombinedProvisions(userId): Observable<any> {
return forkJoin(this.getProvisionsByUser(userId), this.getDestroyProvisions(userId))
}
getCombinedProvisionsAdmin(): Observable<any> {
return forkJoin(this.getProvisionsAdmin(), this.getDestroyProvisionsAdmin())
}*/
ProvisionsService.prototype.getProvisionLogs = function (id) {
return this.httpClient.get("/api/provisions/" + id + "/logs", { responseType: 'text' });
return this.httpClient.get(environment.apiVersionPath + "/provisions/" + id + "/logs", { responseType: 'text' });
};
ProvisionsService.prototype.getDestroyLogs = function (id) {
return this.httpClient.get("/api/destroyprovisions/" + id + "/logs", { responseType: 'text' });
return this.httpClient.get(environment.apiVersionPath + "/destroyprovisions/" + id + "/logs", { responseType: 'text' });
};
ProvisionsService.prototype.composePair = function (pair) {
pair['0'].forEach(function (prov) {
var foundDes = pair['1'].filter(function (d) {
return d.provId.toString() === prov._id.toString();
});
if (foundDes.length) {
prov.destroyId = foundDes[0]._id.toString();
prov.statusDestroy = foundDes[0].status;
prov.dateDestroy = foundDes[0].created;
}
});
return pair;
ProvisionsService.prototype.stopVms = function (id, userId) {
return this.httpClient.post(environment.apiVersionPath + "/users/" + userId + "/provisions/" + id + "/deallocatevms", null);
};
ProvisionsService.prototype.startVms = function (id, userId) {
return this.httpClient.post(environment.apiVersionPath + "/users/" + userId + "/provisions/" + id + "/startvms", null);
};
ProvisionsService.prototype.extend = function (id, userId) {
return this.httpClient.post(environment.apiVersionPath + "/users/" + userId + "/provisions/" + id + "/extend", null);
};
ProvisionsService.prototype.setSelectedProv = function (provision) {
if (provision) {
this.selectedProv = provision;
}
else {
this.selectedProv = null;
}
};
ProvisionsService.prototype.getSelectedProv = function () {
return this.selectedProv;
};
ProvisionsService.prototype.timeRunning = function (p) {
var now = new Date();
var runningFromTime = p.runningFrom ? new Date(p.runningFrom).getTime() : new Date(p.created).getTime();
var totalRunningTime = p.timeRunning * 1000 * 60;
if (p.statusVms !== 'Stopped' && p.statusVms !== 'Starting' && !p.isDestroyed) {
totalRunningTime = totalRunningTime + Math.abs(now.getTime() - runningFromTime);
}
var authShutdownDate = new Date(runningFromTime);
authShutdownDate.setDate(authShutdownDate.getDate() + this.RUNNING_PERIOD);
var autoshutDown = authShutdownDate.getTime() - now.getTime();
var durationAutoShutdown = moment.duration(autoshutDown);
var duration = moment.duration(totalRunningTime);
p.runningDays = Math.floor(duration.asDays());
p.runningHours = duration.hours();
p.runningMinutes = duration.minutes();
p.autoshutdownDays = Math.floor(durationAutoShutdown.asDays());
p.autoshutdownHours = durationAutoShutdown.hours();
p.autoshutdownMinutes = durationAutoShutdown.minutes();
};
ProvisionsService = __decorate([
Injectable({

View File

@@ -1 +1 @@
{"version":3,"file":"provisions.service.js","sourceRoot":"","sources":["../../../../../src/app/services/provisions.service.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"provisions.service.js","sourceRoot":"","sources":["../../../../../src/app/services/provisions.service.ts"],"names":[],"mappings":"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"}

View File

@@ -9,12 +9,19 @@ var __metadata = (this && this.__metadata) || function (k, v) {
};
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment.prod';
var ScenariosService = /** @class */ (function () {
function ScenariosService(httpClient) {
this.httpClient = httpClient;
}
ScenariosService.prototype.getScenarios = function () {
return this.httpClient.get("/api/scenarios");
return this.httpClient.get(environment.apiVersionPath + "/scenarios");
};
ScenariosService.prototype.getScenariosAll = function () {
return this.httpClient.get(environment.apiVersionPath + "/scenarios/all");
};
ScenariosService.prototype.getScenarioVmtypes = function () {
return this.httpClient.get(environment.apiVersionPath + "/scenarios/vmtypes");
};
ScenariosService = __decorate([
Injectable({

View File

@@ -1 +1 @@
{"version":3,"file":"scenarios.service.js","sourceRoot":"","sources":["../../../../../src/app/services/scenarios.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAMlD;IAEE,0BAAqB,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAK,CAAC;IAEjD,uCAAY,GAAZ;QACE,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC/C,CAAC;IANU,gBAAgB;QAH5B,UAAU,CAAC;YACV,UAAU,EAAE,MAAM;SACnB,CAAC;yCAGiC,UAAU;OAFhC,gBAAgB,CAO5B;IAAD,uBAAC;CAAA,AAPD,IAOC;SAPY,gBAAgB"}
{"version":3,"file":"scenarios.service.js","sourceRoot":"","sources":["../../../../../src/app/services/scenarios.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAKlE;IAEE,0BAAqB,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAK,CAAC;IAEjD,uCAAY,GAAZ;QACE,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAI,WAAW,CAAC,cAAc,eAAY,CAAC,CAAC;IACxE,CAAC;IAED,0CAAe,GAAf;QACE,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAI,WAAW,CAAC,cAAc,mBAAgB,CAAC,CAAC;IAC5E,CAAC;IAED,6CAAkB,GAAlB;QACE,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAI,WAAW,CAAC,cAAc,uBAAoB,CAAC,CAAC;IAChF,CAAC;IAdU,gBAAgB;QAH5B,UAAU,CAAC;YACV,UAAU,EAAE,MAAM;SACnB,CAAC;yCAGiC,UAAU;OAFhC,gBAAgB,CAgB5B;IAAD,uBAAC;CAAA,AAhBD,IAgBC;SAhBY,gBAAgB"}

View File

@@ -9,15 +9,19 @@ var __metadata = (this && this.__metadata) || function (k, v) {
};
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment.prod';
var UsersService = /** @class */ (function () {
function UsersService(httpClient) {
this.httpClient = httpClient;
}
UsersService.prototype.getMe = function () {
return this.httpClient.get(environment.apiVersionPath + "/users/me");
};
UsersService.prototype.getUsers = function () {
return this.httpClient.get("/api/users");
return this.httpClient.get(environment.apiVersionPath + "/users");
};
UsersService.prototype.updateUser = function (userId, patchData) {
return this.httpClient.put("/api/users/" + userId, patchData);
return this.httpClient.put(environment.apiVersionPath + "/users/" + userId, patchData);
};
UsersService = __decorate([
Injectable({

View File

@@ -1 +1 @@
{"version":3,"file":"users.service.js","sourceRoot":"","sources":["../../../../../src/app/services/users.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAMlD;IAEE,sBAAqB,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAK,CAAC;IAEjD,+BAAQ,GAAR;QACE,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC3C,CAAC;IAED,iCAAU,GAAV,UAAW,MAAM,EAAE,SAAS;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,gBAAc,MAAQ,EAAE,SAAS,CAAC,CAAC;IAChE,CAAC;IAVU,YAAY;QAHxB,UAAU,CAAC;YACV,UAAU,EAAE,MAAM;SACnB,CAAC;yCAGiC,UAAU;OAFhC,YAAY,CAWxB;IAAD,mBAAC;CAAA,AAXD,IAWC;SAXY,YAAY"}
{"version":3,"file":"users.service.js","sourceRoot":"","sources":["../../../../../src/app/services/users.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAKlE;IAEE,sBAAqB,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAK,CAAC;IAEjD,4BAAK,GAAL;QACE,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAI,WAAW,CAAC,cAAc,cAAW,CAAC,CAAC;IACvE,CAAC;IAED,+BAAQ,GAAR;QACE,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAI,WAAW,CAAC,cAAc,WAAQ,CAAC,CAAC;IACpE,CAAC;IAED,iCAAU,GAAV,UAAW,MAAM,EAAE,SAAS;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAI,WAAW,CAAC,cAAc,eAAU,MAAQ,EAAE,SAAS,CAAC,CAAC;IACzF,CAAC;IAdU,YAAY;QAHxB,UAAU,CAAC;YACV,UAAU,EAAE,MAAM;SACnB,CAAC;yCAGiC,UAAU;OAFhC,YAAY,CAexB;IAAD,mBAAC;CAAA,AAfD,IAeC;SAfY,YAAY"}

View File

@@ -0,0 +1,286 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Component, HostListener, ViewChild, ChangeDetectorRef } from '@angular/core';
import { MdbTableDirective, MdbTablePaginationComponent, MDBModalService } from 'angular-bootstrap-md';
import { ProvisionsService } from '../services/provisions.service';
import { AlertService } from '../services/alert.service';
import { ModalInfoComponent } from '../alert/modalinfo.component';
import { ModalConfirmComponent } from '../alert/confirm.component';
import { ScenariosService } from '../services/scenarios.service';
import { timer } from 'rxjs';
import { switchMap } from 'rxjs/operators';
var TableAdminComponent = /** @class */ (function () {
function TableAdminComponent(modalService, _scenariosService, _alertService, cdRef, _provisionsService) {
this.modalService = modalService;
this._scenariosService = _scenariosService;
this._alertService = _alertService;
this.cdRef = cdRef;
this._provisionsService = _provisionsService;
this.pagingIsDisabled = false;
this.searchText = '';
this.selectedprov = null;
this.showInfo = false;
this.logShow = false;
this.logstype = 'provision';
this.maxVisibleItems = 10;
this.filterParams = {
isDestroyed: false
};
}
TableAdminComponent.prototype.oninput = function () {
this.mdbTablePagination.searchText = this.searchText;
};
TableAdminComponent.prototype._process = function (provisions) {
var _this = this;
provisions.forEach(function (p) {
p._scenario = _this.scenarios.filter(function (s) { return s.name === p.scenario; });
_this._provisionsService.timeRunning(p);
});
if (!this.provisions) {
this.provisions = provisions;
}
else {
this.provisions.forEach(function (p, index, object) {
var found = provisions.filter(function (a) { return a._id.toString() === p._id.toString(); });
if (found.length) {
p.status = found[0].status;
p.statusVms = found[0].statusVms;
p.isDestroyed = found[0].isDestroyed;
p.outputs = found[0].outputs;
p.destroy = found[0].destroy;
this._provisionsService.timeRunning(p);
}
else {
object.splice(index, 1);
}
}.bind(this));
provisions.forEach(function (p) {
var found = this.provisions.filter(function (a) { return a._id.toString() === p._id.toString(); });
if (found.length === 0) {
this.provisions.unshift(p);
}
}.bind(this));
}
this._initElements(this.provisions);
};
TableAdminComponent.prototype._initElements = function (items) {
this.mdbTable.setDataSource(items);
this.elements = this.mdbTable.getDataSource();
this.previous = this.mdbTable.getDataSource();
};
TableAdminComponent.prototype.ngOnInit = function () {
var _this = this;
var scenariosSub = this._scenariosService.getScenariosAll().subscribe(function (res) {
scenariosSub.unsubscribe();
_this.scenarios = res.results;
_this.subscription = timer(0, 8000).pipe(switchMap(function () { return _this._provisionsService.getProvisionsAdmin(_this.filterParams); })).subscribe(function (provisions) {
_this._process(provisions.results);
});
});
this.mdbTablePagination.paginationChange().subscribe(function (data) {
/*let page = data.last - data.first;
if (page < this.limit && page > 0) {
page = Math.ceil(data.last / this.limit);
if (this.page !== page) {
this.page = Math.ceil(data.last / this.limit);
this.loadTable();
}
}*/
});
//this._initElements();
};
TableAdminComponent.prototype.ngAfterViewInit = function () {
if (this.mdbTablePagination) {
this.mdbTablePagination.setMaxVisibleItemsNumberTo(this.maxVisibleItems);
this.mdbTablePagination.calculateFirstItemIndex();
this.mdbTablePagination.calculateLastItemIndex();
this.cdRef.detectChanges();
}
};
TableAdminComponent.prototype.searchItems = function () {
var _this = this;
var prev = this.mdbTable.getDataSource();
if (!this.searchText) {
this.mdbTable.setDataSource(this.previous);
this.elements = this.mdbTable.getDataSource();
}
if (this.searchText) {
this.elements = this.mdbTable.searchLocalDataBy(this.searchText);
this.mdbTable.setDataSource(prev);
}
if (this.mdbTablePagination) {
this.mdbTablePagination.calculateFirstItemIndex();
this.mdbTablePagination.calculateLastItemIndex();
this.mdbTable.searchDataObservable(this.searchText).subscribe(function () {
_this.mdbTablePagination.calculateFirstItemIndex();
_this.mdbTablePagination.calculateLastItemIndex();
});
}
};
TableAdminComponent.prototype.showLogs = function ($event, provision, type) {
$event.preventDefault();
$event.stopPropagation();
this.logstype = type;
this.logShow = false;
this.selectedprov = provision;
this.logShow = true;
};
TableAdminComponent.prototype.onLogsClose = function () {
this.selectedprov = null;
this.logShow = false;
};
TableAdminComponent.prototype.openConfirmStartModal = function (provision) {
var _this = this;
var modalRef = this.modalService.show(ModalConfirmComponent, {
class: 'modal-sm modal-notify modal-info',
containerClass: '',
data: {
info: {
title: 'Confirm Start VMs?',
icon: 'play',
buttonColor: 'grey'
}
}
});
var sub = modalRef.content.action.subscribe(function (result) {
sub.unsubscribe();
_this._startVms(provision);
});
};
TableAdminComponent.prototype._startVms = function (provision) {
var _this = this;
var sub = this._provisionsService.startVms(provision._id.toString(), provision.user._id).subscribe(function (res) {
provision.startVms = res.startVms;
sub.unsubscribe();
_this._alertService.showAlert({
type: 'alert-primary',
text: "Starting all VMs for scenario '" + provision.scenario + "'..."
});
});
};
TableAdminComponent.prototype.openConfirmStopModal = function (provision) {
var _this = this;
var modalRef = this.modalService.show(ModalConfirmComponent, {
class: 'modal-sm modal-notify modal-info',
containerClass: '',
data: {
info: {
title: 'Confirm Stop VMs?',
icon: 'stop',
buttonColor: 'grey'
}
}
});
var sub = modalRef.content.action.subscribe(function (result) {
sub.unsubscribe();
_this._stopVms(provision);
});
};
TableAdminComponent.prototype._stopVms = function (provision) {
var _this = this;
var sub = this._provisionsService.stopVms(provision._id.toString(), provision.user._id).subscribe(function (res) {
provision.startVms = res.startVms;
sub.unsubscribe();
_this._alertService.showAlert({
type: 'alert-primary',
text: "Stopping all VMs for scenario '" + provision.scenario + "'..."
});
});
};
TableAdminComponent.prototype.openInfoModal = function (provision) {
this.modalService.show(ModalInfoComponent, {
backdrop: true,
keyboard: true,
focus: true,
show: false,
ignoreBackdropClick: false,
class: 'modal-lg',
containerClass: '',
animated: true,
data: {
info: provision
}
});
};
TableAdminComponent.prototype.openConfirmDestroyModal = function (provision) {
var _this = this;
var modalRef = this.modalService.show(ModalConfirmComponent, {
class: 'modal-sm modal-notify modal-danger',
containerClass: '',
data: {
info: {
title: 'Confirm destroy this provision?',
icon: 'times-circle'
}
}
});
var sub = modalRef.content.action.subscribe(function (result) {
sub.unsubscribe();
_this._provisionsService.newDestroy(provision._id.toString(), provision.user._id).subscribe(function (provUpdated) {
_this._alertService.showAlert({
type: 'alert-primary',
text: "Provision of scenario '" + provision.scenario + "' is going to be destroyed"
});
provision.destroy = provUpdated.destroy;
});
});
};
TableAdminComponent.prototype.openConfirmDeleteModal = function (provision) {
var _this = this;
var modalRef = this.modalService.show(ModalConfirmComponent, {
class: 'modal-sm modal-notify modal-danger',
containerClass: '',
data: {
info: {
title: 'Confirm delete?',
icon: 'trash-alt'
}
}
});
var sub = modalRef.content.action.subscribe(function (result) {
sub.unsubscribe();
_this._provisionsService.delProvision(provision._id, provision.user._id).subscribe(function (res) {
_this.elements = _this.elements.filter(function (e) {
return e._id.toString() !== provision._id.toString();
});
_this._initElements(_this.elements);
_this._alertService.showAlert({
type: 'alert-primary',
text: "Provision entry '" + provision.scenario + "' was deleted"
});
});
});
};
__decorate([
ViewChild(MdbTablePaginationComponent, { static: true }),
__metadata("design:type", MdbTablePaginationComponent)
], TableAdminComponent.prototype, "mdbTablePagination", void 0);
__decorate([
ViewChild(MdbTableDirective, { static: true }),
__metadata("design:type", MdbTableDirective)
], TableAdminComponent.prototype, "mdbTable", void 0);
__decorate([
HostListener('input'),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], TableAdminComponent.prototype, "oninput", null);
TableAdminComponent = __decorate([
Component({
selector: 'table-admin',
templateUrl: './table-admin.component.html',
styleUrls: ['./table-admin.component.scss']
}),
__metadata("design:paramtypes", [MDBModalService, ScenariosService, AlertService, ChangeDetectorRef, ProvisionsService])
], TableAdminComponent);
return TableAdminComponent;
}());
export { TableAdminComponent };
//# sourceMappingURL=table-admin.component.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,109 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { MdbTablePaginationComponent, MdbTableDirective } from 'angular-bootstrap-md';
import { Component, ViewChild, HostListener, ChangeDetectorRef, Input } from '@angular/core';
import { AuthGuard } from '../services/auth.guard';
import { UsersService } from '../services/users.service';
var TableUsersComponent = /** @class */ (function () {
function TableUsersComponent(cdRef, _usersService, _auth) {
var _this = this;
this.cdRef = cdRef;
this._usersService = _usersService;
this._auth = _auth;
this.previous = [];
this.searchText = '';
this.maxVisibleItems = 8;
this._auth.getUserInfo().subscribe(function (value) {
_this.currentUser = value;
});
}
TableUsersComponent.prototype.oninput = function () {
this.mdbTablePagination.searchText = this.searchText;
};
TableUsersComponent.prototype._initElements = function () {
this.mdbTable.setDataSource(this.elements);
this.elements = this.mdbTable.getDataSource();
this.previous = this.mdbTable.getDataSource();
};
TableUsersComponent.prototype.ngOnInit = function () {
this._initElements();
};
TableUsersComponent.prototype.ngAfterViewInit = function () {
this.mdbTablePagination.setMaxVisibleItemsNumberTo(this.maxVisibleItems);
this.mdbTablePagination.calculateFirstItemIndex();
this.mdbTablePagination.calculateLastItemIndex();
this.cdRef.detectChanges();
};
TableUsersComponent.prototype.searchItems = function () {
var _this = this;
var prev = this.mdbTable.getDataSource();
if (!this.searchText) {
this.mdbTable.setDataSource(this.previous);
this.elements = this.mdbTable.getDataSource();
}
if (this.searchText) {
this.elements = this.mdbTable.searchLocalDataBy(this.searchText);
this.mdbTable.setDataSource(prev);
}
this.mdbTablePagination.calculateFirstItemIndex();
this.mdbTablePagination.calculateLastItemIndex();
this.mdbTable.searchDataObservable(this.searchText).subscribe(function () {
_this.mdbTablePagination.calculateFirstItemIndex();
_this.mdbTablePagination.calculateLastItemIndex();
});
};
TableUsersComponent.prototype.setAdmin = function (user) {
var _this = this;
this._usersService.updateUser(user._id, { "role": "admin" }).subscribe(function (res1) {
_this._usersService.getUsers().subscribe(function (res) {
_this.elements = res.results;
_this._initElements();
});
});
};
TableUsersComponent.prototype.removeAdmin = function (user) {
var _this = this;
this._usersService.updateUser(user._id, { "role": "user" }).subscribe(function (res1) {
_this._usersService.getUsers().subscribe(function (res) {
_this.elements = res.results;
_this._initElements();
});
});
};
__decorate([
ViewChild(MdbTablePaginationComponent, { static: true }),
__metadata("design:type", MdbTablePaginationComponent)
], TableUsersComponent.prototype, "mdbTablePagination", void 0);
__decorate([
ViewChild(MdbTableDirective, { static: true }),
__metadata("design:type", MdbTableDirective)
], TableUsersComponent.prototype, "mdbTable", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], TableUsersComponent.prototype, "elements", void 0);
__decorate([
HostListener('input'),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], TableUsersComponent.prototype, "oninput", null);
TableUsersComponent = __decorate([
Component({
selector: 'table-users',
templateUrl: './table-users.component.html',
styleUrls: ['./table-users.component.scss']
}),
__metadata("design:paramtypes", [ChangeDetectorRef, UsersService, AuthGuard])
], TableUsersComponent);
return TableUsersComponent;
}());
export { TableUsersComponent };
//# sourceMappingURL=table-users.component.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"table-users.component.js","sourceRoot":"","sources":["../../../../../src/app/tables/table-users.component.ts"],"names":[],"mappings":"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"}

View File

@@ -20,6 +20,12 @@ var HeaderComponent = /** @class */ (function () {
}
HeaderComponent.prototype.ngOnInit = function () {
};
HeaderComponent.prototype.logout = function ($event) {
$event.preventDefault();
$event.stopPropagation();
window.location.href = "/logout";
this._auth.clearUser();
};
HeaderComponent.prototype.ngOnDestroy = function () {
this.subs.unsubscribe();
};

View File

@@ -1 +1 @@
{"version":3,"file":"header.component.js","sourceRoot":"","sources":["../../../../../../src/app/ui/header/header.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAU,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAQtD;IAKE,yBAAqB,KAAgB;QAArC,iBAKC;QALoB,UAAK,GAAL,KAAK,CAAW;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,SAAS,CAAE,UAAA,KAAK;YACnD,KAAI,CAAC,IAAI,GAAG,KAAK,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAI,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,kCAAQ,GAAR;IAEA,CAAC;IAED,qCAAW,GAAX;QACE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAC1B,CAAC;IAlBU,eAAe;QAL3B,SAAS,CAAC;YACT,QAAQ,EAAE,YAAY;YACtB,WAAW,EAAE,yBAAyB;YACtC,SAAS,EAAE,CAAC,yBAAyB,CAAC;SACvC,CAAC;yCAM4B,SAAS;OAL1B,eAAe,CAoB3B;IAAD,sBAAC;CAAA,AApBD,IAoBC;SApBY,eAAe"}
{"version":3,"file":"header.component.js","sourceRoot":"","sources":["../../../../../../src/app/ui/header/header.component.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAU,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAQtD;IAKE,yBAAqB,KAAgB;QAArC,iBAKC;QALoB,UAAK,GAAL,KAAK,CAAW;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,SAAS,CAAE,UAAA,KAAK;YACnD,KAAI,CAAC,IAAI,GAAG,KAAK,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAI,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,kCAAQ,GAAR;IAEA,CAAC;IAED,gCAAM,GAAN,UAAO,MAAM;QACX,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,MAAM,CAAC,eAAe,EAAE,CAAC;QACzB,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,SAAS,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;IACzB,CAAC;IAED,qCAAW,GAAX;QACE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAC1B,CAAC;IAzBU,eAAe;QAL3B,SAAS,CAAC;YACT,QAAQ,EAAE,YAAY;YACtB,WAAW,EAAE,yBAAyB;YACtC,SAAS,EAAE,CAAC,yBAAyB,CAAC;SACvC,CAAC;yCAM4B,SAAS;OAL1B,eAAe,CA2B3B;IAAD,sBAAC;CAAA,AA3BD,IA2BC;SA3BY,eAAe"}

View File

@@ -1,12 +1,5 @@
export var environment = {
production: false,
config: {
tenant: 'c21eeb5f-f5a6-44e8-a997-124f2f7a497c',
clientId: '40742f13-bde8-4b1b-ac07-54c11b36b779',
postLogoutRedirectUri: 'http://localhost:4200',
endpoints: {
'http://localhost:4200/': 'the id'
}
}
apiVersionPath: '/api/v1'
};
//# sourceMappingURL=environment.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../../../../src/environments/environment.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,WAAW,GAAG;IACzB,UAAU,EAAE,KAAK;IACjB,MAAM,EAAE;QACN,MAAM,EAAE,sCAAsC;QAC9C,QAAQ,EAAE,sCAAsC;QAChD,qBAAqB,EAAE,uBAAuB;QAC9C,SAAS,EAAE;YACT,wBAAwB,EAAE,QAAQ;SACnC;KACF;CACF,CAAC"}
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../../../../src/environments/environment.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,WAAW,GAAG;IACzB,UAAU,EAAE,KAAK;IACjB,cAAc,EAAE,SAAS;CAC1B,CAAC"}

View File

@@ -1,4 +1,5 @@
export var environment = {
production: true
production: true,
apiVersionPath: '/api/v1'
};
//# sourceMappingURL=environment.prod.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"environment.prod.js","sourceRoot":"","sources":["../../../../src/environments/environment.prod.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,WAAW,GAAG;IACzB,UAAU,EAAE,IAAI;CACjB,CAAC"}
{"version":3,"file":"environment.prod.js","sourceRoot":"","sources":["../../../../src/environments/environment.prod.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,WAAW,GAAG;IACzB,UAAU,EAAE,IAAI;IAChB,cAAc,EAAE,SAAS;CAC1B,CAAC"}

Binary file not shown.

128
dist/qmi-cloud/assets/faq.md vendored Normal file
View File

@@ -0,0 +1,128 @@
# FAQ
Just an assorted selection of questions and answers.
### 1\. What can I use QMI Cloud for?
- QMI Cloud scenarios can be used to perform product demonstrations, enablement sessions and PoC environments. It is built to aid with Customer Engagements.
* * *
### 2\. Are these QMI scenarios ready to go End-To-End demos?
- Not at this moment, a global environment is being built for PreSales by GEAR.
- Provided scenarios are meant for (See 1). QMI works by installing licensing the products. QMI completes the main setup for the scenario to properly work where possible. You may need to put custom data, Qlik Sense applications or whatever you need for your customer engagement.
* * *
### 3\. Where are QMI Cloud resources deployed?
- All cloud resources such as Virtual Machines (VMs), disks, etc are deployed in the Qlik Azure subscription.
- For the time being, all resources are deployed in the __East US__ region in Azure. This means that it could be some significant latency or delays if you are located in another region.
* * *
### 4\. What will happen when I provision a scenario?
- Necessary resources for that scenario to work are deployed within Azure.
- An email is sent to the owner (e.g. you) indicating whether the provision was successful or with failures.
- Upon success, all credentials and access information for this provision is sent with that email.
- From that moment, VMs will keep at 'Running' status for 4 full days.
- On day 3, an email is sent warning that in the next 24 hours the VMs will automatically stop.
- You can "extend" VMs at Running status. This will renew the 'Running' period for 4 extra days. Other way, VMs will automatically stop within the next 24 hours.
- You can monitor 'Running time' and 'Time remaining until auto stop' at all times.
- __Provision will be automatically destroyed after 10 days of inactivity (10 days with Stopped VMs). On day 9 you'll get a warning email advising this will happen in 24 hours.__
* * *
### 5\. How many scenarios can I have provisioned at the same time?
- There is no limitation on the number of scenarios (or instances of the same one) provisioned at the same time. Just be aware of COST and keep VMs Stopped when possible.
- Do not forget to Destroy those provisions that you no longer need.
* * *
### 6\. Are scenarios accessible from the Internet or just from within Qlik VPN?
- All scenarios are accessible from within the Qlik VPN.
- Some are also accessible from the Intenet (external access). This is indicated on the UI for each scenario.
* * *
### 7\. Is QMI Cloud under the 'Qlik Customer Engagement Terms' policy?
- Yes.
- Only anonymous or public/free data can be used.
- Customer data is available with QSE SaaS, work is being done to aid PreSales manage 3rd Party data.
* * *
### 8\. Do scenarios communicate with each other?
- Yes.
- Private IPs assigned to all VMs are reachable.
- All ports are open for these private IPs (within the Qlik VPN).
* * *
### 9\. What can I do if I don't find a scenario that suits my needs?
- You can create end-to-end more complete demos with different Qlik products using combination of multiple scenarios.
- For example, if you needed an NPrinting demo/poc, you could use Qlik Sense scenario and Windows Blank scenario, then you can install NPrinting in this Windows Blank scenario and complete the setup yourself.
* * *
### 10\. Who is paying for these instances?
- The costs for these instances are allocated to PreSales.
- It is essential that we are all cost consciouse setup yourself.
* * *
### 11\. Can I manually stop and start the scenarios?
- Yes.
* * *
### 12\. If I shutdown the scenario, does it allocate a new IP Address?
- No.
* * *
### 13\. Are the mandatory security tools installed on these instances?
- Yes.
- Security is key for Qlik, whilst these are initially installed (Cabon Black on Windows, CrowdStrike on Linux) it is your responsibility as the owner of this instance to ensure everything is upto date.
* * *
### 14\. Can I create new instances?
- This capability will be described soon.
* * *
### 15\. How are we managing Costs?
- Excessive use for instances, will need to be justified, every instance logged it tagged with your trigram. The usage of QMI Cloud will be made public within a Qlik Sense Application.
- GEAR is looking at estimating the price for each server that you initiate.
* * *
### 16\. My Team use a team server; can I use this as well?
- This is open to everyone, if you do have a team server, then for cost purposes, please use that server.
* * *

View File

@@ -6,8 +6,8 @@
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="assets/favicon.ico">
<link rel="stylesheet" href="styles.a176d817fea8bea6cd9e.css"></head>
<link rel="stylesheet" href="styles.529f751cbb5308365172.css"></head>
<body>
<app-root></app-root>
<script src="runtime.689ba4fd6cadb82c1ac2.js" defer></script><script src="polyfills-es5.f752a17531a45fe93c1f.js" nomodule defer></script><script src="polyfills.06ba8d1a3d9dd3a8e8b9.js" defer></script><script src="scripts.cc5d7fb76aa54d397727.js" defer></script><script src="main.09d3646b3fdc1d594bb9.js" defer></script></body>
<script src="runtime.689ba4fd6cadb82c1ac2.js" defer></script><script src="polyfills-es5.f752a17531a45fe93c1f.js" nomodule defer></script><script src="polyfills.06ba8d1a3d9dd3a8e8b9.js" defer></script><script src="scripts.6866cf66954a0b739d41.js" defer></script><script src="main.b7d3a2d901b927013a9e.js" defer></script></body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -34,7 +34,8 @@ services:
MONGO_INITDB_ROOT_PASSWORD: example
networks:
- backend
ports:
- "27017:27017"
app:
build: .
@@ -47,7 +48,9 @@ services:
environment:
#- HOSTNAME_URL=https://qmi-cloud:3100
- REDIS_URL=redis://redis
- MONGO_URI=mongodb://root:example@mongo/qmi?authSource=admin
- MONGO_URI=mongodb://root:example@mongo/qmicloud?authSource=admin
#- CERT_PFX_FILENAME=wildcard_qliktech_com.pfx
#- CERT_PFX_PASSWORD=xxxxxxxxxxx
command:
- ./server/wait-for.sh
- --timeout=20
@@ -78,7 +81,7 @@ services:
replicas: 2
environment:
- REDIS_URL=redis://redis
- MONGO_URI=mongodb://root:example@mongo/qmi?authSource=admin
- MONGO_URI=mongodb://root:example@mongo/qmicloud?authSource=admin
- PROJECT_PATH=${PWD}
- SSHPATH=/Users/aor/.ssh
command: "sh -c 'npm run worker:dev'"

View File

@@ -1,7 +1,7 @@
export VERSION=$(cat package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]')
docker build -f ./docker-server/Dockerfile -t qlikgear/qmi-cloud-app:$VERSION ./
docker build -f ./docker-app/Dockerfile -t qlikgear/qmi-cloud-app:$VERSION ./
docker build -f ./docker-worker/Dockerfile -t qlikgear/qmi-cloud-worker:$VERSION ./
docker build -f ./docker-server/Dockerfile -t qlikgear/qmi-cloud-app:latest ./
docker build -f ./docker-app/Dockerfile -t qlikgear/qmi-cloud-app:latest ./
docker build -f ./docker-worker/Dockerfile -t qlikgear/qmi-cloud-worker:latest ./
echo "$DOCKER_REGISTRY_PASSWORD" | docker login -u "$DOCKER_REGISTRY_USER" --password-stdin
docker push qlikgear/qmi-cloud-app:$VERSION

82
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "qmi-cloud",
"version": "1.0.6",
"version": "1.0.9",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1873,6 +1873,11 @@
}
}
},
"@types/marked": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.7.4.tgz",
"integrity": "sha512-fdg0NO4qpuHWtZk6dASgsrBggY+8N4dWthl1bAQG9ceKUNKFjqpHaDKCAhRUI6y8vavG7hLSJ4YBwJtZyZEXqw=="
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@@ -3812,6 +3817,17 @@
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
"dev": true
},
"clipboard": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz",
"integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==",
"optional": true,
"requires": {
"good-listener": "^1.2.2",
"select": "^1.1.2",
"tiny-emitter": "^2.0.0"
}
},
"cliui": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
@@ -4957,6 +4973,12 @@
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"delegate": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
"optional": true
},
"denque": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
@@ -6831,6 +6853,15 @@
}
}
},
"good-listener": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
"optional": true,
"requires": {
"delegate": "^3.1.2"
}
},
"got": {
"version": "6.7.1",
"resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
@@ -8523,6 +8554,14 @@
"source-map-support": "^0.5.5"
}
},
"katex": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.11.1.tgz",
"integrity": "sha512-5oANDICCTX0NqYIyAiFCCwjQ7ERu3DQG2JFHLbYOf+fXaMoH8eg/zOq5WSYJsKMi/QebW+Eh3gSM+oss1H/bww==",
"requires": {
"commander": "^2.19.0"
}
},
"killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@@ -9004,6 +9043,11 @@
"object-visit": "^1.0.0"
}
},
"marked": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz",
"integrity": "sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw=="
},
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -9570,11 +9614,27 @@
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw=="
},
"ngx-markdown": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/ngx-markdown/-/ngx-markdown-9.0.0.tgz",
"integrity": "sha512-wcXMxA4Skgk9SzhfDRjihap/Kjq17jmMQiE/Ccp0bNibGaDgS5DbZiPBlMNLkp669UvjY9wVuxE4NuDtmQHS9w==",
"requires": {
"@types/marked": "^0.7.2",
"katex": "^0.11.0",
"marked": "^0.8.0",
"prismjs": "^1.16.0"
}
},
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
},
"node-fetch-npm": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.3.tgz",
@@ -11164,6 +11224,14 @@
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
},
"prismjs": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.20.0.tgz",
"integrity": "sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ==",
"requires": {
"clipboard": "^2.0.0"
}
},
"private": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
@@ -12045,6 +12113,12 @@
"ajv-keywords": "^3.1.0"
}
},
"select": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
"optional": true
},
"select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@@ -13480,6 +13554,12 @@
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
},
"tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
"optional": true
},
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "qmi-cloud",
"version": "1.0.7",
"version": "1.0.10",
"scripts": {
"start": "node -r esm server/server.js",
"dev": "nodemon -r esm server/server.js",
@@ -44,8 +44,11 @@
"hammerjs": "^2.0.8",
"jsonwebtoken": "^8.5.1",
"leonardo-ui": "^1.7.1",
"moment": "^2.24.0",
"mongoose": "^5.7.4",
"ms-rest-azure": "^3.0.0",
"ngx-markdown": "^9.0.0",
"node-fetch": "^2.6.0",
"nodemailer": "^6.4.2",
"nodemon": "^1.19.1",
"passport": "^0.4.0",

View File

@@ -1,4 +0,0 @@
#/bin/bash
git pull origin master
docker-compose rm -s -f
docker-compose up -d

View File

@@ -1,21 +1,13 @@
const MsRest = require('ms-rest-azure');
var computeManagementClient = require('azure-arm-compute');
const SUBSCRIPTION_ID = "62ebff8f-c40b-41be-9239-252d6c0c8ad9";
const db = require("./mongo");
const sendEmail = require("./send-email");
var computeClient;
function auth(cb) {
if ( computeClient ) {
cb(computeClient);
} else {
MsRest.loginWithMSI({ port: 50342 }, function(err, credentials){
if (err) {
console.log("Could not authenticate with Azure", err);
return;
}
computeClient = new computeManagementClient(credentials, SUBSCRIPTION_ID);
cb(computeClient);
});
}
async function _getClient() {
var credentials = await MsRest.loginWithMSI({ port: 50342 });
console.log("Azure CLI authenticated", credentials);
return new computeManagementClient(credentials, SUBSCRIPTION_ID);
}
async function asyncForEach(array, callback) {
@@ -24,56 +16,55 @@ async function asyncForEach(array, callback) {
}
}
function deallocate(resourceGroupName, cb) {
try {
console.log("Deallocating VMs for resource group: "+resourceGroupName);
auth(async function(computeClient){
let finalResult = await computeClient.virtualMachines.list(resourceGroupName);
let out = [];
await asyncForEach(finalResult, async function(vm) {
let res = await computeClient.virtualMachines.deallocate(resourceGroupName, vm.name);
out.push(res);
});
console.log("All VMs DEALLOCATED for resource group: "+resourceGroupName);
cb(null, out);
})
} catch (err) {
console.log("Error deallocating VMs for resource group: "+resourceGroupName);
cb(err, null);
async function deallocate(provision, isSendEmailAfter ) {
let rgName = provision.scenario.toUpperCase();
rgName = rgName.replace(/AZQMI/g, 'QMI');
rgName = rgName + "-" + provision._id.toString();
db.provision.update(provision._id, {"statusVms": "Stopping"});
console.log("Deallocating VMs for resource group: "+rgName);
var computeClient = await _getClient();
let finalResult = await computeClient.virtualMachines.list(rgName);
await asyncForEach(finalResult, async function(vm) {
await computeClient.virtualMachines.deallocate(rgName, vm.name);
});
let timeRunning = db.utils.getNewTimeRunning(provision);
await db.provision.update(provision._id.toString(), {"statusVms": "Stopped", "timeRunning": timeRunning, "stoppedFrom": new Date(), "pendingNextAction": undefined});
if ( isSendEmailAfter && provision._scenario) {
await sendEmail.sendVMsStopped(provision, provision._scenario);
}
console.log("All VMs DEALLOCATED for resource group: "+rgName);
}
function start(resourceGroupName, cb){
try {
console.log("Starting VMs for resource group: "+resourceGroupName);
auth(async function(computeClient){
let finalResult = await computeClient.virtualMachines.list(resourceGroupName);
let out = [];
await asyncForEach(finalResult, async function(vm) {
let res = await computeClient.virtualMachines.start(resourceGroupName, vm.name);
out.push(res);
});
console.log("All VMs RUNNING for resource group: "+resourceGroupName);
cb(null,out);
});
} catch (err) {
console.log("Error starting VMs for resource group: "+resourceGroupName);
cb(err, null);
}
async function start(provision){
let rgName = provision.scenario.toUpperCase();
rgName = rgName.replace(/AZQMI/g, 'QMI');
rgName = rgName + "-" + provision._id.toString();
db.provision.update(provision._id, {"statusVms": "Starting"});
console.log("Starting VMs for resource group: "+rgName);
var computeClient = await _getClient();
let finalResult = await computeClient.virtualMachines.list(rgName);
await asyncForEach(finalResult, async function(vm) {
await computeClient.virtualMachines.start(rgName, vm.name);
});
let countExtend = db.utils.getNewCountExtend(provision);
await db.provision.update(provision._id.toString(), {"statusVms": "Running", "runningFrom": new Date(), "countExtend": countExtend, "pendingNextAction": undefined});
console.log("All VMs RUNNING for resource group: "+rgName);
}
function getResourceGroupVms(resourceGroupName, cb){
auth(function(computeClient){
computeClient.virtualMachines.list(resourceGroupName, cb);
});
async function getResourceGroupVms(rgName){
return await computeClient.virtualMachines.list(rgName);
}
function getAllVms(cb){
auth(function(computeClient){
computeClient.virtualMachines.listAll(cb);
});
async function getAllVms(){
return await computeClient.virtualMachines.listAll(rgName);
}
module.exports.start = start;

4
server/checkstop.sh Executable file
View File

@@ -0,0 +1,4 @@
BASEDIR=$(dirname "$0")
d=`date`
echo "------ $d"
MONGO_URI=mongodb://root:example@localhost:27017/qmicloud?authSource=admin node $BASEDIR/stop5.js $1 $2 $3

152
server/destroy5.js Normal file
View File

@@ -0,0 +1,152 @@
var myArgs = process.argv.slice(2);
if ( myArgs.length < 3 ) {
console.log("Missing args", myArgs);
process.exit(0);
}
var db = require('./mongo');
const sendEmail = require("./send-email");
const moment = require('moment');
const fetch = require('node-fetch');
const IS_REAL = myArgs[2] !== 'test';
const STOPPED_PERIOD = myArgs[1]; //Days
const STOPPED_LIMIT_HOURS_WARNING = 24*(STOPPED_PERIOD-1); //Hours
const STOPPED_LIMIT_HOURS_STOP = 24*STOPPED_PERIOD; //Hours
const API_KEY = process.env.API_KEY;
const SERVER_URL = "http://localhost:3000";
if ( !API_KEY ) {
console.log("Missing env API_KEY");
process.exit(0);
}
async function postDestroy(provision) {
const userId = provision.user._id.toString();
const provId = provision._id.toString();
return fetch(`${SERVER_URL}/api/v1/users/${userId}/provisions/${provId}/destroy?apiKey=${API_KEY}`, {
method: 'POST',
headers:{
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(json => console.log(json));
}
function timeRunning(p) {
let totalStopTime = Math.abs(new Date().getTime() - new Date(p.stoppedFrom).getTime());
let duration = moment.duration(totalStopTime);
p.duration = {
hours: Math.floor(duration.asHours()),
complete: Math.floor(duration.asDays()) +"d "+duration.hours()+"h "+duration.minutes()
};
}
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
async function init(type) {
var limit, cb;
var filter = {
"isDestroyed":false,
"isDeleted": false,
"statusVms": "Stopped"
};
if ( type === "warning" ) {
limit = STOPPED_LIMIT_HOURS_WARNING;
filter.pendingNextAction = {$ne: "destroy"};
cb = doSendEmailDestroyWarning;
} else if ( type === "destroy" ) {
limit = STOPPED_LIMIT_HOURS_STOP;
filter.pendingNextAction = "destroy";
cb = doDestroy;
} else {
console.log("Invalid 'type'. Do nothing.");
return;
}
let provisions = await db.provision.get(filter);
let scenarios = await db.scenario.get();
await asyncForEach(provisions.results, async function(p) {
var _scenario = scenarios.results.filter(s=>{
return s.name === p.scenario
});
if ( _scenario.length ){
p._scenario = _scenario[0];
}
timeRunning(p);
if (!IS_REAL) {
console.log(`${p._id} - limit: ${limit} hs - actual duration: ${p.duration.hours} hs`);
}
if ( p.duration && p.duration.hours >= limit) {
await cb(p);
}
});
}
const doSendEmailDestroyWarning = async function(p) {
if ( p.pendingNextAction === 'destroy') {
console.log(`Warning email Destroy already sent. Wait for pending action to complete.`);
} else {
let msg = `Send warning DESTROY email - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenario.title}' (${p._id}) being 'Inactive' more than ${STOPPED_LIMIT_HOURS_WARNING} hours (exactly ${p.duration.complete})`;
console.log(msg);
if ( IS_REAL ) {
await db.provision.update(p._id, {"pendingNextAction": "destroy"});
await sendEmail.sendWillDestroyIn24(p, p._scenario);
await db.notification.add({ provision: p._id.toString(), type: 'warningDestroy', message: msg });
}
}
};
const doDestroy = async function(p) {
try {
let msg = `Provision destroyed - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenario.title}' (${p._id}) being 'Inactive' more than ${STOPPED_LIMIT_HOURS_STOP} hours (exactly ${p.duration.complete})`
console.log(msg);
if ( IS_REAL ) {
await postDestroy(p);
await db.notification.add({ provision: p._id.toString(), type: 'destroy', message: msg });
}
} catch (error) {
console.log("doDestroy Error", error);
}
};
function check(type) {
init(type).then(function(){
db.mongoose.connection.close()
process.exit(0);
}).catch(function(e){
db.mongoose.connection.close()
console.log("Error", e);
process.exit(0);
});
}
// --------------------------------
switch (myArgs[0]) {
case 'warning':
check("warning");
break;
case 'destroy':
check("destroy");
break;
default:
console.log('Sorry, that is not something I know how to do.');
process.exit(0);
}

57
server/fix.js Normal file
View File

@@ -0,0 +1,57 @@
var db = require('./mongo');
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
async function toObjectId(model, fieldName){
var filter = {};
filter[fieldName] = {$type : 2};
var results = await model.find(filter);
try {
await asyncForEach(results, async function(d) {
var oldId = d[fieldName];
var remFilter = {};
remFilter[fieldName] = oldId;
await model.deleteOne(remFilter);
console.log("Deleted!", oldId);
Object.entries(d).forEach(async function([key, value]){
if ( key === "_doc") {
await db.scenario.add(value);
console.log("Saved new");
}
});
//console.log("new doc", d);
//await db.scenario.add(d);
//await model.create(d);
//console.log("SaVED");
});
} catch (e) {
console.log("er", e);
}
}
async function destroyStuff(){
var results = await Destroy.find({provId:{$type : 2}});
await asyncForEach(results, async function(d) {
console.log("doc", d);
var destroy = d._id;
await Provision.updateOne({_id: d.provId}, {destroy: destroy});
d.provId = undefined;
d.save();
});
}
toObjectId(db.models.Scenario, "_id");
//toObjectId(Destroy, "userId", "user");
//destroyStuff();

29
server/models/ApiKey.js Normal file
View File

@@ -0,0 +1,29 @@
const mongoose = require('mongoose');
mongoose.set('useFindAndModify', false);
const crypto = require("crypto");
//mongoose.set('debug', true)
const schema = new mongoose.Schema({
user: {
type: mongoose.Types.ObjectId, ref: 'User'
},
created: {
type: Date,
default: Date.now
},
updated: {
type: Date,
default: Date.now
},
apiKey: {
type: String,
default: function() {
return crypto.randomBytes(64).toString('hex');
},
index: true
}
});
module.exports = mongoose.model('ApiKey', schema)

View File

@@ -4,9 +4,6 @@ mongoose.set('useFindAndModify', false);
const destroySchema = new mongoose.Schema({
userId: {
type: mongoose.Types.ObjectId, ref: 'User'
},
user: {
type: mongoose.Types.ObjectId, ref: 'User'
},
@@ -23,8 +20,7 @@ const destroySchema = new mongoose.Schema({
default: "queued"
},
logFile: String,
jobId: String,
provId: String
jobId: String
});

View File

@@ -0,0 +1,28 @@
const mongoose = require('mongoose');
mongoose.set('useFindAndModify', false);
//mongoose.set('debug', true)
const sc = new mongoose.Schema({
created: {
type: Date,
default: Date.now
},
updated: {
type: Date,
default: Date.now
},
type: {
type: String
},
message: {
type: String
},
provision: {
type: mongoose.Types.ObjectId, ref: 'Provision',
index: true
}
});
module.exports = mongoose.model('Notification', sc)

View File

@@ -3,11 +3,9 @@ mongoose.set('useFindAndModify', false);
//mongoose.set('debug', true)
const provisionSchema = new mongoose.Schema({
userId: {
type: mongoose.Types.ObjectId, ref: 'User'
},
user: {
type: mongoose.Types.ObjectId, ref: 'User'
type: mongoose.Types.ObjectId, ref: 'User',
index: true
},
created: {
type: Date,
@@ -18,6 +16,8 @@ const provisionSchema = new mongoose.Schema({
default: Date.now
},
scenario: String,
description: String,
vmImage: Object,
vmType: String,
nodeCount: Number,
status: {
@@ -34,7 +34,8 @@ const provisionSchema = new mongoose.Schema({
},
isDeleted: {
type: Boolean,
default: false
default: false,
index: true
},
statusVms: {
type: String,
@@ -42,6 +43,23 @@ const provisionSchema = new mongoose.Schema({
},
destroy: {
type: mongoose.Types.ObjectId, ref: 'Destroy'
},
runningFrom: {
type: Date
},
stoppedFrom: {
type: Date
},
timeRunning: {
type: Number,
default: 0
},
countExtend: {
type: Number,
default: 0
},
pendingNextAction: {
type: String
}
});

View File

@@ -12,15 +12,36 @@ const scenarioSchema = new mongoose.Schema({
type: Date,
default: Date.now
},
version: String,
name: String,
isAdminOnly: Boolean,
title: String,
version: {
type: String,
requred: true
},
name: {
type: String,
requred: true
},
isAdminOnly: {
type: Boolean,
default: false
},
isWafPolicyAppGw: {
type: Boolean,
default: false
},
isExternal: {
type: Boolean,
default: false
},
title: {
type: String,
requred: true
},
description: String,
vmTypes: Array,
vmTypeDefault: String,
nodeCount: Number,
availableProductVersions: Array
availableProductVersions: Array,
productVersionDefault: String,
newImageName: String //For Gen scenarios
});

View File

@@ -2,9 +2,10 @@ const mongoose = require('mongoose');
const options = {
loggerLevel: 'error',
useNewUrlParser: true,
reconnectInterval: 2000,
reconnectTries: 30, // Retry up to 30 times
useCreateIndex: true
//reconnectInterval: 2000,
//reconnectTries: 30, // Retry up to 30 times
useCreateIndex: true,
useUnifiedTopology: true
};
// Connect to DB
@@ -23,8 +24,8 @@ mongoose.connection.on('reconnected', () => {
// If the connection throws an error
mongoose.connection.on('error', (err) => {
console.log(`dbevent: error: ${err}`);
console.log(`Retry mongo connect`);
mongoose.connect(process.env.MONGO_URI, options);
//console.log(`Retry mongo connect`);
//mongoose.connect(process.env.MONGO_URI, options);
});
// External Dependancies
@@ -36,37 +37,68 @@ const Destroy = require('./models/Destroy');
const User = require('./models/User');
const Scenario = require('./models/Scenario');
const VmType = require('./models/VmType');
const ApiKey = require('./models/ApiKey');
const Notification = require('./models/Notification');
const getOid = async (oid, reply) => {
const getNewCountExtend = function(provision) {
return provision.countExtend !== undefined? (provision.countExtend + 1) : 1;
};
const getNewTimeRunning = function (provision) {
let runningFrom = provision.runningFrom? new Date(provision.runningFrom).getTime() : new Date(provision.created).getTime();
let timeRunning = provision.timeRunning !== undefined? provision.timeRunning : 0; //minutes
let diffMinutes = Math.abs(new Date().getTime() - runningFrom)/1000/60;
let minutesFromLastRunning = Math.floor(diffMinutes);
return Math.floor(minutesFromLastRunning + timeRunning);
};
const get = async (model, filter, extras, reply) => {
var sort = extras && extras.sort? extras.sort : {created: -1};
try {
const entity = await User.findOne({ oid: oid});
return entity;
var exec = model.find(filter).sort(sort);
if ( extras && extras.skip ) {
exec = exec.skip(extras.skip);
}
if ( extras && extras.limit ) {
exec = exec.limit(extras.limit);
}
if ( model === Provision ) {
exec = exec.populate({ path: 'user', select: 'displayName upn'}).populate('destroy');
}
const entity = await exec;
return {
total: await model.countDocuments(filter),
results: entity
};
} catch (err) {
throw boom.boomify(err)
}
}
const getScenarioByName = async (name, reply) => {
const getById = async (model, id, reply) => {
try {
const entity = await Scenario.findOne({ name: name});
var exec = model.findById(id);
if ( model === Provision ) {
exec = exec.populate({ path: 'user', select: 'displayName upn'}).populate('destroy');
}
const entity = await exec;
return entity;
} catch (err) {
throw boom.boomify(err)
throw boom.boomify(err);
}
}
};
const get = async (model, filter, reply) => {
const getOne = async (model, filter, reply) => {
try {
const entity = await model.find(filter).sort({created: -1}).populate('user').populate('destroy');
return entity;
} catch (err) {
throw boom.boomify(err)
}
}
const getSingle = async (model, id, reply) => {
try {
const entity = await model.findById(id).populate('user').populate('destroy');
var exec = model.findOne(filter);
if ( model === Provision ) {
exec = exec.populate('user').populate('destroy');
}
const entity = await exec;
return entity;
} catch (err) {
throw boom.boomify(err);
@@ -86,7 +118,12 @@ const update = async (model, id, body, reply) => {
try {
const { ...updateData } = body;
updateData.updated = new Date();
const update = await model.findByIdAndUpdate(id, updateData, { new: true }).populate('user').populate('destroy');
console.log("UPDATE", id, updateData);
var exec = model.findByIdAndUpdate(id, updateData, { new: true });
if ( model === Provision ) {
exec = exec.populate('user').populate('destroy');
}
const update = await exec;
return update;
} catch (err) {
throw boom.boomify(err)
@@ -104,11 +141,14 @@ const del = async (model, id, reply) => {
function _m(model) {
return {
get: async (filter, reply) => {
return get(model, filter, reply);
get: async (filter, extras, reply) => {
return get(model, filter, extras, reply);
},
getSingle: async (id, reply) => {
return getSingle(model, id, reply);
getById: async (id, reply) => {
return getById(model, id, reply);
},
getOne: async (filter, reply)=> {
return getOne(model, filter, reply);
},
add: async (data, reply) => {
return add(model, data, reply);
@@ -122,80 +162,30 @@ function _m(model) {
}
}
const mScenarios = _m(Scenario);
mScenarios.getScenarioByName = getScenarioByName;
module.exports = {
provision: _m(Provision),
destroy: _m(Destroy),
scenario: mScenarios,
scenario: _m(Scenario),
vmtype: _m(VmType),
user: {
get: async (filter, reply) => {
return get(User, filter, reply);
},
getOid: async (oid, reply) => {
return getOid(oid, reply);
},
getSingle: async (req, reply) => {
return getSingle(User, req, reply);
},
add: async (data, reply) => {
return add(User, data, reply);
},
update: async (data, reply) => {
return update(User, data, reply);
}
apiKey: _m(ApiKey),
notification: _m(Notification),
user: _m(User),
utils: {
getNewTimeRunning: getNewTimeRunning,
getNewCountExtend: getNewCountExtend
},
mongoose: mongoose,
models: {
Provision: Provision,
Destroy: Destroy,
Scenario: Scenario,
User: User,
VmType: VmType,
Notification: Notification,
ApiKey: ApiKey
}
}
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
async function toObjectId(model, fieldName, fieldNameTemp){
var filter = {};
filter[fieldName] = {$type : 2};
var results = await model.find(filter);
await asyncForEach(results, async function(d) {
console.log("doc", d);
var newId = mongoose.Types.ObjectId(d[fieldName]); // to ObjectId
var oldId = d[fieldName];
d[fieldName] = undefined;
d[fieldNameTemp] = newId;
await model.create(d);
var remFilter = {};
remFilter[fieldName] = oldId;
await model.remove(remFilter);
});
}
async function destroyStuff(){
var results = await Destroy.find({provId:{$type : 2}});
await asyncForEach(results, async function(d) {
console.log("doc", d);
var destroy = d._id;
await Provision.updateOne({_id: d.provId}, {destroy: destroy});
d.provId = undefined;
d.save();
});
}
toObjectId(Provision, "userId", "user");
toObjectId(Destroy, "userId", "user");
destroyStuff();
};

View File

@@ -32,7 +32,7 @@ passport.deserializeUser(function(oid, done) {
});
var _findByOid = async function(oid, fn) {
var mongouser = await db.user.getOid(oid);
var mongouser = await db.user.getOne({"oid": oid});
if (mongouser && mongouser.oid === oid){
return fn(null, mongouser);
} else {
@@ -197,29 +197,42 @@ module.exports.init = function(app){
});
};
module.exports.ensureAuthenticatedDoLogin = function(req, res, next) {
if ( req.isAuthenticated() ) {
async function isApiKeyAuthenticated(req) {
if (req.query && req.query.apiKey){
let key = req.query.apiKey;
var result = await db.apiKey.get({apiKey: key});
if ( result.length > 0 ) {
req.user = result[0].user;
}
return result.length > 0;
}else {
return false;
}
}
module.exports.ensureAuthenticatedDoLogin = async function(req, res, next) {
if ( await isApiKeyAuthenticated(req) || req.isAuthenticated() ) {
return next();
}
res.redirect('/login');
};
module.exports.ensureAuthenticated = function(req, res, next) {
if ( req.isAuthenticated() ) {
module.exports.ensureAuthenticated = async function(req, res, next) {
if ( await isApiKeyAuthenticated(req) || req.isAuthenticated() ) {
return next();
}
res.status(401).send({"error": "Unauthorized"});
};
module.exports.ensureAuthenticatedAndAdmin = function(req, res, next) {
if ( req.isAuthenticated() && (req.user.role === 'admin' || req.user.role === 'superadmin') ) {
module.exports.ensureAuthenticatedAndAdmin = async function(req, res, next) {
if ( ( await isApiKeyAuthenticated(req) || req.isAuthenticated()) && (req.user.role === 'admin' || req.user.role === 'superadmin') ) {
return next();
}
res.status(401).send({"error": "Unauthorized"});
};
module.exports.ensureAuthenticatedAndIsMe = function (req, res, next) {
if ( req.isAuthenticated() ) {
module.exports.ensureAuthenticatedAndIsMe = async function (req, res, next) {
if ( await isApiKeyAuthenticated(req) || req.isAuthenticated() ) {
if ( req.user._id == req.params.userId || req.user.role === 'admin' || req.user.role === 'superadmin' ) {
return next();
} else {

View File

@@ -48,7 +48,7 @@ router.get('/', passport.ensureAuthenticatedAndAdmin, async (req, res, next) =>
*/
router.get('/:id', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
try {
const mongoJob = await db.destroy.getSingle(req.params.id);
const mongoJob = await db.destroy.getById(req.params.id);
if (!mongoJob){
return res.status(404).json({"msg": "Not found"});
}
@@ -79,7 +79,7 @@ router.get('/:id', passport.ensureAuthenticatedAndAdmin, async (req, res, next)
*/
router.get('/:id/logs', passport.ensureAuthenticated ,async (req, res, next) => {
try {
const mongoJob = await db.destroy.getSingle(req.params.id);
const mongoJob = await db.destroy.getById(req.params.id);
if (!mongoJob){
return res.status(404).json({"msg": "Not found"});
}

View File

@@ -13,13 +13,36 @@ const fs = require('fs-extra');
* summary: Get all Provisions (Only admin)
* produces:
* - application/json
* parameters:
* - name: filter
* in: query
* required: false
* type: object
* content:
* application/json:
* schema:
* type: object
* - name: extras
* in: query
* required: false
* type: object
* content:
* application/json:
* schema:
* type: object
* responses:
* 200:
* description: JSON Array
*/
router.get('/', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
try {
const result = await db.provision.get({"isDeleted": false});
try {
let filter = req.query.filter? JSON.parse(req.query.filter) : {};
if ( filter.isDeleted === undefined ) {
filter.isDeleted = false;
}
let extras = req.query.extras? JSON.parse(req.query.extras) : {};
const result = await db.provision.get(filter, extras);
return res.json(result);
} catch (error) {
next(error);
@@ -48,7 +71,7 @@ router.get('/', passport.ensureAuthenticatedAndAdmin, async (req, res, next) =>
*/
router.get('/:id', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
try {
const mongoJob = await db.provision.getSingle(req.params.id);
const mongoJob = await db.provision.getById(req.params.id);
if (!mongoJob){
return res.status(404).json({"msg": "Not found"});
}
@@ -81,7 +104,7 @@ router.get('/:id', passport.ensureAuthenticatedAndAdmin, async (req, res, next)
*/
router.delete('/:id', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
try {
const mongoJob = await db.provision.getSingle(req.params.id);
const mongoJob = await db.provision.getById(req.params.id);
if (!mongoJob){
return res.status(404).json({"msg": "Not found"});
}
@@ -119,7 +142,7 @@ router.delete('/:id', passport.ensureAuthenticatedAndAdmin, async (req, res, nex
*/
router.get('/:id/logs', passport.ensureAuthenticated, async (req, res, next) => {
try {
const mongoJob = await db.provision.getSingle(req.params.id);
const mongoJob = await db.provision.getById(req.params.id);
if (!mongoJob){
return res.status(404).json({"msg": "Not found"});
}

View File

@@ -3,6 +3,17 @@ const router = express.Router()
const db = require('../mongo.js');
const passport = require('../passport');
router.get('/all', passport.ensureAuthenticated, async (req, res, next) => {
try {
const result = await db.scenario.get();
return res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /scenarios:
@@ -17,13 +28,12 @@ const passport = require('../passport');
*/
router.get('/', passport.ensureAuthenticated, async (req, res, next) => {
try {
const result = await db.scenario.get();
const filter = {};
if (req.user.role === "user") {
return res.json(result.filter( (s)=>!s.isAdminOnly));
} else {
return res.json(result);
filter.isAdminOnly = false;
}
const result = await db.scenario.get(filter);
return res.json(result);
} catch (error) {
next(error);
@@ -61,34 +71,52 @@ router.get('/vmtypes', passport.ensureAuthenticated, async (req, res, next) => {
* summary: Add new scenario (Only Admin)
* produces:
* - application/json
* parameters:
* - in: body
* name: body
* description: Scenario object
* required: true
* schema:
* type: object
* properties:
* name:
* type: string
* description:
* type: string
* version:
* type: string
* vmTypes:
* type: array
* items:
* type: object
* availableProductVersions:
* type: array
* items:
* type: object
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* title:
* type: string
* description:
* type: string
* version:
* type: string
* isAdminOnly:
* type: boolean
* isExternal:
* type: boolean
* availableProductVersions:
* type: array
* items:
* type: object
* properties:
* product:
* type: string
* vmTypeDefault:
* type: string
* index:
* type: string
* versions:
* type: array
* items:
* type: object
* properties:
* name:
* type: string
* image:
* type: string
* responses:
* 200:
* description: Scenario
*/
router.post('/', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
try {
console.log("BODY", req.body);
const result = await db.scenario.add(req.body);
return res.json(result);
} catch (error) {
@@ -96,4 +124,36 @@ router.get('/vmtypes', passport.ensureAuthenticated, async (req, res, next) => {
}
});
/**
* @swagger
* /scenarios/{id}:
* put:
* description: Update scenario (Only Admin)
* summary: Update scenario (Only Admin)
* parameters:
* - name: id
* in: path
* type: string
* required: true
* - in: body
* name: body
* description: Scenario object
* required: true
* produces:
* - application/json
* responses:
* 200:
* description: User
*/
router.put('/:id', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
console.log(req.params.id, "req.body", req.body);
try {
const result = await db.scenario.update(req.params.id, req.body);
return res.json(result);
} catch (error) {
next(error);
}
});
module.exports = router;

View File

@@ -5,7 +5,6 @@ const passport = require('../passport');
const fs = require('fs-extra');
const azurecli = require('../azurecli');
import { queues, TF_APPLY_QUEUE, TF_APPLY_QSEOK_QUEUE, TF_DESTROY_QUEUE } from '../queues';
/**
@@ -43,7 +42,7 @@ router.get('/', passport.ensureAuthenticatedAndAdmin, async (req, res, next) =>
*/
router.get('/me', passport.ensureAuthenticated, async (req, res, next) => {
try {
const result = await db.user.getSingle(req.user._id);
const result = await db.user.getById(req.user._id);
return res.json(result);
} catch (error) {
next(error);
@@ -69,7 +68,7 @@ router.get('/me', passport.ensureAuthenticated, async (req, res, next) => {
*/
router.get('/:userId', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
const result = await db.user.getSingle(req.params.userId);
const result = await db.user.getById(req.params.userId);
return res.json(result);
} catch (error) {
next(error);
@@ -121,26 +120,56 @@ router.put('/:userId', passport.ensureAuthenticatedAndAdmin, async (req, res, ne
* in: path
* type: string
* required: true
* - in: body
* name: body
* description: Provision object
* required: true
* schema:
* type: object
* properties:
* scenario:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* scenario:
* type: string
* description:
* type: string
* vmImage:
* type: object
* properties:
* vm1:
* type: object
* properties:
* vmType:
* type: string
* version:
* type: object
* properties:
* name:
* type: string
* image:
* type: string
* responses:
* 200:
* description: Provision
* 404:
* description: Scenario not found
* 400:
* description: Invalid vmImage
*/
router.post('/:userId/provisions', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
req.body.user = req.params.userId;
const scenarioSource = await db.scenario.getOne({name: req.body.scenario});
if (!scenarioSource) {
return res.status(404).json({"msg": "Scenario not found "});
}
if (!req.body.vmImage || !req.body.vmImage.vm1 || !req.body.vmImage.vm1.vmType ) {
return res.status(400).json({"msg": "Invalid vmImage"});
}
const mongoJob = await db.provision.add(req.body);
const scenarioSource = await db.scenario.getScenarioByName(req.body.scenario);
if ( mongoJob.scenario === "azqmi-qseok" ){
queues[TF_APPLY_QSEOK_QUEUE].add("tf_apply_qseok_job", {
@@ -195,7 +224,8 @@ router.post('/:userId/provisions', passport.ensureAuthenticatedAndIsMe, async (r
*/
router.delete('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
const mongoJob = await db.provision.getSingle(req.params.id);
const mongoJob = await db.provision.getById(req.params.id);
if (!mongoJob){
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
}
@@ -238,27 +268,16 @@ router.delete('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, as
*/
router.post('/:userId/provisions/:id/deallocatevms', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
let mongoJob = await db.provision.getSingle(req.params.id);
let mongoJob = await db.provision.getById(req.params.id);
if (!mongoJob){
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
return res.status(404).json({"msg": "Not found provision with id "+req.params.id});
}
let rgName = mongoJob.scenario.toUpperCase();
rgName = rgName.replace(/AZQMI/g, 'QMI');
rgName = rgName + "-" + mongoJob._id.toString();
db.provision.update(req.params.id, {"statusVms": "Stopping"});
azurecli.deallocate(rgName, function(err, res){
if (err) {
db.provision.update(req.params.id, {"statusVms": "Error_Stopping"});
} else {
db.provision.update(req.params.id, {"statusVms": "Stopped"});
}
});
azurecli.deallocate(mongoJob);
return res.json({"statusVms": "Stopping"});
} catch (error) {
db.provision.update(req.params.id, {"statusVms": "Error_Stopping"});
next(error);
}
});
@@ -289,25 +308,63 @@ router.post('/:userId/provisions/:id/deallocatevms', passport.ensureAuthenticate
*/
router.post('/:userId/provisions/:id/startvms', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
let mongoJob = await db.provision.getSingle(req.params.id);
let mongoJob = await db.provision.getById(req.params.id);
if (!mongoJob){
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
}
let rgName = mongoJob.scenario.toUpperCase();
rgName = rgName.replace(/AZQMI/g, 'QMI');
rgName = rgName + "-" + mongoJob._id.toString();
db.provision.update(req.params.id, {"statusVms": "Starting"});
azurecli.start(rgName, function(err, res){
if (err) {
db.provision.update(req.params.id, {"statusVms": "Error_Starting"});
} else {
db.provision.update(req.params.id, {"statusVms": "Running"});
}
});
azurecli.start(mongoJob);
return res.json({"statusVms": "Starting"});
} catch (error) {
db.provision.update(req.params.id, {"statusVms": "Error_Starting"});
next(error);
}
});
/**
* @swagger
* /users/{userId}/provisions/{id}/extend:
* post:
* description: Extend this provision Running more time
* summary: Extend this provision Running more time
* produces:
* - application/json
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* - name: id
* in: path
* type: string
* required: true
* responses:
* 200:
* description: Provision
* 404:
* description: Not found
*
*/
router.post('/:userId/provisions/:id/extend', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
let mongoJob = await db.provision.getById(req.params.id);
if (!mongoJob){
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
}
/*if ( mongoJob.countExtend === 5 ) {
return res.status(200).json({"msg": "You have reached the limit for the number of times to extend the Running VMs period."});
}*/
let timeRunning = db.utils.getNewTimeRunning(mongoJob);
let countExtend = db.utils.getNewCountExtend(mongoJob);
mongoJob = await db.provision.update(req.params.id, {"runningFrom":new Date(), "timeRunning": timeRunning, "countExtend": countExtend, "pendingNextAction": undefined});
return res.json(mongoJob);
} catch (error) {
next(error);
}
@@ -315,7 +372,7 @@ router.post('/:userId/provisions/:id/startvms', passport.ensureAuthenticatedAndI
/**
* @swagger
* /users/{userId}/destroyprovisions:
* /users/{userId}/provisions/{id}/destroy:
* post:
* description: Destroy a Terraform Provision
* summary: Destroy a Terraform Provision
@@ -326,26 +383,29 @@ router.post('/:userId/provisions/:id/startvms', passport.ensureAuthenticatedAndI
* in: path
* type: string
* required: true
* - in: body
* name: body
* description: Provision object
* - name: id
* in: path
* type: string
* required: true
* schema:
* type: object
* properties:
* id:
* type: string
* responses:
* 200:
* description: Provision
* 404:
* description: Not found
*
*/
router.post('/:userId/destroyprovisions', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
router.post('/:userId/provisions/:id/destroy', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
req.body.userId = req.params.userId;
const destroyJob = await db.destroy.add({ "user": req.body.userId });
const mongoJob = await db.provision.update(req.body.id, {"destroy": destroyJob._id});
const scenarioSource = await db.scenario.getScenarioByName(mongoJob.scenario);
let mongoJob = await db.provision.getById(req.params.id);
if (!mongoJob){
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
}
const destroyJob = await db.destroy.add({ "user": req.params.userId });
mongoJob = await db.provision.update(req.params.id, {"destroy": destroyJob._id});
const scenarioSource = await db.scenario.getOne({name: mongoJob.scenario});
queues[TF_DESTROY_QUEUE].add("tf_destroy_job", {
scenario: mongoJob.scenario,
@@ -358,7 +418,7 @@ router.post('/:userId/destroyprovisions', passport.ensureAuthenticatedAndIsMe, a
return res.status(200).json(mongoJob);
} catch (error) {
next(error);
return res.status(error.output.statusCode).json({"err":error});
}
});
@@ -382,7 +442,8 @@ router.post('/:userId/destroyprovisions', passport.ensureAuthenticatedAndIsMe, a
router.get('/:userId/provisions', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
const result = await db.provision.get({"user": req.params.userId, "isDeleted": false});
const filter = {"user": req.params.userId, "isDeleted": false};
const result = await db.provision.get(filter);
return res.json(result);
} catch (error) {
next(error);

View File

@@ -3,6 +3,10 @@ const nodemailer = require('nodemailer');
const FROM = '"Qlik" <no-reply@qlik.com>';
var transporter;
const RUNNING_PERIOD = 4;
const STOP_PERIOD = 10;
if ( process.env.GMAIL_USERNAME && process.env.GMAIL_PASSWORD ) {
//GMAIL
transporter = nodemailer.createTransport({
@@ -23,7 +27,112 @@ if ( process.env.GMAIL_USERNAME && process.env.GMAIL_PASSWORD ) {
});
}
async function _doSend(to, subject, htmlText) {
// send mail with defined transport object
let info = await transporter.sendMail( {
from: FROM, // sender address
to: to, // list of receivers
subject: subject, // Subject line
text: subject, // plain text body
html: htmlText // html body
} );
console.log('Provision Email ('+info.messageId+') sent to: ' + to);
}
function _getCommonDetails(provision, scenario){
return `<div style="color:#404040;font-size:18px;margin:20px 0px">
<p style="margin:0px">Provision information:</p>
</div>
<div>
<span style="color:#404040">Purpose: </span> ${provision.description}
</div>
<div>
<span style="color:#404040">Scenario: </span> ${scenario.title}
</div>
<div>
<span style="color:#404040">Description: </span> ${scenario.description}
</div>
<div>
<span style="color:#404040">ProvisionID: </span> ${provision._id}
</div>`;
}
function getHtmlScenarioDestroyIn24( provision, scenario) {
var common = _getCommonDetails(provision,scenario);
return`<div style="width:600px;color:black!important;font-family:'Source Sans Pro',sans-serif;padding:50px">
<div style="background-color:white;height:100%;padding:20px 10px">
<div style="color:#404040;font-size:34px;text-align:center;margin:20px">
<p style="margin:0px">QMI Cloud</p>
</div>
<div style="color:#404040;font-size:22px;margin:20px 0px 40px 0px">
<p style="margin:0px">Provision '${scenario.title}' inactive more than ${(STOP_PERIOD - 1)} days</p>
</div>
<div style="color:#404040;font-size:18px;margin:10px 0px">
<p style="margin:0px;color: #FF2020">This scenario will be automatically DESTROYED in less than 24h.</p>
</div>
<div style="color:#404040;font-size:16px;margin:30px 0px">
<p style="margin:0px">If you don't want this to happen, you've got 24 hours (from when this email was sent) as a grace period to get back at 'Running' status this provision.</p>
</div>
${common}
<div style="color:#404040;font-size:16px;margin:30px 0px">
<p style="margin:0px">Check it out at <a href="https://qmicloud.qliktech.com">https://qmicloud.qliktech.com</a></p>
</div>
</div>
</div>`;
}
function getHtmlScenarioVMsStopped( provision, scenario) {
var common = _getCommonDetails(provision,scenario);
return `<div style="width:600px;color:black!important;font-family:'Source Sans Pro',sans-serif;padding:50px">
<div style="background-color:white;height:100%;padding:20px 10px">
<div style="color:#404040;font-size:34px;text-align:center;margin:20px">
<p style="margin:0px">QMI Cloud</p>
</div>
<div style="color:#404040;font-size:22px;margin:20px 0px 40px 0px">
<p style="margin:0px">Provision '${scenario.title}'</p>
</div>
<div style="color:#404040;font-size:18px;margin:10px 0px">
<p style="margin:0px;color: #FF2020">All VMs for this provision <b>stopped</b> automatically.</p>
</div>
<div style="color:#404040;font-size:16px;margin:30px 0px">
<p style="margin:0px">You can start them up again from <a href="https://qmicloud.qliktech.com">https://qmicloud.qliktech.com</a></p>
</div>
${common}
<div style="color:#404040;font-size:16px;margin:30px 0px">
<p style="margin:0px">Check it out at <a href="https://qmicloud.qliktech.com">https://qmicloud.qliktech.com</a></p>
</div>
</div>
</div>`;
}
function getHtmlScenarioWillStopIn24( provision, scenario ) {
var common = _getCommonDetails(provision,scenario);
return`<div style="width:600px;color:black!important;font-family:'Source Sans Pro',sans-serif;padding:50px">
<div style="background-color:white;height:100%;padding:20px 10px">
<div style="color:#404040;font-size:34px;text-align:center;margin:20px">
<p style="margin:0px">QMI Cloud</p>
</div>
<div style="color:#404040;font-size:22px;margin:20px 0px 40px 0px">
<p style="margin:0px">Provision '${scenario.title}'</p>
</div>
<div style="color:#404040;font-size:18px;margin:10px 0px">
<p style="margin:0px;color: #FF2020">This scenario will automatically stop its VMs in less than 24h.</p>
</div>
<div style="color:#404040;font-size:18px;margin:20px 0px 10px 0px">
<p style="margin:0px;color: #FF2020">Take action and extend the period ${RUNNING_PERIOD} extra days.</p>
</div>
<div style="color:#404040;font-size:16px;margin:30px 0px">
<p style="margin:0px">If you don't want the VMs to automatically stop, you've got 24 hours (from when this email was sent) as a grace period to extend this scenario's <b style="color: #009845">Running</b> VMs for ${RUNNING_PERIOD} extra days.</p>
</div>
${common}
<div style="color:#404040;font-size:16px;margin:30px 0px">
<p style="margin:0px">Check it out at <a href="https://qmicloud.qliktech.com">https://qmicloud.qliktech.com</a></p>
</div>
</div>
</div>`;
}
function getHtmlNewProvision(provision, scenario) {
var htmlint;
if ( provision && provision.outputs ) {
@@ -38,99 +147,64 @@ function getHtmlNewProvision(provision, scenario) {
</div>`;
}
return`<div style="width:600px;color:black!important;font-family:'Source Sans Pro',sans-serif;padding:50px">
var common = _getCommonDetails(provision, scenario);
return `<div style="width:600px;color:black!important;font-family:'Source Sans Pro',sans-serif;padding:50px">
<div style="background-color:white;height:100%;padding:20px 10px">
<p style="text-align:left;margin-bottom:30px;margin-left:0px">
<img src="https://www.qlik.com/us/-/media/images/qlik/global/qlik-logo-2x.png" width="150" height="32" alt="Qlik" style="border:0;height:auto;line-height:100%;outline:none;text-decoration:none" class="CToWUd">
</p>
<div style="color:#404040;font-size:34px;text-align:center;margin:20px">
<p style="margin:0px">QMI Cloud</p>
</div>
<div style="color:#404040;font-size:20px;margin:20px 0px">
<div style="color:#404040;font-size:22px;margin:20px 0px">
<p style="margin:0px">Scenario '${scenario.title}' successfully provisioned!</p>
</div>
<div style="color:#404040;font-size:18px;margin:20px 0px">
<p style="margin:0px">Scenario information:</p>
</div>
<div>
<span style="color:#404040">Scenario: </span> ${scenario.title}
</div>
<div>
<span style="color:#404040">Description: </span> ${scenario.description}
</div>
<div>
<span style="color:#404040">ProvisionID: </span> ${provision._id}
</div>
<div>
<span style="color:#404040">VM Size: </span> ${provision.vmType}
</div>
${common}
<div style="margin: 30px 0px;">
${htmlint}
</div>
<div style="color:#404040;font-size:16px;margin:30px 0px">
<p style="margin:0px">Check it out at <a href="https://qmicloud.qliktech.com">https://qmicloud.qliktech.com</a></p>
</div>
</div>
</div>`;
}
function getHtmlErrorProvision(provision, scenario) {
var common = _getCommonDetails(provision, scenario);
return`<div style="width:600px;color:black!important;font-family:'Source Sans Pro',sans-serif;padding:50px">
<div style="background-color:white;height:100%;padding:20px 10px">
<p style="text-align:left;margin-bottom:30px;margin-left:0px">
<img src="https://www.qlik.com/us/-/media/images/qlik/global/qlik-logo-2x.png" width="150" height="32" alt="Qlik" style="border:0;height:auto;line-height:100%;outline:none;text-decoration:none" class="CToWUd">
</p>
<div style="color:#404040;font-size:34px;text-align:center;margin:20px">
<p style="margin:0px">QMI Cloud</p>
</div>
<div style="color:#404040;font-size:20px;margin:20px 0px">
<p style="margin:0px;color: #FF2020">Opps! Something didn't work.</p>
<p style="margin:0px;color: #FF2020">Oops! Something didn't work.</p>
</div>
<div style="color:#404040;font-size:20px;margin:20px 0px 50px 0px">
<p style="margin:0px">Scenario '${scenario.title}' failed during provision.</p>
</div>
<div style="color:#404040;font-size:18px;margin:20px 0px">
<p style="margin:0px">Scenario information:</p>
</div>
<div>
<span style="color:#404040">Scenario: </span> ${scenario.title}
</div>
<div>
<span style="color:#404040">Description: </span> ${scenario.description}
</div>
<div>
<span style="color:#404040">ProvisionID: </span> ${provision._id}
${common}
<div style="color:#404040;font-size:16px;margin:30px 0px">
<p style="margin:0px">Check it out at <a href="https://qmicloud.qliktech.com">https://qmicloud.qliktech.com</a></p>
</div>
</div>
</div>`;
}
function getHtmlDestroyProvision(provision, scenario) {
var common = _getCommonDetails(provision, scenario);
return`<div style="width:600px;color:black!important;font-family:'Source Sans Pro',sans-serif;padding:50px">
<div style="background-color:white;height:100%;padding:20px 10px">
<p style="text-align:left;margin-bottom:30px;margin-left:0px">
<img src="https://www.qlik.com/us/-/media/images/qlik/global/qlik-logo-2x.png" width="150" height="32" alt="Qlik" style="border:0;height:auto;line-height:100%;outline:none;text-decoration:none" class="CToWUd">
</p>
<div style="color:#404040;font-size:34px;text-align:center;margin:20px">
<p style="margin:0px">QMI Cloud</p>
</div>
<div style="color:#404040;font-size:20px;margin:40px 0px">
<p style="margin:0px">Scenario '${scenario.title}' successfully destroyed!</p>
</div>
<div style="color:#404040;font-size:18px;margin:20px 0px">
<p style="margin:0px">Scenario information:</p>
</div>
<div>
<span style="color:#404040">Scenario: </span> ${scenario.title}
</div>
<div>
<span style="color:#404040">Description: </span> ${scenario.description}
</div>
<div>
<span style="color:#404040">ProvisionID: </span> ${provision._id}
</div>
<div style="color:#404040;font-size:18px;margin:20px 0px">
<p style="margin:0px">Thanks for using QMI Cloud!</p>
${common}
<div style="color:#404040;font-size:16px;margin:30px 0px">
<p style="margin:0px">Check it out at <a href="https://qmicloud.qliktech.com">https://qmicloud.qliktech.com</a></p>
</div>
</div>
</div>`;
@@ -138,71 +212,44 @@ function getHtmlDestroyProvision(provision, scenario) {
// async..await is not allowed in global scope, must use a wrapper
async function send( provision, user, scenario ) {
/*let testAccount = await nodemailer.createTestAccount();
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
host: "smtp.ethereal.email",
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: testAccount.user, // generated ethereal user
pass: testAccount.pass // generated ethereal password
}
});*/
async function send( provision, scenario ) {
const htmlText = getHtmlNewProvision(provision, scenario);
// create reusable transporter object using the default SMTP transport
// send mail with defined transport object
let info = await transporter.sendMail({
from: FROM, // sender address
to: user.upn, // list of receivers
subject: 'QMI Cloud - Provision finished successfully', // Subject line
text: 'QMI Cloud - Provision finished successfully', // plain text body
html: htmlText // html body
});
console.log('Provision Email ('+info.messageId+') sent to: ' + user.upn);
//console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
await _doSend(provision.user.upn, 'QMI Cloud - Provision finished successfully', htmlText);
}
async function sendError(provision, user, scenario ) {
async function sendError(provision, scenario ) {
const htmlText = getHtmlErrorProvision(provision, scenario);
// send mail with defined transport object
let info = await transporter.sendMail({
from: FROM, // sender address
to: user.upn, // list of receivers
subject: 'QMI Cloud - Provision with failures', // Subject line
text: 'QMI Cloud - Provision with failures', // plain text body
html: htmlText // html body
});
console.log('Provision Email ('+info.messageId+') sent to: ' + user.upn);
await _doSend(provision.user.upn, 'QMI Cloud - Provision with failures', htmlText);
}
async function sendDestroyed(provision, user, scenario ) {
async function sendDestroyed(provision, scenario ) {
const htmlText = getHtmlDestroyProvision(provision, scenario);
await _doSend(provision.user.upn, 'QMI Cloud - Provision destroyed successfully', htmlText);
}
// send mail with defined transport object
let info = await transporter.sendMail({
from: FROM, // sender address
to: user.upn, // list of receivers
subject: 'QMI Cloud - Scenario destroyed successfully', // Subject line
text: 'QMI Cloud - Scenario destroyed successfully', // plain text body
html: htmlText // html body
});
async function sendWillStopIn24( provision, scenario ) {
console.log('Provision Email ('+info.messageId+') sent to: ' + user.upn);
const htmlText = getHtmlScenarioWillStopIn24( provision, scenario);
await _doSend(provision.user.upn, 'QMI Cloud - VMs will stop in less than 24h', htmlText);
}
async function sendWillDestroyIn24( provision, scenario ) {
const htmlText = getHtmlScenarioDestroyIn24( provision, scenario);
await _doSend(provision.user.upn, 'QMI Cloud - Provision will destroy in less than 24h', htmlText);
}
async function sendVMsStopped( provision, scenario ) {
const htmlText = getHtmlScenarioVMsStopped( provision, scenario);
await _doSend(provision.user.upn, 'QMI Cloud - VMs stopped automatically', htmlText);
}
module.exports.send = send;
module.exports.sendError = sendError;
module.exports.sendDestroyed = sendDestroyed;
module.exports.sendWillStopIn24 = sendWillStopIn24;
module.exports.sendVMsStopped = sendVMsStopped;
module.exports.sendWillDestroyIn24 = sendWillDestroyIn24;

View File

@@ -71,10 +71,10 @@ app.use(express.static(__dirname + '/../dist/qmi-cloud'));
passport.init(app);
app.use("/api/scenarios", routesApiScenarios);
app.use("/api/users", routesApiUsers);
app.use("/api/provisions", routesApiProvisions);
app.use("/api/destroyprovisions", routesApiDestroyProvisions);
app.use("/api/v1/scenarios", routesApiScenarios);
app.use("/api/v1/users", routesApiUsers);
app.use("/api/v1/provisions", routesApiProvisions);
app.use("/api/v1/destroyprovisions", routesApiDestroyProvisions);
app.get('/*',(req, res, next) =>{
if (req.originalUrl.indexOf("/api-docs") !== -1 || req.originalUrl.indexOf("/arena") !== -1 ) {
@@ -94,14 +94,52 @@ app.get('/logout', function(req, res) {
const options = {
swaggerDefinition: {
definition: {
openapi: "3.0.3",
// Like the one described here: https://swagger.io/specification/#infoObject
info: {
title: 'QMI Cloud - API',
version: '1.0.0',
//description: 'Test Express API with autogenerated swagger doc',
description: 'REST API for QMI Cloud solutions',
contact: {
"name": "Qlik GEAR",
"email": "DL-Enterprise-ArchitectsGEAR@qlik.com"
}
},
basePath: "/api"
servers: [{
"url": "/api/v1",
"description": "Production Server"
}],
components: {
securitySchemes: {
ApiKeyAuth: {
type: "apiKey",
name: "apiKey",
in: "query"
}
},
schemas: {
"user": {
"properties": {
"displayName": {
"type": "string"
},
"upn": {
"type": "string"
},
"oid": {
"type": "string"
},
"role": {
"type": "string"
}
}
}
}
},
security: [{
ApiKeyAuth: []
}]
},
// List of files to be processes. You can also set globs './routes/*.js'
apis: [
@@ -109,7 +147,7 @@ const options = {
'server/routes/api-users.js',
'server/routes/api-provisions.js',
'server/routes/api-destroyprovisions.js',
],
]
};
const specs = swaggerJsdoc(options);
@@ -120,13 +158,15 @@ app.listen(3000, () => {
console.log(`Server listening on port 3000`)
});
var optionsHttps = {
pfx: fs.readFileSync(path.resolve(__dirname, 'certs', process.env.CERT_PFX_FILENAME)),
passphrase: process.env.CERT_PFX_PASSWORD
};
if ( process.env.CERT_PFX_PASSWORD && process.env.CERT_PFX_FILENAME) {
var optionsHttps = {
pfx: fs.readFileSync(path.resolve(__dirname, 'certs', process.env.CERT_PFX_FILENAME)),
passphrase: process.env.CERT_PFX_PASSWORD
};
https.createServer(optionsHttps, app).listen(3100, function(){
console.log(`Secure server listening on port 3100`);
});
https.createServer(optionsHttps, app).listen(3100, function(){
console.log(`Secure server listening on port 3100`);
});
}

View File

@@ -1,19 +0,0 @@
Params (
[string] $ApplicationGatewayName,
[string] $ApplicationGatewayResourceGroup = "AppGW_RG",
[string] $PolicyName = "QlikSenseDefault",
[string] $PolicyResourceGroup = "QMI-infra-vnet"
)
Connect-AzAccount -Identity
$gw = Get-AzApplicationGateway -Name $ApplicationGatewayName -ResourceGroupName $ApplicationGatewayResourceGroup
$policy = Get-AzApplicationGatewayFirewallPolicy -Name $PolicyName -ResourceGroupName $PolicyResourceGroup
#Save the policy itself
Set-AzApplicationGatewayFirewallPolicy -InputObject $policy
#Attach the policy to an Application Gateway
$gw.FirewallPolicy = $policy
#Save the Application Gateway
Set-AzApplicationGateway -ApplicationGateway $gw

135
server/stop5.js Normal file
View File

@@ -0,0 +1,135 @@
var myArgs = process.argv.slice(2);
if ( myArgs.length < 3 ) {
console.log("Missing args", myArgs);
process.exit(0);
}
const IS_REAL = myArgs[2] !== 'test';
const RUNNING_PERIOD = myArgs[1]; //Days
const RUNNING_LIMIT_HOURS_WARNING = 24*(RUNNING_PERIOD-1);
const RUNNING_LIMIT_HOURS_STOP = 24*RUNNING_PERIOD;
var db = require('./mongo');
const sendEmail = require("./send-email");
const moment = require('moment');
const azurecli = require('./azurecli');
function timeRunning(p) {
let runningFromTime = p.runningFrom? new Date(p.runningFrom).getTime() : new Date(p.created).getTime();
let totalRunningFromTime;
if (p.statusVms !== 'Stopped' && p.statusVms !== 'Starting' && !p.isDestroyed) {
totalRunningFromTime = Math.abs(new Date().getTime() - runningFromTime);
}
let duration = moment.duration(totalRunningFromTime);
p.duration = {
hours: Math.floor(duration.asHours()),
complete: Math.floor(duration.asDays()) +"d "+duration.hours()+"h "+duration.minutes()
};
}
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
async function init(type) {
var limit, cb;
var filter = {
"isDestroyed":false,
"isDeleted": false,
"statusVms": "Running"
};
if ( type === "warning" ) {
limit = RUNNING_LIMIT_HOURS_WARNING;
filter.pendingNextAction = {$ne: "stopVms"};
cb = doSendEmailWarning;
} else if ( type === "stop" ) {
limit = RUNNING_LIMIT_HOURS_STOP;
filter.pendingNextAction = "stopVms";
cb = doStop;
} else {
console.log("Invalid 'type'. Do nothing.");
return;
}
let provisions = await db.provision.get(filter);
let scenarios = await db.scenario.get();
await asyncForEach(provisions.results, async function(p) {
var _scenario = scenarios.results.filter(s=>{
return s.name === p.scenario
});
if ( _scenario.length ){
p._scenario = _scenario[0];
}
timeRunning(p);
if (!IS_REAL) {
console.log(`${p._id} - limit: ${limit} hs - actual duration: ${p.duration.hours} hs`);
}
if ( p.duration && p.duration.hours >= limit) {
await cb(p);
}
});
}
const doSendEmailWarning = async function(p) {
if ( p.pendingNextAction === 'stopVms') {
console.log(`Warning email Stop already sent. Wait for pending action to complete.`);
} else {
let msg = `Send warning STOP email - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenario.title}' (${p._id}) being 'Running' more than ${RUNNING_LIMIT_HOURS_WARNING} hours (exactly ${p.duration.complete})`;
console.log(msg);
if ( IS_REAL ) {
await db.provision.update(p._id, {"pendingNextAction": "stopVms"});
await sendEmail.sendWillStopIn24(p, p._scenario);
await db.notification.add({ provision: p._id.toString(), type: 'warningStop', message: msg });
}
}
};
const doStop = async function(p) {
try {
let msg = `VMs stopped - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenario.title}' (${p._id}) being 'Running' more than ${RUNNING_LIMIT_HOURS_STOP} hours (exactly ${p.duration.complete})`
console.log(msg);
if ( IS_REAL ) {
await azurecli.deallocate(p, true);
await db.notification.add({ provision: p._id.toString(), type: 'stop', message: msg });
}
} catch (error) {
console.log("doStop Error", error);
await db.provision.update(p._id, {"statusVms": "Error_Stopping"});
}
};
function check(type) {
init(type).then(function(){
db.mongoose.connection.close()
process.exit(0);
}).catch(function(e){
db.mongoose.connection.close()
console.log("Error", e);
process.exit(0);
});
}
// --------------------------------
switch (myArgs[0]) {
case 'warning':
check("warning");
break;
case 'stop':
check("stop");
break;
default:
console.log('Sorry, that is not something I know how to do.');
process.exit(0);
}

View File

@@ -19,31 +19,34 @@ module.exports = async function(job) {
return tf.plan(provJob, job.data.user.displayName);
})
.then(async function() {
return await db.provision.update(provJob._id,{"status": "provisioning"});
return await db.provision.update(provJob._id,{"status": "provisioning", "runningFrom": new Date(), "runningTime": 0, "countExtend": 0});
}).then(function(provJobUpdated) {
// TERRAFORM APPLY
return tf.apply(provJobUpdated, job.data.user.displayName);
}).then(async function(output) {
var status = ( output.indexOf("Error:") !== -1 )? "error" : "provisioned";
return await db.provision.update(provJob._id, {"status": status});
}).then(async function(mongoUpdated) {
// Application Gateway assign policy
return azure.appgateway(mongoUpdated);
}).then(async function(mongoUpdated) {
return tf.outputs(mongoUpdated).then( async function(outputs){
return await db.provision.update(mongoUpdated._id, {"outputs": outputs});
});
}).then(async function(mongoUpdated) {
// Application Gateway assign policy
return azure.appgateway(mongoUpdated, job.data._scenario);
}).then(async function(mongoUpdated) {
// Create Image
return azure.createimage(mongoUpdated, job.data._scenario);
}).then(function(mongoUpdated) {
if (mongoUpdated.status === "provisioned") {
sendEmail.send(mongoUpdated, job.data.user, job.data._scenario);
sendEmail.send(mongoUpdated, job.data._scenario);
} else {
sendEmail.sendError(mongoUpdated, job.data.user, job.data._scenario);
sendEmail.sendError(mongoUpdated, job.data._scenario);
}
return Promise.resolve({"success": true, provMongo: mongoUpdated});
}).catch(function(err) {
console.log("Provision: error", err);
db.provision.update(provJob._id, {"status": "error"});
sendEmail.sendError(provJob, job.data.user, job.data._scenario);
sendEmail.sendError(provJob, job.data._scenario);
return Promise.reject({"success": false, "error": err});
});
}

View File

@@ -7,9 +7,9 @@ const fs = require("fs");
const DOCKERIMAGE = "mcr.microsoft.com/azure-powershell";
//const cmd = `docker run --net=host -w /myapp -v ${FOLDER}:/myapp mcr.microsoft.com/azure-powershell pwsh appgw.ps1 -ApplicationGatewayName ${appGwName}`;
const appgateway = function( mongoJob ) {
const appgateway = function( mongoJob, scenario ) {
if ( mongoJob.scenario === 'azqmi-qs-sn' || mongoJob.scenario === 'azqmi-qdc-qs') {
if ( mongoJob.status === 'provisioned' && scenario.isWafPolicyAppGw ) {
var provision_id = mongoJob._id.toString();
var processStream = fs.createWriteStream(mongoJob.logFile, {flags:'a'});
var name = 'qmi-azureps-appgw-'+provision_id;
@@ -40,4 +40,44 @@ const appgateway = function( mongoJob ) {
};
module.exports.appgateway = appgateway;
const createimage = function( mongoJob, scenario ) {
if ( mongoJob.status === 'provisioned' && scenario.newImageName ) {
var provision_id = mongoJob._id.toString();
var processStream = fs.createWriteStream(mongoJob.logFile, {flags:'a'});
var name = 'qmi-azureps-createimage-'+provision_id;
let rgName = mongoJob.scenario.toUpperCase();
rgName = rgName + "-" + provision_id;
let imageName = scenario.newImageName + "-" + new Date().getTime();
console.log(`AzurePS: will spin up container: ${name}`);
return docker.run(DOCKERIMAGE, ['pwsh', 'createimage.ps1', "-rgName", rgName, "-imageName", imageName ], processStream, {
"name": name,
"WorkingDir": "/myapp",
"HostConfig": {
"Binds": [
`${mongoJob.path}/shell:/myapp`
],
"NetworkMode": "host"
}
}).then(function(data) {
var output = data[0];
var container = data[1];
console.log(`AzurePS: ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
return container.remove();
}).then(function() {
console.log(`AzurePS: ${name} removed!`);
return Promise.resolve(mongoJob);
});
} else {
return Promise.resolve(mongoJob);
}
};
module.exports.appgateway = appgateway;
module.exports.createimage = createimage;

View File

@@ -23,14 +23,51 @@ function hook_stdout(callback) {
}
}
function _buildExec( exec, provision ) {
if (!provision.vmImage) {
//Old way
if ( provision.vmType ) {
exec.push('-var');
exec.push(`vm_type=${provision.vmType}`);
}
if ( provision.nodeCount) {
exec.push('-var');
exec.push(`agent_count=${provision.nodeCount}`);
}
} else if ( provision.vmImage ) {
//New way
for (let key in provision.vmImage) {
if (provision.vmImage[key].nodeCount) {
exec.push('-var');
exec.push(`agent_count_${key}=${provision[key].nodeCount}`);
}
if (provision.vmImage[key].vmType) {
exec.push('-var');
exec.push(`vm_type_${key}=${provision.vmImage[key].vmType}`);
}
if (provision.vmImage[key].version) {
exec.push('-var');
exec.push(`image_reference_${key}=${provision.vmImage[key].version.image}`);
}
}
}
return exec;
}
const init = function( provMongo ) {
const templatePath = path.join(PROJECT_PATH, 'az-tf-templates', provMongo.scenario);
const name = `qmi-tf-init-${provMongo._id}`;
console.log(`Provision: will spin up container: ${name}`);
console.log(`Init: will spin up container: ${name}`);
var processStream = fs.createWriteStream(provMongo.logFile, {flags:'a'});
return docker.run(DOCKERIMAGE, ['terraform', 'init', '-no-color', '-from-module=/template'], processStream, {
let exec = ['terraform', 'init', '-no-color', '-from-module=/template'];
console.log('Init: exec: '+exec.join(" "));
return docker.run(DOCKERIMAGE, exec, processStream, {
//"Env": ["VAR_ENV=whatever"],
"name": name,
"WorkingDir": "/app",
@@ -43,30 +80,54 @@ const init = function( provMongo ) {
}).then(function(data) {
var output = data[0];
var container = data[1];
console.log(`Provision: ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
console.log(`Init: ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
return container.remove();
}).then(function() {
console.log(`Provision: ${name} removed!`);
console.log(`Init: ${name} removed!`);
return provMongo;
});
}
};
const plan = function( provMongo, user ) {
const name = `qmi-tf-plan-${provMongo._id}`;
console.log(`Provision: will spin up container: ${name}`);
console.log(`Plan: will spin up container: ${name}`);
var processStream = fs.createWriteStream(provMongo.logFile, {flags:'a'});
//var processStream = process.stdout;
let exec = ['terraform', 'plan', '-no-color', '-input=false', '-out=tfplan', '-var-file=scenario.tfvars', '-var', `provision_id=${provMongo._id}`, '-var', `user_id=${user}`];
if ( provMongo.vmType ) {
exec.push('-var');
exec.push(`vm_type=${provMongo.vmType}`);
}
var exec = ['terraform', 'plan', '-no-color', '-input=false', '-out=tfplan', '-var-file=scenario.tfvars', '-var', `provision_id=${provMongo._id}`, '-var', `user_id=${user}`];
exec = _buildExec(exec, provMongo);
console.log('Plan: exec: '+exec.join(" "));
return docker.run(DOCKERIMAGE, exec, processStream, {
//"Env": ["VAR_ENV=whatever"],
"name": name,
"WorkingDir": "/app",
"HostConfig": {
"Binds": [
`${provMongo.path}:/app`,
`${SSHPATH}:/root/.ssh`
],
"NetworkMode": "host"
}
}).then(function(data){
var container = data[1];
console.log(`Plan: ${name} (${container.id}) has finished with code: ${data[0].StatusCode}`);
return container.remove();
}).then(function() {
console.log(`Plan: ${name} removed!`);
return fs.readFileSync(provMongo.logFile);
})
};
if ( provMongo.nodeCount ) {
exec.push('-var');
exec.push(`agent_count=${provMongo.nodeCount}`);
}
const apply = function( provMongo, user ) {
const name = `qmi-tf-apply-${provMongo._id}`;
console.log(`Apply: will spin up container: ${name}`);
var processStream = fs.createWriteStream(provMongo.logFile, {flags:'a'});
//var processStream = process.stdout;
var exec = ['terraform', 'apply', 'tfplan', '-no-color'];
console.log('Apply: exec: '+exec.join(" "));
return docker.run(DOCKERIMAGE, exec, processStream, {
//"Env": ["VAR_ENV=whatever"],
@@ -80,41 +141,11 @@ const plan = function( provMongo, user ) {
"NetworkMode": "host"
}
}).then(function(data){
let output = data[0];
let container = data[1];
console.log(`Provision: ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
console.log(`Apply: ${name} (${container.id}) has finished with code: ${data[0].StatusCode}`);
return container.remove();
}).then(function() {
console.log(`Provision: ${name} removed!`);
return fs.readFileSync(provMongo.logFile);
})
}
const apply = function( provMongo, user ) {
const name = `qmi-tf-apply-${provMongo._id}`;
console.log(`Provision: will spin up container: ${name}`);
var processStream = fs.createWriteStream(provMongo.logFile, {flags:'a'});
//var processStream = process.stdout;
return docker.run(DOCKERIMAGE, ['terraform', 'apply', 'tfplan', '-no-color'], processStream, {
//"Env": ["VAR_ENV=whatever"],
"name": name,
"WorkingDir": "/app",
"HostConfig": {
"Binds": [
`${provMongo.path}:/app`,
`${SSHPATH}:/root/.ssh`
],
"NetworkMode": "host"
}
}).then(function(data){
let output = data[0];
let container = data[1];
console.log(`Provision: ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
return container.remove();
}).then(function() {
console.log(`Provision: ${name} removed!`);
console.log(`Apply: ${name} removed!`);
return fs.readFileSync(provMongo.logFile);
})
}
@@ -122,20 +153,12 @@ const apply = function( provMongo, user ) {
const destroy = function(destroyMongo, provMongo) {
const name = `qmi-tf-destroy-${destroyMongo._id}`;
console.log(`Destroy Provision: will spin up container: ${name}`);
console.log(`Destroy: will spin up container: ${name}`);
var processStream = fs.createWriteStream(destroyMongo.logFile, {flags:'a'});
let exec = ['terraform', 'destroy', '-auto-approve', '-no-color', '-var-file=scenario.tfvars', "-var", `provision_id=${destroyMongo.provId}`];
var exec = ['terraform', 'destroy', '-auto-approve', '-no-color', '-var-file=scenario.tfvars', "-var", `provision_id=${destroyMongo.provId}`];
exec = _buildExec(exec, provMongo);
console.log('Destroy: exec: '+exec.join(" "));
if (provMongo.vmType) {
exec.push("-var");
exec.push(`vm_type=${provMongo.vmType}`);
}
if ( provMongo.nodeCount ) {
exec.push('-var');
exec.push(`agent_count=${provMongo.nodeCount}`);
}
return docker.run(DOCKERIMAGE, exec, processStream, {
//"Env": ["VAR_ENV=whatever"],
"name": name,
@@ -147,26 +170,30 @@ const destroy = function(destroyMongo, provMongo) {
]
}
}).then(function(data) {
var output = data[0];
var container = data[1];
console.log(`Processor Destroy: '${name}' (${container.id}) has finished with code: ${output.StatusCode}`);
console.log(`Destroy: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
return container.remove();
}).then(async function(data) {
console.log(`Processor Destroy: '${name}' removed!`);
console.log(`Destroy: '${name}' removed!`);
return fs.readFileSync(destroyMongo.logFile);
});
}
};
const outputs = function(provMongo) {
const name = `qmi-tf-output-${provMongo._id}`;
console.log(`Destroy Provision: will spin up container: ${name}`);
let tfout = "";
let unhook = hook_stdout(function(string, encoding, fd) {
console.log(`Output: will spin up container: ${name}`);
var exec = ['terraform', 'output', '-no-color', '-json'];
console.log('Output: exec: '+exec.join(" "));
var tfout = "";
var unhook = hook_stdout(function(string, encoding, fd) {
tfout += string.trim();
});
return docker.run(DOCKERIMAGE, ['terraform', 'output', '-no-color', '-json'], process.stdout, {
return docker.run(DOCKERIMAGE, exec, process.stdout, {
//"Env": ["VAR_ENV=whatever"],
"name": name,
"WorkingDir": "/app",
@@ -177,20 +204,20 @@ const outputs = function(provMongo) {
}
}).then(function(data) {
unhook();
let output = data[0];
let container = data[1];
console.log(`Processor Destroy: '${name}' (${container.id}) has finished with code: ${output.StatusCode}`);
var container = data[1];
console.log(`Output: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
return container.remove();
}).then(async function(data) {
console.log(`Processor Destroy: '${name}' removed!`);
let out = JSON.parse(tfout);
console.log(`Output: '${name}' removed!`);
console.log("Output: tfout: " + tfout);
var out = JSON.parse(tfout);
var o = {};
for (var key in out) {
o[key] = out[key].value;
}
return o;
});
}
};
module.exports.init = init;
module.exports.plan = plan;

View File

@@ -11,7 +11,7 @@ module.exports = async function(job){
"logFile": path.join('/logs', 'destroy', `${job.data.id}.log`)
});
var provMongo = await db.provision.getSingle(job.data.provId);
var provMongo = await db.provision.getById(job.data.provId);
return tf.destroy(destroyMongo, provMongo)
.then(async function(output) {
@@ -21,8 +21,9 @@ module.exports = async function(job){
update2 = await db.provision.update(provMongo._id, {"isDestroyed": false});
} else {
update = await db.destroy.update(destroyMongo._id, {"status": "destroyed"});
update2 = await db.provision.update(provMongo._id, {"isDestroyed": true});
sendEmail.sendDestroyed(update2, job.data.user, job.data._scenario);
let timeRunning = db.utils.getNewTimeRunning(provMongo);
update2 = await db.provision.update(provMongo._id, {"isDestroyed": true, "timeRunning": timeRunning, "pendingNextAction": undefined});
sendEmail.sendDestroyed(update2, job.data._scenario);
}
return { destroy: update, provision: update2 };
}).then(async function(res) {

View File

@@ -1,8 +1,27 @@
<h1 style="margin-top: 80px;">Users</h1>
<ul style="margin-top: 80px;" class="nav nav-pills nav-fill">
<li class="nav-item">
<a class="nav-link" (click)="tabSelect($event, 'Provisions')" [ngClass]="{'active': tab === 'Provisions'}">Provisions</a>
</li>
<li class="nav-item">
<a class="nav-link" (click)="tabSelect($event, 'Users')" [ngClass]="{'active': tab === 'Users'}">Users</a>
</li>
<li class="nav-item">
<a class="nav-link" (click)="tabSelect($event, 'Scenarios')" [ngClass]="{'active': tab === 'Scenarios'}">Scenarios</a>
</li>
</ul>
<table-users *ngIf="users && users.length" [elements]="users"></table-users>
<div *ngIf="tab === 'Provisions'">
<!--<h1>Provisions</h1>-->
<table-provisions></table-provisions>
</div>
<h1>Provisions</h1>
<table-admin *ngIf="provisions && provisions.length" [elements]="provisions"></table-admin>
<div *ngIf="tab === 'Users'">
<!--<h1>Users</h1>-->
<table-users></table-users>
</div>
<div *ngIf="tab === 'Scenarios'">
<!--<h1>Scenarios</h1>-->
<table-scenarios></table-scenarios>
</div>
<qmi-alert></qmi-alert>

View File

@@ -1,3 +1,7 @@
td {
vertical-align: middle;
}
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
background-color: #009845;
}

View File

@@ -1,10 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { UsersService } from '../services/users.service';
import { ProvisionsService } from '../services/provisions.service';
import { Subscription, timer } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { ScenariosService } from '../services/scenarios.service';
@Component({
selector: 'app-admin',
@@ -13,73 +7,22 @@ import { ScenariosService } from '../services/scenarios.service';
})
export class AdminComponent implements OnInit {
users;
provisions;
destroys;
subscription: Subscription;
scenarios;
tab : string = 'Provisions';
constructor( private _usersService: UsersService, private _provisionsService: ProvisionsService, private _scenariosService: ScenariosService ) { }
private _process(provisions) : void {
provisions.forEach(p=>{
p._scenario = this.scenarios.filter(s => s.name === p.scenario);
});
if ( !this.provisions ) {
this.provisions = provisions;
} else {
this.provisions.forEach( function(p, index, object) {
let found = provisions.filter(a=>a._id.toString() === p._id.toString());
if ( found.length ) {
p.status = found[0].status;
p.statusVms = found[0].statusVms;
p.isDestroyed = found[0].isDestroyed;
p.outputs = found[0].outputs;
p.destroy = found[0].destroy;
} else {
object.splice(index, 1);
}
});
constructor() { }
provisions.forEach(function(p) {
let found = this.provisions.filter(a=>a._id.toString() === p._id.toString());
if (found.length === 0){
this.provisions.unshift(p);
}
}.bind(this));
}
}
ngOnInit() {
var usersSub = this._usersService.getUsers().subscribe( res => {
usersSub.unsubscribe();
this.users = res;
});
var scenariosSub = this._scenariosService.getScenarios().subscribe( res => {
scenariosSub.unsubscribe();
this.scenarios = res;
this.subscription = timer(0, 5000).pipe( switchMap(() => this._provisionsService.getProvisionsAdmin() ) ).subscribe(provisions => {
this._process(provisions);
});
});
}
private _refresh(): void {
var instantSubs = this._provisionsService.getProvisionsAdmin().subscribe( provisions=>{
instantSubs.unsubscribe();
this._process(provisions);
});
}
ngOnDestroy() {
if ( this.subscription ) {
this.subscription.unsubscribe();
}
tabSelect($event, tab) {
$event.preventDefault();
$event.stopPropagation();
this.tab = tab;
}
}

View File

@@ -0,0 +1,19 @@
<!--Content-->
<div class="modal-content text-center">
<!--Header-->
<div class="modal-header d-flex justify-content-center">
<p class="heading">{{info.title}}</p>
</div>
<!--Body-->
<div class="modal-body">
<mdb-icon fas icon="{{info.icon}}" size="4x" class="animated rotateIn"></mdb-icon>
</div>
<!--Footer-->
<div class="modal-footer justify-content-center">
<a type="button" mdbBtn color="{{info.buttonColor}}" size="sm" outline="true" class="waves-effect" mdbWavesEffect (click)="confirm();">Yes</a>
<a type="button" mdbBtn color="{{info.buttonColor}}" size="sm" class="waves-effect" data-dismiss="modal" (click)="modalRef.hide()" mdbWavesEffect>No</a>
</div>
</div>
<!--/.Content-->

View File

View File

@@ -0,0 +1,32 @@
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { MDBModalRef } from 'angular-bootstrap-md';
import { Subject } from 'rxjs';
@Component({
selector: 'qmi-modalconfirm',
templateUrl: './confirm.component.html',
styleUrls: ['./confirm.component.scss']
})
export class ModalConfirmComponent implements OnInit, OnDestroy {
info;
action: Subject<any> = new Subject();
constructor( public modalRef: MDBModalRef ) {}
ngOnInit() {
if (!this.info.buttonColor) {
this.info.buttonColor = "danger";
}
}
ngOnDestroy() {
}
confirm() : void {
this.action.next();
this.modalRef.hide();
}
}

View File

@@ -3,28 +3,37 @@
<button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title w-100" id="myModalLabel">Provision information</h4>
<h3 style="text-align: center;" class="modal-title w-100">Provision information</h3>
</div>
<div class="modal-body">
<div>
<b>ProvisionID: </b> <span class="mydata">{{info._id}}</span>
</div>
<div>
<b>Purpose: </b> {{info.description}}
</div>
<div>
<b>Scenario: </b> {{info._scenario[0].title}}
</div>
<div>
<b>ProvisionID: </b> {{info._id}}
<div *ngIf="info.vmType && !info.vmImage">
<b>Instance Type: </b> {{info.vmType}} <span *ngIf="info.nodeCount">( {{info.nodeCount}} nodes )</span>
</div>
<div>
<b>Instance Type: </b> {{info.vmType}}
<div *ngFor="let item of info.vmImage | keyvalue">
<div *ngIf="item.value.version">
<b>Product version: </b> <span>{{item.value.version.name}}</span>
</div>
<div *ngIf="item.value.vmType" >
<b>Instance Type: </b> <span>{{item.value.vmType}}</span> <span *ngIf="item.value.nodeCount">( {{item.value.nodeCount}} nodes )</span>
</div>
</div>
<div *ngIf="info.nodeCount">
<b>Number of nodes: </b> {{info.nodeCount}}
</div>
<h5 style="padding-top: 10px;">Connection resources</h5>
<h5 *ngIf="info.outputs" class="info-subtitle">Connection resources</h5>
<div *ngFor="let item of info.outputs | keyvalue">
<b>{{item.key}}</b>
<pre class="mypre">{{item.value}}</pre>
<div class="mydata">{{item.value}}</div>
</div>
</div>
<div class="modal-footer">
<button type="button" mdbBtn color="elegant" class="waves-light" aria-label="Close" (click)="modalRef.hide()" mdbWavesEffect>Close</button>
<button type="button" mdbBtn size="sm" color="grey" class="waves-light" aria-label="Close" (click)="modalRef.hide()" mdbWavesEffect>Close</button>
</div>
</div>

Some files were not shown because too many files have changed in this diff Show More