diff --git a/console/services/helm_app_yaml.py b/console/services/helm_app_yaml.py index 377cc6b68f..8940ce0065 100644 --- a/console/services/helm_app_yaml.py +++ b/console/services/helm_app_yaml.py @@ -1,14 +1,13 @@ import datetime import json import logging +import re import time +from console.exception.main import AbortRequest from console.models.main import RainbondCenterApp, RainbondCenterAppVersion, AppHelmOverrides from console.repositories.helm import helm_repo -from console.services.app_actions import app_manage_service -from console.services.region_resource_processing import region_resource from www.apiclient.regionapi import RegionInvokeApi -from www.models.main import RegionApp from www.utils.crypt import make_uuid3, make_uuid region_api = RegionInvokeApi() @@ -256,82 +255,61 @@ def get_helm_chart_information(self, region, tenant_name, repo_url, chart_name): _, body = region_api.get_chart_information(region, tenant_name, repo_chart) return body["bean"] - def get_command_install_yaml(self, region, tenant_name, command): - _, body = region_api.command_helm_yaml(region, tenant_name, {"command": command}) - return body["bean"] - - def tgz_yaml_handle(self, eid, region, tenant, app_id, user, data): - app = RegionApp.objects.filter(app_id=app_id) - if app: - app = app[0] - data = { - "event_id": "", - "region_app_id": app.region_app_id, - "tenant_id": tenant.tenant_id, - "namespace": tenant.namespace, - "yaml": data.get("yaml", "") - } - _, body = region_api.yaml_resource_import(eid, region.region_id, data) - ac = body["bean"] - region_resource.create_k8s_resources(ac["k8s_resources"], app_id) - service_ids = region_resource.create_components(app, ac["component"], tenant, region.region_name, user.user_id) - app_manage_service.batch_action(region.region_name, tenant, user, "deploy", service_ids, None, None) - - def repo_yaml_handle(self, eid, region_id, command, region_name, tenant, data, user_id): - logger.info("begin function repo_yaml_handle") - cmd_list = command.split() - repo_name, repo_url, username, password, chart_name, version = "", "", "", "", "", "" - overrides = list() - logger.info("parse the helm command") - for i in range(len(cmd_list)): - if cmd_list[i] == "--repo" and i + 1 != len(cmd_list): - repo_url = cmd_list[i + 1] - repo_name = repo_url.split("/")[-1] - if repo_name == "" or len(repo_name) > 32: - repo_name = "rainbond" - if cmd_list[i] == "--username" and i + 1 != len(cmd_list): - username = cmd_list[i + 1] - if cmd_list[i] == "--version" and i + 1 != len(cmd_list): - version = cmd_list[i + 1] - if cmd_list[i] == "--password" and i + 1 != len(cmd_list): - password = cmd_list[i + 1] - if cmd_list[i] == "--set" and i + 1 != len(cmd_list): - overrides.append(cmd_list[i + 1]) - if not cmd_list[i].startswith('-') and i + 1 != len(cmd_list): - if not cmd_list[i + 1].startswith('-'): - chart_name = cmd_list[i + 1] - overrides = [{override.split("=")[0]: override.split("=")[1]} for override in overrides] - if not repo_name: - return None - chart_data = self.get_helm_chart_information(region_name, tenant.tenant_name, repo_url, chart_name) - if not version: - logger.warning("version is not obtained from the command.use the highest version of {}".format(chart_name)) - version = chart_data[0]["Version"] - i = 0 - repo_name = repo_name + "cmd" - while True: - i = i + 1 - repo_name = repo_name + str(i) + def parse_helm_command(self, command, region_name, tenant): + result = dict() + repo_add_pattern = r'^helm\s+repo\s+add\s+(?P\S+)\s+(?P\S+)(?:\s+--username\s+(?P\S+))?(?:\s+--password\s+(?P\S+))?$' + repo_add_match = re.match(repo_add_pattern, command) + if repo_add_match: + result['command'] = 'repo_add' + repo_name = repo_add_match.group('repo_name') + repo_url = repo_add_match.group('repo_url') + username = repo_add_match.group('username') if repo_add_match.group('username') else "" + password = repo_add_match.group('password') if repo_add_match.group('password') else "" repo = helm_repo.get_helm_repo_by_name(repo_name) if not repo: logger.info("create helm repo {}".format(repo_name)) self.add_helm_repo(repo_name, repo_url, username, password) - break else: - if repo["repo_url"] == repo_url: - logger.info("helm repo {} is exist and url is the same".format(repo_name)) - break + raise AbortRequest("helm repo is exist", "仓库名称已存在", status_code=404, error_code=404) + result["repo_name"] = repo_name + result["repo_url"] = repo_url + result["username"] = username + result["password"] = password + return result - return { - "version": version, - "repo_name": repo_name, - "repo_url": repo_url, - "username": username, - "password": password, - "chart_name": chart_name, - "eid": eid, - "overrides": overrides - } + install_pattern = r'^helm\s+install\s+(?P\S+)\s+(?P\S+)(?:(?:\s+--version\s+(?P\S+))?(?P(?:\s+--set\s+[^-].*)*))?$' + set_pattern = r'--set\s+([^=]+)=([^ \s]+)' + + install_match = re.match(install_pattern, command) + if install_match: + result['command'] = 'install' + release_name = install_match.group('release_name') + version = install_match.group('version') + chart = install_match.group('chart') + result['overrides'] = list() + set_values_str = install_match.group('set_values') + if set_values_str: + set_values = re.findall(set_pattern, set_values_str) + for key, value in set_values: + result['overrides'].append({key.strip(): value.strip()}) + repo_name = chart.split("/")[0] + chart_name = chart.split("/")[1] + repo = helm_repo.get_helm_repo_by_name(repo_name) + if not repo: + raise AbortRequest("helm repo is not exist", "商店不存在,执行 helm repo add 进行添加", status_code=404, error_code=404) + repo_url = repo.get("repo_url") + chart_data = self.get_helm_chart_information(region_name, tenant.tenant_name, repo_url, chart_name) + if not version: + logger.warning("version is not obtained from the command.use the highest version of {}".format(chart_name)) + version = chart_data[0]["Version"] + result["release_name"] = release_name + result["chart"] = chart + result["version"] = version + result["repo_name"] = repo_name + result["repo_url"] = repo_url + result["chart_name"] = chart_name + return result + raise AbortRequest("helm command command mismatch", "命令解析失败,请检查命令", status_code=404, error_code=404) helm_app_service = HelmAppService() diff --git a/console/views/helm_app.py b/console/views/helm_app.py index 85c8680533..8cb543895e 100644 --- a/console/views/helm_app.py +++ b/console/views/helm_app.py @@ -128,29 +128,9 @@ def post(self, request, *args, **kwargs): 命令安装helm应用 """ command = request.data.get("command") - app_id = request.data.get("app_id") - command = command.replace("helm install", "template", 1) - command_yaml_data = helm_app_service.get_command_install_yaml(self.region_name, self.tenant_name, command) - ret = dict() - ret["information"] = command_yaml_data.get("yaml", "") - ret["status"] = command_yaml_data.get("status", False) - if command_yaml_data["status"]: - ret["status"] = True - if str(command).endswith('tgz'): - ret["tgz"] = True - helm_app_service.tgz_yaml_handle(self.enterprise.enterprise_id, self.region, self.tenant, app_id, self.user, - command_yaml_data) - ret["information"] = "" - else: - ret["tgz"] = False - data = helm_app_service.repo_yaml_handle(self.enterprise.enterprise_id, self.region.region_id, command, - self.region_name, self.tenant, command_yaml_data, self.user.user_id) - ret["information"] = "" - if not data: - ret["status"] = False - ret["information"] = "未从命令中获取到chart名字" - ret["chart"] = data - result = general_message(200, "success", "执行成功", bean=ret) + data = helm_app_service.parse_helm_command(command, self.region_name, self.tenant) + data['eid'] = self.enterprise.enterprise_id + result = general_message(200, "success", "执行成功", bean=data) return Response(result, status=status.HTTP_200_OK) diff --git a/www/apiclient/regionapi.py b/www/apiclient/regionapi.py index fc9462e9ee..b153d611f5 100644 --- a/www/apiclient/regionapi.py +++ b/www/apiclient/regionapi.py @@ -565,13 +565,6 @@ def get_volume_options(self, region, tenant_name): res, body = self._get(url, self.default_headers, region=region) return body - def command_helm_yaml(self, region, tenant_name, data): - uri_prefix, token = self.__get_region_access_info(tenant_name, region) - url = uri_prefix + "/v2/helm/command_helm" - self._set_headers(token) - res, body = self._get(url, self.default_headers, region=region, body=json.dumps(data), timeout=20) - return res, body - def get_chart_information(self, region, tenant_name, data): uri_prefix, token = self.__get_region_access_info(tenant_name, region) url = uri_prefix + "/v2/helm/get_chart_information"