Browse Source

add hybrid ssh

master
zeus 8 months ago
parent
commit
5dde85410e
43 changed files with 2259 additions and 643 deletions
  1. +3
    -0
      README.md
  2. +9
    -0
      hybrid/create-keys.sh
  3. +4
    -0
      hybrid/keys.json
  4. +1
    -1
      hybrid/privatekey
  5. +1
    -1
      hybrid/publickey
  6. +44
    -0
      src-local/hybrid/connect/join-backup.sh
  7. +43
    -0
      src-local/hybrid/connect/join.sh
  8. +23
    -0
      src-local/hybrid/connect/leave-backup.sh
  9. +23
    -0
      src-local/hybrid/connect/leave.sh
  10. +1
    -0
      src-local/hybrid/connect/privatekey
  11. +1
    -0
      src-local/hybrid/connect/publickey
  12. +16
    -0
      src-local/hybrid/connect/status-wg.sh
  13. +37
    -0
      src-local/hybrid/connect/status.sh
  14. +33
    -0
      src-local/hybrid/connect/swarmlab-connect.sh
  15. +38
    -0
      src-local/hybrid/connect/template-connect.sh
  16. +2
    -0
      src-local/hybrid/connect/template-swarm.sh
  17. +10
    -0
      src-local/hybrid/connect/template-wg0.conf
  18. +11
    -0
      src-local/hybrid/connect/wg-test.sh
  19. +10
    -0
      src-local/hybrid/connect/wg0.conf
  20. +9
    -0
      src-local/hybrid/create-keys.sh
  21. +2
    -0
      src-local/hybrid/join.sh
  22. +1
    -0
      src-local/hybrid/keys.json
  23. +1
    -0
      src-local/hybrid/privatekey
  24. +1
    -0
      src-local/hybrid/publickey
  25. +29
    -0
      src-local/hybrid/scripts/add-nic-veth-pair.sh
  26. +26
    -0
      src-local/hybrid/scripts/add-nic.sh
  27. +24
    -0
      src-local/hybrid/scripts/expose-netns.sh
  28. +0
    -48
      src-local/llo/bclient.js
  29. +0
    -32
      src-local/llo/client.js
  30. +0
    -40
      src-local/llo/iotclient.js
  31. +0
    -381
      src-local/llo/iotserver.js
  32. +285
    -0
      src-local/llo/new.js
  33. +0
    -29
      src-local/llo/pubsub.js
  34. +0
    -32
      src-local/llo/test.js
  35. +0
    -38
      src-local/llo/test1.js
  36. +40
    -5
      src/App.vue
  37. +55
    -0
      src/components/manageservices.vue
  38. +670
    -0
      src/components/manageservices/manage-service.vue
  39. +55
    -0
      src/components/myconnect-server.vue
  40. +396
    -0
      src/components/mynetwork/myconnect-server.vue
  41. +69
    -0
      src/components/mynetwork/mytable.vue
  42. +139
    -2
      src/store/modules/create_pipelineLLO.js
  43. +147
    -34
      viwsession/session1

+ 3
- 0
README.md View File

@@ -1,2 +1,5 @@
# swarmlab-hybrid

jq
sudo apt install wireguard


+ 9
- 0
hybrid/create-keys.sh View File

@@ -0,0 +1,9 @@


wg genkey | tee ./privatekey | wg pubkey > ./publickey

privatekey=$(head -1 ./privatekey)
publickey=$(head -1 ./publickey)

jq --arg key0 'private' --arg private $privatekey --arg key1 'public' --arg public $publickey '. | .[$key0]=$private | .[$key1]=$public ' <<<'{}' > ./keys.json


+ 4
- 0
hybrid/keys.json View File

@@ -0,0 +1,4 @@
{
"private": "EDcHFoG5cE/110wPaYgVjNdtHkULRMDE9vECia/4I3g=",
"public": "hQ4VKJePvguRkcGOOaT7fcKNE2HyYGqBoacByNNd7Xo="
}

+ 1
- 1
hybrid/privatekey View File

@@ -1 +1 @@
6CdrILpdZcm1OfOecSQSgaI90sLNOTVW9zO9Dac5b0w=
kCoimlkUSkb4MaEVoI4ePThzKDYNZF9A/4d0L1u3q38=

+ 1
- 1
hybrid/publickey View File

@@ -1 +1 @@
fEirlFuleXLeY2pgsCVb8G16DEVXJVGJuXdifX1+/wY=
R97cS/PXC5N1dxom0pODyNhqnXfyIUqg04Fu1OU0fGs=

+ 44
- 0
src-local/hybrid/connect/join-backup.sh View File

@@ -0,0 +1,44 @@

function swarmlab_ifup() {
swarmlab=$(/bin/bash /data/appl/ok/swarmlab-hybrid-agent/src-local/hybrid/connect/status.sh wg0 | jq .swarmlab)
tempswarm="${swarmlab%\"}"
tempswarm="${tempswarm#\"}"
swarmlab=$tempswarm
echo $swarmlab
}
function hybrid_ifup() {
hybrid=$(/bin/bash /data/appl/ok/swarmlab-hybrid-agent/src-local/hybrid/connect/status.sh wg0 | jq .hybrid)
tempswarm1="${hybrid%\"}"
tempswarm1="${tempswarm1#\"}"
hybrid=$tempswarm1
echo $hybrid
}

hybrid=$(hybrid_ifup)
if [ $hybrid == 'NotOnline' ]; then
/bin/bash /data/appl/ok/swarmlab-hybrid-agent/src-local/hybrid/connect/swarmlab-connect.sh
sleep 2
hybrid1=$(hybrid_ifup)
if [ $hybrid1 == 'NotOnline' ]; then
echo "Failed to start wg0 network interface"
else
echo "Swarmlab hybrid $hybrid"
fi
else
echo "Swarmlab hybrid $hybrid"
fi

swarmlab=$(swarmlab_ifup)
if [ $swarmlab != 'active' ]; then
sleep 1
swarmlab1=$(swarmlab_ifup)
if [ $swarmlab1 != 'active' ]; then
echo "Failed to connect on swarmlab master"
echo "Exec "
echo "/bin/bash /data/appl/ok/swarmlab-hybrid-agent/src-local/hybrid/connect/reload-swarmlab.sh"
echo "Please try again"
fi
else
echo "Swarmlab master $swarmlab"
fi


+ 43
- 0
src-local/hybrid/connect/join.sh View File

@@ -0,0 +1,43 @@

function swarmlab_ifup() {
swarmlab=$(/bin/bash /data/appl/ok/swarmlab-hybrid-agent/src-local/hybrid/connect/status.sh wg0 | jq .swarmlab)
tempswarm="${swarmlab%\"}"
tempswarm="${tempswarm#\"}"
swarmlab=$tempswarm
echo $swarmlab
}
function hybrid_ifup() {
hybrid=$(/bin/bash /data/appl/ok/swarmlab-hybrid-agent/src-local/hybrid/connect/status.sh wg0 | jq .hybrid)
tempswarm1="${hybrid%\"}"
tempswarm1="${tempswarm1#\"}"
hybrid=$tempswarm1
echo $hybrid
}

hybrid=$(hybrid_ifup)
if [ $hybrid == 'NotOnline' ]; then
/bin/bash /data/appl/ok/swarmlab-hybrid-agent/src-local/hybrid/connect/swarmlab-connect.sh
sleep 2
hybrid1=$(hybrid_ifup)
if [ $hybrid1 == 'NotOnline' ]; then
echo "Failed to start wg0 network interface"
else
echo "Swarmlab hybrid $hybrid"
fi
else
echo "Swarmlab hybrid $hybrid"
fi

