Beispiel #1
0
    def test_attach_with_invalid_arguments(self):
        # Invalid request to attach volume an invalid target
        body = {"os-attach": {"mountpoint": "/dev/vdc"}}
        req = webob.Request.blank("/v2/fake/volumes/1/action")
        req.method = "POST"
        req.headers["content-type"] = "application/json"
        req.body = jsonutils.dumps(body)
        res = req.get_response(fakes.wsgi_app())
        self.assertEqual(res.status_int, 400)

        # Invalid request to attach volume to an instance and a host
        body = {"os-attach": {"instance_uuid": "fake", "host_name": "fake_host", "mountpoint": "/dev/vdc"}}
        req = webob.Request.blank("/v2/fake/volumes/1/action")
        req.method = "POST"
        req.headers["content-type"] = "application/json"
        req.body = jsonutils.dumps(body)
        res = req.get_response(fakes.wsgi_app())
        self.assertEqual(res.status_int, 400)

        # Invalid request to attach volume with an invalid mode
        body = {"os-attach": {"instance_uuid": "fake", "mountpoint": "/dev/vdc", "mode": "rr"}}
        req = webob.Request.blank("/v2/fake/volumes/1/action")
        req.method = "POST"
        req.headers["content-type"] = "application/json"
        req.body = jsonutils.dumps(body)
        res = req.get_response(fakes.wsgi_app())
        self.assertEqual(res.status_int, 400)
        body = {"os-attach": {"host_name": "fake_host", "mountpoint": "/dev/vdc", "mode": "ww"}}
        req = webob.Request.blank("/v2/fake/volumes/1/action")
        req.method = "POST"
        req.headers["content-type"] = "application/json"
        req.body = jsonutils.dumps(body)
        res = req.get_response(fakes.wsgi_app())
        self.assertEqual(res.status_int, 400)
Beispiel #2
0
    def _is_serializable(value):
        """Returns True if value is serializable."""
        try:
            jsonutils.dumps(value)
        except TypeError:
            LOG.info(_("Value with type=%s is not serializable") %
                     type(value))
            return False

        return True
Beispiel #3
0
    def __call__(self, target, creds, enforcer):
        """Check http: rules by calling to a remote server.

        This example implementation simply verifies that the response
        is exactly 'True'.
        """

        url = ('http:' + self.match) % target
        data = {'target': jsonutils.dumps(target),
                'credentials': jsonutils.dumps(creds)}
        post_data = urlparse.urlencode(data)
        f = urlrequest.urlopen(url, post_data)
        return f.read() == "True"
Beispiel #4
0
def _check_http(brain, match_kind, match, target_dict, cred_dict):
    """Check http: rules by calling to a remote server.

    This example implementation simply verifies that the response is
    exactly 'True'. A custom brain using response codes could easily
    be implemented.

    """
    url = 'http:' + (match % target_dict)
    data = {'target': jsonutils.dumps(target_dict),
            'credentials': jsonutils.dumps(cred_dict)}
    post_data = urllib.urlencode(data)
    f = urllib2.urlopen(url, post_data)
    return f.read() == "True"
Beispiel #5
0
    def _pack_json_msg(self, msg):
        """Qpid cannot serialize dicts containing strings longer than 65535
           characters.  This function dumps the message content to a JSON
           string, which Qpid is able to handle.

        :param msg: May be either a Qpid Message object or a bare dict.
        :returns: A Qpid Message with its content field JSON encoded.
        """
        try:
            msg.content = jsonutils.dumps(msg.content)
        except AttributeError:
            # Need to have a Qpid message so we can set the content_type.
            msg = qpid_messaging.Message(jsonutils.dumps(msg))
        msg.content_type = JSON_CONTENT_TYPE
        return msg
    def test_update_all_with_keys_in_uppercase_and_lowercase(self):
        self.stubs.Set(cinder.db, 'volume_metadata_get',
                       return_create_volume_metadata)
        self.stubs.Set(cinder.db, 'volume_metadata_update',
                       return_new_volume_metadata)
        req = fakes.HTTPRequest.blank(self.url)
        req.method = 'PUT'
        req.content_type = "application/json"
        body = {
            'metadata': {
                'key10': 'value10',
                'KEY10': 'value10',
                'key99': 'value99',
                'KEY20': 'value20',
            },
        }
        expected = {
            'metadata': {
                'key10': 'value10',
                'key99': 'value99',
                'KEY20': 'value20',
            },
        }
        req.body = jsonutils.dumps(expected)
        res_dict = self.controller.update_all(req, self.req_id, body)

        self.assertEqual(expected, res_dict)
