Merge remote-tracking branch 'upstream/master' into demo-mano-integration
[osm/vim-emu.git] / src / emuvim / api / openstack / openstack_dummies / glance_dummy_api.py
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 logging
5 import json
6
7
8 class GlanceDummyApi(BaseOpenstackDummy):
9 def __init__(self, in_ip, in_port, compute):
10 super(GlanceDummyApi, self).__init__(in_ip, in_port)
11 self.compute = compute
12 self.api.add_resource(Shutdown,
13 "/shutdown")
14 self.api.add_resource(GlanceListApiVersions,
15 "/versions")
16 self.api.add_resource(GlanceSchema,
17 "/v2/schemas/image",
18 "/v2/schemas/metadefs/namespace",
19 "/v2/schemas/metadefs/resource_type")
20 self.api.add_resource(GlanceListImagesApi,
21 "/v1/images",
22 "/v1/images/detail",
23 "/v2/images",
24 "/v2/images/detail",
25 resource_class_kwargs={'api': self})
26 self.api.add_resource(GlanceImageByIdApi,
27 "/v1/images/<id>",
28 "/v2/images/<id>",
29 resource_class_kwargs={'api': self})
30
31 def _start_flask(self):
32 logging.info("Starting %s endpoint @ http://%s:%d" % ("GlanceDummyApi", self.ip, self.port))
33 if self.app is not None:
34 self.app.before_request(self.dump_playbook)
35 self.app.run(self.ip, self.port, debug=True, use_reloader=False)
36
37
38 class Shutdown(Resource):
39 def get(self):
40 logging.debug(("%s is beeing shut down") % (__name__))
41 func = request.environ.get('werkzeug.server.shutdown')
42 if func is None:
43 raise RuntimeError('Not running with the Werkzeug Server')
44 func()
45
46
47 class GlanceListApiVersions(Resource):
48 def get(self):
49 logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
50 resp = dict()
51 resp['versions'] = dict()
52 versions = [{
53 "status": "CURRENT",
54 "id": "v2",
55 "links": [
56 {
57 "href": request.url_root + '/v2',
58 "rel": "self"
59 }
60 ]
61 }]
62 resp['versions'] = versions
63 return Response(json.dumps(resp), status=200, mimetype='application/json')
64
65
66 class GlanceSchema(Resource):
67 def get(self):
68 logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
69 resp = dict()
70 resp['name'] = 'someImageName'
71 resp['properties'] = dict()
72 # just an ugly hack to allow the openstack client to work
73 return Response(json.dumps(resp), status=200, mimetype='application/json')
74
75
76 class GlanceListImagesApi(Resource):
77 def __init__(self, api):
78 self.api = api
79
80 def get(self):
81 logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
82 try:
83 resp = dict()
84 resp['next'] = None
85 resp['first'] = "/v2/images"
86 resp['schema'] = "/v2/schemas/images"
87 resp['images'] = list()
88 limit = 18
89 c = 0
90 for image in self.api.compute.images.values():
91 f = dict()
92 f['id'] = image.id
93 f['name'] = str(image.name).replace(":latest", "")
94 f['checksum'] = "2dad48f09e2a447a9bf852bcd93548c1"
95 f['container_format'] = "docker"
96 f['disk_format'] = "raw"
97 f['size'] = 1
98 f['created_at'] = "2016-03-15T15:09:07.000000"
99 f['deleted'] = False
100 f['deleted_at'] = None
101 f['is_public'] = True
102 f['min_disk'] = 1
103 f['min_ram'] = 128
104 f['owner'] = "3dad48f09e2a447a9bf852bcd93548c1"
105 f['properties'] = {}
106 f['protected'] = False
107 f['status'] = "active"
108 f['updated_at'] = "2016-03-15T15:09:07.000000"
109 f['virtual_size'] = 1
110 f['marker'] = None
111 resp['images'].append(f)
112 c+=1
113 if c > limit: # ugly hack to stop buggy glance client to do infinite requests
114 break
115 if "marker" in request.args: # ugly hack to fix pageination of openstack client
116 resp['images'] = None
117 return Response(json.dumps(resp), status=200, mimetype="application/json")
118
119 except Exception as ex:
120 logging.exception(u"%s: Could not retrieve the list of images." % __name__)
121 return ex.message, 500
122
123 def post(self):
124 """
125 This one is a real fake! It does not really create anything and the mentioned image
126 should already be registered with Docker. However, this function returns a reply that looks
127 like the image was just created to make orchestrators, like OSM, happy.
128 """
129 logging.debug("API CALL: %s POST" % str(self.__class__.__name__))
130 # lets see what we should create
131 img_name = request.headers.get("X-Image-Meta-Name")
132 img_size = request.headers.get("X-Image-Meta-Size")
133 img_disk_format = request.headers.get("X-Image-Meta-Disk-Format")
134 img_is_public = request.headers.get("X-Image-Meta-Is-Public")
135 img_container_format = request.headers.get("X-Image-Meta-Container-Format")
136 # try to find ID of already existing image (matched by name)
137 img_id=None
138 for image in self.api.compute.images.values():
139 if img_name in image.name:
140 img_id = image.id
141 logging.debug("Image name: %s" % img_name)
142 logging.debug("Image id: %s" % img_id)
143 # build a response body that looks like a real one
144 resp = dict()
145 f = dict()
146 f['id'] = img_id
147 f['name'] = img_name
148 f['checksum'] = "2dad48f09e2a447a9bf852bcd93548c1"
149 f['container_format'] = img_container_format
150 f['disk_format'] = img_disk_format
151 f['size'] = img_size
152 f['created_at'] = "2016-03-15T15:09:07.000000"
153 f['deleted'] = False
154 f['deleted_at'] = None
155 f['is_public'] = img_is_public
156 f['min_disk'] = 1
157 f['min_ram'] = 128
158 f['owner'] = "3dad48f09e2a447a9bf852bcd93548c1"
159 f['properties'] = {}
160 f['protected'] = False
161 f['status'] = "active"
162 f['updated_at'] = "2016-03-15T15:09:07.000000"
163 f['virtual_size'] = 1
164 resp['image'] = f
165 # build actual response with headers and everything
166 r = Response(json.dumps(resp), status=201, mimetype="application/json")
167 r.headers.add("Location", "http://%s:%d/v1/images/%s" % (self.api.ip,
168 self.api.port,
169 img_id))
170 return r
171
172
173 class GlanceImageByIdApi(Resource):
174 def __init__(self, api):
175 self.api = api
176
177 def get(self, id):
178 logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
179 from emuvim.api.heat.openstack_dummies.nova_dummy_api import NovaListImages
180 nova = NovaListImages(self.api)
181 return nova.get(id)
182
183 def put(self, id):
184 logging.debug("API CALL: %s " % str(self.__class__.__name__))
185 logging.warning("Endpoint not implemented")
186 return None
187
188