swarmlab=$(swarmlab_ifup)
if [ $swarmlab != 'active' ]; then
sleep 1
swarmlab1=$(swarmlab_ifup)
if [ $swarmlab1 != 'active' ]; then
echo "Failed to connect on swarmlab master"
echo "Exec "
echo "/bin/bash /data/appl/ok/swarmlab-hybrid-agent/src-local/hybrid/connect/reload-swarmlab.sh"
echo "Please try again"
fi
else
echo "Swarmlab master $swarmlab"
fi

+ 23
- 0
src-local/hybrid/connect/leave-backup.sh View File

@@ -0,0 +1,23 @@
function hybrid_ifup() {
hybrid=$(/bin/bash /data/appl/ok/swarmlab-hybrid-agent/src-local/hybrid/connect/status.sh wg0 | jq .hybrid)
tempswarm1="${hybrid%\"}"
tempswarm1="${tempswarm1#\"}"
hybrid=$tempswarm1
echo $hybrid
}

hybrid=$(hybrid_ifup)
if [ $hybrid == 'NotOnline' ]; then
echo "Swarmlab hybrid $hybrid"
else
ip link set wg0 down
ip link del wg0
sleep 3
hybrid1=$(hybrid_ifup)
if [ $hybrid1 == 'NotOnline' ]; then
echo "Swarmlab hybrid $hybrid"
else
echo "Swarmlab hybrid $hybrid"
fi
fi


+ 23
- 0
src-local/hybrid/connect/leave.sh View File

@@ -0,0 +1,23 @@

function hybrid_ifup() {
hybrid=$(/bin/bash /data/appl/ok/swarmlab-hybrid-agent/src-local/hybrid/connect/status.sh wg0 | jq .hybrid)
tempswarm1="${hybrid%\"}"
tempswarm1="${tempswarm1#\"}"
hybrid=$tempswarm1
echo $hybrid
}

hybrid=$(hybrid_ifup)
if [ $hybrid == 'NotOnline' ]; then
echo "Swarmlab hybrid $hybrid"
else
ip link set wg0 down
ip link del wg0
sleep 3
hybrid1=$(hybrid_ifup)
if [ $hybrid1 == 'NotOnline' ]; then
echo "Swarmlab hybrid $hybrid"
else
echo "Swarmlab hybrid $hybrid"
fi
fi

+ 1
- 0
src-local/hybrid/connect/privatekey View File

@@ -0,0 +1 @@
uHuqIEOoQTsESNhiz7Uu1COJlbIHdruBiMUG1GvBTHM=

+ 1
- 0
src-local/hybrid/connect/publickey View File

@@ -0,0 +1 @@
ol5eKuHsOOAY9mWpVnsVTG+EODv8Hcl8bMobkNx4Si8=

+ 16
- 0
src-local/hybrid/connect/status-wg.sh View File

@@ -0,0 +1,16 @@

function ifup {
if [[ ! -d /sys/class/net/${1} ]]; then
#printf 'No such interface: %s\n' "$1" >&2
return 1
else
[[ $(</sys/class/net/${1}/operstate) == up ]]
fi
}

if ifup $1; then
echo Online
else
echo 'Not online'
fi


+ 37
- 0
src-local/hybrid/connect/status.sh View File

@@ -0,0 +1,37 @@


function ifup {
if [[ ! -d /sys/class/net/${1} ]]; then
return 1
else
[[ $(</sys/class/net/${1}/carrier) == 1 ]]
fi
}

if ifup $1; then
hybridswarm='Online'
else
hybridswarm='NotOnline'
fi


dockerswarm=$(docker info --format "{{json .}}" | jq .Swarm.LocalNodeState)
tempswarm="${dockerswarm%\"}"
tempswarm="${tempswarm#\"}"
dockerswarm=$tempswarm

dockerswarmid=$(docker info --format "{{json .}}" | jq .Swarm.NodeID)
tempswarm1="${dockerswarmid%\"}"
tempswarm1="${tempswarm1#\"}"
swarmlabid=$tempswarm1
#echo $dockerswarm
#echo $hybridswarm
#echo $swarmlabid

#jq --arg key0 'swarmlab' --arg swarmlab $dockerswarm --arg key1 'hybrid' --arg hybrid $hybridswarm --arg key2 'swarmlabid' --arg swarmlabid $swarmlabid'. | .[$key0]=$swarmlab | .[$key1]=$hybrid | .[$key2]=$swarmlabid' <<<'{}'
jq \
--arg key0 'swarmlab' --arg swarmlab $dockerswarm \
--arg key1 'hybrid' --arg hybrid $hybridswarm \
--arg key2 'swarmlabid' --arg swarmlabid $swarmlabid \
'. | .[$key0]=$swarmlab | .[$key1]=$hybrid | .[$key2]=$swarmlabid' <<<'{}'


+ 33
- 0
src-local/hybrid/connect/swarmlab-connect.sh View File

@@ -0,0 +1,33 @@

DEV_NAME=wg0
INTERFACE_IP=10.13.13.2/16
INTERFACE_IProute=10.13.13.2
ENDPOINT_IP=83.212.77.133

ip link set $DEV_NAME down
ip link del $DEV_NAME
# add wireguard interface
ip link add $DEV_NAME type wireguard

# set wireguard conf
wg setconf $DEV_NAME /data/appl/ok/swarmlab-hybrid-agent/src-local/hybrid/connect/$DEV_NAME.conf

# assign ip to wireguard interface
ip addr add $INTERFACE_IP dev $DEV_NAME

# set sysctl
sysctl -w net.ipv4.conf.all.rp_filter=2

# set mtu for wireguard interface
ip link set mtu 1420 up dev $DEV_NAME

# bring wireguard interface up
ip link set up dev $DEV_NAME

# add route
ip route add default via $INTERFACE_IProute metric 2 table 200
ip route show table 200 | grep -w $INTERFACE_IProute

# add local lan route
ip rule add table main suppress_prefixlength 0
ip rule show | grep -w "suppress_prefixlength"

+ 38
- 0
src-local/hybrid/connect/template-connect.sh View File

@@ -0,0 +1,38 @@

DEV_NAME=wg0
#INTERFACE_IP=10.13.13.2/24
INTERFACE_IP=10.13.13.2/16
INTERFACE_IProute=10.13.13.2
ENDPOINT_IP=`grep Endpoint /etc/wireguard/$DEV_NAME.conf | awk '{print $3}' | cut -d: -f1`

echo "ip $INTERFACE_IP"

ip link set $DEV_NAME down
ip link del $DEV_NAME
# add wireguard interface
ip link add $DEV_NAME type wireguard

# set wireguard conf
wg setconf $DEV_NAME /etc/wireguard/$DEV_NAME.conf


# assign ip to wireguard interface
ip addr add $INTERFACE_IP dev $DEV_NAME

# set sysctl
sysctl -w net.ipv4.conf.all.rp_filter=2

# set mtu for wireguard interface
ip link set mtu 1420 up dev $DEV_NAME

# bring wireguard interface up
ip link set up dev $DEV_NAME

# add route
ip route add default via $INTERFACE_IProute metric 2 table 200
ip route show table 200 | grep -w $INTERFACE_IProute

# add local lan route
ip rule add table main suppress_prefixlength 0
ip rule show | grep -w "suppress_prefixlength"


+ 2
- 0
src-local/hybrid/connect/template-swarm.sh View File

@@ -0,0 +1,2 @@

