def getServiceModel(self, app_service_list):
        published_service_list = []
        for app_service in app_service_list:
            service = ServiceInfo()
            service.service_key = app_service.service_key
            service.version = app_service.app_version
            service.publisher = app_service.publisher
            service.service_name = app_service.app_alias
            service.pic = app_service.logo
            service.info = app_service.info
            service.desc = app_service.desc
            service.status = app_service.status
            service.category = "app_publish"
            service.is_service = app_service.is_service
            service.is_web_service = app_service.is_web_service
            service.version = app_service.app_version
            service.update_version = app_service.update_version
            service.image = app_service.image
            service.slug = app_service.slug
            service.extend_method = app_service.extend_method
            service.cmd = app_service.cmd
            service.setting = ""
            service.env = app_service.env
            service.dependecy = ""
            service.min_node = app_service.min_node
            service.min_cpu = app_service.min_cpu
            service.min_memory = app_service.min_memory
            service.inner_port = app_service.inner_port
            service.volume_mount_path = app_service.volume_mount_path
            service.service_type = app_service.service_type
            service.is_init_accout = app_service.is_init_accout
            service.creater = app_service.creater
            service.namespace = app_service.namespace
            service.publish_type = "group"
            published_service_list.append(service)

        return published_service_list
Beispiel #2
0
    def post(self, request, *args, **kwargs):
        result = {}
        tenant_id = self.tenant.tenant_id
        compose_file_id = request.POST.get("compose_file_id", "")
        group_id = request.POST.get("group_id", "")
        try:
            # judge region tenant is init
            success = tenant_svc.init_for_region(self.response_region,
                                                 self.tenantName, tenant_id,
                                                 self.user)
            if not success:
                result["status"] = "failure"
                return JsonResponse(result, status=200)

            # if tenantAccountService.isOwnedMoney(self.tenant, self.response_region):
            #     result["status"] = "owed"
            #     return JsonResponse(result, status=200)
            if group_id == "":
                result["status"] = "no_group"
                return JsonResponse(result, status=200)

            services_attach_infos = request.POST.get("services_attach_infos",
                                                     "")
            services_attach_infos = self.json_loads(services_attach_infos)

            deps = {}
            services_list = []
            for service_attach_info in services_attach_infos:
                service_cname = service_attach_info.get("app_name")
                service_id = service_attach_info.get("service_id")
                deps[service_cname] = service_id
                ts = TenantServiceInfo()
                min_memory = int(
                    service_attach_info.get("service_min_memory", 128))
                # 将G转换为M
                if min_memory < 128:
                    min_memory *= 1024
                min_node = int(service_attach_info.get("service_min_node", 1))
                ts.min_memory = min_memory
                ts.min_node = min_node
                services_list.append(ts)
            res = tenantUsedResource.predict_batch_services_memory(
                self.tenant, services_list, self.response_region)
            if not res:
                result["status"] = "over_memory"
                result["tenant_type"] = self.tenant.pay_type
                return JsonResponse(result, status=200)

            for service_attach_info in services_attach_infos:
                service_cname = service_attach_info.get("app_name", "")
                if service_cname == "":
                    result["status"] = "empty"
                    return JsonResponse(result, status=200)
                min_memory = int(
                    service_attach_info.get("service_min_memory", 128))
                # 将G转换为M
                if min_memory < 128:
                    min_memory *= 1024
                min_node = int(service_attach_info.get("service_min_node", 1))

                # calculate resource
                tempService = TenantServiceInfo()
                tempService.min_memory = min_memory
                tempService.service_region = self.response_region
                tempService.min_node = int(min_node)

                diffMemory = min_memory
                # 判断是否超出资源
                rt_type, flag = tenantUsedResource.predict_next_memory(
                    self.tenant, tempService, diffMemory, False)
                if not flag:
                    if rt_type == "memory":
                        result["status"] = "over_memory"
                        result["tenant_type"] = self.tenant.pay_type
                    else:
                        result["status"] = "over_money"
                    return JsonResponse(result, status=200)

                service_id = service_attach_info.get("service_id", None)
                if service_id is None:
                    result["status"] = "no_service"
                    return JsonResponse(result, status=200)

                service_alias = "gr" + service_id[-6:]
                service_image = service_attach_info.get("service_image")

                version = ""
                if ":" in service_image:
                    index = service_image.index(":")
                    version = service_image[index + 1:]
                else:
                    version = "latest"

                service = ServiceInfo()
                service.service_key = "0000"
                service.desc = ""
                service.category = "app_publish"
                service.image = service_image
                service.cmd = ""
                service.setting = ""
                service.extend_method = "stateless"
                service.env = ","
                service.min_node = min_node
                cm = min_memory
                if min_memory != "":
                    cm = int(min_memory)

                service.min_memory = cm
                service.min_cpu = baseService.calculate_service_cpu(
                    self.response_region, cm)
                service.inner_port = 0
                service.volume_mount_path = ""

                service.version = version
                service.namespace = "goodrain"
                service.update_version = 1
                service.volume_mount_path = ""
                service.service_type = "application"

                # service host_path
                service.host_path = "/grdata/tenant/" + self.tenant.tenant_id + "/service/" + service_id

                # 创建服务
                newTenantService = baseService.create_service(
                    service_id,
                    tenant_id,
                    service_alias,
                    service_cname,
                    service,
                    self.user.pk,
                    region=self.response_region)
                newTenantService.code_from = "image_manual"
                newTenantService.language = "docker-compose"
                newTenantService.save()
                sai = attach_info_mamage.create_service_attach_info(
                    newTenantService,
                    newTenantService.min_memory * newTenantService.min_node, 0)
                monitorhook.serviceMonitor(self.user.nick_name,
                                           newTenantService, 'create_service',
                                           True)
                ServiceGroupRelation.objects.create(
                    service_id=service_id,
                    group_id=int(group_id),
                    tenant_id=tenant_id,
                    region_name=self.response_region)
                result[service_id] = {
                    "service_id": service_id,
                    "service_cname": service_cname,
                    "service_alias": service_alias
                }
            result["status"] = "success"
            result["group_id"] = group_id
            result["compose_file_id"] = compose_file_id

        except Exception as e:
            ServiceGroupRelation.objects.filter(
                group_id=int(group_id)).delete()
            logger.exception(e)
        return JsonResponse(result, status=200)
