Merge pull request #242 from mpeuster/master
authorpeusterm <manuel.peuster@uni-paderborn.de>
Wed, 30 Aug 2017 18:46:26 +0000 (20:46 +0200)
committerpeusterm <manuel.peuster@uni-paderborn.de>
Wed, 30 Aug 2017 18:46:26 +0000 (20:46 +0200)
OpenStack-fake API improvements for OSM DevOps integration and containerized deployment

ansible/install.yml
src/emuvim/api/openstack/helper.py [new file with mode: 0644]
src/emuvim/api/openstack/openstack_dummies/__init__.py
src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py
src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py
src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py
src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py
src/emuvim/api/openstack/openstack_dummies/neutron_sfc_dummy_api.py
src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py
src/emuvim/examples/openstack_single_dc.py
utils/docker/Dockerfile

index d6a6297..b972b4e 100755 (executable)
@@ -72,5 +72,8 @@
    - name: install ipaddress
      pip: name=ipaddress state=latest
 
+   - name: install urllib
+     pip: name=urllib state=latest
+
 
 
diff --git a/src/emuvim/api/openstack/helper.py b/src/emuvim/api/openstack/helper.py
new file mode 100644 (file)
index 0000000..dca3ba5
--- /dev/null
@@ -0,0 +1,11 @@
+from urlparse import urlparse
+import logging
+
+LOG = logging.getLogger("api.openstack.helper")
+
+def get_host(r):
+    try:
+        return urlparse(r.base_url).hostname
+    except:
+        LOG.error("Could not get host part of request URL.")
+    return "0.0.0.0"
index 451ce11..5874ebe 100755 (executable)
@@ -3,4 +3,3 @@ from heat_dummy_api import HeatDummyApi
 from keystone_dummy_api import KeystoneDummyApi
 from neutron_dummy_api import NeutronDummyApi
 from nova_dummy_api import NovaDummyApi
-
index a61c710..8113397 100755 (executable)
@@ -1,6 +1,7 @@
 from flask_restful import Resource
 from flask import Response, request
 from emuvim.api.openstack.openstack_dummies.base_openstack_dummy import BaseOpenstackDummy
+from emuvim.api.openstack.helper import get_host
 import logging
 import json
 
@@ -182,7 +183,7 @@ class GlanceListImagesApi(Resource):
         resp['image'] = f
         # build actual response with headers and everything
         r = Response(json.dumps(resp), status=201, mimetype="application/json")
-        r.headers.add("Location", "http://%s:%d/v1/images/%s" % (self.api.ip,
+        r.headers.add("Location", "http://%s:%d/v1/images/%s" % (get_host(request),
                                                                  self.api.port,
                                                                  img_id))
         return r
index 8262adb..a5b6402 100755 (executable)
@@ -2,6 +2,7 @@ from flask import request, Response
 from flask_restful import Resource
 from emuvim.api.openstack.resources import Stack
 from emuvim.api.openstack.openstack_dummies.base_openstack_dummy import BaseOpenstackDummy
+from emuvim.api.openstack.helper import get_host
 from datetime import datetime
 from emuvim.api.openstack.heat_parser import HeatParser
 import logging
@@ -75,7 +76,7 @@ class HeatListAPIVersions(Resource):
             "id": "v1.0",
             "links": [
                 {
-                    "href": "http://%s:%d/v2.0" % (self.api.ip, self.api.port),
+                    "href": "http://%s:%d/v2.0" % (get_host(request), self.api.port),
                     "rel": "self"
                 }
             ]
@@ -123,7 +124,7 @@ class HeatCreateStack(Resource):
                                      "links": [
                                          {
                                              "href": "http://%s:%s/v1/%s/stacks/%s"
-                                                     % (self.api.ip, self.api.port, tenant_id, stack.id),
+                                                     % (get_host(request), self.api.port, tenant_id, stack.id),
                                              "rel": "self"
                                          }]}}
 
@@ -204,7 +205,7 @@ class HeatShowStack(Resource):
                     "links": [
                         {
                             "href": "http://%s:%s/v1/%s/stacks/%s"
-                                    % (self.api.ip, self.api.port, tenant_id, stack.id),
+                                    % (get_host(request), self.api.port, tenant_id, stack.id),
                             "rel": "self"
                         }
                     ],
