示例#1
0
    def init_region_tenant(self, tenant, region):
        """
        为团队初始化所在数据中心数据,如果tenant_region存在记录,且未初始化,将记录更新
        :param tenant:
        :param region:
        :return: 成功返回True,失败返回False
        """
        logger.debug("init region tenant...")
        success = True
        tenant_region = self.get_tenant_region_info(tenant, region)
        if not tenant_region:
            tenant_region = TenantRegionInfo()
            tenant_region.tenant_id = tenant.tenant_id
            tenant_region.region_name = region
            tenant_region.save()
        if not tenant_region.is_init:
            api = RegionInvokeApi()
            logger.debug(
                "create tenant {0} with tenant_id {1} on region {2}".format(
                    tenant.tenant_name, tenant.tenant_id, region))
            logger.info("start invoking api to init region tenant !")
            try:
                res, body = api.create_tenant(region, tenant.tenant_name,
                                              tenant.tenant_id,
                                              tenant.enterprise_id)
                logger.debug(res, body)
                tenant_region.is_active = True
                tenant_region.is_init = True
                # todo 将从数据中心获取的租户信息记录到tenant_region, 当前只是用tenant的数据填充
                tenant_region.region_tenant_id = tenant.tenant_id
                tenant_region.region_tenant_name = tenant.tenant_name
                tenant_region.region_scope = 'public'
                tenant_region.enterprise_id = tenant.enterprise_id

                tenant_region.save()
            except api.CallApiError as e:
                logger.error("create tenant {0} failed".format(
                    tenant.tenant_name))
                logger.exception(e)
                success = False
        # 部分初始化但是
        else:
            if (not tenant_region.region_tenant_id) or \
                    (not tenant_region.region_tenant_name) or \
                    (not tenant_region.enterprise_id):
                tenant_region.region_tenant_id = tenant.tenant_id
                tenant_region.region_tenant_name = tenant.tenant_name
                tenant_region.region_scope = 'public'
                tenant_region.enterprise_id = tenant.enterprise_id
                tenant_region.save()
        return success