docker swarm join --token SWMTKN-1-3099nls9my5ns1s0mnmwkx41mhpawl80hwjjbskbll7nghqhgn-asu68y4lhd1qlbpxr6oosk6wl 10.13.13.1:2377

+ 10
- 0
src-local/hybrid/connect/template-wg0.conf View File

@@ -0,0 +1,10 @@
[Interface]
PrivateKey = kJd3ga9/1b5NalONMP+CuezTZB+ZmaQVdzM7jLYUe30=
ListenPort = 51820

[Peer]
PublicKey = WAuzcpIf1obckeLP94owls31j58LP2k+yIAasx9VFU8=
Endpoint = 83.212.77.133:51820
AllowedIPs = 10.13.13.0/16, 0.0.0.0/0, ::/0
PersistentKeepalive = 30


+ 11
- 0
src-local/hybrid/connect/wg-test.sh View File

@@ -0,0 +1,11 @@
[Interface]
PrivateKey = CCJXNalGbNIDK5oz5IG8lGuQFATfEcSILw7tWqNO9U4
ListenPort = 51820

[Peer]
#PublicKey = WAuzcpIf1obckeLP94owls31j58LP2k+yIAasx9VFU8=
PublicKey = yMTjzSFQloNH22v+sN9k4cIaOUujq/m+vB2HJdJM7GI=
Endpoint = 83.212.77.133:51820
AllowedIPs = 10.13.13.0/24, 0.0.0.0/0, ::/0
PersistentKeepalive = 30


+ 10
- 0
src-local/hybrid/connect/wg0.conf View File

@@ -0,0 +1,10 @@
[Interface]
PrivateKey = kJd3ga9/1b5NalONMP+CuezTZB+ZmaQVdzM7jLYUe30=
ListenPort = 51820

[Peer]
PublicKey = WAuzcpIf1obckeLP94owls31j58LP2k+yIAasx9VFU8=
Endpoint = 83.212.77.133:51820
AllowedIPs = 10.13.13.0/16, 0.0.0.0/0, ::/0
PersistentKeepalive = 30


+ 9
- 0
src-local/hybrid/create-keys.sh View File

@@ -0,0 +1,9 @@


wg genkey | tee ./privatekey | wg pubkey > ./publickey

privatekey=$(head -1 ./privatekey)
publickey=$(head -1 ./publickey)

jq --arg key0 'private' --arg private $privatekey --arg key1 'public' --arg public $publickey '. | .[$key0]=$private | .[$key1]=$public ' <<<'{}' | tee ./keys.json


+ 2
- 0
src-local/hybrid/join.sh View File

@@ -0,0 +1,2 @@
docker swarm join --token SWMTKN-1-3099nls9my5ns1s0mnmwkx41mhpawl80hwjjbskbll7nghqhgn-asu68y4lhd1qlbpxr6oosk6wl 10.13.13.1:2377


+ 1
- 0
src-local/hybrid/keys.json View File

@@ -0,0 +1 @@
"{\"status\":\"off\",\"privatekey\":\"kJd3ga9/1b5NalONMP+CuezTZB+ZmaQVdzM7jLYUe30=\",\"publickey\":\"jf4fC0tmGe4Ioz+dY5c/AksqicZGGqJIH1OncOUIuj8=\",\"server_ip\":\"83.212.77.133:51820\",\"workerkey\":\"SWMTKN-1-3099nls9my5ns1s0mnmwkx41mhpawl80hwjjbskbll7nghqhgn-asu68y4lhd1qlbpxr6oosk6wl\",\"allowed_ips\":\"10.13.13.0/16, 0.0.0.0/0, ::/0\",\"swarmlab_public_wgkey\":\"WAuzcpIf1obckeLP94owls31j58LP2k+yIAasx9VFU8=\",\"wg_ip\":\"10.13.13.2\",\"swarm_ip\":\"10.13.13.1:2377\",\"wg_port\":\"51820\"}"

+ 1
- 0
src-local/hybrid/privatekey View File

@@ -0,0 +1 @@
EEQqA/IEqbKRHuo8Har5JsjatOYY++JMmiU/QEr4zlw=

+ 1
- 0
src-local/hybrid/publickey View File

@@ -0,0 +1 @@
iAn+EwqtojVrIV58N5jpnjlHeqCYhGKS8gHpaHuieBA=

+ 29
- 0
src-local/hybrid/scripts/add-nic-veth-pair.sh View File

@@ -0,0 +1,29 @@
#!/bin/sh