Beispiel #7
0
    def __call__(self, *args):
        data = jsonutils.dumps({'object': self.obj,
                                'method': self.method,
                                'params': args})
        auth = ('%s:%s' % (self.user, self.password)).encode('base64')[:-1]
        headers = {'Content-Type': 'application/json',
                   'Authorization': 'Basic %s' % (auth,)}
        LOG.debug(_('Sending JSON data: %s'), data)
        request = urllib2.Request(self.url, data, headers)
        response_obj = urllib2.urlopen(request)
        if response_obj.info().status == 'EOF in headers':
            if self.auto and self.url.startswith('http://'):
                LOG.info(_('Auto switching to HTTPS connection to %s'),
                         self.url)
                self.url = 'https' + self.url[4:]
                request = urllib2.Request(self.url, data, headers)
                response_obj = urllib2.urlopen(request)
            else:
                LOG.error(_('No headers in server response'))
                raise NexentaJSONException(_('Bad response from server'))

        response_data = response_obj.read()
        LOG.debug(_('Got response: %s'), response_data)
        response = jsonutils.loads(response_data)
        if response.get('error') is not None:
            raise NexentaJSONException(response['error'].get('message', ''))
        else:
            return response.get('result')
Beispiel #8
0
def serialize_remote_exception(failure_info):
    """Prepares exception data to be sent over rpc.

    Failure_info should be a sys.exc_info() tuple.

    """
    tb = traceback.format_exception(*failure_info)
    failure = failure_info[1]
    LOG.error(_("Returning exception %s to caller"), unicode(failure))
    LOG.error(tb)

    kwargs = {}
    if hasattr(failure, 'kwargs'):
        kwargs = failure.kwargs

    data = {
        'class': str(failure.__class__.__name__),
        'module': str(failure.__class__.__module__),
        'message': unicode(failure),
        'tb': tb,
        'args': failure.args,
        'kwargs': kwargs
    }

    json_data = jsonutils.dumps(data)

    return json_data
Beispiel #9
0
def serialize_msg(raw_msg):
    # NOTE(russellb) See the docstring for _RPC_ENVELOPE_VERSION for more
    # information about this format.
    msg = {_VERSION_KEY: _RPC_ENVELOPE_VERSION,
           _MESSAGE_KEY: jsonutils.dumps(raw_msg)}

    return msg
Beispiel #10
0
 def test_force_delete_snapshot(self):
     self.stubs.Set(os.path, 'exists', lambda x: True)
     # admin context
     ctx = context.RequestContext('admin', 'fake', True)
     # current status is creating
     volume = db.volume_create(ctx, {'host': 'test'})
     snapshot = db.snapshot_create(ctx, {'status': 'creating',
                                         'volume_size': 1,
                                         'volume_id': volume['id']})
     path = '/v2/fake/snapshots/%s/action' % snapshot['id']
     req = webob.Request.blank(path)
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     req.body = jsonutils.dumps({'os-force_delete': {}})
     # attach admin context to request
     req.environ['cinder.context'] = ctx
     # start service to handle rpc.cast for 'delete snapshot'
     svc = self.start_service('volume', host='test')
     # make request
     resp = req.get_response(app())
     # request is accepted
     self.assertEqual(resp.status_int, 202)
     # snapshot is deleted
     self.assertRaises(exception.NotFound, db.snapshot_get, ctx,
                       snapshot['id'])
     # cleanup
     svc.stop()
Beispiel #11
0
 def test_force_detach_volume(self):
     # admin context
     ctx = context.RequestContext("admin", "fake", True)
     # current status is available
     volume = db.volume_create(ctx, {"status": "available", "host": "test", "provider_location": ""})
     # start service to handle rpc messages for attach requests
     self.start_service("volume", host="test")
     self.volume_api.reserve_volume(ctx, volume)
     self.volume_api.initialize_connection(ctx, volume, {})
     mountpoint = "/dev/vbd"
     self.volume_api.attach(ctx, volume, fakes.FAKE_UUID, mountpoint)
     # volume is attached
     volume = db.volume_get(ctx, volume["id"])
     self.assertEquals(volume["status"], "in-use")
     self.assertEquals(volume["instance_uuid"], fakes.FAKE_UUID)
     self.assertEquals(volume["mountpoint"], mountpoint)
     self.assertEquals(volume["attach_status"], "attached")
     # build request to force detach
     req = webob.Request.blank("/v1/fake/volumes/%s/action" % volume["id"])
     req.method = "POST"
     req.headers["content-type"] = "application/json"
     # request status of 'error'
     req.body = jsonutils.dumps({"os-force_detach": None})
     # attach admin context to request
     req.environ["cinder.context"] = ctx
     # make request
     resp = req.get_response(app())
     # request is accepted
     self.assertEquals(resp.status_int, 202)
     volume = db.volume_get(ctx, volume["id"])
     # status changed to 'available'
     self.assertEquals(volume["status"], "available")
     self.assertEquals(volume["instance_uuid"], None)
     self.assertEquals(volume["mountpoint"], None)
     self.assertEquals(volume["attach_status"], "detached")
Beispiel #12
0
    def format(self, record):
        message = {
            "message": record.getMessage(),
            "asctime": self.formatTime(record, self.datefmt),
            "name": record.name,
            "msg": record.msg,
            "args": record.args,
            "levelname": record.levelname,
            "levelno": record.levelno,
            "pathname": record.pathname,
            "filename": record.filename,
            "module": record.module,
            "lineno": record.lineno,
            "funcname": record.funcName,
            "created": record.created,
            "msecs": record.msecs,
            "relative_created": record.relativeCreated,
            "thread": record.thread,
            "thread_name": record.threadName,
            "process_name": record.processName,
            "process": record.process,
            "traceback": None,
        }

        if hasattr(record, "extra"):
            message["extra"] = record.extra

        if record.exc_info:
            message["traceback"] = self.formatException(record.exc_info)

        return jsonutils.dumps(message)
