From 2e5c05fff2537a83318fc9525462b9a265de38cf Mon Sep 17 00:00:00 2001 From: Abdel-Kader Chabi-Sika-Boni Date: Sun, 3 Jan 2021 19:00:14 +0100 Subject: [PATCH] mise a jour --- Dockerfiles/API.txt | 34 +++ Dockerfiles/explanations.txt | 45 ++++ .../automatic_images_creation.sh | 23 +++ .../forContainerNet/bootserver/Dockerfile | 22 ++ .../bootserver/bootstrap_client.py | 52 +++++ .../bootserver/bootstrap_server.py | 194 ++++++++++++++++++ Dockerfiles/forContainerNet/device/Dockerfile | 28 +++ .../device/bootstrap_client.py | 52 +++++ Dockerfiles/forContainerNet/device/device.js | 53 +++++ .../forContainerNet/gateway/Dockerfile | 28 +++ .../gateway/bootstrap_client.py | 52 +++++ .../forContainerNet/gateway/gateway.js | 127 ++++++++++++ Dockerfiles/forContainerNet/server/Dockerfile | 28 +++ .../server/bootstrap_client.py | 52 +++++ Dockerfiles/forContainerNet/server/server.js | 167 +++++++++++++++ enonce/2020-2021-_UE-PETAR--SUJETS-ETUDE.pdf | Bin 0 -> 109806 bytes jsfiles/README.md | 2 + jsfiles/device.js | 53 +++++ jsfiles/gateway.js | 127 ++++++++++++ jsfiles/server.js | 167 +++++++++++++++ topologie/topology.py | 191 +++++++++++++++++ 21 files changed, 1497 insertions(+) create mode 100644 Dockerfiles/API.txt create mode 100644 Dockerfiles/explanations.txt create mode 100755 Dockerfiles/forContainerNet/automatic_images_creation.sh create mode 100644 Dockerfiles/forContainerNet/bootserver/Dockerfile create mode 100755 Dockerfiles/forContainerNet/bootserver/bootstrap_client.py create mode 100755 Dockerfiles/forContainerNet/bootserver/bootstrap_server.py create mode 100644 Dockerfiles/forContainerNet/device/Dockerfile create mode 100755 Dockerfiles/forContainerNet/device/bootstrap_client.py create mode 100644 Dockerfiles/forContainerNet/device/device.js create mode 100644 Dockerfiles/forContainerNet/gateway/Dockerfile create mode 100755 Dockerfiles/forContainerNet/gateway/bootstrap_client.py create mode 100644 Dockerfiles/forContainerNet/gateway/gateway.js create mode 100644 Dockerfiles/forContainerNet/server/Dockerfile create mode 100755 Dockerfiles/forContainerNet/server/bootstrap_client.py create mode 100644 Dockerfiles/forContainerNet/server/server.js create mode 100644 enonce/2020-2021-_UE-PETAR--SUJETS-ETUDE.pdf create mode 100644 jsfiles/README.md create mode 100644 jsfiles/device.js create mode 100644 jsfiles/gateway.js create mode 100644 jsfiles/server.js create mode 100755 topologie/topology.py diff --git a/Dockerfiles/API.txt b/Dockerfiles/API.txt new file mode 100644 index 0000000..d591f55 --- /dev/null +++ b/Dockerfiles/API.txt @@ -0,0 +1,34 @@ +SERVER +GET /devices +GET /device/:dev +POST /device/:dev/data +GET /device/:dev/data +POST /devices/register +GET /gateways +GET /gateways/:gw +POST /gateways/register +GET /ping +GET /health + +GATEWAY (Intermediary & Final) +POST /gateways/register +POST /devices/register +POST /device/:dev/data +GET /gateways +GET /gateway/:gw +GET /ping +GET /health + +DEVICE +--- + +Data Format +{ Name : LOCAL_ENDPOINT.NAME, + Data : dataItem++, //an integer incrementing everytime data is sent + Time : Date.now(), //the date (+hour) the data has been sent +} + +Register Format +{ Name : LOCAL_ENDPOINT.NAME, //the name of the entity which want to register itself + PoC : 'http://' + LOCAL_ENDPOINT.IP + ':' + LOCAL_ENDPOINT.PORT, //the address from which the registering entity can be joined +} diff --git a/Dockerfiles/explanations.txt b/Dockerfiles/explanations.txt new file mode 100644 index 0000000..13ce461 --- /dev/null +++ b/Dockerfiles/explanations.txt @@ -0,0 +1,45 @@ +Test Architecture + +********************** +* CONTAINER * +* IP = x.x.x.x * +* * +* ++++++++++++++++++ * +* + SERVER (srv) + * +* + IP = 127.0.0.1 + * +* + PORT = 8080 + * +* ++++++++++++++++++ * +********************** + || +********************** +* CONTAINER * +* IP = x.x.x.x * +* * +* ++++++++++++++++++ * +* + GATWEWAY (gwi) + * +* + IP = 127.0.0.1 + * +* + PORT = 8181 + * +* ++++++++++++++++++ * +********************** + || +********************** +* CONTAINER * +* IP = x.x.x.x * +* * +* ++++++++++++++++++ * +* + GATEWAY (gwf1) + * +* + IP = 127.0.0.1 + * +* + PORT = 8282 + * +* ++++++++++++++++++ * +********************** + || +********************** +* CONTAINER * +* IP = x.x.x.x * +* * +* ++++++++++++++++++ * +* + DEVICE (dev1) + * +* + IP = 127.0.0.1 + * +* + PORT = 9001 + * +* ++++++++++++++++++ * +********************** diff --git a/Dockerfiles/forContainerNet/automatic_images_creation.sh b/Dockerfiles/forContainerNet/automatic_images_creation.sh new file mode 100755 index 0000000..a42fb29 --- /dev/null +++ b/Dockerfiles/forContainerNet/automatic_images_creation.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# This script intend to delete existing images (if exists) and recreate them all +# This script must be launch in root mode +# This script must be launched from the 'forContainerNet' folder +# This script must be launched by being sure there isn't any running container using the images below (exit from topology if not yet done) + +docker rmi config:topo +docker rmi server:topo +docker rmi gateway:topo +docker rmi device:topo + +cd bootserver +docker build -t config:topo . + +cd ../server +docker build -t server:topo . + +cd ../gateway +docker build -t gateway:topo . + +cd ../device +docker build -t device:topo . diff --git a/Dockerfiles/forContainerNet/bootserver/Dockerfile b/Dockerfiles/forContainerNet/bootserver/Dockerfile new file mode 100644 index 0000000..70df60a --- /dev/null +++ b/Dockerfiles/forContainerNet/bootserver/Dockerfile @@ -0,0 +1,22 @@ +# Choosing the image to use +FROM node:buster + +# Installing required libraries +RUN apt-get update && \ + apt-get install -y net-tools iputils-ping python-pip && \ + pip install flask && \ + pip install requests && \ + mkdir mydir && \ + cd mydir + +COPY bootstrap_server.py /mydir + +SHELL ["/bin/bash", "-c"] + +RUN echo "nohup python /mydir/bootstrap_server.py &" > start.sh && \ + echo "/bin/bash" >> start.sh && \ + chmod 777 start.sh + +# Mandatory entrypoint in containernet +ENTRYPOINT ./start.sh + diff --git a/Dockerfiles/forContainerNet/bootserver/bootstrap_client.py b/Dockerfiles/forContainerNet/bootserver/bootstrap_client.py new file mode 100755 index 0000000..07a48b5 --- /dev/null +++ b/Dockerfiles/forContainerNet/bootserver/bootstrap_client.py @@ -0,0 +1,52 @@ +#!/usr/bin/python +#coding: utf-8 +import os +import subprocess +import requests +from time import sleep + + +BOOTSTRAP_SERVER_ADDRESS = '10.10.10.10:5555' + +def retrieve_config(): + my_json_config = {"verdict":"oops"} + my_ip = str(subprocess.check_output("echo $MY_IP", shell=True)).rstrip() + print("MY_IP : %s"%(my_ip)) + while my_json_config["verdict"] != "yes": + try: + resp = requests.get("http://%s/getmyconfig/%s"%(BOOTSTRAP_SERVER_ADDRESS, my_ip), timeout=2) + except: + print("Unable to join the bootstrap server") + try: + my_json_config = resp.json() + print("Extracted configs [succ] : %s"%(my_json_config)) + except: + print("Unable to extract configs from bootstrap server's answer") + print("Extracted configs [fail] : %s"%(my_json_config)) + print("request url : ==>%s<=="%("http://%s/getmyconfig/%s"%(BOOTSTRAP_SERVER_ADDRESS, my_ip))) + if "verdict" in my_json_config and my_json_config["verdict"] == "yes": + my_config = config_json_to_string(my_json_config) + subprocess.check_output("node /mydir/*.js %s"%(my_config), shell=True) + else: + my_json_config = {"verdict":"oops"} + sleep(3) + +def config_json_to_string(json_config): + config = "" + if "local_ip" in json_config: + config += "--local_ip "+json_config["local_ip"]+" " + if "local_port" in json_config: + config += "--local_port "+str(json_config["local_port"])+" " + if "local_name" in json_config: + config += "--local_name "+json_config["local_name"]+" " + if "remote_ip" in json_config: + config += "--remote_ip "+json_config["remote_ip"]+" " + if "remote_port" in json_config: + config += "--remote_port "+str(json_config["remote_port"])+" " + if "remote_name" in json_config: + config += "--remote_name "+json_config["remote_name"]+" " + if "send_period" in json_config: + config += "--send_period "+str(json_config["send_period"])+" " + return config.strip() + +retrieve_config() diff --git a/Dockerfiles/forContainerNet/bootserver/bootstrap_server.py b/Dockerfiles/forContainerNet/bootserver/bootstrap_server.py new file mode 100755 index 0000000..89a24f8 --- /dev/null +++ b/Dockerfiles/forContainerNet/bootserver/bootstrap_server.py @@ -0,0 +1,194 @@ +#!/usr/bin/python +#coding: utf-8 +'''In our topology, we assume the container running this script has ip address 10.10.10.10 + (useful information according to our topology: useless otherwise) +''' +from flask import Flask, jsonify + +app = Flask(__name__) + +SVR_IP = '10.0.0.1' #name = srv + +GWI1_IP = '10.2.2.1' #name = gwi1 +GWI2_IP = '10.2.2.2' #name = gwi2 (dc) + +GWF1_IP = '10.0.1.100' #name = gwf1 +DEV1_GWF1_IP = '10.0.1.1' #name = dev1gwf1 +DEV2_GWF1_IP = '10.0.1.2' #name = dev2gwf1 +DEV3_GWF1_IP = '10.0.1.3' #name = dev3gwf1 + +GWF2_IP = '10.0.2.100' #name = gwf2 +DEV1_GWF2_IP = '10.0.2.1' #name = dev1gwf2 +DEV2_GWF2_IP = '10.0.2.2' #name = dev2gwf2 +DEV3_GWF2_IP = '10.0.2.3' #name = dev3gwf2 + +GWF3_IP = '10.0.3.100' #name = gwf3 +DEV1_GWF3_IP = '10.0.3.1' #name = dev1gwf3 +DEV2_GWF3_IP = '10.0.3.2' #name = dev2gwf3 +DEV3_GWF3_IP = '10.0.3.3' #name = dev3gwf3 + +''' +Formats of configs: +SERVER = "--local_ip 127.0.0.1 --local_port 8080 --local_name %s" +GATEWAY_I = "--local_ip 127.0.0.1 --local_port 8181 --local_name %s --remote_ip %s --remote_port 8080 --remote_name %s" +GATEWAY_F = "--local_ip 127.0.0.1​ --local_port 8282 --local_name %s --remote_ip %s --remote_port 8181 --remote_name %s" +DEV = "--local_ip 127.0.0.1​ --local_port 9001 --local_name %s --remote_ip %s --remote_port 8282 --remote_name %s --send_period 3000" +''' + +SVR_READY = False +GWI1_READY = False +GWI2_READY = False +GWF1_READY = False +GWF2_READY = False +GWF3_READY = False + +@app.route("/getmyconfig/") +def configurations_giver(my_ip="127.0.0.1"): + global SVR_READY + global GWI1_READY + global GWI2_READY + global GWF1_READY + global GWF2_READY + global GWF3_READY + configs = {"local_ip":my_ip, "verdict":"oops"} + if my_ip==SVR_IP: + configs["local_port"] = 8080 + configs["local_name"] = "srv" + configs["verdict"] = "yes" + SVR_READY = True + elif my_ip==GWI1_IP: + if SVR_READY: + configs["local_port"] = 8181 + configs["local_name"] = "gwi1" + configs["remote_ip"] = SVR_IP + configs["remote_port"] = 8080 + configs["remote_name"] = "srv" + configs["verdict"] = "yes" + GWI1_READY = True + elif my_ip==GWF1_IP: + if GWI1_READY: + configs["local_port"] = 8282 + configs["local_name"] = "gwf1" + configs["remote_ip"] = GWI1_IP + configs["remote_port"] = 8181 + configs["remote_name"] = "gwi1" + configs["verdict"] = "yes" + GWF1_READY = True + elif my_ip==GWF2_IP: + if GWI1_READY: + configs["local_port"] = 8282 + configs["local_name"] = "gwf2" + configs["remote_ip"] = GWI1_IP + configs["remote_port"] = 8181 + configs["remote_name"] = "gwi1" + configs["verdict"] = "yes" + GWF2_READY = True + elif my_ip==GWF3_IP: + if GWI1_READY: + configs["local_port"] = 8282 + configs["local_name"] = "gwf3" + configs["remote_ip"] = GWI1_IP + configs["remote_port"] = 8181 + configs["remote_name"] = "gwi1" + configs["verdict"] = "yes" + GWF3_READY = True + elif my_ip==DEV1_GWF1_IP: + if GWF1_READY: + configs["local_port"] = 9001 + configs["local_name"] = "dev1gwf1" + configs["remote_ip"] = GWF1_IP + configs["remote_port"] = 8282 + configs["remote_name"] = "gwf1" + configs["send_period"] = 3000 + configs["verdict"] = "yes" + elif my_ip==DEV2_GWF1_IP: + if GWF1_READY: + configs["local_port"] = 9001 + configs["local_name"] = "dev2gwf1" + configs["remote_ip"] = GWF1_IP + configs["remote_port"] = 8282 + configs["remote_name"] = "gwf1" + configs["send_period"] = 3000 + configs["verdict"] = "yes" + elif my_ip==DEV3_GWF1_IP: + if GWF1_READY: + configs["local_port"] = 9001 + configs["local_name"] = "dev3gwf1" + configs["remote_ip"] = GWF1_IP + configs["remote_port"] = 8282 + configs["remote_name"] = "gwf1" + configs["send_period"] = 3000 + configs["verdict"] = "yes" + elif my_ip==DEV1_GWF2_IP: + if GWF2_READY: + configs["local_port"] = 9001 + configs["local_name"] = "dev1gwf2" + configs["remote_ip"] = GWF2_IP + configs["remote_port"] = 8282 + configs["remote_name"] = "gwf2" + configs["send_period"] = 3000 + configs["verdict"] = "yes" + elif my_ip==DEV2_GWF2_IP: + if GWF2_READY: + configs["local_port"] = 9001 + configs["local_name"] = "dev2gwf2" + configs["remote_ip"] = GWF2_IP + configs["remote_port"] = 8282 + configs["remote_name"] = "gwf2" + configs["send_period"] = 3000 + configs["verdict"] = "yes" + elif my_ip==DEV3_GWF2_IP: + if GWF2_READY: + configs["local_port"] = 9001 + configs["local_name"] = "dev3gwf2" + configs["remote_ip"] = GWF2_IP + configs["remote_port"] = 8282 + configs["remote_name"] = "gwf2" + configs["send_period"] = 3000 + configs["verdict"] = "yes" + elif my_ip==DEV1_GWF3_IP: + if GWF3_READY: + configs["local_port"] = 9001 + configs["local_name"] = "dev1gwf3" + configs["remote_ip"] = GWF3_IP + configs["remote_port"] = 8282 + configs["remote_name"] = "gwf3" + configs["send_period"] = 3000 + configs["verdict"] = "yes" + elif my_ip==DEV2_GWF3_IP: + if GWF3_READY: + configs["local_port"] = 9001 + configs["local_name"] = "dev2gwf3" + configs["remote_ip"] = GWF3_IP + configs["remote_port"] = 8282 + configs["remote_name"] = "gwf3" + configs["send_period"] = 3000 + configs["verdict"] = "yes" + elif my_ip==DEV3_GWF3_IP: + if GWF3_READY: + configs["local_port"] = 9001 + configs["local_name"] = "dev3gwf3" + configs["remote_ip"] = GWF3_IP + configs["remote_port"] = 8282 + configs["remote_name"] = "gwf3" + configs["send_period"] = 3000 + configs["verdict"] = "yes" + return jsonify(configs) + +@app.route("/getmyconfig/") +def configurations_giver_to_dc(): + global GWI2_READY + configs = {"local_ip":GWI2_IP, "verdict":"oops"} + if SVR_READY: + configs["local_port"] = 8181 + configs["local_name"] = "gwi2" + configs["remote_ip"] = SVR_IP + configs["remote_port"] = 8080 + configs["remote_name"] = "srv" + configs["verdict"] = "yes" + GWI2_READY = True + return jsonify(configs) + +if __name__=='__main__': + app.run(debug=False, host='0.0.0.0', port=5555) + diff --git a/Dockerfiles/forContainerNet/device/Dockerfile b/Dockerfiles/forContainerNet/device/Dockerfile new file mode 100644 index 0000000..2dd0c5c --- /dev/null +++ b/Dockerfiles/forContainerNet/device/Dockerfile @@ -0,0 +1,28 @@ +# Choosing the image to use +FROM node:buster + +# Installing required libraries +RUN apt-get update && \ + apt-get install -y net-tools iputils-ping python-pip && \ + pip install flask && \ + pip install requests && \ + mkdir mydir && \ + cd mydir && \ + npm install express && \ + npm install yargs && \ + npm install systeminformation && \ + npm install request + +COPY device.js /mydir + +COPY bootstrap_client.py /mydir + +SHELL ["/bin/bash", "-c"] + +RUN echo "nohup python /mydir/bootstrap_client.py &" > start.sh && \ + echo "/bin/bash" >> start.sh && \ + chmod 777 start.sh + +# Mandatory entrypoint in containernet +ENTRYPOINT ./start.sh + diff --git a/Dockerfiles/forContainerNet/device/bootstrap_client.py b/Dockerfiles/forContainerNet/device/bootstrap_client.py new file mode 100755 index 0000000..07a48b5 --- /dev/null +++ b/Dockerfiles/forContainerNet/device/bootstrap_client.py @@ -0,0 +1,52 @@ +#!/usr/bin/python +#coding: utf-8 +import os +import subprocess +import requests +from time import sleep + + +BOOTSTRAP_SERVER_ADDRESS = '10.10.10.10:5555' + +def retrieve_config(): + my_json_config = {"verdict":"oops"} + my_ip = str(subprocess.check_output("echo $MY_IP", shell=True)).rstrip() + print("MY_IP : %s"%(my_ip)) + while my_json_config["verdict"] != "yes": + try: + resp = requests.get("http://%s/getmyconfig/%s"%(BOOTSTRAP_SERVER_ADDRESS, my_ip), timeout=2) + except: + print("Unable to join the bootstrap server") + try: + my_json_config = resp.json() + print("Extracted configs [succ] : %s"%(my_json_config)) + except: + print("Unable to extract configs from bootstrap server's answer") + print("Extracted configs [fail] : %s"%(my_json_config)) + print("request url : ==>%s<=="%("http://%s/getmyconfig/%s"%(BOOTSTRAP_SERVER_ADDRESS, my_ip))) + if "verdict" in my_json_config and my_json_config["verdict"] == "yes": + my_config = config_json_to_string(my_json_config) + subprocess.check_output("node /mydir/*.js %s"%(my_config), shell=True) + else: + my_json_config = {"verdict":"oops"} + sleep(3) + +def config_json_to_string(json_config): + config = "" + if "local_ip" in json_config: + config += "--local_ip "+json_config["local_ip"]+" " + if "local_port" in json_config: + config += "--local_port "+str(json_config["local_port"])+" " + if "local_name" in json_config: + config += "--local_name "+json_config["local_name"]+" " + if "remote_ip" in json_config: + config += "--remote_ip "+json_config["remote_ip"]+" " + if "remote_port" in json_config: + config += "--remote_port "+str(json_config["remote_port"])+" " + if "remote_name" in json_config: + config += "--remote_name "+json_config["remote_name"]+" " + if "send_period" in json_config: + config += "--send_period "+str(json_config["send_period"])+" " + return config.strip() + +retrieve_config() diff --git a/Dockerfiles/forContainerNet/device/device.js b/Dockerfiles/forContainerNet/device/device.js new file mode 100644 index 0000000..a89042d --- /dev/null +++ b/Dockerfiles/forContainerNet/device/device.js @@ -0,0 +1,53 @@ +var express = require('express') +var app = express() +var request = require('request'); + +var argv = require('yargs').argv; +// --local_ip +// --local_port +// --local_name +// --remote_ip +// --remote_port +// --remote_name +// --send_period + +var LOCAL_ENDPOINT = {IP : argv.local_ip, PORT : argv.local_port, NAME : argv.local_name}; +var REMOTE_ENDPOINT = {IP : argv.remote_ip, PORT : argv.remote_port, NAME : argv.remote_name}; + +var DATA_PERIOD = argv.send_period; + +function doPOST(uri, body, onResponse) { + request({method: 'POST', uri: uri, json : body}, onResponse); +} + +function register() { + doPOST( + 'http://' + REMOTE_ENDPOINT.IP + ':' + REMOTE_ENDPOINT.PORT + '/devices/register', + { + Name : LOCAL_ENDPOINT.NAME, + PoC : 'http://' + LOCAL_ENDPOINT.IP + ':' + LOCAL_ENDPOINT.PORT, + }, + function(error, response, respBody) { + console.log(respBody); + } + ); +} + +var dataItem = 0; +function sendData() { + doPOST( + 'http://' + REMOTE_ENDPOINT.IP + ':' + REMOTE_ENDPOINT.PORT + '/device/'+ LOCAL_ENDPOINT.NAME + '/data', + { + Name : LOCAL_ENDPOINT.NAME, + Data : dataItem++, + Time : Date.now(), + }, + function(error, response, respBody) { + console.log(respBody); + } + ); +} + +register(); + +setInterval(sendData, DATA_PERIOD); diff --git a/Dockerfiles/forContainerNet/gateway/Dockerfile b/Dockerfiles/forContainerNet/gateway/Dockerfile new file mode 100644 index 0000000..17a540b --- /dev/null +++ b/Dockerfiles/forContainerNet/gateway/Dockerfile @@ -0,0 +1,28 @@ +# Choosing the image to use +FROM node:buster + +# Installing required libraries +RUN apt-get update && \ + apt-get install -y net-tools iputils-ping python-pip && \ + pip install flask && \ + pip install requests && \ + mkdir mydir && \ + cd mydir && \ + npm install express && \ + npm install yargs && \ + npm install systeminformation && \ + npm install request + +COPY gateway.js /mydir + +COPY bootstrap_client.py /mydir + +SHELL ["/bin/bash", "-c"] + +RUN echo "nohup python /mydir/bootstrap_client.py &" > start.sh && \ + echo "/bin/bash" >> start.sh && \ + chmod 777 start.sh + +# Mandatory entrypoint in containernet +ENTRYPOINT ./start.sh + diff --git a/Dockerfiles/forContainerNet/gateway/bootstrap_client.py b/Dockerfiles/forContainerNet/gateway/bootstrap_client.py new file mode 100755 index 0000000..07a48b5 --- /dev/null +++ b/Dockerfiles/forContainerNet/gateway/bootstrap_client.py @@ -0,0 +1,52 @@ +#!/usr/bin/python +#coding: utf-8 +import os +import subprocess +import requests +from time import sleep + + +BOOTSTRAP_SERVER_ADDRESS = '10.10.10.10:5555' + +def retrieve_config(): + my_json_config = {"verdict":"oops"} + my_ip = str(subprocess.check_output("echo $MY_IP", shell=True)).rstrip() + print("MY_IP : %s"%(my_ip)) + while my_json_config["verdict"] != "yes": + try: + resp = requests.get("http://%s/getmyconfig/%s"%(BOOTSTRAP_SERVER_ADDRESS, my_ip), timeout=2) + except: + print("Unable to join the bootstrap server") + try: + my_json_config = resp.json() + print("Extracted configs [succ] : %s"%(my_json_config)) + except: + print("Unable to extract configs from bootstrap server's answer") + print("Extracted configs [fail] : %s"%(my_json_config)) + print("request url : ==>%s<=="%("http://%s/getmyconfig/%s"%(BOOTSTRAP_SERVER_ADDRESS, my_ip))) + if "verdict" in my_json_config and my_json_config["verdict"] == "yes": + my_config = config_json_to_string(my_json_config) + subprocess.check_output("node /mydir/*.js %s"%(my_config), shell=True) + else: + my_json_config = {"verdict":"oops"} + sleep(3) + +def config_json_to_string(json_config): + config = "" + if "local_ip" in json_config: + config += "--local_ip "+json_config["local_ip"]+" " + if "local_port" in json_config: + config += "--local_port "+str(json_config["local_port"])+" " + if "local_name" in json_config: + config += "--local_name "+json_config["local_name"]+" " + if "remote_ip" in json_config: + config += "--remote_ip "+json_config["remote_ip"]+" " + if "remote_port" in json_config: + config += "--remote_port "+str(json_config["remote_port"])+" " + if "remote_name" in json_config: + config += "--remote_name "+json_config["remote_name"]+" " + if "send_period" in json_config: + config += "--send_period "+str(json_config["send_period"])+" " + return config.strip() + +retrieve_config() diff --git a/Dockerfiles/forContainerNet/gateway/gateway.js b/Dockerfiles/forContainerNet/gateway/gateway.js new file mode 100644 index 0000000..440a310 --- /dev/null +++ b/Dockerfiles/forContainerNet/gateway/gateway.js @@ -0,0 +1,127 @@ +var express = require('express') +var app = express() +app.use(express.json()) // for parsing application/json + +var request = require('request'); +const si = require('systeminformation'); +var argv = require('yargs').argv; +// --local_ip +// --local_port +// --local_name +// --remote_ip +// --remote_port +// --remote_name + +var LOCAL_ENDPOINT = {IP : argv.local_ip, PORT : argv.local_port, NAME : argv.local_name}; +var REMOTE_ENDPOINT = {IP : argv.remote_ip, PORT : argv.remote_port, NAME : argv.remote_name}; + +const E_OK = 200; +const E_CREATED = 201; +const E_FORBIDDEN = 403; +const E_NOT_FOUND = 404; +const E_ALREADY_EXIST = 500; + + +var db = { + gateways : new Map() + }; + +function addNewGateway(gw) { + var res = -1; + if (!db.gateways.get(gw.Name)) { + db.gateways.set(gw.Name, gw); + res = 0; + } + return res; +} + +function removeGateway(gw) { + if (db.gateways.get(gw.Name)) + db.gateways.delete(gw.Name); +} + + +function doPOST(uri, body, onResponse) { + request({method: 'POST', uri: uri, json : body}, onResponse); +} + +function register() { + doPOST( + 'http://' + REMOTE_ENDPOINT.IP + ':' + REMOTE_ENDPOINT.PORT + '/gateways/register', + { + Name : LOCAL_ENDPOINT.NAME, + PoC : 'http://' + LOCAL_ENDPOINT.IP + ':' + LOCAL_ENDPOINT.PORT, + }, + function(error, response, respBody) { + console.log(respBody); + } + ); +} + + +app.post('/gateways/register', function(req, res) { + console.log(req.body); + var result = addNewGateway(req.body); + if (result === 0) + res.sendStatus(E_CREATED); + else + res.sendStatus(E_ALREADY_EXIST); + }); +app.post('/devices/register', function(req, res) { + console.log(req.body); + doPOST( + 'http://' + REMOTE_ENDPOINT.IP + ':' +REMOTE_ENDPOINT.PORT + '/devices/register', + req.body, + function(error, response, respBody) { + console.log(respBody); + res.sendStatus(E_OK); + } + ) + }); + app.post('/device/:dev/data', function(req, res) { + console.log(req.body); + var dev = req.params.dev; + doPOST( + 'http://' + REMOTE_ENDPOINT.IP + ':' +REMOTE_ENDPOINT.PORT + '/device/' + dev + '/data', + req.body, + function(error, response, respBody) { + console.log(respBody); + res.sendStatus(E_OK); + } + ) +}); +app.get('/gateways', function(req, res) { + console.log(req.body); + let resObj = []; + db.gateways.forEach((v,k) => { + resObj.push(v); + }); + res.send(resObj); +}); +app.get('/gateway/:gw', function(req, res) { + console.log(req.body); + var gw = req.params.gw; + var gateway = db.gateways.get(gw); + if (gateway) + res.status(E_OK).send(JSON.stringify(gateway)); + else + res.sendStatus(E_NOT_FOUND); +}); + +app.get('/ping', function(req, res) { + console.log(req.body); + res.status(E_OK).send({pong: Date.now()}); +}); +app.get('/health', function(req, res) { + console.log(req.body); + si.currentLoad((d) => { + console.log(d); + res.status(E_OK).send(JSON.stringify(d)); + }) +}); + + +register(); +app.listen(LOCAL_ENDPOINT.PORT , function () { + console.log(LOCAL_ENDPOINT.NAME + ' listening on : ' + LOCAL_ENDPOINT.PORT ); +}); diff --git a/Dockerfiles/forContainerNet/server/Dockerfile b/Dockerfiles/forContainerNet/server/Dockerfile new file mode 100644 index 0000000..21c507b --- /dev/null +++ b/Dockerfiles/forContainerNet/server/Dockerfile @@ -0,0 +1,28 @@ +# Choosing the image to use +FROM node:buster + +# Installing required libraries +RUN apt-get update && \ + apt-get install -y net-tools iputils-ping python-pip && \ + pip install flask && \ + pip install requests && \ + mkdir mydir && \ + cd mydir && \ + npm install express && \ + npm install yargs && \ + npm install systeminformation && \ + npm install request + +COPY server.js /mydir + +COPY bootstrap_client.py /mydir + +SHELL ["/bin/bash", "-c"] + +RUN echo "nohup python /mydir/bootstrap_client.py &" > start.sh && \ + echo "/bin/bash" >> start.sh && \ + chmod 777 start.sh + +# Mandatory entrypoint in containernet +ENTRYPOINT ./start.sh + diff --git a/Dockerfiles/forContainerNet/server/bootstrap_client.py b/Dockerfiles/forContainerNet/server/bootstrap_client.py new file mode 100755 index 0000000..07a48b5 --- /dev/null +++ b/Dockerfiles/forContainerNet/server/bootstrap_client.py @@ -0,0 +1,52 @@ +#!/usr/bin/python +#coding: utf-8 +import os +import subprocess +import requests +from time import sleep + + +BOOTSTRAP_SERVER_ADDRESS = '10.10.10.10:5555' + +def retrieve_config(): + my_json_config = {"verdict":"oops"} + my_ip = str(subprocess.check_output("echo $MY_IP", shell=True)).rstrip() + print("MY_IP : %s"%(my_ip)) + while my_json_config["verdict"] != "yes": + try: + resp = requests.get("http://%s/getmyconfig/%s"%(BOOTSTRAP_SERVER_ADDRESS, my_ip), timeout=2) + except: + print("Unable to join the bootstrap server") + try: + my_json_config = resp.json() + print("Extracted configs [succ] : %s"%(my_json_config)) + except: + print("Unable to extract configs from bootstrap server's answer") + print("Extracted configs [fail] : %s"%(my_json_config)) + print("request url : ==>%s<=="%("http://%s/getmyconfig/%s"%(BOOTSTRAP_SERVER_ADDRESS, my_ip))) + if "verdict" in my_json_config and my_json_config["verdict"] == "yes": + my_config = config_json_to_string(my_json_config) + subprocess.check_output("node /mydir/*.js %s"%(my_config), shell=True) + else: + my_json_config = {"verdict":"oops"} + sleep(3) + +def config_json_to_string(json_config): + config = "" + if "local_ip" in json_config: + config += "--local_ip "+json_config["local_ip"]+" " + if "local_port" in json_config: + config += "--local_port "+str(json_config["local_port"])+" " + if "local_name" in json_config: + config += "--local_name "+json_config["local_name"]+" " + if "remote_ip" in json_config: + config += "--remote_ip "+json_config["remote_ip"]+" " + if "remote_port" in json_config: + config += "--remote_port "+str(json_config["remote_port"])+" " + if "remote_name" in json_config: + config += "--remote_name "+json_config["remote_name"]+" " + if "send_period" in json_config: + config += "--send_period "+str(json_config["send_period"])+" " + return config.strip() + +retrieve_config() diff --git a/Dockerfiles/forContainerNet/server/server.js b/Dockerfiles/forContainerNet/server/server.js new file mode 100644 index 0000000..9428d17 --- /dev/null +++ b/Dockerfiles/forContainerNet/server/server.js @@ -0,0 +1,167 @@ +var express = require('express') +var app = express() +app.use(express.json()) + +var argv = require('yargs').argv; +// --local_ip +// --local_port +// --local_name +const si = require('systeminformation'); + +var LOCAL_ENDPOINT = {IP : argv.local_ip, PORT : argv.local_port, NAME : argv.local_name}; + +const E_OK = 200; +const E_CREATED = 201; +const E_FORBIDDEN = 403; +const E_NOT_FOUND = 404; +const E_ALREADY_EXIST = 500; + + +var db = { + devices : new Map(), + data : new Map(), + gateways : new Map() + }; + +function addNewDevice(dev) { + var result = -1; + if (!db.devices.get(dev.Name)) { + db.devices.set(dev.Name, dev); + + if (db.devices.get(dev.Name)) + db.data.delete(dev.Name); + db.data.set(dev.Name, []); + + result = 0; + } + return result; +} + +function addNewGateway(gw) { + var result = -1; + if (!db.gateways.get(gw.Name)) { + db.gateways.set(gw.Name, gw); + result = 0; + } + return result; +} + +function removeDevice(dev) { + if (db.devices.get(dev.Name)) { + db.devices.delete(dev.Name); + if (db.devices.get(dev.Name)) + db.data.delete(dev.Name); + } +} + +function removeGateway(gw) { + if (db.gateways.get(gw.Name)) + db.gateways.delete(gw.Name); +} + +function addDeviceData(dev, data) { + var result = -1; + var device = db.devices.get(dev); + if (device) { + db.data.get(dev).push(data); + result = 0; + } + return result; +} + + + +app.get('/devices', function(req, res) { + console.log(req.body); + let resObj = []; + db.devices.forEach((v,k) => { + resObj.push(v); + }); + res.status(E_OK).send(resObj); +}); +app.get('/device/:dev', function(req, res) { + console.log(req.body); + var dev = req.params.dev; + var device = db.devices.get(dev); + if (device) + res.status(E_OK).send(JSON.stringify(device)); + else + res.sendStatus(E_NOT_FOUND); +}); +app.post('/device/:dev/data', function(req, res) { + console.log(req.body); + var dev = req.params.dev; + var result = addDeviceData(dev, req.body); + if (result === 0) + res.sendStatus(E_CREATED); + else + res.sendStatus(E_NOT_FOUND); +}); +app.get('/device/:dev/data', function(req, res) { + console.log(req.body); + var dev = req.params.dev; + var device = db.devices.get(dev); + if (device){ + var data = db.data.get(dev); + if (data) { + let resObj = []; + data.forEach((v,k) => { + resObj.push(v); + }); + res.status(E_OK).send(JSON.stringify(resObj)); + } + else + res.sendStatus(E_NOT_FOUND); + } + else + res.sendStatus(E_NOT_FOUND); +}); +app.post('/devices/register', function(req, res) { + console.log(req.body); + var result = addNewDevice(req.body); + if ( result === 0) + res.sendStatus(E_CREATED); + else + res.sendStatus(E_ALREADY_EXIST); +}); +app.get('/gateways', function(req, res) { + console.log(req.body); + let resObj = []; + db.gateways.forEach((v,k) => { + resObj.push(v); + }); + res.send(resObj); +}); +app.get('/gateway/:gw', function(req, res) { + console.log(req.body); + var gw = req.params.gw; + var gateway = db.gateways.get(gw); + if (gateway) + res.status(E_OK).send(JSON.stringify(gateway)); + else + res.sendStatus(E_NOT_FOUND); +}); +app.post('/gateways/register', function(req, res) { + console.log(req.body); + var result = addNewGateway(req.body); + if ( result === 0) + res.sendStatus(E_CREATED); + else + res.sendStatus(E_ALREADY_EXIST); +}); + +app.get('/ping', function(req, res) { + console.log(req.body); + res.status(E_OK).send({pong: Date.now()}); +}); +app.get('/health', function(req, res) { + console.log(req.body); + si.currentLoad((d) => { + console.log(d); + res.status(E_OK).send(JSON.stringify(d)); + }) +}); + +app.listen(LOCAL_ENDPOINT.PORT , function () { + console.log(LOCAL_ENDPOINT.NAME + ' listening on : ' + LOCAL_ENDPOINT.PORT ); +}); diff --git a/enonce/2020-2021-_UE-PETAR--SUJETS-ETUDE.pdf b/enonce/2020-2021-_UE-PETAR--SUJETS-ETUDE.pdf new file mode 100644 index 0000000000000000000000000000000000000000..662ba379455ffe28ccebd21548941faa2b574c06 GIT binary patch literal 109806 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%0D>(Ul%u=zD%me=;ab2#`5SDtDx;QqzY7`0z%^M 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 { + resObj.push(v); + }); + res.send(resObj); +}); +app.get('/gateway/:gw', function(req, res) { + console.log(req.body); + var gw = req.params.gw; + var gateway = db.gateways.get(gw); + if (gateway) + res.status(E_OK).send(JSON.stringify(gateway)); + else + res.sendStatus(E_NOT_FOUND); +}); + +app.get('/ping', function(req, res) { + console.log(req.body); + res.status(E_OK).send({pong: Date.now()}); +}); +app.get('/health', function(req, res) { + console.log(req.body); + si.currentLoad((d) => { + console.log(d); + res.status(E_OK).send(JSON.stringify(d)); + }) +}); + + +register(); +app.listen(LOCAL_ENDPOINT.PORT , function () { + console.log(LOCAL_ENDPOINT.NAME + ' listening on : ' + LOCAL_ENDPOINT.PORT ); +}); diff --git a/jsfiles/server.js b/jsfiles/server.js new file mode 100644 index 0000000..9428d17 --- /dev/null +++ b/jsfiles/server.js @@ -0,0 +1,167 @@ +var express = require('express') +var app = express() +app.use(express.json()) + +var argv = require('yargs').argv; +// --local_ip +// --local_port +// --local_name +const si = require('systeminformation'); + +var LOCAL_ENDPOINT = {IP : argv.local_ip, PORT : argv.local_port, NAME : argv.local_name}; + +const E_OK = 200; +const E_CREATED = 201; +const E_FORBIDDEN = 403; +const E_NOT_FOUND = 404; +const E_ALREADY_EXIST = 500; + + +var db = { + devices : new Map(), + data : new Map(), + gateways : new Map() + }; + +function addNewDevice(dev) { + var result = -1; + if (!db.devices.get(dev.Name)) { + db.devices.set(dev.Name, dev); + + if (db.devices.get(dev.Name)) + db.data.delete(dev.Name); + db.data.set(dev.Name, []); + + result = 0; + } + return result; +} + +function addNewGateway(gw) { + var result = -1; + if (!db.gateways.get(gw.Name)) { + db.gateways.set(gw.Name, gw); + result = 0; + } + return result; +} + +function removeDevice(dev) { + if (db.devices.get(dev.Name)) { + db.devices.delete(dev.Name); + if (db.devices.get(dev.Name)) + db.data.delete(dev.Name); + } +} + +function removeGateway(gw) { + if (db.gateways.get(gw.Name)) + db.gateways.delete(gw.Name); +} + +function addDeviceData(dev, data) { + var result = -1; + var device = db.devices.get(dev); + if (device) { + db.data.get(dev).push(data); + result = 0; + } + return result; +} + + + +app.get('/devices', function(req, res) { + console.log(req.body); + let resObj = []; + db.devices.forEach((v,k) => { + resObj.push(v); + }); + res.status(E_OK).send(resObj); +}); +app.get('/device/:dev', function(req, res) { + console.log(req.body); + var dev = req.params.dev; + var device = db.devices.get(dev); + if (device) + res.status(E_OK).send(JSON.stringify(device)); + else + res.sendStatus(E_NOT_FOUND); +}); +app.post('/device/:dev/data', function(req, res) { + console.log(req.body); + var dev = req.params.dev; + var result = addDeviceData(dev, req.body); + if (result === 0) + res.sendStatus(E_CREATED); + else + res.sendStatus(E_NOT_FOUND); +}); +app.get('/device/:dev/data', function(req, res) { + console.log(req.body); + var dev = req.params.dev; + var device = db.devices.get(dev); + if (device){ + var data = db.data.get(dev); + if (data) { + let resObj = []; + data.forEach((v,k) => { + resObj.push(v); + }); + res.status(E_OK).send(JSON.stringify(resObj)); + } + else + res.sendStatus(E_NOT_FOUND); + } + else + res.sendStatus(E_NOT_FOUND); +}); +app.post('/devices/register', function(req, res) { + console.log(req.body); + var result = addNewDevice(req.body); + if ( result === 0) + res.sendStatus(E_CREATED); + else + res.sendStatus(E_ALREADY_EXIST); +}); +app.get('/gateways', function(req, res) { + console.log(req.body); + let resObj = []; + db.gateways.forEach((v,k) => { + resObj.push(v); + }); + res.send(resObj); +}); +app.get('/gateway/:gw', function(req, res) { + console.log(req.body); + var gw = req.params.gw; + var gateway = db.gateways.get(gw); + if (gateway) + res.status(E_OK).send(JSON.stringify(gateway)); + else + res.sendStatus(E_NOT_FOUND); +}); +app.post('/gateways/register', function(req, res) { + console.log(req.body); + var result = addNewGateway(req.body); + if ( result === 0) + res.sendStatus(E_CREATED); + else + res.sendStatus(E_ALREADY_EXIST); +}); + +app.get('/ping', function(req, res) { + console.log(req.body); + res.status(E_OK).send({pong: Date.now()}); +}); +app.get('/health', function(req, res) { + console.log(req.body); + si.currentLoad((d) => { + console.log(d); + res.status(E_OK).send(JSON.stringify(d)); + }) +}); + +app.listen(LOCAL_ENDPOINT.PORT , function () { + console.log(LOCAL_ENDPOINT.NAME + ' listening on : ' + LOCAL_ENDPOINT.PORT ); +}); diff --git a/topologie/topology.py b/topologie/topology.py new file mode 100755 index 0000000..740f5ea --- /dev/null +++ b/topologie/topology.py @@ -0,0 +1,191 @@ +#!/usr/bin/python +# Copyright (c) 2020 INSA Toulouse +# ALL RIGHTS RESERVED. +# +# This topology has been built by inspiring on the 'default_single_dc_topology.py' example of son-emu +# +# Authors +# Abdel Kader CHABI SIKA BONI (Master2 ILoRD at INSA Toulouse, chabisik@etud.insa-toulouse.fr) +# Arnaud PRIEU (5SDBD at INSA Toulouse, prieu@etud.insa-toulouse.fr) +# Year: 2020-2021 + + +import logging +from mininet.log import setLogLevel, info +from emuvim.dcemulator.net import DCNetwork +from emuvim.api.rest.rest_api_endpoint import RestApiEndpoint +from emuvim.api.openstack.openstack_api_endpoint import OpenstackApiEndpoint + +logging.basicConfig(level=logging.INFO) +setLogLevel('info') # set Mininet loglevel +logging.getLogger('werkzeug').setLevel(logging.DEBUG) +logging.getLogger('api.openstack.base').setLevel(logging.DEBUG) +logging.getLogger('api.openstack.compute').setLevel(logging.DEBUG) +logging.getLogger('api.openstack.keystone').setLevel(logging.DEBUG) +logging.getLogger('api.openstack.nova').setLevel(logging.DEBUG) +logging.getLogger('api.openstack.neutron').setLevel(logging.DEBUG) +logging.getLogger('api.openstack.heat').setLevel(logging.DEBUG) +logging.getLogger('api.openstack.heat.parser').setLevel(logging.DEBUG) +logging.getLogger('api.openstack.glance').setLevel(logging.DEBUG) +logging.getLogger('api.openstack.helper').setLevel(logging.DEBUG) + +##################################################################################################### +# OUR TOPOLOGY'S DETAILS # +# (if changed, bootstrap server script must be changed too and the new config:topo image builded) # +##################################################################################################### +BOOTSTRAP_SERVER = '10.10.10.10' #name = btrap; port = 5555 + +SVR_IP = '10.0.0.1' #name = srv + +GWI1_IP = '10.2.2.1' #name = gwi1 +GWI2_IP = '10.2.2.2' #name = gwi2 + +GWF1_IP = '10.0.1.100' #name = gwf1 +DEV1_GWF1_IP = '10.0.1.1' #name = dev1gwf1 +DEV2_GWF1_IP = '10.0.1.2' #name = dev2gwf1 +DEV3_GWF1_IP = '10.0.1.3' #name = dev3gwf1 + +GWF2_IP = '10.0.2.100' #name = gwf2 +DEV1_GWF2_IP = '10.0.2.1' #name = dev1gwf2 +DEV2_GWF2_IP = '10.0.2.2' #name = dev2gwf2 +DEV3_GWF2_IP = '10.0.2.3' #name = dev3gwf2 + +GWF3_IP = '10.0.3.100' #name = gwf3 +DEV1_GWF3_IP = '10.0.3.1' #name = dev1gwf3 +DEV2_GWF3_IP = '10.0.3.2' #name = dev2gwf3 +DEV3_GWF3_IP = '10.0.3.3' #name = dev3gwf3 + +''' +TOPOLOGY OVERVIEW +Necessary docker images: config:topo ; server:topo ; gateway:topo ; device:topo + + + ++++++++ ++++++++ + + dev1 +--- + gwf1 + + ++++++++ | ++++++++ + | | ______________++++++++ + | | | + dev2 + + ++++++++ | ++++++++ ++++++++ ++++++++ + + gwi1 + |_______+ s5 +----------------------------+ dev3 + + ++++++++ ++++++++ ++++++++ ++++++++ + | | _____________________________________________+ gwf2 + + | | | ++++++++ + +++++++ +++++++ +++++++ +++++++ ++++++++ ++++++++ + + srv +--------+ s1 +---------+ s2 +---------+ s3 +------+ s6 +--------------------+ dev1 + + +++++++ +++++++ +++++++ +++++++ ++++++++ ++++++++ + | | | | | ++++++++ + | | | | |_____________+ dev2 + + | | | | ++++++++ + | | ++++++ | ++++++++ + | | + s4 +---- |_____+ dev3 + + | | ++++++ | ++++++++ + | +++++++++ | | + | + btrap + | |____++++++++ ++++++++ + | +++++++++ ______| + s7 +--------+ dev1 + + | | ++++++++ ++++++++ + | | ______________| | | + | ________| | | | + | | | | |___________++++++++ + | | | | + dev2 + + | ++++++ | | ++++++++ + |____________________________+ DC + ++++++++ ++++++++ + ++++++ + dev3 + + gwf3 + + ++++++++ ++++++++ +''' +##################################################################################################### + + +def create_topology(): + net = DCNetwork(monitor=False, enable_learning=True) + + dc1 = net.addDatacenter("dc1") + # add OpenStack-like APIs to the emulated DC + api1 = OpenstackApiEndpoint("0.0.0.0", 6001) + api1.connect_datacenter(dc1) + api1.start() + api1.connect_dc_network(net) + # add the command line interface endpoint to the emulated DC (REST API) + rapi1 = RestApiEndpoint("0.0.0.0", 5001) + rapi1.connectDCNetwork(net) + rapi1.connectDatacenter(dc1) + rapi1.start() + + info('*** Adding bootstrap server\n') + btrap = net.addDocker('btrap', ip=BOOTSTRAP_SERVER, dimage="config:topo") + + info('*** Adding topology server\n') + srv = net.addDocker('srv', ip=SVR_IP, dimage="server:topo", environment={'MY_IP':SVR_IP}) + + info('*** Adding topology intermediary gateway\n') + gwi1 = net.addDocker('gwi1', ip=GWI1_IP, dimage="gateway:topo", environment={'MY_IP':GWI1_IP}) + + info('*** Adding topology final gateways\n') + gwf1 = net.addDocker('gwf1', ip=GWF1_IP, dimage="gateway:topo", environment={'MY_IP':GWF1_IP}) + gwf2 = net.addDocker('gwf2', ip=GWF2_IP, dimage="gateway:topo", environment={'MY_IP':GWF2_IP}) + gwf3 = net.addDocker('gwf3', ip=GWF3_IP, dimage="gateway:topo", environment={'MY_IP':GWF3_IP}) + + info('*** Adding 1st final gateway devices\n') + dev1gwf1 = net.addDocker('dev1gwf1', ip=DEV1_GWF1_IP, dimage="device:topo", environment={'MY_IP':DEV1_GWF1_IP}) + dev2gwf1 = net.addDocker('dev2gwf1', ip=DEV2_GWF1_IP, dimage="device:topo", environment={'MY_IP':DEV2_GWF1_IP}) + dev3gwf1 = net.addDocker('dev3gwf1', ip=DEV3_GWF1_IP, dimage="device:topo", environment={'MY_IP':DEV3_GWF1_IP}) + + info('*** Adding 2nd final gateway devices\n') + dev1gwf2 = net.addDocker('dev1gwf2', ip=DEV1_GWF2_IP, dimage="device:topo", environment={'MY_IP':DEV1_GWF2_IP}) + dev2gwf2 = net.addDocker('dev2gwf2', ip=DEV2_GWF2_IP, dimage="device:topo", environment={'MY_IP':DEV2_GWF2_IP}) + dev3gwf2 = net.addDocker('dev3gwf2', ip=DEV3_GWF2_IP, dimage="device:topo", environment={'MY_IP':DEV3_GWF2_IP}) + + info('*** Adding 3rd final gateway devices\n') + dev1gwf3 = net.addDocker('dev1gwf3', ip=DEV1_GWF3_IP, dimage="device:topo", environment={'MY_IP':DEV1_GWF3_IP}) + dev2gwf3 = net.addDocker('dev2gwf3', ip=DEV2_GWF3_IP, dimage="device:topo", environment={'MY_IP':DEV2_GWF3_IP}) + dev3gwf3 = net.addDocker('dev3gwf3', ip=DEV3_GWF3_IP, dimage="device:topo", environment={'MY_IP':DEV3_GWF3_IP}) + + info('*** Adding switches\n') + s1 = net.addSwitch('s1') + s2 = net.addSwitch('s2') + s3 = net.addSwitch('s3') + s4 = net.addSwitch('s4') + s5 = net.addSwitch('s5') + s6 = net.addSwitch('s6') + s7 = net.addSwitch('s7') + + info('*** Creating links\n') + net.addLink(btrap, s2) + net.addLink(s1, s2) + net.addLink(s1, srv) + net.addLink(gwi1, s2) + net.addLink(s2, s3) + net.addLink(s3, s4) + net.addLink(dc1, s4) + net.addLink(dc1, srv) # + ########ZONE1########### + net.addLink(s3, s5) + net.addLink(gwf1, s5) + net.addLink(dev1gwf1, s5) + net.addLink(dev2gwf1, s5) + net.addLink(dev3gwf1, s5) + ########ZONE2########### + net.addLink(s3, s6) + net.addLink(gwf2, s6) + net.addLink(dev1gwf2, s6) + net.addLink(dev2gwf2, s6) + net.addLink(dev3gwf2, s6) + ########ZONE3########### + net.addLink(s4, s7) + net.addLink(gwf3, s7) + net.addLink(dev1gwf3, s7) + net.addLink(dev2gwf3, s7) + net.addLink(dev3gwf3, s7) + + info('*** Starting network\n') + net.start() + net.CLI() + # when the user types exit in the CLI, we stop the emulator + net.stop() + + +def main(): + create_topology() + + +if __name__ == '__main__': + main()