class RegionInfo(object): # region_list = settings.REGIONS region_list = regionConfig.regions() region_ports = settings.WILD_PORTS region_domains = settings.WILD_DOMAINS is_private = sn.instance.is_private() if is_private: region_list = regionConfig.regions()[0:1] # region_list = settings.REGIONS[0:1] @classmethod def region_names(cls): return tuple([e['name'] for e in cls.region_list]) @classmethod def region_labels(cls): return tuple([e['label'] for e in cls.region_list]) @classmethod def register_choices(cls): choices = [] for item in cls.region_list: if item['enable']: choices.append((item['name'], item['label'])) return choices @classmethod def valid_regions(cls): choices = [] for item in cls.region_list: if item['enable']: choices.append(item['name']) return choices @classmethod def region_port(cls, region_name): return cls.region_ports[region_name] @classmethod def region_domain(cls, region_name): return cls.region_domains[region_name] @classmethod def regions(cls): return regionConfig.regions()
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
def regions(cls): return regionConfig.regions()
def post(self, request, *args, **kwargs): """注册管理员""" admin_form = AdminForm(request.POST) import datetime if admin_form.is_valid(): email = request.POST.get('email') nick_name = request.POST.get('nick_name') password = request.POST.get('password') password_repeat = request.POST.get('password_repeat') region = request.POST.get('machine_region') if region is None or region == "" or region == "1": region = RegionInfo.register_choices()[0][0] # 企业名称 enter_alias = request.POST.get('enter_alias', '') # 租户信息 tenant_name = nick_name # 清理之前所有的租户 tenant_count = Tenants.objects.all().count() if tenant_count > 0: logger.error("account.register", "租户已存在,请先清理租户!") context = self.get_context() admin_form.add_error("", "租户已存在,请先清理租户!") context["form"] = admin_form return TemplateResponse(request, 'www/wizard/admin.html', context) # Tenants.objects.all().delete() regions = regionConfig.regions() if region not in [r['name'] for r in regions]: logger.error("account.register", "配置文件中未找到待初始化的数据中心配置信息!") context = self.get_context() admin_form.add_error("", "配置文件中未找到待初始化的数据中心配置信息!") context["form"] = admin_form return TemplateResponse(request, 'www/wizard/admin.html', context) # 添加本地企业信息 enterprise = enterprise_svc.create_enterprise( enterprise_alias=enter_alias) # 添加用户 user = Users(email=email, nick_name=nick_name, client_ip=get_client_ip(request), rf='admin', is_active=False, enterprise_id=enterprise.enterprise_id) user.set_password(password) user.save() monitorhook.registerMonitor(user, 'register') # 添加django用户 tmpname = nick_name + "_token" oauth_user = OAuthUser.objects.create(username=tmpname) oauth_user.set_password(password) oauth_user.is_staff = True oauth_user.save() # 初始化企业与团队信息 region_names = [region] enterprise_svc.create_and_init_tenant(user.user_id, tenant_name, region_names, enterprise.enterprise_id) # 第一个用户默认作为云帮管理员 superadmin = SuperAdminUser() superadmin.email = email superadmin.save() # create gitlab user if user.email is not None and user.email != "": codeRepositoriesService.createUser(user, email, password, nick_name, nick_name) # 登录系统 user = authenticate(username=nick_name, password=password) login(request, user) self.user = request.user # 发送数据到app进行注册 data = { "username": nick_name, "email": email, "password": password, } json_data = json.dumps(data) try: # for num in range(0, 3): appClient.timeout = 5 res, body = appClient.post_admin_info(json_data) if res is None: logger.error("account.register", "register app failed!") else: logger.debug("account.register", res) logger.debug("account.register", body) if res.status == 200: logger.debug("account.register", "register app success!") else: logger.error("account.register", "register app failed!") except Exception as e: logger.exception("account.register", e) url = '/apps/{0}'.format(tenant_name) if settings.MODULES["Package_Show"]: selected_pay_level = "" pl = request.GET.get("pl", "") region_levels = pl.split(":") if len(region_levels) == 2: selected_pay_level = region_levels[1] url = '/payed/{0}/select?selected={1}'.format( tenant_name, selected_pay_level) logger.debug(url) return self.redirect_to(url) else: context = self.get_context() context["form"] = admin_form return TemplateResponse(request, 'www/wizard/admin.html', context)