Beispiel #13
0
    def __init__(self, session, callback, node_name, node_opts, link_name, link_opts):
        """Declare a queue on an amqp session.

        'session' is the amqp session to use
        'callback' is the callback to call when messages are received
        'node_name' is the first part of the Qpid address string, before ';'
        'node_opts' will be applied to the "x-declare" section of "node"
                    in the address string.
        'link_name' goes into the "name" field of the "link" in the address
                    string
        'link_opts' will be applied to the "x-declare" section of "link"
                    in the address string.
        """
        self.callback = callback
        self.receiver = None
        self.session = None

        addr_opts = {
            "create": "always",
            "node": {"type": "topic", "x-declare": {"durable": True, "auto-delete": True}},
            "link": {
                "name": link_name,
                "durable": True,
                "x-declare": {"durable": False, "auto-delete": True, "exclusive": False},
            },
        }
        addr_opts["node"]["x-declare"].update(node_opts)
        addr_opts["link"]["x-declare"].update(link_opts)

        self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts))

        self.reconnect(session)
Beispiel #14
0
    def __init__(self, session, node_name, node_opts=None):
        """Init the Publisher class with the exchange_name, routing_key,
        and other options
        """
        self.sender = None
        self.session = session

        addr_opts = {
            "create": "always",
            "node": {
                "type": "topic",
                "x-declare": {
                    "durable": False,
                    # auto-delete isn't implemented for exchanges in qpid,
                    # but put in here anyway
                    "auto-delete": True,
                },
            },
        }
        if node_opts:
            addr_opts["node"]["x-declare"].update(node_opts)

        self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts))

        self.reconnect(session)
Beispiel #15
0
    def format(self, record):
        message = {'message': record.getMessage(),
                   'asctime': self.formatTime(record, self.datefmt),
                   'name': record.name,
                   'msg': record.msg,
                   'args': record.args,
                   'levelname': record.levelname,
                   'levelno': record.levelno,
                   'pathname': record.pathname,
                   'filename': record.filename,
                   'module': record.module,
                   'lineno': record.lineno,
                   'funcname': record.funcName,
                   'created': record.created,
                   'msecs': record.msecs,
                   'relative_created': record.relativeCreated,
                   'thread': record.thread,
                   'thread_name': record.threadName,
                   'process_name': record.processName,
                   'process': record.process,
                   'traceback': None}

        if hasattr(record, 'extra'):
            message['extra'] = record.extra

        if record.exc_info:
            message['traceback'] = self.formatException(record.exc_info)

        return jsonutils.dumps(message)
Beispiel #16
0
    def _issue_api_request(self, method_name, params):
        """All API requests to SolidFire device go through this method

        Simple json-rpc web based API calls.
        each call takes a set of paramaters (dict)
        and returns results in a dict as well.
        """

        host = FLAGS.san_ip
        # For now 443 is the only port our server accepts requests on
        port = 443

        # NOTE(john-griffith): Probably don't need this, but the idea is
        # we provide a request_id so we can correlate
        # responses with requests
        request_id = int(uuid.uuid4())  # just generate a random number

        cluster_admin = FLAGS.san_login
        cluster_password = FLAGS.san_password

        command = {'method': method_name,
                   'id': request_id}

        if params is not None:
            command['params'] = params

        payload = jsonutils.dumps(command, ensure_ascii=False)
        payload.encode('utf-8')
        # we use json-rpc, webserver needs to see json-rpc in header
        header = {'Content-Type': 'application/json-rpc; charset=utf-8'}

        if cluster_password is not None:
            # base64.encodestring includes a newline character
            # in the result, make sure we strip it off
            auth_key = base64.encodestring('%s:%s' % (cluster_admin,
                                           cluster_password))[:-1]
            header['Authorization'] = 'Basic %s' % auth_key

        LOG.debug(_("Payload for SolidFire API call: %s"), payload)
        connection = httplib.HTTPSConnection(host, port)
        connection.request('POST', '/json-rpc/1.0', payload, header)
        response = connection.getresponse()
        data = {}

        if response.status != 200:
            connection.close()
            raise exception.SolidFireAPIException(status=response.status)

        else:
            data = response.read()
            try:
                data = jsonutils.loads(data)

            except (TypeError, ValueError), exc:
                connection.close()
                msg = _("Call to json.loads() raised an exception: %s") % exc
                raise exception.SfJsonEncodeFailure(msg)

            connection.close()
 def test_retype_volume_no_body(self):
     # Request with no body should fail
     req = webob.Request.blank('/v2/fake/volumes/1/action')
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     req.body = jsonutils.dumps({'os-retype': None})
     res = req.get_response(fakes.wsgi_app())
     self.assertEqual(res.status_int, 400)
 def make_update_readonly_flag_test(self, readonly, return_code):
     body = {"os-update_readonly_flag": {"readonly": readonly}}
     req = webob.Request.blank('/v2/fake/volumes/1/action')
     req.method = "POST"
     req.body = jsonutils.dumps(body)
     req.headers["content-type"] = "application/json"
     res = req.get_response(fakes.wsgi_app())
     self.assertEqual(res.status_int, return_code)
