Compare commits
12 Commits
refactorwo
...
givvy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4f070826d | ||
|
|
bf84db1254 | ||
|
|
36ea9bbba1 | ||
|
|
bd63ef3837 | ||
|
|
0283850cce | ||
|
|
dd1380f13b | ||
|
|
811c1560c4 | ||
|
|
257cc64d8d | ||
|
|
7abf246fd5 | ||
|
|
3aea0e6acc | ||
|
|
d3bf735edc | ||
|
|
de09fe22a7 |
BIN
dist/qmi-cloud/3rdpartylicenses.txt
vendored
BIN
dist/qmi-cloud/3rdpartylicenses.txt
vendored
Binary file not shown.
4
dist/qmi-cloud/index.html
vendored
4
dist/qmi-cloud/index.html
vendored
@@ -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.529f751cbb5308365172.css"></head>
|
||||
<link rel="stylesheet" href="styles.096cda9efd9a8b224b3d.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.6866cf66954a0b739d41.js" defer></script><script src="main.a8feb6a790452d58d3ff.js" defer></script></body>
|
||||
<script src="runtime.e227d1a0e31cbccbf8ec.js" defer></script><script src="polyfills-es5.f1f388528ea207060cbf.js" nomodule defer></script><script src="polyfills.335424f161535f57733f.js" defer></script><script src="scripts.5520a99f673924c17e00.js" defer></script><script src="main.39aa2c5b2de4993d0e07.js" defer></script></body>
|
||||
</html>
|
||||
|
||||
1
dist/qmi-cloud/main.39aa2c5b2de4993d0e07.js
vendored
Normal file
1
dist/qmi-cloud/main.39aa2c5b2de4993d0e07.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/qmi-cloud/main.a8feb6a790452d58d3ff.js
vendored
1
dist/qmi-cloud/main.a8feb6a790452d58d3ff.js
vendored
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
1
dist/qmi-cloud/scripts.5520a99f673924c17e00.js
vendored
Normal file
1
dist/qmi-cloud/scripts.5520a99f673924c17e00.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
80
dist/qmi-cloud/styles.096cda9efd9a8b224b3d.css
vendored
Normal file
80
dist/qmi-cloud/styles.096cda9efd9a8b224b3d.css
vendored
Normal file
File diff suppressed because one or more lines are too long
74
dist/qmi-cloud/styles.529f751cbb5308365172.css
vendored
74
dist/qmi-cloud/styles.529f751cbb5308365172.css
vendored
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
version: '3.8'
|
||||
version: '3.7'
|
||||
|
||||
volumes:
|
||||
redisdb:
|
||||
@@ -55,11 +55,11 @@ services:
|
||||
- source: qmicloud_config
|
||||
target: config.json
|
||||
environment:
|
||||
- HOSTNAME_URL=https://localhost:3000
|
||||
- HOSTNAME_URL=http://localhost:3000
|
||||
- REDIS_URL=redis://redis
|
||||
- MONGO_URI=mongodb://root:example@mongo/qmicloud?authSource=admin
|
||||
#- CERT_PFX_FILENAME=wildcard_qliktech_com.pfx
|
||||
#- CERT_PFX_PASSWORD=xxxxxxxxxxx
|
||||
- CERT_PFX_FILENAME=
|
||||
- CERT_PFX_PASSWORD=
|
||||
command:
|
||||
- ./server/wait-for.sh
|
||||
- --timeout=20
|
||||
@@ -92,8 +92,6 @@ services:
|
||||
image: qlikgear/qmi-cloud-worker:latest
|
||||
container_name: qmi-cloud-worker
|
||||
restart: on-failure
|
||||
deploy:
|
||||
replicas: 2
|
||||
environment:
|
||||
- REDIS_URL=redis://redis
|
||||
- MONGO_URI=mongodb://root:example@mongo/qmicloud?authSource=admin
|
||||
@@ -101,6 +99,8 @@ services:
|
||||
- GIT_SCENARIOS=git::git@gitlab.com:qmi/qmi-cloud-scenarios.git
|
||||
- GIT_TAG=dev
|
||||
- SSHPATH=/Users/aor/.ssh
|
||||
- DOCKERIMAGE_AZURE_POWERSHELL=mcr.microsoft.com/azure-powershell:4.2.0-ubuntu-18.04
|
||||
- DOCKERIMAGE_TERRAFORM=qlikgear/terraform:1.0.1
|
||||
command: "sh -c 'npm run start:dev'"
|
||||
volumes:
|
||||
# -- Dev only volumes
|
||||
|
||||
33
gitlab-ci.sh
33
gitlab-ci.sh
@@ -18,27 +18,24 @@ fi
|
||||
|
||||
echo "$DOCKER_REGISTRY_PASSWORD" | docker login --username "$DOCKER_REGISTRY_USER" --password-stdin
|
||||
|
||||
echo "--- Building image: qlikgear/qmi-cloud-app:$TAG_APP"
|
||||
docker build -f ./Dockerfile -t qlikgear/qmi-cloud-app:$TAG_APP ./
|
||||
echo "--- Pushing image: qlikgear/qmi-cloud-app:$TAG_APP"
|
||||
docker push qlikgear/qmi-cloud-app:$TAG_APP
|
||||
echo "--- Building image: qlikgear/qmi-cloud-cli:$TAG_CLI"
|
||||
docker build -f ./qmi-cloud-cli/Dockerfile -t qlikgear/qmi-cloud-cli:$TAG_CLI ./
|
||||
echo "--- Pushing image: qlikgear/qmi-cloud-cli:$TAG_CLI"
|
||||
docker push qlikgear/qmi-cloud-cli:$TAG_CLI
|
||||
docker build -f ./qmi-cloud-cli/Dockerfile -t qlikgear/qmi-cloud-cli:$STABLE_TAG ./
|
||||
docker push qlikgear/qmi-cloud-cli:$STABLE_TAG
|
||||
|
||||
|
||||
echo "--- Building image: qlikgear/qmi-cloud-worker:$TAG_WORKER"
|
||||
docker build -f ./qmi-cloud-worker/Dockerfile -t qlikgear/qmi-cloud-worker:$TAG_WORKER ./
|
||||
echo "--- Pushing image: qlikgear/qmi-cloud-worker:$TAG_WORKER"
|
||||
docker push qlikgear/qmi-cloud-worker:$TAG_WORKER
|
||||
docker build -f ./qmi-cloud-worker/Dockerfile -t qlikgear/qmi-cloud-worker:$STABLE_TAG ./
|
||||
docker push qlikgear/qmi-cloud-worker:$STABLE_TAG
|
||||
|
||||
|
||||
echo "--- Building image: qlikgear/qmi-cloud-cli:$TAG_CLI"
|
||||
docker build -f ./qmi-cloud-cli/Dockerfile -t qlikgear/qmi-cloud-cli:$TAG_CLI ./
|
||||
echo "--- Pushing image: qlikgear/qmi-cloud-cli:$TAG_CLI"
|
||||
docker push qlikgear/qmi-cloud-cli:$TAG_CLI
|
||||
|
||||
if [ "$CI_COMMIT_REF_NAME" = "master" ] || [ "$CI_COMMIT_REF_NAME" = "dev" ]; then
|
||||
docker build -f ./Dockerfile -t qlikgear/qmi-cloud-app:$STABLE_TAG ./
|
||||
docker build -f ./qmi-cloud-worker/Dockerfile -t qlikgear/qmi-cloud-worker:$STABLE_TAG ./
|
||||
docker build -f ./qmi-cloud-cli/Dockerfile -t qlikgear/qmi-cloud-cli:$STABLE_TAG ./
|
||||
docker push qlikgear/qmi-cloud-app:$STABLE_TAG
|
||||
docker push qlikgear/qmi-cloud-worker:$STABLE_TAG
|
||||
docker push qlikgear/qmi-cloud-cli:$STABLE_TAG
|
||||
fi
|
||||
echo "--- Building image: qlikgear/qmi-cloud-app:$TAG_APP"
|
||||
docker build -f ./Dockerfile -t qlikgear/qmi-cloud-app:$TAG_APP ./
|
||||
echo "--- Pushing image: qlikgear/qmi-cloud-app:$TAG_APP"
|
||||
docker push qlikgear/qmi-cloud-app:$TAG_APP
|
||||
docker build -f ./Dockerfile -t qlikgear/qmi-cloud-app:$STABLE_TAG ./
|
||||
docker push qlikgear/qmi-cloud-app:$STABLE_TAG
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "qmi-cloud-app",
|
||||
"version": "1.1.2",
|
||||
"version": "1.1.5",
|
||||
"scripts": {
|
||||
"start": "node -r esm server/server.js",
|
||||
"start:dev": "nodemon -r esm server/server.js",
|
||||
@@ -8,7 +8,6 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"qmi-cloud-common": "./qmi-cloud-common",
|
||||
"@angular-devkit/build-angular": "^0.900.7",
|
||||
"@angular/animations": "~9.0.7",
|
||||
"@angular/common": "~9.0.7",
|
||||
@@ -16,11 +15,13 @@
|
||||
"@angular/core": "~9.0.7",
|
||||
"@angular/forms": "~9.0.7",
|
||||
"@angular/http": "~7.0.0",
|
||||
"@angular/localize": "~9.0.7",
|
||||
"@angular/platform-browser": "~9.0.7",
|
||||
"@angular/platform-browser-dynamic": "~9.0.7",
|
||||
"@angular/router": "~9.0.7",
|
||||
"@fortawesome/fontawesome-free": "^5.12.1",
|
||||
"@hapi/boom": "^9.1.0",
|
||||
"@ng-bootstrap/ng-bootstrap": "6.2.0",
|
||||
"@types/chart.js": "^2.9.16",
|
||||
"adal-angular4": "^4.0.12",
|
||||
"angular-bootstrap-md": "^9.0.0",
|
||||
@@ -46,6 +47,7 @@
|
||||
"nodemon": "^1.19.1",
|
||||
"passport": "^0.4.0",
|
||||
"passport-azure-ad": "^4.1.0",
|
||||
"qmi-cloud-common": "./qmi-cloud-common",
|
||||
"rxjs": "~6.5.4",
|
||||
"swagger-jsdoc": "3.5.0",
|
||||
"swagger-ui-express": "4.1.3",
|
||||
@@ -71,4 +73,4 @@
|
||||
"tslint": "~5.11.0",
|
||||
"typescript": "~3.7.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
docker run --net=host \
|
||||
-e MONGO_URI="mongodb://root:example@localhost:27017/qmicloud?authSource=admin" \
|
||||
-e API_KEY="c229219ccdd72d11e8ea253fd3876d247e5f489c9c84922cabdfb0cc194d8ff398a8d8d6528d8241efc99add2207e0ec75122a1b2c5598cc340cbe6b7c3c0dbf" \
|
||||
qlikgear/qmi-cloud-cli:latest -s destroy -t warning -p 4 -r test
|
||||
qlikgear/qmi-cloud-cli:latest -s checkdestroy -t warning -p 4 -r test
|
||||
```
|
||||
|
||||
```
|
||||
@@ -12,3 +12,11 @@ docker run --net=host \
|
||||
-e MONGO_URI="mongodb://root:example@localhost:27017/qmicloud?authSource=admin" \
|
||||
qlikgear/qmi-cloud-cli:latest -s initdb
|
||||
```
|
||||
|
||||
```
|
||||
docker run --net=host -e MONGO_URI=$MONGO_URI -e API_KEY=$API_KEY qlikgear/qmi-cloud-cli:latest -s checkdestroy -t warning -p 20 -r test
|
||||
```
|
||||
|
||||
```
|
||||
docker run --net=host -e MONGO_URI=$MONGO_URI -e API_KEY=$API_KEY qlikgear/qmi-cloud-cli:latest -s checkstop -t warning -p 4 -r test
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "qmi-cloud-cli",
|
||||
"version": "1.1.2",
|
||||
"version": "1.1.3",
|
||||
"scripts": {
|
||||
},
|
||||
"private": true,
|
||||
|
||||
24
qmi-cloud-cli/shell-utils/cost.sh
Normal file
24
qmi-cloud-cli/shell-utils/cost.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
# LOGIN
|
||||
az login --identity
|
||||
|
||||
BASEDIR=$(dirname "$0")
|
||||
SUBS="62ebff8f-c40b-41be-9239-252d6c0c8ad9"
|
||||
CONTAINER="exports"
|
||||
STORAGEACCOUNT="qmiexports"
|
||||
STORAGEACCOUNTKEY="6PI/qNoJ7UnX83lVcffN7p7X1TwYXv+jHKLIEcMKZWpWA01Vj75AAyjq4dXJdmUgCeSEIRefHnJzQeuPZRHInQ=="
|
||||
|
||||
# GET FILES
|
||||
az storage blob download-batch --destination . --source $CONTAINER --account-name $STORAGEACCOUNT --account-key $STORAGEACCOUNTKEY --pattern *.csv --subscription $SUBS
|
||||
|
||||
|
||||
# MOVE LATEST FILE PER MONTH TO FOLDER latest
|
||||
echo "BASEDIR=$BASEDIR"
|
||||
|
||||
for d in "$BASEDIR/qmicloud/qmicloud/"*
|
||||
do
|
||||
folderBase=$(basename "$d")
|
||||
ymn=$(echo $folderBase | cut -c1-6)
|
||||
lastFile=$(find $d -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" ")
|
||||
echo $lastFile
|
||||
cp $lastFile $BASEDIR/$ymn.csv
|
||||
done
|
||||
@@ -69,7 +69,10 @@ const provisionSchema = new mongoose.Schema({
|
||||
},
|
||||
pendingNextAction: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
autoShutdown: {
|
||||
type: mongoose.Types.ObjectId, ref: 'ProvisionAutoShutdown'
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
34
qmi-cloud-common/models/ProvisionAutoShutdown.js
Normal file
34
qmi-cloud-common/models/ProvisionAutoShutdown.js
Normal file
@@ -0,0 +1,34 @@
|
||||
const mongoose = require('mongoose');
|
||||
mongoose.set('useFindAndModify', false);
|
||||
//mongoose.set('debug', true)
|
||||
|
||||
|
||||
const sc = new mongoose.Schema({
|
||||
is24x7: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: true
|
||||
},
|
||||
localeShutdownTime: {
|
||||
type: String
|
||||
},
|
||||
localeStartupTime: {
|
||||
type: String
|
||||
},
|
||||
utcTagShutdownTime: {
|
||||
type: String
|
||||
},
|
||||
utcTagStartupTime: {
|
||||
type: String
|
||||
},
|
||||
timezoneOffset: {
|
||||
type: Number
|
||||
},
|
||||
weekStartDay: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
module.exports = mongoose.model('ProvisionAutoShutdown', sc)
|
||||
@@ -35,6 +35,10 @@ const scenarioSchema = new mongoose.Schema({
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isDivvyEnabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isDisabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
|
||||
@@ -31,6 +31,7 @@ mongoose.connection.on('error', (err) => {
|
||||
|
||||
|
||||
// Get Data Models
|
||||
const ProvisionAutoShutdown = require('./models/ProvisionAutoShutdown');
|
||||
const Provision = require('./models/Provision');
|
||||
const Destroy = require('./models/Destroy');
|
||||
const User = require('./models/User');
|
||||
@@ -87,7 +88,7 @@ const get = async (model, filter, select, skip, limit, populates, reply) => {
|
||||
});
|
||||
} else {
|
||||
if ( model === Provision ) {
|
||||
exec = exec.populate({ path: 'user', select: 'displayName upn'}).populate({path:'destroy', select: "-user -jobId"});
|
||||
exec = exec.populate({ path: 'user', select: 'displayName upn'}).populate({path:'destroy', select: "-user -jobId"}).populate({path: "autoShutdown"});
|
||||
}
|
||||
|
||||
if ( model === ApiKey ) {
|
||||
@@ -120,7 +121,7 @@ const getById = async (model, id, reply) => {
|
||||
try {
|
||||
var exec = model.findById(id);
|
||||
if ( model === Provision ) {
|
||||
exec = exec.populate('user').populate('destroy');
|
||||
exec = exec.populate('user').populate('destroy').populate("autoShutdown");
|
||||
}
|
||||
if ( model === ApiKey ) {
|
||||
exec = exec.populate('user');
|
||||
@@ -139,7 +140,7 @@ const getOne = async (model, filter, reply) => {
|
||||
try {
|
||||
var exec = model.findOne(filter);
|
||||
if ( model === Provision ) {
|
||||
exec = exec.populate('user').populate('destroy');
|
||||
exec = exec.populate('user').populate('destroy').populate("autoShutdown");
|
||||
}
|
||||
if ( model === ApiKey ) {
|
||||
exec = exec.populate('user');
|
||||
@@ -170,7 +171,7 @@ const update = async (model, id, body, reply) => {
|
||||
console.log("UPDATE", id, updateData);
|
||||
var exec = model.findByIdAndUpdate(id, updateData, { new: true });
|
||||
if ( model === Provision ) {
|
||||
exec = exec.populate('user').populate('destroy');
|
||||
exec = exec.populate('user').populate('destroy').populate("autoShutdown");
|
||||
}
|
||||
if ( model === ApiKey ) {
|
||||
exec = exec.populate('user');
|
||||
@@ -219,6 +220,7 @@ function _m(model) {
|
||||
|
||||
|
||||
module.exports = {
|
||||
provisionAutoShutdown: _m(ProvisionAutoShutdown),
|
||||
provision: _m(Provision),
|
||||
destroy: _m(Destroy),
|
||||
scenario: _m(Scenario),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "qmi-cloud-common",
|
||||
"version": "1.1.2",
|
||||
"version": "1.1.3",
|
||||
"dependencies": {
|
||||
"@hapi/boom": "^9.1.0",
|
||||
"mongoose": "^5.7.4",
|
||||
|
||||
@@ -4,7 +4,7 @@ const docker = new Docker({
|
||||
//'socketPath': '/var/run/docker.sock'
|
||||
});
|
||||
const fs = require("fs");
|
||||
const DOCKERIMAGE = "mcr.microsoft.com/azure-powershell";
|
||||
const DOCKERIMAGE = process.env.DOCKERIMAGE_AZURE_POWERSHELL || "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( provision, scenario ) {
|
||||
|
||||
@@ -5,7 +5,7 @@ const docker = new Docker({
|
||||
const fs = require('fs');
|
||||
const GIT_SCENARIOS = process.env.GIT_SCENARIOS;
|
||||
const GIT_TAG = process.env.GIT_TAG || "master";
|
||||
const DOCKERIMAGE = "qlikgear/terraform:1.0.1";
|
||||
const DOCKERIMAGE = process.env.DOCKERIMAGE_TERRAFORM || "qlikgear/terraform:1.0.1";
|
||||
const SSHPATH = process.env.SSHPATH;
|
||||
|
||||
function hook_stdout(callback) {
|
||||
@@ -92,6 +92,24 @@ function _buildVarsExec( exec, provision, scenario ) {
|
||||
exec.push(`is_external_access=${provision.isExternalAccess}`);
|
||||
}
|
||||
|
||||
if ( provision.autoShutdown ) {
|
||||
if ( provision.autoShutdown.is24x7 === true ) {
|
||||
exec.push('-var');
|
||||
exec.push(`is_24x7=true`);
|
||||
} else if ( provision.autoShutdown.is24x7 === false ) {
|
||||
exec.push('-var');
|
||||
exec.push(`is_24x7=false`);
|
||||
if ( provision.autoShutdown.utcTagStartupTime ) {
|
||||
exec.push('-var');
|
||||
exec.push(`startupTime=${provision.autoShutdown.utcTagStartupTime}`);
|
||||
}
|
||||
if ( provision.autoShutdown.utcTagShutdownTime ) {
|
||||
exec.push('-var');
|
||||
exec.push(`shutdownTime=${provision.autoShutdown.utcTagShutdownTime}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return exec;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "qmi-cloud-worker",
|
||||
"version": "1.1.2",
|
||||
"version": "1.1.3",
|
||||
"scripts": {
|
||||
"start": "node -r esm index.js",
|
||||
"start:dev": "nodemon -r esm index.js",
|
||||
|
||||
@@ -229,6 +229,39 @@ router.delete('/:id', passport.ensureAuthenticatedAndAdmin, async (req, res, nex
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /provisions/{id}:
|
||||
* put:
|
||||
* description: Update Provision by ID
|
||||
* summary: Update Provision by ID
|
||||
* tags:
|
||||
* - admin
|
||||
* parameters:
|
||||
* - name: id
|
||||
* in: path
|
||||
* type: string
|
||||
* required: true
|
||||
* - in: body
|
||||
* name: body
|
||||
* description: Provision object
|
||||
* required: true
|
||||
* produces:
|
||||
* - application/json
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Provision
|
||||
*/
|
||||
router.put('/:id', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
|
||||
|
||||
try {
|
||||
const result = await db.provision.update(req.params.id, req.body);
|
||||
return res.json(result);
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /provisions/{id}/logs:
|
||||
|
||||
@@ -172,6 +172,12 @@ router.post('/:userId/provisions', passport.ensureAuthenticatedAndIsMe, async (r
|
||||
return res.status(400).json({"msg": "Invalid vmImage"});
|
||||
}
|
||||
req.body.scenarioVersion = scenarioSource.version;
|
||||
|
||||
if ( req.body.autoShutdownData && req.body.autoShutdownData.is24x7 !== undefined ) {
|
||||
const autoShutdown = await db.provisionAutoShutdown.add(req.body.autoShutdownData);
|
||||
req.body.autoShutdown = autoShutdown._id;
|
||||
}
|
||||
|
||||
const mongoJob = await db.provision.add(req.body);
|
||||
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ import { SubscriptionsService } from './services/deployopts.service';
|
||||
import { TableApiKeysComponent } from './tables/table-apikeys.component';
|
||||
import { ApikeyModalComponent } from './modals/edit-apikey.component';
|
||||
import { VmTypeModalComponent } from './modals/edit-vmtype.component';
|
||||
import { ProvisionModalComponent } from './modals/edit-provision.component';
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
|
||||
|
||||
@@ -81,7 +83,8 @@ export function markedOptions(): MarkedOptions {
|
||||
TableApiKeysComponent,
|
||||
ApikeyModalComponent,
|
||||
TableVmTypesComponent,
|
||||
VmTypeModalComponent
|
||||
VmTypeModalComponent,
|
||||
ProvisionModalComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@@ -93,6 +96,7 @@ export function markedOptions(): MarkedOptions {
|
||||
MarkdownModule.forRoot({
|
||||
loader: HttpClient
|
||||
}),
|
||||
NgbModule,
|
||||
],
|
||||
providers: [
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: MyHttpInterceptor, multi: true },
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="modal-content text-center">
|
||||
<!--Header-->
|
||||
<div class="modal-header d-flex justify-content-center">
|
||||
<p class="heading">{{info.title}}</p>
|
||||
<p class="heading" [innerHTML]="info.title"></p>
|
||||
</div>
|
||||
|
||||
<!--Body-->
|
||||
|
||||
@@ -24,13 +24,13 @@ export class ApikeyModalComponent implements OnInit, OnDestroy {
|
||||
ngOnInit() {
|
||||
this._usersService.getUsers().subscribe(res=> {
|
||||
this.users = res.results;
|
||||
console.log("apiKey",this.apiKey);
|
||||
if (this.apiKey) {
|
||||
this.sendData = JSON.parse(JSON.stringify(this.apiKey))
|
||||
}
|
||||
if (this.apiKey.user ) {
|
||||
this.selectedUser = this.apiKey.user._id;
|
||||
}
|
||||
this.users = this.users.sort(function(a, b){return a.displayName.localeCompare(b.displayName);});
|
||||
if (this.apiKey) {
|
||||
this.sendData = JSON.parse(JSON.stringify(this.apiKey))
|
||||
}
|
||||
if (this.apiKey.user ) {
|
||||
this.selectedUser = this.apiKey.user._id;
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
26
src/app/modals/edit-provision.component.html
Normal file
26
src/app/modals/edit-provision.component.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<!--Content-->
|
||||
<div class="modal-content">
|
||||
<div class="modal-header text-center">
|
||||
<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 font-weight-bold">Edit Provision</h4>
|
||||
</div>
|
||||
<div class="modal-body" style="max-height: 650px; overflow: auto;">
|
||||
<div>
|
||||
<section style="padding: 20px 0px;">
|
||||
<label>Onwer (*):</label>
|
||||
<select class="browser-default custom-select custom-select-sm" [(ngModel)]="selectedUser">
|
||||
<option *ngFor="let item of users" [value]="item._id">{{item.displayName}}</option>
|
||||
</select>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer d-flex justify-content-center">
|
||||
<button style="margin-right: 100px;" *ngIf="sendData._id" mdbBtn color="danger" outline="true" class="waves-light" size="sm" mdbWavesEffect (click)="delete();">Delete</button>
|
||||
<button mdbBtn color="dark-green" size="sm" outline="true" class="waves-effect" mdbWavesEffect (click)="modalRef.hide()">Cancel</button>
|
||||
<button mdbBtn color="dark-green" class="waves-light" size="sm" mdbWavesEffect (click)="confirm();">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<!--/.Content-->
|
||||
0
src/app/modals/edit-provision.component.scss
Normal file
0
src/app/modals/edit-provision.component.scss
Normal file
45
src/app/modals/edit-provision.component.ts
Normal file
45
src/app/modals/edit-provision.component.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { MDBModalRef } from 'angular-bootstrap-md';
|
||||
import { Subject } from 'rxjs';
|
||||
import { UsersService } from '../services/users.service';
|
||||
import { ProvisionsService } from '../services/provisions.service';
|
||||
|
||||
@Component({
|
||||
selector: 'qmi-edit-provision',
|
||||
templateUrl: './edit-provision.component.html',
|
||||
styleUrls: ['./edit-provision.component.scss']
|
||||
})
|
||||
export class ProvisionModalComponent implements OnInit, OnDestroy {
|
||||
|
||||
provision;
|
||||
action: Subject<any> = new Subject();
|
||||
users;
|
||||
selectedUser;
|
||||
|
||||
sendData : any = {};
|
||||
|
||||
constructor( public modalRef: MDBModalRef, private _usersService: UsersService, private _provisionsService: ProvisionsService ) {}
|
||||
|
||||
ngOnInit() {
|
||||
var sub = this._usersService.getUsers().subscribe(res=> {
|
||||
this.users = res.results;
|
||||
this.users = this.users.sort(function(a, b){return a.displayName.localeCompare(b.displayName);});
|
||||
sub.unsubscribe();
|
||||
if (this.provision.user ) {
|
||||
this.selectedUser = this.provision.user._id;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
||||
}
|
||||
|
||||
confirm() : void {
|
||||
this._provisionsService.updateProvisionAdmin(this.provision._id, { user: this.selectedUser } ).subscribe( res=>{
|
||||
this.action.next(res);
|
||||
this.modalRef.hide();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,6 +40,9 @@
|
||||
<section style="padding: 20px 0px; margin: 0px 20px">
|
||||
<mdb-checkbox (change)="checkOnchange($event, 'isExternal')" [checked]="sendData.isExternal" [default]="false"><mdb-icon fas icon="globe-americas" class="grey-text" aria-hidden="true"></mdb-icon> With External Access?</mdb-checkbox>
|
||||
</section>
|
||||
<section style="padding: 20px 0px; margin: 0px 20px">
|
||||
<mdb-checkbox (change)="checkOnchange($event, 'isDivvyEnabled')" [checked]="sendData.isDivvyEnabled" [default]="false"><mdb-icon fas icon="clock" class="grey-text" aria-hidden="true"></mdb-icon> Enable DivvyCloud Tags?</mdb-checkbox>
|
||||
</section>
|
||||
<section style="padding: 20px 0px; margin: 0px 20px">
|
||||
<mdb-checkbox (change)="checkOnchange($event, 'isWafPolicyAppGw')" [checked]="sendData.isWafPolicyAppGw" [default]="false"><mdb-icon fas icon="fire-extinguisher" class="grey-text" aria-hidden="true"></mdb-icon> Apply WAF policy after provision?</mdb-checkbox>
|
||||
</section>
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
</div>
|
||||
|
||||
<section *ngIf="scenario.isExternal" style="padding: 20px 0px; margin: 0px 20px">
|
||||
<mdb-checkbox [default]="false" (change)="checkOnchange($event)">Enable External Access</mdb-checkbox>
|
||||
<mdb-checkbox [default]="false" (change)="checkOnchange($event)">Enable External Access <i>(<mdb-icon fas icon="exclamation-triangle"></mdb-icon> only if it's strictly necessary)</i></mdb-checkbox>
|
||||
</section>
|
||||
|
||||
<section *ngIf="!scenario.isExternal" style="padding: 20px 0px; margin: 0px 20px">
|
||||
<mdb-checkbox [default]="false" (change)="checkOnchange($event)" [disabled]="true"><span style="color:#ccc">Enable External Access</span><br><i><mdb-icon fas icon="exclamation-triangle"></mdb-icon> This scenario only allows access from VPN</i></mdb-checkbox>
|
||||
<mdb-checkbox [default]="false" (change)="checkOnchange($event)" [disabled]="true"><span style="color:#ccc">Enable External Access <i>(only if it's strictly necessary)</i></span><br><i><mdb-icon fas icon="exclamation-triangle"></mdb-icon> This scenario only allows access from VPN</i></mdb-checkbox>
|
||||
</section>
|
||||
|
||||
<div style="padding-top: 10px" class="md-form" >
|
||||
@@ -55,6 +55,30 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="scenario.isDivvyEnabled">
|
||||
<div>
|
||||
<label>Running window</label>
|
||||
</div>
|
||||
<div class="md-form row" *ngIf="!autoShutdown.is24x7">
|
||||
<div class="col-sm-6">
|
||||
<div>Startup time:</div>
|
||||
<ngb-timepicker style="font-size: 10px;" [(ngModel)]="autoShutdown.startupTime" [meridian]="true" [minuteStep]="15"></ngb-timepicker>
|
||||
<div>
|
||||
<i>UTC - {{getUTCTimes().startupTime}}</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div>Shutdown time:</div>
|
||||
<ngb-timepicker [(ngModel)]="autoShutdown.shutdownTime" [meridian]="true" [minuteStep]="15"></ngb-timepicker>
|
||||
<div>
|
||||
<i>UTC - {{getUTCTimes().shutdownTime}}</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section style="padding: 20px 0px; margin: 0px 20px">
|
||||
<mdb-checkbox [default]="false" [checked]="autoShutdown.is24x7" (change)="checkOnchangeAutoshutdown($event)">Enable 24x7 access <i>(Requires permission from regional manager)</i></mdb-checkbox>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer d-flex justify-content-center">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
label {
|
||||
position: relative;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.md-form {
|
||||
@@ -9,4 +10,8 @@ label {
|
||||
|
||||
::placeholder {
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
.ngb-tp-meridian .btn {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Component, Injectable, OnInit, OnDestroy } from '@angular/core';
|
||||
import { MDBModalRef } from 'angular-bootstrap-md';
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
import { ScenariosService } from '../services/scenarios.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'qmi-new-provision',
|
||||
templateUrl: './new-provision.component.html',
|
||||
@@ -13,10 +14,10 @@ export class NewProvisionConfirmComponent implements OnInit, OnDestroy {
|
||||
scenario;
|
||||
action: Subject<any> = new Subject();
|
||||
shortDesc: string;
|
||||
sendData = {
|
||||
sendData : any = {
|
||||
description: "",
|
||||
servers: null,
|
||||
isExternalAccess: false,
|
||||
isExternalAccess: false
|
||||
};
|
||||
selectedProductVersion: any = {};
|
||||
selectedVmType: any = {};
|
||||
@@ -25,6 +26,19 @@ export class NewProvisionConfirmComponent implements OnInit, OnDestroy {
|
||||
vmTypesSub: Subscription;
|
||||
vmTypes: any;
|
||||
servers: any = {};
|
||||
today = new Date();
|
||||
autoShutdown: any = {
|
||||
is24x7: false,
|
||||
startupTime: {
|
||||
"hour": this.today.getHours(),
|
||||
"minute": 0
|
||||
},
|
||||
shutdownTime: {
|
||||
"hour": this.today.getHours()+8,
|
||||
"minute": 0
|
||||
}
|
||||
};
|
||||
|
||||
constructor( public modalRef: MDBModalRef, private _scenariosService: ScenariosService ) {}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -55,6 +69,35 @@ export class NewProvisionConfirmComponent implements OnInit, OnDestroy {
|
||||
})
|
||||
}
|
||||
|
||||
private _addZero(i) {
|
||||
if (i < 10) {
|
||||
i = "0" + i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
getUTCTimes() : any {
|
||||
var dateStartup = new Date();
|
||||
var dateShutdown = new Date();
|
||||
dateStartup.setHours(this.autoShutdown.startupTime.hour);
|
||||
dateStartup.setMinutes(this.autoShutdown.startupTime.minute);
|
||||
dateStartup.setSeconds(0);
|
||||
dateShutdown.setHours(this.autoShutdown.shutdownTime.hour);
|
||||
dateShutdown.setMinutes(this.autoShutdown.shutdownTime.minute);
|
||||
dateShutdown.setSeconds(0);
|
||||
//var hourStart = this._addZero(dateStartup.getUTCHours());
|
||||
//var hourShut = this._addZero(dateShutdown.getUTCHours());
|
||||
var minShut = this._addZero(dateShutdown.getUTCMinutes());
|
||||
var minStart = this._addZero(dateStartup.getUTCMinutes());
|
||||
return {
|
||||
startupTime: dateStartup.getUTCHours() +":"+minStart,
|
||||
shutdownTime: dateShutdown.getUTCHours() +":"+minShut,
|
||||
tagStartup: this._addZero(dateStartup.getUTCHours())+""+minStart,
|
||||
tagShutdown: this._addZero(dateShutdown.getUTCHours())+""+minShut,
|
||||
timezoneOffset: dateStartup.getTimezoneOffset()
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
||||
}
|
||||
@@ -87,14 +130,34 @@ export class NewProvisionConfirmComponent implements OnInit, OnDestroy {
|
||||
})
|
||||
});
|
||||
}
|
||||
if ( this.scenario.isDivvyEnabled ) {
|
||||
if ( !this.autoShutdown.is24x7 ) {
|
||||
this.sendData.autoShutdownData = {
|
||||
is24x7: false,
|
||||
utcTagStartupTime: this.getUTCTimes().tagStartup,
|
||||
utcTagShutdownTime: this.getUTCTimes().tagShutdown,
|
||||
localeStartupTime: this.autoShutdown.startupTime.hour+":"+this._addZero(this.autoShutdown.startupTime.minute),
|
||||
localeShutdownTime: this.autoShutdown.shutdownTime.hour+":"+this._addZero(this.autoShutdown.shutdownTime.minute),
|
||||
timezoneOffset: this.getUTCTimes().timezoneOffset
|
||||
}
|
||||
} else {
|
||||
this.sendData.autoShutdownData = {
|
||||
is24x7: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log("sendData", this.sendData);
|
||||
this.action.next(this.sendData);
|
||||
this.modalRef.hide();
|
||||
}
|
||||
|
||||
checkOnchange($event) {
|
||||
console.log("Checked?", $event.checked);
|
||||
this.sendData.isExternalAccess = $event.checked;
|
||||
}
|
||||
|
||||
checkOnchangeAutoshutdown($event) {
|
||||
this.autoShutdown.is24x7 = $event.checked;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -41,7 +41,7 @@ export class ScenariosComponent implements OnInit, OnDestroy {
|
||||
|
||||
openNewProvisionConfirmModal(scenario) {
|
||||
var modalRef = this.modalService.show(NewProvisionConfirmComponent, {
|
||||
class: 'modal-md modal-notify',
|
||||
class: 'modal-lg modal-notify',
|
||||
containerClass: '',
|
||||
data: {
|
||||
scenario: scenario
|
||||
@@ -60,6 +60,9 @@ export class ScenariosComponent implements OnInit, OnDestroy {
|
||||
if ( data.servers ) {
|
||||
postData["vmImage"] = data.servers;
|
||||
}
|
||||
if (data.autoShutdownData) {
|
||||
postData["autoShutdownData"] = data.autoShutdownData;
|
||||
}
|
||||
|
||||
this._provisionsService.newProvision(postData, this.user._id).subscribe( res => {
|
||||
console.log("Done!", res);
|
||||
|
||||
@@ -43,6 +43,10 @@ export class ProvisionsService {
|
||||
return this.httpClient.delete(`${environment.apiVersionPath}/users/${userId}/provisions/${id}`);
|
||||
}
|
||||
|
||||
updateProvisionAdmin(id, patch): Observable<any> {
|
||||
return this.httpClient.put(`${environment.apiVersionPath}/provisions/${id}`, patch);
|
||||
}
|
||||
|
||||
newDestroy(id, userId) : Observable<any> {
|
||||
return this.httpClient.post(`${environment.apiVersionPath}/users/${userId}/provisions/${id}/destroy`, null);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<tr>
|
||||
<th>ProvisionID</th>
|
||||
<th [mdbTableSort]="elements" sortBy="created" >Prov. Date <mdb-icon fas icon="sort"></mdb-icon></th>
|
||||
<th [mdbTableSort]="elements" sortBy="user.displayName">User <mdb-icon fas icon="sort"></mdb-icon></th>
|
||||
<th [mdbTableSort]="elements" sortBy="user.displayName">Owner <mdb-icon fas icon="sort"></mdb-icon></th>
|
||||
<th [mdbTableSort]="elements" sortBy="scenario">Scenario (v)<mdb-icon fas icon="sort"></mdb-icon></th>
|
||||
<th [mdbTableSort]="elements" sortBy="isExternalAccess">Ext. Access? <mdb-icon fas icon="sort"></mdb-icon></th>
|
||||
<th [mdbTableSort]="elements" sortBy="statusVms">VMs (Running time)<mdb-icon fas icon="sort"></mdb-icon></th>
|
||||
@@ -40,7 +40,9 @@
|
||||
<a href (click)="showLogs($event, provision, 'provision')" class="lui-text-info">{{ provision._id }}</a>
|
||||
</td>
|
||||
<td (click)="openInfoModal(provision)" *ngIf="pagingIsDisabled || (i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex)">{{provision.created | date: 'MMM dd, yyyy - H:mm'}}</td>
|
||||
<td (click)="openInfoModal(provision)" *ngIf="pagingIsDisabled || (i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex)" class="ell" title="{{provision.path}}" >{{provision.user.displayName}}</td>
|
||||
<td *ngIf="pagingIsDisabled || (i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex)" class="ell" title="{{provision.path}}" >
|
||||
<a href (click)="openOwnerChange($event, provision)" class="lui-text-info">{{provision.user.displayName}}</a>
|
||||
</td>
|
||||
<td (click)="openInfoModal(provision)"*ngIf="pagingIsDisabled || (i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex)">{{provision.scenario}} (v{{provision.scenarioVersion}})</td>
|
||||
<td style="text-align: center;" (click)="openInfoModal(provision)"*ngIf="pagingIsDisabled || (i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex)"><mdb-icon *ngIf="provision.isExternalAccess" fas icon="check"></mdb-icon></td>
|
||||
<td (click)="openInfoModal(provision)" *ngIf="pagingIsDisabled || (i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex)">
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Component, OnInit, ElementRef, HostListener, AfterViewInit, ViewChild, ChangeDetectorRef, Input, OnDestroy } from '@angular/core';
|
||||
import { Component, OnInit, HostListener, AfterViewInit, ViewChild, ChangeDetectorRef, OnDestroy } 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 '../modals/modalinfo.component';
|
||||
import { ModalConfirmComponent } from '../modals/confirm.component';
|
||||
import { Subscription, timer } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { ScenariosService } from '../services/scenarios.service';
|
||||
import { ProvisionModalComponent } from '../modals/edit-provision.component';
|
||||
@Component({
|
||||
selector: 'table-provisions',
|
||||
templateUrl: './table-provisions.component.html',
|
||||
@@ -39,7 +39,6 @@ export class TableProvisionsAdminComponent implements OnInit, OnDestroy, AfterVi
|
||||
this.mdbTablePagination.searchText = this.searchText;
|
||||
}
|
||||
|
||||
|
||||
selectedprov: any = null;
|
||||
showInfo: boolean = false;
|
||||
logShow: boolean = false;
|
||||
@@ -59,10 +58,11 @@ export class TableProvisionsAdminComponent implements OnInit, OnDestroy, AfterVi
|
||||
}
|
||||
|
||||
private _process(provisions) : void {
|
||||
provisions.forEach(p=>{
|
||||
provisions.forEach( p=> {
|
||||
p.user.currentUserId = p.user._id;
|
||||
p._scenario = this.scenarios.filter(s => s.name === p.scenario);
|
||||
this._provisionsService.timeRunning(p);
|
||||
});
|
||||
} );
|
||||
if ( this.elements.length === 0 ) {
|
||||
this.elements = provisions;
|
||||
} else {
|
||||
@@ -93,7 +93,6 @@ export class TableProvisionsAdminComponent implements OnInit, OnDestroy, AfterVi
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
var scenariosSub = this._scenariosService.getScenariosAll().subscribe( res => {
|
||||
scenariosSub.unsubscribe();
|
||||
this.scenarios = res.results;
|
||||
@@ -126,6 +125,26 @@ export class TableProvisionsAdminComponent implements OnInit, OnDestroy, AfterVi
|
||||
}
|
||||
}
|
||||
|
||||
openOwnerChange($event, provision){
|
||||
$event.preventDefault();
|
||||
var modalRef = this.modalService.show(ProvisionModalComponent, {
|
||||
class: 'modal-md modal-notify',
|
||||
containerClass: '',
|
||||
data: {
|
||||
provision: provision
|
||||
}
|
||||
} );
|
||||
|
||||
var sub = modalRef.content.action.subscribe( (result: any) => {
|
||||
sub.unsubscribe();
|
||||
provision.user = result.user;
|
||||
this._alertService.showAlert({
|
||||
type: 'alert-primary',
|
||||
text: `New owner ${provision.user.displayName} assigned to this provision`
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
searchItems() {
|
||||
const prev = this.mdbTable.getDataSource();
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<th style="width: 400px;">AvailableProductVersions</th>
|
||||
<th mdbTooltip="isAdminOnly?" style="width: 34px; text-align: center;"><mdb-icon fas icon="user-secret" class="grey-text" aria-hidden="true"></mdb-icon></th>
|
||||
<th mdbTooltip="isExternal?" style="width: 34px; text-align: center;"><mdb-icon fas icon="globe-americas" class="grey-text" aria-hidden="true"></mdb-icon></th>
|
||||
<th mdbTooltip="isDivvyEnabled?" style="width: 34px; text-align: center;"><mdb-icon fas icon="clock" class="grey-text" aria-hidden="true"></mdb-icon></th>
|
||||
<th mdbTooltip="isWafPolicyAppGw?" style="width: 34px; text-align: center;"><mdb-icon fas icon="fire-extinguisher" class="grey-text" aria-hidden="true"></mdb-icon></th>
|
||||
<!--<th mdbTooltip="isVnetIsolated?" style="width: 34px; text-align: center;"><mdb-icon fas icon="network-wired" class="grey-text" aria-hidden="true"></mdb-icon></th>-->
|
||||
<th mdbTooltip="isDisabled?" style="width: 34px; text-align: center;"><mdb-icon fas icon="ban" class="grey-text" aria-hidden="true"></mdb-icon></th>
|
||||
@@ -35,6 +36,7 @@
|
||||
<td *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex"><pre>{{item.availableProductVersions | json}}</pre></td>
|
||||
<td mdbTooltip="isAdminOnly?" style="width: 34px; text-align: center;" *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex"><mdb-icon *ngIf="item.isAdminOnly" fas icon="check"></mdb-icon></td>
|
||||
<td mdbTooltip="isExternal?" style="width: 34px; text-align: center;" *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex"><mdb-icon *ngIf="item.isExternal" fas icon="check"></mdb-icon></td>
|
||||
<td mdbTooltip="isDivvyEnabled?" style="width: 34px; text-align: center;" *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex"><mdb-icon *ngIf="item.isDivvyEnabled" fas icon="check"></mdb-icon></td>
|
||||
<td mdbTooltip="isWafPolicyAppGw?" style="width: 34px; text-align: center;" *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex"><mdb-icon *ngIf="item.isWafPolicyAppGw" fas icon="check"></mdb-icon></td>
|
||||
<!--<td mdbTooltip="isVnetIsolated?" style="width: 34px; text-align: center;" *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex"><mdb-icon *ngIf="item.isVnetIsolated" fas icon="check"></mdb-icon></td>-->
|
||||
<td mdbTooltip="isDisabled?" style="width: 34px; text-align: center;" *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex"><mdb-icon *ngIf="item.isDisabled" fas icon="check"></mdb-icon></td>
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/***************************************************************************************************
|
||||
* Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
|
||||
*/
|
||||
import '@angular/localize/init';
|
||||
/**
|
||||
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||
* You can add your own extra polyfills to this file.
|
||||
|
||||
@@ -31,4 +31,6 @@ body {
|
||||
color: #616161 !important;
|
||||
}
|
||||
}
|
||||
//@import "assets/album.css";
|
||||
//@import "assets/album.css";
|
||||
/* Importing Bootstrap SCSS file. */
|
||||
@import '~bootstrap/scss/bootstrap';
|
||||
|
||||
150
yarn.lock
150
yarn.lock
@@ -198,6 +198,15 @@
|
||||
resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-9.0.7.tgz#c204467383ee5f194a73a365ea7c543c6900bb54"
|
||||
integrity sha512-IZG1kvw48JyFRy7bfMHqBixWrEHZmXmkP5DWsi5Tw6KusaczkMghI20BevCkodPcajXWHAUHNKyp1tlE3OnH0w==
|
||||
|
||||
"@angular/localize@~9.0.7":
|
||||
version "9.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-9.0.7.tgz#c40846e679917ee1575b009f78de822ac100add0"
|
||||
integrity sha512-nlmcxEVZmz4ty1MXE1OFnHMYndedQUunZY4MB3lm7c8MJrRnI5x7zAOvkwI+sUF0Hy3rfjkO7ddOzGBfDtjPPA==
|
||||
dependencies:
|
||||
"@babel/core" "7.8.3"
|
||||
glob "7.1.2"
|
||||
yargs "13.1.0"
|
||||
|
||||
"@angular/platform-browser-dynamic@~9.0.7":
|
||||
version "9.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.0.7.tgz#7ca7e728fea0ba81b1009de1aa59a003b73c89af"
|
||||
@@ -220,6 +229,13 @@
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.10.1"
|
||||
|
||||
"@babel/code-frame@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
|
||||
integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.10.4"
|
||||
|
||||
"@babel/code-frame@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e"
|
||||
@@ -247,6 +263,27 @@
|
||||
semver "^5.4.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/core@7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.3.tgz#30b0ebb4dd1585de6923a0b4d179e0b9f5d82941"
|
||||
integrity sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.8.3"
|
||||
"@babel/generator" "^7.8.3"
|
||||
"@babel/helpers" "^7.8.3"
|
||||
"@babel/parser" "^7.8.3"
|
||||
"@babel/template" "^7.8.3"
|
||||
"@babel/traverse" "^7.8.3"
|
||||
"@babel/types" "^7.8.3"
|
||||
convert-source-map "^1.7.0"
|
||||
debug "^4.1.0"
|
||||
gensync "^1.0.0-beta.1"
|
||||
json5 "^2.1.0"
|
||||
lodash "^4.17.13"
|
||||
resolve "^1.3.2"
|
||||
semver "^5.4.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/core@^7.7.5":
|
||||
version "7.10.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.2.tgz#bd6786046668a925ac2bd2fd95b579b92a23b36a"
|
||||
@@ -289,6 +326,16 @@
|
||||
lodash "^4.17.13"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.10.4", "@babel/generator@^7.8.3":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.4.tgz#e49eeed9fe114b62fa5b181856a43a5e32f5f243"
|
||||
integrity sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==
|
||||
dependencies:
|
||||
"@babel/types" "^7.10.4"
|
||||
jsesc "^2.5.1"
|
||||
lodash "^4.17.13"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.4.0", "@babel/generator@^7.8.4":
|
||||
version "7.8.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.4.tgz#35bbc74486956fe4251829f9f6c48330e8d0985e"
|
||||
@@ -349,6 +396,15 @@
|
||||
"@babel/template" "^7.10.1"
|
||||
"@babel/types" "^7.10.1"
|
||||
|
||||
"@babel/helper-function-name@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a"
|
||||
integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==
|
||||
dependencies:
|
||||
"@babel/helper-get-function-arity" "^7.10.4"
|
||||
"@babel/template" "^7.10.4"
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/helper-function-name@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca"
|
||||
@@ -365,6 +421,13 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.10.1"
|
||||
|
||||
"@babel/helper-get-function-arity@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2"
|
||||
integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==
|
||||
dependencies:
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/helper-get-function-arity@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5"
|
||||
@@ -461,6 +524,13 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.10.1"
|
||||
|
||||
"@babel/helper-split-export-declaration@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz#2c70576eaa3b5609b24cb99db2888cc3fc4251d1"
|
||||
integrity sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==
|
||||
dependencies:
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/helper-split-export-declaration@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9"
|
||||
@@ -473,6 +543,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz#5770b0c1a826c4f53f5ede5e153163e0318e94b5"
|
||||
integrity sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2"
|
||||
integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==
|
||||
|
||||
"@babel/helper-wrap-function@^7.10.1":
|
||||
version "7.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz#956d1310d6696257a7afd47e4c42dfda5dfcedc9"
|
||||
@@ -492,6 +567,15 @@
|
||||
"@babel/traverse" "^7.10.1"
|
||||
"@babel/types" "^7.10.1"
|
||||
|
||||
"@babel/helpers@^7.8.3":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044"
|
||||
integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==
|
||||
dependencies:
|
||||
"@babel/template" "^7.10.4"
|
||||
"@babel/traverse" "^7.10.4"
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/highlight@^7.10.1":
|
||||
version "7.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.1.tgz#841d098ba613ba1a427a2b383d79e35552c38ae0"
|
||||
@@ -501,6 +585,15 @@
|
||||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/highlight@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143"
|
||||
integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.10.4"
|
||||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/highlight@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797"
|
||||
@@ -515,6 +608,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.2.tgz#871807f10442b92ff97e4783b9b54f6a0ca812d0"
|
||||
integrity sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==
|
||||
|
||||
"@babel/parser@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.4.tgz#9eedf27e1998d87739fb5028a5120557c06a1a64"
|
||||
integrity sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==
|
||||
|
||||
"@babel/parser@^7.4.3", "@babel/parser@^7.8.3", "@babel/parser@^7.8.4":
|
||||
version "7.8.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.4.tgz#d1dbe64691d60358a974295fa53da074dd2ce8e8"
|
||||
@@ -929,6 +1027,15 @@
|
||||
"@babel/parser" "^7.10.1"
|
||||
"@babel/types" "^7.10.1"
|
||||
|
||||
"@babel/template@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
|
||||
integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
"@babel/parser" "^7.10.4"
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/template@^7.4.0", "@babel/template@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8"
|
||||
@@ -953,6 +1060,21 @@
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.13"
|
||||
|
||||
"@babel/traverse@^7.10.4", "@babel/traverse@^7.8.3":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.4.tgz#e642e5395a3b09cc95c8e74a27432b484b697818"
|
||||
integrity sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
"@babel/generator" "^7.10.4"
|
||||
"@babel/helper-function-name" "^7.10.4"
|
||||
"@babel/helper-split-export-declaration" "^7.10.4"
|
||||
"@babel/parser" "^7.10.4"
|
||||
"@babel/types" "^7.10.4"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.13"
|
||||
|
||||
"@babel/traverse@^7.4.3":
|
||||
version "7.8.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.4.tgz#f0845822365f9d5b0e312ed3959d3f827f869e3c"
|
||||
@@ -977,6 +1099,15 @@
|
||||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.4.tgz#369517188352e18219981efd156bfdb199fff1ee"
|
||||
integrity sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.10.4"
|
||||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.4.0", "@babel/types@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c"
|
||||
@@ -1008,6 +1139,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd"
|
||||
integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==
|
||||
|
||||
"@ng-bootstrap/ng-bootstrap@6.2.0":
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-6.2.0.tgz#0506d612ca6002bd8fa398d006fa2641013e11d4"
|
||||
integrity sha512-wqwhnJFyEwvzWQJjXrEt+7oBTSvu2qPbdYvUFYhDVzOJLWB5M7YEhDAkMrfHQJ0pZNBMGr580FqYue+XiURY0Q==
|
||||
|
||||
"@ngtools/webpack@9.0.7":
|
||||
version "9.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.0.7.tgz#2d9397544afcf503530eafc764c64d40a99fa070"
|
||||
@@ -4593,6 +4729,18 @@ glob-parent@~5.1.0:
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob@7.1.2:
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
|
||||
integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@7.1.5:
|
||||
version "7.1.5"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0"
|
||||
@@ -8390,7 +8538,7 @@ qjobs@^1.1.4:
|
||||
integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==
|
||||
|
||||
qmi-cloud-common@./qmi-cloud-common:
|
||||
version "1.1.2"
|
||||
version "1.1.3"
|
||||
dependencies:
|
||||
"@hapi/boom" "^9.1.0"
|
||||
azure-arm-compute "^10.0.0"
|
||||
|
||||
Reference in New Issue
Block a user