if [ $# -lt 3 ]; then
echo "This script will create a veth pair, attach one end to an OVS bridge,"
echo "and another end to the specified container as a virtual NIC."
echo ""
echo "Usage: $0 <CONTAINER> <VETH> <PEER> <OVS BRIDGE>"
echo "Example: $0 test-container-1 veth-1 peer-1 br-int"
exit 1
fi

CONTAINER=$1
VETH=$2
PEER=$3
OVS_BR=$4
NETNS=`sudo docker inspect -f '{{.State.Pid}}' $CONTAINER`

echo "add veth pair[$VETH <--> $PEER] to container[$CONTAINER] in netns[$NETNS]"
ip link delete $VETH || true
ip link add $VETH type veth peer name $PEER

echo "add port to ovs bridge $OVS_BR"
ovs-vsctl add-port $OVS_BR $VETH

echo "move $PEER to netns $NETNS"
ip link set $PEER netns $NETNS
ip netns exec $NETNS ip link set dev $PEER up

echo "done"

+ 26
- 0
src-local/hybrid/scripts/add-nic.sh View File

@@ -0,0 +1,26 @@
#!/bin/sh

if [ $# -lt 3 ]; then
echo "This script will add an OVS internal port to an OVS bridge,"
echo "then assign the port to the specified container as a virtual NIC."
echo ""
echo "Usage: $0 <CONTAINER> <NIC NAME> <OVS BRIDGE>"
echo "Example: $0 test-container-1 vnic-1 br-int"
exit 1
fi

CONTAINER=$1
PORT=$2
OVS_BR=$3
NETNS=`sudo docker inspect -f '{{.State.Pid}}' $CONTAINER`
echo "add port[$PORT] to container[$CONTAINER] in netns[$NETNS]"

echo "add port to ovs bridge $OVS_BR"
ovs-vsctl add-port $OVS_BR $PORT -- set Interface $PORT type=internal
#ovs-vsctl add-port br-int vnic-1 -- set Interface vnic-1 type=internal

echo "move $PORT to netns $NETNS"
ip link set $PORT netns $NETNS
ip netns exec $NETNS ip link set dev $PORT up

echo "done"

+ 24
- 0
src-local/hybrid/scripts/expose-netns.sh View File

@@ -0,0 +1,24 @@
#!/bin/bash

if [ $# -ne 1 ]; then
echo "Usage: $0 <container id or name>"
exit 1
fi

echo "expose container $1 netns"
NETNS=`sudo docker inspect -f '{{.State.Pid}}' $1`

if [ ! -d /var/run/netns ]; then
mkdir /var/run/netns
fi
if [ -f /var/run/netns/$NETNS ]; then
rm -rf /var/run/netns/$NETNS
fi

ln -s /proc/$NETNS/ns/net /var/run/netns/$NETNS
echo "done. netns: $NETNS"

echo "============================="
echo "current network namespaces: "
echo "============================="
ip netns

+ 0
- 48
src-local/llo/bclient.js View File

@@ -1,48 +0,0 @@
var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

const socketAuth = require('socketio-auth');

socketoptions = {
secure:true,
reconnect: true,
rejectUnauthorized : false
};


// Client
var io2 = require('socket.io-client');
var socket = io2.connect('https://83.212.78.17:3088', socketoptions);

socket.on('connection', s => {
console.error('socket2 connection');
var id = s.id


var roomiot = 'iot'
socket.emit('iot', roomiot);

socket.emit('subscribe', roomiot);

socket.emit('pingServerEmit', roomiot);


s.on('message', function (data) {
console.log('from room1 '+data);
});
s.on('iot', function (data) {
console.log('from room1 '+data);
});
});

var roomiot = 'iot'
socket.emit('action', roomiot);

socket.on('message', function (data) {
console.log('from room '+data);
});




+ 0
- 32
src-local/llo/client.js View File

@@ -1,32 +0,0 @@
options = {
secure:true,
reconnect: true,
rejectUnauthorized : false
};

// Client
var io2 = require('socket.io-client');
var socket = io2.connect('http://localhost:8084', options);
//var socket = io2.connect('https://service.swarmlab.io:55583');

var msg2 = "hello";
socket.emit('pingServer', msg2);



//var socket = require('socket.io-client')('httpis://localhost:8099');
socket.on('connect', function(){
console.error('connect ...');
//socket.emit("adhoc", 'Hallo World!')
});
socket.on('customEmit', function(data){
console.error('customEmit '+data);
//socket.emit("adhoc", 'Hallo World!')

});
socket.on('disconnect', function(){
console.error('disconnect');

});
//socket.emit("adhoc", 'Hallo World!')


+ 0
- 40
src-local/llo/iotclient.js View File

@@ -1,40 +0,0 @@

var fs = require( 'fs' );
var app = require('express')();
var https = require('https');
var server = https.createServer({
key: fs.readFileSync('./llo/swarmlab.key'),
cert: fs.readFileSync('./llo/swarmlab.crt'),
//ca: fs.readFileSync('./test_ca.crt'),
requestCert: false,
rejectUnauthorized: false
},app);


server.listen(3000, () => console.error('listening on https://localhost:3000/'));
var io = require('socket.io').listen(server);
console.error('socket.io example');



io.on('connection', s => {
if( typeof s !== "undefined" ){
console.error('socket connection');
}

s.on('actionstart', obj => {
console.error('fromclient '+obj);
socket.emit("log", obj)
});
/*
s.on('s1', function(room) {
console.log('leaving room', room);
})
*/
s.on('s1', () => {
console.log('hi from server');
}); // listen to the event


});


+ 0
- 381
src-local/llo/iotserver.js View File

@@ -1,381 +0,0 @@
"use strict"

var pathmodule = require('path');
var app = require('express')();
var http = require('http').Server(app);
var https = require('https');
var CONFIG = require( pathmodule.resolve( __dirname, "runconfig.js" ) );
const io = require("socket.io")(http, {
// pingTimeout: 30000,
// allowUpgrades: false,
// serveClient: false,
// pingInterval: 10000,
// //transports: [ 'websocket', 'polling' ],
// transports: [ 'polling', 'websocket' ],
cors: {
origin: "http://localhost:8080",
methods: ["GET", "POST"],
allowedHeaders: ["my-custom-header"],
credentials: true
},
cookie: {
name: "test",
httpOnly: false,
path: "/custom"
}
});

const { DateTime } = require("luxon");


var async = require("async");
const { check, validationResult } = require('express-validator');
const urlExistSync = require("url-exist-sync");

var express = require('express');
app.use(express.json());

const axios = require('axios');
axios.defaults.timeout = 30000

const helmet = require('helmet');
app.use(helmet());

const cors = require('cors')
const whitelist = [
'http://localhost:8080',
'http://localhost:3080',
'http://localhost:3081',
'http://localhost:3082'
]
const corsOptions = {
credentials: true,
methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'],
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
allowedHeaders: [
'Content-Type',
'Authorization',
'X-Requested-With',
'device-remember-token',
'Access-Control-Allow-Origin',
'Access-Control-Allow-Headers',
'Origin',
'Accept'
],
origin: function(origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(null, true)
//callback(new Error('Not allowed by CORS'))
}
}
}
app.use(cors)



// ***************************************************
// checktoken
// ***************************************************

async function checkToken(token) {
const agent = new https.Agent({
rejectUnauthorized: false,
});
const instance = axios.create({
baseURL: 'https://api.swarmlab.io',
withCredentials: true,
rejectUnauthorized: false,
crossdomain: true,
httpsAgent: agent,
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer '+token
}
})
try {
var pipelines = {
"source":'ssologin'
}
var params = {
pipeline: pipelines
}

var options = {
headers: { 'content-type': 'application/x-www-form-urlencoded',Authorization: `Bearer ${token}` },
};

instance.defaults.timeout = 30000;
const res = await instance.post('/istokenvalidsso',params,options);
if(res.status == 200){
//console.log("check " +JSON.stringify(res.data))
return res.data
}else{
console.log("noerror: " + res)
return res.status

}
}
catch (err) {
console.error("error: "+err);
var error = new Object();
error.action = '401'
return error
}
}


function convertDateToUTC(date) {
return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(),date.getUTCMilliseconds());
}

// ***************************************************
// get pipelines
// ***************************************************

async function getpipelines(token,pipelinename) {
const agent = new https.Agent({
rejectUnauthorized: false,
});
const instance = axios.create({
baseURL: 'https://api.swarmlab.io',
withCredentials: true,
rejectUnauthorized: false,
crossdomain: true,
httpsAgent: agent,
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer '+token
}
})
/*
var params = {
playbook: value
}
var options = {
params: params,
headers: { 'content-type': 'application/x-www-form-urlencoded',Authorization: `Bearer ${token}` },
};

const playbook = await api.GET('playbookCode',options);
return playbook
*/
try {

var pipelines = {
"querytokenFilter":CONFIG.api.token,
"filter":pipelinename
}
//var params = {
// pipeline: pipelines
// }
var params = {
querytokenFilter:CONFIG.api.token,
filter:pipelinename
}

var options = {
params: params,
headers: { 'content-type': 'application/x-www-form-urlencoded',Authorization: `Bearer ${token}` },
};

//https://api.swarmlab.io/gettutorlabrooms?sort=pipelinename%7Casc&page=1&per_page=5&filter=&type=scripts&tutor=yes
instance.defaults.timeout = 30000;
//const res = await instance.get('/getplaygrounds',params,options);
const res = await instance.get('/getplaygrounds',options);
if(res.status == 200){
return res.data
}else{
console.log("noerror: " + res)
return await res.status

}
}
catch (err) {
console.error("error: "+err);
var error = new Object();
error.action = '401'
return await error
}
}

// ***************************************************
// get user pipelines
// ***************************************************

async function getuserpipelines(token,user,swarmlabname) {
var pipelinename = user
const agent = new https.Agent({
rejectUnauthorized: false,
});
const instance = axios.create({
baseURL: 'https://api.swarmlab.io',
withCredentials: true,
rejectUnauthorized: false,
crossdomain: true,
httpsAgent: agent,
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer '+token
}
})
try {

var pipelines = {
"querytokenFilter":CONFIG.api.token,
"filter":pipelinename,
swarmlabname:swarmlabname
}
//var params = {
// pipeline: pipelines
// }
var params = {
querytokenFilter:CONFIG.api.token,
filter:pipelinename,
swarmlabname:swarmlabname
}

var options = {
params: params,
headers: { 'content-type': 'application/x-www-form-urlencoded',Authorization: `Bearer ${token}` },
};

instance.defaults.timeout = 30000;
const res = await instance.get('/getuserplaygrounds',options);
if(res.status == 200){
return res.data
}else{
console.log("noerror: " + res)
return await res.status

}
}
catch (err) {
console.error("error: "+err);
var error = new Object();
error.action = '401'
error.error = err
return await error
}
}


