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 from emuvim
.api
.openstack
.helper
import get_host
9 LOG
= logging
.getLogger("api.openstack.glance")
12 class GlanceDummyApi(BaseOpenstackDummy
):
13 def __init__(self
, in_ip
, in_port
, compute
):
14 super(GlanceDummyApi
, self
).__init
__(in_ip
, in_port
)
15 self
.compute
= compute
16 self
.api
.add_resource(Shutdown
,
18 self
.api
.add_resource(GlanceListApiVersions
,
20 self
.api
.add_resource(GlanceSchema
,
22 "/v2/schemas/metadefs/namespace",
23 "/v2/schemas/metadefs/resource_type")
24 self
.api
.add_resource(GlanceListImagesApi
,
29 resource_class_kwargs
={'api': self
})
30 self
.api
.add_resource(GlanceImageByIdApi
,
33 resource_class_kwargs
={'api': self
})
34 self
.api
.add_resource(GlanceImageByDockerNameApi
,
35 "/v1/images/<owner>/<container>",
36 "/v2/images/<owner>/<container>",
37 resource_class_kwargs
={'api': self
})
39 def _start_flask(self
):
40 LOG
.info("Starting %s endpoint @ http://%s:%d" % ("GlanceDummyApi", self
.ip
, self
.port
))
41 if self
.app
is not None:
42 self
.app
.before_request(self
.dump_playbook
)
43 self
.app
.run(self
.ip
, self
.port
, debug
=True, use_reloader
=False)
46 class Shutdown(Resource
):
48 LOG
.debug(("%s is beeing shut down") % (__name__
))
49 func
= request
.environ
.get('werkzeug.server.shutdown')
51 raise RuntimeError('Not running with the Werkzeug Server')
55 class GlanceListApiVersions(Resource
):
57 LOG
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
59 resp
['versions'] = dict()
65 "href": request
.url_root
+ '/v2',
70 resp
['versions'] = versions
71 return Response(json
.dumps(resp
), status
=200, mimetype
='application/json')
74 class GlanceSchema(Resource
):
76 LOG
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
78 resp
['name'] = 'someImageName'
79 resp
['properties'] = dict()
80 # just an ugly hack to allow the openstack client to work
81 return Response(json
.dumps(resp
), status
=200, mimetype
='application/json')
84 class GlanceListImagesApi(Resource
):
85 def __init__(self
, api
):
89 LOG
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
93 resp
['first'] = "/v2/images"
94 resp
['schema'] = "/v2/schemas/images"
95 resp
['images'] = list()
98 for image
in self
.api
.compute
.images
.values():
101 f
['name'] = str(image
.name
).replace(":latest", "")
102 f
['checksum'] = "2dad48f09e2a447a9bf852bcd93548c1"
103 f
['container_format'] = "docker"
104 f
['disk_format'] = "raw"
106 f
['created_at'] = "2016-03-15T15:09:07.000000"
108 f
['deleted_at'] = None
109 f
['is_public'] = True
112 f
['owner'] = "3dad48f09e2a447a9bf852bcd93548c1"
114 f
['protected'] = False
115 f
['status'] = "active"
116 f
['updated_at'] = "2016-03-15T15:09:07.000000"
117 f
['virtual_size'] = 1
119 resp
['images'].append(f
)
121 if c
> limit
: # ugly hack to stop buggy glance client to do infinite requests
123 if "marker" in request
.args
: # ugly hack to fix pageination of openstack client
124 resp
['images'] = None
125 return Response(json
.dumps(resp
), status
=200, mimetype
="application/json")
127 except Exception as ex
:
128 LOG
.exception(u
"%s: Could not retrieve the list of images." % __name__
)
129 return ex
.message
, 500
133 This one is a real fake! It does not really create anything and the mentioned image
134 should already be registered with Docker. However, this function returns a reply that looks
135 like the image was just created to make orchestrators, like OSM, happy.
137 LOG
.debug("API CALL: %s POST" % str(self
.__class
__.__name
__))
139 body_data
= json
.loads(request
.data
)
142 # lets see what we should create
143 img_name
= request
.headers
.get("X-Image-Meta-Name")
144 img_size
= request
.headers
.get("X-Image-Meta-Size")
145 img_disk_format
= request
.headers
.get("X-Image-Meta-Disk-Format")
146 img_is_public
= request
.headers
.get("X-Image-Meta-Is-Public")
147 img_container_format
= request
.headers
.get("X-Image-Meta-Container-Format")
148 # try to use body payload if header fields are empty
150 img_name
= body_data
.get("name")
152 img_disk_format
= body_data
.get("disk_format")
153 img_is_public
= True if "public" in body_data
.get("visibility") else False
154 img_container_format
= body_data
.get("container_format")
155 # try to find ID of already existing image (matched by name)
157 for image
in self
.api
.compute
.images
.values():
158 if str(img_name
) in image
.name
:
160 LOG
.debug("Image name: %s" % img_name
)
161 LOG
.debug("Image id: %s" % img_id
)
162 # build a response body that looks like a real one
167 f
['checksum'] = "2dad48f09e2a447a9bf852bcd93548c1"
168 f
['container_format'] = img_container_format
169 f
['disk_format'] = img_disk_format
171 f
['created_at'] = "2016-03-15T15:09:07.000000"
173 f
['deleted_at'] = None
174 f
['is_public'] = img_is_public
177 f
['owner'] = "3dad48f09e2a447a9bf852bcd93548c1"
179 f
['protected'] = False
180 f
['status'] = "active"
181 f
['updated_at'] = "2016-03-15T15:09:07.000000"
182 f
['virtual_size'] = 1
184 # build actual response with headers and everything
185 r
= Response(json
.dumps(resp
), status
=201, mimetype
="application/json")
186 r
.headers
.add("Location", "http://%s:%d/v1/images/%s" % (get_host(request
),
192 class GlanceImageByIdApi(Resource
):
193 def __init__(self
, api
):
197 LOG
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
200 for image
in self
.api
.compute
.images
.values():
201 if image
.id == id or image
.name
== id:
202 resp
['id'] = image
.id
203 resp
['name'] = image
.name
205 return Response(json
.dumps(resp
), status
=200, mimetype
="application/json")
207 response
= Response("Image with id or name %s does not exists." % id, status
=404)
208 response
.headers
['Access-Control-Allow-Origin'] = '*'
211 except Exception as ex
:
212 LOG
.exception(u
"%s: Could not retrieve image with id %s." % (__name__
, id))
213 return Response(ex
.message
, status
=500, mimetype
='application/json')
216 LOG
.debug("API CALL: %s " % str(self
.__class
__.__name
__))
217 LOG
.warning("Endpoint not implemented")
221 class GlanceImageByDockerNameApi(Resource
):
222 def __init__(self
, api
):
225 def get(self
, owner
, container
):
226 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
228 name
= "%s/%s" % (owner
, container
)
229 if name
in self
.api
.compute
.images
:
230 image
= self
.api
.compute
.images
[name
]
232 resp
['id'] = image
.id
233 resp
['name'] = image
.name
234 return Response(json
.dumps(resp
), status
=200, mimetype
="application/json")
236 response
= Response("Image with id or name %s does not exists." % id, status
=404)
237 response
.headers
['Access-Control-Allow-Origin'] = '*'
240 except Exception as ex
:
241 logging
.exception(u
"%s: Could not retrieve image with id %s." % (__name__
, id))
242 return Response(ex
.message
, status
=500, mimetype
='application/json')