Beispiel #1
0
 def __get_current_app_and_version(self):
     """
     :return:
     app object
     app_version object
     """
     from console.services.market_app_service import market_app_service
     group_id = service_group_relation_repo.get_group_id_by_service(
         self.service)
     service_ids = group_service_relation_repo.get_services_by_group(
         group_id).values_list("service_id", flat=True)
     versions = service_source_repo.get_service_sources(
         self.tenant.tenant_id,
         service_ids).exclude(version=None).values_list("version",
                                                        flat=True)
     sorted_versions = sorted(
         versions,
         key=lambda x: map(lambda y: int(filter(str.isdigit, str(y))),
                           x.split(".")))
     current_version = sorted_versions[-1]
     if not self.install_from_cloud:
         app, app_version = rainbond_app_repo.get_rainbond_app_and_version(
             self.tenant.enterprise_id, self.service_source.group_key,
             current_version)
     else:
         app, app_version = market_app_service.get_app_from_cloud(
             self.tenant, self.service_source.group_key, current_version)
         self.market_id = app.market_id
     if app_version:
         self.template = json.loads(app_version.app_template)
         self.current_app = app
         self.current_version = app_version
Beispiel #2
0
    def export_app(self, eid, app_id, version, export_format):
        app, app_version = rainbond_app_repo.get_rainbond_app_and_version(
            eid, app_id, version)
        if not app or not app_version:
            raise RbdAppNotFound("未找到该应用")

        # get region TODO: get region by app publish meta info
        region = self.select_handle_region(eid)
        region_name = region.region_name
        export_record = app_export_record_repo.get_export_record(
            eid, app_id, version, export_format)
        if export_record:
            if export_record.status == "success":
                raise ExportAppError(msg="exported",
                                     mes_show="已存在该导出记录",
                                     status_code=409)
            if export_record.status == "exporting":
                logger.debug("export record exists: event_id :{0}".format(
                    export_record.event_id))
                return export_record
        # did not export, make a new export record
        # make export data
        event_id = make_uuid()
        data = {
            "event_id": event_id,
            "group_key": app.app_id,
            "version": app_version.version,
            "format": export_format,
            "group_metadata": self.__get_app_metata(app, app_version)
        }

        try:
            region_api.export_app(region_name, eid, data)
        except region_api.CallApiError as e:
            logger.exception(e)
            raise ExportAppError()

        params = {
            "event_id": event_id,
            "group_key": app_id,
            "version": version,
            "format": export_format,
            "status": "exporting",
            "enterprise_id": eid,
            "region_name": region.region_name
        }

        return app_export_record_repo.create_app_export_record(**params)
    def _app_template(enterprise_id, app_model_key, version, app_template_source):
        if not app_template_source.is_install_from_cloud():
            _, app_version = rainbond_app_repo.get_rainbond_app_and_version(enterprise_id, app_model_key, version)
        else:
            market = app_market_repo.get_app_market_by_name(
                enterprise_id, app_template_source.get_market_name(), raise_exception=True)
            _, app_version = app_market_service.cloud_app_model_to_db_model(market, app_model_key, version)

        if not app_version:
            raise AbortRequest("app template not found", "找不到应用模板", status_code=404, error_code=404)

        try:
            app_template = json.loads(app_version.app_template)
            app_template["update_time"] = app_version.update_time
            return app_template
        except JSONDecodeError:
            raise AbortRequest("invalid app template", "该版本应用模板已损坏, 无法升级")
Beispiel #4
0
    def __get_current_app_and_version(self):
        """
        :return:
        app object
        app_version object
        """
        group_id = service_group_relation_repo.get_group_id_by_service(self.service)
        service_ids = group_service_relation_repo.get_services_by_group(group_id).values_list("service_id", flat=True)
        service_sources = service_source_repo.get_service_sources(self.tenant.tenant_id, service_ids)
        versions = service_sources.exclude(version=None).values_list("version", flat=True)
        if versions:

            def foobar(y):
                try:
                    s = filter(str.isdigit, str(y))
                    return int(s)
                except ValueError:
                    # compatible with old version like 'RELEASE.2018-04-19T2'
                    return -1

            sorted_versions = sorted(versions, key=lambda x: map(foobar, x.split(".")))
            current_version = sorted_versions[-1]
            current_version_source = service_sources.filter(version=current_version).first()
        else:
            current_version = None
            current_version_source = None
        if not self.install_from_cloud:
            app, app_version = rainbond_app_repo.get_rainbond_app_and_version(self.tenant.enterprise_id,
                                                                              self.service_source.group_key, current_version)
        else:
            app, app_version = app_market_service.cloud_app_model_to_db_model(self.market, self.service_source.group_key,
                                                                              current_version)
        if app_version:
            self.template = json.loads(app_version.app_template)
            self.current_app = app
            self.current_version = app_version
            if current_version_source:
                self.service_source.create_time = current_version_source.create_time
