Merge pull request #133 from mpeuster/master
[osm/vim-emu.git] / src / emuvim / api / zerorpc / compute.py
old mode 100644 (file)
new mode 100755 (executable)
index 6e4a083..5e5d0de
@@ -1,4 +1,31 @@
 """
+Copyright (c) 2015 SONATA-NFV and Paderborn University
+ALL RIGHTS RESERVED.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
+nor the names of its contributors may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+
+This work has been performed in the framework of the SONATA project,
+funded by the European Commission under Grant number 671517 through
+the Horizon 2020 and 5G-PPP programmes. The authors would like to
+acknowledge the contributions of their colleagues of the SONATA
+partner consortium (www.sonata-nfv.eu).
+"""
+"""
 Distributed Cloud Emulator (dcemulator)
 (c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
 """
@@ -7,6 +34,11 @@ import logging
 import threading
 import zerorpc
 
+import paramiko
+import ipaddress
+import time
+import gevent
+
 logging.basicConfig(level=logging.INFO)
 
 
@@ -56,9 +88,9 @@ class MultiDatacenterApi(object):
     def __init__(self, dcs):
         self.dcs = dcs
 
-    def compute_action_start(self, dc_label, compute_name, image, command, network):
+    def compute_action_start(self, dc_label, compute_name, image, network, command):
         """
-        Start a new compute instance: A docker container
+        Start a new compute instance: A docker container (note: zerorpc does not support keyword arguments)
         :param dc_label: name of the DC
         :param compute_name: compute container name
         :param image: image name
@@ -71,7 +103,9 @@ class MultiDatacenterApi(object):
         try:
             c = self.dcs.get(dc_label).startCompute(
                 compute_name, image=image, command=command, network=network)
-            return str(c.name)
+            #return str(c.name)
+            # return docker inspect dict
+            return c.getStatus()
         except Exception as ex:
             logging.exception("RPC error.")
             return ex.message
@@ -111,6 +145,108 @@ class MultiDatacenterApi(object):
             logging.exception("RPC error.")
             return ex.message
 
+    @zerorpc.stream
+    def compute_profile(self, dc_label, compute_name, kwargs):
+        # note: zerorpc does not support keyword arguments
+
+        ## VIM/dummy gatekeeper's tasks:
+        # start vnf
+        vnf_status = self.compute_action_start( dc_label, compute_name,
+                                  kwargs.get('image'),
+                                  kwargs.get('network'),
+                                  kwargs.get('command'))
+        # start traffic source (with fixed ip addres, no use for now...)
+        psrc_status = self.compute_action_start( dc_label, 'psrc', 'profile_source', [{'id':'output'}], None)
+        # start traffic sink (with fixed ip addres)
+        psink_status = self.compute_action_start(dc_label, 'psink', 'profile_sink', [{'id': 'input'}], None)
+        # link vnf to traffic source
+        DCNetwork = self.dcs.get(dc_label).net
+        DCNetwork.setChain('psrc', compute_name,
+                           vnf_src_interface='output',
+                           vnf_dst_interface=kwargs.get('input'),
+                           cmd='add-flow', weight=None, bidirectional=True)
+        DCNetwork.setChain('psrc', compute_name,
+                           vnf_src_interface='output',
+                           vnf_dst_interface=kwargs.get('input'),
+                           cmd='add-flow', weight=None,
+                           match='dl_type=0x0800,nw_proto=17,udp_dst=5001',
+                           cookie=10)
+        DCNetwork.setChain( compute_name, 'psink',
+                           vnf_src_interface='output',
+                           vnf_dst_interface=kwargs.get('input'),
+                           cmd='add-flow', weight=None, bidirectional=True)
+        DCNetwork.setChain(compute_name, 'psink',
+                       vnf_src_interface='output',
+                       vnf_dst_interface=kwargs.get('input'),
+                       cmd='add-flow', weight=None,
+                       match='dl_type=0x0800,nw_proto=17,udp_dst=5001',
+                       cookie=11)
+
+        ## SSM/SP tasks:
+        # start traffic generation
+        '''
+        for nw in psrc_status.get('network'):
+            if nw.get('intf_name') == 'output':
+                psrc_output_ip = unicode(nw['ip'])
+                break
+        dummy_iperf_server_ip = ipaddress.IPv4Address(psrc_output_ip) + 1
+        '''
+        for nw in psink_status.get('network'):
+            if nw.get('intf_name') == 'input':
+                psink_input_ip = nw['ip']
+                break
+
+
+        # get monitor data and analyze
+        vnf_uuid = vnf_status['id']
+        psrc_mgmt_ip = psrc_status['docker_network']
+
+        # query rate
+
+        #need to wait a bit before containers are fully up?
+        time.sleep(2)
+
+        def generate():
+            for rate in [0, 1, 2, 3]:
+                #logging.info('query:{0}'.format(query_cpu))
+
+                output_line = DCNetwork.monitor_agent.profile(psrc_mgmt_ip, rate, psink_input_ip, vnf_uuid)
+                gevent.sleep(0)
+                yield output_line
+
+            # query loss
+
+
+            # create table
+
+            ## VIM/dummy gatekeeper's tasks:
+            # remove vnfs and chain
+            DCNetwork.setChain('psrc', compute_name,
+                               vnf_src_interface='output',
+                               vnf_dst_interface=kwargs.get('input'),
+                               cmd='del-flows', weight=None, bidirectional=True)
+            DCNetwork.setChain('psrc', compute_name,
+                               vnf_src_interface='output',
+                               vnf_dst_interface=kwargs.get('input'),
+                               cmd='del-flows', weight=None,
+                               match='dl_type=0x0800,nw_proto=17,udp_dst=5001',
+                               cookie=10)
+            DCNetwork.setChain(compute_name, 'psink',
+                               vnf_src_interface='output',
+                               vnf_dst_interface=kwargs.get('input'),
+                               cmd='del-flows', weight=None, bidirectional=True)
+            DCNetwork.setChain(compute_name, 'psink',
+                               vnf_src_interface='output',
+                               vnf_dst_interface=kwargs.get('input'),
+                               cmd='del-flows', weight=None,
+                               match='dl_type=0x0800,nw_proto=17,udp_dst=5001',
+                               cookie=11)
+            self.compute_action_stop(dc_label, compute_name)
+            self.compute_action_stop(dc_label, 'psink')
+            self.compute_action_stop(dc_label, 'psrc')
+
+        return generate()
+
     def datacenter_list(self):
         logging.debug("RPC CALL: datacenter list")
         try:
@@ -126,3 +262,5 @@ class MultiDatacenterApi(object):
         except Exception as ex:
             logging.exception("RPC error.")
             return ex.message
+
+