Beispiel #19
0
 def _issue_backup_reset(self, ctx, backup, updated_status):
     req = webob.Request.blank("/v2/fake/backups/%s/action" % backup["id"])
     req.method = "POST"
     req.headers["content-type"] = "application/json"
     req.body = jsonutils.dumps({"os-reset_status": updated_status})
     req.environ["cinder.context"] = ctx
     resp = req.get_response(app())
     return resp
 def _retype_volume_exec(self, expected_status, new_type='foo'):
     req = webob.Request.blank('/v2/fake/volumes/1/action')
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     retype_body = {'new_type': new_type, 'migration_policy': 'never'}
     req.body = jsonutils.dumps({'os-retype': retype_body})
     res = req.get_response(fakes.wsgi_app())
     self.assertEqual(res.status_int, expected_status)
 def test_retype_volume_bad_policy(self):
     # Request with invalid migration policy should fail
     req = webob.Request.blank('/v2/fake/volumes/1/action')
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     retype_body = {'new_type': 'foo', 'migration_policy': 'invalid'}
     req.body = jsonutils.dumps({'os-retype': retype_body})
     res = req.get_response(fakes.wsgi_app())
     self.assertEqual(res.status_int, 400)
    def test_update_all_malformed_data(self):
        self.stubs.Set(cinder.db, "volume_metadata_update", return_create_volume_metadata)
        req = fakes.HTTPRequest.blank(self.url)
        req.method = "PUT"
        req.content_type = "application/json"
        expected = {"metadata": ["asdf"]}
        req.body = jsonutils.dumps(expected)

        self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update_all, req, self.id, expected)
    def test_update_all_nonexistent_volume(self):
        self.stubs.Set(cinder.db, "volume_get", return_volume_nonexistent)
        req = fakes.HTTPRequest.blank(self.url)
        req.method = "PUT"
        req.content_type = "application/json"
        body = {"metadata": {"key10": "value10"}}
        req.body = jsonutils.dumps(body)

        self.assertRaises(webob.exc.HTTPNotFound, self.controller.update_all, req, "100", body)
    def test_update_item_nonexistent_volume(self):
        self.stubs.Set(cinder.db, "volume_get", return_volume_nonexistent)
        req = fakes.HTTPRequest.blank("/v1.1/fake/volumes/asdf/metadata/key1")
        req.method = "PUT"
        body = {"meta": {"key1": "value1"}}
        req.body = jsonutils.dumps(body)
        req.headers["content-type"] = "application/json"

        self.assertRaises(webob.exc.HTTPNotFound, self.controller.update, req, self.id, "key1", body)
    def test_update_item_value_too_long(self):
        self.stubs.Set(cinder.db, "volume_metadata_update", return_create_volume_metadata)
        req = fakes.HTTPRequest.blank(self.url + "/key1")
        req.method = "PUT"
        body = {"meta": {"key1": ("a" * 260)}}
        req.body = jsonutils.dumps(body)
        req.headers["content-type"] = "application/json"

        self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, self.controller.update, req, self.id, "key1", body)
    def test_update_item_body_uri_mismatch(self):
        self.stubs.Set(cinder.db, "volume_metadata_update", return_create_volume_metadata)
        req = fakes.HTTPRequest.blank(self.url + "/bad")
        req.method = "PUT"
        body = {"meta": {"key1": "value1"}}
        req.body = jsonutils.dumps(body)
        req.headers["content-type"] = "application/json"

        self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, req, self.id, "bad", body)
Beispiel #27
0
 def _issue_volume_reset(self, ctx, volume, updated_status):
     req = webob.Request.blank('/v2/fake/volumes/%s/action' % volume['id'])
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     req.body = \
         jsonutils.dumps({'os-reset_status': updated_status})
     req.environ['cinder.context'] = ctx
     resp = req.get_response(app())
     return resp
Beispiel #28
0
 def _migrate_volume_comp_exec(self, ctx, volume, new_volume, error, expected_status, expected_id, no_body=False):
     req = webob.Request.blank("/v2/fake/volumes/%s/action" % volume["id"])
     req.method = "POST"
     req.headers["content-type"] = "application/json"
     body = {"new_volume": new_volume["id"], "error": error}
     if no_body:
         req.body = jsonutils.dumps({"": body})
     else:
         req.body = jsonutils.dumps({"os-migrate_volume_completion": body})
     req.environ["cinder.context"] = ctx
     resp = req.get_response(app())
     resp_dict = ast.literal_eval(resp.body)
     # verify status
     self.assertEqual(resp.status_int, expected_status)
     if expected_id:
         self.assertEqual(resp_dict["save_volume_id"], expected_id)
     else:
         self.assertNotIn("save_volume_id", resp_dict)
