コード例 #1
0
ファイル: test_az_ag.py プロジェクト: paperandsoap/tricircle
    def test_list_pods_by_tenant(self):

        pod1, _ = az_ag.get_pod_by_az_tenant(self.context,
                                             FAKE_AZ + FAKE_AZ,
                                             FAKE_TENANT_ID)
        pods = az_ag.list_pods_by_tenant(self.context, FAKE_TENANT_ID)
        self.assertEqual(pod1, None)
        self.assertEqual(len(pods), 0)

        # TODO(joehuang): tenant bound to multiple pods in one AZ

        # schedule one
        pod2, _ = az_ag.get_pod_by_az_tenant(self.context,
                                             FAKE_AZ,
                                             FAKE_TENANT_ID)
        pods = az_ag.list_pods_by_tenant(self.context, FAKE_TENANT_ID)
        self.assertDictEqual(pods[0], pod2)
コード例 #2
0
    def test_get_pod_by_az_tenant(self):

        pod1, _ = az_ag.get_pod_by_az_tenant(self.context,
                                             FAKE_AZ + FAKE_AZ,
                                             FAKE_TENANT_ID)
        self.assertIsNone(pod1)
        pods = az_ag.list_pods_by_tenant(self.context, FAKE_TENANT_ID)
        self.assertEqual(len(pods), 0)

        # schedule one
        pod2, _ = az_ag.get_pod_by_az_tenant(self.context,
                                             FAKE_AZ,
                                             FAKE_TENANT_ID)

        pod_bindings = core.query_resource(self.context,
                                           models.PodBinding,
                                           [{'key': 'tenant_id',
                                             'comparator': 'eq',
                                             'value': FAKE_TENANT_ID}],
                                           [])
        self.assertIsNotNone(pod_bindings)
        if pod_bindings[0]['pod_id'] == FAKE_SITE_ID:
            self.assertEqual(pod2['pod_name'], FAKE_SITE_NAME)
            self.assertEqual(pod2['pod_id'], FAKE_SITE_ID)
            self.assertEqual(pod2['az_name'], FAKE_AZ)

        else:
            self.assertEqual(pod2['pod_name'], FAKE_SITE_NAME_2)
            self.assertEqual(pod2['pod_id'], FAKE_SITE_ID_2)
            self.assertEqual(pod2['az_name'], FAKE_AZ)

        # scheduled one should always be bound
        pod3, _ = az_ag.get_pod_by_az_tenant(self.context,
                                             FAKE_AZ,
                                             FAKE_TENANT_ID)

        self.assertEqual(pod2['pod_name'], pod3['pod_name'])
        self.assertEqual(pod2['pod_id'], pod3['pod_id'])
        self.assertEqual(pod2['az_name'], pod3['az_name'])
コード例 #3
0
ファイル: test_az_ag.py プロジェクト: paperandsoap/tricircle
    def test_get_pod_by_az_tenant(self):

        pod1, _ = az_ag.get_pod_by_az_tenant(self.context,
                                             FAKE_AZ + FAKE_AZ,
                                             FAKE_TENANT_ID)
        self.assertEqual(pod1, None)
        pods = az_ag.list_pods_by_tenant(self.context, FAKE_TENANT_ID)
        self.assertEqual(len(pods), 0)

        # schedule one
        pod2, _ = az_ag.get_pod_by_az_tenant(self.context,
                                             FAKE_AZ,
                                             FAKE_TENANT_ID)

        pod_bindings = core.query_resource(self.context,
                                           models.PodBinding,
                                           [{'key': 'tenant_id',
                                             'comparator': 'eq',
                                             'value': FAKE_TENANT_ID}],
                                           [])
        self.assertIsNotNone(pod_bindings)
        if pod_bindings[0]['pod_id'] == FAKE_SITE_ID:
            self.assertEqual(pod2['pod_name'], FAKE_SITE_NAME)
            self.assertEqual(pod2['pod_id'], FAKE_SITE_ID)
            self.assertEqual(pod2['az_name'], FAKE_AZ)
        else:
            self.assertEqual(pod2['pod_name'], FAKE_SITE_NAME_2)
            self.assertEqual(pod2['pod_id'], FAKE_SITE_ID_2)
            self.assertEqual(pod2['az_name'], FAKE_AZ)

        # scheduled one should always be bound
        pod3, _ = az_ag.get_pod_by_az_tenant(self.context,
                                             FAKE_AZ,
                                             FAKE_TENANT_ID)

        self.assertEqual(pod2['pod_name'], pod3['pod_name'])
        self.assertEqual(pod2['pod_id'], pod3['pod_id'])
        self.assertEqual(pod2['az_name'], pod3['az_name'])