global.online='ob';
global.pipelines=[];


// ***************************************************
// rest get
// ***************************************************




app.get('/run', (req, res, next) => {

(async() => {

var RES = new Object();
RES.code = req.query["action"]
RES.token = req.query["token"]
RES.error = false
RES.error_msg = "ok"
res.json(RES)
})()

});


// ***************************************************
// socket
// ***************************************************

//function getSHA256ofJSON(input){
// return require("crypto").createHash("sha256").update(JSON.stringify(input)).digest("hex");
//}

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

function getSHA256ofJSON(data, inputEncoding, encoding){
if (!data) {
return '';
}
inputEncoding = inputEncoding || 'utf-8';
encoding = encoding || 'hex';
const hash = require("crypto").createHash('md5');
return hash.update(JSON.stringify(data), inputEncoding).digest(encoding);
}





io.on('connection', s => {
console.error('socket connection');

// ------------------------------
// --- set
// ------------------------------
var usersession = new Object();
usersession.SOCKET = {};
usersession.SOCKET.error = {};
console.error('socket ...');
//s.auth = false;
s.auth = true;

// ------------------------------
// --- authenticate
// ------------------------------
s.on('authenticate', function(data){
const token = data
//console.log('invalid 1 ' + token);
console.log("check " +JSON.stringify(data))
(async() => {
//var isvalid = await checkToken(token);
//
/*
if(isvalid.action == 'ok'){
console.log("Authserver ok ", s.id + ' - ' + token);
usersession.SOCKET.user = isvalid.user
usersession.SOCKET.scope = isvalid.scope // space delimeter
usersession.SOCKET.token = isvalid.token
s.auth = true;
}else{
console.log("Authserver no ", s.id + ' - ' + token);
s.auth = false;
}
*/
s.auth = true;
})()
});
/*
setTimeout(function(){
if (!s.auth) {
console.log("Disconnecting timeout socket ", s.id);
//s.disconnect('unauthorized');
}else{
var room = usersession.SOCKET.user
//s.on("subscribe", function (room) {
s.join(room);
console.log("joining rooom", s.rooms);
console.log(room + ' created ')
// });
}
}, 30000);
*/

var id = s.id
s.on('action', obj => {
console.error('from client '+ s.id + ' obj ' + obj);
});
});

http.listen(3000, () => console.error('listening on http://localhost:3000/'));
console.error('socket.io example');

+ 285
- 0
src-local/llo/new.js View File

@@ -208,6 +208,199 @@ app.get('/getservicesstatus', (req, res, next) => {

});

app.get('/get_config', (req, res, next) => {

var mypath = process.cwd()
var RES = new Object();
var found = 'yes'
RES.error = false
RES.error_msg = "ok"
RES.data = found;
RES.data = mypath
res.json(RES)
/*
exec('pwd', (err, stdout, stderr) => {
if (err) {
console.error(`exec error: ${err}`);
return;
}
if (stdout) {
var string = stdout.toString()
console.log(JSON.stringify(string))
var found = 'yes'
RES.error = false
RES.error_msg = "ok"
RES.data = found;
RES.data = string
res.json(RES)

}else{
var found = 'no'
RES.error = false
RES.error_msg = "ok"
RES.data = found;
res.json(RES)
}
});
*/
});

app.get('/create_config', (req, res, next) => {

var RES = new Object();
RES.value = req.query["value"]
console.log('value error '+JSON.stringify(RES.value))
//var showexec = `cd ./hybrid; /bin/bash ./create-keys.sh`
fs.writeFileSync('./hybrid/keys.json', JSON.stringify(RES.value));
RES.value = JSON.parse(RES.value);

var INTERFACE_IP=RES.value.wg_ip
var endpoint_tmp=RES.value.server_ip
var fields = endpoint_tmp.split(':');
var endpoint = fields[0];
var mypath = process.cwd()

var swarmlab_config_template = `
DEV_NAME=wg0
INTERFACE_IP=${INTERFACE_IP}/16
INTERFACE_IProute=${INTERFACE_IP}
ENDPOINT_IP=${endpoint}

ip link set $DEV_NAME down
ip link del $DEV_NAME
# add wireguard interface
ip link add $DEV_NAME type wireguard

# set wireguard conf
wg setconf $DEV_NAME ${mypath}/hybrid/connect/$DEV_NAME.conf

# assign ip to wireguard interface
ip addr add $INTERFACE_IP dev $DEV_NAME

# set sysctl
sysctl -w net.ipv4.conf.all.rp_filter=2

# set mtu for wireguard interface
ip link set mtu 1420 up dev $DEV_NAME

# bring wireguard interface up
ip link set up dev $DEV_NAME

# add route
ip route add default via $INTERFACE_IProute metric 2 table 200
ip route show table 200 | grep -w $INTERFACE_IProute

# add local lan route
ip rule add table main suppress_prefixlength 0
ip rule show | grep -w "suppress_prefixlength"
`
fs.writeFileSync('./hybrid/connect/swarmlab-connect.sh', swarmlab_config_template);

var allowed_ips=RES.value.allowed_ips
var swarmlab_public_wgkey=RES.value.swarmlab_public_wgkey
var swarmlab_privatekey=RES.value.privatekey
var swarmlab_wg_port=RES.value.wg_port
var swarmlab_wg0_template = `[Interface]
PrivateKey = ${swarmlab_privatekey}
ListenPort = ${swarmlab_wg_port}

[Peer]
PublicKey = ${swarmlab_public_wgkey}
Endpoint = ${endpoint_tmp}
AllowedIPs = ${allowed_ips}
PersistentKeepalive = 30

`
fs.writeFileSync('./hybrid/connect/template-wg0.conf', swarmlab_wg0_template);

var swarmlab_swarm=RES.value.workerkey
var swarmlab_swarm_ip=RES.value.swarm_ip
var swarmlab_swarm_template = `
docker swarm join --token ${swarmlab_swarm} ${swarmlab_swarm_ip}
`
fs.writeFileSync('./hybrid/connect/template-swarm.sh', swarmlab_swarm_template);


var swarmlab_swarm_join_template = `
function swarmlab_ifup() {
swarmlab=$(/bin/bash ${mypath}/hybrid/connect/status.sh wg0 | jq .swarmlab)
tempswarm="\${swarmlab%\\"}"
tempswarm="\${tempswarm#\\"}"
swarmlab=$tempswarm
echo $swarmlab
}
function hybrid_ifup() {
hybrid=$(/bin/bash ${mypath}/hybrid/connect/status.sh wg0 | jq .hybrid)
tempswarm1="\${hybrid%\\"}"
tempswarm1="\${tempswarm1#\\"}"
hybrid=$tempswarm1
echo $hybrid
}

hybrid=$(hybrid_ifup)
if [ $hybrid == 'NotOnline' ]; then
/bin/bash ${mypath}/hybrid/connect/swarmlab-connect.sh
echo "Start wg0 network interface"
sleep 3
hybrid1=$(hybrid_ifup)
if [ $hybrid1 == 'NotOnline' ]; then
echo "Failed to start wg0 network interface"
else
echo "Swarmlab hybrid $hybrid"
fi
else
echo "Swarmlab hybrid $hybrid"
fi

sleep 1
swarmlab=$(swarmlab_ifup)
if [ $swarmlab != 'active' ]; then
sleep 5
swarmlab1=$(swarmlab_ifup)
if [ $swarmlab1 != 'active' ]; then
echo "Failed to connect on swarmlab master"
echo "Exec "
echo "/bin/bash ${mypath}/hybrid/connect/reload-swarmlab.sh"
echo "Please try again"
fi
else
echo "Swarmlab master $swarmlab"
fi
`
fs.writeFileSync('./hybrid/connect/join.sh', swarmlab_swarm_join_template);

var swarmlab_swarm_leave_template = `
function hybrid_ifup() {
hybrid=$(/bin/bash ${mypath}/hybrid/connect/status.sh wg0 | jq .hybrid)
tempswarm1="\${hybrid%\\"}"
tempswarm1="\${tempswarm1#\\"}"
hybrid=$tempswarm1
echo $hybrid
}

hybrid=$(hybrid_ifup)
if [ $hybrid == 'NotOnline' ]; then
echo "Swarmlab hybrid $hybrid"
else
ip link set wg0 down
ip link del wg0
sleep 3
hybrid1=$(hybrid_ifup)
if [ $hybrid1 == 'NotOnline' ]; then
echo "Swarmlab hybrid $hybrid"
else
echo "Swarmlab hybrid $hybrid"
fi
fi
`

fs.writeFileSync('./hybrid/connect/leave.sh', swarmlab_swarm_leave_template);

RES.error = false
RES.error_msg = "ok"
res.json(RES)
});