Beispiel #29
0
    def test_attach_to_instance(self):
        body = {"os-attach": {"instance_uuid": "fake", "mountpoint": "/dev/vdc", "mode": "rw"}}
        req = webob.Request.blank("/v2/fake/volumes/1/action")
        req.method = "POST"
        req.body = jsonutils.dumps(body)
        req.headers["content-type"] = "application/json"

        res = req.get_response(fakes.wsgi_app())
        self.assertEqual(res.status_int, 202)
Beispiel #30
0
 def test_simple_api_actions(self):
     app = fakes.wsgi_app()
     for _action in self._actions:
         req = webob.Request.blank("/v2/fake/volumes/%s/action" % self.UUID)
         req.method = "POST"
         req.body = jsonutils.dumps({_action: None})
         req.content_type = "application/json"
         res = req.get_response(app)
         self.assertEqual(res.status_int, 202)
Beispiel #31
0
    def test_attach_to_host(self):
        # using 'read-write' mode attach volume by default
        body = {
            'os-attach': {
                'host_name': 'fake_host',
                'mountpoint': '/dev/vdc'
            }
        }
        req = webob.Request.blank('/v2/fake/volumes/1/action')
        req.method = "POST"
        req.body = jsonutils.dumps(body)
        req.headers["content-type"] = "application/json"

        res = req.get_response(fakes.wsgi_app())
        self.assertEqual(res.status_int, 202)
Beispiel #32
0
    def test_update_readonly_flag(self):
        def fake_update_readonly_flag(*args, **kwargs):
            return {}

        self.stubs.Set(volume.API, 'update_readonly_flag',
                       fake_update_readonly_flag)

        body = {'os-update_readonly_flag': {'readonly': True}}
        req = webob.Request.blank('/v2/fake/volumes/1/action')
        req.method = "POST"
        req.body = jsonutils.dumps(body)
        req.headers["content-type"] = "application/json"

        res = req.get_response(fakes.wsgi_app())
        self.assertEqual(res.status_int, 202)
    def test_invalid_metadata_items_on_create(self):
        self.stubs.Set(db, 'volume_metadata_update',
                       return_create_volume_metadata)
        req = fakes.HTTPRequest.blank(self.url)
        req.method = 'POST'
        req.headers["content-type"] = "application/json"

        #test for long key
        data = {"metadata": {"a" * 260: "value1"}}
        req.body = jsonutils.dumps(data)
        self.assertRaises(webob.exc.HTTPRequestEntityTooLarge,
                          self.controller.create, req, self.req_id, data)

        #test for long value
        data = {"metadata": {"key": "v" * 260}}
        req.body = jsonutils.dumps(data)
        self.assertRaises(webob.exc.HTTPRequestEntityTooLarge,
                          self.controller.create, req, self.req_id, data)

        #test for empty key.
        data = {"metadata": {"": "value1"}}
        req.body = jsonutils.dumps(data)
        self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
                          req, self.req_id, data)
 def _migrate_volume_exec(self, ctx, volume, host, expected_status,
                          force_host_copy=False):
     admin_ctx = context.get_admin_context()
     # build request to migrate to host
     req = webob.Request.blank('/v2/fake/volumes/%s/action' % volume['id'])
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     body = {'os-migrate_volume': {'host': host,
                                   'force_host_copy': force_host_copy}}
     req.body = jsonutils.dumps(body)
     req.environ['cinder.context'] = ctx
     resp = req.get_response(app())
     # verify status
     self.assertEqual(resp.status_int, expected_status)
     volume = db.volume_get(admin_ctx, volume['id'])
     return volume
Beispiel #35
0
    def test_create_server_bad_hints(self):
        req = fakes.HTTPRequest.blank('/v2/fake/volumes')
        req.method = 'POST'
        req.content_type = 'application/json'
        body = {
            'volume': {
                'id': id,
                'volume_type_id': 'cedef40a-ed67-4d10-800e-17455edce175',
                'volume_id': '1',
                'scheduler_hints': 'a',
            }
        }

        req.body = jsonutils.dumps(body)
        res = req.get_response(self.app)
        self.assertEqual(400, res.status_int)
 def test_migrate_volume_without_host_parameter(self):
     expected_status = 400
     host = 'test3'
     ctx = context.RequestContext('admin', 'fake', True)
     volume = self._migrate_volume_prep()
     # build request to migrate without host
     req = webob.Request.blank('/v2/fake/volumes/%s/action' % volume['id'])
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     body = {'os-migrate_volume': {'host': host,
                                   'force_host_copy': False}}
     req.body = jsonutils.dumps(body)
     req.environ['cinder.context'] = ctx
     resp = req.get_response(app())
     # verify status
     self.assertEqual(resp.status_int, expected_status)
