Example #1
0
    def test_get_pod_service_ctx(self):
        pod_dict = {
            'pod_id': 'fake_pod_id',
            'pod_name': 'fake_pod_name',
            'az_name': 'fake_az'
        }

        config_dict = {
            'service_id': 'fake_service_id',
            'pod_id': 'fake_pod_id',
            'service_type': cons.ST_CINDER,
            'service_url': 'http://127.0.0.1:8774/v2.1/$(tenant_id)s'
        }
        t_url = 'http://127.0.0.1:8774/v2/my_tenant_id/volumes'
        api.create_pod(self.context, pod_dict)
        api.create_pod_service_configuration(self.context, config_dict)

        b_url = 'http://127.0.0.1:8774/v2.1/my_tenant_id/volumes'

        b_endpoint = hclient.get_pod_service_endpoint(self.context,
                                                      pod_dict['pod_name'],
                                                      cons.ST_CINDER)
        self.assertEqual(b_endpoint, config_dict['service_url'])

        b_ctx = hclient.get_pod_service_ctx(self.context, t_url,
                                            pod_dict['pod_name'],
                                            cons.ST_CINDER)
        self.assertEqual(b_ctx['t_ver'], 'v2')
        self.assertEqual(b_ctx['t_url'], t_url)
        self.assertEqual(b_ctx['b_ver'], 'v2.1')
        self.assertEqual(b_ctx['b_url'], b_url)

        # wrong pod name
        b_ctx = hclient.get_pod_service_ctx(self.context, t_url,
                                            pod_dict['pod_name'] + '1',
                                            cons.ST_CINDER)
        self.assertEqual(b_ctx['t_ver'], 'v2')
        self.assertEqual(b_ctx['t_url'], t_url)
        self.assertEqual(b_ctx['b_ver'], '')
        self.assertEqual(b_ctx['b_url'], '')

        # wrong service_type
        b_ctx = hclient.get_pod_service_ctx(self.context, t_url,
                                            pod_dict['pod_name'],
                                            cons.ST_CINDER + '1')
        self.assertEqual(b_ctx['t_ver'], 'v2')
        self.assertEqual(b_ctx['t_url'], t_url)
        self.assertEqual(b_ctx['b_ver'], '')
        self.assertEqual(b_ctx['b_url'], '')
Example #2
0
    def _get_all(self, context):

        # TODO(joehuang): query optimization for pagination, sort, etc
        ret = {}
        ret['volumes'] = []

        pods = az_ag.list_pods_by_tenant(context, self.tenant_id)
        for pod in pods:
            if pod['pod_name'] == '':
                continue

            query = urlparse.urlsplit(request.url).query
            query_filters = urlparse.parse_qsl(query)
            skip_pod = False
            for k, v in query_filters:
                if k == 'availability_zone' and v != pod['az_name']:
                    skip_pod = True
                    break
            if skip_pod:
                continue

            s_ctx = hclient.get_pod_service_ctx(context,
                                                request.url,
                                                pod['pod_name'],
                                                s_type=cons.ST_CINDER)
            if s_ctx['b_url'] == '':
                LOG.error(
                    _LE("bottom pod endpoint incorrect %s") % pod['pod_name'])
                continue

            # TODO(joehuang): get the release of top and bottom
            t_release = cons.R_MITAKA
            b_release = cons.R_MITAKA
            b_headers = hclient.convert_header(t_release, b_release,
                                               request.headers)

            resp = hclient.forward_req(context, 'GET', b_headers,
                                       s_ctx['b_url'], request.body)

            if resp.status_code == 200:

                routings = db_api.get_bottom_mappings_by_tenant_pod(
                    context, self.tenant_id, pod['pod_id'], cons.RT_VOLUME)

                b_ret_body = jsonutils.loads(resp.content)
                if b_ret_body.get('volumes'):
                    for vol in b_ret_body['volumes']:

                        if not routings.get(vol['id']):
                            b_ret_body['volumes'].remove(vol)
                            continue

                        vol['availability_zone'] = pod['az_name']

                    ret['volumes'].extend(b_ret_body['volumes'])

                if b_ret_body.get('volumes_links'):
                    ret['volumes_links'] = b_ret_body['volumes_links']
        return ret