function create_project(swarmlabname,project){

var services_path = './instance/'+swarmlabname+'/'+project
@@ -244,6 +437,31 @@ function create_project(swarmlabname,project){
});
}

function myserverStatus(){
var serverStatus = '/bin/bash ./hybrid/connect/status.sh wg0';
exec(serverStatus, (err, stdout, stderr) => {
if (err) {
console.error(`exec error: ${err}`);
return;
}
if (stdout) {
var string = stdout.toString()
string = JSON.parse(string);
//var stringstr = string.replace(/^"(.*)"$/, '$1');

var n = {}
n.data = string
io.emit('message_hybrid_status', n);
}
});
}

myserverStatus();

setInterval(function(){
myserverStatus()
}, 30000)

let child = [];
var ppid = ''
io.on('connection', function(socket) {
@@ -464,6 +682,73 @@ SSH_PORT=
//child[0].kill();
});

socket.on('create-wirequard', (value) => {
let rawdatafile = './hybrid/config.json'
var workerkey = value.workerkey
var privatekey = value.privatekey
var publickey = value.publickey
var server_ip = value.server_ip // 83.212.77.133:51820
var allowed_ips = value.allowed_ips // 10.13.13.0/16, 0.0.0.0/0, ::/0

var services_json = {
workerkey: workerkey,
privatekey: privatekey,
publickey: publickey,
server_ip: server_ip,
allowed_ips: allowed_ips
};
let datajson = JSON.stringify(services_json);
fs.writeFileSync(rawdatafile, datajson);

var services_path = ` ----------------
create a file
/etc/wireguard/wg0.conf
-----------------------
`
var ENV_service_file = `
create a file connect-server.sh

[Interface]
PrivateKey = ${privatekey}
ListenPort = 51820

[Peer]
PublicKey = ${publickey}
Endpoint = ${server_ip}
AllowedIPs = ${allowedOrigins}
PersistentKeepalive = 30

`
var n = {}
n.data = services_path
io.emit('message_out', n);
n.data = ENV_service_file
io.emit('message_out', n);

var n = {}
n.data = 'sudo bash ./connect-server.sh'
io.emit('message_close', n);
});
socket.on('get-serverconfig', () => {

let rawdatafile = './hybrid/keys.json'
if (fs.existsSync(rawdatafile)) {
let rawdata = fs.readFileSync(rawdatafile);
let config = JSON.parse(rawdata);
var n = {}
n.file = 'ok'
n.data = config
io.emit('message_config', n);
}else{
var n = {}
n.file = 'nodata'
n.data = 'nodata'
io.emit('message_config', n);
}
});


});

