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
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", "该版本应用模板已损坏, 无法升级")
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
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))
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"])