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