Example #1
0
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()
Example #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
Example #3
0
 def regions(cls):
     return regionConfig.regions()
Example #4
0
    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)