1 # Copyright (c) 2015 SONATA-NFV and Paderborn University
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 # Neither the name of the SONATA-NFV, Paderborn University
17 # nor the names of its contributors may be used to endorse or promote
18 # products derived from this software without specific prior written
21 # This work has been performed in the framework of the SONATA project,
22 # funded by the European Commission under Grant number 671517 through
23 # the Horizon 2020 and 5G-PPP programmes. The authors would like to
24 # acknowledge the contributions of their colleagues of the SONATA
25 # partner consortium (www.sonata-nfv.eu).
26 from manage
import OpenstackManage
28 from openstack_dummies
.glance_dummy_api
import GlanceDummyApi
29 from openstack_dummies
.heat_dummy_api
import HeatDummyApi
30 from openstack_dummies
.keystone_dummy_api
import KeystoneDummyApi
31 from openstack_dummies
.neutron_dummy_api
import NeutronDummyApi
32 from openstack_dummies
.nova_dummy_api
import NovaDummyApi
41 class OpenstackApiEndpoint():
43 Base class for an OpenStack datacenter.
44 It holds information about all connected endpoints.
48 def __init__(self
, listenip
, port
):
51 self
.compute
= compute
.OpenstackCompute()
52 self
.openstack_endpoints
= dict()
53 self
.openstack_endpoints
['keystone'] = KeystoneDummyApi(
55 self
.openstack_endpoints
['neutron'] = NeutronDummyApi(
56 self
.ip
, self
.port
+ 4696, self
.compute
)
57 self
.openstack_endpoints
['nova'] = NovaDummyApi(
58 self
.ip
, self
.port
+ 3774, self
.compute
)
59 self
.openstack_endpoints
['heat'] = HeatDummyApi(
60 self
.ip
, self
.port
+ 3004, self
.compute
)
61 self
.openstack_endpoints
['glance'] = GlanceDummyApi(
62 self
.ip
, self
.port
+ 4242, self
.compute
)
64 self
.rest_threads
= list()
65 self
.manage
= OpenstackManage()
66 self
.manage
.add_endpoint(self
)
67 OpenstackApiEndpoint
.dc_apis
.append(self
)
69 def connect_datacenter(self
, dc
):
71 Connect a datacenter to this endpoint.
72 An endpoint can only be connected to a single datacenter.
74 :param dc: Datacenter object
78 for ep
in self
.openstack_endpoints
.values():
79 ep
.manage
= self
.manage
80 logging
.info("Connected DC(%s) to API endpoint %s(%s:%d)" %
81 (dc
.label
, self
.__class
__.__name
__, self
.ip
, self
.port
))
83 def connect_dc_network(self
, dc_network
):
85 Connect the datacenter network to the endpoint.
87 :param dc_network: Datacenter network reference
88 :type dc_network: :class:`.net`
90 self
.manage
.net
= dc_network
91 self
.compute
.nets
[self
.manage
.floating_network
.id] = self
.manage
.floating_network
92 logging
.info("Connected DCNetwork to API endpoint %s(%s:%d)" % (
93 self
.__class
__.__name
__, self
.ip
, self
.port
))
95 def start(self
, wait_for_port
=False):
97 Start all connected OpenStack endpoints that are connected to this API endpoint.
99 for c
in self
.openstack_endpoints
.values():
100 c
.compute
= self
.compute
101 c
.manage
= self
.manage
102 c
.server_thread
= threading
.Thread(target
=c
._start
_flask
, args
=())
103 c
.server_thread
.daemon
= True
104 c
.server_thread
.name
= c
.__class
__.__name
__
105 c
.server_thread
.start()
107 self
._wait
_for
_port
(c
.ip
, c
.port
)
111 Stop all connected OpenStack endpoints that are connected to this API endpoint.
113 for c
in self
.openstack_endpoints
.values():
115 # for c in self.openstack_endpoints.values():
116 # if c.server_thread:
117 # print("Waiting for WSGIServers to be stopped ...")
118 # c.server_thread.join()
120 def _wait_for_port(self
, ip
, port
):
121 for i
in range(0, 10):
122 s
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
123 s
.settimeout(1) # 1 Second Timeout
124 r
= s
.connect_ex((ip
, port
))
126 break # port is open proceed
129 "Waiting for {}:{} ... ({}/10)".format(ip
, port
, i
+ 1))