index 7abf9c4..ea7ae45 100755 (executable)
@@ -1,6 +1,7 @@
 from flask_restful import Resource
 from flask import request, Response
 from emuvim.api.openstack.openstack_dummies.base_openstack_dummy import BaseOpenstackDummy
+from emuvim.api.openstack.helper import get_host
 import logging
 import json
 
@@ -15,8 +16,8 @@ class KeystoneDummyApi(BaseOpenstackDummy):
         self.api.add_resource(Shutdown, "/shutdown")
         self.api.add_resource(KeystoneShowAPIv2, "/v2.0", resource_class_kwargs={'api': self})
         self.api.add_resource(KeystoneGetToken, "/v2.0/tokens", resource_class_kwargs={'api': self})
-        self.api.add_resource(KeystoneShowAPIv3, "/v3", resource_class_kwargs={'api': self})
-        self.api.add_resource(KeystoneGetTokenv3, "/v3/auth/tokens", resource_class_kwargs={'api': self})
+        self.api.add_resource(KeystoneShowAPIv3, "/v3.0", resource_class_kwargs={'api': self})
+        self.api.add_resource(KeystoneGetTokenv3, "/v3.0/auth/tokens", resource_class_kwargs={'api': self})
 
     def _start_flask(self):
         LOG.info("Starting %s endpoint @ http://%s:%d" % (__name__, self.ip, self.port))
@@ -62,7 +63,7 @@ class KeystoneListVersions(Resource):
             "id": "v2.0",
             "links": [
                 {
-                    "href": "http://%s:%d/v2.0" % (self.api.ip, self.api.port),
+                    "href": "http://%s:%d/v2.0" % (get_host(request), self.api.port),
                     "rel": "self"
                 }
             ],
@@ -113,32 +114,12 @@ class KeystoneShowAPIv2(Resource):
             "id": "v2.0",
             "links": [
                 {
-                    "href": "http://%s:%d/v2.0" % (self.api.ip, self.api.port),
-                    "rel": "self"
-                },
-                {
-                    "href": "http://%s:%d/v2.0/tokens" % (self.api.ip, self.api.port),
-                    "rel": "self"
-                },
-                {
-                    "href": "http://%s:%d/v2.0/networks" % (self.api.ip, neutron_port),
-                    "rel": "self"
-                },
-                {
-                    "href": "http://%s:%d/v2.0/subnets" % (self.api.ip, neutron_port),
-                    "rel": "self"
-                },
-                {
-                    "href": "http://%s:%d/v2.0/ports" % (self.api.ip, neutron_port),
-                    "rel": "self"
-                },
-                {
-                    "href": "http://%s:%d/v1/<tenant_id>/stacks" % (self.api.ip, heat_port),
+                    "href": "http://%s:%d/v2.0" % (get_host(request), self.api.port),
                     "rel": "self"
                 }
             ]
         }
-
+        LOG.debug(json.dumps(resp))
         return Response(json.dumps(resp), status=200, mimetype='application/json')
 
 
@@ -169,33 +150,13 @@ class KeystoneShowAPIv3(Resource):
             "media-types": [
                 {
                     "base": "application/json",
-                    "type": "application/vnd.openstack.identity-v2.0+json"
+                    "type": "application/vnd.openstack.identity-v3.0+json"
                 }
             ],
-            "id": "v2.0",
+            "id": "v3.0",
             "links": [
                 {
-                    "href": "http://%s:%d/v2.0" % (self.api.ip, self.api.port),
-                    "rel": "self"
-                },
-                {
-                    "href": "http://%s:%d/v2.0/tokens" % (self.api.ip, self.api.port),
-                    "rel": "self"
-                },
-                {
-                    "href": "http://%s:%d/v2.0/networks" % (self.api.ip, neutron_port),
-                    "rel": "self"
-                },
-                {
-                    "href": "http://%s:%d/v2.0/subnets" % (self.api.ip, neutron_port),
-                    "rel": "self"
-                },
-                {
-                    "href": "http://%s:%d/v2.0/ports" % (self.api.ip, neutron_port),
-                    "rel": "self"
-                },
-                {
-                    "href": "http://%s:%d/v1/<tenant_id>/stacks" % (self.api.ip, heat_port),
+                    "href": "http://%s:%d/v3.0" % (get_host(request), self.api.port),
                     "rel": "self"
                 }
             ]
