Ejemplo n.º 1
0
    def manage_existing_snapshot(self, snapshot, driver_options):
        """Manage existing share snapshot with manila."""
        volID = self.private_storage.get(snapshot['share']['id'], 'volID')
        LOG.debug('volID: %s', volID)

        existing_share = self.api_executor.get_share_info(
            self.configuration.qnap_poolname, vol_no=volID)

        if existing_share is None:
            msg = _("The share id %s was not found on backend.") % volID
            LOG.error(msg)
            raise exception.ShareNotFound(msg)

        snapshot_id = snapshot.get('provider_location')
        snapshot_id_info = snapshot_id.split('@')

        if len(snapshot_id_info) == 2:
            share_name = snapshot_id_info[0]
            snapshot_name = snapshot_id_info[1]
        else:
            msg = _("Incorrect provider_location format. It should have the "
                    "following format: share_name@snapshot_name.")
            LOG.error(msg)
            raise exception.InvalidParameterValue(msg)

        if share_name != existing_share.find('vol_label').text:
            msg = (_("The assigned share %(share_name)s was not matched "
                     "%(vol_label)s on backend.") % {
                         'share_name': share_name,
                         'vol_label': existing_share.find('vol_label').text
                     })
            LOG.error(msg)
            raise exception.ShareNotFound(msg)

        check_snapshot = self.api_executor.get_snapshot_info(
            volID=volID, snapshot_name=snapshot_name)
        if check_snapshot is None:
            msg = (_("The snapshot %(snapshot_name)s was not "
                     "found on backend.") % {
                         'snapshot_name': snapshot_name
                     })
            LOG.error(msg)
            raise exception.InvalidParameterValue(err=msg)

        _metadata = {
            'snapshot_id': snapshot_id,
        }
        self.private_storage.update(snapshot['id'], _metadata)
        parent_size = check_snapshot.find('parent_size')
        snap_size_gb = None
        if parent_size is not None:
            snap_size_gb = math.ceil(float(parent_size.text) / units.Gi)
        return {'size': snap_size_gb}
Ejemplo n.º 2
0
    def _validate(self, filter_properties):
        context = filter_properties['context']
        hints = filter_properties.get('scheduler_hints')

        if hints is None:
            raise SchedulerHintsNotSet
        else:
            share_uuids = hints.get(self._filter_type)
            if share_uuids is None:
                raise SchedulerHintsNotSet

        share_uuids = share_uuids.split(",")

        filter_properties['scheduler_hints'][self._filter_type] = []

        filtered_hosts = []
        for uuid in share_uuids:
            try:
                share = self.share_api.get(context, uuid)
            except exception.NotFound:
                raise exception.ShareNotFound(uuid)
            instances = share.get('instances')
            if len(instances) == 0:
                raise exception.ShareInstanceNotFound(share_instance_id=uuid)
            filtered_hosts.append(
                [instance.get('host') for instance in instances])

        if self._filter_type == AFFINITY_FILTER:
            filter_properties['scheduler_hints'][self._filter_type] = list(
                set.intersection(*map(set, filtered_hosts)))
        else:
            filter_properties['scheduler_hints'][self._filter_type] = list(
                set.union(*map(set, filtered_hosts)))

        return filter_properties
Ejemplo n.º 3
0
    def ensure_share(self, context, share, share_server):
        """Ensure that the share is exported."""
        share_name = share['id']
        share_proto = share['share_proto']

        backend_share = self.client.get_share(share_name, share_proto)
        if not backend_share.existed:
            raise exception.ShareNotFound(share_id=share_name)
Ejemplo n.º 4
0
 def _fake_get(self, context, uuid):
     if uuid in fake_shares_1.keys():
         return fake_shares_1[uuid]
     if uuid in fake_shares_2.keys():
         return fake_shares_2[uuid]
     if uuid in fake_shares_3.keys():
         return fake_shares_3[uuid]
     raise exception.ShareNotFound(uuid)