server.listen(serverPort, function() {

+ 0
- 29
src-local/llo/pubsub.js View File

@@ -1,29 +0,0 @@
var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

/*
// server side code
io.sockets.on('connection', function(socket) {
socket.on('create', function(room) {
socket.join(room);
});
});

*/


io.on('connection', s => {

s.on("iot", function (room) {
s.join(room);
console.error('hi');
s.to(room).emit('message', 'hi from server');
io.emit('iotdata', 'hi from server');
});

});


http.listen(8084, () => console.error('listening on http://localhost:8084/'));

+ 0
- 32
src-local/llo/test.js View File

@@ -1,32 +0,0 @@
"use strict"

var app = require('express')();
var http = require('http').Server(app);
var https = require('https');

var express = require('express');
app.use(express.json());

const helmet = require('helmet');
app.use(helmet());

const cors = require('cors')
app.use(cors)

app.get('/run', (req, res, next) => {
console.log('hi');

(async() => {

var RES = new Object();
RES.code = req.query["action"]
RES.token = req.query["token"]
RES.error = false
RES.error_msg = "ok"
res.json(RES)
})()

});

http.listen(3000, () => console.error('listening on http://localhost:3000/'));
console.error('socket.io example');

+ 0
- 38
src-local/llo/test1.js View File

@@ -1,38 +0,0 @@

var app = require('express')();
var fs = require('fs');

const cors = require('cors')
const helmet = require('helmet');
//app.use(cors)
app.use(helmet());

var options = {
key: fs.readFileSync('./llo/swarmlab.key'),
cert: fs.readFileSync('./llo/swarmlab.crt')
};
var serverPort = 3000;

var https = require('https').Server(options, app);
//var server = https.createServer(options, app);



app.get('/run', (req, res, next) => {
console.log('hi');

(async() => {

var RES = new Object();
RES.code = req.query["action"]
RES.token = req.query["token"]
RES.error = false
RES.error_msg = "ok"
//res.json(RES)
res.send(RES)
})()

});

https.listen(3000, () => console.error('listening on http://localhost:3000/'));
console.error('socket.io example');

+ 40
- 5
src/App.vue View File

@@ -11,7 +11,7 @@
<a class="nav-link" href="#"
@click="hybrid('services')"
>
Manage_Your_Lab_Instances</a>
Manage_Your_Local_LabInstances</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
@@ -37,7 +37,9 @@
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
<a class="nav-link" href="#"
@click="hybrid('connect-server')"
>Config_hybrid_server</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
@@ -45,7 +47,11 @@
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
<a class="nav-link" href="#"
@click="hybrid('manage_service')"
>
Manage_Your_hybrid_LabInstances</a>
</li>
</li>
</ul>
<ul class="nav navbar-nav flex-row justify-content-md-center justify-content-start flex-nowrap">
@@ -84,7 +90,29 @@
</b-col>
</b-row>

<b-row
v-show="hybridmenou == 'connect-server'"
>
<b-col cols="12">
<connect-server
style="background-color: #f8f9fa"
>
</connect-server>

</b-col>
</b-row>

<b-row
v-show="hybridmenou == 'manage_service'"
>
<b-col cols="12">
<manage-services
style="background-color: #f8f9fa"
>
</manage-services>

</b-col>
</b-row>


</div>
@@ -93,15 +121,18 @@
<script>
import "@/assets/css/themify-icons.css";

//import NetworkTable from "./components/mynetwork/mytable.vue";
import ConnectServer from "./components/myconnect-server.vue";
import NetworkTable from "./components/mynetwork.vue";
import ServicesTable from "./components/myservices.vue";
import ManageServices from "./components/manageservices.vue";

export default {
name: 'app',
components: {
NetworkTable,
ServicesTable
ServicesTable,
ConnectServer,
ManageServices
},
data() {
return {
@@ -121,8 +152,12 @@ export default {
console.log(action)
if(action == 'bootstrap'){
this.$root.$emit('hybrid_refresh_dockerservices')
}else if(action == 'connect-server'){
this.$root.$emit('hybrid_connect_server')
}else if(action == 'services'){
this.$root.$emit('hybrid_refresh_availableservices')
}else if(action == 'manage_service'){
//this.$root.$emit('hybrid_manage_service')
}
}


+ 55
- 0
src/components/manageservices.vue View File

@@ -0,0 +1,55 @@
<template>
<card class="card-user" style="max-height:100%">

<div class="row" >
<div class="col-7 order-first " >
<br>
<myconnect-manage-server>

</myconnect-manage-server>
</div>

<div class="col-5 order-last" >
<br>
<adhoc-view>

</adhoc-view>
</div>
</div>


</card>
</template>
<script>
import {mapState, mapGetters, mapActions} from 'vuex'
//import ViewNetwork from "./mynetwork/mytable.vue";
import AdhocView from "./mynetwork/AdhocView.vue";
import card from '@/components/Card.vue'
//import DockerServices from "./mynetwork/dockerservices.vue";
import MyconnectManageServer from "./manageservices/manage-service.vue";
export default {
components: {
AdhocView,
card,
MyconnectManageServer
},
data () {
return {
loading: false,
consoleView: 'off',
productIndex: 1
}
},
mounted() {
},
beforeDestroy () {
},


created () {
}
};
</script>
<style>
</style>


+ 670
- 0
src/components/manageservices/manage-service.vue View File

@@ -0,0 +1,670 @@
<template>
<card class="card-user" style="max-height:100%">
<div class="author">
<img class="avatar border-white" src="@/assets/img/docker.png" alt="...">
</div>

<b-container fluid class="bv-example-row">






<div class="input-group input-group-sm sm-3">
<div class="input-group-prepend">
<button
class="btn btn-outline-primary"
round
type="button"
@click="onAction('add')"
>
Add Network Node</button>
</div>
<input type="text"
class="form-control"
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
placeholder="Search"
v-model="searchFor"
@keyup.enter="setFilter"
>
<div class="input-group-append">
<button
class="btn btn-outline-primary"
round
type="button"
@click="setFilter">
Go</button>
</div>
<div class="input-group-append">
<button class="btn btn-outline-secondary"
round
type="button"
@click="resetFilter">
Reset</button>
</div>
</div>

<!-- add newNODE -->
<card class="card-user" style="max-height:100%"
v-if="nodeadmin"
>
<br>
<div class="white h-20 flex-fixed-width-item"

<!-- add newROW ---------------------------------------------------- -->
<div class="row" >
<div class="col-3 order-first pr-md-1" >
<input type="text"
class="form-control"
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
placeholder="Name"
v-model="nodename"
>
</div> <!-- coll -->

<div class="col-3 pr-md-1" >



<ValidationProvider name="nodeid" rules="required|alpha_num" ref="provider"
v-slot="{ valid, errors, ariaMsg, ariaInput }"
v-if="nodeadminupdate"
>
<input type="text"
class="form-control"
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
placeholder="NodeId"
disabled
v-model="nodeid"
>
</ValidationProvider>
<ValidationProvider name="nodeid" rules="required|alpha_num" ref="provider"
v-slot="{ valid, errors, ariaMsg, ariaInput }"
v-else
>
<input type="text"
class="form-control"
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
placeholder="NodeId"
v-model="nodeid"
data-vv-as='"Node id"'
data-vv-value-path="nodeid"
data-vv-name="nodeid"
>
<span>{{ errors[0] }}</span>
</ValidationProvider>
</div> <!-- coll -->

<div class="col-3 pr-md-1" >
<input type="text"
class="form-control"
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
placeholder="IP"
v-model="nodeip"
>
</div> <!-- coll -->
</div> <!-- row -->

<!-- add newROW ---------------------------------------------------- -->
<div class="row" >
<div class="col-3 order-first pr-md-1" >
<input type="text"
class="form-control"
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
placeholder="Role"
v-model="noderole"
>
</div> <!-- coll -->

<div class="col-3 pr-md-1" >
<input type="text"
class="form-control"
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
placeholder="Zones"
v-model="nodezones"
>
</div> <!-- coll -->

<div class="col-3 pr-md-1" >
<input type="text"
class="form-control"
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
placeholder="nodedesc"
v-model="nodedesc"
>
</div> <!-- coll -->
</div> <!-- row -->

<!-- add newROW ---------------------------------------------------- -->
<div class="row" >
<div class="col-2 pr-md-1" >
<div class="input-group input-group-sm sm-3">
<div class="input-group-append">

<button
class="btn btn-outline-primary"
round
type="button"
v-if="nodeadminupdate"
@click="onAction('update')">
update</button>
<button
class="btn btn-outline-primary"
round
type="button"
v-else
@click="onAction('addserver')">
add</button>
</div>

<div class="input-group-append">
<button class="btn btn-outline-secondary"
round
type="button"
@click="onAction('cancel')"
>
Cancel</button>
</div>
</div>
</div> <!-- coll -->
</div> <!-- row -->
</card> <!-- card -->
<!-- add newNODE -->

<div class="white h-100 flex-fixed-width-item"
<vuetable
ref="vuetable"
:key="vuetablekey"
:api-url='apiurl'
:api-mode="true"
:http-options="httpOptions"
:fields="fields"
:item-actions="itemActions"
:sort-order="sortOrder"
:show-sort-icons="true"
:multi-sort="multiSort"
:per-page="perpage"
pagination-path="links.pagination"
:pagination-component="paginationComponent"
:append-params="moreParams"
wrapper-class="vuetable-wrapper"
loading-class="loading"
detail-row-id="id"
@vuetable:pagination-data="onPaginationData"
@vuetable:load-success="loadsuccess"
:css="css.table"
>
<template slot="actions" slot-scope="props">
<div class="table-button-container">
<button
class="ti-pencil btn btn-outline-secondary btn-sm"
@click="onAction('edit', props.rowData, props.rowIndex)"
>
</button>
<button
round
class="ti-trash btn btn-outline-secondary btn-sm"
@click="onAction('rm', props.rowData, props.rowIndex)"
>
</button>

</div>
</template>
</vuetable>
<div class="vuetable-pagination ui basic segment grid">
<vuetable-pagination-info
ref="paginationInfo"
:css="css.paginationInfo"
>
</vuetable-pagination-info>
<vuetable-pagination
:css="css.pagination"
ref="pagination"
@vuetable-pagination:change-page="onChangePage"
>
</vuetable-pagination>
</div>









</b-container>
</card>
</template>
<script>
import store from '@/store/index'
import {mapState, mapGetters, mapActions,dispatch} from 'vuex'
import Vue from 'vue'
import {Vuetable, VuetablePaginationDropdown} from 'vuetable-2'
import card from '@/components/Card.vue'
import VuetablePaginationInfo from 'vuetable-2/src/components/VuetablePaginationInfo'
import VuetablePagination from 'vuetable-2/src/components/VuetablePagination'
import CssConfig from 'vuetable-2/src/components/VuetableCssConfig.js'
import {ApiConfig} from "@/config/index";
import { extend } from 'vee-validate';
import { required, alpha_num } from 'vee-validate/dist/rules';

// No message specified.
extend('alpha_num', alpha_num);

// Override the default message.
extend('required', {
...required,
message: 'This field is required'
});
export default {
components: {
card,
Vuetable,
VuetablePagination,
VuetablePaginationInfo,
VuetablePaginationDropdown
},
props: {
},
data() {
return{
token: '',
valid:false,
nodeadmin:false,
nodeadminupdate:false,
rowdata:{},
nodename:'',
nodeid:'',
nodeip:'',
noderole:'',
nodezones:'',
nodedesc:'',
playbookInfo: {},
token: '',
playbook: {
'title':'',
'name':'',
'description':''
},
container:{
name:'',
view:0
},
pipeline:{},
selected: '',
options: [
{ text: 'Packages', value: 'packages' },
{ text: 'Images', value: 'images' },
{ text: 'Scripts', value: 'scripts' }
],
showModal: false,
visibility: [],
active:false,
vuetablekey:0,
fielddata:{},
fields: [
{
name: 'name',
title: '<span class="orange"></span>Name',
sortField: 'name',
titleClass: 'text-center aligned',
visible:true,
dataClass: "center aligned",
width: '20%'
},
{
name: 'nodeid',
title: '<span class="text-warning">nodeid</span>',
titleClass: 'text-center aligned',
sortField: 'nodeid',
visible:true,
width: '20%'
},
{
name: 'ip',
title: '<span class="orange"></span>IP',
titleClass: 'text-center aligned',
sortField: 'swarmlabname',
visible:true,
width: '13%'
},
{
name: 'role',
title: '<span class="orange"></span>Role',
titleClass: 'text-center aligned',
sortField: 'role',
visible:true,
width: '15%',
formatter (value) {
const result = /^ondemand_playground/.test(value);
if (result) {
var v = '<p class="text-warning">Playground</p>'
return v
}else{
var v = '<p class="text-info">Lab</p>'
return v
}
}

},
{
name: 'zones',
title: '<span class="text-warning">Zones</span>',
sortField: 'zones',
titleClass: 'text-center aligned',
visible:true,
width: '20%'
},
{
name: 'status',
title: '<span class="orange"></span>Status',
titleClass: 'text-center aligned',
sortField: 'status',
visible:true,
width: '5%'
},
{
name: '__slot:actions',
title: 'Actions',
titleClass: 'text-center aligned',
dataClass: "text-center aligned",
width: '10%'
},
{
name: '_id',
title: '<span class="orange"></span>mongo',
visible:false
}
],
//apiurl:ApiConfig.url_80+"/swarmlabservices",
apiurl:ApiConfig.swarmlab_url_80+"/getswarmlabhybrid",
css: CssConfig,
perpage: 9,
searchFor: '',
sortOrder: [{
field: 'pipelinename',
direction: 'asc'
}],
multiSort: true,
paginationComponent: 'vuetable-pagination',
itemActions: [
{ name: 'view-item', label: '', icon: 'glyphicon glyphicon-zoom-in', class: 'btn btn-info', extra: {'title': 'View', 'data-toggle':"tooltip", 'data-placement': "left"} },
{ name: 'edit-item', label: '', icon: 'glyphicon glyphicon-pencil', class: 'btn btn-warning', extra: {title: 'Edit', 'data-toggle':"tooltip", 'data-placement': "top"} },
{ name: 'delete-item', label: '', icon: 'glyphicon glyphicon-remove', class: 'btn btn-danger', extra: {title: 'Delete', 'data-toggle':"tooltip", 'data-placement': "right" } }
],
moreParams: {
'filter': '',
'type': 'hybrid'
},
}
},
mounted() {
},
created() {
var url_string = window.location.href
var url = new URL(url_string);
this.token = url.searchParams.get("token");
console.log("token "+ this.token);

},
beforeDestroy () {
},
computed: {
httpOptions() {
var token = this.token
var p="headers: {Authorization: token}}"; //table props -> :http-options="httpOptions"
return {headers: {Authorization: 'Bearer ' + token}} //table props -> :http-options="httpOptions"
},

},

methods: {
onError (type,description) {
var winfo=description
var info='<h5>Bootstrap '+type+'</h5>'
this.$swal({
type: type,
html: info+winfo,
showCloseButton: true,
showLoaderOnConfirm: false,
allowOutsideClick: false,
cancelButtonText: 'No, cancel!',
showCancelButton: false,
showLoaderOnConfirm: false,
reverseButtons: true,
focusCancel: true,
confirmButtonText: 'Ok!'
})
},


setFilter () {
this.moreParams = {
'filter': this.searchFor,
'type': this.selected
}
Vue.nextTick( () => this.$refs.vuetable.refresh())
},
resetFilter () {
this.moreParams = {}
this.searchFor = ''
Vue.nextTick( () => this.$refs.vuetable.refresh())
},
onPaginationData (paginationData) {
this.$refs.pagination.setPaginationData(paginationData)
this.$refs.paginationInfo.setPaginationData(paginationData)
},
onChangePage (page) {
this.$refs.vuetable.changePage(page)
},
editRow(rowData) {
alert("You clicked edit on"+ JSON.stringify(rowData));
},
async onAction (action, data, index) {
if(action == 'edit' ){
this.nodeadmin = true
this.nodeadminupdate = true
this.nodeid = data.nodeid
this.nodeip = data.ip
this.nodename = data.name
this.noderole = data.role
this.nodezones = data.zones
this.nodedesc = data.description
console.log(JSON.stringify(data))
console.log(JSON.stringify(index))
}else if(action == 'update' ){
await this.$refs.provider.validate().then(success => {
if (success.valid) {
this.valid = true
console.log('valid '+JSON.stringify(success))
}else{
this.valid = false
console.log('no valid'+JSON.stringify(success))
}
});
if (this.valid) {
var log = await store.dispatch("pipelineLLO/swarmlabhybridadd",{
token:this.token,
action:'add',
nodeid: this.nodeid,
nodeip: this.nodeip,
nodename: this.nodename,
noderole: this.noderole,
nodezones: this.nodezones,
nodedesc: this.nodedesc
})
//console.log(this.nodename)
//console.log(this.nodeid)
//console.log(this.nodeip)
//console.log(this.noderole)
//console.log(this.nodezones)
//console.log(this.nodedesc)
Vue.nextTick( () => this.$refs.vuetable.refresh())
}
}else if(action == 'rm' ){
this.rowdata = data
this.$swal({
type: 'info',
html: 'info',
showCloseButton: true,
showLoaderOnConfirm: false,
allowOutsideClick: false,
cancelButtonText: 'No, cancel!',
showCancelButton: true,
showLoaderOnConfirm: false,
reverseButtons: true,
focusCancel: true,
confirmButtonText: 'Yes, Delete it!'
}).then((result)=> {
this.rmAndClose(result);
})

}else if(action == 'add' ){
this.nodeadmin = true
this.nodeadminupdate = false
}else if(action == 'addserver' ){
await this.$refs.provider.validate().then(success => {
if (success.valid) {
this.valid = true
console.log('valid '+JSON.stringify(success))
}else{
this.valid = false
console.log('no valid'+JSON.stringify(success))
}
});

if (this.valid) {
this.nodeadmin = false
this.nodeadminupdate = false
var log = await store.dispatch("pipelineLLO/swarmlabhybridadd",{
token:this.token,
action:'add',
nodeid: this.nodeid,
nodeip: this.nodeip,
nodename: this.nodename,
noderole: this.noderole,
nodezones: this.nodezones,