1 from flask_restful
import Resource
2 from flask
import Response
, request
3 from emuvim
.api
.openstack
.openstack_dummies
.base_openstack_dummy
import BaseOpenstackDummy
4 import emuvim
.api
.openstack
.docker_util
as DockerUtil
10 class MonitorDummyApi(BaseOpenstackDummy
):
11 def __init__(self
, inc_ip
, inc_port
):
12 super(MonitorDummyApi
, self
).__init
__(inc_ip
, inc_port
)
14 self
.api
.add_resource(MonitorVersionsList
, "/",
15 resource_class_kwargs
={'api': self
})
16 self
.api
.add_resource(MonitorVnf
, "/v1/monitor/<vnf_name>",
17 resource_class_kwargs
={'api': self
})
18 self
.api
.add_resource(MonitorVnfAbs
, "/v1/monitor/abs/<vnf_name>",
19 resource_class_kwargs
={'api': self
})
20 self
.api
.add_resource(MonitorVnfDcStack
, "/v1/monitor/<dc>/<stack>/<vnf_name>",
21 resource_class_kwargs
={'api': self
})
22 self
.api
.add_resource(Shutdown
, "/shutdown")
24 def _start_flask(self
):
25 logging
.info("Starting %s endpoint @ http://%s:%d" % ("MonitorDummyApi", self
.ip
, self
.port
))
26 if self
.app
is not None:
27 self
.app
.run(self
.ip
, self
.port
, debug
=True, use_reloader
=False, threaded
=True)
30 class Shutdown(Resource
):
32 A get request to /shutdown will shut down this endpoint.
36 logging
.debug(("%s is beeing shut down") % (__name__
))
37 func
= request
.environ
.get('werkzeug.server.shutdown')
39 raise RuntimeError('Not running with the Werkzeug Server')
43 class MonitorVersionsList(Resource
):
44 def __init__(self
, api
):
52 :return: Returns the api versions.
53 :rtype: :class:`flask.response`
55 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
57 # at least let it look like an open stack function
60 resp
['versions'] = dict()
64 "href": "http://%s:%d/v1/" % (self
.api
.ip
, self
.api
.port
),
70 "updated": "2013-07-23T11:33:21Z"
73 return Response(json
.dumps(resp
), status
=200, mimetype
="application/json")
75 except Exception as ex
:
76 logging
.exception(u
"%s: Could not show list of versions." % __name__
)
77 return ex
.message
, 500
80 class MonitorVnf(Resource
):
81 def __init__(self
, api
):
84 def get(self
, vnf_name
):
86 Calculates the workload for the specified docker container. Requires at least one second, to calculate
87 the network traffic and cpu usage over time.
89 :param vnf_name: Specifies the docker container via name.
90 :type vnf_name: ``str``
91 :return: Returns a json response with network, cpu and memory usage over time, and specifies the storage
92 access, the number of running processes and the current system time.
93 :rtype: :class:`flask.response`
95 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
96 if len(vnf_name
) < 3 or 'mn.' != vnf_name
[:3]:
97 vnf_name
= 'mn.' + vnf_name
100 from emuvim
.api
.openstack
.openstack_api_endpoint
import OpenstackApiEndpoint
101 for api
in OpenstackApiEndpoint
.dc_apis
:
102 if vnf_name
[3:] in api
.compute
.dc
.net
:
107 return Response(u
"MonitorAPI: VNF %s does not exist.\n" % (vnf_name
[3:]),
109 mimetype
="application/json")
111 docker_id
= DockerUtil
.docker_container_id(vnf_name
)
113 out_dict
.update(DockerUtil
.monitoring_over_time(docker_id
))
114 out_dict
.update(DockerUtil
.docker_mem(docker_id
))
115 out_dict
.update(DockerUtil
.docker_PIDS(docker_id
))
116 out_dict
['SYS_time'] = int(time
.time() * 1000000000)
118 response
= Response(json
.dumps(out_dict
) + '\n', status
=200, mimetype
="application/json")
119 response
.headers
['Access-Control-Allow-Origin'] = '*'
121 except Exception as e
:
122 logging
.exception(u
"%s: Error getting monitoring information.\n %s" % (__name__
, e
))
123 return Response(u
"Error getting monitoring information.\n", status
=500, mimetype
="application/json")
126 class MonitorVnfAbs(Resource
):
127 def __init__(self
, api
):
130 def get(self
, vnf_name
):
132 Calculates the workload for the specified docker container, at this point in time.
134 :param vnf_name: Specifies the docker container via name.
135 :type vnf_name: ``str``
136 :return: Returns a json response with network, cpu, memory usage and storage access, as absolute values from
137 startup till this point of time. It also contains the number of running processes and the current
139 :rtype: :class:`flask.response`
141 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
142 if len(vnf_name
) < 3 or 'mn.' != vnf_name
[:3]:
143 vnf_name
= 'mn.' + vnf_name
146 from emuvim
.api
.openstack
.openstack_api_endpoint
import OpenstackApiEndpoint
147 for api
in OpenstackApiEndpoint
.dc_apis
:
148 if vnf_name
[3:] in api
.compute
.dc
.net
:
152 return Response(u
"MonitorAPI: VNF %s does not exist\n" % vnf_name
[3:],
154 mimetype
="application/json")
156 docker_id
= DockerUtil
.docker_container_id(vnf_name
)
158 out_dict
.update(DockerUtil
.docker_abs_cpu(docker_id
))
159 out_dict
.update(DockerUtil
.docker_mem(docker_id
))
160 out_dict
.update(DockerUtil
.docker_abs_net_io(docker_id
))
161 out_dict
.update(DockerUtil
.docker_block_rw(docker_id
))
162 out_dict
.update(DockerUtil
.docker_PIDS(docker_id
))
163 out_dict
['SYS_time'] = int(time
.time() * 1000000000)
165 response
= Response(json
.dumps(out_dict
) + '\n', status
=200, mimetype
="application/json")
166 response
.headers
['Access-Control-Allow-Origin'] = '*'
168 except Exception as e
:
169 logging
.exception(u
"%s: Error getting monitoring information.\n %s" % (__name__
, e
))
170 return Response(u
"Error getting monitoring information.\n", status
=500, mimetype
="application/json")
173 class MonitorVnfDcStack(Resource
):
174 def __init__(self
, api
):
177 def get(self
, dc
, stack
, vnf_name
):
179 Calculates the workload for the specified docker container, at this point in time.
180 This api call is for the translator to monitor a vnfs of a specific datacenter and stack.
182 :param dc: Target datacenter.
184 :param stack: Target stack
186 :param vnf_name: Specifies the docker container via name.
187 :type vnf_name: ``str``
188 :return: Returns a json response with network, cpu, memory usage and storage access, as absolute values from
189 startup till this point of time. It also contains the number of running processes and the current
191 :rtype: :class:`flask.response`
193 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
195 # search for real name
196 vnf_name
= self
._findName
(dc
, stack
, vnf_name
)
198 if type(vnf_name
) is not str:
199 # something went wrong, vnf_name is a Response object
203 docker_id
= DockerUtil
.docker_container_id(vnf_name
)
205 out_dict
.update(DockerUtil
.monitoring_over_time(docker_id
))
206 out_dict
.update(DockerUtil
.docker_mem(docker_id
))
207 out_dict
.update(DockerUtil
.docker_PIDS(docker_id
))
208 out_dict
['SYS_time'] = int(time
.time() * 1000000000)
210 response
= Response(json
.dumps(out_dict
) + '\n', status
=200, mimetype
="application/json")
211 response
.headers
['Access-Control-Allow-Origin'] = '*'
213 except Exception as e
:
214 logging
.exception(u
"%s: Error getting monitoring information.\n %s" % (__name__
, e
))
215 return Response(u
"Error getting monitoring information.\n", status
=500, mimetype
="application/json")
217 # Tries to find real container name according to heat template names
218 # Returns a string or a Response object
219 def _findName(self
, dc
, stack
, vnf
):
221 from emuvim
.api
.openstack
.openstack_api_endpoint
import OpenstackApiEndpoint
222 for api
in OpenstackApiEndpoint
.dc_apis
:
223 # search for datacenters
224 if dc
in api
.manage
.net
.dcs
:
225 dc_real
= api
.manage
.net
.dcs
[dc
]
228 return Response(u
"DC %s does not exist\n" % (dc
), status
=500, mimetype
="application/json")
230 # search for related OpenStackAPIs
232 for api
in OpenstackApiEndpoint
.dc_apis
:
233 if api
.compute
.dc
== dc_real
:
236 return Response(u
"OpenStackAPI does not exist\n", status
=500, mimetype
="application/json")
239 for stackObj
in api_real
.compute
.stacks
.values():
240 if stackObj
.stack_name
== stack
:
241 stack_real
= stackObj
242 if stack_real
is None:
243 return Response(u
"Stack %s does not exist\n" % (stack
), status
=500, mimetype
="application/json")
246 for server
in stack_real
.servers
.values():
247 if server
.template_name
== vnf
:
250 if server_real
is None:
251 return Response(u
"VNF %s does not exist\n" % (vnf
), status
=500, mimetype
="application/json")
252 container_real
= 'mn.' + server_real
.name
253 return container_real