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
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