Beispiel #3
0
    def post(self, request, format=None):
        """
        获取某个租户信息(tenant_id或者tenant_name)
        ---
        parameters:
            - name: service_key
              description: 服务key
              required: true
              type: string
              paramType: form
            - name: app_version
              description: 服务版本
              required: true
              type: string
              paramType: form
            - name: image
              description: 镜像名
              required: false
              type: string
              paramType: form
            - name: slug
              description: slug包
              required: false
              type: string
              paramType: form
            - name: dest_yb
              description: dest_yb
              required: false
              type: boolean
              paramType: form
            - name: dest_ys
              description: dest_ys
              required: false
              type: boolean
              paramType: form
            - name: share_id
              description: share_id
              required: false
              type: string
              paramType: form

        """
        data = {}
        isys = False
        serviceInfo = None
        try:
            service_key = request.data.get('service_key', "")
            app_version = request.data.get('app_version', "")
            logger.debug(
                "group.publish",
                "invoke publish service method  service_key:" + service_key +
                " service_version" + app_version)
            image = request.data.get('image', "")
            slug = request.data.get('slug', "")
            dest_yb = request.data.get('dest_yb', False)
            dest_ys = request.data.get('dest_ys', False)

            app = AppService.objects.get(service_key=service_key,
                                         app_version=app_version)
            logger.debug(
                "group.publish",
                "dest_yb ==> {0} dest_ys ==> {1}".format(dest_yb, dest_ys))
            if not app.dest_yb:
                app.dest_yb = dest_yb
            if not app.dest_ys:
                app.dest_ys = dest_ys
            isok = False
            if app.is_outer and app.dest_yb and app.dest_ys:
                isok = True
            # if app.is_outer and app.dest_ys:
            #     isok = True
            #     app.dest_yb = True
            if not app.is_outer and app.dest_yb:
                isok = True
            if slug != "" and not slug.startswith("/"):
                slug = "/" + slug
            if isok:
                update_version = 1
                try:
                    serviceInfo = ServiceInfo.objects.get(
                        service_key=service_key, version=app_version)
                    update_version = serviceInfo.update_version + 1
                except Exception:
                    pass
                if serviceInfo is None:
                    serviceInfo = ServiceInfo()
                serviceInfo.service_key = app.service_key
                serviceInfo.publisher = app.publisher
                serviceInfo.service_name = app.app_alias
                serviceInfo.pic = app.logo
                serviceInfo.info = app.info
                serviceInfo.desc = app.desc
                serviceInfo.status = "published"
                if app.status == "private":
                    serviceInfo.status = app.status
                serviceInfo.category = "app_publish"
                serviceInfo.is_service = app.is_service
                serviceInfo.is_web_service = app.is_web_service
                serviceInfo.version = app.app_version
                serviceInfo.update_version = update_version
                if image != "":
                    serviceInfo.image = image
                else:
                    serviceInfo.image = app.image
                serviceInfo.slug = slug
                serviceInfo.extend_method = app.extend_method
                serviceInfo.cmd = app.cmd
                serviceInfo.setting = ""
                # SLUG_PATH=/app_publish/redis-stat/20151201175854.tgz,
                if slug != "":
                    serviceInfo.env = app.env + ",SLUG_PATH=" + slug + ","
                else:
                    serviceInfo.env = app.env
                serviceInfo.dependecy = ""
                serviceInfo.min_node = app.min_node
                serviceInfo.min_cpu = app.min_cpu
                serviceInfo.min_memory = app.min_memory
                serviceInfo.inner_port = app.inner_port
                serviceInfo.volume_mount_path = app.volume_mount_path
                serviceInfo.service_type = app.service_type
                serviceInfo.is_init_accout = app.is_init_accout
                serviceInfo.creater = app.creater
                serviceInfo.namespace = app.namespace
                # 判断是否为组发布
                key = request.data.get('share_id', None)
                if key:
                    serviceInfo.publish_type = "group"
                else:
                    serviceInfo.publish_type = "single"
                serviceInfo.save()
            app.is_ok = isok
            if slug != "":
                app.slug = slug
            if image != "":
                app.image = image
            app.save()
            isys = app.dest_ys
        except Exception as e:
            logger.exception(e)
            return Response({"ok": False}, status=500)

        logger.debug("group.publish", " ==> isok:{0}".format(isok))
        logger.debug("group.publish", " ==> isys:{0}".format(isys))
        logger.debug(
            "group.publish", " ==> Publish_YunShi:{0}".format(
                settings.MODULES["Publish_YunShi"]))

        # 发布到云市,调用http接口发送数据
        if isok and isys and settings.MODULES["Publish_YunShi"]:
            logger.debug("group.publish", " =====> publish to app market!")
            data = self.init_data(app, slug, image)
            apputil = AppSendUtil(service_key, app_version)
            # 发送服务参数不发送图片参数
            if data.get("pic") is not None:
                data.pop('pic')
            data["show_category"] = app.show_category
            # 添加租户信息
            try:
                tenant = Tenants.objects.get(tenant_id=data["tenant_id"])
                data["tenant_name"] = tenant.tenant_name
            except Tenants.DoesNotExist:
                logger.error(
                    "group.publish",
                    "tenant is not exists,tenant_id={}".format(
                        data["tenant_id"]))
            # 添加发布类型信息: publish or share
            # AppServiceExtend存在信息
            num = AppServiceExtend.objects.filter(
                service_key=service_key, app_version=app_version).count()
            if num == 1:
                data["publish_flow_type"] = 1

            share_id = None
            try:
                share_id = request.data.get('share_id', None)
                logger.debug("group.publish", "====> share id is " + share_id)
            except Exception as e:
                logger.exception(e)
            data["share_id"] = share_id
            apputil.send_services(data)
            # 发送图片
            if str(app.logo) is not None and str(app.logo) != "":
                image_url = str(app.logo)
                logger.debug("group.publish",
                             'send service logo:{}'.format(image_url))
                apputil.send_image('app_logo', image_url)
            # 发送请求到所有的数据中心进行数据同步
            # self.downloadImage(serviceInfo)

            # 判断是否服务组发布,发布是否成功
            logger.debug("group.publish", "========> before send app group !")
            app_service_group = None
            try:
                logger.debug(dest_ys)
                if share_id is not None and dest_ys:
                    try:
                        app_service_group = AppServiceGroup.objects.get(
                            ID=share_id)
                    except AppServiceGroup.DoesNotExist as e:
                        logger.exception(e)
                    if app_service_group is not None:
                        curr_step = app_service_group.step
                        if curr_step > 0:
                            logger.debug(
                                "group.publish",
                                "before remove one app from app_group ! step {}"
                                .format(curr_step))
                            curr_step -= 1
                            logger.debug(
                                "group.publish",
                                "after remove one app from app_group ! step {}"
                                .format(curr_step))
                            app_service_group.step = curr_step
                            app_service_group.save()
                        # 判断是否为最后一次调用,发布到最后一个应用后将组信息填写到云市
                        if curr_step == 0 and app_service_group.is_market:
                            logger.info(
                                "group.publish",
                                "send group publish info to app_market")
                            # 将服务组信息发送到云市
                            tenant_id = data["tenant_id"]
                            param_data = {
                                "group_name":
                                app_service_group.group_share_alias,
                                "group_key": app_service_group.group_share_id,
                                "tenant_id": tenant_id,
                                "group_version":
                                app_service_group.group_version,
                                "publish_type": app_service_group.publish_type,
                                "desc": app_service_group.desc,
                                "installable": app_service_group.installable
                            }
                            # tmp_ids = app_service_group.service_ids
                            # service_id_list = json.loads(tmp_ids)
                            logger.debug(
                                "group.publish", "===> group_id {0}".format(
                                    app_service_group.group_id))
                            service_id_list = ServiceGroupRelation.objects.filter(
                                group_id=app_service_group.group_id
                            ).values_list("service_id", flat=True)
                            if len(service_id_list) > 0:
                                # 查询最新发布的信息发送到云市。现在同一service_id会发布不同版本存在于云市,取出最新发布的
                                app_service_list = self.get_newest_published_service(
                                    service_id_list)
                                tenant_service_list = TenantServiceInfo.objects.filter(
                                    service_id__in=service_id_list,
                                    tenant_id=tenant_id)
                                service_category_map = {
                                    x.service_id: "self"
                                    if x.category == "application" else "other"
                                    for x in tenant_service_list
                                }
                                logger.debug(
                                    "group.publish",
                                    "===> service_category_map {}".format(
                                        service_category_map))
                                service_data = []
                                for app in app_service_list:
                                    owner = service_category_map.get(
                                        app.service_id, "other")
                                    service_map = {
                                        "service_key": app.service_key,
                                        "version": app.app_version,
                                        "owner": owner
                                    }

                                    service_data.append(service_map)
                                param_data["data"] = service_data
                                # 执行后台安装应用组流程,仅公有云
                                is_publish = sn.instance.cloud_assistant == "goodrain" and (
                                    not sn.instance.is_private())
                                if is_publish:
                                    backServiceInstall = BackServiceInstall()
                                    group_id, grdemo_service_ids, url_map, region_name = backServiceInstall.install_services(
                                        share_id)
                                    grdemo_console_url = "https://user.goodrain.com/apps/grdemo/myservice/?gid={0}&region={1}".format(
                                        str(group_id), region_name)

                                    param_data.update(
                                        {"console_url": grdemo_console_url})
                                    param_data.update(
                                        {"preview_urls": url_map})
                                # 发送组信息到云市
                                num = apputil.send_group(param_data)
                                if num != 0:
                                    logger.exception(
                                        "publish service group failed!")
                            # 应用组发布成功
                            app_service_group.is_success = True
                            app_service_group.save()
            except Exception as e:
                app_service_group.is_success = False
                app_service_group.save()
                logger.exception("group.publish", e)
                logger.error("group.publish", "publish service group failed!")

        return Response({"ok": True}, status=200)