@@ -260,11 +221,11 @@ class KeystoneGetToken(Resource):
             ret['access']['serviceCatalog'] = [{
                 "endpoints": [
                     {
-                        "adminURL": "http://%s:%s/v2.1/%s" % (self.api.ip, self.api.port + 3774, user['id']),
+                        "adminURL": "http://%s:%s/v2.1/%s" % (get_host(request), self.api.port + 3774, user['id']),
                         "region": "RegionOne",
-                        "internalURL": "http://%s:%s/v2.1/%s" % (self.api.ip, self.api.port + 3774, user['id']),
+                        "internalURL": "http://%s:%s/v2.1/%s" % (get_host(request), self.api.port + 3774, user['id']),
                         "id": "2dad48f09e2a447a9bf852bcd93548ef",
-                        "publicURL": "http://%s:%s/v2.1/%s" % (self.api.ip, self.api.port + 3774, user['id'])
+                        "publicURL": "http://%s:%s/v2.1/%s" % (get_host(request), self.api.port + 3774, user['id'])
                     }
                 ],
                 "endpoints_links": [],
@@ -274,11 +235,11 @@ class KeystoneGetToken(Resource):
                 {
                     "endpoints": [
                         {
-                            "adminURL": "http://%s:%s/v2.0" % (self.api.ip, self.api.port),
+                            "adminURL": "http://%s:%s/v2.0" % (get_host(request), self.api.port),
                             "region": "RegionOne",
-                            "internalURL": "http://%s:%s/v2.0" % (self.api.ip, self.api.port),
+                            "internalURL": "http://%s:%s/v2.0" % (get_host(request), self.api.port),
                             "id": "2dad48f09e2a447a9bf852bcd93543fc",
-                            "publicURL": "http://%s:%s/v2" % (self.api.ip, self.api.port)
+                            "publicURL": "http://%s:%s/v2" % (get_host(request), self.api.port)
                         }
                     ],
                     "endpoints_links": [],
@@ -288,11 +249,11 @@ class KeystoneGetToken(Resource):
                 {
                     "endpoints": [
                         {
-                            "adminURL": "http://%s:%s" % (self.api.ip, self.api.port + 4696),
+                            "adminURL": "http://%s:%s" % (get_host(request), self.api.port + 4696),
                             "region": "RegionOne",
-                            "internalURL": "http://%s:%s" % (self.api.ip, self.api.port + 4696),
+                            "internalURL": "http://%s:%s" % (get_host(request), self.api.port + 4696),
                             "id": "2dad48f09e2a447a9bf852bcd93548cf",
-                            "publicURL": "http://%s:%s" % (self.api.ip, self.api.port + 4696)
+                            "publicURL": "http://%s:%s" % (get_host(request), self.api.port + 4696)
                         }
                     ],
                     "endpoints_links": [],
@@ -302,11 +263,11 @@ class KeystoneGetToken(Resource):
                 {
                     "endpoints": [
                         {
-                            "adminURL": "http://%s:%s" % (self.api.ip, self.api.port + 4242),
+                            "adminURL": "http://%s:%s" % (get_host(request), self.api.port + 4242),
                             "region": "RegionOne",
-                            "internalURL": "http://%s:%s" % (self.api.ip, self.api.port + 4242),
+                            "internalURL": "http://%s:%s" % (get_host(request), self.api.port + 4242),
                             "id": "2dad48f09e2a447a9bf852bcd93548cf",
-                            "publicURL": "http://%s:%s" % (self.api.ip, self.api.port + 4242)
+                            "publicURL": "http://%s:%s" % (get_host(request), self.api.port + 4242)
                         }
                     ],
                     "endpoints_links": [],
@@ -316,11 +277,11 @@ class KeystoneGetToken(Resource):
                 {
                     "endpoints": [
                         {
-                            "adminURL": "http://%s:%s/v1/%s" % (self.api.ip, self.api.port + 3004, user['id']),
+                            "adminURL": "http://%s:%s/v1/%s" % (get_host(request), self.api.port + 3004, user['id']),
                             "region": "RegionOne",
-                            "internalURL": "http://%s:%s/v1/%s" % (self.api.ip, self.api.port + 3004, user['id']),
+                            "internalURL": "http://%s:%s/v1/%s" % (get_host(request), self.api.port + 3004, user['id']),
                             "id": "2dad48f09e2a447a9bf852bcd93548bf",
-                            "publicURL": "http://%s:%s/v1/%s" % (self.api.ip, self.api.port + 3004, user['id'])
+                            "publicURL": "http://%s:%s/v1/%s" % (get_host(request), self.api.port + 3004, user['id'])
                         }
                     ],
                     "endpoints_links": [],
@@ -406,7 +367,7 @@ class KeystoneGetTokenv3(Resource):
             token['catalog'] = [{
                 "endpoints": [
                     {
-                        "url": "http://%s:%s/v2.1/%s" % (self.api.ip, self.api.port + 3774, user['id']),
+                        "url": "http://%s:%s/v2.1/%s" % (get_host(request), self.api.port + 3774, user['id']),
                         "region": "RegionOne",
                         "interface": "public",
                         "id": "2dad48f09e2a447a9bf852bcd93548ef"
@@ -419,7 +380,7 @@ class KeystoneGetTokenv3(Resource):
                 {
                     "endpoints": [
                         {
-                            "url": "http://%s:%s/v2.0" % (self.api.ip, self.api.port),
+                            "url": "http://%s:%s/v2.0" % (get_host(request), self.api.port),
                             "region": "RegionOne",
                             "interface": "public",
                             "id": "2dad48f09e2a447a9bf852bcd93543fc"
@@ -432,7 +393,7 @@ class KeystoneGetTokenv3(Resource):
                 {
                     "endpoints": [
                         {
-                            "url": "http://%s:%s" % (self.api.ip, self.api.port + 4696),
+                            "url": "http://%s:%s" % (get_host(request), self.api.port + 4696),
                             "region": "RegionOne",
                             "interface": "public",
                             "id": "2dad48f09e2a447a9bf852bcd93548cf"
@@ -445,7 +406,7 @@ class KeystoneGetTokenv3(Resource):
                 {
                     "endpoints": [
                         {
-                            "url": "http://%s:%s" % (self.api.ip, self.api.port + 4242),
+                            "url": "http://%s:%s" % (get_host(request), self.api.port + 4242),
                             "region": "RegionOne",
                             "interface": "public",
                             "id": "2dad48f09e2a447a9bf852bcd93548cf"
@@ -458,7 +419,7 @@ class KeystoneGetTokenv3(Resource):
                 {
                     "endpoints": [
                         {
-                            "url": "http://%s:%s/v1/%s" % (self.api.ip, self.api.port + 3004, user['id']),
+                            "url": "http://%s:%s/v1/%s" % (get_host(request), self.api.port + 3004, user['id']),
                             "region": "RegionOne",
                             "interface": "public",
                             "id": "2dad48f09e2a447a9bf852bcd93548bf"
@@ -469,7 +430,6 @@ class KeystoneGetTokenv3(Resource):
                     "name": "heat"
                 }
             ]
-            
             return Response(json.dumps(ret), status=201, mimetype='application/json')
 
         except Exception as ex:
index 9835bcd..0acc8ff 100755 (executable)
@@ -1,6 +1,7 @@
 from flask_restful import Resource
 from flask import request, Response
 from emuvim.api.openstack.openstack_dummies.base_openstack_dummy import BaseOpenstackDummy
+from emuvim.api.openstack.helper import get_host
 from datetime import datetime
 import neutron_sfc_dummy_api as SFC
 import logging
index 93121c3..a778913 100644 (file)
@@ -5,6 +5,7 @@ import json
 import uuid
 
 from emuvim.api.openstack.resources.port_chain import PortChain
+from emuvim.api.openstack.helper import get_host
 
 
 class SFC(Resource):
index 514755e..2b356e1 100755 (executable)
@@ -1,6 +1,7 @@
 from flask_restful import Resource
 from flask import Response, request
 from emuvim.api.openstack.openstack_dummies.base_openstack_dummy import BaseOpenstackDummy
+from emuvim.api.openstack.helper import get_host
 import logging
 import json
 import uuid
@@ -103,7 +104,7 @@ class NovaVersionsList(Resource):
                         }
                     ]
                 }
-            """ % (self.api.ip, self.api.port)
+            """ % (get_host(request), self.api.port)
 
             response = Response(resp, status=200, mimetype="application/json")
             response.headers['Access-Control-Allow-Origin'] = '*'
@@ -157,7 +158,7 @@ class NovaVersionShow(Resource):
                     "updated": "2013-07-23T11:33:21Z"
                 }
             }
-            """ % (self.api.ip, self.api.port)
+            """ % (get_host(request), self.api.port)
 
             response = Response(resp, status=200, mimetype="application/json")
             response.headers['Access-Control-Allow-Origin'] = '*'
@@ -188,7 +189,7 @@ class NovaListServersApi(Resource):
             resp['servers'] = list()
             for server in self.api.compute.computeUnits.values():
                 s = server.create_server_dict(self.api.compute)
-                s['links'] = [{'href': "http://%s:%d/v2.1/%s/servers/%s" % (self.api.ip,
+                s['links'] = [{'href': "http://%s:%d/v2.1/%s/servers/%s" % (get_host(request),
                                                                             self.api.port,
                                                                             id,
                                                                             server.id)}]
@@ -276,7 +277,7 @@ class NovaListServersAndPortsApi(Resource):
             resp['servers'] = list()
             for server in self.api.compute.computeUnits.values():
                 s = server.create_server_dict(self.api.compute)
-                s['links'] = [{'href': "http://%s:%d/v2.1/%s/servers/%s" % (self.api.ip,
+                s['links'] = [{'href': "http://%s:%d/v2.1/%s/servers/%s" % (get_host(request),
                                                                             self.api.port,
                                                                             id,
                                                                             server.id)}]
@@ -322,7 +323,7 @@ class NovaListServersDetailed(Resource):
             resp = {"servers": list()}
             for server in self.api.compute.computeUnits.values():
                 s = server.create_server_dict(self.api.compute)
-                s['links'] = [{'href': "http://%s:%d/v2.1/%s/servers/%s" % (self.api.ip,
+                s['links'] = [{'href': "http://%s:%d/v2.1/%s/servers/%s" % (get_host(request),
                                                                             self.api.port,
                                                                             id,
                                                                             server.id)}]
@@ -331,7 +332,7 @@ class NovaListServersDetailed(Resource):
                     "id": flavor.id,
                     "links": [
                         {
-                            "href": "http://%s:%d/v2.1/%s/flavors/%s" % (self.api.ip,
+                            "href": "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request),
                                                                          self.api.port,
                                                                          id,
                                                                          flavor.id),
@@ -344,7 +345,7 @@ class NovaListServersDetailed(Resource):
                     "id": image.id,
                     "links": [
                         {
-                            "href": "http://%s:%d/v2.1/%s/images/%s" % (self.api.ip,
+                            "href": "http://%s:%d/v2.1/%s/images/%s" % (get_host(request),
                                                                         self.api.port,
                                                                         id,
                                                                         image.id),
@@ -385,7 +386,7 @@ class NovaListFlavors(Resource):
                 f = flavor.__dict__.copy()
                 f['id'] = flavor.id
                 f['name'] = flavor.name
-                f['links'] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (self.api.ip,
+                f['links'] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request),
                                                                             self.api.port,
                                                                             id,
                                                                             flavor.id)}]
@@ -411,7 +412,7 @@ class NovaListFlavors(Resource):
             data.get("disk"), "GB")
         # create response based on incoming data
         data["id"] = f.id
-        data["links"] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (self.api.ip,
+        data["links"] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request),
                                                                        self.api.port,
                                                                        id,
                                                                        f.id)}]
@@ -441,7 +442,7 @@ class NovaListFlavorsDetails(Resource):
                 # but use a copy so we don't modifiy the original
                 f = flavor.__dict__.copy()
                 # add additional expected stuff stay openstack compatible
-                f['links'] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (self.api.ip,
+                f['links'] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request),
                                                                             self.api.port,
                                                                             id,
                                                                             flavor.id)}]
@@ -475,7 +476,7 @@ class NovaListFlavorsDetails(Resource):
             data.get("disk"), "GB")
         # create response based on incoming data
         data["id"] = f.id
-        data["links"] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (self.api.ip,
+        data["links"] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request),
                                                                        self.api.port,
                                                                        id,
                                                                        f.id)}]
@@ -510,7 +511,7 @@ class NovaListFlavorById(Resource):
                         break
             resp['flavor']['id'] = flavor.id
             resp['flavor']['name'] = flavor.name
-            resp['flavor']['links'] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (self.api.ip,
+            resp['flavor']['links'] = [{'href': "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request),
                                                                                      self.api.port,
                                                                                      id,
                                                                                      flavor.id)}]
@@ -552,7 +553,7 @@ class NovaListImages(Resource):
                 f = dict()
                 f['id'] = image.id
                 f['name'] = str(image.name).replace(":latest", "")
-                f['links'] = [{'href': "http://%s:%d/v2.1/%s/images/%s" % (self.api.ip,
+                f['links'] = [{'href': "http://%s:%d/v2.1/%s/images/%s" % (get_host(request),
                                                                            self.api.port,
                                                                            id,
                                                                            image.id)}]
@@ -589,7 +590,7 @@ class NovaListImagesDetails(Resource):
                 f = image.__dict__.copy()
                 # add additional expected stuff stay openstack compatible
                 f['name'] = str(image.name).replace(":latest", "")
-                f['links'] = [{'href': "http://%s:%d/v2.1/%s/images/%s" % (self.api.ip,
+                f['links'] = [{'href': "http://%s:%d/v2.1/%s/images/%s" % (get_host(request),
                                                                            self.api.port,
                                                                            id,
                                                                            image.id)}]
@@ -674,7 +675,7 @@ class NovaShowServerDetails(Resource):
             if server is None:
                 return Response("Server with id or name %s does not exists." % serverid, status=404)
             s = server.create_server_dict()
-            s['links'] = [{'href': "http://%s:%d/v2.1/%s/servers/%s" % (self.api.ip,
+            s['links'] = [{'href': "http://%s:%d/v2.1/%s/servers/%s" % (get_host(request),
                                                                         self.api.port,
                                                                         id,
                                                                         server.id)}]
@@ -684,7 +685,7 @@ class NovaShowServerDetails(Resource):
                 "id": flavor.id,
                 "links": [
                     {
-                        "href": "http://%s:%d/v2.1/%s/flavors/%s" % (self.api.ip,
+                        "href": "http://%s:%d/v2.1/%s/flavors/%s" % (get_host(request),
                                                                      self.api.port,
                                                                      id,
                                                                      flavor.id),
@@ -697,7 +698,7 @@ class NovaShowServerDetails(Resource):
                 "id": image.id,
                 "links": [
                     {
-                        "href": "http://%s:%d/v2.1/%s/images/%s" % (self.api.ip,
+                        "href": "http://%s:%d/v2.1/%s/images/%s" % (get_host(request),
                                                                     self.api.port,
                                                                     id,
                                                                     image.id),
index b12079d..87e59c8 100644 (file)
@@ -28,21 +28,37 @@ partner consortium (www.sonata-nfv.eu).
 import logging
 from mininet.log import setLogLevel
 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)
 
 
 def create_topology():
     net = DCNetwork(monitor=False, enable_learning=False)
 
     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()
 
     net.start()
     net.CLI()
@@ -51,7 +67,6 @@ def create_topology():
 
 
 def main():
-    setLogLevel('info')  # set Mininet loglevel
     create_topology()
 
 
index 214510e..e1ba00d 100755 (executable)
@@ -52,7 +52,7 @@ RUN make develop
 # install son-emu
 RUN echo 'install son-emu'
 RUN apt-get install -y  python-dev python-zmq libzmq-dev libffi-dev libssl-dev
-RUN pip install -U zerorpc tabulate argparse networkx six ryu oslo.config pytest Flask flask_restful requests prometheus_client pyaml
+RUN pip install -U zerorpc tabulate argparse networkx six ryu oslo.config pytest Flask flask_restful requests urllib prometheus_client pyaml
 WORKDIR /
 #avoid pulling not the latest git, copy the current dir, to run this from Jenkins
 #RUN git clone https://github.com/sonata-nfv/son-emu.git
@@ -65,5 +65,5 @@ RUN echo 'Done'
 
 ENTRYPOINT ["/son-emu/utils/docker/entrypoint.sh"]
 
-# dummy GK, cAdvisor, Prometheus Push Gateway, son-emu REST API
-EXPOSE 5000 8081 9091 5001
+# dummy GK, cAdvisor, Prometheus Push Gateway, son-emu REST API, OpenStack-fake APIs
+EXPOSE 5000 8081 9091 5001 4000 10243 9005 6001 9775 10697