def test_restore_ports(): from console.services.app_actions.app_restore import AppRestore tn = Tenants() tn.tenant_id = "c1a29fe4d7b0413993dc859430cf743d" svc = TenantServiceInfo() svc.service_id = "5a9209f3a3e94695b23fbd8b16a07d2b" backup_data = { "service_ports": [{ "lb_mapping_port": 0, "protocol": "http", "mapping_port": 80, "tenant_id": "c1a29fe4d7b0413993dc859430cf743d", "port_alias": "GR063B3980", "container_port": 80, "is_outer_service": False, "is_inner_service": False, "service_id": "5a9209f3a3e94695b23fbd8b16a07d2b", "ID": 513 }], } service_ports = backup_data["service_ports"] raw_ports = [port["port_alias"] for port in service_ports] app_restore = AppRestore(tn, svc) app_restore.ports(service_ports) ports = port_repo.get_service_ports(tn.tenant_id, svc.service_id) for port in ports: assert port.port_alias in raw_ports
def test_list_by_svc_share_uuids(): tenant_id = "6d1c06e1d9e84d57aeb42ea80d49018a" service_id = "560ca84003254737a426d0bd5f513afd" service_cname = "WordPress" group_id = 20 service = TenantServiceInfo() service.tenant_id = tenant_id service.service_id = service_id service.service_cname = service_cname service.save() service_source = ServiceSourceInfo() service_source.team_id = tenant_id service_source.service_id = service_id service_source.service_share_uuid = "2669c2cec6bc7bf5aab29a0ea2703d66" service_source.save() group_relation = ServiceGroupRelation() group_relation.service_id = service_id group_relation.group_id = group_id group_relation.save() from console.repositories.app import service_repo result = service_repo.list_by_svc_share_uuids( group_id, ["2669c2cec6bc7bf5aab29a0ea2703d66"]) service = result[0] assert service.get("service_id") == service_id assert service.get("service_cname") == service_cname
def test_envs_changes(): from console.services.app_actions.properties_changes import PropertiesChanges from console.repositories.app_config import env_var_repo tenant_id = "c1a29fe4d7b0413993dc859430cf743d" service_id = "03289ae373e65e4a1a22046d7f76ca5e" tenantServiceEnvVar = {} tenantServiceEnvVar["tenant_id"] = tenant_id tenantServiceEnvVar["service_id"] = service_id tenantServiceEnvVar['container_port'] = 0 tenantServiceEnvVar["name"] = "NGINX_VERSION" tenantServiceEnvVar["attr_name"] = "NGINX_VERSION" tenantServiceEnvVar["attr_value"] = "1.15.12-1~stretch" tenantServiceEnvVar["is_change"] = False tenantServiceEnvVar["scope"] = "inner" env_var_repo.add_service_env(**tenantServiceEnvVar) envs = [ { "is_change": True, "name": "\\u65e5\\u5fd7\\u8f93\\u51fa\\u65b9\\u5f0f", "attr_value": "file", "attr_name": "DESTINATION" }, { "is_change": True, "name": "\\u8be6\\u7ec6\\u9519\\u8bef\\u65e5\\u5fd7", "attr_value": "true", "attr_name": "TRACEALLEXCEPTIONS" }, { "is_change": True, "name": "NGINX_VERSION", "attr_value": "1.15.12-1~stretch", "attr_name": "NGINX_VERSION" }, ] service = TenantServiceInfo() service.tenant_id = tenant_id service.service_id = service_id properties_changes = PropertiesChanges(service, Tenants()) env_changes = properties_changes.env_changes(envs) print(env_changes) assert 2 == len(env_changes["add"]) assert next( iter([ x for x in env_changes["add"] if x["attr_name"] == "DESTINATION" ]), None) assert next( iter([ x for x in env_changes["add"] if x["attr_name"] == "TRACEALLEXCEPTIONS" ]), None)
def __init_app(self, service_base_info, new_service_id, new_servie_alias, user, region, tenant): service_base_info.pop("ID") ts = TenantServiceInfo(**service_base_info) ts.service_id = new_service_id ts.service_alias = new_servie_alias ts.service_region = region ts.creater = user.user_id ts.tenant_id = tenant.tenant_id ts.create_status = "creating" ts.save() return ts
def _create_component(snap): # component component = TenantServiceInfo(**snap["service_base"]) # component source component_source = ServiceSourceInfo(**snap["service_source"]) # environment envs = [TenantServiceEnvVar(**env) for env in snap["service_env_vars"]] # ports ports = [TenantServicesPort(**port) for port in snap["service_ports"]] # service_extend_method extend_info = ServiceExtendMethod(**snap["service_extend_method"]) # volumes volumes = [TenantServiceVolume(**volume) for volume in snap["service_volumes"]] # configuration files config_files = [TenantServiceConfigurationFile(**config_file) for config_file in snap["service_config_file"]] # probe probes = [ServiceProbe(**probe) for probe in snap["service_probes"]] # monitors monitors = [ServiceMonitor(**monitor) for monitor in snap["service_monitors"]] # graphs graphs = [ComponentGraph(**graph) for graph in snap["component_graphs"]] return Component( component=component, component_source=component_source, envs=envs, ports=ports, volumes=volumes, config_files=config_files, probe=probes[0] if probes else None, extend_info=extend_info, monitors=monitors, graphs=graphs, plugin_deps=[], )
def test_record_not_found(mocker): with pytest.raises(RecordNotFound): from console.services.app_actions.properties_changes import PropertiesChanges service_source = ServiceSourceInfo() service_source.group_key = "dummy group_key" mocker.patch( "console.repositories.app.service_source_repo.get_service_source", return_value=service_source) properties_changes = PropertiesChanges(TenantServiceInfo(), Tenants()) properties_changes.get_property_changes("eid", "version")
def _create_component(self, snap): # component component = TenantServiceInfo(**snap["service_base"]) # component source component_source = ServiceSourceInfo(**snap["service_source"]) # environment envs = [TenantServiceEnvVar(**env) for env in snap["service_env_vars"]] # ports ports = [TenantServicesPort(**port) for port in snap["service_ports"]] # service_extend_method extend_info = None if snap.get("service_extend_method"): extend_info = ServiceExtendMethod( **snap.get("service_extend_method")) # volumes volumes = [ TenantServiceVolume(**volume) for volume in snap["service_volumes"] ] # configuration files config_files = [ TenantServiceConfigurationFile(**config_file) for config_file in snap["service_config_file"] ] # probe probes = [ServiceProbe(**probe) for probe in snap["service_probes"]] # monitors monitors = [ ServiceMonitor(**monitor) for monitor in snap["service_monitors"] ] # graphs graphs = [ ComponentGraph(**graph) for graph in snap["component_graphs"] ] service_labels = [ ServiceLabels(**label) for label in snap["service_labels"] ] cpt = Component( component=component, component_source=component_source, envs=envs, ports=ports, volumes=volumes, config_files=config_files, probes=probes, extend_info=extend_info, monitors=monitors, graphs=graphs, plugin_deps=[], labels=service_labels, support_labels=self.support_labels, ) cpt.action_type = snap.get("action_type", ActionType.BUILD.value) return cpt
def test_restore_env(): from console.services.app_actions.app_restore import AppRestore tn = Tenants() tn.tenant_id = "c1a29fe4d7b0413993dc859430cf743d" svc = TenantServiceInfo() svc.service_id = "36966cedcad44358a12f1707dece18da" backup_data = { "service_env_vars": [{ "name": "PHPIZE_DEPS", "tenant_id": "c1a29fe4d7b0413993dc859430cf743d", "attr_name": "PHPIZE_DEPS", "container_port": 0, "create_time": "2019-05-14 18:04:26", "attr_value": "autoconf", "is_change": True, "scope": "inner", "service_id": "36966cedcad44358a12f1707dece18da", "ID": 1080 }, { "name": "PHP_EXTRA_CONFIGURE_ARGS", "tenant_id": "c1a29fe4d7b0413993dc859430cf743d", "attr_name": "PHP_EXTRA_CONFIGURE_ARGS", "container_port": 0, "create_time": "2019-05-14 18:04:26", "attr_value": "--with-apxs2 --disable-cgi", "is_change": True, "scope": "inner", "service_id": "36966cedcad44358a12f1707dece18da", "ID": 1081 }] } service_env_vars = backup_data["service_env_vars"] raw_envs = [env["name"] for env in service_env_vars] app_restore = AppRestore(tn, svc) app_restore.envs(service_env_vars) envs = env_var_repo.get_service_env(tn.tenant_id, svc.service_id) for env in envs: assert env.name in raw_envs
def test_rbd_app_not_found(mocker): from console.services.app_actions.properties_changes import PropertiesChanges with open("{}/tests/console/svcupgrade/app_template.json".format( settings.BASE_DIR)) as json_file: app_template = json.load(json_file) rain_app = RainbondCenterApp() rain_app.app_template = json.dumps(app_template) mocker.patch( "console.repositories.market_app_repo.rainbond_app_repo.get_enterpirse_app_by_key_and_version", return_value=rain_app) service_source = ServiceSourceInfo() service_source.group_key = "dummy group_key" mocker.patch( "console.repositories.app.service_source_repo.get_service_source", return_value=service_source) with pytest.raises(RbdAppNotFound): properties_changes = PropertiesChanges(TenantServiceInfo(), Tenants()) properties_changes.get_property_changes("eid", "version")
def create(self, service_base): TenantServiceInfo(**service_base).save()
def __init_compose_service(self, tenant, user, service_cname, image, region): """ 初始化docker compose创建的组件默认数据 """ tenant_service = TenantServiceInfo() tenant_service.tenant_id = tenant.tenant_id tenant_service.service_id = make_uuid() tenant_service.service_cname = service_cname tenant_service.service_alias = "gr" + tenant_service.service_id[-6:] tenant_service.creater = user.pk tenant_service.image = image tenant_service.service_region = region tenant_service.service_key = "0000" tenant_service.desc = "docker compose application" tenant_service.category = "app_publish" tenant_service.setting = "" tenant_service.extend_method = ComponentType.stateless_multiple.value tenant_service.env = "," tenant_service.min_node = 1 tenant_service.min_memory = 128 tenant_service.min_cpu = baseService.calculate_service_cpu(region, 128) tenant_service.inner_port = 0 tenant_service.version = "latest" tenant_service.namespace = "goodrain" tenant_service.update_version = 1 tenant_service.port_type = "multi_outer" tenant_service.create_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') tenant_service.deploy_version = "" tenant_service.git_project_id = 0 tenant_service.service_type = "application" tenant_service.total_memory = 128 tenant_service.volume_mount_path = "" tenant_service.host_path = "/grdata/tenant/" + tenant.tenant_id + "/service/" + tenant_service.service_id tenant_service.code_from = "image_manual" tenant_service.language = "docker-compose" tenant_service.service_source = AppConstants.DOCKER_COMPOSE tenant_service.create_status = "checked" return tenant_service
def __init_third_party_app(self, region, end_point): """ 初始化创建外置服务的默认数据,未存入数据库 """ tenant_service = TenantServiceInfo() tenant_service.service_region = region tenant_service.service_key = "application" tenant_service.desc = "third party service" tenant_service.category = "application" tenant_service.image = "third_party" tenant_service.cmd = "" tenant_service.setting = "" tenant_service.extend_method = "stateless" tenant_service.env = "" tenant_service.min_node = len(end_point) tenant_service.min_memory = 0 tenant_service.min_cpu = 0 tenant_service.version = "81701" tenant_service.namespace = "third_party" tenant_service.update_version = 1 tenant_service.port_type = "multi_outer" tenant_service.create_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') tenant_service.deploy_version = "" tenant_service.git_project_id = 0 tenant_service.service_type = "application" tenant_service.total_memory = 0 tenant_service.volume_mount_path = "" tenant_service.host_path = "" tenant_service.service_source = AppConstants.THIRD_PARTY tenant_service.create_status = "creating" return tenant_service
def __init_source_code_app(self, region): """ 初始化源码创建的应用默认数据,未存入数据库 """ tenant_service = TenantServiceInfo() tenant_service.service_region = region tenant_service.service_key = "application" tenant_service.desc = "application info" tenant_service.category = "application" tenant_service.image = "goodrain.me/runner" tenant_service.cmd = "" tenant_service.setting = "" tenant_service.extend_method = "stateless" tenant_service.env = "" tenant_service.min_node = 1 tenant_service.min_memory = 128 tenant_service.min_cpu = baseService.calculate_service_cpu(region, 128) tenant_service.inner_port = 5000 tenant_service.version = "81701" tenant_service.namespace = "goodrain" tenant_service.update_version = 1 tenant_service.port_type = "multi_outer" tenant_service.create_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') tenant_service.deploy_version = "" tenant_service.git_project_id = 0 tenant_service.service_type = "application" tenant_service.total_memory = 128 tenant_service.volume_mount_path = "" tenant_service.host_path = "" tenant_service.service_source = AppConstants.SOURCE_CODE tenant_service.create_status = "creating" return tenant_service
def _template_to_component(self, tenant_id, template): component = TenantServiceInfo() component.tenant_id = tenant_id component.service_id = make_uuid() component.service_cname = template.get("service_cname", "default-name") component.service_alias = "gr" + component.service_id[-6:] component.creater = self.user.pk component.image = template.get("share_image", template["image"]) component.cmd = template.get("cmd", "") component.service_region = self.region_name component.service_key = template.get("service_key") component.desc = "install from market app" component.category = "app_publish" component.version = template.get("version") component.create_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') component.deploy_version = template.get("deploy_version") component.service_type = "application" component.service_source = AppConstants.MARKET component.create_status = "complete" component.tenant_service_group_id = self.original_app.upgrade_group_id component.build_upgrade = self.is_deploy # component type extend_method = template["extend_method"] if extend_method: if extend_method == "state": component.extend_method = ComponentType.state_multiple.value elif extend_method == "stateless": component.extend_method = ComponentType.stateless_multiple.value else: component.extend_method = extend_method component.min_node = template.get("extend_method_map", {}).get("min_node") if template.get("extend_method_map", {}).get("init_memory"): component.min_memory = template.get("extend_method_map", {}).get("init_memory") elif template.get("extend_method_map", {}).get("min_memory"): component.min_memory = template.get("extend_method_map", {}).get("min_memory") else: component.min_memory = 512 component.min_cpu = component.calculate_min_cpu(component.min_memory) component.total_memory = component.min_node * component.min_memory return component
def __init_docker_image_app(self, region): """ 初始化docker image创建的应用默认数据,未存入数据库 """ tenant_service = TenantServiceInfo() tenant_service.service_region = region tenant_service.service_key = "0000" tenant_service.desc = "docker run application" tenant_service.category = "app_publish" # tenant_service.image = "goodrain.me/runner" # tenant_service.cmd = "start web" tenant_service.setting = "" tenant_service.extend_method = "stateless" tenant_service.env = "," tenant_service.min_node = 1 tenant_service.min_memory = 128 tenant_service.min_cpu = baseService.calculate_service_cpu(region, 128) tenant_service.inner_port = 0 tenant_service.version = "latest" tenant_service.namespace = "goodrain" tenant_service.update_version = 1 tenant_service.port_type = "multi_outer" tenant_service.create_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') tenant_service.deploy_version = "" tenant_service.git_project_id = 0 tenant_service.service_type = "application" tenant_service.total_memory = 128 tenant_service.volume_mount_path = "" tenant_service.host_path = "" tenant_service.code_from = "image_manual" tenant_service.language = "docker-image" tenant_service.create_status = "creating" return tenant_service
def __init_app(self, service_base_info, new_service_id, new_servie_alias, user, region, tenant): service_base_info.pop("ID") ts = TenantServiceInfo(**service_base_info) if service_base_info["service_source"] == "third_party": new_service_id = make_uuid(tenant.tenant_id) new_servie_alias = app_service.create_service_alias(new_service_id) ts.service_id = new_service_id ts.service_alias = new_servie_alias ts.service_region = region ts.creater = user.user_id ts.tenant_id = tenant.tenant_id ts.create_status = "creating" ts.service_cname = ts.service_cname + "-copy" # compatible component type if ts.extend_method == "state": ts.extend_method = "state_multiple" if ts.extend_method == "stateless": ts.extend_method = "stateless_multiple" ts.save() return ts
def create_tenant_service(self, **kwargs): tenant_service = TenantServiceInfo(**kwargs) tenant_service.save() return tenant_service
def __init_app(self, service_base_info, new_service_id, new_servie_alias, user, region, tenant): service_base_info.pop("ID") ts = TenantServiceInfo(**service_base_info) ts.service_id = new_service_id ts.service_alias = new_servie_alias ts.service_region = region ts.creater = user.user_id ts.tenant_id = tenant.tenant_id ts.create_status = "creating" # compatible component type if ts.extend_method == "state": ts.extend_method = "state_multiple" if ts.extend_method == "stateless": ts.extend_method = "stateless_multiple" ts.save() return ts
def post(self, request, *args, **kwargs): service_id = request.POST.get("service_id", "") result = {} try: imsr = ImageServiceRelation.objects.get(service_id=service_id) tenant_id = imsr.tenant_id image_url = imsr.image_url service_cname = imsr.service_cname except Exception as e: logger.exception(e) result["status"] = "notfound" return JsonResponse(result, status=200) service_alias = "gr" + service_id[-6:] try: # 从url中分析出来service_cname 和 version version = "" if ":" in image_url: index = image_url.rindex(":") if service_cname is None or service_cname == "": str_tmp = image_url.split(":") service_cname = str_tmp[len(str_tmp) - 2] version = image_url[index + 1:] else: if service_cname is None or service_cname == "": service_cname = image_url version = "latest" # 端口信息 port_list = json.loads(request.POST.get("port_list", "[]")) # 环境变量信息 env_list = json.loads(request.POST.get("env_list", "[]")) # 持久化目录信息 volume_list = json.loads(request.POST.get("volume_list", "[]")) # 依赖服务id depIds = json.loads(request.POST.get("depend_list", "[]")) # 挂载其他服务目录 service_alias_list = json.loads(request.POST.get('mnt_list', '[]')) # 服务内存 image_service_memory = int( request.POST.get("service_min_memory", 512)) # 服务扩展方式 service_status = request.POST.get("methodval", "stateless") # 判断是否持久化路径是否合法 from www.utils.path_judge import is_path_legal for volume_url in volume_list: url = volume_url.get("volume_path", None) if url: if not is_path_legal(url): result["status"] = "failure" result["msg"] = "路径:{0}不合法".format(url) return JsonResponse(result, status=200) image_url2 = request.POST.get("image_url", "") logger.debug("image_url2 is {}".format(image_url2)) if image_url2 != "" and image_url2 != image_url: image_url = image_url2 try: ImageServiceRelation.objects.filter( service_id=service_id).update(image_url=image_url) logger.debug( "update image_url image_url {0} to image_url2 {1}". format(image_url, image_url2)) except Exception, e: logger.error("update image_url error, {}".format(str(e))) result["status"] = "failure" return JsonResponse(result, status=200) logger.debug("image_url is {}".format(image_url)) # 启动命令 start_cmd = request.POST.get("start_cmd", "") service = ServiceInfo() service.service_key = "0000" service.desc = "" service.category = "app_publish" service.image = image_url service.cmd = start_cmd service.setting = "" service.extend_method = "stateless" service.env = "," service.min_node = 1 cm = 128 if image_service_memory != "": cm = int(image_service_memory) if cm < 128: cm *= 1024 service.min_memory = cm service.min_cpu = baseService.calculate_service_cpu( self.response_region, cm) service.inner_port = 0 # version version需要从image_url中分析出来 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 # calculate resource tempService = TenantServiceInfo() tempService.min_memory = cm tempService.service_region = self.response_region tempService.min_node = int(service.min_node) diffMemory = cm # 判断是否超出资源 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) 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-image" newTenantService.save() self.service = newTenantService 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) self.save_ports_envs_and_volumes(port_list, env_list, volume_list, newTenantService) baseService.create_region_service(newTenantService, self.tenantName, self.response_region, self.user.nick_name, dep_sids=json.dumps([])) baseService.batch_add_dep_volume_v2(self.tenant, self.service, service_alias_list) data = {} data[ "label_values"] = "无状态的应用" if service_status == "stateless" else "有状态的应用" data["enterprise_id"] = self.tenant.enterprise_id region_api.update_service_state_label(self.response_region, self.tenantName, self.service.service_alias, data) self.service.extend_method = service_status self.service.save() # 发送build请求 body = {} event = self.create_service_event(newTenantService, self.tenant, "deploy") kind = "image" body["event_id"] = event.event_id body["deploy_version"] = newTenantService.deploy_version body["operator"] = self.user.nick_name body["action"] = "upgrade" body["kind"] = kind envs = {} buildEnvs = TenantServiceEnvVar.objects.filter( service_id=service_id, attr_name__in=("COMPILE_ENV", "NO_CACHE", "DEBUG", "PROXY", "SBT_EXTRAS_OPTS")) for benv in buildEnvs: envs[benv.attr_name] = benv.attr_value body["envs"] = envs body["enterprise_id"] = self.tenant.enterprise_id region_api.build_service(newTenantService.service_region, self.tenantName, newTenantService.service_alias, body) monitorhook.serviceMonitor(self.user.nick_name, newTenantService, 'init_region_service', True) logger.debug(depIds) for sid in depIds: try: baseService.create_service_dependency( self.tenant, newTenantService, sid, self.response_region) except Exception as e: logger.exception(e) result["status"] = "success" result["service_id"] = service_id result["service_alias"] = service_alias attach_info_mamage.update_attach_info_by_tenant( self.tenant, self.service)
def init(self): self.sources = [ Tenants(), TenantRegionInfo(), TenantRegionResource(), ServiceInfo(), TenantServiceInfo(), TenantServiceInfoDelete(), TenantServiceLog(), TenantServiceRelation(), TenantServiceEnv(), TenantServiceAuth(), TenantServiceExtendMethod(), ServiceDomain(), ServiceDomainCertificate(), PermRelService(), PermRelTenant(), PhoneCode(), TenantServiceL7Info(), TenantServiceEnvVar(), TenantServicesPort(), TenantServiceMountRelation(), TenantServiceVolume(), TenantServiceConfigurationFile(), ServiceGroup(), ServiceGroupRelation(), ImageServiceRelation(), ComposeServiceRelation(), ServiceRule(), ServiceRuleHistory(), ServiceCreateStep(), ServiceProbe(), ConsoleConfig(), TenantEnterprise(), TenantEnterpriseToken(), TenantServiceGroup(), ServiceTcpDomain(), ThirdPartyServiceEndpoints(), ServiceWebhooks(), GatewayCustomConfiguration(), ConsoleSysConfig(), RainbondCenterApp(), RainbondCenterAppInherit(), RainbondCenterPlugin(), ServiceShareRecord(), EnterpriseUserPerm(), TenantUserRole(), TenantUserPermission(), TenantUserRolePermission(), PermGroup(), ServiceRelPerms(), AppExportRecord(), UserMessage(), AppImportRecord(), GroupAppBackupRecord(), GroupAppMigrateRecord(), GroupAppBackupImportRecord(), Applicants(), DeployRelation(), ServiceBuildSource(), TenantServiceBackup(), AppUpgradeRecord(), ServiceUpgradeRecord(), RegionConfig(), CloundBangImages(), Announcement(), ]