class NovaRegion(object): """ Klein routes for the API within a Cloud Servers region. """ def __init__(self, uri_prefix): """ Create a nova region with a given URI prefix (used for generating URIs to servers). """ self.uri_prefix = uri_prefix app = MimicApp() @app.route('/v2/<string:tenant_id>/servers', methods=['POST']) def create_server(self, request, tenant_id): """ Returns a generic create server response, with status 'ACTIVE'. """ server_id = 'test-server{0}-id-{0}'.format(str(randrange(9999999999))) content = json.loads(request.content.read()) response_data = create_server(tenant_id, content['server'], server_id, self.uri_prefix) request.setResponseCode(response_data[1]) return json.dumps(response_data[0]) @app.route('/v2/<string:tenant_id>/servers/<string:server_id>', methods=['GET']) def get_server(self, request, tenant_id, server_id): """ Returns a generic get server response, with status 'ACTIVE' """ response_data = get_server(server_id) request.setResponseCode(response_data[1]) return json.dumps(response_data[0]) @app.route('/v2/<string:tenant_id>/servers', methods=['GET']) def list_servers(self, request, tenant_id): """ Returns list of servers that were created by the mocks, with the given name. """ return _list_servers(request, tenant_id) @app.route('/v2/<string:tenant_id>/servers/detail', methods=['GET']) def list_servers_with_details(self, request, tenant_id): """ Returns list of servers that were created by the mocks, with details such as the metadata. """ return _list_servers(request, tenant_id, details=True) @app.route('/v2/<string:tenant_id>/servers/<string:server_id>', methods=['DELETE']) def delete_server(self, request, tenant_id, server_id): """ Returns a 204 response code, for any server id' """ response_data = delete_server(server_id) request.setResponseCode(response_data[1]) return json.dumps(response_data[0]) @app.route('/v2/<string:tenant_id>/images/<string:image_id>', methods=['GET']) def get_image(self, request, tenant_id, image_id): """ Returns a get image response, for any given imageid """ response_data = get_image(image_id) request.setResponseCode(response_data[1]) return json.dumps(response_data[0]) @app.route('/v2/<string:tenant_id>/flavors/<string:flavor_id>', methods=['GET']) def get_flavor(self, request, tenant_id, flavor_id): """ Returns a get flavor response, for any given flavorid """ response_data = get_flavor(flavor_id) request.setResponseCode(response_data[1]) return json.dumps(response_data[0]) @app.route('/v2/<string:tenant_id>/limits', methods=['GET']) def get_limit(self, request, tenant_id): """ Returns a get flavor response, for any given flavorid """ request.setResponseCode(200) return json.dumps(get_limit()) @app.route('/v2/<string:tenant_id>/servers/<string:server_id>/ips', methods=['GET']) def get_ips(self, request, tenant_id, server_id): """ Returns a get flavor response, for any given flavorid. (currently the GET ips works only after a GET server after the server is created) """ response_data = list_addresses(server_id) request.setResponseCode(response_data[1]) return json.dumps(response_data[0])
class MimicRoot(object): """ Klein routes for the root of the mimic URI hierarchy. """ app = MimicApp() def __init__(self, core, clock=None): """ :param mimic.core.MimicCore core: The core object to dispatch routes from. :param twisted.internet.task.Clock clock: The clock to advance from the ``/mimic/v1.1/tick`` API. """ self.core = core self.clock = clock self.identity_behavior_registry = BehaviorRegistryCollection() @app.route("/", methods=["GET"]) def help(self, request): """ A helpful greeting message. """ request.responseHeaders.setRawHeaders("content-type", ["text/plain"]) return ("To get started with Mimic, POST an authentication request to:" "\n\n/identity/v2.0/tokens\n") @app.route("/identity", branch=True) def get_auth_api(self, request): """ Get the identity ... """ return AuthApi(self.core, self.identity_behavior_registry).app.resource() @app.route("/noit", branch=True) def get_noit_api(self, request): """ Mock Noit api here ... until mimic allows services outside of the service catalog. """ return NoitApi(self.core, self.clock).app.resource() @app.route("/sendgrid/mail.send.json", methods=['POST']) def send_grid_api(self, request): """ Mock SendGrid api responds with a 200. """ request.setResponseCode(200) return b'' @app.route("/cloudmonitoring.rackspace.com", branch=True) def mailgun_api(self, request): """ Mock Mail Gun API. """ return mailgun_api.MailGunApi(self.core).app.resource() @app.route("/fastly", branch=True) def get_fastly_api(self, request): """ Get the Fastly API ... """ return fastly_api.FastlyApi(self.core).app.resource() @app.route("/v1/customer_accounts/CLOUD", branch=True) def get_customer_api(self, request): """ Adds support for the Customer API """ return customer_api.CustomerApi(self.core).app.resource() @app.route("/ironic/v1", branch=True) def ironic_api(self, request): """ Mock Ironic API. """ return ironic_api.IronicApi(self.core).app.resource() @app.route('/mimic/v1.0/presets', methods=['GET']) def get_mimic_presets(self, request): """ Return the preset values for mimic """ request.setResponseCode(200) return json.dumps(get_presets) @app.route("/mimic/v1.1/tick", methods=['POST']) def advance_time(self, request): """ Advance time by the given number of seconds. """ body = json.loads(request.content.read()) amount = body['amount'] self.clock.advance(amount) request.setResponseCode(200) return json.dumps({ "advanced": amount, "now": seconds_to_timestamp(self.clock.seconds()) }) @app.route("/mimic/v1.1/IdentityControlAPI/behaviors", branch=True) def handle_identity_behaviors(self, request): """ Handle creating/deleting behaviors for mimic identity. """ api = AuthControlApiBehaviors(self.identity_behavior_registry) return api.app.resource() @app.route("/mimicking/<string:service_id>/<string:region_name>", branch=True) def get_service_resource(self, request, service_id, region_name): """ Based on the URL prefix of a region and a service, where the region is an identifier (like ORD, DFW, etc) and service is a dynamically-generated UUID for a particular plugin, retrieve the resource associated with that service. """ service_object = self.core.service_with_region( region_name, service_id, base_uri_from_request(request)) if service_object is None: # workaround for https://github.com/twisted/klein/issues/56 return NoResource() return service_object @app.route("/glance", branch=True) def glance_admin_api(self, request): """ Mock for the glance admin api """ return glance_api.GlanceAdminApi(self.core).app.resource()