├── distrib └── .gitkeep ├── scripts ├── bin │ ├── startsap.sh │ └── stopsap.sh ├── provision │ ├── patch_install_script.sh │ ├── finalize.sh │ ├── install_nw.expect │ ├── add_disk.sh │ ├── post_install.sh │ ├── add_swap.sh │ ├── startup.sh │ ├── pre_install.sh │ └── install_nw.sh ├── install_addons.sh ├── addons │ ├── install_nodejs.sh │ ├── install_abapgit.sh │ └── install_ssl_certificates.sh └── service │ └── sapnw.service ├── abapdeploy.js ├── sample.abap ├── .gitignore ├── package.json ├── .eslintrc.json ├── abapdeploy.js └── package-lock.json ├── .gitignore ├── certinst.js ├── certificates │ ├── github1.cer │ ├── github2.cer │ ├── gitlab1.cer │ └── gitlab2.cer ├── .gitignore ├── package.json ├── .eslintrc.json ├── certinst.js └── package-lock.json ├── .gitattributes ├── patch.install.sh.diff ├── changelog.txt ├── Vagrantfile └── README.md /distrib/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scripts/bin/startsap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | sudo -i -u npladm startsap 3 | -------------------------------------------------------------------------------- /scripts/bin/stopsap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | sudo -i -u npladm stopsap 3 | -------------------------------------------------------------------------------- /abapdeploy.js/sample.abap: -------------------------------------------------------------------------------- 1 | report zmytest. 2 | 3 | write: / 'Hello world!'. 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # artefacts 2 | *.log 3 | .vagrant 4 | .vscode 5 | 6 | # distrib dir 7 | distrib/* 8 | !distrib/.gitkeep 9 | -------------------------------------------------------------------------------- /certinst.js/certificates/github1.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbcgua/sap-nw-abap-vagrant/HEAD/certinst.js/certificates/github1.cer -------------------------------------------------------------------------------- /certinst.js/certificates/github2.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbcgua/sap-nw-abap-vagrant/HEAD/certinst.js/certificates/github2.cer -------------------------------------------------------------------------------- /certinst.js/certificates/gitlab1.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbcgua/sap-nw-abap-vagrant/HEAD/certinst.js/certificates/gitlab1.cer -------------------------------------------------------------------------------- /certinst.js/certificates/gitlab2.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbcgua/sap-nw-abap-vagrant/HEAD/certinst.js/certificates/gitlab2.cer -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Shell files and service = LF 5 | *.sh text eol=lf 6 | *.service text eol=lf 7 | -------------------------------------------------------------------------------- /certinst.js/.gitignore: -------------------------------------------------------------------------------- 1 | # Artifacts 2 | node_modules 3 | 4 | # Testing 5 | coverage 6 | 7 | # Logs 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | 12 | # Misc 13 | ~$* 14 | .DS_Store 15 | .vscode 16 | playground.js 17 | -------------------------------------------------------------------------------- /abapdeploy.js/.gitignore: -------------------------------------------------------------------------------- 1 | # Artifacts 2 | node_modules 3 | 4 | # Testing 5 | coverage 6 | 7 | # Logs 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | 12 | # Misc 13 | ~$* 14 | .DS_Store 15 | .vscode 16 | playground.js 17 | -------------------------------------------------------------------------------- /scripts/provision/patch_install_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd /vagrant/ 4 | if [ -n "$(cat distrib/install.sh | grep 'SYBASE LICENSE COPY' )" ]; then 5 | echo "Seems the system configs already patched, skipping" 6 | exit 0 7 | fi 8 | 9 | patch distrib/install.sh patch.install.sh.diff 10 | -------------------------------------------------------------------------------- /scripts/install_addons.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Install nodejs 4 | sh /vagrant/scripts/addons/install_nodejs.sh 5 | 6 | # Install SSL certificates 7 | sudo -i -u vagrant /vagrant/scripts/addons/install_ssl_certificates.sh 8 | 9 | # Install abapGit 10 | sudo -i -u vagrant /vagrant/scripts/addons/install_abapgit.sh 11 | -------------------------------------------------------------------------------- /scripts/provision/finalize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Installation sequence complete" 4 | 5 | # Elapsed time calculation 6 | PROVISION_START_TS=`cat /tmp/provision-start.timestamp` 7 | PROVISION_END_TS=`date +%s` 8 | ELAPSED_TIME=$(($PROVISION_END_TS - $PROVISION_START_TS)) 9 | echo "Installation took $(($ELAPSED_TIME / 60)) minutes and $(($ELAPSED_TIME % 60)) seconds" 10 | -------------------------------------------------------------------------------- /scripts/provision/install_nw.expect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/expect -f 2 | spawn bash ./install.sh -s -k 3 | set PASSWORD "SapPwd1!" 4 | set timeout -1 5 | expect "Do you agree to the above license terms? yes/no:" 6 | send "yes\r" 7 | expect "Please enter a password:" 8 | send "$PASSWORD\r" 9 | expect "Please re-enter password for verification:" 10 | send "$PASSWORD\r" 11 | expect eof 12 | -------------------------------------------------------------------------------- /scripts/addons/install_nodejs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | node -v > /dev/null 2>&1 4 | if [ $? -ne 0 ]; then 5 | echo "Installing nodejs for further scripting..." 6 | # Adding nodejs source for after-installation scripts 7 | curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - 8 | sudo apt-get install -y -q nodejs 9 | echo "Nodejs installed:" `node -v` 10 | else 11 | echo "Nodejs detected:" `node -v` 12 | fi 13 | -------------------------------------------------------------------------------- /scripts/provision/add_disk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Preparing sybase disk ..." 4 | if [ -e /dev/disk/by-label/sybase ]; then 5 | echo " disk already added, skipping" 6 | exit 0 7 | fi 8 | 9 | echo 'start=2048, type=83' | sudo sfdisk -q /dev/sdc # TODO improve device detection 10 | sudo mkfs.ext4 -q -L sybase /dev/sdc1 11 | echo "LABEL=sybase /sybase ext4 noatime 0 0" | sudo tee -a /etc/fstab 12 | sudo mkdir /sybase 13 | sudo mount /sybase 14 | -------------------------------------------------------------------------------- /certinst.js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "certinst", 3 | "version": "1.0.0", 4 | "description": "certificate installator for NW752", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alexander Tsybulsky", 10 | "repository": "https://github.com/sbcgua/sap-nw-abap-vagrant", 11 | "license": "ISC", 12 | "dependencies": { 13 | "node-rfc": "^1.0.0-rc7" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /abapdeploy.js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "abapdeploy", 3 | "version": "1.0.0", 4 | "description": "abap progrmas installator for NW752", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alexander Tsybulsky", 10 | "repository": "https://github.com/sbcgua/sap-nw-abap-vagrant", 11 | "license": "ISC", 12 | "dependencies": { 13 | "abap-adt-api": "^0.5.17", 14 | "commander": "^2.20.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scripts/service/sapnw.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=SAP NW server 3 | After=network.target 4 | 5 | [Service] 6 | # delay start 7 | Type=idle 8 | # mark with this in syslog 9 | SyslogIdentifier=sapnw 10 | # Manual only 11 | Restart=no 12 | 13 | User=npladm 14 | WorkingDirectory=/home/npladm 15 | 16 | # csh needed for environment 17 | ExecStart=/bin/csh -c startsap 18 | ExecStop=/bin/csh -c stopsap 19 | RemainAfterExit=yes 20 | TimeoutStartSec=300 21 | TimeoutStopSec=300 22 | 23 | [Install] 24 | WantedBy=multi-user.target 25 | -------------------------------------------------------------------------------- /abapdeploy.js/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parserOptions": { 4 | "ecmaVersion": 2018, 5 | "sourceType": "module" 6 | }, 7 | "env": { 8 | "node": true, 9 | "jest": true, 10 | "es6": true 11 | }, 12 | "extends": [ 13 | "eslint:recommended" 14 | ], 15 | "rules": { 16 | "quotes": ["error", "single", { "avoidEscape": true }], 17 | "semi": ["error", "always", { "omitLastInOneLineBlock": true}], 18 | "no-console": "off", 19 | "indent": ["error", 4], 20 | "no-trailing-spaces": ["error"] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /scripts/provision/post_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Adjusting SAP profile - increasing workers number..." 4 | PROFILE_PATH=/sapmnt/NPL/profile/NPL_D00_vhcalnplci 5 | sudo cp $PROFILE_PATH $PROFILE_PATH.bak 6 | sudo sed -i -e 's/wp_no_dia = 2/wp_no_dia = 6/' $PROFILE_PATH 7 | 8 | DEFAULT_PROFILE_PATH=/sapmnt/NPL/profile/DEFAULT.PFL 9 | #ssl/ciphersuites = 135:PFS:HIGH::EC_P256:EC_HIGH 10 | #ssl/client_ciphersuites = 150:PFS:HIGH::EC_P256:EC_HIGH 11 | echo "ssl/client_sni_enabled = TRUE" >> $DEFAULT_PROFILE_PATH 12 | 13 | echo "SAP HARDWARE KEY" 14 | sudo -i -u npladm saplicense -get || true 15 | -------------------------------------------------------------------------------- /scripts/provision/add_swap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Adding swap ..." 4 | if [ -n "$(swapon --show)" ]; then 5 | echo " swap is already activated, skipping" 6 | exit 0 7 | fi 8 | 9 | # Creating swap file 10 | sudo fallocate -l 2G /swapfile # 2 gigabytes 11 | sudo chmod 600 /swapfile 12 | sudo mkswap /swapfile 13 | sudo swapon /swapfile 14 | echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab 15 | 16 | # Tune system params 17 | sudo sysctl vm.swappiness=10 18 | sudo sysctl vm.vfs_cache_pressure=50 19 | echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf 20 | echo "vm.vfs_cache_pressure = 50" | sudo tee -a /etc/sysctl.conf 21 | -------------------------------------------------------------------------------- /certinst.js/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 2017, 4 | "sourceType": "module", 5 | "ecmaFeatures": { 6 | "modules": true, 7 | "experimentalObjectRestSpread": true 8 | } 9 | }, 10 | "env": { 11 | "node": true, 12 | "jest": true, 13 | "es6": true 14 | }, 15 | "extends": [ 16 | "eslint:recommended" 17 | ], 18 | "rules": { 19 | "quotes": ["error", "single", { "avoidEscape": true }], 20 | "semi": ["error", "always", { "omitLastInOneLineBlock": true}], 21 | "no-console": "off", 22 | "indent": ["error", 4], 23 | "no-trailing-spaces": ["error"] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /patch.install.sh.diff: -------------------------------------------------------------------------------- 1 | --- distrib/install.sh 2021-07-06 09:56:14.683716400 +0300 2 | +++ distrib/install.sh.patched 2021-07-06 09:57:15.318428000 +0300 3 | @@ -1100,6 +1100,14 @@ 4 | extract_tar 5 | } 6 | 7 | + echo "BEGIN: SYBASE LICENSE COPY !!!" 8 | + ls -AFL /sybase/NPL/SYSAM-2_0/licenses/ 9 | + rm /sybase/NPL/SYSAM-2_0/licenses/*.lic 10 | + cp /vagrant/distrib/SYBASE_ASE_TestDrive.lic /sybase/NPL/SYSAM-2_0/licenses/SYBASE_ASE_TD.lic 11 | + chown 1003:1002 /sybase/NPL/SYSAM-2_0/licenses/SYBASE_ASE_TD.lic 12 | + ls -AFl /sybase/NPL/SYSAM-2_0/licenses/ 13 | + echo "END: SYBASE LICENSE COPY !!!" 14 | + 15 | echo $tasks | grep -q $TASK_install && { 16 | server_install 17 | } 18 | -------------------------------------------------------------------------------- /scripts/addons/install_abapgit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ $(id -u) = '0' ]; then 4 | echo "[!] install_abapgit script must not be run from root" 5 | exit 1 6 | fi 7 | 8 | node -v > /dev/null 2>&1 9 | if [ $? -ne 0 ]; then 10 | echo "[!] Install nodejs before running this script" 11 | exit 1 12 | fi 13 | 14 | echo "Preparing to install abapgit ..." 15 | cp -R /vagrant/abapdeploy.js ~/ 16 | cd ~/abapdeploy.js 17 | npm -q install 18 | 19 | echo "Downloading latest abapgit source ..." 20 | curl -sS https://raw.githubusercontent.com/abapGit/build/master/zabapgit.abap -o /tmp/zabapgit.abap 21 | 22 | echo "Installing abapgit ..." 23 | export AD_IP=localhost 24 | export AD_USER=developer 25 | export AD_PASS=Down1oad 26 | node abapdeploy.js -f /tmp/zabapgit.abap -p zabapgit_full 27 | -------------------------------------------------------------------------------- /scripts/provision/startup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | _LOCAL_BIN=/usr/local/bin 4 | _SERVICE_PATH=/etc/systemd/system/sapnw.service 5 | 6 | if [ ! -e $_LOCAL_BIN/startsap.sh ]; then 7 | echo "Local start/stopsap scripts..." 8 | cp /vagrant/scripts/bin/startsap.sh $_LOCAL_BIN 9 | cp /vagrant/scripts/bin/stopsap.sh $_LOCAL_BIN 10 | chmod 755 $_LOCAL_BIN/startsap.sh 11 | chmod 755 $_LOCAL_BIN/stopsap.sh 12 | fi 13 | 14 | if [ -e /usr/sap/NPL/D00/exe/sapstart ] && [ ! -e $_SERVICE_PATH ]; then 15 | echo "Installing NW service..." 16 | cp /vagrant/scripts/service/sapnw.service /etc/systemd/system/ 17 | chmod 644 $_SERVICE_PATH 18 | systemctl daemon-reload 19 | systemctl enable sapnw 20 | systemctl status sapnw --no-pager --full || true 21 | # systemctl start sapnw 22 | fi 23 | -------------------------------------------------------------------------------- /scripts/provision/pre_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Timestamp 4 | date +%s > /tmp/provision-start.timestamp 5 | 6 | # Check if executed before 7 | if [ -n "$(cat /etc/hosts | grep vhcalnplci.dummy.nodomain )" ]; then 8 | echo "Seems the system configs already patched, skipping" 9 | exit 0 10 | fi 11 | 12 | # Start system configurations 13 | echo "Patching /etc/hosts ..." 14 | echo "10.0.2.15 vhcalnplci vhcalnplci.dummy.nodomain" | sudo tee -a /etc/hosts 15 | sudo sed -i.bak '/127.*vhcalnplci/d' /etc/hosts 16 | 17 | echo "Enabling uuidd ..." 18 | sudo systemctl enable uuidd.service 19 | sudo service uuidd start 20 | 21 | echo "Installing packages (mc, csh, etc) ..." 22 | sudo apt-get -q update 23 | sudo apt-get -y -q --no-install-recommends install mc csh libaio1 unrar expect 24 | # + libstdc++6 ? 25 | 26 | echo "Setting timezone to CET and enabling auto time adjutsments ..." 27 | sudo unlink /etc/localtime 28 | sudo ln -s /usr/share/zoneinfo/CET /etc/localtime 29 | sudo timedatectl set-ntp on 30 | -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | sap-nw-abap-vagrant changelog 2 | ============================= 3 | 4 | Legend 5 | ------ 6 | * : fixed 7 | ! : changed 8 | + : added 9 | - : removed 10 | 11 | 2019-12-21 v1.3.1 12 | ------------------ 13 | * fix issue with "Message: GetoptLong::InvalidOption" #6 14 | ! changed approach to override virtual machine name (from command line org to env var) 15 | + add timestamp and echo elapsed time at the end of provision 16 | 17 | 2019-10-19 v1.3.0 18 | ------------------ 19 | + Support for 752SP4 20 | + increase default workers number (sap profile) 21 | + adjust timezone and ntp inside of VM 22 | 23 | 2019-07-29 v1.2.1 24 | ------------------ 25 | + add command line param (--vm-name) to alter VM name 26 | * new gitlab certificates (had been changed some time ago) 27 | 28 | 2019-03-31 v1.2.0 29 | ------------------ 30 | + install SSL certificates with nodejs and node-rfc 31 | 32 | 2019-01-26 v1.1.0 33 | ------------------ 34 | + autostart with system startup (service) 35 | 36 | 2018-09-22 v1.0.0 37 | ------------------ 38 | + initial release 39 | -------------------------------------------------------------------------------- /scripts/addons/install_ssl_certificates.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ $(id -u) = '0' ]; then 4 | echo "[!] SSL certificate installation script must not be run from root" 5 | exit 1 6 | fi 7 | 8 | node -v > /dev/null 2>&1 9 | if [ $? -ne 0 ]; then 10 | echo "[!] Install nodejs before running this script" 11 | exit 1 12 | fi 13 | 14 | if [ -z "$(cat /home/vagrant/.bashrc | grep /usr/sap/NPL/D00/exe/)" ]; then 15 | echo "" >> /home/vagrant/.bashrc 16 | echo "# Path to SAP libs" >> /home/vagrant/.bashrc 17 | echo "export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/sap/NPL/D00/exe/" >> /home/vagrant/.bashrc 18 | fi 19 | 20 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/sap/NPL/D00/exe/ 21 | 22 | echo "Preparing to install certificates ..." 23 | cp -R /vagrant/certinst.js ~/ 24 | cd ~/certinst.js 25 | npm -q install 26 | 27 | # echo "Certificates installed:" `node certinst.js list -s` 28 | echo "Testing connection ..." 29 | node certinst.js test 30 | echo 31 | 32 | echo "Installing certificates..." 33 | node certinst.js install 34 | echo 35 | 36 | echo "List certificates ..." 37 | node certinst.js list 38 | echo 39 | -------------------------------------------------------------------------------- /scripts/provision/install_nw.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Installing SAP NW ..." 4 | if [ -e /sapmnt ]; then 5 | echo " seems SAP is already installed, skipping" 6 | exit 0 7 | fi 8 | 9 | if [ ! -e /vagrant/distrib/install.sh ]; then 10 | echo " install.sh NOT found, NW install failed, continue manually" 11 | exit 0 12 | fi 13 | 14 | cd /vagrant/distrib 15 | # cp /vagrant/scripts/run-install.sh /tmp 16 | # chmod +x install.sh 17 | # chmod +x /tmp/run-install.sh 18 | sudo expect -f /vagrant/scripts/provision/install_nw.expect 19 | echo "sapinstall script result =" $? 20 | # rm /tmp/run-install.sh 21 | 22 | if [ ! -n "$(netstat -tan4 | grep 3200)" ]; then 23 | echo "Waiting for NW to start ..." 24 | sleep 60s 25 | if [ ! -n "$(netstat -tan4 | grep 3200)" ]; then 26 | echo "Still not started ... waiting more ..." 27 | sleep 60s 28 | if [ ! -n "$(netstat -tan4 | grep 3200)" ]; then 29 | echo "[!] NW hasn't started after 2 minutes, this is strage" 30 | echo "[!] Continuing with the script but there might be some issue" 31 | fi 32 | fi 33 | fi 34 | 35 | if [ -n "$(netstat -tan4 | grep 3200)" ]; then 36 | echo "NW instance detected and listening" 37 | fi 38 | -------------------------------------------------------------------------------- /abapdeploy.js/abapdeploy.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const { promisify } = require('util'); 3 | const readFileAsync = promisify(fs.readFile); 4 | const commander = require('commander'); 5 | const { 6 | ADTClient, 7 | session_types, 8 | } = require('abap-adt-api'); 9 | 10 | function create() { 11 | const ip = process.env.AD_IP || 'localhost'; 12 | const user = process.env.AD_USER || 'developer'; 13 | const pass = process.env.AD_PASS || 'Down1oad'; 14 | 15 | return new ADTClient( 16 | `http://${ip}:8000`, 17 | user, 18 | pass, 19 | ); 20 | } 21 | 22 | async function fetchTmpObj(objName) { // eslint-disable-line no-unused-vars 23 | const client = create(); 24 | const nodes = await client.nodeContents('DEVC/K', '$TMP'); 25 | const node = nodes.nodes.find(i => i.OBJECT_NAME === objName); 26 | const structure = await client.objectStructure(node.OBJECT_URI); 27 | const mainInclude = ADTClient.mainInclude(structure); 28 | const code = await client.getObjectSource(mainInclude); 29 | // console.log(structure, mainInclude); 30 | console.log(code); 31 | } 32 | 33 | async function installProg(name, source) { 34 | const client = create(); 35 | const path = '/sap/bc/adt/programs/programs/' + name; 36 | const main = path + '/source/main'; 37 | 38 | try { 39 | await client.createObject({ 40 | description: name, 41 | name, 42 | objtype: 'PROG/P', 43 | parentName: '$TMP', 44 | parentPath: '/sap/bc/adt/packages/$TMP' 45 | }); 46 | 47 | client.stateful = session_types.stateful; 48 | const handle = await client.lock(path); 49 | await client.setObjectSource(main, source, handle.LOCK_HANDLE); // write the program 50 | console.log(`Program ${name} was successfully created`); 51 | await client.unLock(path, handle.LOCK_HANDLE); 52 | 53 | // read it for verification 54 | // const newsource = await c.getObjectSource(main) 55 | // console.log(newsource); 56 | 57 | const result = await client.activate( name, path ); 58 | console.log(`Program ${name} was activated`); 59 | console.log(result); 60 | } finally { 61 | client.dropSession(); 62 | } 63 | } 64 | 65 | async function main(args) { 66 | 67 | // fetchTmpObj('ZCL_Z001_MPC'); 68 | // installProg('zadt_test_temp', `report zadt_test_temp.\nwrite:/ 'Hello World!'.`); 69 | 70 | if (!args.program) { 71 | console.error('Please specify program name'); 72 | process.exit(1); 73 | } 74 | 75 | try { 76 | const src = await readFileAsync(args.from, 'utf8'); 77 | installProg(args.program, src); 78 | } catch (error) { 79 | console.error(error); 80 | process.exit(1); 81 | } 82 | 83 | } 84 | 85 | process.on('unhandledRejection', async (reason, p) => { 86 | console.error('Unhandled Rejection at: Promise', p, 'reason:', reason); 87 | process.exit(1); 88 | }); 89 | 90 | commander 91 | .option('-p,--program ', 'Program name') 92 | .option('-f,--from ', 'Path to abap source'); 93 | commander.parse(process.argv); 94 | main(commander); 95 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Defaults and constants 5 | vmNameFromEnv = 'VAGRANT_SAPNW_VM_NAME' 6 | argVagrantName = 'sapnw' 7 | argMachineName = 'sap-nw752sp4' 8 | 9 | unless ENV[vmNameFromEnv].to_s.strip.empty? 10 | argVagrantName = ENV[vmNameFromEnv] 11 | argMachineName = ENV[vmNameFromEnv] 12 | puts "[!] VAGRANT_SAPNW_VM_NAME env detected" 13 | puts "[!] VM name is redefined to: #{argVagrantName}" 14 | end 15 | 16 | # Create additional disk in VM directory 17 | class VagrantPlugins::ProviderVirtualBox::Action::SetName 18 | alias_method :original_call, :call 19 | def call(env) 20 | machine = env[:machine] 21 | driver = machine.provider.driver 22 | uuid = driver.instance_eval { @uuid } 23 | ui = env[:ui] 24 | 25 | # Find out folder of VM 26 | vm_folder = "" 27 | vm_info = driver.execute("showvminfo", uuid, "--machinereadable") 28 | lines = vm_info.split("\n") 29 | lines.each do |line| 30 | if line.start_with?("CfgFile") 31 | vm_folder = line.split("=")[1].gsub('"','') 32 | vm_folder = File.dirname(File.expand_path(vm_folder)) 33 | ui.info "VM Folder is: #{vm_folder}" 34 | break 35 | end 36 | end 37 | 38 | disk_size = 60 * 1024 # 1GB 39 | disk_file = File.join(vm_folder, "sybase.vdi") 40 | ui.info "VM additional disk is: #{disk_file}" 41 | 42 | ui.info "Adding disk to VM ..." 43 | if File.exist?(disk_file) 44 | ui.info " disk already exists" 45 | else 46 | ui.info " creating new disk" 47 | driver.execute( 48 | 'createhd', 49 | '--filename', disk_file, 50 | '--format', 'VDI', 51 | '--size', "#{disk_size}", 52 | '--variant', 'Standard' # dynamic disk 53 | ) 54 | ui.info " attaching disk to VM" 55 | driver.execute( 56 | 'storageattach', uuid, 57 | '--storagectl', 'SCSI', 58 | '--port', '2', 59 | '--device', '0', 60 | '--type', 'hdd', 61 | '--medium', disk_file 62 | ) 63 | end 64 | 65 | original_call(env) 66 | end 67 | end 68 | 69 | # Vagrant config 70 | Vagrant.configure("2") do |config| 71 | config.vm.box = "ubuntu/xenial64" 72 | config.vm.hostname = "vhcalnplci" 73 | config.vm.define argVagrantName 74 | 75 | # Check for updates only on `vagrant box outdated` 76 | config.vm.box_check_update = false 77 | 78 | # stopsap may take time 79 | config.vm.graceful_halt_timeout = 600 80 | 81 | # Network 82 | config.vm.network "forwarded_port", guest: 22, guest_ip: "10.0.2.15", host_ip: "127.0.0.1", host: 2222, id: "ssh", auto_correct: true 83 | config.vm.network "forwarded_port", guest: 8000, guest_ip: "10.0.2.15", host_ip: "127.0.0.1", host: 8000, id: "http" 84 | config.vm.network "forwarded_port", guest: 44300, guest_ip: "10.0.2.15", host_ip: "127.0.0.1", host: 44300, id: "https" 85 | config.vm.network "forwarded_port", guest: 3300, guest_ip: "10.0.2.15", host_ip: "127.0.0.1", host: 3300, id: "rfc" 86 | config.vm.network "forwarded_port", guest: 3200, guest_ip: "10.0.2.15", host_ip: "127.0.0.1", host: 3200, id: "sapgui" 87 | 88 | # Virtualbox settings 89 | config.vm.provider "virtualbox" do |vb| 90 | vb.name = argMachineName 91 | vb.memory = "6144" # 6 GB 92 | # vb.memory = "4096" # 4 GB + enable add_swap.sh below !!! 93 | end 94 | 95 | # Provision scripts 96 | config.vm.provision "shell", path: "scripts/provision/add_disk.sh" 97 | # config.vm.provision "shell", path: "scripts/provision/add_swap.sh" 98 | # config.vm.provision "shell", path: "scripts/provision/patch_install_script.sh" 99 | config.vm.provision "shell", path: "scripts/provision/pre_install.sh" 100 | config.vm.provision "shell", path: "scripts/provision/install_nw.sh" 101 | config.vm.provision "shell", path: "scripts/provision/startup.sh" 102 | config.vm.provision "shell", path: "scripts/provision/post_install.sh" 103 | config.vm.provision "shell", path: "scripts/provision/finalize.sh" 104 | end 105 | -------------------------------------------------------------------------------- /certinst.js/certinst.js: -------------------------------------------------------------------------------- 1 | const rfc = require('node-rfc'); 2 | const fs = require('fs'); 3 | const path = require('path'); 4 | const { promisify } = require('util'); 5 | const readFileAsync = promisify( fs.readFile ); 6 | const { spawn } = require('child_process'); 7 | 8 | const abapSystem = { 9 | user: 'sap*', 10 | passwd: 'Down1oad', 11 | ashost: 'localhost', // vhcalnplci 12 | sysnr: '00', 13 | client: '001' 14 | }; 15 | 16 | // function invokeRfc(fnName, params) { 17 | // return new Promise((resolve, reject) => { 18 | // const client = new rfc.Client(abapSystem); 19 | // // console.log('RFC client lib version: ', client.getVersion()); 20 | 21 | // client.connect(function(err) { 22 | // if (err) reject(err); 23 | // client.invoke(fnName, params, (err, res) => { 24 | // if (err) reject(err); 25 | // resolve(res); 26 | // }); 27 | // }); 28 | // }); 29 | // } 30 | 31 | // async function testConnectionOld() { 32 | // try { 33 | // const res = await invokeRfc('STFC_CONNECTION', { REQUTEXT: 'Hello SAP!' }); 34 | // console.log('Result STFC_CONNECTION:', res); 35 | // } catch(err) { 36 | // console.error('Error invoking STFC_CONNECTION:', err); 37 | // } 38 | // } 39 | 40 | async function callRfc(fmName, params, isVerbose = false) { 41 | const client = new rfc.Client(abapSystem); 42 | if (isVerbose) console.log('RFC client lib version: ', client.version); 43 | 44 | await client.open(); 45 | const res = await client.call(fmName, params); 46 | await client.close(); 47 | return res; 48 | } 49 | 50 | async function testConnection(isVerbose = true) { 51 | try { 52 | const res = await callRfc('STFC_CONNECTION', { REQUTEXT: 'Hello SAP!' }, isVerbose); 53 | res.RESPTEXT = res.RESPTEXT.replace(/\s{2,}/g, ' '); // condense 54 | if (isVerbose) console.log('STFC_CONNECTION response:', res); 55 | return true; 56 | } catch (error) { 57 | if (isVerbose) console.error('Error invoking STFC_CONNECTION:', error); 58 | return false; 59 | } 60 | } 61 | 62 | function spawnOpenssl(buf) { 63 | return new Promise((resolve, reject) => { 64 | const openssl = spawn('openssl', ['x509', '-inform', 'der', '-noout', '-subject']); //, '-in', 'cert.cer']); 65 | 66 | let output = ''; 67 | openssl.stdout.on('data', (data) => { output += data }); 68 | openssl.stderr.on('data', (data) => { console.log(`openssl error: ${data}`) }); 69 | openssl.on('close', (code) => code ? reject(code) : resolve(output)); 70 | 71 | openssl.stdin.write(buf); 72 | openssl.stdin.end(); 73 | }); 74 | } 75 | 76 | async function listCertificates(isVerbose = true) { 77 | try { 78 | const res = await callRfc('SSFR_GET_CERTIFICATELIST', { 79 | IS_STRUST_IDENTITY: { PSE_CONTEXT: 'SSLC', PSE_APPLIC: 'ANONYM' } 80 | }); 81 | if (isVerbose) { 82 | console.log(`SSFR_GET_CERTIFICATELIST returned ${res.ET_CERTIFICATELIST.length} certificates`); 83 | let num = 0; 84 | for (const cert of res.ET_CERTIFICATELIST) { 85 | const certCN = await spawnOpenssl(cert); 86 | console.log(` ${++num}:`, certCN.replace('\n', '')); 87 | } 88 | } 89 | return res.ET_CERTIFICATELIST.length; 90 | } catch(err) { 91 | if (isVerbose) console.error('Error invoking SSFR_GET_CERTIFICATELIST:', err); 92 | return -1; 93 | } 94 | } 95 | 96 | function getCertFiles(dir) { 97 | const files = fs.readdirSync(dir).filter(f => /\.cer$/.test(f)); 98 | return files.map(f => path.join(dir, f)); 99 | } 100 | 101 | async function installCertificates(dir) { 102 | 103 | const files = getCertFiles(dir); 104 | 105 | try { 106 | const res = await callRfc('SSFR_PSE_CHECK', { IS_STRUST_IDENTITY: { PSE_CONTEXT: 'SSLC', PSE_APPLIC: 'ANONYM' } }); 107 | console.log('Result SSFR_PSE_CHECK:', res.ET_BAPIRET2[0].TYPE, res.ET_BAPIRET2[0].MESSAGE); 108 | } catch(err) { 109 | console.error('Error invoking SSFR_PSE_CHECK:', err); 110 | } 111 | 112 | const certsBefore = await listCertificates(false); 113 | console.log('Certificates before installation:', certsBefore); 114 | 115 | for (const file of files) { 116 | try { 117 | const certBlob = await readFileAsync(file); 118 | const res = await callRfc('SSFR_PUT_CERTIFICATE', { // eslint-disable-line no-unused-vars 119 | IS_STRUST_IDENTITY: { PSE_CONTEXT: 'SSLC', PSE_APPLIC: 'ANONYM' }, 120 | IV_CERTIFICATE: certBlob, 121 | }); 122 | // console.log(res); 123 | console.log(file, '- OK'); 124 | } catch(err) { 125 | console.log(file, '- FAILED'); 126 | } 127 | } 128 | 129 | const certsAfter = await listCertificates(false); 130 | console.log('Certificates after installation:', certsAfter); 131 | } 132 | 133 | 134 | async function main() { 135 | const command = process.argv[2] ? process.argv[2].toLowerCase() : null; 136 | 137 | if (!['list', 'test', 'install'].includes(command)) { 138 | [ 139 | 'Usage: node certinst.js ', 140 | '', 141 | ' test - test NW connection', 142 | ' list - list installed certificates', 143 | ' install - install certificates from certificates dir', 144 | ].forEach(h => console.log(h)); 145 | process.exit(1); 146 | } 147 | 148 | const isSilent = (process.argv[3] === '-s'); 149 | 150 | if (command === 'test') { 151 | const success = await testConnection(!isSilent); 152 | process.exit(success ? 0 : 1); 153 | } else if (command === 'list') { 154 | const certCount = await listCertificates(!isSilent); 155 | if (certCount >= 0) { 156 | if (isSilent) console.log(certCount); 157 | process.exit(0); 158 | } else { 159 | process.exit(1); 160 | } 161 | } else if (command === 'install') { 162 | await installCertificates('./certificates'); 163 | } else { 164 | console.log('Unknown command'); 165 | } 166 | } 167 | 168 | process.on('unhandledRejection', async (reason, p) => { 169 | console.error('Unhandled Rejection at: Promise', p , 'reason:', reason); 170 | process.exit(1); 171 | }); 172 | main(); 173 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Version](https://img.shields.io/github/v/tag/sbcgua/sap-nw-abap-vagrant.svg) 2 | 3 | # Vagrant config for SAP NW752 SP01/SP04 dev edition 4 | 5 | ## [PINNED] 2020-03 SYBASE LICENCE update 6 | 7 | The sybase DB license included in the original distrib expired on March 2021. The new license can be obtained as described here: https://blogs.sap.com/2018/08/30/as-abap-7.5x-ase-license-available/ 8 | 9 | In order to include this file into a new installation: 10 | 1. Place the `SYBASE_ASE_TestDrive.lic` file into distrib folder, near `install.sh` script. 11 | 2. Edit `Vagrantfile`, uncomment `config.vm.provision "shell", path: "scripts/provision/patch_install_script.sh"` line near the end of the file. 12 | 3. This will adjust the `install.sh` script so that it find and copies the new licence after uncompressing the files and before start of the SAP installation. 13 | 14 | ## What is it ? 15 | 16 | This repo contains a Vagrant script and set of deployment scripts which installs SAP NW752 SP01 dev edition in Ubuntu in Virtual Box environment with **minimal** manual steps required. The target is that you copy the script, download distribs, run Vagrant which will do allmost of steps from the offical guide and some more, and then you have ready system which just needs the post install license steps. In addition to the official installation guide the script does: 17 | 18 | - configures NW to autostart on virtual machine startup 19 | - can *optionally* install github and gitlab SSL certificates to use with abapGit 20 | - can *optionally* install latest abapGit 21 | 22 | For a quick start [watch this video](https://www.youtube.com/watch?v=-BeEF1U-cqQ) 23 | 24 | Confirmed to work with NW752 SP01 and **the newer SP04**. 25 | 26 | ## How to install 27 | 28 | - install **virtual box** 29 | - install **vagrant**. Note: vagrant may require Powershell 3 on Window 7. If this is an issue check [this](https://docs.microsoft.com/en-us/skypeforbusiness/set-up-your-computer-for-windows-powershell/download-and-install-windows-powershell-3-0). 30 | - download this repository (as zip or `git clone`) 31 | - put uncompressed distribution files into `distrib` subfolder of the cloned dir 32 | - open shell in cloned directory (where `Vagrantfile` is) 33 | - run `vagrant up` 34 | - wait for installation to finish ... (took ~1-1.5 hours on my laptop) 35 | - you can connect to the system and follow the post-install steps from the official guide (in particular SAP licence installation). The system will be at **127.0.0.1, 00, NPL** 36 | - *optionally*, run `vagrant ssh -c "sudo /vagrant/scripts/install_addons.sh"` to install SSL certificates mentioned above and latest [abapGit](https://github.com/larshp/abapGit). This can only be done **AFTER** licence installation. 37 | 38 | ## How to use 39 | 40 | Starting from v1.1 of this repo the scripts install sapnw as a `systemd` service and enables it by default. So the netveawer should automatically start on boot (note that it will take a minute or two after the machine is up) and you should be able to connect. On the system halt the service will attempt to gracefully stop NW (with 5 min timeout). If you want to disable the service for whatever reason run `vagrant ssh -c "sudo systemctl disable sapnw"`, then start/stop sap manually (see below). 41 | 42 | ### Start/stop virtual machine 43 | 44 | - all the below assumes you started the console in the `Vagrantfile` directory 45 | - whenever you want to start NW 46 | - start vm with `vagrant up` 47 | - to stop instance 48 | - run `vagrant halt` 49 | - to go inside linux 50 | - run `vagrant ssh` 51 | - completely remove virtual machine destroying all data 52 | - run `vagrant destroy` 53 | 54 | Alternatively you can run VM directly from virtual box, Vagrant did it's job by now and now it is just a convenient option. 55 | 56 | ### Useful commands for `systemd` service control 57 | 58 | - the following commands can be issued either with `vagrant ssh -c ""` or when logged in the system with `vagrant ssh` 59 | - check service status 60 | - `sudo systemctl status sapnw` 61 | - starting/stopping 62 | - `sudo systemctl start sapnw` - manually start the service 63 | - `sudo systemctl stop sapnw` - manually stop the service 64 | - `sudo systemctl enable sapnw` - enable service autostart 65 | - `sudo systemctl disable sapnw` - disable service autostart 66 | - `sudo systemctl daemon-reload` - reload service script in case you changed it manually (`/etc/systemd/system/sapnw.service`) 67 | - see the journal (start/stop output) 68 | - `sudo journalctl -u sapnw -b` 69 | - `sudo journalctl -u sapnw -f` - output last message and follow new ones (useful after manual `sudo systemctl start sapnw`) 70 | - `sudo cat /var/log/syslog | grep sapnw` - same but from system log (may have more info) 71 | - `sudo cat /var/log/syslog | grep SAPNPL` - to see sap instance messages 72 | - useful links about systemd services [digitalocean systemd guide](https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units), [systemd wiki](https://wiki.archlinux.org/index.php/Systemd), [freedesktop systemd docs](https://www.freedesktop.org/software/systemd/man/systemd.service.html) 73 | 74 | 75 | ### Manual mode (if the service is disabled) 76 | 77 | - assuming you started the console in the `Vagrantfile` directory and started the vm ... 78 | - `vagrant ssh -c startsap.sh` - start sap system 79 | - `vagrant ssh -c stopsap.sh` - stop sap system 80 | 81 | ### Changing VM Name 82 | 83 | ~~specify `--vm-name` parameter to set virtual machine name...~~ - this was deprecated in v1.3.1. Unfortunately, parsing command line args in Vagrant file conflicts with it's native args (see more in [this issue](https://github.com/sbcgua/sap-nw-abap-vagrant/issues/6)). Instead a new approach was implemented via environment variables (see below). 84 | 85 | The default name for VM is defined at the beginning of the Vagrant file in `argMachineName` variable. It is used in the code after to define the virtual machine name. You can override it by setting `VAGRANT_SAPNW_VM_NAME` environment variable for the session (or, optionally, redefine it directly in the file). 86 | 87 | The way depends on your shell: 88 | - cmd - `set VAGRANT_SAPNW_VM_NAME=my_new_sapnw` 89 | - powershell - `$env:VAGRANT_SAPNW_VM_NAME="my_new_sapnw"` (mind the double-quotes !) 90 | - bash - `export VAGRANT_SAPNW_VM_NAME=my_new_sapnw` or specifying the var in front of the command e.g. `VAGRANT_SAPNW_VM_NAME=my_new_sapnw vagrant ssh -c "ls -AFl"` 91 | 92 | Don't forget to set the variable, especially before the sensitive commands like `up` and `destroy`. If you work with several instances a lot you might want to create dedicated script/batch files. 93 | 94 | Example (cmd): 95 | ``` 96 | set VAGRANT_SAPNW_VM_NAME=my_new_sapnw 97 | vagrant up 98 | vagrant ssh -c "sudo /vagrant/scripts/install_addons.sh" 99 | ``` 100 | 101 | ### Additional comments 102 | 103 | - you may start the vm from any directory but then you need to address it by id or name. Run `vagrant global-status` to check the name. It should be `sapnw`. So the command to vm would look like `vagrant up sapnw` or `vagrant ssh sapnw -c ` 104 | - `startsap.sh` and `stopsap.sh` are shortcuts that are placed to `/usr/local/bin` during installation. They contain command like `sudo -i -u npladm startsap` 105 | 106 | ## Infos 107 | 108 | ### What is vagrant 109 | 110 | A tool to setup virtual environments conveniently. No need to go through boring installation process which is a plus. Basic virtual machine is created within seconds (for popular flavors that exist in vagrant cloud repository). 111 | 112 | ### Why not docker? (my opinion, no offends :) 113 | 114 | 1) Imho docker is supposed to be stateless. Databases should be in volumes, not inside docker layer. 115 | 2) Besides, docker storage layer is slower than volumes (AFAIK) 116 | 117 | P.S.: Probably this can be solved. `/sybase` directory can be mounted to volume. Also logs and transports should be considered. Well, I don't have enough basis skills for this :) Maybe someday. 118 | P.P.S.: Docker has a lot of potential in terms of composability. E.g. compose several pods with NW dev edition, HANA express for sidecar, configured SMTP server and make them interact. Feel free to reuse the scripts from the repo, they should be very portable to docker, in fact they work inside Ubuntu so might be zero changes needed. 119 | 120 | ### Why Ubuntu 121 | 122 | 1) Ubuntu is very popular linux flavor. The community is huge and there are a lot of materials on how to solve this or that issue 123 | 2) Bare ubuntu server is just ~1 GB in size 124 | 3) and yes, I know debian-like system better than other flavors ;) might be the main reason. 125 | 126 | ### Memory 127 | 128 | Currently machine is setup to consume 6GB. Though in my experiance 4GB is usually enough (ungrounded opinion). One option to decrease memory usage is to activate swap. To do this: 129 | - uncomment `vb.memory = "4096"` in `Vagrantfile` (and comment the one with 6GB) 130 | - uncomment `config.vm.provision "shell", path: "scripts/add_swap.sh"` - this will activate swap during installation. Or just run it after install via ssh `/vagrant/scripts/add_swap.sh` 131 | 132 | ### SSL certificates 133 | 134 | SSL certificates installation can be triggered by `/vagrant/scripts/install_addons.sh` or separate `/vagrant/scripts/addons/install_ssl_certificates.sh` scripts. It install the files from `certificates` directory. The repositiry contains certificates of github and gitlab. However, you can add more (in *.cer format) before running the script above. The script will install all the certificates that are in the folder. In order to initiate certificate script again later (if you don't want to install certificates manually via `STRUST`), login to ssh and run `/vagrant/scripts/addons/install_ssl_certificates.sh`. 135 | 136 | ### Publication 137 | 138 | - [Installing NetWeaver AS ABAP 7.52 SP 01 Developer Edition with Vagrant and Ubuntu](https://blogs.sap.com/2018/09/22/installing-netweaver-as-abap-7.52-sp-01-developer-edition-with-vagrant) 139 | - [How to easily install SAP NetWeaver developer edition 7.52 and abapGit with Vagrant in 10 man-minutes](https://blogs.sap.com/2019/04/30/how-to-easily-install-sap-netweaver-developer-edition-7.52-and-abapgit-with-vagrant-in-10-man-minutes/) 140 | - [Video with installation process](https://www.youtube.com/watch?v=-BeEF1U-cqQ) 141 | 142 | ### Regards and references 143 | 144 | - [AS ABAP 752 SP01, developer edition, official announce](https://blogs.sap.com/2018/09/13/as-abap-752-sp01-developer-edition-to-download/) 145 | - [AS ABAP 7.52 SP01, developer edition: Concise installation guide](https://blogs.sap.com/2018/09/13/as-abap-7.52-sp01-developer-edition-concise-installation-guide/) 146 | - got some script ideas (expect) from https://github.com/tobiashofmann/sap-nw-abap-docker 147 | - https://github.com/wechris/SAPNW75SPS02 as an inspiration 148 | - concept on how to create additional VB drives in VM folder from https://gist.github.com/leifg/4713995 149 | - cool guide on swap file in ubuntu: https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-16-04 150 | - @filak-sap and https://github.com/filak-sap/sap-nw-abap-docker for ideas and inspiration 151 | - https://github.com/SAP/node-rfc - nodejs lib to call SAP RFCs, used for SSL certificate installation 152 | - @marcellourbani for his https://github.com/marcellourbani/abap-adt-api (cool!) 153 | - [AS ABAP 752 SP04, developer edition: NOW AVAILABLE](https://blogs.sap.com/2019/07/01/as-abap-752-sp04-developer-edition-to-download) 154 | - [AS ABAP 7.52 SP04, Developer Edition: Concise Installation Guide](https://blogs.sap.com/2019/10/01/as-abap-7.52-sp04-developer-edition-concise-installation-guide/) 155 | 156 | ### TODO 157 | 158 | - download github/lab certificates directly from internet ? 159 | - migrate to Ubuntu 18.04 LTS (Bionic Beaver) 160 | - improve abapdeploy.js 161 | - early detect presence of distrib 162 | -------------------------------------------------------------------------------- /certinst.js/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "certinst", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/bluebird": { 8 | "version": "3.5.26", 9 | "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.26.tgz", 10 | "integrity": "sha512-aj2mrBLn5ky0GmAg6IPXrQjnN0iB/ulozuJ+oZdrHRAzRbXjGmu4UXsNCjFvPbSaaPZmniocdOzsM392qLOlmQ==" 11 | }, 12 | "ajv": { 13 | "version": "5.5.2", 14 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 15 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 16 | "requires": { 17 | "co": "^4.6.0", 18 | "fast-deep-equal": "^1.0.0", 19 | "fast-json-stable-stringify": "^2.0.0", 20 | "json-schema-traverse": "^0.3.0" 21 | } 22 | }, 23 | "bluebird": { 24 | "version": "3.5.3", 25 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", 26 | "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==" 27 | }, 28 | "co": { 29 | "version": "4.6.0", 30 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 31 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" 32 | }, 33 | "fast-deep-equal": { 34 | "version": "1.1.0", 35 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 36 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" 37 | }, 38 | "fast-json-stable-stringify": { 39 | "version": "2.0.0", 40 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 41 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 42 | }, 43 | "json-schema-traverse": { 44 | "version": "0.3.1", 45 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 46 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" 47 | }, 48 | "node-addon-api": { 49 | "version": "1.6.2", 50 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.6.2.tgz", 51 | "integrity": "sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA==" 52 | }, 53 | "node-rfc": { 54 | "version": "1.0.0-rc7", 55 | "resolved": "https://registry.npmjs.org/node-rfc/-/node-rfc-1.0.0-rc7.tgz", 56 | "integrity": "sha512-d17pRUa9rY0AHZNjXnSa7AEqiRr8B0gCZKXJQyJQKy+A2ZNvTseiwFeJCvxPWX6PB1vAnIElXuT/27Joscb8Pg==", 57 | "requires": { 58 | "@types/bluebird": "^3.5.24", 59 | "ajv": "^5.5.2", 60 | "bluebird": "^3.5.3", 61 | "node-addon-api": "^1.6.2", 62 | "node-pre-gyp": "^0.12.0" 63 | }, 64 | "dependencies": { 65 | "abbrev": { 66 | "version": "1.1.1", 67 | "bundled": true 68 | }, 69 | "ansi-regex": { 70 | "version": "2.1.1", 71 | "bundled": true 72 | }, 73 | "aproba": { 74 | "version": "1.2.0", 75 | "bundled": true 76 | }, 77 | "are-we-there-yet": { 78 | "version": "1.1.5", 79 | "bundled": true, 80 | "requires": { 81 | "delegates": "^1.0.0", 82 | "readable-stream": "^2.0.6" 83 | } 84 | }, 85 | "balanced-match": { 86 | "version": "1.0.0", 87 | "bundled": true 88 | }, 89 | "brace-expansion": { 90 | "version": "1.1.11", 91 | "bundled": true, 92 | "requires": { 93 | "balanced-match": "^1.0.0", 94 | "concat-map": "0.0.1" 95 | } 96 | }, 97 | "chownr": { 98 | "version": "1.1.1", 99 | "bundled": true 100 | }, 101 | "code-point-at": { 102 | "version": "1.1.0", 103 | "bundled": true 104 | }, 105 | "concat-map": { 106 | "version": "0.0.1", 107 | "bundled": true 108 | }, 109 | "console-control-strings": { 110 | "version": "1.1.0", 111 | "bundled": true 112 | }, 113 | "core-util-is": { 114 | "version": "1.0.2", 115 | "bundled": true 116 | }, 117 | "debug": { 118 | "version": "2.6.9", 119 | "bundled": true, 120 | "requires": { 121 | "ms": "2.0.0" 122 | } 123 | }, 124 | "deep-extend": { 125 | "version": "0.6.0", 126 | "bundled": true 127 | }, 128 | "delegates": { 129 | "version": "1.0.0", 130 | "bundled": true 131 | }, 132 | "detect-libc": { 133 | "version": "1.0.3", 134 | "bundled": true 135 | }, 136 | "fs-minipass": { 137 | "version": "1.2.5", 138 | "bundled": true, 139 | "requires": { 140 | "minipass": "^2.2.1" 141 | } 142 | }, 143 | "fs.realpath": { 144 | "version": "1.0.0", 145 | "bundled": true 146 | }, 147 | "gauge": { 148 | "version": "2.7.4", 149 | "bundled": true, 150 | "requires": { 151 | "aproba": "^1.0.3", 152 | "console-control-strings": "^1.0.0", 153 | "has-unicode": "^2.0.0", 154 | "object-assign": "^4.1.0", 155 | "signal-exit": "^3.0.0", 156 | "string-width": "^1.0.1", 157 | "strip-ansi": "^3.0.1", 158 | "wide-align": "^1.1.0" 159 | } 160 | }, 161 | "glob": { 162 | "version": "7.1.3", 163 | "bundled": true, 164 | "requires": { 165 | "fs.realpath": "^1.0.0", 166 | "inflight": "^1.0.4", 167 | "inherits": "2", 168 | "minimatch": "^3.0.4", 169 | "once": "^1.3.0", 170 | "path-is-absolute": "^1.0.0" 171 | } 172 | }, 173 | "has-unicode": { 174 | "version": "2.0.1", 175 | "bundled": true 176 | }, 177 | "iconv-lite": { 178 | "version": "0.4.24", 179 | "bundled": true, 180 | "requires": { 181 | "safer-buffer": ">= 2.1.2 < 3" 182 | } 183 | }, 184 | "ignore-walk": { 185 | "version": "3.0.1", 186 | "bundled": true, 187 | "requires": { 188 | "minimatch": "^3.0.4" 189 | } 190 | }, 191 | "inflight": { 192 | "version": "1.0.6", 193 | "bundled": true, 194 | "requires": { 195 | "once": "^1.3.0", 196 | "wrappy": "1" 197 | } 198 | }, 199 | "inherits": { 200 | "version": "2.0.3", 201 | "bundled": true 202 | }, 203 | "ini": { 204 | "version": "1.3.5", 205 | "bundled": true 206 | }, 207 | "is-fullwidth-code-point": { 208 | "version": "1.0.0", 209 | "bundled": true, 210 | "requires": { 211 | "number-is-nan": "^1.0.0" 212 | } 213 | }, 214 | "isarray": { 215 | "version": "1.0.0", 216 | "bundled": true 217 | }, 218 | "minimatch": { 219 | "version": "3.0.4", 220 | "bundled": true, 221 | "requires": { 222 | "brace-expansion": "^1.1.7" 223 | } 224 | }, 225 | "minimist": { 226 | "version": "0.0.8", 227 | "bundled": true 228 | }, 229 | "minipass": { 230 | "version": "2.3.5", 231 | "bundled": true, 232 | "requires": { 233 | "safe-buffer": "^5.1.2", 234 | "yallist": "^3.0.0" 235 | } 236 | }, 237 | "minizlib": { 238 | "version": "1.2.1", 239 | "bundled": true, 240 | "requires": { 241 | "minipass": "^2.2.1" 242 | } 243 | }, 244 | "mkdirp": { 245 | "version": "0.5.1", 246 | "bundled": true, 247 | "requires": { 248 | "minimist": "0.0.8" 249 | } 250 | }, 251 | "ms": { 252 | "version": "2.0.0", 253 | "bundled": true 254 | }, 255 | "needle": { 256 | "version": "2.2.4", 257 | "bundled": true, 258 | "requires": { 259 | "debug": "^2.1.2", 260 | "iconv-lite": "^0.4.4", 261 | "sax": "^1.2.4" 262 | } 263 | }, 264 | "node-pre-gyp": { 265 | "version": "0.12.0", 266 | "bundled": true, 267 | "requires": { 268 | "detect-libc": "^1.0.2", 269 | "mkdirp": "^0.5.1", 270 | "needle": "^2.2.1", 271 | "nopt": "^4.0.1", 272 | "npm-packlist": "^1.1.6", 273 | "npmlog": "^4.0.2", 274 | "rc": "^1.2.7", 275 | "rimraf": "^2.6.1", 276 | "semver": "^5.3.0", 277 | "tar": "^4" 278 | } 279 | }, 280 | "nopt": { 281 | "version": "4.0.1", 282 | "bundled": true, 283 | "requires": { 284 | "abbrev": "1", 285 | "osenv": "^0.1.4" 286 | } 287 | }, 288 | "npm-bundled": { 289 | "version": "1.0.5", 290 | "bundled": true 291 | }, 292 | "npm-packlist": { 293 | "version": "1.1.12", 294 | "bundled": true, 295 | "requires": { 296 | "ignore-walk": "^3.0.1", 297 | "npm-bundled": "^1.0.1" 298 | } 299 | }, 300 | "npmlog": { 301 | "version": "4.1.2", 302 | "bundled": true, 303 | "requires": { 304 | "are-we-there-yet": "~1.1.2", 305 | "console-control-strings": "~1.1.0", 306 | "gauge": "~2.7.3", 307 | "set-blocking": "~2.0.0" 308 | } 309 | }, 310 | "number-is-nan": { 311 | "version": "1.0.1", 312 | "bundled": true 313 | }, 314 | "object-assign": { 315 | "version": "4.1.1", 316 | "bundled": true 317 | }, 318 | "once": { 319 | "version": "1.4.0", 320 | "bundled": true, 321 | "requires": { 322 | "wrappy": "1" 323 | } 324 | }, 325 | "os-homedir": { 326 | "version": "1.0.2", 327 | "bundled": true 328 | }, 329 | "os-tmpdir": { 330 | "version": "1.0.2", 331 | "bundled": true 332 | }, 333 | "osenv": { 334 | "version": "0.1.5", 335 | "bundled": true, 336 | "requires": { 337 | "os-homedir": "^1.0.0", 338 | "os-tmpdir": "^1.0.0" 339 | } 340 | }, 341 | "path-is-absolute": { 342 | "version": "1.0.1", 343 | "bundled": true 344 | }, 345 | "process-nextick-args": { 346 | "version": "2.0.0", 347 | "bundled": true 348 | }, 349 | "rc": { 350 | "version": "1.2.8", 351 | "bundled": true, 352 | "requires": { 353 | "deep-extend": "^0.6.0", 354 | "ini": "~1.3.0", 355 | "minimist": "^1.2.0", 356 | "strip-json-comments": "~2.0.1" 357 | }, 358 | "dependencies": { 359 | "minimist": { 360 | "version": "1.2.0", 361 | "bundled": true 362 | } 363 | } 364 | }, 365 | "readable-stream": { 366 | "version": "2.3.6", 367 | "bundled": true, 368 | "requires": { 369 | "core-util-is": "~1.0.0", 370 | "inherits": "~2.0.3", 371 | "isarray": "~1.0.0", 372 | "process-nextick-args": "~2.0.0", 373 | "safe-buffer": "~5.1.1", 374 | "string_decoder": "~1.1.1", 375 | "util-deprecate": "~1.0.1" 376 | } 377 | }, 378 | "rimraf": { 379 | "version": "2.6.2", 380 | "bundled": true, 381 | "requires": { 382 | "glob": "^7.0.5" 383 | } 384 | }, 385 | "safe-buffer": { 386 | "version": "5.1.2", 387 | "bundled": true 388 | }, 389 | "safer-buffer": { 390 | "version": "2.1.2", 391 | "bundled": true 392 | }, 393 | "sax": { 394 | "version": "1.2.4", 395 | "bundled": true 396 | }, 397 | "semver": { 398 | "version": "5.6.0", 399 | "bundled": true 400 | }, 401 | "set-blocking": { 402 | "version": "2.0.0", 403 | "bundled": true 404 | }, 405 | "signal-exit": { 406 | "version": "3.0.2", 407 | "bundled": true 408 | }, 409 | "string-width": { 410 | "version": "1.0.2", 411 | "bundled": true, 412 | "requires": { 413 | "code-point-at": "^1.0.0", 414 | "is-fullwidth-code-point": "^1.0.0", 415 | "strip-ansi": "^3.0.0" 416 | } 417 | }, 418 | "string_decoder": { 419 | "version": "1.1.1", 420 | "bundled": true, 421 | "requires": { 422 | "safe-buffer": "~5.1.0" 423 | } 424 | }, 425 | "strip-ansi": { 426 | "version": "3.0.1", 427 | "bundled": true, 428 | "requires": { 429 | "ansi-regex": "^2.0.0" 430 | } 431 | }, 432 | "strip-json-comments": { 433 | "version": "2.0.1", 434 | "bundled": true 435 | }, 436 | "tar": { 437 | "version": "4.4.8", 438 | "bundled": true, 439 | "requires": { 440 | "chownr": "^1.1.1", 441 | "fs-minipass": "^1.2.5", 442 | "minipass": "^2.3.4", 443 | "minizlib": "^1.1.1", 444 | "mkdirp": "^0.5.0", 445 | "safe-buffer": "^5.1.2", 446 | "yallist": "^3.0.2" 447 | } 448 | }, 449 | "util-deprecate": { 450 | "version": "1.0.2", 451 | "bundled": true 452 | }, 453 | "wide-align": { 454 | "version": "1.1.3", 455 | "bundled": true, 456 | "requires": { 457 | "string-width": "^1.0.2 || 2" 458 | } 459 | }, 460 | "wrappy": { 461 | "version": "1.0.2", 462 | "bundled": true 463 | }, 464 | "yallist": { 465 | "version": "3.0.3", 466 | "bundled": true 467 | } 468 | } 469 | } 470 | } 471 | } 472 | -------------------------------------------------------------------------------- /abapdeploy.js/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "abapdeploy", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/caseless": { 8 | "version": "0.12.2", 9 | "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", 10 | "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" 11 | }, 12 | "@types/form-data": { 13 | "version": "2.2.1", 14 | "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", 15 | "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", 16 | "requires": { 17 | "@types/node": "*" 18 | } 19 | }, 20 | "@types/node": { 21 | "version": "11.13.0", 22 | "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.0.tgz", 23 | "integrity": "sha512-rx29MMkRdVmzunmiA4lzBYJNnXsW/PhG4kMBy2ATsYaDjGGR75dCFEVVROKpNwlVdcUX3xxlghKQOeDPBJobng==" 24 | }, 25 | "@types/request": { 26 | "version": "2.48.1", 27 | "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz", 28 | "integrity": "sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg==", 29 | "requires": { 30 | "@types/caseless": "*", 31 | "@types/form-data": "*", 32 | "@types/node": "*", 33 | "@types/tough-cookie": "*" 34 | } 35 | }, 36 | "@types/tough-cookie": { 37 | "version": "2.3.5", 38 | "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", 39 | "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==" 40 | }, 41 | "abap-adt-api": { 42 | "version": "0.5.17", 43 | "resolved": "https://registry.npmjs.org/abap-adt-api/-/abap-adt-api-0.5.17.tgz", 44 | "integrity": "sha512-zMBQmVSjhkdRCT/ysSvkg7T4uJVHntAnLWJkT3m6fFwc1HRkZU+hwB9e3LqRQKsf235+GUb9VpLvSvd4Ah3QXg==", 45 | "requires": { 46 | "@types/request": "^2.48.1", 47 | "fast-xml-parser": "^3.12.12", 48 | "html-entities": "^1.2.1", 49 | "request": "^2.88.0", 50 | "sprintf-js": "^1.1.2", 51 | "tough-cookie": "^3.0.1" 52 | } 53 | }, 54 | "ajv": { 55 | "version": "6.10.0", 56 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", 57 | "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", 58 | "requires": { 59 | "fast-deep-equal": "^2.0.1", 60 | "fast-json-stable-stringify": "^2.0.0", 61 | "json-schema-traverse": "^0.4.1", 62 | "uri-js": "^4.2.2" 63 | } 64 | }, 65 | "asn1": { 66 | "version": "0.2.4", 67 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 68 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 69 | "requires": { 70 | "safer-buffer": "~2.1.0" 71 | } 72 | }, 73 | "assert-plus": { 74 | "version": "1.0.0", 75 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 76 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 77 | }, 78 | "asynckit": { 79 | "version": "0.4.0", 80 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 81 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 82 | }, 83 | "aws-sign2": { 84 | "version": "0.7.0", 85 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 86 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 87 | }, 88 | "aws4": { 89 | "version": "1.8.0", 90 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", 91 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" 92 | }, 93 | "bcrypt-pbkdf": { 94 | "version": "1.0.2", 95 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 96 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 97 | "requires": { 98 | "tweetnacl": "^0.14.3" 99 | } 100 | }, 101 | "caseless": { 102 | "version": "0.12.0", 103 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 104 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 105 | }, 106 | "combined-stream": { 107 | "version": "1.0.7", 108 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", 109 | "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", 110 | "requires": { 111 | "delayed-stream": "~1.0.0" 112 | } 113 | }, 114 | "commander": { 115 | "version": "2.20.0", 116 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", 117 | "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" 118 | }, 119 | "configstore": { 120 | "version": "4.0.0", 121 | "resolved": "https://registry.npmjs.org/configstore/-/configstore-4.0.0.tgz", 122 | "integrity": "sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==", 123 | "requires": { 124 | "dot-prop": "^4.1.0", 125 | "graceful-fs": "^4.1.2", 126 | "make-dir": "^1.0.0", 127 | "unique-string": "^1.0.0", 128 | "write-file-atomic": "^2.0.0", 129 | "xdg-basedir": "^3.0.0" 130 | } 131 | }, 132 | "core-util-is": { 133 | "version": "1.0.2", 134 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 135 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 136 | }, 137 | "crypto-random-string": { 138 | "version": "1.0.0", 139 | "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", 140 | "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" 141 | }, 142 | "dashdash": { 143 | "version": "1.14.1", 144 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 145 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 146 | "requires": { 147 | "assert-plus": "^1.0.0" 148 | } 149 | }, 150 | "delayed-stream": { 151 | "version": "1.0.0", 152 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 153 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 154 | }, 155 | "dot-prop": { 156 | "version": "4.2.0", 157 | "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", 158 | "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", 159 | "requires": { 160 | "is-obj": "^1.0.0" 161 | } 162 | }, 163 | "ecc-jsbn": { 164 | "version": "0.1.2", 165 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 166 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 167 | "requires": { 168 | "jsbn": "~0.1.0", 169 | "safer-buffer": "^2.1.0" 170 | } 171 | }, 172 | "extend": { 173 | "version": "3.0.2", 174 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 175 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 176 | }, 177 | "extsprintf": { 178 | "version": "1.3.0", 179 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 180 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 181 | }, 182 | "fast-deep-equal": { 183 | "version": "2.0.1", 184 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 185 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" 186 | }, 187 | "fast-json-stable-stringify": { 188 | "version": "2.0.0", 189 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 190 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 191 | }, 192 | "fast-xml-parser": { 193 | "version": "3.12.16", 194 | "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.12.16.tgz", 195 | "integrity": "sha512-7ePrHTK4K9BLzY3+6ZOv2YEPOpdYJg3ohyMHxacG6kp1A0Y8KNyjrFfEHJuo8G4T7vT7cIlIXGWoHdIWu9U41A==", 196 | "requires": { 197 | "configstore": "^4.0.0", 198 | "lodash": "^4.17.11", 199 | "nimnjs": "^1.3.2" 200 | } 201 | }, 202 | "forever-agent": { 203 | "version": "0.6.1", 204 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 205 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 206 | }, 207 | "form-data": { 208 | "version": "2.3.3", 209 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 210 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 211 | "requires": { 212 | "asynckit": "^0.4.0", 213 | "combined-stream": "^1.0.6", 214 | "mime-types": "^2.1.12" 215 | } 216 | }, 217 | "getpass": { 218 | "version": "0.1.7", 219 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 220 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 221 | "requires": { 222 | "assert-plus": "^1.0.0" 223 | } 224 | }, 225 | "graceful-fs": { 226 | "version": "4.1.15", 227 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", 228 | "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" 229 | }, 230 | "har-schema": { 231 | "version": "2.0.0", 232 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 233 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 234 | }, 235 | "har-validator": { 236 | "version": "5.1.3", 237 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", 238 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", 239 | "requires": { 240 | "ajv": "^6.5.5", 241 | "har-schema": "^2.0.0" 242 | } 243 | }, 244 | "html-entities": { 245 | "version": "1.2.1", 246 | "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", 247 | "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=" 248 | }, 249 | "http-signature": { 250 | "version": "1.2.0", 251 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 252 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 253 | "requires": { 254 | "assert-plus": "^1.0.0", 255 | "jsprim": "^1.2.2", 256 | "sshpk": "^1.7.0" 257 | } 258 | }, 259 | "imurmurhash": { 260 | "version": "0.1.4", 261 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 262 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" 263 | }, 264 | "ip-regex": { 265 | "version": "2.1.0", 266 | "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", 267 | "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" 268 | }, 269 | "is-obj": { 270 | "version": "1.0.1", 271 | "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", 272 | "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" 273 | }, 274 | "is-typedarray": { 275 | "version": "1.0.0", 276 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 277 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 278 | }, 279 | "isstream": { 280 | "version": "0.1.2", 281 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 282 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 283 | }, 284 | "jsbn": { 285 | "version": "0.1.1", 286 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 287 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 288 | }, 289 | "json-schema": { 290 | "version": "0.2.3", 291 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 292 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 293 | }, 294 | "json-schema-traverse": { 295 | "version": "0.4.1", 296 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 297 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 298 | }, 299 | "json-stringify-safe": { 300 | "version": "5.0.1", 301 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 302 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 303 | }, 304 | "jsprim": { 305 | "version": "1.4.1", 306 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 307 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 308 | "requires": { 309 | "assert-plus": "1.0.0", 310 | "extsprintf": "1.3.0", 311 | "json-schema": "0.2.3", 312 | "verror": "1.10.0" 313 | } 314 | }, 315 | "lodash": { 316 | "version": "4.17.19", 317 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", 318 | "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" 319 | }, 320 | "make-dir": { 321 | "version": "1.3.0", 322 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", 323 | "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", 324 | "requires": { 325 | "pify": "^3.0.0" 326 | } 327 | }, 328 | "mime-db": { 329 | "version": "1.38.0", 330 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", 331 | "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==" 332 | }, 333 | "mime-types": { 334 | "version": "2.1.22", 335 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", 336 | "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", 337 | "requires": { 338 | "mime-db": "~1.38.0" 339 | } 340 | }, 341 | "nimn-date-parser": { 342 | "version": "1.0.0", 343 | "resolved": "https://registry.npmjs.org/nimn-date-parser/-/nimn-date-parser-1.0.0.tgz", 344 | "integrity": "sha512-1Nf+x3EeMvHUiHsVuEhiZnwA8RMeOBVTQWfB1S2n9+i6PYCofHd2HRMD+WOHIHYshy4T4Gk8wQoCol7Hq3av8Q==" 345 | }, 346 | "nimn_schema_builder": { 347 | "version": "1.1.0", 348 | "resolved": "https://registry.npmjs.org/nimn_schema_builder/-/nimn_schema_builder-1.1.0.tgz", 349 | "integrity": "sha512-DK5/B8CM4qwzG2URy130avcwPev4uO0ev836FbQyKo1ms6I9z/i6EJyiZ+d9xtgloxUri0W+5gfR8YbPq7SheA==" 350 | }, 351 | "nimnjs": { 352 | "version": "1.3.2", 353 | "resolved": "https://registry.npmjs.org/nimnjs/-/nimnjs-1.3.2.tgz", 354 | "integrity": "sha512-TIOtI4iqkQrUM1tiM76AtTQem0c7e56SkDZ7sj1d1MfUsqRcq2ZWQvej/O+HBTZV7u/VKnwlKTDugK/75IRPPw==", 355 | "requires": { 356 | "nimn-date-parser": "^1.0.0", 357 | "nimn_schema_builder": "^1.0.0" 358 | } 359 | }, 360 | "oauth-sign": { 361 | "version": "0.9.0", 362 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 363 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 364 | }, 365 | "performance-now": { 366 | "version": "2.1.0", 367 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 368 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 369 | }, 370 | "pify": { 371 | "version": "3.0.0", 372 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 373 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" 374 | }, 375 | "psl": { 376 | "version": "1.1.31", 377 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", 378 | "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==" 379 | }, 380 | "punycode": { 381 | "version": "2.1.1", 382 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 383 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 384 | }, 385 | "qs": { 386 | "version": "6.5.2", 387 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 388 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 389 | }, 390 | "request": { 391 | "version": "2.88.0", 392 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", 393 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", 394 | "requires": { 395 | "aws-sign2": "~0.7.0", 396 | "aws4": "^1.8.0", 397 | "caseless": "~0.12.0", 398 | "combined-stream": "~1.0.6", 399 | "extend": "~3.0.2", 400 | "forever-agent": "~0.6.1", 401 | "form-data": "~2.3.2", 402 | "har-validator": "~5.1.0", 403 | "http-signature": "~1.2.0", 404 | "is-typedarray": "~1.0.0", 405 | "isstream": "~0.1.2", 406 | "json-stringify-safe": "~5.0.1", 407 | "mime-types": "~2.1.19", 408 | "oauth-sign": "~0.9.0", 409 | "performance-now": "^2.1.0", 410 | "qs": "~6.5.2", 411 | "safe-buffer": "^5.1.2", 412 | "tough-cookie": "~2.4.3", 413 | "tunnel-agent": "^0.6.0", 414 | "uuid": "^3.3.2" 415 | }, 416 | "dependencies": { 417 | "punycode": { 418 | "version": "1.4.1", 419 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 420 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 421 | }, 422 | "tough-cookie": { 423 | "version": "2.4.3", 424 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", 425 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 426 | "requires": { 427 | "psl": "^1.1.24", 428 | "punycode": "^1.4.1" 429 | } 430 | } 431 | } 432 | }, 433 | "safe-buffer": { 434 | "version": "5.1.2", 435 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 436 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 437 | }, 438 | "safer-buffer": { 439 | "version": "2.1.2", 440 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 441 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 442 | }, 443 | "signal-exit": { 444 | "version": "3.0.2", 445 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 446 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 447 | }, 448 | "sprintf-js": { 449 | "version": "1.1.2", 450 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", 451 | "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" 452 | }, 453 | "sshpk": { 454 | "version": "1.16.1", 455 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 456 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 457 | "requires": { 458 | "asn1": "~0.2.3", 459 | "assert-plus": "^1.0.0", 460 | "bcrypt-pbkdf": "^1.0.0", 461 | "dashdash": "^1.12.0", 462 | "ecc-jsbn": "~0.1.1", 463 | "getpass": "^0.1.1", 464 | "jsbn": "~0.1.0", 465 | "safer-buffer": "^2.0.2", 466 | "tweetnacl": "~0.14.0" 467 | } 468 | }, 469 | "tough-cookie": { 470 | "version": "3.0.1", 471 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", 472 | "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", 473 | "requires": { 474 | "ip-regex": "^2.1.0", 475 | "psl": "^1.1.28", 476 | "punycode": "^2.1.1" 477 | } 478 | }, 479 | "tunnel-agent": { 480 | "version": "0.6.0", 481 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 482 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 483 | "requires": { 484 | "safe-buffer": "^5.0.1" 485 | } 486 | }, 487 | "tweetnacl": { 488 | "version": "0.14.5", 489 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 490 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 491 | }, 492 | "unique-string": { 493 | "version": "1.0.0", 494 | "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", 495 | "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", 496 | "requires": { 497 | "crypto-random-string": "^1.0.0" 498 | } 499 | }, 500 | "uri-js": { 501 | "version": "4.2.2", 502 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 503 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 504 | "requires": { 505 | "punycode": "^2.1.0" 506 | } 507 | }, 508 | "uuid": { 509 | "version": "3.3.2", 510 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", 511 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" 512 | }, 513 | "verror": { 514 | "version": "1.10.0", 515 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 516 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 517 | "requires": { 518 | "assert-plus": "^1.0.0", 519 | "core-util-is": "1.0.2", 520 | "extsprintf": "^1.2.0" 521 | } 522 | }, 523 | "write-file-atomic": { 524 | "version": "2.4.2", 525 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", 526 | "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", 527 | "requires": { 528 | "graceful-fs": "^4.1.11", 529 | "imurmurhash": "^0.1.4", 530 | "signal-exit": "^3.0.2" 531 | } 532 | }, 533 | "xdg-basedir": { 534 | "version": "3.0.0", 535 | "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", 536 | "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" 537 | } 538 | } 539 | } 540 | --------------------------------------------------------------------------------