Beispiel #37
0
    def get(self, volume_id):
        """Get volume metadata.

        Returns a json-encoded dict containing all metadata and the restore
        version i.e. the version used to decide what actually gets restored
        from this container when doing a backup restore.
        """
        container = {'version': CONF.backup_metadata_version}
        self._save_vol_base_meta(container, volume_id)
        self._save_vol_meta(container, volume_id)
        self._save_vol_glance_meta(container, volume_id)

        if container:
            return jsonutils.dumps(container)
        else:
            return None
 def _migrate_volume_comp_exec(self, ctx, volume, new_volume, error,
                               expected_status, expected_id):
     req = webob.Request.blank('/v2/fake/volumes/%s/action' % volume['id'])
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     body_dict = {'new_volume': new_volume['id'], 'error': error}
     req.body = jsonutils.dumps({'os-migrate_volume_completion': body_dict})
     req.environ['cinder.context'] = ctx
     resp = req.get_response(app())
     resp_dict = ast.literal_eval(resp.body)
     # verify status
     self.assertEqual(resp.status_int, expected_status)
     if expected_id:
         self.assertEqual(resp_dict['save_volume_id'], expected_id)
     else:
         self.assertNotIn('save_volume_id', resp_dict)
Beispiel #39
0
 def setUp(self):
     super(HostFiltersTestCase, self).setUp()
     self.stubs = stubout.StubOutForTesting()
     stub_out_https_backend(self.stubs)
     self.context = context.RequestContext('fake', 'fake')
     self.json_query = jsonutils.dumps(
         ['and',
             ['>=', '$free_capacity_gb', 1024],
             ['>=', '$total_capacity_gb', 10 * 1024]])
     # This has a side effect of testing 'get_filter_classes'
     # when specifying a method (in this case, our standard filters)
     filter_handler = filters.HostFilterHandler('cinder.scheduler.filters')
     classes = filter_handler.get_all_classes()
     self.class_map = {}
     for cls in classes:
         self.class_map[cls.__name__] = cls
    def test_update_all(self):
        self.stubs.Set(cinder.db, 'snapshot_metadata_update',
                       return_create_snapshot_metadata)
        req = fakes.HTTPRequest.blank(self.url)
        req.method = 'PUT'
        req.content_type = "application/json"
        expected = {
            'metadata': {
                'key10': 'value10',
                'key99': 'value99',
            },
        }
        req.body = jsonutils.dumps(expected)
        res_dict = self.controller.update_all(req, self.req_id, expected)

        self.assertEqual(expected, res_dict)
Beispiel #41
0
 def test_force_delete(self):
     # admin context
     ctx = context.RequestContext('admin', 'fake', True)
     # current status is creating
     volume = db.volume_create(ctx, {'size': 1})
     req = webob.Request.blank('/v2/fake/volumes/%s/action' % volume['id'])
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     req.body = jsonutils.dumps({'os-force_delete': {}})
     # attach admin context to request
     req.environ['cinder.context'] = ctx
     resp = req.get_response(app())
     # request is accepted
     self.assertEqual(resp.status_int, 202)
     # volume is deleted
     self.assertRaises(exception.NotFound, db.volume_get, ctx, volume['id'])
Beispiel #42
0
    def check_for_delay(self, verb, path, username=None):
        body = jsonutils.dumps({"verb": verb, "path": path})
        headers = {"Content-Type": "application/json"}

        conn = httplib.HTTPConnection(self.limiter_address)

        if username:
            conn.request("POST", "/%s" % (username), body, headers)
        else:
            conn.request("POST", "/", body, headers)

        resp = conn.getresponse()

        if 200 >= resp.status < 300:
            return None, None

        return resp.getheader("X-Wait-Seconds"), resp.read() or None
 def test_force_detach_host_attached_volume(self):
     # admin context
     ctx = context.RequestContext('admin', 'fake', True)
     # current status is available
     volume = db.volume_create(ctx, {
         'status': 'available',
         'host': 'test',
         'provider_location': ''
     })
     connector = {'initiator': 'iqn.2012-07.org.fake:01'}
     # start service to handle rpc messages for attach requests
     svc = self.start_service('volume', host='test')
     self.volume_api.reserve_volume(ctx, volume)
     self.volume_api.initialize_connection(ctx, volume, connector)
     mountpoint = '/dev/vbd'
     host_name = 'fake-host'
     self.volume_api.attach(ctx, volume, None, host_name, mountpoint)
     # volume is attached
     volume = db.volume_get(ctx, volume['id'])
     self.assertEquals(volume['status'], 'in-use')
     self.assertEquals(volume['instance_uuid'], None)
     self.assertEquals(volume['attached_host'], host_name)
     self.assertEquals(volume['mountpoint'], mountpoint)
     self.assertEquals(volume['attach_status'], 'attached')
     # build request to force detach
     req = webob.Request.blank('/v2/fake/volumes/%s/action' % volume['id'])
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     # request status of 'error'
     req.body = jsonutils.dumps({'os-force_detach': None})
     # attach admin context to request
     req.environ['cinder.context'] = ctx
     # make request
     resp = req.get_response(app())
     # request is accepted
     self.assertEquals(resp.status_int, 202)
     volume = db.volume_get(ctx, volume['id'])
     # status changed to 'available'
     self.assertEquals(volume['status'], 'available')
     self.assertEquals(volume['instance_uuid'], None)
     self.assertEquals(volume['attached_host'], None)
     self.assertEquals(volume['mountpoint'], None)
     self.assertEquals(volume['attach_status'], 'detached')
     # cleanup
     svc.stop()
 def test_reset_status_as_non_admin(self):
     # current status is 'error'
     volume = db.volume_create(context.get_admin_context(),
                               {'status': 'error'})
     req = webob.Request.blank('/v2/fake/volumes/%s/action' % volume['id'])
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     # request changing status to available
     req.body = jsonutils.dumps({'os-reset_status': {'status':
                                                     'available'}})
     # non-admin context
     req.environ['cinder.context'] = context.RequestContext('fake', 'fake')
     resp = req.get_response(app())
     # request is not authorized
     self.assertEquals(resp.status_int, 403)
     volume = db.volume_get(context.get_admin_context(), volume['id'])
     # status is still 'error'
     self.assertEquals(volume['status'], 'error')