Ejemplo n.º 5
0
    def _resize_share(self, share, new_size):
        share_id = share['id']
        quota = self._get_quota(share_id)
        if not quota:
            raise exception.ShareNotFound(reason="Share not found",
                                          share_id=share_id)

        requested_capacity = new_size * units.Gi
        self.vms_session.patch("quotas/{}".format(quota.id),
                               data=dict(hard_limit=requested_capacity))
Ejemplo n.º 6
0
    def _get_share_path_by_name(self,
                                server,
                                share_name,
                                ignore_missing=False):
        cmd = ('Get-SmbShare -Name %s -ErrorAction SilentlyContinue | '
               'Select-Object -ExpandProperty Path' % share_name)
        (share_path, err) = self._remote_exec(server, cmd)
        share_path = share_path.strip() if share_path else None

        if not share_path or ignore_missing:
            raise exception.ShareNotFound(share_id=share_name)

        return share_path
Ejemplo n.º 7
0
    def test_unmanage_share_not_found(self):
        self.mock_policy_check = self.mock_object(
            policy, 'check_policy', mock.Mock(return_value=True))
        self.mock_object(
            share_api.API, 'get', mock.Mock(
                side_effect=exception.ShareNotFound(share_id='fake')))
        snapshot = {'status': constants.STATUS_AVAILABLE, 'id': 'foo_id',
                    'share_id': 'bar_id'}
        self.mock_object(share_api.API, 'get_snapshot',
                         mock.Mock(return_value=snapshot))
        self.mock_object(share_api.API, 'unmanage_snapshot', mock.Mock())

        self.assertRaises(webob.exc.HTTPNotFound,
                          self.controller.unmanage,
                          self.unmanage_request, 'foo_id')
        self.mock_policy_check.assert_called_once_with(
            self.unmanage_request.environ['manila.context'],
            self.resource_name, 'unmanage_snapshot')
Ejemplo n.º 8
0
 def test_share_not_found(self):
     # verify response code for exception.ShareNotFound
     share_id = "fake_share_id"
     e = exception.ShareNotFound(share_id=share_id)
     self.assertEqual(404, e.code)
     self.assertIn(share_id, e.msg)
