Beispiel #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'], '')
Beispiel #2
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'], '')
Beispiel #3
0
    def test_get_pod_service_ctx(self):
        pod_dict = {
            'pod_id': 'fake_pod_id',
            'region_name': 'fake_region_name',
            'az_name': 'fake_az'
        }

        config_dict = {
            'service_id': 'fake_service_id',
            'pod_id': 'fake_pod_id',
            'service_type': cons.ST_NEUTRON,
            'service_url': 'http://127.0.0.1:9696/v2.0/networks'
        }
        t_url = 'http://127.0.0.1:9696/v2.0/networks'
        api.create_pod(self.context, pod_dict)
        api.create_cached_endpoints(self.context, config_dict)

        b_url = 'http://127.0.0.1:9696/v2.0/networks'

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

        b_ctx = hclient.get_pod_service_ctx(self.context, t_url,
                                            pod_dict['region_name'],
                                            cons.ST_NEUTRON)
        self.assertEqual(b_ctx['t_ver'], 'v2.0')
        self.assertEqual(b_ctx['t_url'], t_url)
        self.assertEqual(b_ctx['b_ver'], 'v2.0')
        self.assertEqual(b_ctx['b_url'], b_url)

        # wrong pod name
        b_ctx = hclient.get_pod_service_ctx(self.context, t_url,
                                            pod_dict['region_name'] + '1',
                                            cons.ST_NEUTRON)
        self.assertEqual(b_ctx['t_ver'], 'v2.0')
        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['region_name'],
                                            cons.ST_NEUTRON + '1')
        self.assertEqual(b_ctx['t_ver'], 'v2.0')
        self.assertEqual(b_ctx['t_url'], t_url)
        self.assertEqual(b_ctx['b_ver'], '')
        self.assertEqual(b_ctx['b_url'], '')
Beispiel #4
0
    def _get_all(self, context):

        # TODO(joehuang): query optimization for pagination, sort, etc
        ret = []
        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): convert header and body content
            resp = hclient.forward_req(context, 'GET',
                                       request.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.extend(b_ret_body['volumes'])
        return ret
Beispiel #5
0
    def _get_all(self, context):

        # TODO(joehuang): query optimization for pagination, sort, etc
        ret = []
        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.extend(b_ret_body['volumes'])
        return ret
Beispiel #6
0
    def _get_res_routing_ref(self, context, _id, t_url):

        pod = self._get_pod_by_top_id(context, _id)

        if not pod:
            return None

        pod_name = pod['pod_name']

        s_ctx = hclient.get_pod_service_ctx(context,
                                            t_url,
                                            pod_name,
                                            s_type=cons.ST_CINDER)

        if s_ctx['b_url'] == '':
            LOG.error(_LE("bottom pod endpoint incorrect %s") % pod_name)

        return s_ctx
Beispiel #7
0
    def _get_res_routing_ref(self, context, _id, t_url):

        pod = self._get_pod_by_top_id(context, _id)

        if not pod:
            return None

        pod_name = pod['pod_name']

        s_ctx = hclient.get_pod_service_ctx(
            context,
            t_url,
            pod_name,
            s_type=cons.ST_CINDER)

        if s_ctx['b_url'] == '':
            LOG.error(_LE("bottom pod endpoint incorrect %s") %
                      pod_name)

        return s_ctx
Beispiel #8
0
    def post(self, **kw):
        context = t_context.extract_context_from_environ()

        if 'volume' not in kw:
            pecan.abort(400, _('Volume not found in request body'))
            return

        if 'availability_zone' not in kw['volume']:
            pecan.abort(400, _('Availability zone not set in request'))
            return

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

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

        # 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'] == '':
            pecan.abort(500, _('bottom pod endpoint incorrect'))
            LOG.error(
                _LE("bottom pod endpoint incorrect %s") % pod['pod_name'])
            return

        b_headers = self._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 = self._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 Response(
                        _('Failed to create volume '
                          'resource routing'), 500)

                ret_vol = self._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 {'error': b_ret_body}
Beispiel #9
0
    def post(self, **kw):
        context = t_context.extract_context_from_environ()

        if 'volume' not in kw:
            pecan.abort(400, _('Volume not found in request body'))
            return

        if 'availability_zone' not in kw['volume']:
            pecan.abort(400, _('Availability zone not set in request'))
            return

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

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

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

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

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

        b_headers = self._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 = self._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.error(_LE('Fail to create volume: %(exception)s'),
                              {'exception': e})
                    return Response(_('Failed to create volume'), 500)

                ret_vol = self._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 {'error': b_ret_body}
Beispiel #10
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