no other modules
This commit is contained in:
3
.npmrc
Normal file
3
.npmrc
Normal file
@@ -0,0 +1,3 @@
|
||||
@QMI:registry=https://gitlab.com/api/v4/packages/npm/
|
||||
'//gitlab.com/api/v4/packages/npm/:_authToken'="${GITLAB_AUTH_TOKEN}"
|
||||
'//gitlab.com/api/v4/projects/15526459/packages/npm/:_authToken'="${GITLAB_AUTH_TOKEN}"
|
||||
@@ -1,23 +0,0 @@
|
||||
echo "--- Building QMI Cloud docker images for branch $CI_COMMIT_REF_NAME"
|
||||
|
||||
IMAGE_NAME="qlikgear/qmi-cloud-cli"
|
||||
PROJECT_FOLDER="./qmi-cloud-cli"
|
||||
|
||||
export VERSION=$(cat $PROJECT_FOLDER/package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]')
|
||||
|
||||
export TAG=$VERSION
|
||||
export STABLE_TAG="latest"
|
||||
export BUILD_ENV=""
|
||||
|
||||
if [ "$CI_COMMIT_REF_NAME" != "master" ]; then
|
||||
TAG="$VERSION-$CI_COMMIT_REF_NAME"
|
||||
STABLE_TAG="latestdev"
|
||||
BUILD_ENV="staging"
|
||||
fi
|
||||
|
||||
echo "--- Building image: $IMAGE_NAME:$TAG"
|
||||
docker build -f $PROJECT_FOLDER/Dockerfile --build-arg BUILD_ENV=$BUILD_ENV -t $IMAGE_NAME:$TAG ./
|
||||
echo "--- Pushing image: $IMAGE_NAME:$TAG"
|
||||
docker push $IMAGE_NAME:$TAG
|
||||
docker image tag $IMAGE_NAME:$TAG $IMAGE_NAME:$STABLE_TAG
|
||||
docker push $IMAGE_NAME:$STABLE_TAG
|
||||
@@ -1,26 +0,0 @@
|
||||
echo "--- Building QMI Cloud docker images for branch $CI_COMMIT_REF_NAME"
|
||||
|
||||
IMAGE_NAME="qlikgear/qmi-cloud-webhook"
|
||||
PROJECT_FOLDER="./qmi-cloud-webhook"
|
||||
|
||||
export VERSION=$(cat $PROJECT_FOLDER/package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]')
|
||||
|
||||
export TAG=$VERSION
|
||||
export STABLE_TAG="latest"
|
||||
export BUILD_ENV=""
|
||||
|
||||
if [ "$CI_COMMIT_REF_NAME" != "master" ]; then
|
||||
TAG="$VERSION-$CI_COMMIT_REF_NAME"
|
||||
STABLE_TAG="latestdev"
|
||||
BUILD_ENV="staging"
|
||||
fi
|
||||
|
||||
echo "--- Building image: $IMAGE_NAME:$TAG"
|
||||
docker build -f $PROJECT_FOLDER/Dockerfile --build-arg BUILD_ENV=$BUILD_ENV -t $IMAGE_NAME:$TAG ./
|
||||
echo "--- Pushing image: $IMAGE_NAME:$TAG"
|
||||
docker push $IMAGE_NAME:$TAG
|
||||
docker image tag $IMAGE_NAME:$TAG $IMAGE_NAME:$STABLE_TAG
|
||||
docker push $IMAGE_NAME:$STABLE_TAG
|
||||
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
echo "--- Building QMI Cloud docker images for branch $CI_COMMIT_REF_NAME"
|
||||
|
||||
IMAGE_NAME="qlikgear/qmi-cloud-worker"
|
||||
PROJECT_FOLDER="./qmi-cloud-worker"
|
||||
|
||||
export VERSION=$(cat $PROJECT_FOLDER/package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]')
|
||||
|
||||
export TAG=$VERSION
|
||||
export STABLE_TAG="latest"
|
||||
export BUILD_ENV=""
|
||||
|
||||
if [ "$CI_COMMIT_REF_NAME" != "master" ]; then
|
||||
TAG="$VERSION-$CI_COMMIT_REF_NAME"
|
||||
STABLE_TAG="latestdev"
|
||||
BUILD_ENV="staging"
|
||||
fi
|
||||
|
||||
echo "--- Building image: $IMAGE_NAME:$TAG"
|
||||
docker build -f $PROJECT_FOLDER/Dockerfile --build-arg BUILD_ENV=$BUILD_ENV -t $IMAGE_NAME:$TAG ./
|
||||
echo "--- Pushing image: $IMAGE_NAME:$TAG"
|
||||
docker push $IMAGE_NAME:$TAG
|
||||
docker image tag $IMAGE_NAME:$TAG $IMAGE_NAME:$STABLE_TAG
|
||||
docker push $IMAGE_NAME:$STABLE_TAG
|
||||
2
dist/qmi-cloud/index.html
vendored
2
dist/qmi-cloud/index.html
vendored
@@ -22,7 +22,7 @@
|
||||
data-host="https://innovation.us.qlikcloud.com"
|
||||
data-auth-type="Oauth2"
|
||||
data-client-id="21be5044bba1072c16a803a3e6e4dca0"
|
||||
data-redirect-uri="https://qmicloud.qliktech.com/oauth-callback.html"
|
||||
data-redirect-uri="http://localhost:3000/oauth-callback.html"
|
||||
data-access-token-storage="session"
|
||||
data-auto-redirect="true"></script>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "qmi-cloud-app",
|
||||
"version": "5.0.6",
|
||||
"version": "5.0.7",
|
||||
"scripts": {
|
||||
"start": "node server/server.js",
|
||||
"start:dev": "nodemon server/server.js",
|
||||
@@ -24,6 +24,7 @@
|
||||
"@hapi/boom": "^9.1.0",
|
||||
"@ng-bootstrap/ng-bootstrap": "6.2.0",
|
||||
"@types/chart.js": "^2.9.16",
|
||||
"@QMI/qmi-cloud-common": "2.0.3",
|
||||
"adal-angular4": "^4.0.12",
|
||||
"angular-bootstrap-md": "9.0.0",
|
||||
"animate.css": "^3.7.2",
|
||||
@@ -54,7 +55,6 @@
|
||||
"passport": "^0.4.0",
|
||||
"passport-openidconnect": "^0.1.2",
|
||||
"qdt-components": "^2.5.5",
|
||||
"qmi-cloud-common": "./qmi-cloud-common",
|
||||
"request-ip": "^3.3.0",
|
||||
"rxjs": "~6.5.4",
|
||||
"swagger-jsdoc": "6.2.8",
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
# Stage 1: NOTE: context is actually ../
|
||||
FROM node:20.14-alpine AS sources
|
||||
|
||||
RUN apk --no-cache add yarn git
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ADD ./qmi-cloud-cli ./
|
||||
ADD ./qmi-cloud-common ../qmi-cloud-common
|
||||
|
||||
RUN yarn install --production
|
||||
|
||||
# Stage 2:
|
||||
FROM node:20.14-alpine AS production
|
||||
WORKDIR /app
|
||||
COPY --from=sources /app ./
|
||||
|
||||
RUN chmod a+x ./shell-utils/*.sh
|
||||
|
||||
ENTRYPOINT ["sh", "/app/shell-utils/check.sh"]
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# Examples
|
||||
|
||||
## Check Destroy
|
||||
```
|
||||
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 checkdestroy -t warning -r test
|
||||
```
|
||||
|
||||
## Init DB
|
||||
```
|
||||
docker run --net=host \
|
||||
-e MONGO_URI="mongodb://root:example@localhost:27017/qmicloud?authSource=admin" \
|
||||
qlikgear/qmi-cloud-cli:latest -s initdb
|
||||
```
|
||||
|
||||
## Check Destroy
|
||||
```
|
||||
docker run --net=host -e MONGO_URI=$MONGO_URI -e API_KEY=$API_KEY qlikgear/qmi-cloud-cli:latest -s checkdestroy -t warning -r test
|
||||
```
|
||||
|
||||
## Check Stop
|
||||
```
|
||||
docker run --net=host -e SMTP_EMAIL_SENDER=http://172.20.16.4:9200/sendemail -e MONGO_URI=$MONGO_URI -e API_KEY=$API_KEY qlikgear/qmi-cloud-cli:latest -s checkstop -t warning -r test
|
||||
```
|
||||
|
||||
## Check Errors
|
||||
```
|
||||
docker run --net=host -e MONGO_URI=$MONGO_URI qlikgear/qmi-cloud-cli:latest -s checkerror -r test
|
||||
```
|
||||
|
||||
## Move Destroyed
|
||||
```
|
||||
docker run --net=host -e MONGO_URI=$MONGO_URI -v $PWD/qmi-cloud-provisions:/provisions qlikgear/qmi-cloud-cli:latest -s movedestroyed -r "2020-31-12T00:00:00.000Z"
|
||||
```
|
||||
@@ -1,425 +0,0 @@
|
||||
[
|
||||
{
|
||||
"isAdminOnly": false,
|
||||
"isWafPolicyAppGw": true,
|
||||
"isExternal": true,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Qlik Sense",
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"index": "vm1",
|
||||
"values": [
|
||||
{
|
||||
"name": "Qlik Sense February 2020",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/images/qliksense-base-feb20-2"
|
||||
},
|
||||
{
|
||||
"name": "Qlik Sense April 2020",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/images/qliksense-base-april20-1587800741770"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"name": "azqmi-qs-sn",
|
||||
"title": "Qlik Sense Enterprise on Windows",
|
||||
"description": "Qlik Sense Enterprise on Windows (single node). Dashboard and visualization bundle installed.<br><br>WebConnectors installed but not licensed.",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T09:27:15.596Z",
|
||||
"updated": "2020-05-10T15:27:26.466Z",
|
||||
"__v": 0
|
||||
},
|
||||
{
|
||||
"isAdminOnly": false,
|
||||
"isWafPolicyAppGw": true,
|
||||
"isExternal": true,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Qlik Sense",
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"index": "vm1",
|
||||
"values": [
|
||||
{
|
||||
"name": "Qlik Sense February 2020",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/images/qliksense-base-feb20-2"
|
||||
},
|
||||
{
|
||||
"name": "Qlik Sense April 2020",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/images/qliksense-base-april20-1587800741770"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"product": "QDC",
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"index": "vm2",
|
||||
"values": [
|
||||
{
|
||||
"name": "QDC Single Server December 2019",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/images/qdc-base-4.4-2"
|
||||
},
|
||||
{
|
||||
"name": "QDC Single Server April 2020",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/images/qdc-base-april20-1588850882491"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"name": "azqmi-qdc-qs",
|
||||
"title": "Qlik Data Catalyst and Qlik Sense",
|
||||
"description": "Creates a <b>QDC single server</b> and a <b>Qlik Sense Enterprise</b>.<br><br>Configuration is all set to load QVDs located in C:/QVDs and \"Publish to Qlik\". Setup QDC Catalog in QS Data Manager <a target=\"blank\" href=\"https://confluence.qliktech.com/display/~AOR/QMI+Cloud+-+QDC+Catalogue+setup+in+Qlik+Sense\">here</a>. More appealing QVD demo configuration by <a target=\"blank\" href=\"https://confluence.qliktech.com/display/~kaa/Getting+Qlik+Catalog+for+QVD+ready+for+Demo+on+QMI+Cloud\">Kevin Alty</a>. Troubleshoot 'Publish To Qlik\" <a target=\"blank\" href=\"https://confluence.qliktech.com/display/~AOR/Troubleshooting+Publish+To+Qlik+in+QMI+Cloud+QS-QDC+scenario\">here</a>.",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T09:27:15.596Z",
|
||||
"updated": "2020-05-12T08:39:13.216Z",
|
||||
"__v": 0
|
||||
},
|
||||
{
|
||||
"isAdminOnly": true,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Oracle",
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"name": "azqmi-database-lkn",
|
||||
"title": "Oracle & Other databases",
|
||||
"description": "Oracle Database <b class=\"lui-text-danger\">DO NOT USE, DEV IN PROGRESS</b>",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T09:27:15.596Z",
|
||||
"updated": "2020-05-14T03:58:03.413Z"
|
||||
|
||||
},
|
||||
{
|
||||
"isAdminOnly": true,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "packer",
|
||||
"vmTypeDefault": "Standard_D8s_v3",
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"name": "azqmi-box-builder",
|
||||
"title": "Builds qmi desktop base box with packer",
|
||||
"description": "packer builder <b class=\"lui-text-danger\">DO NOT USE, GEAR INTERNAL ONLY</b>",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T09:27:15.596Z",
|
||||
"updated": "2020-05-20T02:59:57.772Z",
|
||||
"__v": 0
|
||||
},
|
||||
{
|
||||
"isAdminOnly": false,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": true,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "QDC",
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"index": "vm1",
|
||||
"values": [
|
||||
{
|
||||
"name": "QDC Single Server December 2019",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/images/qdc-base-4.4-2"
|
||||
},
|
||||
{
|
||||
"name": "QDC Single Server April 2020",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/images/qdc-base-april20-1588850882491"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"name": "azqmi-qdc-ss",
|
||||
"title": "Qlik Data Catalyst",
|
||||
"description": "Qlik Data Catalyst single server. Set appropriate license (after provision) if QDC4QVDs only version is needed.",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T09:26:39.532Z",
|
||||
"updated": "2020-05-10T15:22:34.537Z",
|
||||
"__v": 0
|
||||
},
|
||||
{
|
||||
"isAdminOnly": false,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Windows",
|
||||
"vmTypeDefault": "Standard_D2s_v3",
|
||||
"diskSizeGbDefault": 128,
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D2s_v3",
|
||||
"name": "azqmi-wn-bl",
|
||||
"title": "Windows Server 2016",
|
||||
"description": "Just a blank Windows Server 2016",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T09:26:11.396Z",
|
||||
"updated": "2020-05-10T12:39:09.646Z",
|
||||
"__v": 0
|
||||
},
|
||||
{
|
||||
"isAdminOnly": false,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Windows",
|
||||
"vmTypeDefault": "Standard_D2s_v3",
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D2s_v3",
|
||||
"name": "azqmi-wn-dbs",
|
||||
"title": "MySQL and MSSQL server databases",
|
||||
"description": "Windows Server 2016 running MySQL and MSSQL server databases.",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T08:55:31.948Z",
|
||||
"updated": "2020-05-16T12:57:06.937Z"
|
||||
},
|
||||
{
|
||||
"isAdminOnly": false,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Ubuntu 18.04",
|
||||
"vmTypeDefault": "Standard_B2s",
|
||||
"diskSizeGbDefault": 128,
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_B2s",
|
||||
"name": "azqmi-ubuntu",
|
||||
"title": "Ubuntu 18.04",
|
||||
"description": "Just a blank Ubuntu 18.04 instance",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T08:55:31.948Z",
|
||||
"updated": "2020-05-10T12:39:12.884Z",
|
||||
"__v": 0
|
||||
},
|
||||
{
|
||||
"isAdminOnly": false,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Centos 7.5",
|
||||
"vmTypeDefault": "Standard_B2s",
|
||||
"diskSizeGbDefault": 128,
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_B2s",
|
||||
"name": "azqmi-centos",
|
||||
"title": "Centos 7.5",
|
||||
"description": "Just a blank Centos 7.5 instance",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T08:55:31.948Z",
|
||||
"updated": "2020-05-10T12:39:15.087Z",
|
||||
"__v": 0
|
||||
},
|
||||
{
|
||||
"isAdminOnly": true,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Centos 7.5",
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"diskSizeGbDefault": 128,
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"name": "gen-qdc",
|
||||
"title": "Image generator - QDC",
|
||||
"description": "This scenario creates a VM and runs QDC install scripts. Then it will generalize the VM for it to become an Azure image.",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T08:55:31.948Z",
|
||||
"updated": "2020-05-10T12:39:17.323Z",
|
||||
"__v": 0,
|
||||
"newImageName": "qdc-base-april20"
|
||||
},
|
||||
{
|
||||
"isAdminOnly": true,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Windows",
|
||||
"vmTypeDefault": "Standard_D8s_v3",
|
||||
"diskSizeGbDefault": 128,
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D8s_v3",
|
||||
"name": "gen-qs",
|
||||
"title": "Image generator - QSEoW",
|
||||
"description": "This scenario creates a VM and will run Qlik Sense install scripts. Then it will generalize the VM for it to become an Azure image.",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T08:55:31.948Z",
|
||||
"updated": "2020-05-10T12:39:21.035Z",
|
||||
"newImageName": "qliksense-base-april20",
|
||||
"__v": 0
|
||||
},
|
||||
{
|
||||
"isAdminOnly": false,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "QlikView",
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"name": "azqmi-qv",
|
||||
"title": "QlikView Server and Publisher",
|
||||
"description": "This scenario creates a VM running <b>QlikView Server and Publisher April 2019 SR1</b> (access from VPN only).",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T08:55:31.948Z",
|
||||
"updated": "2020-05-10T12:39:23.148Z",
|
||||
"__v": 0
|
||||
},
|
||||
{
|
||||
"isAdminOnly": false,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "each node",
|
||||
"vmTypeDefault": "Standard_D8s_v3",
|
||||
"diskSizeGbDefault": 250,
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D8s_v3",
|
||||
"name": "azqmi-qseok-microk8s",
|
||||
"title": "Qlik Sense Enterprise on Kubernetes (microk8s)",
|
||||
"description": "Ubuntu 18.04 running <a target=\"blank\" href=\"https://microk8s.io/\">MicroK8s</a> cluster and QSEoK deployed in it. <br><br><b>Just for Demos, not for PoCs</b>",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T08:55:31.948Z",
|
||||
"updated": "2020-05-10T15:29:19.944Z",
|
||||
"__v": 0
|
||||
},
|
||||
{
|
||||
"isAdminOnly": false,
|
||||
"isWafPolicyAppGw": true,
|
||||
"isExternal": true,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "QIB",
|
||||
"vmTypeDefault": "Standard_D8s_v3",
|
||||
"index": "vm1",
|
||||
"values": [
|
||||
{
|
||||
"name": "Qlik Sense Feb 2020 and QIB Feb 2020",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/images/qliksense-qib-base-feb20-1"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D8s_v3",
|
||||
"name": "azqmi-qs-qib",
|
||||
"title": "Qlik Insight Bot",
|
||||
"description": "Qlik Sense Enterprise on Windows with Qlik Insight Bot.<br><br>WebConnectors installed but not licensed.",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T09:27:15.596Z",
|
||||
"updated": "2020-05-10T15:23:45.891Z"
|
||||
},
|
||||
{
|
||||
"isAdminOnly": true,
|
||||
"isWafPolicyAppGw": true,
|
||||
"isExternal": true,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Windows VM",
|
||||
"vmTypeDefault": "Standard_D8s_v3",
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D8s_v3",
|
||||
"name": "azqmi-qs-np",
|
||||
"title": "Qlik Sense Enterprise and NPrinting",
|
||||
"description": "<b class=\"lui-text-danger\">DO NOT USE, DEV IN PROGRESS</b> One VM running <b>Qlik Sense Feb 2020</b> and <b>NPrinting Feb 2020 SR1</b>. Extenal access through AppGw.<br><br>WebConnectors installed but not licensed.",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T08:55:31.948Z",
|
||||
"updated": "2020-05-10T15:23:56.237Z"
|
||||
},
|
||||
{
|
||||
"isAdminOnly": false,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Ubuntu 18.04",
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"diskSizeGbDefault": 128,
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"name": "azqmi-ubuntu-docker",
|
||||
"title": "Ubuntu with Docker and Docker-Compose",
|
||||
"description": "This is Ubuntu 18.04 with Docker Engine and Docker-Compose installed.",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T08:55:31.948Z",
|
||||
"updated": "2020-05-10T15:24:19.588Z"
|
||||
},
|
||||
{
|
||||
"isAdminOnly": false,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Attunity Replicate/Compose DW",
|
||||
"vmTypeDefault": "Standard_D2s_v3",
|
||||
"index": "vm1",
|
||||
"values": []
|
||||
}
|
||||
],
|
||||
"vmTypeDefault": "Standard_D2s_v3",
|
||||
"name": "azqmi-di",
|
||||
"title": "Attunity Replicate/Compose DW",
|
||||
"description": "Windows Server 2016 with installed Attunity Replicate and Compose DW (v6.6.0).",
|
||||
"version": "1.0",
|
||||
"created": "2019-12-04T08:55:31.948Z",
|
||||
"updated": "2020-05-10T15:24:29.303Z"
|
||||
}
|
||||
]
|
||||
@@ -1,96 +0,0 @@
|
||||
[
|
||||
{
|
||||
"isAdminOnly": true,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Qlik Sense",
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"diskSizeGbDefault": "500",
|
||||
"index": "vm1",
|
||||
"values": [
|
||||
{
|
||||
"name": "Qlik Sense April 2020",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/galleries/QMICloud/images/QlikSenseEnterprise/values/13.72.3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"product": "QDC",
|
||||
"vmTypeDefault": "Standard_D4s_v3",
|
||||
"diskSizeGbDefault": "500",
|
||||
"index": "vm2",
|
||||
"values": [
|
||||
{
|
||||
"name": "QDC Single Server April 2020",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/galleries/QMICloud/images/QDC/values/4.5.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "azqmi-qdc-qs-secure",
|
||||
"title": "Qlik Data Catalyst and Qlik Sense (secure)",
|
||||
"description": "Creates a <b>QDC single server</b> and a <b>Qlik Sense Enterprise</b> in isolation and secure for Customer Data PoC's.<br><br>Configuration is all set to load QVDs located in C:/QVDs and \"Publish to Qlik\". Setup QDC Catalog in QS Data Manager <a target=\"blank\" href=\"https://confluence.qliktech.com/display/~AOR/QMI+Cloud+-+QDC+Catalogue+setup+in+Qlik+Sense\">here</a>. Troubleshoot 'Publish To Qlik\" <a target=\"blank\" href=\"https://confluence.qliktech.com/display/~AOR/Troubleshooting+Publish+To+Qlik+in+QMI+Cloud+QS-QDC+scenario\">here</a>.",
|
||||
"created": "2020-05-18T09:10:35.728Z",
|
||||
"updated": "2020-05-18T15:25:27.282Z",
|
||||
"__v": 0
|
||||
},
|
||||
{
|
||||
"isAdminOnly": true,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "QDC",
|
||||
"vmTypeDefault": "Standard_D8s_v3",
|
||||
"diskSizeGbDefault": 500,
|
||||
"index": "vm1",
|
||||
"values": [
|
||||
{
|
||||
"name": "QDC Single Server April 2020",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/galleries/QMICloud/images/QDC/values/4.5.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "azqmi-qdc-secure",
|
||||
"title": "Qlik Data Catalyst (secure)",
|
||||
"description": "Qlik Data Catalyst deployment in isolation and secure for Customer Data PoC's",
|
||||
"created": "2020-05-18T07:58:28.741Z",
|
||||
"updated": "2020-05-18T15:25:32.828Z",
|
||||
"__v": 0
|
||||
},
|
||||
{
|
||||
"isAdminOnly": true,
|
||||
"isWafPolicyAppGw": false,
|
||||
"isExternal": false,
|
||||
"isDisabled": false,
|
||||
"availableProductvalues": [
|
||||
{
|
||||
"product": "Qlik Sense",
|
||||
"vmTypeDefault": "Standard_D8s_v3",
|
||||
"diskSizeGbDefault": 250,
|
||||
"index": "vm1",
|
||||
"values": [
|
||||
{
|
||||
"name": "Qlik Sense February 2020",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/galleries/QMICloud/images/QlikSenseEnterprise/values/13.62.0"
|
||||
},
|
||||
{
|
||||
"name": "Qlik Sense April 2020",
|
||||
"image": "/subscriptions/62ebff8f-c40b-41be-9239-252d6c0c8ad9/resourceGroups/QMI-Machines/providers/Microsoft.Compute/galleries/QMICloud/images/QlikSenseEnterprise/values/13.72.3"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "azqmi-qs-secure",
|
||||
"title": "Qlik Sense Enterprise on Windows (secure)",
|
||||
"description": "Qlik Sense Enterprise deployment in isolation and secure for Customer Data PoC's",
|
||||
"created": "2020-05-13T11:55:55.785Z",
|
||||
"updated": "2020-05-18T15:25:38.158Z",
|
||||
"__v": 0
|
||||
}
|
||||
]
|
||||
@@ -1,10 +0,0 @@
|
||||
[
|
||||
{
|
||||
"subsId": "62ebff8f-c40b-41be-9239-252d6c0c8ad9",
|
||||
"description": "QMI Automation"
|
||||
},
|
||||
{
|
||||
"subsId": "73c75d40-8c7d-45cf-b4f9-afdb210da92d",
|
||||
"description": "Qlik-Secure"
|
||||
}
|
||||
]
|
||||
@@ -1,62 +0,0 @@
|
||||
[
|
||||
{
|
||||
"_id": "5e73a211710f74000640cbf2",
|
||||
"type": "Standard_B1ms",
|
||||
"desc": "1 CPUs - 2GiB RAM",
|
||||
"costHour": 0.0207
|
||||
},
|
||||
{
|
||||
"_id": "5e73a220710f74000640cbf4",
|
||||
"type": "Standard_B2s",
|
||||
"desc": "2 CPUs - 4GiB RAM",
|
||||
"costHour": 0.0416
|
||||
},
|
||||
{
|
||||
"_id": "5e73a22b710f74000640cbf6",
|
||||
"type": "Standard_D2s_v3",
|
||||
"desc": "2 CPUs - 8GiB RAM",
|
||||
"costHour": 0.096
|
||||
},
|
||||
{
|
||||
"_id": "5e73a240710f74000640cbfa",
|
||||
"type": "Standard_D4s_v3",
|
||||
"desc": "4 CPUs - 16GiB RAM",
|
||||
"costHour": 0.192
|
||||
},
|
||||
{
|
||||
"_id": "5e73a251710f74000640cbfe",
|
||||
"type": "Standard_D8s_v3",
|
||||
"desc": "8 CPUs - 32GiB RAM",
|
||||
"costHour": 0.384
|
||||
},
|
||||
{
|
||||
"_id": "5e73a262710f74000640cc02",
|
||||
"type": "Standard_D16s_v3",
|
||||
"desc": "16 CPUs - 64GiB RAM",
|
||||
"costHour": 0.768
|
||||
},
|
||||
{
|
||||
"_id": "5e92c98ce7b19100066153ab",
|
||||
"type": "Standard_D32s_v3",
|
||||
"desc": "32 CPUs - 128GiB RAM",
|
||||
"costHour": 1.536
|
||||
},
|
||||
{
|
||||
"_id": "5ea9016970653300063fbd17",
|
||||
"type": "Standard_E16s_v3",
|
||||
"desc": "16 CPUs - 128 GiB RAM - Mem. optimized",
|
||||
"costHour": 1.008
|
||||
},
|
||||
{
|
||||
"_id": "5ea901bd70653300063fbd19",
|
||||
"type": "Standard_E20s_v3",
|
||||
"desc": "20 CPUs - 160 GiB RAM - Mem. optimized",
|
||||
"costHour": 1.26
|
||||
},
|
||||
{
|
||||
"_id": "5ea901d670653300063fbd1b",
|
||||
"type": "Standard_E32s_v3",
|
||||
"desc": "32 CPUs - 256GiB RAM - Mem. optimized",
|
||||
"costHour": 2.016
|
||||
}
|
||||
]
|
||||
@@ -1,50 +0,0 @@
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
var initDataSubscriptions = require("../initdata/subscriptions.json");
|
||||
var scenarios1 = require("../initdata/scenariosQMI-Automation.json");
|
||||
var scenarios2 = require("../initdata/scenariosQlik-Secure.json");
|
||||
var vmTypes = require("../initdata/vmtypes.json");
|
||||
|
||||
|
||||
async function asyncForEach(array, callback) {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index, array);
|
||||
}
|
||||
}
|
||||
|
||||
async function init() {
|
||||
// Adding VmTypes
|
||||
await asyncForEach(vmTypes, async function(v){
|
||||
await db.vmtype.add(v);
|
||||
});
|
||||
|
||||
// Adding Subscriptions
|
||||
await asyncForEach(initDataSubscriptions, async function(s){
|
||||
await db.subscription.add(s);
|
||||
});
|
||||
|
||||
var subscription;
|
||||
//QMI Automation
|
||||
subscription = await db.subscription.getOne({"description": "QMI Automation"});
|
||||
await asyncForEach(scenarios1, async function(s){
|
||||
s.subscription = subscription._id;
|
||||
await db.scenario.add(s);
|
||||
});
|
||||
|
||||
//Qlik-Secure
|
||||
subscription = await db.subscription.getOne({"description": "Qlik-Secure"});
|
||||
await asyncForEach(scenarios2, async function(s){
|
||||
s.subscription = subscription._id;
|
||||
await db.scenario.add(s);
|
||||
});
|
||||
|
||||
console.log("Done!");
|
||||
process.exit(0);
|
||||
|
||||
}
|
||||
|
||||
init().catch(function(err){
|
||||
console.log(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
module.exports.init = init;
|
||||
@@ -1,239 +0,0 @@
|
||||
|
||||
var myArgs = process.argv.slice(2);
|
||||
|
||||
if ( myArgs.length < 2 ) {
|
||||
console.log("Missing args", myArgs);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const sendEmail = require("qmi-cloud-common/send-email");
|
||||
const moment = require('moment');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
|
||||
const IS_REAL = myArgs[1] !== 'test';
|
||||
const WARNING_DAYS = 2;
|
||||
|
||||
//---
|
||||
|
||||
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()
|
||||
};
|
||||
}
|
||||
|
||||
function timeFromCreated(p) {
|
||||
let totalTime = Math.abs(new Date().getTime() - new Date(p.created).getTime());
|
||||
let duration = moment.duration(totalTime);
|
||||
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 cb;
|
||||
var filter = {
|
||||
"isDestroyed":false,
|
||||
"isDeleted": false,
|
||||
"$or": [ {"runForever":{ "$exists": false }}, {"runForever": false}],
|
||||
"statusVms": "Stopped",
|
||||
"$and": [{"$or": [
|
||||
{ "options": {"$exists": true}, "options.vm1": { "$exists": true } },
|
||||
{ "vmImage": {"$exists": true}, "vmImage.vm1": { "$exists": true } },
|
||||
]}]
|
||||
};
|
||||
if ( type === "warning" ) {
|
||||
filter.pendingNextAction = {$ne: "destroy"};
|
||||
cb = doSendEmailDestroyWarning;
|
||||
} else if ( type === "exec" ) {
|
||||
filter.pendingNextAction = "destroy";
|
||||
cb = doDestroy;
|
||||
} else {
|
||||
console.log("Invalid 'type'. Do nothing.");
|
||||
return;
|
||||
}
|
||||
|
||||
let provisions = await db.provision.get(filter);
|
||||
|
||||
await asyncForEach(provisions.results, async function(p) {
|
||||
var typeSchedule = "24x7";
|
||||
if ( p.schedule && !p.schedule.is24x7 ) {
|
||||
typeSchedule = 'OnSchedule';
|
||||
}
|
||||
timeRunning(p);
|
||||
|
||||
let stoppedPeriod = p._scenarioDoc.allowedInnactiveDays || 20;
|
||||
let stoppedPeriodExternal = Math.ceil(stoppedPeriod/2);
|
||||
|
||||
var limit;
|
||||
if ( type === "warning" ) {
|
||||
limit = p.isExternalAccess? 24*(stoppedPeriodExternal-WARNING_DAYS) : 24*(stoppedPeriod-WARNING_DAYS);
|
||||
} else if ( type === "exec" ) {
|
||||
limit = p.isExternalAccess? (24*stoppedPeriodExternal) : (24*stoppedPeriod);
|
||||
}
|
||||
if ( !IS_REAL ) {
|
||||
console.log(`${p._id} (${typeSchedule}) - limit: ${limit} hs - actual duration: ${p.duration.hours} hs`);
|
||||
}
|
||||
if ( p.duration && p.duration.hours >= limit) {
|
||||
await cb(p, limit, typeSchedule);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function initOthers() {
|
||||
const WARN_DAYS = 82;
|
||||
const DEST_DAYS = 91;
|
||||
var dWarning = new Date();
|
||||
var dDestroy = new Date();
|
||||
dWarning.setDate(dWarning.getDate() - WARN_DAYS);
|
||||
dDestroy.setDate(dDestroy.getDate() - DEST_DAYS);
|
||||
|
||||
dWarning = dWarning.getTime();
|
||||
dDestroy = dDestroy.getTime();
|
||||
|
||||
var filter = {
|
||||
"isDestroyed":false,
|
||||
"isDeleted": false,
|
||||
"$or": [ {"runForever":{ "$exists": false }}, {"runForever": false}],
|
||||
"scenario": { "$in": ["awsqmi-s3bucket"] }
|
||||
};
|
||||
|
||||
|
||||
let provisions = await db.provision.get(filter);
|
||||
|
||||
await asyncForEach(provisions.results, async function(p) {
|
||||
var typeSchedule = "24x7";
|
||||
timeFromCreated(p);
|
||||
|
||||
let pCreatedAt = new Date(p.created);
|
||||
pCreatedAt = pCreatedAt.getTime();
|
||||
var limit;
|
||||
|
||||
if ( pCreatedAt <= dDestroy ) {
|
||||
//TODO Destroy
|
||||
limit = DEST_DAYS*24;
|
||||
await doDestroy(p, limit, "24x7");
|
||||
} else if ( pCreatedAt > dDestroy && pCreatedAt <= dWarning && !p.pendingNextAction) {
|
||||
//TODO Warning
|
||||
limit = WARN_DAYS*24;
|
||||
let msg = `Send warning DESTROY email - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenarioDoc.title}' (${p._id} - ${typeSchedule}) being 'Inactive' more than ${limit} hours, (exactly ${p.duration.complete})`;
|
||||
console.log(msg);
|
||||
if ( IS_REAL ) {
|
||||
db.event.add({ provision: p._id, type: 'vms.warning-destroy' });
|
||||
await db.provision.update(p._id, {"pendingNextAction": "destroy"});
|
||||
await db.notification.add({ provision: p._id.toString(), type: 'warningDestroy', message: msg });
|
||||
await sendEmail.sendWillDestroyInDays(p, p._scenarioDoc, WARN_DAYS, 10);
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const doSendEmailDestroyWarning = async function(p, limit, typeSchedule) {
|
||||
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._scenarioDoc.title}' (${p._id} - ${typeSchedule}) being 'Inactive' more than ${limit} hours, (exactly ${p.duration.complete})`;
|
||||
console.log(msg);
|
||||
if ( IS_REAL ) {
|
||||
db.event.add({ provision: p._id, type: 'vms.warning-destroy' });
|
||||
await db.provision.update(p._id, {"pendingNextAction": "destroy"});
|
||||
await db.notification.add({ provision: p._id.toString(), type: 'warningDestroy', message: msg });
|
||||
await sendEmail.sendWillDestroyIn24(p, p._scenarioDoc, Math.floor(limit/24), WARNING_DAYS);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const doDestroy = async function(p, limit, typeSchedule) {
|
||||
try {
|
||||
let msg = `Provision destroyed - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenarioDoc.title}' (${p._id} - ${typeSchedule}) being 'Inactive' more than ${limit} hours (exactly ${p.duration.complete})`
|
||||
console.log(msg);
|
||||
if ( IS_REAL ) {
|
||||
db.event.add({ provision: p._id, type: 'vms.exec-destroy' });
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
function checkOthers() {
|
||||
initOthers().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 'exec':
|
||||
check("exec");
|
||||
break;
|
||||
case 'others':
|
||||
checkOthers();
|
||||
break;
|
||||
default:
|
||||
console.log('Sorry, that is not something I know how to do.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
|
||||
var myArgs = process.argv.slice(2);
|
||||
|
||||
if ( myArgs.length < 1 ) {
|
||||
console.log("Missing args", myArgs);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const IS_REAL = myArgs[0] !== 'test';
|
||||
|
||||
|
||||
// ---
|
||||
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const sendEmail = require("qmi-cloud-common/send-email");
|
||||
|
||||
async function asyncForEach(array, callback) {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index, array);
|
||||
}
|
||||
}
|
||||
|
||||
const doSendEmailErrorProvision = async function(p) {
|
||||
let msg = `Send prrovision ERROR email - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenarioDoc.title}' (${p._id}) provisioned with 'Errors'`;
|
||||
console.log(msg);
|
||||
if ( IS_REAL ) {
|
||||
db.event.add({ provision: p._id, type: 'vms.warning-error' });
|
||||
await db.notification.add({ provision: p._id.toString(), type: 'warningError', message: msg });
|
||||
await sendEmail.sendProvisionError(p, p._scenarioDoc);
|
||||
}
|
||||
};
|
||||
|
||||
async function init() {
|
||||
let provisions = await db.provision.get({
|
||||
"isDestroyed":false,
|
||||
"isDeleted": false,
|
||||
"status": "error"
|
||||
});
|
||||
|
||||
await asyncForEach(provisions.results, async function(p) {
|
||||
await doSendEmailErrorProvision(p);
|
||||
});
|
||||
}
|
||||
|
||||
function check() {
|
||||
init().then(function(){
|
||||
db.mongoose.connection.close()
|
||||
process.exit(0);
|
||||
|
||||
}).catch(function(e){
|
||||
db.mongoose.connection.close()
|
||||
console.log("Error", e);
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------
|
||||
check();
|
||||
@@ -1,61 +0,0 @@
|
||||
|
||||
var myArgs = process.argv.slice(2);
|
||||
|
||||
if ( myArgs.length < 1 ) {
|
||||
console.log("Missing args", myArgs);
|
||||
process.exit(0);
|
||||
}
|
||||
console.log("myArgs", myArgs);
|
||||
const ISODATE = new Date(myArgs[0]).toISOString();
|
||||
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
async function asyncForEach(array, callback) {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index, array);
|
||||
}
|
||||
}
|
||||
|
||||
async function init() {
|
||||
let provisions = await db.provision.get({
|
||||
"isDestroyed":true,
|
||||
"isDeleted": false,
|
||||
"created": { "$lt" : ISODATE }
|
||||
});
|
||||
await asyncForEach(provisions.results, async function(p) {
|
||||
await doMoveDestroyed(p);
|
||||
});
|
||||
}
|
||||
|
||||
const doMoveDestroyed = async function(provision) {
|
||||
var scenarioFolder = `${provision.scenario}_${provision._id}`;
|
||||
console.log(`Moving scenario: /provisions/${scenarioFolder}`);
|
||||
if (fs.existsSync(`/provisions/${scenarioFolder}`)) {
|
||||
fs.moveSync(`/provisions/${scenarioFolder}`, `/provisions/deleted/${scenarioFolder}`, { overwrite: true })
|
||||
console.log(`OK.`);
|
||||
} else {
|
||||
console.log(`NOK: It does not exist.`);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function check() {
|
||||
init().then(function(){
|
||||
db.mongoose.connection.close()
|
||||
process.exit(0);
|
||||
|
||||
}).catch(function(e){
|
||||
db.mongoose.connection.close()
|
||||
console.log("Error", e);
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------
|
||||
check();
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
|
||||
var myArgs = process.argv.slice(2);
|
||||
|
||||
if ( myArgs.length < 2 ) {
|
||||
console.log("Missing args", myArgs);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const IS_REAL = myArgs[1] !== 'test';
|
||||
const WARNING_DAYS = 1;
|
||||
|
||||
// ---
|
||||
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const sendEmail = require("qmi-cloud-common/send-email");
|
||||
const moment = require('moment');
|
||||
const cli = require('qmi-cloud-common/cli');
|
||||
|
||||
function timeRunningIs24x7(p) {
|
||||
let runningFromTime = p.runningFrom? new Date(p.runningFrom).getTime() : new Date(p.created).getTime();
|
||||
let 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()
|
||||
};
|
||||
}
|
||||
|
||||
function timeRunningOnSchedule(p) {
|
||||
let runningFromTime = p.runningFrom? new Date(p.runningFrom).getTime() : new Date(p.created).getTime();
|
||||
let totalRunningTime = p.timeRunning*1000*60;
|
||||
let now = new Date();
|
||||
totalRunningTime = totalRunningTime + Math.abs(now.getTime() - runningFromTime);
|
||||
let duration = moment.duration(totalRunningTime);
|
||||
p.duration = {
|
||||
hours: Math.floor(duration.asHours()),
|
||||
complete: Math.floor(duration.asDays()) +"d "+duration.hours()+"h "+duration.minutes()
|
||||
};
|
||||
}
|
||||
|
||||
function timeRunningOnSchedule2(p) {
|
||||
|
||||
let startTimestamp = p.startDateOnSchedule? new Date(p.startDateOnSchedule).getTime() : 0;
|
||||
let endTimestamp = p.endDateOnSchedule? new Date(p.endDateOnSchedule).getTime() : 0;
|
||||
let totalTimeOnschedule = Math.abs(endTimestamp - startTimestamp);
|
||||
let duration = moment.duration(totalTimeOnschedule);
|
||||
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 cb;
|
||||
var filter = {
|
||||
"isDestroyed": false,
|
||||
"isDeleted": false,
|
||||
"$or": [ {"runForever":{ "$exists": false }}, {"runForever": false}],
|
||||
"statusVms": "Running",
|
||||
"$and": [{"$or": [
|
||||
{ "options": {"$exists": true}, "options.vm1": { "$exists": true } },
|
||||
{ "vmImage": {"$exists": true}, "vmImage.vm1": { "$exists": true } },
|
||||
]}]
|
||||
};
|
||||
|
||||
if ( type === "warning" ) {
|
||||
filter.pendingNextAction = { $ne: "stopVms" };
|
||||
cb = doSendEmailWarning;
|
||||
} else if ( type === "exec" ) {
|
||||
filter.pendingNextAction = "stopVms";
|
||||
cb = doStop;
|
||||
} else {
|
||||
console.log("Invalid 'type'. Do nothing.");
|
||||
return;
|
||||
}
|
||||
|
||||
let provisions = await db.provision.get(filter);
|
||||
|
||||
await asyncForEach(provisions.results, async function(p) {
|
||||
//Only if 24x7
|
||||
let typeSchedule = "24x7";
|
||||
let periodDays = p._scenarioDoc.allowed24x7RunningDays;
|
||||
if ( !p.schedule || p.schedule.is24x7 ) {
|
||||
// 24x7
|
||||
timeRunningIs24x7(p);
|
||||
periodDays = p._scenarioDoc.allowed24x7RunningDays;
|
||||
} else if ( p.schedule && !p.schedule.is24x7 ) {
|
||||
// OnSchedule
|
||||
timeRunningOnSchedule2(p);
|
||||
typeSchedule = 'OnSchedule';
|
||||
periodDays = p._scenarioDoc.allowedOnScheduleRunningDays;
|
||||
}
|
||||
let limit;
|
||||
if ( type === "warning" ) {
|
||||
limit = 24*(periodDays-WARNING_DAYS);
|
||||
} else if ( type === "exec" ) {
|
||||
limit = 24*periodDays;
|
||||
}
|
||||
if (!IS_REAL) {
|
||||
console.log(`${p._id} - (${typeSchedule}) - limit: ${limit} hs - actual duration: ${p.duration.hours} hs`);
|
||||
}
|
||||
if ( p.duration && p.duration.hours >= limit) {
|
||||
await cb(p, limit, typeSchedule);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const doSendEmailWarning = async function(p, limit, typeSchedule) {
|
||||
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._scenarioDoc.title}' (${p._id} - ${typeSchedule}) being 'Running' more than ${limit} hours, (exactly ${p.duration.complete})`;
|
||||
console.log(msg);
|
||||
if ( IS_REAL ) {
|
||||
db.event.add({ provision: p._id, type: 'vms.warning-stop' });
|
||||
await db.provision.update(p._id, {"pendingNextAction": "stopVms"});
|
||||
await db.notification.add({ provision: p._id.toString(), type: 'warningStop', message: msg });
|
||||
await sendEmail.sendWillStopIn24(p, p._scenarioDoc, Math.floor(limit/24), WARNING_DAYS);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const doStop = async function(p, limit, typeSchedule) {
|
||||
try {
|
||||
let msg = `VMs stopped - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenarioDoc.title}' (${p._id} - ${typeSchedule}) being 'Running' more than ${limit} hours, (exactly ${p.duration.complete})`
|
||||
console.log(msg);
|
||||
|
||||
if ( IS_REAL ) {
|
||||
if (p.schedule){
|
||||
//Disable Divvy
|
||||
await db.schedule.update(p.schedule._id, {"isStartupTimeEnable": false});
|
||||
await cli.updateVmsTags(p._id, {
|
||||
"24x7": false,
|
||||
"StartupTime": false,
|
||||
"ShutdownTime": false
|
||||
});
|
||||
}
|
||||
//Stop VMs indefinitely
|
||||
db.event.add({ provision: p._id, type: 'vms.exec-stop' });
|
||||
await cli.deallocate(p._id, null, 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 'exec':
|
||||
check("exec");
|
||||
break;
|
||||
default:
|
||||
console.log('Sorry, that is not something I know how to do.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
|
||||
/*var scenarios = ['azqmi-qs-sn', 'azqmi-qdc-qs', 'azqmi-qdc-ss', 'azqmi-qs-qib'];
|
||||
db.models.Provision.updateMany({"scenario": { $in: scenarios}}, {"isExternalAccess": true}, function(err, res){
|
||||
if (err) {
|
||||
console.log("error", err);
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log("Good", res);
|
||||
process.exit(0);
|
||||
}
|
||||
});*/
|
||||
|
||||
/*var promise = db.models.Subscription.create({
|
||||
subsId: "62ebff8f-c40b-41be-9239-252d6c0c8ad9"
|
||||
});
|
||||
promise.then(function (subs) {
|
||||
|
||||
console.log("Good", subs);
|
||||
process.exit(0);
|
||||
|
||||
}).catch(function(err){
|
||||
console.log("error", err);
|
||||
process.exit(1);
|
||||
})*/
|
||||
|
||||
async function getScenario(){
|
||||
var res = await db.scenario.get();
|
||||
console.log("res", res.results);
|
||||
}
|
||||
|
||||
|
||||
/*db.models.Scenario.updateMany({"name": { $exists: true}}, {"subscription": "5ec23bd0999e8a00193725b8"}, function(err, res){
|
||||
if (err) {
|
||||
console.log("error", err);
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log("Good", res);
|
||||
process.exit(0);
|
||||
}
|
||||
});*/
|
||||
|
||||
//getScenario();
|
||||
|
||||
async function asyncForEach(array, callback) {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index, array);
|
||||
}
|
||||
}
|
||||
|
||||
async function getProvisions(filter){
|
||||
return db.provision.get(filter);
|
||||
}
|
||||
|
||||
|
||||
/*getProvisions().then(async function(res){
|
||||
console.log(res.results.length);
|
||||
await asyncForEach(res.results, async function(prov){
|
||||
if ( prov.vmType ) {
|
||||
//console.log("vmType", prov.vmType, prov.options)
|
||||
prov["options"] = {
|
||||
"vm1": {
|
||||
"vmType": prov.vmType,
|
||||
"diskSizeGb": 128
|
||||
}
|
||||
}
|
||||
prov.vmType = null;
|
||||
await prov.save();
|
||||
}
|
||||
});
|
||||
process.exit(0);
|
||||
});*/
|
||||
|
||||
/*db.models.Provision.updateMany({"nodeCount": { $exists: true}}, { $unset: { nodeCount: "" } }, function(err, res){
|
||||
if (err) {
|
||||
console.log("error", err);
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log("Good", res);
|
||||
process.exit(0);
|
||||
}
|
||||
});*/
|
||||
|
||||
/*db.models.Scenario.updateMany({"nodeCount": { $exists: true}}, { $unset: { nodeCount: "" } }, function(err, res){
|
||||
if (err) {
|
||||
console.log("error", err);
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log("Good", res);
|
||||
process.exit(0);
|
||||
}
|
||||
});*/
|
||||
|
||||
/*db.models.Provision.updateMany({}, { "scenarioVersion": "1.0" }, function(err, res){
|
||||
if (err) {
|
||||
console.log("error", err);
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log("Good", res);
|
||||
process.exit(0);
|
||||
}
|
||||
});*/
|
||||
|
||||
/*getProvisions({
|
||||
"isDestroyed": true,
|
||||
"statusVms": "Stopped"
|
||||
}).then(async function(res){
|
||||
console.log(res.results.length);
|
||||
await asyncForEach(res.results, async function(prov){
|
||||
//if ( prov.destroy ) {
|
||||
var runningFrom = new Date(prov.runningFrom).getTime();
|
||||
var updated;
|
||||
if ( prov.destroy ) {
|
||||
updated = new Date(prov.destroy.updated).getTime();
|
||||
} else {
|
||||
updated = new Date(prov.updated).getTime();
|
||||
}
|
||||
var mins = Math.floor( (updated-runningFrom)/1000/60);
|
||||
if ( !isNaN(mins) ) {
|
||||
var newTimeRunning = (prov.timeRunning-mins);
|
||||
|
||||
if ( newTimeRunning > 0 ) {
|
||||
console.log(prov._id, "timeRunning="+prov.timeRunning, " offset="+mins, " timeRunningNew="+newTimeRunning, prov.destroy? "OK" : "BUUUH");
|
||||
|
||||
prov.timeRunning = newTimeRunning;
|
||||
await prov.save();
|
||||
console.log("saved!");
|
||||
}
|
||||
}
|
||||
//}
|
||||
});
|
||||
process.exit(0);
|
||||
})*/
|
||||
|
||||
|
||||
/*getProvisions({
|
||||
"isDestroyed": true
|
||||
}).then(async function(res){
|
||||
console.log(res.results.length);
|
||||
var count = 0;
|
||||
await asyncForEach(res.results, async function(prov){
|
||||
//if ( prov.destroy ) {
|
||||
var actualDestroyDate;
|
||||
if ( prov.destroy ) {
|
||||
actualDestroyDate = prov.destroy.updated;
|
||||
prov.actualDestroyDate = actualDestroyDate;
|
||||
await prov.save();
|
||||
count = count + 1;
|
||||
console.log("saved!", count);
|
||||
}
|
||||
|
||||
//}
|
||||
});
|
||||
process.exit(0);
|
||||
})*/
|
||||
|
||||
getProvisions({
|
||||
"isDestroyed": true, "actualDestroyDate": {"$exists":false}, "isDeleted": true
|
||||
}).then(async function(res){
|
||||
console.log(res.total, res.count);
|
||||
var count = 0;
|
||||
await asyncForEach(res.results, async function(prov){
|
||||
prov.actualDestroyDate = prov.updated;
|
||||
await prov.save();
|
||||
count = count + 1;
|
||||
console.log("saved!", count);
|
||||
});
|
||||
process.exit(0);
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "qmi-cloud-cli",
|
||||
"version": "2.0.6",
|
||||
"scripts": {
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"qmi-cloud-common": "../qmi-cloud-common",
|
||||
"node-fetch": "^2.6.0",
|
||||
"moment": "^2.24.0",
|
||||
"axios": "^0.21.1",
|
||||
"fs-extra": "^8.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
|
||||
BASEDIR=$(dirname "$0")
|
||||
|
||||
helpFunction()
|
||||
{
|
||||
echo ""
|
||||
echo "Usage: $0 -s script"
|
||||
echo -e "\t-s Type of script ( checkstop | checkdestroy | checkerror | movedestroyed | initdb )"
|
||||
exit 1 # Exit script after printing help
|
||||
}
|
||||
|
||||
helpFunctionCheck()
|
||||
{
|
||||
echo ""
|
||||
echo "Usage: $0 -s script [-t type -r realortest]"
|
||||
echo -e "\t-s Type of script ( checkstop | checkdestroy | checkerror )"
|
||||
echo -e "\t-t Type of script ( warning | exec )"
|
||||
echo -e "\t-r Indicate whether is for test or real execution ( test | real )"
|
||||
exit 1 # Exit script after printing help
|
||||
}
|
||||
|
||||
helpFunctionCheck2()
|
||||
{
|
||||
echo ""
|
||||
echo "Usage: $0 -s checkerror [-r realortest]"
|
||||
echo -e "\t-r Indicate whether is for test or real execution ( test | real )"
|
||||
exit 1 # Exit script after printing help
|
||||
}
|
||||
|
||||
helpFunctionCheck3()
|
||||
{
|
||||
echo ""
|
||||
echo "Usage: $0 -s movedestroyed [-r isodate]"
|
||||
echo -e "\t-r An ISODATE (ie: '2020-31-12T00:00:00.000Z') to movedestroyed backwards"
|
||||
exit 1 # Exit script after printing help
|
||||
}
|
||||
|
||||
while getopts "s:t:p:r:" opt
|
||||
do
|
||||
case "$opt" in
|
||||
s ) script="$OPTARG" ;;
|
||||
t ) type="$OPTARG" ;;
|
||||
r ) realortest="$OPTARG" ;;
|
||||
? ) helpFunction ;; # Print helpFunction in case parameter is non-existent
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$script" ]
|
||||
then
|
||||
echo "Script not recognised";
|
||||
helpFunction
|
||||
fi
|
||||
|
||||
if [ "$script" = "checkstop" ] || [ "$script" = "checkdestroy" ]
|
||||
then
|
||||
if [ -z "$type" ] || [ -z "$realortest" ]
|
||||
then
|
||||
echo "Some or all of the parameters are empty";
|
||||
helpFunctionCheck
|
||||
else
|
||||
if [ "$script" = "checkstop" ]
|
||||
then
|
||||
$BASEDIR/checkstop.sh $type $realortest
|
||||
fi
|
||||
|
||||
if [ "$script" = "checkdestroy" ]
|
||||
then
|
||||
$BASEDIR/checkdestroy.sh $type $realortest
|
||||
fi
|
||||
fi
|
||||
elif [ "$script" = "initdb" ]
|
||||
then
|
||||
if [ -z "$MONGO_URI" ]
|
||||
then
|
||||
echo "\$MONGO_URI is empty"
|
||||
exit
|
||||
else
|
||||
echo "\$MONGO_URI=$MONGO_URI"
|
||||
node $BASEDIR/../jobs/db-init.js
|
||||
fi
|
||||
elif [ "$script" = "checkerror" ]
|
||||
then
|
||||
if [ -z "$realortest" ]
|
||||
then
|
||||
echo "Some or all of the parameters are empty";
|
||||
helpFunctionCheck2
|
||||
else
|
||||
node $BASEDIR/../jobs/error5.js $realortest
|
||||
fi
|
||||
elif [ "$script" = "movedestroyed" ]
|
||||
then
|
||||
if [ -z "$realortest" ]
|
||||
then
|
||||
echo "Some or all of the parameters are empty";
|
||||
helpFunctionCheck3
|
||||
else
|
||||
node $BASEDIR/../jobs/move_destroyed.js $realortest
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
BASEDIR=$(dirname "$0")
|
||||
d=`date`
|
||||
echo "------ $d"
|
||||
echo "------ SCRIPT: $0"
|
||||
echo "------ TYPE: $1"
|
||||
echo "------ TEST/REAL: $2"
|
||||
|
||||
if [ -z "$MONGO_URI" ]
|
||||
then
|
||||
echo "\$MONGO_URI is empty"
|
||||
exit
|
||||
else
|
||||
echo "\$MONGO_URI=$MONGO_URI"
|
||||
fi
|
||||
|
||||
if [ -z "$API_KEY" ]
|
||||
then
|
||||
echo "\$API_KEY is empty"
|
||||
exit
|
||||
else
|
||||
echo "\$API_KEY=$API_KEY"
|
||||
fi
|
||||
|
||||
node $BASEDIR/../jobs/destroy5.js $1 $2
|
||||
@@ -1,14 +0,0 @@
|
||||
BASEDIR=$(dirname "$0")
|
||||
d=`date`
|
||||
echo "------ $d"
|
||||
echo "------ SCRIPT: $0"
|
||||
|
||||
if [ -z "$MONGO_URI" ]
|
||||
then
|
||||
echo "\$MONGO_URI is empty"
|
||||
exit
|
||||
else
|
||||
echo "\$MONGO_URI=$MONGO_URI"
|
||||
fi
|
||||
|
||||
node $BASEDIR/../jobs/error5.js $1
|
||||
@@ -1,24 +0,0 @@
|
||||
BASEDIR=$(dirname "$0")
|
||||
d=`date`
|
||||
echo "------ $d"
|
||||
echo "------ SCRIPT: $0"
|
||||
echo "------ TYPE: $1"
|
||||
echo "------ TEST/REAL: $2"
|
||||
|
||||
if [ -z "$MONGO_URI" ]
|
||||
then
|
||||
echo "\$MONGO_URI is empty"
|
||||
exit
|
||||
else
|
||||
echo "\$MONGO_URI=$MONGO_URI"
|
||||
fi
|
||||
|
||||
if [ -z "$API_KEY" ]
|
||||
then
|
||||
echo "\$API_KEY is empty"
|
||||
exit
|
||||
else
|
||||
echo "\$API_KEY=$API_KEY"
|
||||
fi
|
||||
|
||||
node $BASEDIR/../jobs/stop5.js $1 $2
|
||||
@@ -1,24 +0,0 @@
|
||||
# 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
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
id=`docker ps | grep 'mongo:4.2' | awk '{ print $1 }'`
|
||||
d=$(date +%Y-%m-%d-T%H:%M:%S%z)
|
||||
|
||||
docker exec $id sh -c 'exec mongodump --uri="mongodb://root:example@mongo/qmicloud?authSource=admin" --archive' > $1/qmicloud-$d.archive
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,20 @@
|
||||
{
|
||||
"name": "qmi-cloud-common",
|
||||
"version": "2.0.0",
|
||||
"name": "@QMI/qmi-cloud-common",
|
||||
"version": "2.0.3",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-ec2": "^3.590.0",
|
||||
"@aws-sdk/client-rds": "^3.590.0",
|
||||
"@azure/arm-compute": "^22.3.0",
|
||||
"@azure/identity": "^1.5.1",
|
||||
"@azure/arm-dns": "^5.1.0",
|
||||
"@azure/identity": "^1.5.1",
|
||||
"@hapi/boom": "^9.1.0",
|
||||
"axios": "^1.7.2",
|
||||
"barracuda-api": "https://gitlab.com/qlik_gear/barracuda-api-node.git#1.1.0",
|
||||
"bull": "^3.11.0",
|
||||
"mongoose": "^8.4.1",
|
||||
"nodemailer": "^6.4.2",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"publishConfig":{
|
||||
"registry": "https://gitlab.com/api/v4/projects/15526459/packages/npm/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
# Stage 1:
|
||||
FROM node:20.14-alpine AS sources
|
||||
|
||||
RUN apk --no-cache add yarn git
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ADD ./qmi-cloud-webhook ./
|
||||
ADD ./qmi-cloud-common ../qmi-cloud-common
|
||||
|
||||
RUN yarn install --production
|
||||
|
||||
# Stage 2:
|
||||
FROM node:20.14-alpine AS production
|
||||
WORKDIR /app
|
||||
COPY --from=sources /app ./
|
||||
COPY ./config ./config
|
||||
|
||||
EXPOSE 5050
|
||||
|
||||
CMD ["node", "index.js"]
|
||||
@@ -1,96 +0,0 @@
|
||||
'use strict'
|
||||
/* dependencies */
|
||||
const express = require('express');
|
||||
const NodeCache = require( "node-cache" );
|
||||
const TRIGGER_STATUS = process.env.TRIGGER_STATUS || "Stopped";
|
||||
const LOGEVENT_NAME = process.env.LOGEVENT_NAME || "AzureWebhook";
|
||||
const SERVICE_NAME = process.env.SERVICE_NAME || "QMI-AzureAlert";
|
||||
const DIVVYCLOUDAPP_CALLER = process.env.DIVVYCLOUDAPP_CALLER || "b5b96c8e-ab9a-4ce0-900c-3cc3d0176cd7";
|
||||
|
||||
const divvy = require('qmi-cloud-common/divvy');
|
||||
|
||||
// Create an Express application.
|
||||
const app = express();
|
||||
|
||||
const myCache = new NodeCache( { stdTTL: 180 } ); //5 minutes cache
|
||||
|
||||
// Add body parser.
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
|
||||
|
||||
// Add routers
|
||||
app.post('/', divvy.isApiKeyAuthenticated, (req, res) => {
|
||||
|
||||
var now = new Date();
|
||||
now = now.toISOString();
|
||||
|
||||
const azureEvent = req.body;
|
||||
|
||||
if ( azureEvent.data && azureEvent.data.context && azureEvent.data.context.activityLog ) {
|
||||
|
||||
const rgName = azureEvent.data.context.activityLog.resourceGroupName;
|
||||
const resourceId = azureEvent.data.context.activityLog.resourceId;
|
||||
//console.log("activityLog", event.data.context.activityLog);
|
||||
|
||||
const provId = rgName.split("-")[rgName.split("-").length-1];
|
||||
|
||||
if ( provId && !myCache.get( provId ) ) {
|
||||
|
||||
|
||||
const caller = azureEvent.data.context.activityLog.caller;
|
||||
|
||||
var logEvent = LOGEVENT_NAME;
|
||||
if ( caller === DIVVYCLOUDAPP_CALLER ) {
|
||||
logEvent = "DivvyCloudApp";
|
||||
}
|
||||
|
||||
const vmName = resourceId.split("/")[resourceId.split("/").length-1];
|
||||
const event = {
|
||||
"provID": provId,
|
||||
"rgName": rgName,
|
||||
"cloudName": SERVICE_NAME,
|
||||
"instanceState": TRIGGER_STATUS,
|
||||
"logEvent": logEvent,
|
||||
"vmName": vmName
|
||||
};
|
||||
|
||||
myCache.set(provId, event);
|
||||
divvy.onEvent(event, req.user);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
res.json(req.body);
|
||||
})
|
||||
|
||||
app.post('/divvy', divvy.isApiKeyAuthenticated, (req, res) => {
|
||||
|
||||
var now = new Date();
|
||||
now = now.toISOString();
|
||||
|
||||
const provId = req.body.provID? req.body.provID : null;
|
||||
|
||||
if ( provId && !myCache.get( provId ) ) {
|
||||
myCache.set(provId, req.body);
|
||||
divvy.onEvent(req.body, req.user);
|
||||
}
|
||||
|
||||
res.json(req.body);
|
||||
})
|
||||
|
||||
app.post('/test', (req, res) => {
|
||||
console.log("Calling /test POST endpoint");
|
||||
res.send("OK");
|
||||
});
|
||||
|
||||
app.use((req, res, next) => res.send("404"))
|
||||
app.use((err, req, res, next) => {
|
||||
console.error(err)
|
||||
if (res.headerSent) return next(err)
|
||||
return res.send("500")
|
||||
})
|
||||
|
||||
|
||||
module.exports = app;
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
let port = process.env.PORT || 5050;
|
||||
|
||||
const app = require('./app');
|
||||
|
||||
// Start listening for requests.
|
||||
app.listen(port, ()=>{
|
||||
console.log("Server is running on port ", port);
|
||||
});
|
||||
|
||||
process.on('uncaughtException', err => console.error('uncaught exception:', err.toString()));
|
||||
process.on('unhandledRejection', error => console.error('unhandled rejection:', error.toString()));
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"name": "qmi-cloud-webhook",
|
||||
"version": "1.0.0",
|
||||
"description": "qmi-cloud-webhook",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node ./index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.19.2",
|
||||
"node-cache": "^5.1.2",
|
||||
"qmi-cloud-common": "../qmi-cloud-common"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,21 +0,0 @@
|
||||
# Stage 1: NOTE: context is actually ../
|
||||
FROM node:20.14-alpine AS sources
|
||||
|
||||
RUN apk --no-cache add yarn git
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ADD ./qmi-cloud-worker ./
|
||||
ADD ./qmi-cloud-common ../qmi-cloud-common
|
||||
|
||||
|
||||
RUN yarn install --production
|
||||
|
||||
# Stage 2:
|
||||
FROM node:20.14-alpine AS production
|
||||
WORKDIR /app
|
||||
COPY --from=sources /app ./
|
||||
COPY ./config ./config
|
||||
|
||||
|
||||
CMD ["node", "index.js"]
|
||||
@@ -1,153 +0,0 @@
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const path = require('path');
|
||||
const PROJECT_PATH = process.env.PROJECT_PATH;
|
||||
const tf = require("./docker/tf");
|
||||
const azure = require("./docker/azure");
|
||||
const sendEmail = require("qmi-cloud-common/send-email");
|
||||
const guaca = require("./guacamole");
|
||||
const MYQUEUES = require('qmi-cloud-common/queues');
|
||||
const queues = MYQUEUES.queues;
|
||||
const WEBHOOK_QUEUE = MYQUEUES.WEBHOOK_QUEUE;
|
||||
|
||||
module.exports = async function(job) {
|
||||
|
||||
const triggerUser = job.data.user;
|
||||
|
||||
var prov = await db.provision.update(job.data.id, {
|
||||
"status": "initializing",
|
||||
"jobId": job.id,
|
||||
"logFile": path.join('/logs', 'provision', `${job.data.id}.log`),
|
||||
"path": path.join(PROJECT_PATH, '..', 'qmi-cloud-provisions', `${job.data.scenario}_${job.data.id}`)
|
||||
});
|
||||
|
||||
if ( !prov ) {
|
||||
console.log(`ProcessorApply# Error: Not found Provision object in Database (it should exist!), provisionId is: ${job.data.id}` );
|
||||
return Promise.reject({"success": false, "err": "Not found Provision object in Worker"});
|
||||
}
|
||||
|
||||
var idProv = prov._id.toString();
|
||||
|
||||
db.event.add({ user: triggerUser._id, provision: prov._id, type: 'provision.init' });
|
||||
|
||||
// TERRAFORM INIT
|
||||
return tf.init(prov)
|
||||
.then(async function(res) {
|
||||
if ( res.statusCode === 1 ) {
|
||||
console.log(`ProcessorApply# Error at Terraform INIT for provision (${idProv})`);
|
||||
return Promise.reject({"success": false, "error": "Error at Terraform Init", provStatus: "error_init"});
|
||||
} else {
|
||||
// TERRAFORM PLAN
|
||||
return tf.plan(prov);
|
||||
}
|
||||
} )
|
||||
.then( async function(res) {
|
||||
if ( res.statusCode === 1 ) {
|
||||
console.log(`ProcessorApply# Error at Terraform PLAN for provision (${idProv}) `);
|
||||
return Promise.reject({"success": false, "error": "Error at Terraform Plan", provStatus: "error_plan"});
|
||||
} else {
|
||||
const dateNow = new Date();
|
||||
let patch = {
|
||||
"status": "provisioning",
|
||||
"statusVms": (prov.scenario === 'azqmi-synapse' || prov.scenario === 'awsqmi-rds' || prov.options && prov.options.vm1)? "Running" : "N/A",
|
||||
"runningFrom": dateNow,
|
||||
"runningTime": 0,
|
||||
"countExtend": 0
|
||||
};
|
||||
if ( prov.schedule && !prov.schedule.is24x7 ) {
|
||||
patch["startDateOnSchedule"] = dateNow;
|
||||
patch["endDateOnSchedule"] = dateNow;
|
||||
}
|
||||
return await db.provision.update(prov._id, patch);
|
||||
}
|
||||
} ).then( function(prov) {
|
||||
// TERRAFORM APPLY
|
||||
return tf.apply(prov);
|
||||
} ).then( async function(res) {
|
||||
// Save Provision status
|
||||
if ( res.statusCode === 1 ) {
|
||||
console.log(`ProcessorApply# Error at Terraform APPLY for provision (${idProv})`);
|
||||
} else if ( res.statusCode === 137 ){
|
||||
console.log(`ProcessorApply# Apply container must have been killed!`);
|
||||
return Promise.reject({"success": false, "error": "Apply container must have been killed", provStatus: "aborted"});
|
||||
}
|
||||
|
||||
var status = ( res.output.indexOf("Error:") !== -1 )? "error" : "provisioned";
|
||||
return await db.provision.update(prov._id, {"status": status});
|
||||
|
||||
} ).then( async function(prov) {
|
||||
// Generate Terraform OUTPUTS and store in provision object
|
||||
return tf.outputs(prov).then( async function(outputs){
|
||||
//if ( outputs.barracudaAzureFqdn ) {
|
||||
// let fqdn = outputs.barracudaAzureFqdn;
|
||||
// delete outputs['barracudaAzureFqdn'];
|
||||
// return await db.provision.update(prov._id, {"barracudaAzureFqdn": fqdn, "outputs": outputs});
|
||||
//} else {
|
||||
return await db.provision.update(prov._id, {"outputs": outputs});
|
||||
//}
|
||||
});
|
||||
|
||||
} )
|
||||
//.then( async function(prov) {
|
||||
// if ( prov.isExternalAccess && prov.barracudaAzureFqdn ) {
|
||||
// console.log(`ProcessorApply# Calling Barracuda service to create App and DNS CName for provision (${prov._id})`);
|
||||
// barracuda.createApp(prov);
|
||||
// }
|
||||
// return prov;
|
||||
//} )
|
||||
.then( async function(prov) {
|
||||
// Application Gateway assign policy
|
||||
return azure.appgateway(prov, job.data._scenario);
|
||||
} ).then( async function(prov) {
|
||||
// Create Image
|
||||
return azure.createimage(prov, job.data._scenario);
|
||||
} ).then( async function(prov) {
|
||||
// Guacamole Web access
|
||||
return await guaca.setUserConnection(prov, job.data._scenario);
|
||||
|
||||
} ).then( function(prov) {
|
||||
if (prov.status === "provisioned") {
|
||||
db.event.add({ provision: prov._id, type: 'provision.finished' });
|
||||
sendEmail.sendProvisionSuccess(prov, job.data._scenario);
|
||||
|
||||
queues[WEBHOOK_QUEUE].add("webhook_job", {
|
||||
provId: prov._id,
|
||||
scenario: prov.scenario,
|
||||
user: triggerUser._id,
|
||||
eventType: 'provision.finished'
|
||||
});
|
||||
|
||||
} else {
|
||||
db.event.add({ provision: prov._id, type: 'provision.error' });
|
||||
sendEmail.sendProvisionError(prov, job.data._scenario);
|
||||
|
||||
queues[WEBHOOK_QUEUE].add("webhook_job", {
|
||||
provId: prov._id,
|
||||
scenario: prov.scenario,
|
||||
user: triggerUser._id,
|
||||
eventType: 'provision.error'
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return Promise.resolve({"success": true, provMongo: prov});
|
||||
} ).catch( function(err) {
|
||||
console.log("ProcessorApply# Provision: error", err);
|
||||
|
||||
var errormsg = err.provStatus? err.provStatus : 'error'
|
||||
db.provision.update(prov._id, {"status": errormsg});
|
||||
db.event.add({ user: triggerUser._id, provision: prov._id, type: 'provision.'+errormsg });
|
||||
|
||||
if ( errormsg !== "aborted") {
|
||||
sendEmail.sendProvisionError(prov, job.data._scenario);
|
||||
}
|
||||
|
||||
queues[WEBHOOK_QUEUE].add("webhook_job", {
|
||||
provId: prov._id,
|
||||
scenario: prov.scenario,
|
||||
user: triggerUser._id,
|
||||
eventType: 'provision.'+errormsg
|
||||
});
|
||||
|
||||
return Promise.reject({"success": false, "error": err});
|
||||
} );
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
const Docker = require('dockerode');
|
||||
const docker = new Docker({
|
||||
'socketPath': '/home/docker.sock'
|
||||
//'socketPath': '/var/run/docker.sock'
|
||||
});
|
||||
const fs = require("fs");
|
||||
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 ) {
|
||||
|
||||
if ( provision.status === 'provisioned' && scenario.isWafPolicyAppGw && provision.isExternalAccess ) {
|
||||
var provision_id = provision._id.toString();
|
||||
var processStream = fs.createWriteStream(provision.logFile, {flags:'a'});
|
||||
var name = 'qmi-azureps-appgw-'+provision_id;
|
||||
console.log(`AzurePS# will spin up container: ${name}`);
|
||||
|
||||
return docker.run(DOCKERIMAGE, ['pwsh', 'appgw.ps1', "-ProvisionId", provision_id, "-Subscription", provision.deployOpts.subsId, "-PolicyName", provision.deployOpts.wafPolicyName , "-PolicyResourceGroup", provision.deployOpts.wafPolicyRgName ], processStream, {
|
||||
"name": name,
|
||||
"WorkingDir": "/myapp",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${provision.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(provision);
|
||||
});
|
||||
|
||||
} else {
|
||||
return Promise.resolve(provision);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const createimage = function( provision, scenario ) {
|
||||
|
||||
if ( provision.status === 'provisioned' && scenario.newImageName ) {
|
||||
var provision_id = provision._id.toString();
|
||||
var processStream = fs.createWriteStream(provision.logFile, {flags:'a'});
|
||||
var name = 'qmi-azureps-createimage-'+provision_id;
|
||||
|
||||
let rgName = provision.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": [
|
||||
`${provision.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(provision);
|
||||
});
|
||||
|
||||
} else {
|
||||
return Promise.resolve(provision);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports.appgateway = appgateway;
|
||||
module.exports.createimage = createimage;
|
||||
@@ -1,88 +0,0 @@
|
||||
const Docker = require('dockerode');
|
||||
const docker = new Docker({
|
||||
'socketPath': '/home/docker.sock'
|
||||
//'socketPath': '/var/run/docker.sock'
|
||||
});
|
||||
const PROJECT_PATH = process.env.PROJECT_PATH;
|
||||
const DOCKERIMAGE = "bitnami/kubectl:latest";
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const KUBE_PATH = path.join(PROJECT_PATH, 'logs', 'kube');
|
||||
|
||||
const _done = function(data){
|
||||
let output = data[0];
|
||||
let container = data[1];
|
||||
console.log(`kubectl# (${container.id}) has finished with code: ${output.StatusCode}`);
|
||||
return container.remove();
|
||||
};
|
||||
|
||||
const kubeconfig = function( provId ) {
|
||||
|
||||
fs.writeFileSync(`/app/logs/kube/config_${provId}`, kubeConfigContent);
|
||||
console.log(`kubectl# will spin up container`);
|
||||
|
||||
return docker.run(DOCKERIMAGE, ['config', 'current-context', '--kubeconfig', `/app/config_${provId}` ], processStream, {
|
||||
//"name": initContName,
|
||||
"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${KUBE_PATH}:/app`,
|
||||
]
|
||||
}
|
||||
}).then(_done);
|
||||
};
|
||||
|
||||
const apply = function( provId, kubeConfigContent ) {
|
||||
|
||||
fs.writeFileSync(`/logs/kube/${provId}.config`, kubeConfigContent);
|
||||
console.log(`kubectl# will spin up container`);
|
||||
const yaml = path.join(PROJECT_PATH, 'az-tf-templates', 'azqmi-qseok', 'scripts', 'azure-sc.yaml');
|
||||
return docker.run(DOCKERIMAGE, ['apply','-f', '/yamlfile', '--kubeconfig', `/app/${provId}.config` ], process.stdout, {
|
||||
//"name": initContName,
|
||||
"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${KUBE_PATH}:/app`,
|
||||
`${yaml}:/yamlfile`
|
||||
]
|
||||
}
|
||||
}).then(_done);
|
||||
};
|
||||
|
||||
const getpod = function( provId, kubeConfigContent ) {
|
||||
|
||||
fs.writeFileSync(`/logs/kube/${provId}.config`, kubeConfigContent);
|
||||
console.log(`kubectl# will spin up container`);
|
||||
|
||||
return docker.run(DOCKERIMAGE, ['get', 'pod', '--kubeconfig', `/app/${provId}.config` ], process.stdout, {
|
||||
//"name": initContName,
|
||||
"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${KUBE_PATH}:/app`,
|
||||
]
|
||||
}
|
||||
}).then(_done);
|
||||
};
|
||||
|
||||
const getsvc = function( provId, kubeConfigContent ) {
|
||||
|
||||
fs.writeFileSync(`/logs/kube/config_${provId}`, kubeConfigContent);
|
||||
console.log(`kubectl# will spin up container`);
|
||||
|
||||
console.log(`kubectl# will spin up container`);
|
||||
return docker.run(DOCKERIMAGE, ['get', 'svc', '--kubeconfig', `/app/config_${provId}` ], process.stdout, {
|
||||
//"name": initContName,
|
||||
"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${KUBE_PATH}:/app`,
|
||||
]
|
||||
}
|
||||
}).then(_done);
|
||||
};
|
||||
|
||||
module.exports.kubeconfig = kubeconfig;
|
||||
module.exports.apply = apply;
|
||||
module.exports.getpod = getpod;
|
||||
module.exports.getsvc = getsvc;
|
||||
@@ -1,206 +0,0 @@
|
||||
const Docker = require('dockerode');
|
||||
const docker = new Docker({
|
||||
'socketPath': '/home/docker.sock'
|
||||
//'socketPath': '/var/run/docker.sock'
|
||||
});
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const SSHPATH = process.env.SSHPATH;
|
||||
const DOCKERIMAGE = "mcr.microsoft.com/azure-cli";
|
||||
const PROJECT_PATH = process.env.PROJECT_PATH;
|
||||
|
||||
const pause = function(provision) {
|
||||
|
||||
if ( provision.scenario !== 'azqmi-synapse' ) {
|
||||
console.log(`SynapseAzCLI# provision (${provision._id}) is not AZ SYNAPSE`);
|
||||
return {"message": `Won't do anything, provision (${provision._id}) is not AZ SYNAPSE`};
|
||||
}
|
||||
|
||||
if ( !provision.outputs ) {
|
||||
console.log(`SynapseAzCLI# provision (${provision._id}) AZ SYNAPSE has NO outputs`);
|
||||
return {"message": `Won't do anything, provision (${provision._id}) AZ SYNAPSE has NO outputs`};
|
||||
}
|
||||
|
||||
const name = `qmi-synpause-${provision._id}`;
|
||||
console.log(`SynapseAzCLI# Pause Synapse: ${name}`);
|
||||
var processStream = fs.createWriteStream(provision.logFile, {flags:'a'});
|
||||
var exec = ['synpause', provision.outputs.Synapse_WS_ID, provision.outputs.Synapse_Database];
|
||||
console.log('SynapseAzCLI# Pause Synapse: exec: '+exec.join(" "));
|
||||
|
||||
return docker.run(DOCKERIMAGE, exec, processStream, {
|
||||
//"Env": vars.envs,
|
||||
"name": name,
|
||||
//"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${provision.path}/synpause.sh:/bin/synpause`,
|
||||
`${SSHPATH}:/root/.ssh`
|
||||
]
|
||||
}
|
||||
}).then(function(data) {
|
||||
var container = data[1];
|
||||
console.log(`SynapseAzCLI# Pause Synapse: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`SynapseAzCLI# Pause Synapse: Container '${name}' removed!`);
|
||||
return data[0].StatusCode;
|
||||
});
|
||||
}).then(async function(statusCode) {
|
||||
|
||||
return {"output": fs.readFileSync(provision.logFile), "statusCode": statusCode};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
const resume = function(provision) {
|
||||
|
||||
if ( provision.scenario !== 'azqmi-synapse' ) {
|
||||
console.log(`SynapseAzCLI# provision (${provision._id}) is not AZ SYNAPSE`);
|
||||
return {"message": `Won't do anything, provision (${provision._id}) is not AZ SYNAPSE`};
|
||||
}
|
||||
|
||||
if ( !provision.outputs ) {
|
||||
console.log(`SynapseAzCLI# provision (${provision._id}) AZ SYNAPSE has NO outputs`);
|
||||
return {"message": `Won't do anything, provision (${provision._id}) AZ SYNAPSE has NO outputs`};
|
||||
}
|
||||
|
||||
const name = `qmi-synresume-${provision._id}`;
|
||||
console.log(`SynapseAzCLI# Resume Synapse: ${name}`);
|
||||
var processStream = fs.createWriteStream(provision.logFile, {flags:'a'});
|
||||
var exec = ['synresume', provision.outputs.Synapse_WS_ID, provision.outputs.Synapse_Database];
|
||||
console.log('SynapseAzCLI# Resume Synapse: exec: '+exec.join(" "));
|
||||
|
||||
return docker.run(DOCKERIMAGE, exec, processStream, {
|
||||
//"Env": vars.envs,
|
||||
"name": name,
|
||||
//"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${provision.path}/synresume.sh:/bin/synresume`,
|
||||
`${SSHPATH}:/root/.ssh`
|
||||
]
|
||||
}
|
||||
}).then(function(data) {
|
||||
var container = data[1];
|
||||
console.log(`SynapseAzCLI# Resume Synapse: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`SynapseAzCLI# Resume Synapse: Container '${name}' removed!`);
|
||||
return data[0].StatusCode;
|
||||
});
|
||||
}).then(async function(statusCode) {
|
||||
|
||||
return {"output": fs.readFileSync(provision.logFile), "statusCode": statusCode};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
const createSnapshotFromDisk = function(data) {
|
||||
const rGroup = data.rGroup;
|
||||
const rGroupTarget = data.rGroupTarget || "QMI-Machines";
|
||||
const sufix = data.sufix || Date.now();
|
||||
const provision = data.provision;
|
||||
|
||||
const name = `qmi-createsnaps-${sufix}`;
|
||||
console.log(`CreateSnapsAzCLI# container: ${name}`);
|
||||
var processStream = provision? fs.createWriteStream(provision.logFile, {flags:'a'}) : fs.createWriteStream("/logs/general/qmi-snapshots.log", {flags:'a'});
|
||||
var exec = ['create-snapshots', rGroup, rGroupTarget, sufix, provision._id];
|
||||
console.log('CreateSnapsAzCLI# exec: '+exec.join(" "));
|
||||
let scriptPath = path.join(PROJECT_PATH,'..');
|
||||
return docker.run(DOCKERIMAGE, exec, processStream, {
|
||||
//"Env": vars.envs,
|
||||
"name": name,
|
||||
//"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${scriptPath}/create-snapshots.sh:/bin/create-snapshots`,
|
||||
`${SSHPATH}:/root/.ssh`
|
||||
]
|
||||
}
|
||||
}).then(function(data) {
|
||||
var container = data[1];
|
||||
console.log(`CreateSnapsAzCLI# '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`CreateSnapsAzCLI# Container '${name}' removed!`);
|
||||
return data[0].StatusCode;
|
||||
});
|
||||
}).then(async function(statusCode) {
|
||||
|
||||
return {"output": fs.readFileSync("/logs/general/qmi-snapshots.log"), "statusCode": statusCode};
|
||||
});
|
||||
}
|
||||
|
||||
const copySnapshots = function(data) {
|
||||
|
||||
let snapName = data.snapName;
|
||||
let regions = data.regions;
|
||||
|
||||
const name = `qmi-copysnaps`;
|
||||
console.log(`CopySnapsAzCLI# container: ${name}`);
|
||||
var processStream = fs.createWriteStream("/logs/general/qmi-snapshots.log", {flags:'a'});
|
||||
var exec = ['copy-snapshots-to-sa', snapName, regions];
|
||||
console.log('CopySnapsAzCLI# exec: '+exec.join(" "));
|
||||
let scriptPath = path.join(PROJECT_PATH,'..');
|
||||
return docker.run(DOCKERIMAGE, exec, processStream, {
|
||||
//"Env": vars.envs,
|
||||
"name": name,
|
||||
//"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${scriptPath}/copy-snapshots-to-sa.sh:/bin/copy-snapshots-to-sa`,
|
||||
`${SSHPATH}:/root/.ssh`
|
||||
]
|
||||
}
|
||||
}).then(function(data) {
|
||||
var container = data[1];
|
||||
console.log(`CopySnapsAzCLI# '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`CopySnapsAzCLI# Container '${name}' removed!`);
|
||||
return data[0].StatusCode;
|
||||
});
|
||||
}).then(async function(statusCode) {
|
||||
|
||||
return {"output": fs.readFileSync("/logs/general/qmi-snapshots.log"), "statusCode": statusCode};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
const checkCopySnapshots = function(data) {
|
||||
|
||||
let snapName = data.snapName;
|
||||
|
||||
const name = `qmi-checkcopysnaps`;
|
||||
console.log(`CheckCopySnapsAzCLI# container: ${name}`);
|
||||
var processStream = fs.createWriteStream("/logs/general/qmi-snapshots.log", {flags:'a'});
|
||||
var exec = ['checkcopystatus', snapName];
|
||||
console.log('CheckCopySnapsAzCLI# exec: '+exec.join(" "));
|
||||
|
||||
let scriptPath = path.join(PROJECT_PATH,'..');
|
||||
|
||||
return docker.run(DOCKERIMAGE, exec, processStream, {
|
||||
//"Env": vars.envs,
|
||||
"name": name,
|
||||
//"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${scriptPath}/checkcopystatus.sh:/bin/checkcopystatus`,
|
||||
`${SSHPATH}:/root/.ssh`
|
||||
]
|
||||
}
|
||||
}).then(function(data) {
|
||||
var container = data[1];
|
||||
console.log(`CheckCopySnapsAzCLI# '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`CheckCopySnapsAzCLI# Container '${name}' removed!`);
|
||||
return data[0].StatusCode;
|
||||
});
|
||||
}).then(async function(statusCode) {
|
||||
|
||||
return {"output": fs.readFileSync("/logs/general/qmi-snapshots.log"), "statusCode": statusCode};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
module.exports.pause = pause;
|
||||
module.exports.resume = resume;
|
||||
module.exports.createSnapshotFromDisk = createSnapshotFromDisk;
|
||||
module.exports.copySnapshots = copySnapshots;
|
||||
module.exports.checkCopySnapshots = checkCopySnapshots;
|
||||
@@ -1,446 +0,0 @@
|
||||
const Docker = require('dockerode');
|
||||
const docker = new Docker({
|
||||
'socketPath': '/home/docker.sock'
|
||||
});
|
||||
const fs = require('fs');
|
||||
const GIT_SCENARIOS = process.env.GIT_SCENARIOS;
|
||||
const GIT_TAG = process.env.GIT_TAG || "master";
|
||||
const SSHPATH = process.env.SSHPATH;
|
||||
const AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID;
|
||||
const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY;
|
||||
|
||||
function hook_stdout(callback) {
|
||||
var old_write = process.stdout.write
|
||||
|
||||
process.stdout.write = (function(write) {
|
||||
return function(string, encoding, fd) {
|
||||
write.apply(process.stdout, arguments)
|
||||
callback(string, encoding, fd)
|
||||
}
|
||||
})(process.stdout.write)
|
||||
|
||||
return function() {
|
||||
process.stdout.write = old_write
|
||||
}
|
||||
}
|
||||
|
||||
function _buildVarsExec( exec, provision ) {
|
||||
|
||||
let gitBranch = GIT_TAG;
|
||||
if ( provision._scenarioDoc && provision._scenarioDoc.gitBranch && provision._scenarioDoc.gitBranch.trim() !== "") {
|
||||
gitBranch = provision._scenarioDoc.gitBranch;
|
||||
}
|
||||
let prefix = provision.scenario.toUpperCase();
|
||||
prefix = prefix.replace(/AZQMI/g, 'QMI');
|
||||
|
||||
let envs = [
|
||||
`AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}`,
|
||||
`AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}`,
|
||||
`AWS_DEFAULT_REGION=us-east-1`,
|
||||
`TF_VAR_envbranch=${gitBranch}`,
|
||||
`TF_VAR_user_email=${provision.user.upn}`,
|
||||
`TF_VAR_user_oid=${provision.user.oid}`,
|
||||
`TF_VAR_prefix=${prefix}`
|
||||
];
|
||||
|
||||
if ( provision.forcedDestroyDate ) {
|
||||
let d1 = new Date(provision.forcedDestroyDate);
|
||||
let d2 = d1.toISOString().split('T')[0];
|
||||
envs.push(`TF_VAR_forced_destroy=${d2}`);
|
||||
}
|
||||
|
||||
if ( provision.deployOpts ) {
|
||||
|
||||
if ( provision.deployOpts.subsId ) {
|
||||
exec.push('-var');
|
||||
exec.push(`subscription_id=${provision.deployOpts.subsId}`);
|
||||
}
|
||||
|
||||
if ( provision.deployOpts.location ) {
|
||||
exec.push('-var');
|
||||
exec.push(`location=${provision.deployOpts.location}`);
|
||||
}
|
||||
|
||||
if ( provision.deployOpts.vnetExists ) {
|
||||
envs.push(`TF_VAR_subnet_id=${provision.deployOpts.subnetId}`);
|
||||
if ( provision.isExternalAccess ) {
|
||||
envs.push(`TF_VAR_app_gw_subnet=${provision.deployOpts.appGwSubnetId}`);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exec.push('-var');
|
||||
exec.push(`provision_id=${provision._id}`);
|
||||
exec.push('-var');
|
||||
exec.push(`user_id=${provision.user.displayName}`);
|
||||
|
||||
//DEPRECATED VMIMAGE
|
||||
if ( provision.vmImage ) {
|
||||
for ( let key in provision.vmImage ) {
|
||||
|
||||
if ( !provision.vmImage[key].disabled ) {
|
||||
|
||||
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}`);
|
||||
} else {
|
||||
exec.push('-var');
|
||||
exec.push(`vm_type_${key}=ENABLED`);
|
||||
}
|
||||
|
||||
if ( provision.vmImage[key].diskSizeGb ) {
|
||||
exec.push('-var');
|
||||
exec.push(`disk_size_gb_${key}=${provision.vmImage[key].diskSizeGb}`);
|
||||
}
|
||||
|
||||
if ( provision.vmImage[key].version && provision.vmImage[key].version.image) {
|
||||
exec.push('-var');
|
||||
exec.push(`image_reference_${key}=${provision.vmImage[key].version.image}`);
|
||||
}
|
||||
|
||||
if ( provision.vmImage[key].version && provision.vmImage[key].version.init_password) {
|
||||
exec.push('-var');
|
||||
exec.push(`image_reference_${key}_init_password=${provision.vmImage[key].version.init_password}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NEW ATTRS
|
||||
if ( provision.options ) {
|
||||
for ( let key in provision.options ) {
|
||||
|
||||
if ( !provision.options[key].disabled ) {
|
||||
|
||||
if ( key.indexOf("vm") !== -1 ) {
|
||||
if ( provision.options[key].nodeCount ) {
|
||||
exec.push('-var');
|
||||
exec.push(`agent_count_${key}=${provision[key].nodeCount}`);
|
||||
}
|
||||
if ( provision.options[key].vmType ) {
|
||||
exec.push('-var');
|
||||
exec.push(`vm_type_${key}=${provision.options[key].vmType}`);
|
||||
}else {
|
||||
exec.push('-var');
|
||||
exec.push(`vm_type_${key}=ENABLED`);
|
||||
}
|
||||
if ( provision.options[key].diskSizeGb ) {
|
||||
exec.push('-var');
|
||||
exec.push(`disk_size_gb_${key}=${provision.options[key].diskSizeGb}`);
|
||||
}
|
||||
if ( provision.options[key].selected && provision.options[key].selected.value) {
|
||||
exec.push('-var');
|
||||
exec.push(`image_reference_${key}=${provision.options[key].selected.value}`);
|
||||
}
|
||||
|
||||
if ( provision.options[key].selected && provision.options[key].selected.init_password) {
|
||||
exec.push('-var');
|
||||
exec.push(`image_reference_${key}_init_password=${provision.options[key].selected.init_password}`);
|
||||
}
|
||||
} else {
|
||||
if ( provision.options[key].selected && provision.options[key].selected.value) {
|
||||
exec.push('-var');
|
||||
exec.push(`attr_${key}=${provision.options[key].selected.value}`);
|
||||
} else {
|
||||
exec.push('-var');
|
||||
exec.push(`attr_${key}=ENABLED`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( provision.isExternalAccess ) {
|
||||
exec.push('-var');
|
||||
exec.push(`is_external_access=${provision.isExternalAccess}`);
|
||||
}
|
||||
|
||||
if ( provision.schedule ) {
|
||||
if ( provision.schedule.is24x7 === true ) {
|
||||
exec.push('-var');
|
||||
exec.push(`is_24x7=true`);
|
||||
} else if ( provision.schedule.is24x7 === false ) {
|
||||
exec.push('-var');
|
||||
exec.push(`is_24x7=false`);
|
||||
if ( provision.schedule.utcTagStartupTime && provision.schedule.isStartupTimeEnable ) {
|
||||
exec.push('-var');
|
||||
exec.push(`startupTime=${provision.schedule.utcTagStartupTime}`);
|
||||
}
|
||||
if ( provision.schedule.utcTagShutdownTime ) {
|
||||
exec.push('-var');
|
||||
exec.push(`shutdownTime=${provision.schedule.utcTagShutdownTime}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {"exec": exec, "envs": envs};
|
||||
}
|
||||
|
||||
const init = function( provision ) {
|
||||
|
||||
const name = `qmi-tf-init-${provision._id}`;
|
||||
console.log(`Terraform# Init: will spin up container: ${name}`);
|
||||
var processStream = fs.createWriteStream(provision.logFile, {flags:'a'});
|
||||
let gitBranch = GIT_TAG;
|
||||
if ( provision._scenarioDoc && provision._scenarioDoc.gitBranch && provision._scenarioDoc.gitBranch.trim() !== "") {
|
||||
gitBranch = provision._scenarioDoc.gitBranch;
|
||||
}
|
||||
let exec = ['terraform', 'init', '-no-color', `-from-module=${GIT_SCENARIOS}//${provision.scenario}?ref=${gitBranch}`];
|
||||
console.log('Terraform# Init: exec: '+exec.join(" "));
|
||||
console.log('Terraform# Init: version to use is : '+provision.terraformImage);
|
||||
return docker.run(provision.terraformImage, exec, processStream, {
|
||||
//"Env": [],
|
||||
"name": name,
|
||||
"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${provision.path}:/app`
|
||||
]
|
||||
}
|
||||
}).then(function(data) {
|
||||
var output = data[0];
|
||||
var container = data[1];
|
||||
console.log(`Terraform# Init: ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`Terraform# Init: ${name} removed!`);
|
||||
return output.StatusCode;
|
||||
});
|
||||
}).then(function(statusCode) {
|
||||
return {"provision": provision, "statusCode": statusCode};
|
||||
});
|
||||
};
|
||||
|
||||
const plan = function( provision ) {
|
||||
|
||||
const name = `qmi-tf-plan-${provision._id}`;
|
||||
console.log(`Terraform# Plan: will spin up container: ${name}`);
|
||||
var processStream = fs.createWriteStream(provision.logFile, {flags:'a'});
|
||||
//var processStream = process.stdout;
|
||||
var exec = ['terraform', 'plan', '-no-color', '-input=false', '-out=tfplan' ];
|
||||
var vars = _buildVarsExec(exec, provision);
|
||||
exec = vars.exec;
|
||||
console.log('Terraform# Plan: exec: '+exec.join(" "));
|
||||
console.log('Terraform# Plan: version to use is : '+provision.terraformImage);
|
||||
return docker.run(provision.terraformImage, exec, processStream, {
|
||||
"Env": vars.envs,
|
||||
"name": name,
|
||||
"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${provision.path}:/app`,
|
||||
`${SSHPATH}:/root/.ssh`
|
||||
],
|
||||
"NetworkMode": "host"
|
||||
}
|
||||
}).then(function(data){
|
||||
var container = data[1];
|
||||
console.log(`Terraform# Plan: ${name} (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`Terraform# Plan: ${name} removed!`);
|
||||
return data[0].StatusCode;
|
||||
});
|
||||
}).then(function(statusCode) {
|
||||
return {"output": fs.readFileSync(provision.logFile), "statusCode": statusCode};
|
||||
})
|
||||
};
|
||||
|
||||
const apply = function( provision ) {
|
||||
|
||||
const name = `qmi-tf-apply-${provision._id}`;
|
||||
console.log(`Terraform# Apply: will spin up container: ${name}`);
|
||||
var processStream = fs.createWriteStream(provision.logFile, {flags:'a'});
|
||||
//var processStream = process.stdout;
|
||||
|
||||
var exec = ['terraform', 'apply', 'tfplan', '-no-color'];
|
||||
console.log('Terraform# Apply: exec: '+exec.join(" "));
|
||||
console.log('Terraform# Apply: version to use is : '+provision.terraformImage);
|
||||
return docker.run(provision.terraformImage, exec, processStream, {
|
||||
"Env": [
|
||||
`AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}`,
|
||||
`AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}`,
|
||||
`AWS_DEFAULT_REGION=us-east-1`
|
||||
],
|
||||
"name": name,
|
||||
"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${provision.path}:/app`,
|
||||
`${SSHPATH}:/root/.ssh`
|
||||
],
|
||||
"NetworkMode": "host"
|
||||
}
|
||||
}).then(function(data){
|
||||
let container = data[1];
|
||||
console.log(`Terraform# Apply: ${name} (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`Terraform# Apply: Container '${name}' removed!`);
|
||||
return data[0].StatusCode;
|
||||
});
|
||||
}).then(function(statusCode) {
|
||||
return {"output": fs.readFileSync(provision.logFile), "statusCode": statusCode};
|
||||
})
|
||||
}
|
||||
|
||||
const initUpgrade = async function(destroyMongo, provision) {
|
||||
|
||||
if ( !provision.tfInitUpgrade ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const name = `qmi-tf-initupgrade-${destroyMongo._id}`;
|
||||
console.log(`Terraform# Destroy: will spin up container: ${name}`);
|
||||
var processStream = fs.createWriteStream(destroyMongo.logFile, {flags:'a'});
|
||||
var exec = ['terraform', 'init', '-upgrade'];
|
||||
var vars = _buildVarsExec(exec, provision);
|
||||
exec = vars.exec;
|
||||
console.log('Terraform# Destroy: exec: '+exec.join(" "));
|
||||
console.log('Terraform# Destroy: version to use is : '+provision.terraformImage);
|
||||
|
||||
return docker.run(provision.terraformImage, exec, processStream, {
|
||||
"Env": vars.envs,
|
||||
"name": name,
|
||||
"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${provision.path}:/app`,
|
||||
`${SSHPATH}:/root/.ssh`
|
||||
]
|
||||
}
|
||||
}).then(function(data) {
|
||||
var container = data[1];
|
||||
console.log(`Terraform# Destroy: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`Terraform# Destroy: Container '${name}' removed!`);
|
||||
return data[0].StatusCode;
|
||||
});
|
||||
})
|
||||
.then(function(statusCode) {
|
||||
return {"provision": provision, "statusCode": statusCode};
|
||||
});
|
||||
};
|
||||
|
||||
const destroy = function(destroyMongo, provision) {
|
||||
|
||||
const name = `qmi-tf-destroy-${destroyMongo._id}`;
|
||||
console.log(`Terraform# Destroy: will spin up container: ${name}`);
|
||||
var processStream = fs.createWriteStream(destroyMongo.logFile, {flags:'a'});
|
||||
var exec = ['terraform', 'destroy', '-auto-approve', '-no-color'];
|
||||
var vars = _buildVarsExec(exec, provision);
|
||||
exec = vars.exec;
|
||||
console.log('Terraform# Destroy: exec: '+exec.join(" "));
|
||||
console.log('Terraform# Destroy: version to use is : '+provision.terraformImage);
|
||||
|
||||
return docker.run(provision.terraformImage, exec, processStream, {
|
||||
"Env": vars.envs,
|
||||
"name": name,
|
||||
"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${provision.path}:/app`,
|
||||
`${SSHPATH}:/root/.ssh`
|
||||
]
|
||||
}
|
||||
}).then(function(data) {
|
||||
var container = data[1];
|
||||
console.log(`Terraform# Destroy: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`Terraform# Destroy: Container '${name}' removed!`);
|
||||
return data[0].StatusCode;
|
||||
});
|
||||
}).then(async function(statusCode) {
|
||||
|
||||
return {"output": fs.readFileSync(destroyMongo.logFile), "statusCode": statusCode};
|
||||
});
|
||||
};
|
||||
|
||||
const outputs = function(provision) {
|
||||
|
||||
const name = `qmi-tf-output-${provision._id}`;
|
||||
console.log(`Terraform# Output: will spin up container: ${name}`);
|
||||
|
||||
|
||||
var exec = ['terraform', 'output', '-no-color', '-json'];
|
||||
console.log('Terraform# Output: exec: '+exec.join(" "));
|
||||
|
||||
var tfout = "";
|
||||
var unhook = hook_stdout(function(string, encoding, fd) {
|
||||
tfout += string.trim();
|
||||
});
|
||||
return docker.run(provision.terraformImage, exec, process.stdout, {
|
||||
//"Env": [],
|
||||
"name": name,
|
||||
"WorkingDir": "/app",
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
`${provision.path}:/app`
|
||||
]
|
||||
}
|
||||
}).then(function(data) {
|
||||
unhook();
|
||||
var container = data[1];
|
||||
console.log(`Terraform# Output: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove();
|
||||
}).then(async function(data) {
|
||||
console.log(`Terraform# Output: Container '${name}' removed!`);
|
||||
//console.log("Terraform# Output: tfout: " + tfout);
|
||||
var out = JSON.parse(tfout);
|
||||
var o = {};
|
||||
for (var key in out) {
|
||||
o[key] = out[key].value;
|
||||
}
|
||||
return o;
|
||||
});
|
||||
};
|
||||
|
||||
const stop = function(provision) {
|
||||
|
||||
if ( provision.status !== "provisioning" ) {
|
||||
console.log(`Terraform# Stop: provision (${provision._id}) is not provisioning`);
|
||||
return {"message": `Won't stop container: provision (${provision._id}) is not provisioning`};
|
||||
}
|
||||
|
||||
const name = `qmi-tf-apply-${provision._id}`;
|
||||
|
||||
console.log(`Terraform# Stop: will try to stop container: ${name}`);
|
||||
|
||||
return docker.listContainers().then(function(containers) {
|
||||
|
||||
var containerID;
|
||||
|
||||
for (let i=0;i<containers.length;i++) {
|
||||
if ( containers[i].Names && containers[i].Names.length ) {
|
||||
//console.log(`Terraform# Stop: debug container Names: ${containers[i].Names[0]}`);
|
||||
if ( containers[i].Names[0] === ("/"+name) ) {
|
||||
console.log(`Terraform# Stop: container found: ${name}`);
|
||||
containerID = containers[i].Id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( containerID ) {
|
||||
console.log(`Terraform# Stop: stopping container: ${name} with ID ${containerID}`);
|
||||
return docker.getContainer(containerID).kill().then(function(){
|
||||
console.log(`Terraform# Stop: container stopped!!: ${name}`);
|
||||
return {"message": `container ${name} stopped`}
|
||||
});
|
||||
} else {
|
||||
console.log(`Terraform# Stop: container ${name} not found!`);
|
||||
return {"message": `container ${name} not found`};
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
module.exports.init = init;
|
||||
module.exports.plan = plan;
|
||||
module.exports.apply = apply;
|
||||
module.exports.destroy = destroy;
|
||||
module.exports.outputs = outputs;
|
||||
module.exports.stop = stop;
|
||||
module.exports.initUpgrade = initUpgrade;
|
||||
@@ -1,308 +0,0 @@
|
||||
'use strict';
|
||||
const axios = require('axios');
|
||||
const https = require("https");
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
|
||||
const GUACA_DATASOURCE = process.env.GUACA_DATASOURCE || "postgresql";
|
||||
const GUACA_BASEURL = process.env.GUACA_BASEURL || "http://qmicloud-dev.qliktech.com:8080/guacamole";
|
||||
const GUACA_PUBLIC_URL = process.env.GUACA_PUBLIC_URL || "https://qmicloud-dev.qliktech.com/guacamole";
|
||||
const GUACA_USERNAME = process.env.GUACA_USERNAME || "guacadmin";
|
||||
const GUACA_PASSWORD = process.env.GUACA_PASSWORD;
|
||||
|
||||
|
||||
const base64urlEncode = function(value) {
|
||||
|
||||
// Translate padded standard base64 to unpadded base64url
|
||||
return Buffer.from(value).toString('base64').replace(/[+/=]/g,
|
||||
(str) => ({
|
||||
'+' : '-',
|
||||
'/' : '_',
|
||||
'=' : ''
|
||||
})[str]
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
const guacamoleClientId = function(id, type, dataSource) {
|
||||
return base64urlEncode([
|
||||
id,
|
||||
type,
|
||||
dataSource
|
||||
].join('\0'));
|
||||
};
|
||||
|
||||
async function _auth() {
|
||||
try {
|
||||
const params = new URLSearchParams();
|
||||
params.append('username', GUACA_USERNAME);
|
||||
params.append('password', GUACA_PASSWORD);
|
||||
|
||||
var res = await axios.post(`${GUACA_BASEURL}/api/tokens`, params, {
|
||||
httpsAgent: new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
})
|
||||
});
|
||||
|
||||
return res.data.authToken;
|
||||
|
||||
|
||||
} catch (err) {
|
||||
// Handle Error Here
|
||||
console.log("Guacamole# Could not auth", err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function _createUser(email, token) {
|
||||
|
||||
try {
|
||||
|
||||
var body = {
|
||||
"username": email,
|
||||
"attributes": {
|
||||
"disabled": "",
|
||||
"expired": "",
|
||||
"access-window-start": "",
|
||||
"access-window-end": "",
|
||||
"valid-from": "",
|
||||
"valid-until": "",
|
||||
"timezone": null
|
||||
}
|
||||
};
|
||||
await axios({
|
||||
url: `${GUACA_BASEURL}/api/session/data/${GUACA_DATASOURCE}/users`,
|
||||
method: "post",
|
||||
data: body,
|
||||
httpsAgent: new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
}),
|
||||
headers: {
|
||||
'Guacamole-Token': token
|
||||
}
|
||||
});
|
||||
|
||||
console.log("Guacamole# User created: ", email);
|
||||
|
||||
return email;
|
||||
|
||||
|
||||
} catch (err) {
|
||||
// Handle Error Here
|
||||
|
||||
console.log("Guacamole# User already existed: ", email);
|
||||
|
||||
return email;
|
||||
}
|
||||
}
|
||||
|
||||
async function _createConnection(type, name, ip, username, password, token) {
|
||||
try {
|
||||
var body = {
|
||||
"parentIdentifier": "ROOT",
|
||||
"name": name,
|
||||
"protocol": type,
|
||||
"parameters": {
|
||||
"port": type === "ssh"? "22" : "3389",
|
||||
"read-only": "",
|
||||
"swap-red-blue": "",
|
||||
"cursor": "",
|
||||
"color-depth": "",
|
||||
"force-lossless": "",
|
||||
"clipboard-encoding": "",
|
||||
"disable-copy": "",
|
||||
"disable-paste": "",
|
||||
"dest-port": "",
|
||||
"recording-exclude-output": "",
|
||||
"recording-exclude-mouse": "",
|
||||
"recording-include-keys": "",
|
||||
"create-recording-path": "",
|
||||
"enable-sftp": "",
|
||||
"sftp-port": "",
|
||||
"sftp-server-alive-interval": "",
|
||||
"sftp-disable-download": "",
|
||||
"sftp-disable-upload": "",
|
||||
"enable-audio": "",
|
||||
"wol-send-packet": "",
|
||||
"wol-udp-port": "",
|
||||
"wol-wait-time": "",
|
||||
"security": "nla",
|
||||
"disable-auth": "",
|
||||
"ignore-cert": "true",
|
||||
"gateway-port": "",
|
||||
"server-layout": "",
|
||||
"timezone": null,
|
||||
"enable-touch": "",
|
||||
"console": "",
|
||||
"width": "",
|
||||
"height": "",
|
||||
"dpi": "",
|
||||
"resize-method": "",
|
||||
"normalize-clipboard": "",
|
||||
"console-audio": "",
|
||||
"disable-audio": "",
|
||||
"enable-audio-input": "",
|
||||
"enable-printing": "",
|
||||
"enable-drive": "",
|
||||
"disable-download": "",
|
||||
"disable-upload": "",
|
||||
"create-drive-path": "",
|
||||
"enable-wallpaper": "",
|
||||
"enable-theming": "",
|
||||
"enable-font-smoothing": "",
|
||||
"enable-full-window-drag": "",
|
||||
"enable-desktop-composition": "",
|
||||
"enable-menu-animations": "",
|
||||
"disable-bitmap-caching": "",
|
||||
"disable-offscreen-caching": "",
|
||||
"disable-glyph-caching": "",
|
||||
"preconnection-id": "",
|
||||
"recording-exclude-touch": "",
|
||||
"hostname": ip,
|
||||
"username": username,
|
||||
"password": password
|
||||
},
|
||||
"attributes": {
|
||||
"max-connections": "2",
|
||||
"max-connections-per-user": "2",
|
||||
"weight": "",
|
||||
"failover-only": "",
|
||||
"guacd-port": "",
|
||||
"guacd-encryption": ""
|
||||
}
|
||||
};
|
||||
var res = await axios({
|
||||
url: `${GUACA_BASEURL}/api/session/data/${GUACA_DATASOURCE}/connections`,
|
||||
method: "post",
|
||||
data: body,
|
||||
httpsAgent: new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
}),
|
||||
headers: {
|
||||
'Guacamole-Token': token
|
||||
}
|
||||
});
|
||||
|
||||
console.log("Guacamole# Connection created: ", name);
|
||||
|
||||
return res.data;
|
||||
|
||||
|
||||
} catch (err) {
|
||||
// Handle Error Here
|
||||
console.log("Guacamole# Could not create Guaca Connection", err.config.data);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function _addConnectionToUser(email, identifier, token) {
|
||||
try {
|
||||
var body = [
|
||||
{
|
||||
"op": "add",
|
||||
"path": "/connectionPermissions/"+identifier,
|
||||
"value": "READ"
|
||||
}
|
||||
];
|
||||
var res = await axios({
|
||||
url: `${GUACA_BASEURL}/api/session/data/${GUACA_DATASOURCE}/users/${email}/permissions`,
|
||||
method: "patch",
|
||||
data: body,
|
||||
httpsAgent: new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
}),
|
||||
headers: {
|
||||
'Guacamole-Token': token
|
||||
}
|
||||
});
|
||||
|
||||
console.log("Guacamole# Connection identifier ("+identifier+") added to user: ", email);
|
||||
|
||||
return res.data;
|
||||
|
||||
} catch (err) {
|
||||
// Handle Error Here
|
||||
console.log("Guacamole# Could not add connection "+identifier+" to Guaca User " + email);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function setUserConnection(provision, scenario){
|
||||
|
||||
var resultProvision = provision;
|
||||
|
||||
if ( provision && provision.status === 'provisioned' && provision.options && provision.options.vm1 ) {
|
||||
var token = await _auth();
|
||||
|
||||
if (token) {
|
||||
let userEmailLower = provision.user.mail.toLowerCase();
|
||||
var email = await _createUser(userEmailLower, token);
|
||||
|
||||
|
||||
let ip = provision.outputs["RDP-ip"] || provision.outputs["Replicate__RDP_IP"] || provision.outputs["Private_IP"] || provision.outputs["IP"];
|
||||
let credentials = provision.outputs["RDP-credentials"] || provision.outputs["Replicate__RDP-credentials"] || provision.outputs["User-and-Password"] || provision.outputs["All_DBs_User-and-Password"];
|
||||
|
||||
if (ip && credentials){
|
||||
let username = credentials.split(" / ")[0];
|
||||
let password = credentials.split(" / ")[1];
|
||||
|
||||
if (username && password){
|
||||
let connection;
|
||||
let connName = `(${scenario.name}_${provision._id}) - ${provision.description}`;
|
||||
let type;
|
||||
if ( scenario.labels.indexOf("linux") === -1 ) {
|
||||
connection = await _createConnection("rdp",connName, ip, username, password, token);
|
||||
type = "RDP";
|
||||
} else {
|
||||
connection = await _createConnection("ssh", connName, ip, username, password, token);
|
||||
type = "SSH";
|
||||
}
|
||||
if (connection) {
|
||||
let outputs = provision.outputs || {};
|
||||
const guacClient = guacamoleClientId(connection.identifier,"c", GUACA_DATASOURCE);
|
||||
outputs[`WEB_${type}_ACCESS_WITH_GUACAMOLE`] = `${GUACA_PUBLIC_URL}/#/client/${guacClient}`;
|
||||
|
||||
_addConnectionToUser(email, connection.identifier, token);
|
||||
|
||||
resultProvision = await db.provision.update(provision._id, {"guacaConnId": connection.identifier, outputs: outputs});
|
||||
|
||||
} else {
|
||||
console.log("Guacamole# No connection was created for provision: ", provision._id);
|
||||
}
|
||||
} else {
|
||||
console.log("Guacamole# Could not find username or password for provision:", provision._id);
|
||||
}
|
||||
} else {
|
||||
console.log("Guacamole# Could not find ip or credentials for provision:", provision._id);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return resultProvision;
|
||||
|
||||
}
|
||||
|
||||
async function deleteConnection(provision){
|
||||
if ( provision.guacaConnId ) {
|
||||
try {
|
||||
var token = await _auth();
|
||||
await axios({
|
||||
url: `${GUACA_BASEURL}/api/session/data/${GUACA_DATASOURCE}/connections/${provision.guacaConnId}`,
|
||||
method: "delete",
|
||||
httpsAgent: new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
}),
|
||||
headers: {
|
||||
'Guacamole-Token': token
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
// Handle Error Here
|
||||
console.log("Guacamole# Could not delete connection ("+provision.guacaConnId+")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.setUserConnection = setUserConnection;
|
||||
module.exports.deleteConnection = deleteConnection;
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
const MYQUEUES = require('qmi-cloud-common/queues');
|
||||
const TF_APPLY_QUEUE = MYQUEUES.TF_APPLY_QUEUE;
|
||||
const TF_APPLY_QSEOK_QUEUE = MYQUEUES.TF_APPLY_QSEOK_QUEUE;
|
||||
const TF_DESTROY_QUEUE = MYQUEUES.TF_DESTROY_QUEUE;
|
||||
const STOP_CONTAINER_QUEUE = MYQUEUES.STOP_CONTAINER_QUEUE;
|
||||
const SYNAPSE_QUEUE = MYQUEUES.SYNAPSE_QUEUE;
|
||||
const WEBHOOK_QUEUE = MYQUEUES.WEBHOOK_QUEUE;
|
||||
const queues = MYQUEUES.queues;
|
||||
|
||||
var path = require("path");
|
||||
|
||||
|
||||
queues[TF_APPLY_QUEUE].process("tf_apply_job", 10, path.resolve(__dirname, 'processor-apply.js'));
|
||||
queues[TF_APPLY_QSEOK_QUEUE].process("tf_apply_qseok_job", 10, path.resolve(__dirname, 'processor-apply-qseok.js'));
|
||||
queues[TF_DESTROY_QUEUE].process("tf_destroy_job", 10, path.resolve(__dirname, 'processor-destroy.js'));
|
||||
queues[STOP_CONTAINER_QUEUE].process("tf_abort_apply_job", 10, path.resolve(__dirname, 'processor-stop-container.js'));
|
||||
queues[SYNAPSE_QUEUE].process("synapse_job", 10, path.resolve(__dirname, 'processor-synapse.js'));
|
||||
queues[WEBHOOK_QUEUE].process("webhook_job", 10, path.resolve(__dirname, 'processor-webhook.js'));
|
||||
|
||||
|
||||
console.log(`Worker queues started!`);
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "qmi-cloud-worker",
|
||||
"version": "2.2.1",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"start:dev": "nodemon index.js",
|
||||
"test": "echo \"No test specified\" && exit 0"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"qmi-cloud-common": "../qmi-cloud-common",
|
||||
"dockerode": "^3.0.2",
|
||||
"esm": "^3.2.25",
|
||||
"nodemon": "^1.19.1",
|
||||
"axios": "^0.21.1"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
const commonApply = require("./common-apply");
|
||||
//const kubectl = require('./docker/kubectl');
|
||||
|
||||
module.exports = function(job){
|
||||
return commonApply(job);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
const commonApply = require("./common-apply");
|
||||
|
||||
module.exports = function(job){
|
||||
return commonApply(job);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
const tf = require('./docker/tf');
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const path = require('path');
|
||||
const sendEmail = require("qmi-cloud-common/send-email");
|
||||
const barracuda = require("qmi-cloud-common/barracuda");
|
||||
const guaca = require("./guacamole");
|
||||
|
||||
const MYQUEUES = require('qmi-cloud-common/queues');
|
||||
const queues = MYQUEUES.queues;
|
||||
const WEBHOOK_QUEUE = MYQUEUES.WEBHOOK_QUEUE;
|
||||
|
||||
|
||||
module.exports = async function(job){
|
||||
|
||||
var triggerUser = job.data.user;
|
||||
|
||||
var destroyMongo = await db.destroy.update(job.data.id, {
|
||||
"status": "destroying",
|
||||
"jobId": job.id,
|
||||
"logFile": path.join('/logs', 'destroy', `${job.data.id}.log`)
|
||||
});
|
||||
|
||||
if ( !destroyMongo ) {
|
||||
console.log(`ProcessorDestroy# Not found Destroy object in Database (it should exist!), detroyId is: ${job.data.id}` );
|
||||
return Promise.reject({"success": false, "err": "Not found Destroy object in Worker"});
|
||||
}
|
||||
|
||||
var provMongo = await db.provision.getById(job.data.provId);
|
||||
// Deleting Barracuda App if existed
|
||||
if ( provMongo.barracudaAppId ) {
|
||||
console.log(`ProcessorDestroy# Deleting Barracuda App...` );
|
||||
barracuda.deleteApp(provMongo);
|
||||
} else {
|
||||
console.log(`ProcessorDestroy# There is no barracuda to be deleted` );
|
||||
}
|
||||
|
||||
db.event.add({ user: triggerUser._id, provision: provMongo._id, type: 'provision.destroy-init' });
|
||||
|
||||
return tf.initUpgrade(destroyMongo, provMongo).then(async function() {
|
||||
return tf.destroy(destroyMongo, provMongo).then(async function(res) {
|
||||
let update, update2;
|
||||
if ( res.output.indexOf("Error:") !== -1 ) {
|
||||
update = await db.destroy.update(destroyMongo._id,{"status": "error"});
|
||||
update2 = await db.provision.update(provMongo._id, {"isDestroyed": false});
|
||||
|
||||
} else {
|
||||
update = await db.destroy.update(destroyMongo._id, {"status": "destroyed"});
|
||||
let timeRunning = db.utils.getNewTimeRunning(provMongo);
|
||||
update2 = await db.provision.update(provMongo._id, {"isDestroyed": true, "timeRunning": timeRunning, "pendingNextAction": null, "actualDestroyDate": new Date()});
|
||||
sendEmail.sendDestroyedSuccess(update2, job.data._scenario);
|
||||
guaca.deleteConnection(provMongo);
|
||||
|
||||
|
||||
//console.log(`ProcessorDestroy# Deleting shares of this provision` );
|
||||
//db.sharedProvision.delMany({"provision":update2._id});
|
||||
}
|
||||
return { destroy: update, provision: update2 };
|
||||
});
|
||||
}).then(async function(res) {
|
||||
if ( res.provision.isDestroyed ) {
|
||||
console.log(`ProcessorDestroy# Provision (${res.provision._id}) destroyed!` );
|
||||
db.event.add({ provision: provMongo._id, type: 'provision.destroy-finished' });
|
||||
|
||||
let tempApiKey = await db.apiKey.getOne({"description": res.provision._id});
|
||||
if (tempApiKey && tempApiKey._id){
|
||||
console.log(`ProcessorDestroy# Deleting APIKEY created for this provision: (${res.provision._id})` );
|
||||
db.apiKey.del(tempApiKey._id);
|
||||
}
|
||||
|
||||
|
||||
queues[WEBHOOK_QUEUE].add("webhook_job", {
|
||||
provId: res.provision._id,
|
||||
scenario: res.provision.scenario,
|
||||
user: triggerUser._id,
|
||||
eventType: 'provision.destroy-finished'
|
||||
});
|
||||
|
||||
} else {
|
||||
console.log(`ProcessorDestroy# Provision (${res.provision._id}) NOT destroyed - Error!` );
|
||||
db.event.add({ provision: provMongo._id, type: 'provision.destroy-error' });
|
||||
|
||||
queues[WEBHOOK_QUEUE].add("webhook_job", {
|
||||
provId: provMongo._id,
|
||||
scenario: provMongo.scenario,
|
||||
user: triggerUser._id,
|
||||
eventType: 'provision.destroy-error'
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve({"success": true, job: res});
|
||||
}).catch(function(err) {
|
||||
console.log("ProcessorDestroy# err", err);
|
||||
db.event.add({ provision: provMongo._id, type: 'provision.destroy-error' });
|
||||
db.destroy.update(destroyMongo._id, {"status": "error", "isDestroyed": false});
|
||||
return Promise.reject({"success": false, "err": err});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const tf = require("./docker/tf");
|
||||
|
||||
module.exports = async function(job) {
|
||||
|
||||
var prov = await db.provision.getById(job.data.provId);
|
||||
|
||||
if ( !prov ) {
|
||||
console.log(`ProcessorStopContainer# Error: Not found Provision object in Database (it should exist!), provisionId is: ${job.data.id}` );
|
||||
return Promise.reject({"success": false, "err": "Not found Provision object in Worker"});
|
||||
}
|
||||
|
||||
// TERRAFORM INIT
|
||||
return tf.stop(prov)
|
||||
.then( function(res) {
|
||||
return Promise.resolve( { "success": true, "output": res });
|
||||
} ).catch( function(err) {
|
||||
console.log("ProcessorStopContainer# Error:", err);
|
||||
return Promise.reject({"success": false, "error": err});
|
||||
} );
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const synapse = require("./docker/synapse");
|
||||
|
||||
module.exports = async function(job) {
|
||||
|
||||
console.log(`ProcessorAzCLI# will execute ${job.data.tasktype} task`);
|
||||
|
||||
if (job.data.tasktype === 'pause') {
|
||||
|
||||
var prov = await db.provision.getById(job.data.provId);
|
||||
|
||||
if ( !prov ) {
|
||||
console.log(`ProcessorAzCLI# Error: Not found Provision object in Database (it should exist!), provisionId is: ${job.data.id}` );
|
||||
return Promise.reject({"success": false, "err": "Not found Provision object in Worker"});
|
||||
}
|
||||
|
||||
// Synapse Pause
|
||||
db.provision.update(prov._id, {"statusVms": "Stopping"});
|
||||
return synapse.pause(prov)
|
||||
.then( function(res) {
|
||||
db.provision.update(prov._id, {"statusVms": "Stopped"});
|
||||
return Promise.resolve( { "success": true, "output": res });
|
||||
} ).catch( function(err) {
|
||||
console.log("ProcessorAzCLI# Error:", err);
|
||||
db.provision.update(prov._id, {"statusVms": "Running"});
|
||||
return Promise.reject({"success": false, "error": err});
|
||||
} );
|
||||
} else if (job.data.tasktype === 'resume') {
|
||||
|
||||
var prov = await db.provision.getById(job.data.provId);
|
||||
|
||||
if ( !prov ) {
|
||||
console.log(`ProcessorAzCLI# Error: Not found Provision object in Database (it should exist!), provisionId is: ${job.data.id}` );
|
||||
return Promise.reject({"success": false, "err": "Not found Provision object in Worker"});
|
||||
}
|
||||
|
||||
// Synapse Resume
|
||||
db.provision.update(prov._id, {"statusVms": "Starting"});
|
||||
return synapse.resume(prov)
|
||||
.then( function(res) {
|
||||
db.provision.update(prov._id, {"statusVms": "Running"});
|
||||
return Promise.resolve( { "success": true, "output": res });
|
||||
} ).catch( function(err) {
|
||||
console.log("ProcessorAzCLI# Error:", err);
|
||||
db.provision.update(prov._id, {"statusVms": "Stopped"});
|
||||
return Promise.reject({"success": false, "error": err});
|
||||
} );
|
||||
} else if (job.data.tasktype === 'create-snapshots') {
|
||||
return synapse.createSnapshotFromDisk(job.data)
|
||||
.then( function(res) {
|
||||
return Promise.resolve( { "success": true, "output": res });
|
||||
} ).catch( function(err) {
|
||||
console.log("ProcessorAzCLI# Error:", err);
|
||||
return Promise.reject({"success": false, "error": err});
|
||||
} );
|
||||
|
||||
} else if (job.data.tasktype === 'copy-snapshots') {
|
||||
|
||||
return synapse.copySnapshots(job.data)
|
||||
.then( function(res) {
|
||||
return Promise.resolve( { "success": true, "output": res });
|
||||
} ).catch( function(err) {
|
||||
console.log("ProcessorAzCLI# Error:", err);
|
||||
return Promise.reject({"success": false, "error": err});
|
||||
} );
|
||||
} else if (job.data.tasktype === 'check-copy-snapshots') {
|
||||
|
||||
return synapse.checkCopySnapshots(job.data)
|
||||
.then( function(res) {
|
||||
return Promise.resolve( { "success": true, "output": res });
|
||||
} ).catch( function(err) {
|
||||
console.log("ProcessorAzCLI# Error:", err);
|
||||
return Promise.reject({"success": false, "error": err});
|
||||
} );
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const axios = require('axios');
|
||||
const https = require("https");
|
||||
|
||||
module.exports = async function(job) {
|
||||
|
||||
//console.log(`ProcessorWebhook# Processing Webhook`, job.data );
|
||||
|
||||
const get = await db.webhook.get({ "eventType": job.data.eventType });
|
||||
const webhooks = get.results;
|
||||
|
||||
if ( !webhooks || webhooks.length === 0 ) {
|
||||
return Promise.resolve({"success": false, "msg": `Not found Webhooks to execute for event '${job.data.eventType}'`});
|
||||
}
|
||||
|
||||
|
||||
var provision = (job.data && job.data.provId)? await db.provision.getById(job.data.provId) : undefined;
|
||||
|
||||
webhooks.forEach(wh => {
|
||||
|
||||
if ( wh.isEnabled && (!wh.scenario || job.data.scenario === wh.scenario ) ) {
|
||||
|
||||
const url = wh.url;
|
||||
const payload = {
|
||||
event: wh.eventType,
|
||||
scenario: job.data.scenario,
|
||||
data: provision
|
||||
};
|
||||
const headers = wh.headers;
|
||||
|
||||
try {
|
||||
|
||||
console.log(`ProcessorWebhook# Executing '${wh.name}' - POST to URL '${url}' and event '${wh.eventType}'` );
|
||||
console.log(`ProcessorWebhook# Payload: `, JSON.stringify(payload));
|
||||
|
||||
axios({
|
||||
url: url,
|
||||
method: "post",
|
||||
data: payload,
|
||||
httpsAgent: new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
}),
|
||||
headers: headers
|
||||
});
|
||||
|
||||
wh.lastExecResult = "OK";
|
||||
wh.lastExecPayload = JSON.stringify(payload);
|
||||
|
||||
} catch (error) {
|
||||
wh.lastExecResult = "NOK";
|
||||
|
||||
console.log(`ProcessorWebhook# ERROR!! Executing POST URL '${url}' and event '${wh.eventType}'`);
|
||||
|
||||
} finally {
|
||||
wh.lastExecTs = new Date();
|
||||
wh.save();
|
||||
}
|
||||
} else {
|
||||
console.log(`ProcessorWebhook# - Do nothing`);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
console.log(`ProcessorWebhook# '${job.data.eventType}' DONE!!` );
|
||||
return Promise.resolve({"success": true, "msg": "done!"});
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@ const config = require('./config');
|
||||
// set up database for express session
|
||||
const MongoStore = require('connect-mongo')(expressSession);
|
||||
const mongoose = require('mongoose');
|
||||
const db = require("qmi-cloud-common/mongo");
|
||||
const db = require("@QMI/qmi-cloud-common/mongo");
|
||||
const axios = require('axios');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
@@ -8,7 +8,7 @@ const utils = require('./utils');
|
||||
// set up database for express session
|
||||
const MongoStore = require('connect-mongo')(expressSession);
|
||||
const mongoose = require('mongoose');
|
||||
const db = require("qmi-cloud-common/mongo");
|
||||
const db = require("@QMI/qmi-cloud-common/mongo");
|
||||
|
||||
const sessionStore = config.useMongoDBSessionStore? new MongoStore({
|
||||
mongooseConnection: mongoose.connection,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const db = require('@QMI/qmi-cloud-common/mongo');
|
||||
const passport = require('../passport-okta');
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const express = require('express')
|
||||
const router = express.Router()
|
||||
|
||||
const qmiConfig = require('qmi-cloud-common/qmi-config').qmiConfig;
|
||||
const qmiConfig = require('@QMI/qmi-cloud-common/qmi-config').qmiConfig;
|
||||
|
||||
router.get('/', async (req, res, next) => {
|
||||
try {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const express = require('express')
|
||||
const router = express.Router()
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const db = require('@QMI/qmi-cloud-common/mongo');
|
||||
const passport = require('../passport-okta');
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const express = require('express')
|
||||
const router = express.Router()
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const db = require('@QMI/qmi-cloud-common/mongo');
|
||||
const passport = require('../passport-okta');
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const divvy = require('qmi-cloud-common/divvy');
|
||||
const divvy = require('@QMI/qmi-cloud-common/divvy');
|
||||
const passport = require('../passport-okta');
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const db = require('@QMI/qmi-cloud-common/mongo');
|
||||
const passport = require('../passport-okta');
|
||||
const sendEmail = require('qmi-cloud-common/send-email');
|
||||
const sendEmail = require('@QMI/qmi-cloud-common/send-email');
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
const express = require('express')
|
||||
const router = express.Router()
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const db = require('@QMI/qmi-cloud-common/mongo');
|
||||
const passport = require('../passport-okta');
|
||||
const fs = require('fs-extra');
|
||||
const cli = require('qmi-cloud-common/cli');
|
||||
const cli = require('@QMI/qmi-cloud-common/cli');
|
||||
|
||||
|
||||
const MYQUEUES = require('qmi-cloud-common/queues');
|
||||
const MYQUEUES = require('@QMI/qmi-cloud-common/queues');
|
||||
const queues = MYQUEUES.queues;
|
||||
const SYNAPSE_QUEUE = MYQUEUES.SYNAPSE_QUEUE;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const express = require('express')
|
||||
const router = express.Router()
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const db = require('@QMI/qmi-cloud-common/mongo');
|
||||
const passport = require('../passport-okta');
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const db = require('@QMI/qmi-cloud-common/mongo');
|
||||
const passport = require('../passport-okta');
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const express = require('express')
|
||||
const router = express.Router()
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const db = require('@QMI/qmi-cloud-common/mongo');
|
||||
const moment = require('moment');
|
||||
const azurecli = require('qmi-cloud-common/azurecli');
|
||||
const azurecli = require('@QMI/qmi-cloud-common/azurecli');
|
||||
|
||||
const CACHED_PERIOD = 30; //minutes
|
||||
var cachedTime;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const db = require('@QMI/qmi-cloud-common/mongo');
|
||||
const passport = require('../passport-okta');
|
||||
const cloudshare = require('../training/cloudshare');
|
||||
const qa = require('../training/automations');
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
const express = require('express')
|
||||
const router = express.Router()
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const db = require('@QMI/qmi-cloud-common/mongo');
|
||||
const passport = require('../passport-okta');
|
||||
const fs = require('fs-extra');
|
||||
const cli = require('qmi-cloud-common/cli');
|
||||
const barracuda = require("qmi-cloud-common/barracuda");
|
||||
const sendEmail = require("qmi-cloud-common/send-email");
|
||||
const cli = require('@QMI/qmi-cloud-common/cli');
|
||||
const sendEmail = require("@QMI/qmi-cloud-common/send-email");
|
||||
const requestIp = require('request-ip');
|
||||
const utils = require('../utils');
|
||||
var qmiConfig = require('qmi-cloud-common/qmi-config').qmiConfig;
|
||||
var qmiConfig = require('@QMI/qmi-cloud-common/qmi-config').qmiConfig;
|
||||
|
||||
|
||||
async function asyncForEach(array, callback) {
|
||||
@@ -17,7 +16,7 @@ async function asyncForEach(array, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
const MYQUEUES = require('qmi-cloud-common/queues');
|
||||
const MYQUEUES = require('@QMI/qmi-cloud-common/queues');
|
||||
const queues = MYQUEUES.queues;
|
||||
const TF_APPLY_QUEUE = MYQUEUES.TF_APPLY_QUEUE;
|
||||
const TF_APPLY_QSEOK_QUEUE = MYQUEUES.TF_APPLY_QSEOK_QUEUE;
|
||||
@@ -500,7 +499,6 @@ router.delete('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, as
|
||||
});
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /users/{userId}/provisions/{id}/barracuda:
|
||||
* get:
|
||||
* description: Barracuda - get details and provision status
|
||||
@@ -523,7 +521,7 @@ router.delete('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, as
|
||||
* description: Not found
|
||||
*
|
||||
*/
|
||||
router.get('/:userId/provisions/:id/barracuda', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
|
||||
/*router.get('/:userId/provisions/:id/barracuda', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
|
||||
try {
|
||||
|
||||
let provision = await db.provision.getById(req.params.id);
|
||||
@@ -542,10 +540,9 @@ router.delete('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, as
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
});*/
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /users/{userId}/provisions/{id}/barracuda:
|
||||
* post:
|
||||
* description: Barracuda - give a provision external access
|
||||
@@ -568,7 +565,7 @@ router.delete('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, as
|
||||
* description: Not found
|
||||
*
|
||||
*/
|
||||
router.post('/:userId/provisions/:id/barracuda', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
|
||||
/*router.post('/:userId/provisions/:id/barracuda', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
|
||||
try {
|
||||
|
||||
let provision = await db.provision.getById(req.params.id);
|
||||
@@ -594,10 +591,9 @@ router.delete('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, as
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
});*/
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /users/{userId}/provisions/{id}/barracuda:
|
||||
* delete:
|
||||
* description: Barracuda - delete a provision external access
|
||||
@@ -620,7 +616,7 @@ router.delete('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, as
|
||||
* description: Not found
|
||||
*
|
||||
*/
|
||||
router.delete('/:userId/provisions/:id/barracuda', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
|
||||
/*router.delete('/:userId/provisions/:id/barracuda', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
|
||||
try {
|
||||
|
||||
let provision = await db.provision.getById(req.params.id);
|
||||
@@ -642,7 +638,7 @@ router.delete('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, as
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
});*/
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const db = require('@QMI/qmi-cloud-common/mongo');
|
||||
const passport = require('../passport-okta');
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ const { createProxyMiddleware } = require('http-proxy-middleware');
|
||||
|
||||
const Arena = require('bull-arena');
|
||||
|
||||
const MYQUEUES = require('qmi-cloud-common/queues');
|
||||
const MYQUEUES = require('@QMI/qmi-cloud-common/queues');
|
||||
const TF_APPLY_QUEUE = MYQUEUES.TF_APPLY_QUEUE;
|
||||
const TF_APPLY_QSEOK_QUEUE = MYQUEUES.TF_APPLY_QSEOK_QUEUE;
|
||||
const TF_DESTROY_QUEUE = MYQUEUES.TF_DESTROY_QUEUE;
|
||||
|
||||
543
yarn.lock
543
yarn.lock
@@ -2,6 +2,23 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@QMI/qmi-cloud-common@2.0.3":
|
||||
version "2.0.3"
|
||||
resolved "https://gitlab.com/api/v4/projects/15526459/packages/npm/@QMI/qmi-cloud-common/-/@QMI/qmi-cloud-common-2.0.3.tgz#dfd255257817fafab2e2e502b41515308675a020"
|
||||
integrity sha1-39JVJXgX+vqy4uUCtBUVMIZ1oCA=
|
||||
dependencies:
|
||||
"@aws-sdk/client-ec2" "^3.590.0"
|
||||
"@aws-sdk/client-rds" "^3.590.0"
|
||||
"@azure/arm-compute" "^22.3.0"
|
||||
"@azure/arm-dns" "^5.1.0"
|
||||
"@azure/identity" "^1.5.1"
|
||||
"@hapi/boom" "^9.1.0"
|
||||
axios "^1.7.2"
|
||||
bull "^3.11.0"
|
||||
mongoose "^8.4.1"
|
||||
nodemailer "^6.4.2"
|
||||
uuid "^8.3.2"
|
||||
|
||||
"@ampproject/remapping@^2.2.0":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4"
|
||||
@@ -929,15 +946,6 @@
|
||||
"@azure/core-rest-pipeline" "^1.8.0"
|
||||
tslib "^2.2.0"
|
||||
|
||||
"@azure/core-auth@^1.1.4":
|
||||
version "1.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.7.2.tgz#558b7cb7dd12b00beec07ae5df5907d74df1ebd9"
|
||||
integrity sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==
|
||||
dependencies:
|
||||
"@azure/abort-controller" "^2.0.0"
|
||||
"@azure/core-util" "^1.1.0"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/core-auth@^1.3.0", "@azure/core-auth@^1.4.0", "@azure/core-auth@^1.6.0", "@azure/core-auth@^1.8.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.9.0.tgz#ac725b03fabe3c892371065ee9e2041bee0fd1ac"
|
||||
@@ -947,7 +955,7 @@
|
||||
"@azure/core-util" "^1.11.0"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/core-client@^1.6.1", "@azure/core-client@^1.7.0":
|
||||
"@azure/core-client@^1.0.0", "@azure/core-client@^1.6.1", "@azure/core-client@^1.7.0":
|
||||
version "1.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@azure/core-client/-/core-client-1.9.2.tgz#6fc69cee2816883ab6c5cdd653ee4f2ff9774f74"
|
||||
integrity sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w==
|
||||
@@ -977,7 +985,7 @@
|
||||
dependencies:
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/core-rest-pipeline@^1.14.0", "@azure/core-rest-pipeline@^1.8.0", "@azure/core-rest-pipeline@^1.9.1":
|
||||
"@azure/core-rest-pipeline@^1.1.0", "@azure/core-rest-pipeline@^1.14.0", "@azure/core-rest-pipeline@^1.8.0", "@azure/core-rest-pipeline@^1.9.1":
|
||||
version "1.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.19.0.tgz#4cc60d3f2ee68cf0ef379851b4ed175f7932c8c5"
|
||||
integrity sha512-bM3308LRyg5g7r3Twprtqww0R/r7+GyVxj4BafcmVPo4WQoGt5JXuaqxHEFjw2o3rvFZcUPiqJMg6WuvEEeVUA==
|
||||
@@ -991,6 +999,14 @@
|
||||
https-proxy-agent "^7.0.0"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/core-tracing@1.0.0-preview.12":
|
||||
version "1.0.0-preview.12"
|
||||
resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.12.tgz#f53ff452c0742ad981c244f97d93d37ca2b5e139"
|
||||
integrity sha512-nvo2Wc4EKZGN6eFu9n3U7OXmASmL8VxoPIH7xaD6OlQqi44bouF0YIi9ID5rEsKLiAU59IYx6M297nqWVMWPDg==
|
||||
dependencies:
|
||||
"@opentelemetry/api" "^1.0.0"
|
||||
tslib "^2.2.0"
|
||||
|
||||
"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.2.0.tgz#7be5d53c3522d639cf19042cbcdb19f71bc35ab2"
|
||||
@@ -998,14 +1014,6 @@
|
||||
dependencies:
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/core-util@^1.1.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.9.0.tgz#469afd7e6452d5388b189f90d33f7756b0b210d1"
|
||||
integrity sha512-AfalUQ1ZppaKuxPPMsFEUdX6GZPB3d9paR9d/TTL7Ow2De8cJaC7ibi7kWVlFAVPCYo31OcnGymc0R89DX8Oaw==
|
||||
dependencies:
|
||||
"@azure/abort-controller" "^2.0.0"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/core-util@^1.11.0", "@azure/core-util@^1.2.0", "@azure/core-util@^1.6.1":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.11.0.tgz#f530fc67e738aea872fbdd1cc8416e70219fada7"
|
||||
@@ -1014,6 +1022,30 @@
|
||||
"@azure/abort-controller" "^2.0.0"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/identity@^1.5.1":
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/@azure/identity/-/identity-1.5.2.tgz#09da6aa8e14f2dace3dd8f66de7d7d56bfee5db7"
|
||||
integrity sha512-vqyeRbd2i0h9F4mqW5JbkP1xfabqKQ21l/81osKhpOQ2LtwaJW6nw4+0PsVYnxcbPHFCIZt6EWAk74a3OGYZJA==
|
||||
dependencies:
|
||||
"@azure/core-auth" "^1.3.0"
|
||||
"@azure/core-client" "^1.0.0"
|
||||
"@azure/core-rest-pipeline" "^1.1.0"
|
||||
"@azure/core-tracing" "1.0.0-preview.12"
|
||||
"@azure/logger" "^1.0.0"
|
||||
"@azure/msal-node" "1.0.0-beta.6"
|
||||
"@types/stoppable" "^1.1.0"
|
||||
axios "^0.21.1"
|
||||
events "^3.0.0"
|
||||
jws "^4.0.0"
|
||||
msal "^1.0.2"
|
||||
open "^7.0.0"
|
||||
qs "^6.7.0"
|
||||
stoppable "^1.1.0"
|
||||
tslib "^2.0.0"
|
||||
uuid "^8.3.0"
|
||||
optionalDependencies:
|
||||
keytar "^7.3.0"
|
||||
|
||||
"@azure/logger@^1.0.0":
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.1.4.tgz#223cbf2b424dfa66478ce9a4f575f59c6f379768"
|
||||
@@ -1021,33 +1053,22 @@
|
||||
dependencies:
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@azure/ms-rest-azure-env@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@azure/ms-rest-azure-env/-/ms-rest-azure-env-2.0.0.tgz#45809f89763a480924e21d3c620cd40866771625"
|
||||
integrity sha512-dG76W7ElfLi+fbTjnZVGj+M9e0BIEJmRxU6fHaUQ12bZBe8EJKYb2GV50YWNaP2uJiVQ5+7nXEVj1VN1UQtaEw==
|
||||
|
||||
"@azure/ms-rest-js@^2.0.4":
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@azure/ms-rest-js/-/ms-rest-js-2.7.0.tgz#8639065577ffdf4946951e1d246334ebfd72d537"
|
||||
integrity sha512-ngbzWbqF+NmztDOpLBVDxYM+XLcUj7nKhxGbSU9WtIsXfRB//cf2ZbAG5HkOrhU9/wd/ORRB6lM/d69RKVjiyA==
|
||||
"@azure/msal-common@^4.0.0":
|
||||
version "4.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-4.5.1.tgz#f35af8b634ae24aebd0906deb237c0db1afa5826"
|
||||
integrity sha512-/i5dXM+QAtO+6atYd5oHGBAx48EGSISkXNXViheliOQe+SIFMDo3gSq3lL54W0suOSAsVPws3XnTaIHlla0PIQ==
|
||||
dependencies:
|
||||
"@azure/core-auth" "^1.1.4"
|
||||
abort-controller "^3.0.0"
|
||||
form-data "^2.5.0"
|
||||
node-fetch "^2.6.7"
|
||||
tslib "^1.10.0"
|
||||
tunnel "0.0.6"
|
||||
uuid "^8.3.2"
|
||||
xml2js "^0.5.0"
|
||||
debug "^4.1.1"
|
||||
|
||||
"@azure/ms-rest-nodeauth@^3.1.1":
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@azure/ms-rest-nodeauth/-/ms-rest-nodeauth-3.1.1.tgz#2624222f0685ae580801d6f1abeab20923814693"
|
||||
integrity sha512-UA/8dgLy3+ZiwJjAZHxL4MUB14fFQPkaAOZ94jsTW/Z6WmoOeny2+cLk0+dyIX/iH6qSrEWKwbStEeB970B9pA==
|
||||
"@azure/msal-node@1.0.0-beta.6":
|
||||
version "1.0.0-beta.6"
|
||||
resolved "https://registry.yarnpkg.com/@azure/msal-node/-/msal-node-1.0.0-beta.6.tgz#da6bc3a3a861057c85586055960e069f162548ee"
|
||||
integrity sha512-ZQI11Uz1j0HJohb9JZLRD8z0moVcPks1AFW4Q/Gcl67+QvH4aKEJti7fjCcipEEZYb/qzLSO8U6IZgPYytsiJQ==
|
||||
dependencies:
|
||||
"@azure/ms-rest-azure-env" "^2.0.0"
|
||||
"@azure/ms-rest-js" "^2.0.4"
|
||||
adal-node "^0.2.2"
|
||||
"@azure/msal-common" "^4.0.0"
|
||||
axios "^0.21.1"
|
||||
jsonwebtoken "^8.5.1"
|
||||
uuid "^8.3.0"
|
||||
|
||||
"@babel/code-frame@^7.24.7", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3":
|
||||
version "7.24.7"
|
||||
@@ -1902,6 +1923,11 @@
|
||||
rxjs "6.5.3"
|
||||
webpack-sources "1.4.3"
|
||||
|
||||
"@opentelemetry/api@^1.0.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe"
|
||||
integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==
|
||||
|
||||
"@schematics/angular@9.0.7":
|
||||
version "9.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.7.tgz#e09ab998c2b3aa7269d91378b08a0fbca5037ea6"
|
||||
@@ -2434,6 +2460,13 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.6.tgz#164e169dd061795b50b83c19e4d3be09f8d3a454"
|
||||
integrity sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g==
|
||||
|
||||
"@types/stoppable@^1.1.0":
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/stoppable/-/stoppable-1.1.3.tgz#2cc4bd15594a9ad61f4d396d88594d7678f0b561"
|
||||
integrity sha512-7wGKIBJGE4ZxFjk9NkjAxZMLlIXroETqP1FJCdoSvKmEznwmBxQFmTB1dsCkAvVcNemuSZM5qkkd9HE/NL2JTw==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/webidl-conversions@*":
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz#1306dbfa53768bcbcfc95a1c8cde367975581859"
|
||||
@@ -2609,11 +2642,6 @@
|
||||
"@webassemblyjs/wast-parser" "1.8.5"
|
||||
"@xtuc/long" "4.2.2"
|
||||
|
||||
"@xmldom/xmldom@^0.8.3":
|
||||
version "0.8.10"
|
||||
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99"
|
||||
integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==
|
||||
|
||||
"@xtuc/ieee754@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
||||
@@ -2637,13 +2665,6 @@ JSONStream@^1.3.4:
|
||||
jsonparse "^1.2.0"
|
||||
through ">=2.2.7 <3"
|
||||
|
||||
abort-controller@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
|
||||
integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
|
||||
dependencies:
|
||||
event-target-shim "^5.0.0"
|
||||
|
||||
accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
|
||||
@@ -2674,20 +2695,6 @@ adal-angular@^1.0.17:
|
||||
resolved "https://registry.yarnpkg.com/adal-angular/-/adal-angular-1.0.18.tgz#51cee7e408b5fe6a105740da73cab9be16e26fb4"
|
||||
integrity sha512-X24lNbv3H8mjevnWxy2n6SLKN/kAQbg6b9xM9sqBwXBTobhArMaUHy3hd5xwSFMu8wiTu8A5Z52T56i7NqBoxA==
|
||||
|
||||
adal-node@^0.2.2:
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/adal-node/-/adal-node-0.2.4.tgz#881beed9d493b76a86706ad5c8dc6f60eff04520"
|
||||
integrity sha512-zIcvbwQFKMUtKxxj8YMHeTT1o/TPXfVNsTXVgXD8sxwV6h4AFQgK77dRciGhuEF9/Sdm3UQPJVPc/6XxrccSeA==
|
||||
dependencies:
|
||||
"@xmldom/xmldom" "^0.8.3"
|
||||
async "^2.6.3"
|
||||
axios "^0.21.1"
|
||||
date-utils "*"
|
||||
jws "3.x.x"
|
||||
underscore ">= 1.3.1"
|
||||
uuid "^3.1.0"
|
||||
xpath.js "~1.1.0"
|
||||
|
||||
adm-zip@^0.5.2:
|
||||
version "0.5.14"
|
||||
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.14.tgz#2c557c0bf12af4311cf6d32970f4060cf8133b2a"
|
||||
@@ -3268,7 +3275,7 @@ async-limiter@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
|
||||
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
|
||||
|
||||
async@^2.5.0, async@^2.6.2, async@^2.6.3, async@^2.6.4:
|
||||
async@^2.5.0, async@^2.6.2, async@^2.6.4:
|
||||
version "2.6.4"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
|
||||
integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
|
||||
@@ -3372,12 +3379,6 @@ balanced-match@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
"barracuda-api@https://gitlab.com/qlik_gear/barracuda-api-node.git#1.1.0":
|
||||
version "0.0.10"
|
||||
resolved "https://gitlab.com/qlik_gear/barracuda-api-node.git#ce8be42102398a45bf896cf973290b46d2e18666"
|
||||
dependencies:
|
||||
axios "^0.21.1"
|
||||
|
||||
base64-arraybuffer@0.1.5:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
|
||||
@@ -3464,6 +3465,15 @@ bl@^2.2.1:
|
||||
readable-stream "^2.3.5"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
bl@^4.0.3:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
|
||||
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
|
||||
dependencies:
|
||||
buffer "^5.5.0"
|
||||
inherits "^2.0.4"
|
||||
readable-stream "^3.4.0"
|
||||
|
||||
blob@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683"
|
||||
@@ -3740,7 +3750,7 @@ buffer@^4.3.0:
|
||||
ieee754 "^1.1.4"
|
||||
isarray "^1.0.0"
|
||||
|
||||
buffer@^5.6.0:
|
||||
buffer@^5.5.0, buffer@^5.6.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
|
||||
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
|
||||
@@ -3865,6 +3875,14 @@ cache-base@^1.0.1:
|
||||
union-value "^1.0.0"
|
||||
unset-value "^1.0.0"
|
||||
|
||||
call-bind-apply-helpers@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz#32e5892e6361b29b0b545ba6f7763378daca2840"
|
||||
integrity sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==
|
||||
dependencies:
|
||||
es-errors "^1.3.0"
|
||||
function-bind "^1.1.2"
|
||||
|
||||
call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
|
||||
@@ -3876,6 +3894,14 @@ call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bin
|
||||
get-intrinsic "^1.2.4"
|
||||
set-function-length "^1.2.1"
|
||||
|
||||
call-bound@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.3.tgz#41cfd032b593e39176a71533ab4f384aa04fd681"
|
||||
integrity sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==
|
||||
dependencies:
|
||||
call-bind-apply-helpers "^1.0.1"
|
||||
get-intrinsic "^1.2.6"
|
||||
|
||||
call-me-maybe@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz#03f964f19522ba643b1b0693acb9152fe2074baa"
|
||||
@@ -5066,11 +5092,6 @@ date-format@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/date-format/-/date-format-1.2.0.tgz#615e828e233dd1ab9bb9ae0950e0ceccfa6ecad8"
|
||||
integrity sha512-lAJqBmFzCLcDJdI9cEnJ7loSkLTh1PbIgZUndlzvYbf6NyFEr5n9rQhOwr6CIGwZqyQ3sYeQQiP9NOVQmgmRMA==
|
||||
|
||||
date-utils@*:
|
||||
version "1.2.21"
|
||||
resolved "https://registry.yarnpkg.com/date-utils/-/date-utils-1.2.21.tgz#61fb16cdc1274b3c9acaaffe9fc69df8720a2b64"
|
||||
integrity sha512-wJMBjqlwXR0Iv0wUo/lFbhSQ7MmG1hl36iuxuE91kW+5b5sWbase73manEqNH9sOLFAMG83B4ffNKq9/Iq0FVA==
|
||||
|
||||
date.js@^0.3.1:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/date.js/-/date.js-0.3.3.tgz#ef1e92332f507a638795dbb985e951882e50bbda"
|
||||
@@ -5135,6 +5156,13 @@ decode-uri-component@^0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
|
||||
integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==
|
||||
|
||||
decompress-response@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
|
||||
integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==
|
||||
dependencies:
|
||||
mimic-response "^3.1.0"
|
||||
|
||||
deep-equal@^1.0.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.2.tgz#78a561b7830eef3134c7f6f3a3d6af272a678761"
|
||||
@@ -5290,6 +5318,11 @@ destroy@1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
|
||||
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
|
||||
|
||||
detect-libc@^2.0.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700"
|
||||
integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==
|
||||
|
||||
detect-node@^2.0.4:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
|
||||
@@ -5416,6 +5449,15 @@ drag-tracker@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/drag-tracker/-/drag-tracker-1.0.0.tgz#9bd33d380bc3056db69bd5b3cf6e062fec58bd64"
|
||||
integrity sha512-BSGDl37YXpW49dLMRfiDExxzD3yPOpLEBGx05Wed3z2sk2+Qd5dFvHCSVFTPsGTeltGBtkRB4qhLhSKv6tvBKw==
|
||||
|
||||
dunder-proto@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
|
||||
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
|
||||
dependencies:
|
||||
call-bind-apply-helpers "^1.0.1"
|
||||
es-errors "^1.3.0"
|
||||
gopd "^1.2.0"
|
||||
|
||||
duplexer3@^0.1.4:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e"
|
||||
@@ -5511,7 +5553,7 @@ encoding@^0.1.11:
|
||||
dependencies:
|
||||
iconv-lite "^0.6.2"
|
||||
|
||||
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
||||
end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
|
||||
@@ -5679,6 +5721,11 @@ es-define-property@^1.0.0:
|
||||
dependencies:
|
||||
get-intrinsic "^1.2.4"
|
||||
|
||||
es-define-property@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
|
||||
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
|
||||
|
||||
es-errors@^1.0.0, es-errors@^1.2.1, es-errors@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
|
||||
@@ -5781,11 +5828,6 @@ etag@~1.8.1:
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
|
||||
|
||||
event-target-shim@^5.0.0:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
|
||||
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
|
||||
|
||||
eventemitter3@^4.0.0:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
@@ -5870,6 +5912,11 @@ expand-range@^0.1.0:
|
||||
is-number "^0.1.1"
|
||||
repeat-string "^0.2.2"
|
||||
|
||||
expand-template@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"
|
||||
integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==
|
||||
|
||||
express-handlebars@^5.1.0:
|
||||
version "5.3.5"
|
||||
resolved "https://registry.yarnpkg.com/express-handlebars/-/express-handlebars-5.3.5.tgz#a04a1e670aa97d5b3a8080de8336f79228593540"
|
||||
@@ -6201,15 +6248,6 @@ forever-agent@~0.6.1:
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==
|
||||
|
||||
form-data@^2.5.0:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
|
||||
integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
form-data@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
|
||||
@@ -6260,6 +6298,11 @@ fs-access@^1.0.0:
|
||||
dependencies:
|
||||
null-check "^1.0.0"
|
||||
|
||||
fs-constants@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
|
||||
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
|
||||
|
||||
fs-exists-sync@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add"
|
||||
@@ -6381,6 +6424,22 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@
|
||||
has-symbols "^1.0.3"
|
||||
hasown "^2.0.0"
|
||||
|
||||
get-intrinsic@^1.2.5, get-intrinsic@^1.2.6:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.7.tgz#dcfcb33d3272e15f445d15124bc0a216189b9044"
|
||||
integrity sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==
|
||||
dependencies:
|
||||
call-bind-apply-helpers "^1.0.1"
|
||||
es-define-property "^1.0.1"
|
||||
es-errors "^1.3.0"
|
||||
es-object-atoms "^1.0.0"
|
||||
function-bind "^1.1.2"
|
||||
get-proto "^1.0.0"
|
||||
gopd "^1.2.0"
|
||||
has-symbols "^1.1.0"
|
||||
hasown "^2.0.2"
|
||||
math-intrinsics "^1.1.0"
|
||||
|
||||
get-object@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/get-object/-/get-object-0.2.0.tgz#d92ff7d5190c64530cda0543dac63a3d47fe8c0c"
|
||||
@@ -6394,6 +6453,14 @@ get-port@^5.1.1:
|
||||
resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193"
|
||||
integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==
|
||||
|
||||
get-proto@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
|
||||
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
|
||||
dependencies:
|
||||
dunder-proto "^1.0.1"
|
||||
es-object-atoms "^1.0.0"
|
||||
|
||||
get-stream@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
|
||||
@@ -6432,6 +6499,11 @@ getpass@^0.1.1:
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
github-from-package@0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
|
||||
integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==
|
||||
|
||||
gl-matrix@^3.2.1:
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.4.3.tgz#fc1191e8320009fd4d20e9339595c6041ddc22c9"
|
||||
@@ -6562,6 +6634,11 @@ gopd@^1.0.1:
|
||||
dependencies:
|
||||
get-intrinsic "^1.1.3"
|
||||
|
||||
gopd@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
|
||||
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
|
||||
|
||||
got@^6.7.1:
|
||||
version "6.7.1"
|
||||
resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
|
||||
@@ -6734,6 +6811,11 @@ has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3:
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
|
||||
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
|
||||
|
||||
has-symbols@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
|
||||
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
|
||||
|
||||
has-tostringtag@^1.0.0, has-tostringtag@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
|
||||
@@ -7697,7 +7779,7 @@ is-wsl@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
|
||||
integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==
|
||||
|
||||
is-wsl@^2.1.0:
|
||||
is-wsl@^2.1.0, is-wsl@^2.1.1:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
|
||||
integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
|
||||
@@ -8074,7 +8156,16 @@ jwa@^1.4.1:
|
||||
ecdsa-sig-formatter "1.0.11"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
jws@3.x.x, jws@^3.2.2:
|
||||
jwa@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc"
|
||||
integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==
|
||||
dependencies:
|
||||
buffer-equal-constant-time "1.0.1"
|
||||
ecdsa-sig-formatter "1.0.11"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
jws@^3.2.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
|
||||
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
|
||||
@@ -8082,6 +8173,14 @@ jws@3.x.x, jws@^3.2.2:
|
||||
jwa "^1.4.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
jws@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4"
|
||||
integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==
|
||||
dependencies:
|
||||
jwa "^2.0.0"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
kareem@2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.5.1.tgz#7b8203e11819a8e77a34b3517d3ead206764d15d"
|
||||
@@ -8172,6 +8271,14 @@ kdbush@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-3.0.0.tgz#f8484794d47004cc2d85ed3a79353dbe0abc2bf0"
|
||||
integrity sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew==
|
||||
|
||||
keytar@^7.3.0:
|
||||
version "7.9.0"
|
||||
resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.9.0.tgz#4c6225708f51b50cbf77c5aae81721964c2918cb"
|
||||
integrity sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==
|
||||
dependencies:
|
||||
node-addon-api "^4.3.0"
|
||||
prebuild-install "^7.0.1"
|
||||
|
||||
killable@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
|
||||
@@ -8616,6 +8723,11 @@ marked@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-1.2.9.tgz#53786f8b05d4c01a2a5a76b7d1ec9943d29d72dc"
|
||||
integrity sha512-H8lIX2SvyitGX+TRdtS06m1jHMijKN/XjfH6Ooii9fvxMlh8QdqBfBDkGUpMWH2kQNrtixjzYUa3SH8ROTgRRw==
|
||||
|
||||
math-intrinsics@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
|
||||
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
|
||||
|
||||
md5.js@^1.3.4:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
|
||||
@@ -8754,6 +8866,11 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
||||
|
||||
mimic-response@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
|
||||
integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
|
||||
|
||||
mini-css-extract-plugin@0.8.0:
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz#81d41ec4fe58c713a96ad7c723cdb2d0bd4d70e1"
|
||||
@@ -8788,7 +8905,7 @@ minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.1.1:
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6:
|
||||
minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
|
||||
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
|
||||
@@ -8865,6 +8982,11 @@ mixin-deep@^1.2.0:
|
||||
for-in "^1.0.2"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
|
||||
version "0.5.3"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
|
||||
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
|
||||
|
||||
mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@^0.5.6, mkdirp@~0.5.1, mkdirp@~0.5.x:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
|
||||
@@ -9011,6 +9133,13 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1, ms@^2.1.3:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
msal@^1.0.2:
|
||||
version "1.4.18"
|
||||
resolved "https://registry.yarnpkg.com/msal/-/msal-1.4.18.tgz#2e626d2b986a388a1ed7736eb346cce6b6e97e5f"
|
||||
integrity sha512-QyWMWrZqpwtK6LEqhwtbikxIWqA1EOcdMvDeIDjIXdGU29wM4orwq538sPe1+JfKDIgPmJj1Fgi5B7luaw/IyA==
|
||||
dependencies:
|
||||
tslib "^1.9.3"
|
||||
|
||||
multicast-dns-service-types@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901"
|
||||
@@ -9056,6 +9185,11 @@ nanomatch@^1.2.9:
|
||||
snapdragon "^0.8.1"
|
||||
to-regex "^3.0.1"
|
||||
|
||||
napi-build-utils@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-2.0.0.tgz#13c22c0187fcfccce1461844136372a47ddc027e"
|
||||
integrity sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==
|
||||
|
||||
negotiator@0.6.3:
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
|
||||
@@ -9082,6 +9216,18 @@ nice-try@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
node-abi@^3.3.0:
|
||||
version "3.74.0"
|
||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.74.0.tgz#5bfb4424264eaeb91432d2adb9da23c63a301ed0"
|
||||
integrity sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==
|
||||
dependencies:
|
||||
semver "^7.3.5"
|
||||
|
||||
node-addon-api@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f"
|
||||
integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==
|
||||
|
||||
node-fetch-npm@^2.0.2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz#6507d0e17a9ec0be3bec516958a497cec54bf5a4"
|
||||
@@ -9091,13 +9237,6 @@ node-fetch-npm@^2.0.2:
|
||||
json-parse-better-errors "^1.0.0"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
node-fetch@^2.6.7:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
|
||||
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
|
||||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-forge@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
|
||||
@@ -9326,6 +9465,11 @@ object-inspect@^1.13.1:
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2"
|
||||
integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==
|
||||
|
||||
object-inspect@^1.13.3:
|
||||
version "1.13.4"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213"
|
||||
integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==
|
||||
|
||||
object-is@^1.1.5:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07"
|
||||
@@ -9438,6 +9582,14 @@ open@7.0.0:
|
||||
dependencies:
|
||||
is-wsl "^2.1.0"
|
||||
|
||||
open@^7.0.0:
|
||||
version "7.4.2"
|
||||
resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321"
|
||||
integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==
|
||||
dependencies:
|
||||
is-docker "^2.0.0"
|
||||
is-wsl "^2.1.1"
|
||||
|
||||
opn@^5.5.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc"
|
||||
@@ -10210,6 +10362,24 @@ potpack@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/potpack/-/potpack-1.0.2.tgz#23b99e64eb74f5741ffe7656b5b5c4ddce8dfc14"
|
||||
integrity sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==
|
||||
|
||||
prebuild-install@^7.0.1:
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.3.tgz#d630abad2b147443f20a212917beae68b8092eec"
|
||||
integrity sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==
|
||||
dependencies:
|
||||
detect-libc "^2.0.0"
|
||||
expand-template "^2.0.3"
|
||||
github-from-package "0.0.0"
|
||||
minimist "^1.2.3"
|
||||
mkdirp-classic "^0.5.3"
|
||||
napi-build-utils "^2.0.0"
|
||||
node-abi "^3.3.0"
|
||||
pump "^3.0.0"
|
||||
rc "^1.2.7"
|
||||
simple-get "^4.0.0"
|
||||
tar-fs "^2.0.0"
|
||||
tunnel-agent "^0.6.0"
|
||||
|
||||
prepend-http@^1.0.0, prepend-http@^1.0.1:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
|
||||
@@ -10450,22 +10620,6 @@ qjobs@^1.1.4:
|
||||
resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071"
|
||||
integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==
|
||||
|
||||
qmi-cloud-common@./qmi-cloud-common:
|
||||
version "2.0.0"
|
||||
dependencies:
|
||||
"@aws-sdk/client-ec2" "^3.590.0"
|
||||
"@aws-sdk/client-rds" "^3.590.0"
|
||||
"@azure/arm-compute" "^22.3.0"
|
||||
"@azure/arm-dns" "^5.1.0"
|
||||
"@azure/ms-rest-nodeauth" "^3.1.1"
|
||||
"@hapi/boom" "^9.1.0"
|
||||
axios "^1.7.2"
|
||||
barracuda-api "https://gitlab.com/qlik_gear/barracuda-api-node.git#1.1.0"
|
||||
bull "^3.11.0"
|
||||
mongoose "^8.4.1"
|
||||
nodemailer "^6.4.2"
|
||||
uuid "^8.3.2"
|
||||
|
||||
qs@6.11.0:
|
||||
version "6.11.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
|
||||
@@ -10480,6 +10634,13 @@ qs@^6.11.2:
|
||||
dependencies:
|
||||
side-channel "^1.0.6"
|
||||
|
||||
qs@^6.7.0:
|
||||
version "6.14.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930"
|
||||
integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==
|
||||
dependencies:
|
||||
side-channel "^1.1.0"
|
||||
|
||||
qs@~6.5.2:
|
||||
version "6.5.3"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
|
||||
@@ -10551,7 +10712,7 @@ raw-loader@3.1.0:
|
||||
loader-utils "^1.1.0"
|
||||
schema-utils "^2.0.1"
|
||||
|
||||
rc@^1.0.1, rc@^1.1.6:
|
||||
rc@^1.0.1, rc@^1.1.6, rc@^1.2.7:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
||||
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
|
||||
@@ -10652,7 +10813,7 @@ read-package-tree@5.3.1:
|
||||
string_decoder "~1.1.1"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readable-stream@^3.0.6, readable-stream@^3.6.0:
|
||||
readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
|
||||
version "3.6.2"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
|
||||
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
|
||||
@@ -11216,6 +11377,11 @@ semver@^7.3.2:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13"
|
||||
integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==
|
||||
|
||||
semver@^7.3.5:
|
||||
version "7.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f"
|
||||
integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
|
||||
|
||||
send@0.18.0:
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
|
||||
@@ -11361,6 +11527,35 @@ shebang-regex@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
|
||||
integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==
|
||||
|
||||
side-channel-list@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad"
|
||||
integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==
|
||||
dependencies:
|
||||
es-errors "^1.3.0"
|
||||
object-inspect "^1.13.3"
|
||||
|
||||
side-channel-map@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42"
|
||||
integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==
|
||||
dependencies:
|
||||
call-bound "^1.0.2"
|
||||
es-errors "^1.3.0"
|
||||
get-intrinsic "^1.2.5"
|
||||
object-inspect "^1.13.3"
|
||||
|
||||
side-channel-weakmap@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea"
|
||||
integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==
|
||||
dependencies:
|
||||
call-bound "^1.0.2"
|
||||
es-errors "^1.3.0"
|
||||
get-intrinsic "^1.2.5"
|
||||
object-inspect "^1.13.3"
|
||||
side-channel-map "^1.0.1"
|
||||
|
||||
side-channel@^1.0.4, side-channel@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2"
|
||||
@@ -11371,6 +11566,17 @@ side-channel@^1.0.4, side-channel@^1.0.6:
|
||||
get-intrinsic "^1.2.4"
|
||||
object-inspect "^1.13.1"
|
||||
|
||||
side-channel@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9"
|
||||
integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==
|
||||
dependencies:
|
||||
es-errors "^1.3.0"
|
||||
object-inspect "^1.13.3"
|
||||
side-channel-list "^1.0.0"
|
||||
side-channel-map "^1.0.1"
|
||||
side-channel-weakmap "^1.0.2"
|
||||
|
||||
sift@16.0.1:
|
||||
version "16.0.1"
|
||||
resolved "https://registry.yarnpkg.com/sift/-/sift-16.0.1.tgz#e9c2ccc72191585008cf3e36fc447b2d2633a053"
|
||||
@@ -11386,6 +11592,20 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
|
||||
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
|
||||
|
||||
simple-concat@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
|
||||
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
|
||||
|
||||
simple-get@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543"
|
||||
integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==
|
||||
dependencies:
|
||||
decompress-response "^6.0.0"
|
||||
once "^1.3.1"
|
||||
simple-concat "^1.0.0"
|
||||
|
||||
simple-swizzle@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
|
||||
@@ -11745,6 +11965,11 @@ statuses@2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
|
||||
|
||||
stoppable@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/stoppable/-/stoppable-1.1.0.tgz#32da568e83ea488b08e4d7ea2c3bcc9d75015d5b"
|
||||
integrity sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==
|
||||
|
||||
stream-browserify@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"
|
||||
@@ -12070,6 +12295,27 @@ tapable@^1.0.0, tapable@^1.1.3:
|
||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
|
||||
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
|
||||
|
||||
tar-fs@^2.0.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.2.tgz#425f154f3404cb16cb8ff6e671d45ab2ed9596c5"
|
||||
integrity sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==
|
||||
dependencies:
|
||||
chownr "^1.1.1"
|
||||
mkdirp-classic "^0.5.2"
|
||||
pump "^3.0.0"
|
||||
tar-stream "^2.1.4"
|
||||
|
||||
tar-stream@^2.1.4:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
|
||||
integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
|
||||
dependencies:
|
||||
bl "^4.0.3"
|
||||
end-of-stream "^1.4.1"
|
||||
fs-constants "^1.0.0"
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^3.1.1"
|
||||
|
||||
tar@^4.4.10:
|
||||
version "4.4.19"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3"
|
||||
@@ -12281,11 +12527,6 @@ tr46@^4.1.1:
|
||||
dependencies:
|
||||
punycode "^2.3.0"
|
||||
|
||||
tr46@~0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
|
||||
|
||||
tree-kill@1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
|
||||
@@ -12310,12 +12551,12 @@ tslib@1.10.0:
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
|
||||
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
|
||||
|
||||
tslib@^1.10.0, tslib@^1.11.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0:
|
||||
tslib@^1.11.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2.2.0:
|
||||
tslib@^2.0.0, tslib@^2.2.0:
|
||||
version "2.8.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
|
||||
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
|
||||
@@ -12362,11 +12603,6 @@ tunnel-agent@^0.6.0:
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
tunnel@0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
|
||||
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
|
||||
|
||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||
version "0.14.5"
|
||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||
@@ -12498,11 +12734,6 @@ undefsafe@^2.0.2:
|
||||
resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c"
|
||||
integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==
|
||||
|
||||
"underscore@>= 1.3.1":
|
||||
version "1.13.6"
|
||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441"
|
||||
integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==
|
||||
|
||||
undici-types@~5.26.4:
|
||||
version "5.26.5"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
|
||||
@@ -12740,7 +12971,7 @@ utils-merge@1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
|
||||
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
|
||||
|
||||
uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0, uuid@^3.3.2:
|
||||
uuid@^3.0.0, uuid@^3.0.1, uuid@^3.3.2:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||
@@ -12883,11 +13114,6 @@ webdriver-manager@^12.0.6:
|
||||
semver "^5.3.0"
|
||||
xml2js "^0.4.17"
|
||||
|
||||
webidl-conversions@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
|
||||
|
||||
webidl-conversions@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
|
||||
@@ -13043,14 +13269,6 @@ whatwg-url@^13.0.0:
|
||||
tr46 "^4.1.1"
|
||||
webidl-conversions "^7.0.0"
|
||||
|
||||
whatwg-url@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
|
||||
dependencies:
|
||||
tr46 "~0.0.3"
|
||||
webidl-conversions "^3.0.0"
|
||||
|
||||
when@~3.6.x:
|
||||
version "3.6.4"
|
||||
resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e"
|
||||
@@ -13182,14 +13400,6 @@ xml2js@^0.4.17:
|
||||
sax ">=0.6.0"
|
||||
xmlbuilder "~11.0.0"
|
||||
|
||||
xml2js@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.5.0.tgz#d9440631fbb2ed800203fad106f2724f62c493b7"
|
||||
integrity sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==
|
||||
dependencies:
|
||||
sax ">=0.6.0"
|
||||
xmlbuilder "~11.0.0"
|
||||
|
||||
xmlbuilder@~11.0.0:
|
||||
version "11.0.1"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
|
||||
@@ -13200,11 +13410,6 @@ xmlhttprequest-ssl@~1.5.4:
|
||||
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"
|
||||
integrity sha512-/bFPLUgJrfGUL10AIv4Y7/CUt6so9CLtB/oFxQSHseSDNNCdC6vwwKEqwLN6wNPBg9YWXAiMu8jkf6RPRS/75Q==
|
||||
|
||||
xpath.js@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/xpath.js/-/xpath.js-1.1.0.tgz#3816a44ed4bb352091083d002a383dd5104a5ff1"
|
||||
integrity sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==
|
||||
|
||||
xtend@^4.0.0, xtend@~4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
|
||||
Reference in New Issue
Block a user