Beispiel #45
0
    def test_create(self):
        self.stubs.Set(db, 'volume_metadata_get', return_empty_volume_metadata)
        self.stubs.Set(db, 'volume_metadata_update',
                       return_create_volume_metadata)

        req = fakes.HTTPRequest.blank('/v2/volume_metadata')
        req.method = 'POST'
        req.content_type = "application/json"
        body = {
            "metadata": {
                "key1": "value1",
                "key2": "value2",
                "key3": "value3",
            }
        }
        req.body = jsonutils.dumps(body)
        res_dict = self.controller.create(req, self.req_id, body)
        self.assertEqual(body, res_dict)
Beispiel #46
0
 def test_malformed_reset_status_body(self):
     # admin context
     ctx = context.RequestContext('admin', 'fake', True)
     # current status is available
     volume = db.volume_create(ctx, {'status': 'available', 'size': 1})
     req = webob.Request.blank('/v2/fake/volumes/%s/action' % volume['id'])
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     # malformed request body
     req.body = jsonutils.dumps({'os-reset_status': {'x-status': 'bad'}})
     # attach admin context to request
     req.environ['cinder.context'] = ctx
     resp = req.get_response(app())
     # bad request
     self.assertEqual(resp.status_int, 400)
     volume = db.volume_get(ctx, volume['id'])
     # status is still 'available'
     self.assertEqual(volume['status'], 'available')
 def test_reset_status_for_missing_volume(self):
     # admin context
     ctx = context.RequestContext('admin', 'fake', True)
     # missing-volume-id
     req = webob.Request.blank('/v2/fake/volumes/%s/action' %
                               'missing-volume-id')
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     # malformed request body
     req.body = jsonutils.dumps({'os-reset_status': {'status':
                                                     'available'}})
     # attach admin context to request
     req.environ['cinder.context'] = ctx
     resp = req.get_response(app())
     # not found
     self.assertEquals(resp.status_int, 404)
     self.assertRaises(exception.NotFound, db.volume_get, ctx,
                       'missing-volume-id')
Beispiel #48
0
 def test_reset_status_as_admin(self):
     # admin context
     ctx = context.RequestContext('admin', 'fake', True)
     # current status is available
     volume = db.volume_create(ctx, {'status': 'available'})
     req = webob.Request.blank('/v2/fake/volumes/%s/action' % volume['id'])
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     # request status of 'error'
     req.body = jsonutils.dumps({'os-reset_status': {'status': 'error'}})
     # attach admin context to request
     req.environ['cinder.context'] = ctx
     resp = req.get_response(app())
     # request is accepted
     self.assertEqual(resp.status_int, 202)
     volume = db.volume_get(ctx, volume['id'])
     # status changed to 'error'
     self.assertEqual(volume['status'], 'error')
 def test_update_progress(self):
     ctx = context.RequestContext('admin', 'fake', True)
     # snapshot in 'error_deleting'
     volume = db.volume_create(ctx, {})
     snapshot = db.snapshot_create(ctx, {'volume_id': volume['id']})
     req = webob.Request.blank('/v2/fake/snapshots/%s/action' %
                               snapshot['id'])
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     # request status of 'error'
     req.body = jsonutils.dumps({'os-update_progress': 'progress!'})
     # attach admin context to request
     req.environ['cinder.context'] = ctx
     resp = req.get_response(app())
     # request is accepted
     self.assertEquals(resp.status_int, 202)
     snapshot = db.snapshot_get(ctx, snapshot['id'])
     # status changed to 'error'
     self.assertEquals(snapshot['progress'], 'progress!')
Beispiel #50
0
    def __init__(self, session, callback, node_name, node_opts, link_name,
                 link_opts):
        """Declare a queue on an amqp session.

        'session' is the amqp session to use
        'callback' is the callback to call when messages are received
        'node_name' is the first part of the Qpid address string, before ';'
        'node_opts' will be applied to the "x-declare" section of "node"
                    in the address string.
        'link_name' goes into the "name" field of the "link" in the address
                    string
        'link_opts' will be applied to the "x-declare" section of "link"
                    in the address string.
        """
        self.callback = callback
        self.receiver = None
        self.session = None

        addr_opts = {
            "create": "always",
            "node": {
                "type": "topic",
                "x-declare": {
                    "durable": True,
                    "auto-delete": True,
                },
            },
            "link": {
                "name": link_name,
                "durable": True,
                "x-declare": {
                    "durable": False,
                    "auto-delete": True,
                    "exclusive": False,
                },
            },
        }
        addr_opts["node"]["x-declare"].update(node_opts)
        addr_opts["link"]["x-declare"].update(link_opts)

        self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts))

        self.reconnect(session)