Ejemplo n.º 9
0
class ShareSnapshotAdminActionsAPITest(test.TestCase):

    def setUp(self):
        super(ShareSnapshotAdminActionsAPITest, self).setUp()
        self.controller = share_snapshots.ShareSnapshotsController()
        self.flags(transport_url='rabbit://*****:*****@mqhost:5672')
        self.admin_context = context.RequestContext('admin', 'fake', True)
        self.member_context = context.RequestContext('fake', 'fake')

        self.resource_name = self.controller.resource_name
        self.manage_request = fakes.HTTPRequest.blank(
            '/snapshots/manage', use_admin_context=True,
            version=MIN_MANAGE_SNAPSHOT_API_VERSION)
        self.snapshot_id = 'fake'
        self.unmanage_request = fakes.HTTPRequest.blank(
            '/snapshots/%s/unmanage' % self.snapshot_id,
            use_admin_context=True,
            version=MIN_MANAGE_SNAPSHOT_API_VERSION)

    def _get_context(self, role):
        return getattr(self, '%s_context' % role)

    def _setup_snapshot_data(self, snapshot=None, version='2.7'):
        if snapshot is None:
            share = db_utils.create_share()
            snapshot = db_utils.create_snapshot(
                status=constants.STATUS_AVAILABLE, share_id=share['id'])
        path = '/v2/fake/snapshots/%s/action' % snapshot['id']
        req = fakes.HTTPRequest.blank(path, script_name=path, version=version)
        return snapshot, req

    def _reset_status(self, ctxt, model, req, db_access_method,
                      valid_code, valid_status=None, body=None, version='2.7'):
        if float(version) > 2.6:
            action_name = 'reset_status'
        else:
            action_name = 'os-reset_status'
        if body is None:
            body = {action_name: {'status': constants.STATUS_ERROR}}
        req.method = 'POST'
        req.headers['content-type'] = 'application/json'
        req.headers['X-Openstack-Manila-Api-Version'] = version
        req.body = six.b(jsonutils.dumps(body))
        req.environ['manila.context'] = ctxt

        resp = req.get_response(fakes.app())

        # validate response code and model status
        self.assertEqual(valid_code, resp.status_int)

        actual_model = db_access_method(ctxt, model['id'])
        self.assertEqual(valid_status, actual_model['status'])

    @ddt.data(*fakes.fixture_reset_status_with_different_roles)
    @ddt.unpack
    def test_snapshot_reset_status_with_different_roles(self, role, valid_code,
                                                        valid_status, version):
        ctxt = self._get_context(role)
        snapshot, req = self._setup_snapshot_data(version=version)

        self._reset_status(ctxt, snapshot, req, db.share_snapshot_get,
                           valid_code, valid_status, version=version)

    @ddt.data(
        ({'os-reset_status': {'x-status': 'bad'}}, '2.6'),
        ({'reset_status': {'x-status': 'bad'}}, '2.7'),
        ({'os-reset_status': {'status': 'invalid'}}, '2.6'),
        ({'reset_status': {'status': 'invalid'}}, '2.7'),
    )
    @ddt.unpack
    def test_snapshot_invalid_reset_status_body(self, body, version):
        snapshot, req = self._setup_snapshot_data(version=version)

        self._reset_status(self.admin_context, snapshot, req,
                           db.share_snapshot_get, 400,
                           constants.STATUS_AVAILABLE, body, version=version)

    def _force_delete(self, ctxt, model, req, db_access_method, valid_code,
                      version='2.7'):
        if float(version) > 2.6:
            action_name = 'force_delete'
        else:
            action_name = 'os-force_delete'
        req.method = 'POST'
        req.headers['content-type'] = 'application/json'
        req.headers['X-Openstack-Manila-Api-Version'] = version
        req.body = six.b(jsonutils.dumps({action_name: {}}))
        req.environ['manila.context'] = ctxt

        resp = req.get_response(fakes.app())

        # Validate response
        self.assertEqual(valid_code, resp.status_int)

    @ddt.data(*fakes.fixture_force_delete_with_different_roles)
    @ddt.unpack
    def test_snapshot_force_delete_with_different_roles(self, role, resp_code,
                                                        version):
        ctxt = self._get_context(role)
        snapshot, req = self._setup_snapshot_data(version=version)

        self._force_delete(ctxt, snapshot, req, db.share_snapshot_get,
                           resp_code, version=version)

    def test_snapshot_force_delete_missing(self):
        ctxt = self._get_context('admin')
        snapshot, req = self._setup_snapshot_data(snapshot={'id': 'fake'})

        self._force_delete(ctxt, snapshot, req, db.share_snapshot_get, 404)

    @ddt.data(
        {},
        {'snapshots': {}},
        {'snapshot': get_fake_manage_body(share_id='xxxxxxxx')},
        {'snapshot': get_fake_manage_body(provider_location='xxxxxxxx')}
    )
    def test_snapshot_manage_invalid_body(self, body):
        self.mock_policy_check = self.mock_object(
            policy, 'check_policy', mock.Mock(return_value=True))
        self.assertRaises(webob.exc.HTTPUnprocessableEntity,
                          self.controller.manage,
                          self.manage_request,
                          body)
        self.mock_policy_check.assert_called_once_with(
            self.manage_request.environ['manila.context'],
            self.resource_name, 'manage_snapshot')

    @ddt.data(
        {'version': '2.12',
         'data': get_fake_manage_body(name='foo', display_description='bar')},
        {'version': '2.12',
         'data': get_fake_manage_body(display_name='foo', description='bar')},
        {'version': '2.17',
         'data': get_fake_manage_body(display_name='foo', description='bar')},
        {'version': '2.17',
         'data': get_fake_manage_body(name='foo', display_description='bar')},
    )
    @ddt.unpack
    def test_snapshot_manage(self, version, data):
        self.mock_policy_check = self.mock_object(
            policy, 'check_policy', mock.Mock(return_value=True))
        data['snapshot']['share_id'] = 'fake'
        data['snapshot']['provider_location'] = 'fake_volume_snapshot_id'
        data['snapshot']['driver_options'] = {}
        return_snapshot = fake_share.fake_snapshot(
            create_instance=True, id='fake_snap',
            provider_location='fake_volume_snapshot_id')
        self.mock_object(
            share_api.API, 'manage_snapshot', mock.Mock(
                return_value=return_snapshot))
        share_snapshot = {
            'share_id': 'fake',
            'provider_location': 'fake_volume_snapshot_id',
            'display_name': 'foo',
            'display_description': 'bar',
        }

        req = fakes.HTTPRequest.blank(
            '/snapshots/manage', use_admin_context=True, version=version)

        actual_result = self.controller.manage(req, data)

        actual_snapshot = actual_result['snapshot']
        share_api.API.manage_snapshot.assert_called_once_with(
            mock.ANY, share_snapshot, data['snapshot']['driver_options'])
        self.assertEqual(return_snapshot['id'],
                         actual_result['snapshot']['id'])
        self.assertEqual('fake_volume_snapshot_id',
                         actual_result['snapshot']['provider_location'])

        if (api_version.APIVersionRequest(version) >=
                api_version.APIVersionRequest('2.17')):
            self.assertEqual(return_snapshot['user_id'],
                             actual_snapshot['user_id'])
            self.assertEqual(return_snapshot['project_id'],
                             actual_snapshot['project_id'])
        else:
            self.assertNotIn('user_id', actual_snapshot)
            self.assertNotIn('project_id', actual_snapshot)
        self.mock_policy_check.assert_called_once_with(
            req.environ['manila.context'], self.resource_name,
            'manage_snapshot')

    @ddt.data(exception.ShareNotFound(share_id='fake'),
              exception.ShareSnapshotNotFound(snapshot_id='fake'),
              exception.ManageInvalidShareSnapshot(reason='error'),
              exception.InvalidShare(reason='error'))
    def test_manage_exception(self, exception_type):
        self.mock_policy_check = self.mock_object(
            policy, 'check_policy', mock.Mock(return_value=True))
        body = get_fake_manage_body(
            share_id='fake', provider_location='fake_volume_snapshot_id',
            driver_options={})
        self.mock_object(
            share_api.API, 'manage_snapshot', mock.Mock(
                side_effect=exception_type))

        http_ex = webob.exc.HTTPNotFound

        if (isinstance(exception_type, exception.ManageInvalidShareSnapshot)
                or isinstance(exception_type, exception.InvalidShare)):
            http_ex = webob.exc.HTTPConflict

        self.assertRaises(http_ex,
                          self.controller.manage,
                          self.manage_request, body)
        self.mock_policy_check.assert_called_once_with(
            self.manage_request.environ['manila.context'],
            self.resource_name, 'manage_snapshot')

    @ddt.data('1.0', '2.6', '2.11')
    def test_manage_version_not_found(self, version):
        body = get_fake_manage_body(
            share_id='fake', provider_location='fake_volume_snapshot_id',
            driver_options={})
        fake_req = fakes.HTTPRequest.blank(
            '/snapshots/manage', use_admin_context=True,
            version=version)

        self.assertRaises(exception.VersionNotFoundForAPIMethod,
                          self.controller.manage,
                          fake_req, body)

    def test_snapshot__unmanage(self):
        body = {}
        snapshot = {'status': constants.STATUS_AVAILABLE, 'id': 'bar_id',
                    'share_id': 'bar_id'}
        fake_req = fakes.HTTPRequest.blank(
            '/snapshots/unmanage',
            use_admin_context=True,
            version='2.49')
        mock_unmanage = self.mock_object(self.controller, '_unmanage')

        self.controller.unmanage(fake_req, snapshot['id'], body)

        mock_unmanage.assert_called_once_with(fake_req, snapshot['id'], body,
                                              allow_dhss_true=True)

    def test_snapshot_unmanage_share_server(self):
        self.mock_policy_check = self.mock_object(
            policy, 'check_policy', mock.Mock(return_value=True))
        share = {'status': constants.STATUS_AVAILABLE, 'id': 'bar_id',
                 'share_server_id': 'fake_server_id'}
        self.mock_object(share_api.API, 'get', mock.Mock(return_value=share))
        snapshot = {'status': constants.STATUS_AVAILABLE, 'id': 'foo_id',
                    'share_id': 'bar_id'}
        self.mock_object(share_api.API, 'get_snapshot',
                         mock.Mock(return_value=snapshot))

        self.assertRaises(webob.exc.HTTPForbidden,
                          self.controller.unmanage,
                          self.unmanage_request,
                          snapshot['id'])
        self.controller.share_api.get_snapshot.assert_called_once_with(
            self.unmanage_request.environ['manila.context'], snapshot['id'])
        self.controller.share_api.get.assert_called_once_with(
            self.unmanage_request.environ['manila.context'], share['id'])
        self.mock_policy_check.assert_called_once_with(
            self.unmanage_request.environ['manila.context'],
            self.resource_name, 'unmanage_snapshot')

    def test_snapshot_unmanage_replicated_snapshot(self):
        self.mock_policy_check = self.mock_object(
            policy, 'check_policy', mock.Mock(return_value=True))
        share = {'status': constants.STATUS_AVAILABLE, 'id': 'bar_id',
                 'has_replicas': True}
        self.mock_object(share_api.API, 'get', mock.Mock(return_value=share))
        snapshot = {'status': constants.STATUS_AVAILABLE, 'id': 'foo_id',
                    'share_id': 'bar_id'}
        self.mock_object(share_api.API, 'get_snapshot',
                         mock.Mock(return_value=snapshot))

        self.assertRaises(webob.exc.HTTPConflict,
                          self.controller.unmanage,
                          self.unmanage_request,
                          snapshot['id'])
        self.controller.share_api.get_snapshot.assert_called_once_with(
            self.unmanage_request.environ['manila.context'], snapshot['id'])
        self.controller.share_api.get.assert_called_once_with(
            self.unmanage_request.environ['manila.context'], share['id'])
        self.mock_policy_check.assert_called_once_with(
            self.unmanage_request.environ['manila.context'],
            self.resource_name, 'unmanage_snapshot')

    @ddt.data(*constants.TRANSITIONAL_STATUSES)
    def test_snapshot_unmanage_with_transitional_state(self, status):
        self.mock_policy_check = self.mock_object(
            policy, 'check_policy', mock.Mock(return_value=True))
        share = {'status': constants.STATUS_AVAILABLE, 'id': 'bar_id'}
        self.mock_object(share_api.API, 'get', mock.Mock(return_value=share))
        snapshot = {'status': status, 'id': 'foo_id', 'share_id': 'bar_id'}
        self.mock_object(
            self.controller.share_api, 'get_snapshot',
            mock.Mock(return_value=snapshot))
        self.assertRaises(
            webob.exc.HTTPForbidden,
            self.controller.unmanage, self.unmanage_request, snapshot['id'])

        self.controller.share_api.get_snapshot.assert_called_once_with(
            self.unmanage_request.environ['manila.context'], snapshot['id'])
        self.controller.share_api.get.assert_called_once_with(
            self.unmanage_request.environ['manila.context'], share['id'])
        self.mock_policy_check.assert_called_once_with(
            self.unmanage_request.environ['manila.context'],
            self.resource_name, 'unmanage_snapshot')

    def test_snapshot_unmanage(self):
        self.mock_policy_check = self.mock_object(
            policy, 'check_policy', mock.Mock(return_value=True))
        share = {'status': constants.STATUS_AVAILABLE, 'id': 'bar_id',
                 'host': 'fake_host'}
        self.mock_object(share_api.API, 'get', mock.Mock(return_value=share))
        snapshot = {'status': constants.STATUS_AVAILABLE, 'id': 'foo_id',
                    'share_id': 'bar_id'}
        self.mock_object(share_api.API, 'get_snapshot',
                         mock.Mock(return_value=snapshot))
        self.mock_object(share_api.API, 'unmanage_snapshot', mock.Mock())

        actual_result = self.controller.unmanage(self.unmanage_request,
                                                 snapshot['id'])

        self.assertEqual(202, actual_result.status_int)
        self.controller.share_api.get_snapshot.assert_called_once_with(
            self.unmanage_request.environ['manila.context'], snapshot['id'])
        share_api.API.unmanage_snapshot.assert_called_once_with(
            mock.ANY, snapshot, 'fake_host')
        self.mock_policy_check.assert_called_once_with(
            self.unmanage_request.environ['manila.context'],
            self.resource_name, 'unmanage_snapshot')

    def test_unmanage_share_not_found(self):
        self.mock_policy_check = self.mock_object(
            policy, 'check_policy', mock.Mock(return_value=True))
        self.mock_object(
            share_api.API, 'get', mock.Mock(
                side_effect=exception.ShareNotFound(share_id='fake')))
        snapshot = {'status': constants.STATUS_AVAILABLE, 'id': 'foo_id',
                    'share_id': 'bar_id'}
        self.mock_object(share_api.API, 'get_snapshot',
                         mock.Mock(return_value=snapshot))
        self.mock_object(share_api.API, 'unmanage_snapshot', mock.Mock())

        self.assertRaises(webob.exc.HTTPNotFound,
                          self.controller.unmanage,
                          self.unmanage_request, 'foo_id')
        self.mock_policy_check.assert_called_once_with(
            self.unmanage_request.environ['manila.context'],
            self.resource_name, 'unmanage_snapshot')

    def test_unmanage_snapshot_not_found(self):
        self.mock_policy_check = self.mock_object(
            policy, 'check_policy', mock.Mock(return_value=True))
        share = {'status': constants.STATUS_AVAILABLE, 'id': 'bar_id'}
        self.mock_object(share_api.API, 'get', mock.Mock(return_value=share))
        self.mock_object(
            share_api.API, 'get_snapshot', mock.Mock(
                side_effect=exception.ShareSnapshotNotFound(
                    snapshot_id='foo_id')))
        self.mock_object(share_api.API, 'unmanage_snapshot', mock.Mock())

        self.assertRaises(webob.exc.HTTPNotFound,
                          self.controller.unmanage,
                          self.unmanage_request, 'foo_id')
        self.mock_policy_check.assert_called_once_with(
            self.unmanage_request.environ['manila.context'],
            self.resource_name, 'unmanage_snapshot')

    @ddt.data('1.0', '2.6', '2.11')
    def test_unmanage_version_not_found(self, version):
        snapshot_id = 'fake'
        fake_req = fakes.HTTPRequest.blank(
            '/snapshots/%s/unmanage' % snapshot_id,
            use_admin_context=True,
            version=version)

        self.assertRaises(exception.VersionNotFoundForAPIMethod,
                          self.controller.unmanage,
                          fake_req, 'fake')

    def test_snapshot_unmanage_dhss_true_with_share_server(self):
        self.mock_policy_check = self.mock_object(
            policy, 'check_policy', mock.Mock(return_value=True))
        share = {'status': constants.STATUS_AVAILABLE, 'id': 'bar_id',
                 'host': 'fake_host',
                 'share_server_id': 'fake'}
        mock_get = self.mock_object(share_api.API, 'get',
                                    mock.Mock(return_value=share))
        snapshot = {'status': constants.STATUS_AVAILABLE, 'id': 'bar_id',
                    'share_id': 'bar_id'}
        self.mock_object(share_api.API, 'get_snapshot',
                         mock.Mock(return_value=snapshot))
        self.mock_object(share_api.API, 'unmanage_snapshot')

        actual_result = self.controller._unmanage(self.unmanage_request,
                                                  snapshot['id'],
                                                  allow_dhss_true=True)

        self.assertEqual(202, actual_result.status_int)
        self.controller.share_api.get_snapshot.assert_called_once_with(
            self.unmanage_request.environ['manila.context'], snapshot['id'])
        share_api.API.unmanage_snapshot.assert_called_once_with(
            mock.ANY, snapshot, 'fake_host')
        mock_get.assert_called_once_with(
            self.unmanage_request.environ['manila.context'], snapshot['id']
        )
        self.mock_policy_check.assert_called_once_with(
            self.unmanage_request.environ['manila.context'],
            self.resource_name, 'unmanage_snapshot')