1 from flask_restful
import Resource
2 from flask
import Response
, request
3 from emuvim
.api
.openstack
.openstack_dummies
.base_openstack_dummy
import BaseOpenstackDummy
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
,
14 self
.api
.add_resource(GlanceListApiVersions
,
16 self
.api
.add_resource(GlanceSchema
,
18 "/v2/schemas/metadefs/namespace",
19 "/v2/schemas/metadefs/resource_type")
20 self
.api
.add_resource(GlanceListImagesApi
,
25 resource_class_kwargs
={'api': self
})
26 self
.api
.add_resource(GlanceImageByIdApi
,
29 resource_class_kwargs
={'api': self
})
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)
38 class Shutdown(Resource
):
40 logging
.debug(("%s is beeing shut down") % (__name__
))
41 func
= request
.environ
.get('werkzeug.server.shutdown')
43 raise RuntimeError('Not running with the Werkzeug Server')
47 class GlanceListApiVersions(Resource
):
49 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
51 resp
['versions'] = dict()
57 "href": request
.url_root
+ '/v2',
62 resp
['versions'] = versions
63 return Response(json
.dumps(resp
), status
=200, mimetype
='application/json')
66 class GlanceSchema(Resource
):
68 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
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')
76 class GlanceListImagesApi(Resource
):
77 def __init__(self
, api
):
81 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
85 resp
['first'] = "/v2/images"
86 resp
['schema'] = "/v2/schemas/images"
87 resp
['images'] = list()
90 for image
in self
.api
.compute
.images
.values():
93 f
['name'] = str(image
.name
).replace(":latest", "")
94 f
['checksum'] = "2dad48f09e2a447a9bf852bcd93548c1"
95 f
['container_format'] = "docker"
96 f
['disk_format'] = "raw"
98 f
['created_at'] = "2016-03-15T15:09:07.000000"
100 f
['deleted_at'] = None
101 f
['is_public'] = True
104 f
['owner'] = "3dad48f09e2a447a9bf852bcd93548c1"
106 f
['protected'] = False
107 f
['status'] = "active"
108 f
['updated_at'] = "2016-03-15T15:09:07.000000"
109 f
['virtual_size'] = 1
111 resp
['images'].append(f
)
113 if c
> limit
: # ugly hack to stop buggy glance client to do infinite requests
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")
119 except Exception as ex
:
120 logging
.exception(u
"%s: Could not retrieve the list of images." % __name__
)
121 return ex
.message
, 500
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.
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)
138 for image
in self
.api
.compute
.images
.values():
139 if img_name
in image
.name
:
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
148 f
['checksum'] = "2dad48f09e2a447a9bf852bcd93548c1"
149 f
['container_format'] = img_container_format
150 f
['disk_format'] = img_disk_format
152 f
['created_at'] = "2016-03-15T15:09:07.000000"
154 f
['deleted_at'] = None
155 f
['is_public'] = img_is_public
158 f
['owner'] = "3dad48f09e2a447a9bf852bcd93548c1"
160 f
['protected'] = False
161 f
['status'] = "active"
162 f
['updated_at'] = "2016-03-15T15:09:07.000000"
163 f
['virtual_size'] = 1
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
,
173 class GlanceImageByIdApi(Resource
):
174 def __init__(self
, api
):
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
)
184 logging
.debug("API CALL: %s " % str(self
.__class
__.__name
__))
185 logging
.warning("Endpoint not implemented")