Beispiel #5
0
    def post(self, request, group_id, *args, **kwargs):
        """提交升级任务"""
        rq_args = (
            {
                'key': 'upgrade_record_id',
                'required': True,
                'error': 'upgrade_record_id is a required parameter'
            },
            {
                'key': 'group_key',
                'required': True,
                'error': 'group_key is a required parameter'
            },
            {
                'key': 'version',
                'required': True,
                'error': 'version is a required parameter'
            },
            {
                'key': 'services',
                'required': True,
                'error': 'services is a required parameter'
            },
        )
        data = parse_date(request, rq_args)
        group_key = data['group_key']
        version = data['version']
        app_record = get_object_or_404(
            AppUpgradeRecord,
            msg="Upgrade record not found",
            tenant_id=self.tenant.tenant_id,
            group_id=int(group_id),
            group_key=group_key,
            status=UpgradeStatus.NOT.value,
            pk=data['upgrade_record_id'],
        )
        old_service = group_service.get_rainbond_services(group_id, group_key).first()
        pc = PropertiesChanges(old_service, self.tenant)

        # 处理新增的组件
        add_service_infos = {
            service['service']['service_key']: service['upgrade_info']
            for service in data['services'] if service['service']['type'] == UpgradeType.ADD.value and service['upgrade_info']
        }
        install_info = {}
        if add_service_infos:
            if pc.install_from_cloud:
                old_app_model, old_app = app_market_service.cloud_app_model_to_db_model(pc.market, group_key, version)
            else:
                old_app_model, old_app = rainbond_app_repo.get_rainbond_app_and_version(self.tenant.enterprise_id, group_key,
                                                                                        version)
            old_app.template = old_app.app_template
            old_app.app_name = old_app_model.app_name
            new_app = deepcopy(old_app)
            # mock app信息
            template = json.loads(new_app.template)
            template['apps'] = add_service_infos.values()
            new_app.template = json.dumps(template)

            # 查询某一个云市应用下的所有组件
            services = group_service.get_rainbond_services(int(group_id), group_key)
            try:
                install_info = market_app_service.install_service_when_upgrade_app(self.tenant, self.response_region, self.user,
                                                                                   group_id, new_app, old_app, services, True,
                                                                                   pc.install_from_cloud, pc.market_name)

            except ResourceNotEnoughException as re:
                raise re
            except AccountOverdueException as re:
                logger.exception(re)
                return MessageResponse(msg="resource is not enough", msg_show=re.message, status_code=412, error_code=10406)
            upgrade_service.create_add_service_record(app_record, install_info['events'], add_service_infos)

        # 处理需要升级的组件
        upgrade_service_infos = {
            service['service']['service_id']: service['upgrade_info']
            for service in data['services']
            if service['service']['type'] == UpgradeType.UPGRADE.value and service['upgrade_info']
        }

        app_record.version = version
        app_record.old_version = pc.current_version.version
        app_record.save()

        services = service_repo.get_services_by_service_ids_and_group_key(data['group_key'], upgrade_service_infos.keys())

        market_services = [
            upgrade_service.market_service_and_create_backup(self.tenant, service, app_record.version) for service in services
        ]

        # 处理依赖关系
        if add_service_infos:
            market_app_service.save_service_deps_when_upgrade_app(
                self.tenant,
                install_info['service_key_dep_key_map'],
                install_info['key_service_map'],
                install_info['apps'],
                install_info['app_map'],
            )

        upgrade_service.upgrade_database(market_services)
        upgrade_service.send_upgrade_request(market_services, self.tenant, self.user, app_record, upgrade_service_infos,
                                             self.oauth_instance)
        upgrade_repo.change_app_record_status(app_record, UpgradeStatus.UPGRADING.value)

        return MessageResponse(msg="success", bean=upgrade_service.serialized_upgrade_record(app_record))