Beispiel #51
0
    def test_create_server_without_hints(self):
        @wsgi.response(202)
        def fake_create(*args, **kwargs):
            self.assertNotIn('scheduler_hints', kwargs['body'])
            return self.fake_instance

        self.stubs.Set(cinder.api.v2.volumes.VolumeController, 'create',
                       fake_create)

        req = fakes.HTTPRequest.blank('/v2/fake/volumes')
        req.method = 'POST'
        req.content_type = 'application/json'
        body = {
            'id': id,
            'volume_type_id': 'cedef40a-ed67-4d10-800e-17455edce175',
            'volume_id': '1',
        }
        req.body = jsonutils.dumps(body)
        res = req.get_response(self.app)
        self.assertEqual(202, res.status_int)
 def test_invalid_reset_attached_status(self):
     # admin context
     ctx = context.RequestContext('admin', 'fake', True)
     # current status is available
     volume = db.volume_create(ctx, {'status': 'available',
                                     'attach_status': 'detached'})
     req = webob.Request.blank('/v2/fake/volumes/%s/action' % volume['id'])
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     # 'invalid' is not a valid attach_status
     body = {'os-reset_status': {'status': 'available',
                                 'attach_status': 'invalid'}}
     req.body = jsonutils.dumps(body)
     # attach admin context to request
     req.environ['cinder.context'] = ctx
     resp = req.get_response(app())
     # bad request
     self.assertEquals(resp.status_int, 400)
     volume = db.volume_get(ctx, volume['id'])
     # status and attach_status un-modified
     self.assertEquals(volume['status'], 'available')
     self.assertEquals(volume['attach_status'], 'detached')
 def test_invalid_status_for_snapshot(self):
     # admin context
     ctx = context.RequestContext('admin', 'fake', True)
     # snapshot in 'available'
     volume = db.volume_create(ctx, {})
     snapshot = db.snapshot_create(ctx, {'status': 'available',
                                         'volume_id': volume['id']})
     req = webob.Request.blank('/v2/fake/snapshots/%s/action' %
                               snapshot['id'])
     req.method = 'POST'
     req.headers['content-type'] = 'application/json'
     # 'attaching' is not a valid status for snapshots
     req.body = jsonutils.dumps({'os-reset_status': {'status':
                                                     'attaching'}})
     # attach admin context to request
     req.environ['cinder.context'] = ctx
     resp = req.get_response(app())
     # request is accepted
     self.assertEquals(resp.status_int, 400)
     snapshot = db.snapshot_get(ctx, snapshot['id'])
     # status is still 'available'
     self.assertEquals(snapshot['status'], 'available')
    def test_create_with_keys_in_uppercase_and_lowercase(self):
        # if the keys in uppercase_and_lowercase, should return the one
        # which server added
        self.stubs.Set(cinder.db, 'snapshot_metadata_get',
                       return_empty_snapshot_metadata)
        self.stubs.Set(cinder.db, 'snapshot_metadata_update',
                       return_create_snapshot_metadata_insensitive)

        req = fakes.HTTPRequest.blank('/v1/snapshot_metadata')
        req.method = 'POST'
        req.content_type = "application/json"
        body = {"metadata": {"key1": "value1",
                             "KEY1": "value1",
                             "key2": "value2",
                             "KEY2": "value2",
                             "key3": "value3",
                             "KEY4": "value4"}}
        expected = {"metadata": {"key1": "value1",
                                 "key2": "value2",
                                 "key3": "value3",
                                 "KEY4": "value4"}}
        req.body = jsonutils.dumps(body)
        res_dict = self.controller.create(req, self.req_id, body)
        self.assertEqual(expected, res_dict)
Beispiel #55
0
 def test_put_metadata(self):
     metadata = {'version': 1}
     self.driver.put_metadata(self.volume_id, jsonutils.dumps(metadata))
Beispiel #56
0
 def test_put_invalid_version(self):
     container = jsonutils.dumps({'version': 2})
     self.assertRaises(exception.BackupMetadataUnsupportedVersion,
                       self.bak_meta_api.put, self.volume_id, container)
Beispiel #57
0
def _json_dumps(properties, attr):
    prop = properties[attr]
    if not isinstance(prop, basestring):
        properties[attr] = jsonutils.dumps(prop)
Beispiel #58
0
 def _request_data(self, verb, path):
     """Get data decribing a limit request verb/path."""
     return jsonutils.dumps({"verb": verb, "path": path})
Beispiel #59
0
 def esm_command(self, request):
     request['data'] = jsonutils.dumps(request['data'])
     return self.configure([request])
Beispiel #60
0
 def test_is_serializable(self):
     data = {'foo': 'bar'}
     if self.bak_meta_api._is_serializable(data):
         jsonutils.dumps(data)