From b668d69e8e81bf4e6378daa6fb87e1e9f493aaf7 Mon Sep 17 00:00:00 2001 From: peusterm Date: Wed, 30 Aug 2017 09:22:15 +0200 Subject: [PATCH] let OpenStack APIs work inside a container --- ansible/install.yml | 3 + .../openstack/openstack_dummies/__init__.py | 1 - .../openstack_dummies/glance_dummy_api.py | 3 +- .../openstack_dummies/heat_dummy_api.py | 7 +- .../openstack_dummies/keystone_dummy_api.py | 67 ++++++++++--------- .../openstack_dummies/neutron_dummy_api.py | 1 + .../neutron_sfc_dummy_api.py | 1 + .../openstack_dummies/nova_dummy_api.py | 35 +++++----- src/emuvim/examples/openstack_single_dc.py | 12 +++- utils/docker/Dockerfile | 4 +- 10 files changed, 76 insertions(+), 58 deletions(-) diff --git a/ansible/install.yml b/ansible/install.yml index d6a6297..b972b4e 100755 --- a/ansible/install.yml +++ b/ansible/install.yml @@ -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/openstack_dummies/__init__.py b/src/emuvim/api/openstack/openstack_dummies/__init__.py index 451ce11..5874ebe 100755 --- a/src/emuvim/api/openstack/openstack_dummies/__init__.py +++ b/src/emuvim/api/openstack/openstack_dummies/__init__.py @@ -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 - diff --git a/src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py index a61c710..8113397 100755 --- a/src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py @@ -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 diff --git a/src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py index 8262adb..a5b6402 100755 --- a/src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py @@ -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" } ], diff --git a/src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py index 7abf9c4..e39cfeb 100755 --- a/src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py @@ -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 @@ -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,27 +114,27 @@ class KeystoneShowAPIv2(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" }, { - "href": "http://%s:%d/v2.0/tokens" % (self.api.ip, self.api.port), + "href": "http://%s:%d/v2.0/tokens" % (get_host(request), self.api.port), "rel": "self" }, { - "href": "http://%s:%d/v2.0/networks" % (self.api.ip, neutron_port), + "href": "http://%s:%d/v2.0/networks" % (get_host(request), neutron_port), "rel": "self" }, { - "href": "http://%s:%d/v2.0/subnets" % (self.api.ip, neutron_port), + "href": "http://%s:%d/v2.0/subnets" % (get_host(request), neutron_port), "rel": "self" }, { - "href": "http://%s:%d/v2.0/ports" % (self.api.ip, neutron_port), + "href": "http://%s:%d/v2.0/ports" % (get_host(request), neutron_port), "rel": "self" }, { - "href": "http://%s:%d/v1//stacks" % (self.api.ip, heat_port), + "href": "http://%s:%d/v1//stacks" % (get_host(request), heat_port), "rel": "self" } ] @@ -175,27 +176,27 @@ class KeystoneShowAPIv3(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" }, { - "href": "http://%s:%d/v2.0/tokens" % (self.api.ip, self.api.port), + "href": "http://%s:%d/v2.0/tokens" % (get_host(request), self.api.port), "rel": "self" }, { - "href": "http://%s:%d/v2.0/networks" % (self.api.ip, neutron_port), + "href": "http://%s:%d/v2.0/networks" % (get_host(request), neutron_port), "rel": "self" }, { - "href": "http://%s:%d/v2.0/subnets" % (self.api.ip, neutron_port), + "href": "http://%s:%d/v2.0/subnets" % (get_host(request), neutron_port), "rel": "self" }, { - "href": "http://%s:%d/v2.0/ports" % (self.api.ip, neutron_port), + "href": "http://%s:%d/v2.0/ports" % (get_host(request), neutron_port), "rel": "self" }, { - "href": "http://%s:%d/v1//stacks" % (self.api.ip, heat_port), + "href": "http://%s:%d/v1//stacks" % (get_host(request), heat_port), "rel": "self" } ] @@ -260,11 +261,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 +275,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 +289,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 +303,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 +317,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 +407,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 +420,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 +433,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 +446,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 +459,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" diff --git a/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py index 9835bcd..0acc8ff 100755 --- a/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py @@ -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 diff --git a/src/emuvim/api/openstack/openstack_dummies/neutron_sfc_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/neutron_sfc_dummy_api.py index 93121c3..a778913 100644 --- a/src/emuvim/api/openstack/openstack_dummies/neutron_sfc_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/neutron_sfc_dummy_api.py @@ -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): diff --git a/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py index 514755e..2b356e1 100755 --- a/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py @@ -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), diff --git a/src/emuvim/examples/openstack_single_dc.py b/src/emuvim/examples/openstack_single_dc.py index 25ef3e3..87e59c8 100644 --- a/src/emuvim/examples/openstack_single_dc.py +++ b/src/emuvim/examples/openstack_single_dc.py @@ -32,6 +32,17 @@ 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(): @@ -56,7 +67,6 @@ def create_topology(): def main(): - setLogLevel('info') # set Mininet loglevel create_topology() diff --git a/utils/docker/Dockerfile b/utils/docker/Dockerfile index 6d3a074..e1ba00d 100755 --- a/utils/docker/Dockerfile +++ b/utils/docker/Dockerfile @@ -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 @@ -66,4 +66,4 @@ RUN echo 'Done' ENTRYPOINT ["/son-emu/utils/docker/entrypoint.sh"] # dummy GK, cAdvisor, Prometheus Push Gateway, son-emu REST API, OpenStack-fake APIs -EXPOSE 5000 8081 9091 5001 6001 6002 6003 6004 +EXPOSE 5000 8081 9091 5001 4000 10243 9005 6001 9775 10697 -- 2.25.1