From 9c252b6c886bc254872fd1dfe3c19fab6fe15570 Mon Sep 17 00:00:00 2001 From: peusterm Date: Wed, 6 Jan 2016 16:59:53 +0100 Subject: [PATCH] added basic API registration and connection mechanism --- README.md | 11 ++++++-- emuvim/api/zerorpcapi.py | 53 ++++++++++++++++++++++++++++++++++++++ emuvim/cli/__main__.py | 24 +++++++++++++++++ emuvim/dcemulator/net.py | 2 +- emuvim/dcemulator/node.py | 2 +- emuvim/example_topology.py | 18 +++++++++++-- 6 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 emuvim/api/zerorpcapi.py diff --git a/README.md b/README.md index 0ee1d9e..63ed10e 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,18 @@ ## emu-vim +### Requirements +* needs the latest Dockernet to be installed in the system + * the wrapper uses standard Python imports to use the Dockernet modules +* Uses ZeroMQ based RPC to open a cloud-like interface that can be used by a demo CLI client + * pip install import zerorpc + * This will be replaced / extended by a REST API later + ### TODO * Add runtime API -** call startAPI from topology definition and start it in a own thread? -** make it possible to start different API endpoints for different DCs? + * call startAPI from topology definition and start it in a own thread? + * make it possible to start different API endpoints for different DCs? * Add resource constraints to datacenters * Add constraints to Links * Check if we can use the Mininet GUI to visualize our DCs? \ No newline at end of file diff --git a/emuvim/api/zerorpcapi.py b/emuvim/api/zerorpcapi.py new file mode 100644 index 0000000..88d7740 --- /dev/null +++ b/emuvim/api/zerorpcapi.py @@ -0,0 +1,53 @@ +""" +Distributed Cloud Emulator (dcemulator) +(c) 2015 by Manuel Peuster +""" + +import logging +import threading +import zerorpc + +logging.basicConfig(level=logging.DEBUG) + + +class ZeroRpcApiEndpoint(object): + + def __init__(self, listenip, port): + self.dcs = {} + self.ip = listenip + self.port = port + logging.debug("Created API endpoint %s(%s:%d)" % ( + self.__class__.__name__, self.ip, self.port)) + + def connectDatacenter(self, dc): + self.dcs[dc.name] = dc + logging.info("Connected DC(%s) to API endpoint %s(%s:%d)" % ( + dc.name, self.__class__.__name__, self.ip, self.port)) + + def start(self): + thread = threading.Thread(target=self._api_server_thread, args=()) + thread.daemon = True + thread.start() + logging.debug("Started API endpoint %s(%s:%d)" % ( + self.__class__.__name__, self.ip, self.port)) + + def _api_server_thread(self): + s = zerorpc.Server(MultiDatacenterApi(self.dcs)) + s.bind("tcp://%s:%d" % (self.ip, self.port)) + s.run() + + +class MultiDatacenterApi(object): + + def __init__(self, dcs): + self.dcs = dcs + + def compute_action_start(self, dc_name, compute_name): + # TODO return UUID / IP ? + logging.info("compute start") + + def compute_action_stop(self, dc_name, compute_name): + logging.info("compute stop") + + def compute_list(self): + pass diff --git a/emuvim/cli/__main__.py b/emuvim/cli/__main__.py index e69de29..771049b 100644 --- a/emuvim/cli/__main__.py +++ b/emuvim/cli/__main__.py @@ -0,0 +1,24 @@ +""" + For now only a dummy client. Connects to the zerorpc interface of the + emulator and performs some actions (start/stop/list). +""" +import time +import zerorpc + + +def main(): + print "Example CLI client" + # create connection to remote Mininet instance + c = zerorpc.Client() + c.connect("tcp://127.0.0.1:4242") + + # do some API tests + print c.compute_action_start("dc2", "my_new_container1") + + time.sleep(5) + + print c.compute_action_stop("dc2", "my_new_container1") + + +if __name__ == '__main__': + main() diff --git a/emuvim/dcemulator/net.py b/emuvim/dcemulator/net.py index 8ea41a7..586b1e8 100644 --- a/emuvim/dcemulator/net.py +++ b/emuvim/dcemulator/net.py @@ -69,7 +69,7 @@ class DCNetwork(object): # create link if everything is correct if (node1 is not None and isinstance(node1, OVSKernelSwitch) and node2 is not None and isinstance(node2, OVSKernelSwitch)): - self.mnet.addLink(node1, node2) # TODO we need TCLinks with user defined performance her + self.mnet.addLink(node1, node2) # TODO we need TCLinks with user defined performance here else: raise Exception( "one of the given nodes is not a Mininet switch or None") diff --git a/emuvim/dcemulator/node.py b/emuvim/dcemulator/node.py index b12751f..b095e19 100644 --- a/emuvim/dcemulator/node.py +++ b/emuvim/dcemulator/node.py @@ -29,7 +29,7 @@ class Datacenter(object): Each data center is represented by a single switch to which compute resources can be connected at run time. - TODO: This will be changes in the future to support multiple networks + TODO: This will be changed in the future to support multiple networks per data center """ self.switch = self.net.mnet.addSwitch( diff --git a/emuvim/example_topology.py b/emuvim/example_topology.py index f2be310..a21cdba 100644 --- a/emuvim/example_topology.py +++ b/emuvim/example_topology.py @@ -7,11 +7,13 @@ script. """ import logging from dcemulator.net import DCNetwork +from api.zerorpcapi import ZeroRpcApiEndpoint logging.basicConfig(level=logging.DEBUG) def create_topology1(): + # TODO add long comments to this example to show people how to use this # initialize network net = DCNetwork() @@ -27,12 +29,24 @@ def create_topology1(): net.addLink("dc1", s1) net.addLink(s1, "dc3") net.addLink(s1, dc4) + + # create and start APIs (to access emulated cloud data centers) + zapi1 = ZeroRpcApiEndpoint("0.0.0.0", 4242) + zapi1.connectDatacenter(dc1) + zapi1.connectDatacenter(dc2) + zapi1.start() + # lets also create a second API endpoint on another port to + # demonstrate hat you can have one endpoint for each of + # your data centers + zapi2 = ZeroRpcApiEndpoint("0.0.0.0", 4343) + zapi2.connectDatacenter(dc3) + zapi2.connectDatacenter(dc4) + zapi2.start() + # start network net.start() net.CLI() # TODO remove this when we integrate APIs? net.stop() # TODO remove this when we integrate APIs? - # start APIs (to access emulated cloud data centers) - pass # TODO: how to reflect one API endpoint per DC? def main(): -- 2.17.1