示例#2
0
    def create_and_init_tenant(self,
                               user_id,
                               tenant_name='',
                               region_names=[],
                               enterprise_id='',
                               tenant_alias=''):
        """
        创建一个团队,并完成团队对指定数据中心的初始化
        :param user_id: 用户id
        :param tenant_name: 团队英文, 兼容历史的tenant租户名称信息
        :param tenant_alias: 团队别名, 对团队显示名称
        :param region_names: 指定需要开通的数据中心名字列表
        :param enterprise_id: 企业ID,(兼容实现,如果未指定则使用团队的tenant_id)
        :return: 
        """
        logger.debug('create_and_init_tenant.....')
        logger.debug('user_id: {}'.format(user_id))
        logger.debug('tenant_name: {}'.format(tenant_name))
        logger.debug('region_names: {}'.format(region_names))
        logger.debug('enterprise_id: {}:'.format(enterprise_id))
        logger.debug('tenant_alias: {}'.format(tenant_alias))
        # 判断用户是否存在, 如果有enterprise_id意味着用户与enterprise已经绑定
        if enterprise_id:
            user = Users.objects.get(user_id=user_id,
                                     enterprise_id=enterprise_id)
            enterprise = TenantEnterprise.objects.get(
                enterprise_id=enterprise_id)
        else:
            user = Users.objects.get(user_id=user_id)
            enterprise = None

        if user.is_active:
            logger.info('user is already active, return default tenant')
            return Tenants.objects.get(creater=user.user_id)

        tenant_name_regx = re.compile(r'^[a-z0-9-]*$')
        if tenant_name and not tenant_name_regx.match(tenant_name):
            logger.error('bad tenant_name!')
            raise Exception(
                'tenant_name  must consist of lower case alphanumeric characters or -'
            )

        # 判断团队是否存在
        if not tenant_name:
            tenant_name = self.random_tenant_name()
            logger.info(
                'tenant_name not specify, generator [{}]'.format(tenant_name))

        tenants_num = Tenants.objects.filter(tenant_name=tenant_name).count()
        if tenants_num > 0:
            raise Exception('team {} already existed!'.format(tenant_name))

        # 根据lisence确定是否可以创建新的团队
        is_private = sn.instance.is_private()
        if is_private:
            tenants_num = Tenants.objects.count()

        # 私有云用户默认都是企业付费用户,公有云默认用户是免费企业用户
        if is_private:
            pay_type = 'payed'
            pay_level = 'company'
        else:
            pay_type = 'free'
            pay_level = 'company'

        expired_day = 7
        if hasattr(settings, "TENANT_VALID_TIME"):
            expired_day = int(settings.TENANT_VALID_TIME)
        expire_time = dt.datetime.now() + dt.timedelta(days=expired_day)

        # 计算此团队需要初始化的数据中心
        region_configs = {r.get('name'): r for r in regionConfig.regions()}

        if not region_configs:
            raise Exception('please config one region at least.')

        prepare_init_regions = []
        if region_names:
            for region_name in region_names:
                if region_name in region_configs:
                    prepare_init_regions.append(
                        region_configs.get(region_name))
        else:
            prepare_init_regions.extend(region_configs.values())

        if not prepare_init_regions:
            raise Exception('please init one region at least.')

        logger.info('prepared init region: {}'.format(
            [r.get('name') for r in prepare_init_regions]))
        # 团队管理的默认数据中心
        default_region = prepare_init_regions[0]

        # 使用已存在的企业
        if enterprise:
            logger.info('enterprise existed: {}'.format(
                enterprise.enterprise_name))

            if not tenant_alias:
                tenant_alias = u'{0}的团队'.format(enterprise.enterprise_alias)
            # 创建团队
            tenant = Tenants.objects.create(
                tenant_name=tenant_name,
                pay_type=pay_type,
                pay_level=pay_level,
                creater=user_id,
                region=default_region.get('name'),
                expired_time=expire_time,
                tenant_alias=tenant_alias,
                enterprise_id=enterprise.enterprise_id,
                limit_memory=4096)
            logger.info('create tenant:{}'.format(tenant.to_dict()))

        # 兼容用现有的团队id建立企业信息
        else:
            logger.info(
                'enterprise not existed, use tenant for default enterprise.')
            if not tenant_alias:
                tenant_alias = u'{0}的团队'.format(tenant_name)

            # 创建团队
            tenant = Tenants.objects.create(tenant_name=tenant_name,
                                            pay_type=pay_type,
                                            pay_level=pay_level,
                                            creater=user_id,
                                            region=default_region.get('name'),
                                            expired_time=expire_time,
                                            tenant_alias=tenant_alias,
                                            limit_memory=4096)
            logger.info('create tenant:{}'.format(tenant.to_dict()))

            # 依赖团队信息创建企业信息
            enterprise = TenantEnterprise.objects.create(
                enterprise_name=tenant_name,
                enterprise_alias=tenant_name,
                enterprise_id=tenant.tenant_id)
            logger.info('create enterprise with tenant:{}'.format(
                enterprise.to_dict()))

            # 将企业id关联到团队之上
            tenant.enterprise_id = enterprise.enterprise_id
            tenant.save()

            # 将此用户与企业关系绑定
            user.enterprise_id = enterprise.enterprise_id

        monitor_hook.tenantMonitor(tenant, user, "create_tenant", True)

        # 创建用户团队企业关系及权限,创建团队的用户即为此团队的管理员
        logger.debug(
            'create tenant_perm! user_pk: {0}, tenant_pk:{1}, enterprise_pk:{2}'
            .format(user_id, tenant.pk, enterprise.pk))
        PermRelTenant.objects.create(user_id=user_id,
                                     tenant_id=tenant.pk,
                                     identity='admin',
                                     enterprise_id=enterprise.pk)

        # 初始化数据中心并建立团队与数据中心的关系
        api = RegionInvokeApi()
        for region in prepare_init_regions:
            tenant_region = TenantRegionInfo.objects.create(
                tenant_id=tenant.tenant_id,
                region_name=region.get('name'),
                enterprise_id=enterprise.enterprise_id)
            try:
                res, body = api.create_tenant(region.get('name'),
                                              tenant.tenant_name,
                                              tenant.tenant_id,
                                              enterprise.enterprise_id)
                logger.debug(res)
                logger.debug(body)
                tenant_region.is_active = True
                tenant_region.is_init = True

                # todo 将从数据中心获取的租户信息记录到tenant_region, 当前只是用tenant的数据填充
                tenant_region.region_tenant_id = tenant.tenant_id
                tenant_region.region_tenant_name = tenant.tenant_name
                tenant_region.region_scope = 'public'

                tenant_region.save()
                logger.info("tenant_region[{0}] = {1}, {2}, {3}".format(
                    tenant_region.region_name, tenant_region.region_tenant_id,
                    tenant_region.region_tenant_name,
                    tenant_region.region_scope))

                monitor_hook.tenantMonitor(tenant, user, "init_tenant", True)
                logger.info("init success!")
            except Exception as e:
                logger.error("init failed: {}".format(e.message))
                logger.exception(e)

                tenant_region.is_init = False
                tenant_region.is_active = False
                tenant_region.save()
                monitor_hook.tenantMonitor(tenant, user, "init_tenant", False)

        user.is_active = True
        user.save()

        try:
            content = '新用户: {0}, 手机号: {1}, 租户: {2}, 邮箱: {3}, 企业: {4}'.format(
                user.nick_name, user.phone, tenant.tenant_name, user.email,
                enterprise.enterprise_alias)
            send_mail("new user active tenant", content,
                      '*****@*****.**', notify_mail_list)
        except Exception:
            pass

        return tenant