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).
29 from flask
import Flask
30 from flask_restful
import Api
31 from gevent
.pywsgi
import WSGIServer
33 # need to import total module to set its global variable dcs
35 from compute
import ComputeList
, Compute
, ComputeResources
, DatacenterList
, DatacenterStatus
37 # need to import total module to set its global variable net
39 from network
import NetworkAction
, DrawD3jsgraph
42 from monitor
import MonitorInterfaceAction
, MonitorFlowAction
, MonitorLinkAction
, MonitorSkewAction
, MonitorTerminal
50 class RestApiEndpoint(object):
52 Simple API endpoint that offers a REST
53 interface. This interface will be used by the
54 default command line client.
57 def __init__(self
, listenip
, port
, DCnetwork
=None):
61 # connect this DC network to the rest api endpoint (needed for the
62 # networking and monitoring api)
63 self
.connectDCNetwork(DCnetwork
)
66 # find directory of dashboard files
67 dashboard_file
= pkg_resources
.resource_filename(
68 'emuvim.dashboard', "index.html")
69 dashboard_dir
= path
.dirname(dashboard_file
)
70 logging
.info("Started emu dashboard: {0}".format(dashboard_dir
))
72 self
.app
= Flask(__name__
, static_folder
=dashboard_dir
,
73 static_url_path
='/dashboard')
74 self
.api
= Api(self
.app
)
78 # compute related actions (start/stop VNFs, get info)
79 self
.api
.add_resource(
80 Compute
, "/restapi/compute/<dc_label>/<compute_name>")
81 self
.api
.add_resource(ComputeList
,
83 "/restapi/compute/<dc_label>")
84 self
.api
.add_resource(
85 ComputeResources
, "/restapi/compute/resources/<dc_label>/<compute_name>")
87 self
.api
.add_resource(
88 DatacenterStatus
, "/restapi/datacenter/<dc_label>")
89 self
.api
.add_resource(DatacenterList
, "/restapi/datacenter")
91 # network related actions (setup chaining between VNFs)
92 self
.api
.add_resource(NetworkAction
,
94 self
.api
.add_resource(DrawD3jsgraph
,
95 "/restapi/network/d3jsgraph")
97 # monitoring related actions
98 # export a network interface traffic rate counter
99 self
.api
.add_resource(MonitorInterfaceAction
,
100 "/restapi/monitor/interface")
101 # export flow traffic counter, of a manually pre-installed flow entry,
102 # specified by its cookie
103 self
.api
.add_resource(MonitorFlowAction
,
104 "/restapi/monitor/flow")
105 # install monitoring of a specific flow on a pre-existing link in the service.
106 # the traffic counters of the newly installed monitor flow are exported
107 self
.api
.add_resource(MonitorLinkAction
,
108 "/restapi/monitor/link")
109 # install skewness monitor of resource usage disribution
110 # the skewness metric is exported
111 self
.api
.add_resource(MonitorSkewAction
,
112 "/restapi/monitor/skewness")
113 # start a terminal window for the specified vnfs
114 self
.api
.add_resource(MonitorTerminal
,
115 "/restapi/monitor/term")
117 logging
.debug("Created API endpoint %s(%s:%d)" %
118 (self
.__class
__.__name
__, self
.ip
, self
.port
))
120 def connectDatacenter(self
, dc
):
121 compute
.dcs
[dc
.label
] = dc
123 "Connected DC(%s) to API endpoint %s(%s:%d)" % (dc
.label
, self
.__class
__.__name
__, self
.ip
, self
.port
))
125 def connectDCNetwork(self
, DCnetwork
):
126 network
.net
= DCnetwork
127 monitor
.net
= DCnetwork
129 logging
.info("Connected DCNetwork to API endpoint %s(%s:%d)" % (
130 self
.__class
__.__name
__, self
.ip
, self
.port
))
133 self
.thread
= threading
.Thread(target
=self
._start
_flask
, args
=())
134 self
.thread
.daemon
= True
136 logging
.info("Started API endpoint @ http://%s:%d" %
137 (self
.ip
, self
.port
))
141 self
.http_server
.close()
143 def _start_flask(self
):
144 # self.app.run(self.ip, self.port, debug=False, use_reloader=False)
145 # this should be a more production-fit http-server
146 # self.app.logger.setLevel(logging.ERROR)
147 self
.http_server
= WSGIServer((self
.ip
, self
.port
),
149 # This disables HTTP request logs to not
150 # mess up the CLI when e.g. the
151 # auto-updated dashboard is used
152 log
=open("/dev/null", "w")
154 self
.http_server
.serve_forever()