コード例 #4
0
    def post(self, **kw):
        context = t_context.extract_context_from_environ()

        if 'server' not in kw:
            pecan.abort(400, 'Request body not found')
            return

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

        pod, b_az = az_ag.get_pod_by_az_tenant(
            context, kw['server']['availability_zone'], self.project_id)
        if not pod:
            pecan.abort(400, 'No pod bound to availability zone')
            return

        t_server_dict = kw['server']
        self._process_metadata_quota(context, t_server_dict)
        self._process_injected_file_quota(context, t_server_dict)

        server_body = self._get_create_server_body(kw['server'], b_az)

        top_client = self._get_client()

        sg_filters = [{'key': 'tenant_id', 'comparator': 'eq',
                       'value': self.project_id}]
        top_sgs = top_client.list_security_groups(context, sg_filters)
        top_sg_map = dict((sg['name'], sg) for sg in top_sgs)

        if 'security_groups' not in kw['server']:
            security_groups = ['default']
        else:
            security_groups = []
            for sg in kw['server']['security_groups']:
                if 'name' not in sg:
                    pecan.abort(404, 'Security group name not specified')
                    return
                if sg['name'] not in top_sg_map:
                    pecan.abort(404,
                                'Security group %s not found' % sg['name'])
                    return
                security_groups.append(sg['name'])
        t_sg_ids, b_sg_ids, is_news = self._handle_security_group(
            context, pod, top_sg_map, security_groups)

        if 'networks' in kw['server']:
            server_body['networks'] = []
            for net_info in kw['server']['networks']:
                if 'uuid' in net_info:
                    network = top_client.get_networks(context,
                                                      net_info['uuid'])
                    if not network:
                        pecan.abort(400, 'Network not found')
                        return

                    if not self._check_network_server_the_same_az(
                            network, kw['server']['availability_zone']):
                        pecan.abort(400, 'Network and server not in the same '
                                         'availability zone')
                        return

                    subnets = top_client.list_subnets(
                        context, [{'key': 'network_id',
                                   'comparator': 'eq',
                                   'value': network['id']}])
                    if not subnets:
                        pecan.abort(400, 'Network not contain subnets')
                        return
                    t_port_id, b_port_id = self._handle_network(
                        context, pod, network, subnets,
                        top_sg_ids=t_sg_ids, bottom_sg_ids=b_sg_ids)
                elif 'port' in net_info:
                    port = top_client.get_ports(context, net_info['port'])
                    if not port:
                        pecan.abort(400, 'Port not found')
                        return
                    t_port_id, b_port_id = self._handle_port(
                        context, pod, port)
                server_body['networks'].append({'port': b_port_id})

        # only for security group first created in a pod, we invoke
        # _handle_sg_rule_for_new_group to initialize rules in that group, this
        # method removes all the rules in the new group then add new rules
        top_sg_id_map = dict((sg['id'], sg) for sg in top_sgs)
        new_top_sgs = []
        new_bottom_sg_ids = []
        default_sg = None
        for t_id, b_id, is_new in zip(t_sg_ids, b_sg_ids, is_news):
            sg_name = top_sg_id_map[t_id]['name']
            if sg_name == 'default':
                default_sg = top_sg_id_map[t_id]
                continue
            if not is_new:
                continue
            new_top_sgs.append(top_sg_id_map[t_id])
            new_bottom_sg_ids.append(b_id)
        self._handle_sg_rule_for_new_group(context, pod, new_top_sgs,
                                           new_bottom_sg_ids)
        if default_sg:
            self._handle_sg_rule_for_default_group(
                context, pod, default_sg, self.project_id)

        client = self._get_client(pod['pod_name'])
        nics = [
            {'port-id': _port['port']} for _port in server_body['networks']]

        server = client.create_servers(context,
                                       name=server_body['name'],
                                       image=server_body['imageRef'],
                                       flavor=server_body['flavorRef'],
                                       nics=nics,
                                       security_groups=b_sg_ids)
        with context.session.begin():
            core.create_resource(context, models.ResourceRouting,
                                 {'top_id': server['id'],
                                  'bottom_id': server['id'],
                                  'pod_id': pod['pod_id'],
                                  'project_id': self.project_id,
                                  'resource_type': constants.RT_SERVER})
        pecan.response.status = 202
        return {'server': server}
コード例 #5
0
ファイル: volume.py プロジェクト: paperandsoap/tricircle
    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}
コード例 #6
0
ファイル: volume.py プロジェクト: Ronghui/tricircle
    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}
コード例 #7
0
ファイル: server.py プロジェクト: shipengfei92/tricircle
    def post(self, **kw):
        context = t_context.extract_context_from_environ()

        if 'server' not in kw:
            pecan.abort(400, 'Request body not found')
            return

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

        pod, b_az = az_ag.get_pod_by_az_tenant(
            context, kw['server']['availability_zone'], self.project_id)
        if not pod:
            pecan.abort(400, 'No pod bound to availability zone')
            return

        server_body = self._get_create_server_body(kw['server'], b_az)

        top_client = self._get_client()
        if 'networks' in kw['server']:
            server_body['networks'] = []
            for net_info in kw['server']['networks']:
                if 'uuid' in net_info:
                    network = top_client.get_networks(context,
                                                      net_info['uuid'])
                    if not network:
                        pecan.abort(400, 'Network not found')
                        return
                    subnets = top_client.list_subnets(
                        context, [{'key': 'network_id',
                                   'comparator': 'eq',
                                   'value': network['id']}])
                    if not subnets:
                        pecan.abort(400, 'Network not contain subnets')
                        return
                    bottom_port_id = self._handle_network(context, pod,
                                                          network, subnets)
                elif 'port' in net_info:
                    port = top_client.get_ports(context, net_info['port'])
                    if not port:
                        pecan.abort(400, 'Port not found')
                        return
                    bottom_port_id = self._handle_port(context, pod, port)
                server_body['networks'].append({'port': bottom_port_id})

        client = self._get_client(pod['pod_name'])
        nics = [
            {'port-id': _port['port']} for _port in server_body['networks']]
        server = client.create_servers(context,
                                       name=server_body['name'],
                                       image=server_body['imageRef'],
                                       flavor=server_body['flavorRef'],
                                       nics=nics)
        with context.session.begin():
            core.create_resource(context, models.ResourceRouting,
                                 {'top_id': server['id'],
                                  'bottom_id': server['id'],
                                  'pod_id': pod['pod_id'],
                                  'project_id': self.project_id,
                                  'resource_type': constants.RT_SERVER})
        return {'server': server}