Beispiel #6
0
    def get(self, request, *args, **kwargs):
        """
        组件详情信息
        ---
        parameters:
            - name: tenantName
              description: 租户名
              required: true
              type: string
              paramType: path
            - name: serviceAlias
              description: 组件别名
              required: true
              type: string
              paramType: path
        """
        bean = dict()
        try:
            # status_map = app_service.get_service_status(self.tenant, self.service)
            # used_resource = app_service.get_service_resource_with_plugin(self.tenant, self.service,
            #                                                              status_map["status"])
            # service_abled_plugins = app_plugin_service.get_service_abled_plugin(self.service)
            # plugin_list = [p.to_dict() for p in service_abled_plugins]
            # bean.update(status_map)
            # bean.update(used_resource)
            # bean.update({"plugin_list": plugin_list})
            service_model = self.service.to_dict()
            group_map = group_service.get_services_group_name(
                [self.service.service_id])
            group_name = group_map.get(self.service.service_id)["group_name"]
            group_id = group_map.get(self.service.service_id)["group_id"]
            service_model["group_name"] = group_name
            service_model["group_id"] = group_id
            bean.update({"service": service_model})
            tenant_actions = self.user.actions.tenant_actions
            bean.update({"tenant_actions": tenant_actions})
            service_actions = self.user.actions.service_actions
            bean.update({"service_actions": service_actions})
            event_websocket_url = ws_service.get_event_log_ws(
                self.request, self.service.service_region)
            bean.update({"event_websocket_url": event_websocket_url})
            if self.service.service_source == "market":
                service_source = service_source_repo.get_service_source(
                    self.tenant.tenant_id, self.service.service_id)
                if not service_source:
                    result = general_message(200, "success", "查询成功", bean=bean)
                    return Response(result, status=result["code"])
                rainbond_app, rainbond_app_version = rainbond_app_repo.get_rainbond_app_and_version(
                    self.tenant.enterprise_id, service_source.group_key,
                    service_source.version)
                if not rainbond_app:
                    result = general_message(200,
                                             "success",
                                             "当前云市组件已删除",
                                             bean=bean)
                    return Response(result, status=result["code"])

                bean.update({"rain_app_name": rainbond_app.app_name})
                apps_template = json.loads(rainbond_app_version.app_template)
                apps_list = apps_template.get("apps")
                for app in apps_list:
                    if app["service_key"] == self.service.service_key:
                        if self.service.deploy_version and int(
                                app["deploy_version"]) > int(
                                    self.service.deploy_version):
                            self.service.is_upgrate = True
                            self.service.save()
                            bean.update({"service": service_model})
                try:
                    apps_template = json.loads(
                        rainbond_app_version.app_template)
                    apps_list = apps_template.get("apps")
                    service_source = service_source_repo.get_service_source(
                        self.service.tenant_id, self.service.service_id)
                    if service_source and service_source.extend_info:
                        extend_info = json.loads(service_source.extend_info)
                        if extend_info:
                            for app in apps_list:
                                if "service_share_uuid" in app:
                                    if app["service_share_uuid"] == extend_info[
                                            "source_service_share_uuid"]:
                                        new_version = int(
                                            app["deploy_version"])
                                        old_version = int(extend_info[
                                            "source_deploy_version"])
                                        if new_version > old_version:
                                            self.service.is_upgrate = True
                                            self.service.save()
                                            service_model["is_upgrade"] = True
                                            bean.update(
                                                {"service": service_model})
                                elif "service_share_uuid" not in app and "service_key" in app:
                                    if app["service_key"] == extend_info[
                                            "source_service_share_uuid"]:
                                        new_version = int(
                                            app["deploy_version"])
                                        old_version = int(extend_info[
                                            "source_deploy_version"])
                                        if new_version > old_version:
                                            self.service.is_upgrate = True
                                            self.service.save()
                                            service_model["is_upgrade"] = True
                                            bean.update(
                                                {"service": service_model})
                except Exception as e:
                    logger.exception(e)

            if self.service.service_source == AppConstants.DOCKER_COMPOSE:
                if self.service.create_status != "complete":
                    compose_service_relation = compose_service.get_service_compose_id(
                        self.service)
                    if compose_service_relation:
                        service_model[
                            "compose_id"] = compose_service_relation.compose_id
                        bean.update({"service": service_model})
            bean["is_third"] = False
            if self.service.service_source == "third_party":
                bean["is_third"] = True
                service_endpoints = service_endpoints_repo.get_service_endpoints_by_service_id(
                    self.service.service_id)
                if service_endpoints:
                    bean["register_way"] = service_endpoints.endpoints_type
                    if service_endpoints.endpoints_type == "api":
                        # 从环境变量中获取域名,没有在从请求中获取
                        host = os.environ.get('DEFAULT_DOMAIN',
                                              "http://" + request.get_host())
                        bean[
                            "api_url"] = host + "/console/" + "third_party/{0}".format(
                                self.service.service_id)
                        key_repo = deploy_repo.get_service_key_by_service_id(
                            service_id=self.service.service_id)
                        if key_repo:
                            bean["api_service_key"] = pickle.loads(
                                base64.b64decode(
                                    key_repo.secret_key)).get("secret_key")
                    if service_endpoints.endpoints_type == "discovery":
                        # 返回类型和key
                        endpoints_info_dict = json.loads(
                            service_endpoints.endpoints_info)

                        bean["discovery_type"] = endpoints_info_dict["type"]
                        bean["discovery_key"] = endpoints_info_dict["key"]

            result = general_message(200, "success", "查询成功", bean=bean)
        except Exception as e:
            logger.exception(e)
            result = error_message(e.message)
        return Response(result, status=result["code"])