Example #3
0
    def post(self, **kw):
        context = t_context.extract_context_from_environ()

        if 'volume' not in kw:
            return utils.format_cinder_error(
                400, _("Missing required element 'volume' in request body."))

        az = kw['volume'].get('availability_zone', '')
        pod, pod_az = az_ag.get_pod_by_az_tenant(context,
                                                 az_name=az,
                                                 tenant_id=self.tenant_id)
        if not pod:
            LOG.error(_LE("Pod not configured or scheduling failure"))
            return utils.format_cinder_error(
                500, _('Pod not configured or scheduling failure'))

        t_pod = db_api.get_top_pod(context)
        if not t_pod:
            LOG.error(_LE("Top Pod not configured"))
            return utils.format_cinder_error(500, _('Top Pod not configured'))

        # TODO(joehuang): get release from pod configuration,
        # to convert the content
        # b_release = pod['release']
        # t_release = t_pod['release']
        t_release = cons.R_MITAKA
        b_release = cons.R_MITAKA

        s_ctx = hclient.get_pod_service_ctx(context,
                                            request.url,
                                            pod['pod_name'],
                                            s_type=cons.ST_CINDER)

        if s_ctx['b_url'] == '':
            LOG.error(
                _LE("Bottom Pod endpoint incorrect %s") % pod['pod_name'])
            return utils.format_cinder_error(
                500, _('Bottom Pod endpoint incorrect'))

        b_headers = hclient.convert_header(t_release, b_release,
                                           request.headers)

        t_vol = kw['volume']

        # add or remove key-value in the request for diff. version
        b_vol_req = hclient.convert_object(t_release,
                                           b_release,
                                           t_vol,
                                           res_type=cons.RT_VOLUME)

        # convert az to the configured one
        # remove the AZ parameter to bottom request for default one
        b_vol_req['availability_zone'] = pod['pod_az_name']
        if b_vol_req['availability_zone'] == '':
            b_vol_req.pop("availability_zone", None)

        b_body = jsonutils.dumps({'volume': b_vol_req})

        resp = hclient.forward_req(context, 'POST', b_headers, s_ctx['b_url'],
                                   b_body)
        b_status = resp.status_code
        b_ret_body = jsonutils.loads(resp.content)

        # build routing and convert response from the bottom pod
        # for different version.
        response.status = b_status
        if b_status == 202:
            if b_ret_body.get('volume') is not None:
                b_vol_ret = b_ret_body['volume']

                try:
                    with context.session.begin():
                        core.create_resource(
                            context, models.ResourceRouting, {
                                'top_id': b_vol_ret['id'],
                                'bottom_id': b_vol_ret['id'],
                                'pod_id': pod['pod_id'],
                                'project_id': self.tenant_id,
                                'resource_type': cons.RT_VOLUME
                            })
                except Exception as e:
                    LOG.exception(
                        _LE('Failed to create volume '
                            'resource routing'
                            'top_id: %(top_id)s ,'
                            'bottom_id: %(bottom_id)s ,'
                            'pod_id: %(pod_id)s ,'
                            '%(exception)s '), {
                                'top_id': b_vol_ret['id'],
                                'bottom_id': b_vol_ret['id'],
                                'pod_id': pod['pod_id'],
                                'exception': e
                            })
                    return utils.format_cinder_error(
                        500, _('Failed to create volume resource routing'))

                ret_vol = hclient.convert_object(b_release,
                                                 t_release,
                                                 b_vol_ret,
                                                 res_type=cons.RT_VOLUME)

                ret_vol['availability_zone'] = pod['az_name']

                return {'volume': ret_vol}

        return b_ret_body
Example #4
0
    def post(self, **kw):
        """Create volume metadata associated with a volume.

        :param kw: dictionary of values to be created
        :returns: created volume metadata
        """
        context = t_context.extract_context_from_environ()

        if 'metadata' not in kw:
            return utils.format_cinder_error(
                400, _("Missing required element 'metadata' in "
                       "request body."))

        try:
            pod = utils.get_pod_by_top_id(context, self.volume_id)
            if pod is None:
                return utils.format_cinder_error(
                    404, _('Volume %(volume_id)s could not be found.') % {
                        'volume_id': self.volume_id
                    })

            t_pod = db_api.get_top_pod(context)
            if not t_pod:
                LOG.error(_LE("Top Pod not configured"))
                return utils.format_cinder_error(
                    500, _('Top Pod not configured'))
        except Exception as e:
            LOG.exception(_LE('Fail to create metadata for a volume:'
                              '%(volume_id)s'
                              '%(exception)s'),
                          {'volume_id': self.volume_id,
                           'exception': e})
            return utils.format_cinder_error(500, _('Fail to create metadata'))

        t_release = cons.R_MITAKA
        b_release = cons.R_MITAKA

        s_ctx = hclient.get_pod_service_ctx(
            context,
            request.url,
            pod['pod_name'],
            s_type=cons.ST_CINDER)

        if s_ctx['b_url'] == '':
            LOG.error(_LE("Bottom pod endpoint incorrect %s") %
                      pod['pod_name'])
            return utils.format_cinder_error(
                500, _('Bottom pod endpoint incorrect'))

        b_headers = hclient.convert_header(t_release, b_release,
                                           request.headers)

        t_metadata = kw['metadata']

        # add or remove key-value in the request for diff. version
        b_vol_req = hclient.convert_object(t_release, b_release, t_metadata,
                                           res_type=cons.RT_VOl_METADATA)

        b_body = jsonutils.dumps({'metadata': b_vol_req})

        resp = hclient.forward_req(
            context,
            'POST',
            b_headers,
            s_ctx['b_url'],
            b_body)
        b_status = resp.status_code
        b_body_ret = jsonutils.loads(resp.content)

        # convert response from the bottom pod
        # for different version.
        response.status = b_status
        if b_status == 200:
            if b_body_ret.get('metadata') is not None:
                b_metadata_ret = b_body_ret['metadata']

                vol_ret = hclient.convert_object(b_release, t_release,
                                                 b_metadata_ret,
                                                 res_type=cons.
                                                 RT_VOl_METADATA)

                return {'metadata': vol_ret}

        return b_body_ret