def import_execute(host, auth, upload_id, menu_list, upload_filename): """インポート実行 Args: host (str): ITAのホスト auth (str): ITAの認証情報 upload_id (str): upload id menu_list (str): menu items upload_filename (str): filename Raises: Exception: [description] Returns: str: task id """ globals.logger.debug('---- execute menu import ----') # POST送信する # ヘッダ情報 header = { 'host': host, 'Content-Type': 'application/json', 'Authorization': auth, 'X-Command': 'EXECUTE', } # 実行パラメータ設定 data = menu_list data["upload_id"] = "A_" + upload_id data["data_portability_upload_file_name"] = upload_filename # json文字列に変換("utf-8"形式に自動エンコードされる) json_data = json.dumps(data) # リクエスト送信 exec_response = requests.post( 'http://' + host + '/default/menu/07_rest_api_ver1.php?no=2100000212', headers=header, data=json_data) if exec_response.status_code != 200: globals.logger.error("no=2100000212 status_code:{}".format( exec_response.status_code)) globals.logger.error(exec_response.text) raise common.UserException(exec_response.text) globals.logger.debug(exec_response.text) exec_resp_data = json.loads(exec_response.text) if exec_resp_data["status"] != "SUCCEED" or exec_resp_data["resultdata"][ "RESULTCODE"] != "000": globals.logger.error("no=2100000212 status:{}".format( exec_resp_data["status"])) globals.logger.error(exec_response.text) raise common.UserException(exec_response.text) task_id = exec_resp_data["resultdata"]["TASK_ID"] globals.logger.debug('task_id: ' + task_id) return task_id
def get_ci_pipeline_result_logs(workspace_id, taskrun_name): app_name = "TEKTONタスク実行ログ:" exec_stat = "情報取得" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format(inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # Get Query Parameter latest = request.args.get('latest', default='False') # ヘッダ情報 post_headers = { 'Content-Type': 'application/json', } # epoch-control-tekton-api の呼び先設定 api_url_tekton = "{}://{}:{}/workspace/{}/tekton/taskrun/{}/logs".format( os.environ["EPOCH_CONTROL_TEKTON_PROTOCOL"], os.environ["EPOCH_CONTROL_TEKTON_HOST"], os.environ["EPOCH_CONTROL_TEKTON_PORT"], workspace_id, taskrun_name) # TEKTONタスク実行ログ情報取得 exec_stat = "taskrunログ情報取得" request_response = requests.get(api_url_tekton, params={"latest": latest}) ret = json.loads(request_response.text) if request_response.status_code != 200: if "errorDetail" in ret: error_detail = ret["errorDetail"] else: error_detail = "" raise common.UserException(error_detail) ret_status = 200 response = { "result": ret_status, "log" : ret["log"], } # 戻り値をそのまま返却 return jsonify(response), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def get_users(): """ユーザー情報一覧取得 user info list get Returns: Response: HTTP Respose """ app_name = multi_lang.get_text("EP020-0001", "ユーザー情報:") exec_stat = multi_lang.get_text("EP020-0002", "一覧取得") error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format(inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) api_url = "{}://{}:{}/{}/user".format(os.environ['EPOCH_EPAI_API_PROTOCOL'], os.environ['EPOCH_EPAI_API_HOST'], os.environ['EPOCH_EPAI_API_PORT'], os.environ["EPOCH_EPAI_REALM_NAME"], ) # # get users - ユーザー取得 # response = requests.get(api_url) if response.status_code != 200 and response.status_code != 404: error_detail = multi_lang.get_text("EP020-0008", "ユーザー情報の取得に失敗しました") raise common.UserException("{} Error user get status:{}".format(inspect.currentframe().f_code.co_name, response.status_code)) users = json.loads(response.text) # globals.logger.debug(f"users:{users}") ret_users = [] for user in users["rows"]: ret_user = { "user_id": user["id"], "username": user["username"], } ret_users.append(ret_user) rows = ret_users return jsonify({"result": "200", "rows": rows}), 200 except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def monitoring_argo_cd(): """Argo CD 監視 Returns: None """ global global_argocd_error_count try: globals.logger.debug("monitoring argo cd!") # ヘッダ情報 header info. post_headers = { 'Content-Type': 'application/json', } # ArgoCDの監視する状態は、ITA完了, ArgoCD同期中、ArgoCD処理中とする # The monitoring status of IT-Automation is CD execution start, ITA reservation, and ITA execution. cd_status_in = "{}.{}.{}".format(const.CD_STATUS_ITA_COMPLETE, const.CD_STATUS_ARGOCD_SYNC, const.CD_STATUS_ARGOCD_PROCESSING) # cd-result get api_url = "{}://{}:{}/cd/result?cd_status_in={}".format( os.environ['EPOCH_RS_CD_RESULT_PROTOCOL'], os.environ['EPOCH_RS_CD_RESULT_HOST'], os.environ['EPOCH_RS_CD_RESULT_PORT'], cd_status_in) response = requests.get(api_url) if response.status_code != 200: raise Exception("cd result get error:[{}]".format( response.status_code)) ret = json.loads(response.text) result_rows = ret["rows"] error_exists = False # 明細数分処理する Process for the number of items for result_row in result_rows: # 繰り返し中のUserExceptionは、データを全件処理するため無視する # UserException during repetition is ignored because all data is processed. try: globals.logger.debug( "cd-result workspace_id:[{}] cd_result_id:[{}] cd_status:[{}]" .format(result_row["workspace_id"], result_row["cd_result_id"], result_row["cd_status"])) # ITAの同期が完了したら、ArgoCDのSyncを呼び出す # Call ArgoCD Sync when ITA sync is complete if result_row["cd_status"] == const.CD_STATUS_ITA_COMPLETE: # 状態をArgoCD同期中に変更 contents = json.loads(result_row["contents"]) # get argocd app name app_name = env_name_to_argo_app_name( result_row["workspace_id"], contents["workspace_info"] ["cd_config"]["environments"], contents["environment_name"]) # ArgoCD Sync call api_url = "{}://{}:{}/workspace/{}/argocd/app/{}/sync".format( os.environ['EPOCH_CONTROL_ARGOCD_PROTOCOL'], os.environ['EPOCH_CONTROL_ARGOCD_HOST'], os.environ['EPOCH_CONTROL_ARGOCD_PORT'], result_row["workspace_id"], app_name) response = requests.post(api_url, headers=post_headers) if response.status_code != 200: raise common.UserException( "argocd sync post error:[{}]".format( response.status_code)) # 状態をArgoCD同期中に変更 post_data = { "cd_status": const.CD_STATUS_ARGOCD_SYNC, } # cd-result put api_url = "{}://{}:{}/workspace/{}/cd/result/{}".format( os.environ['EPOCH_RS_CD_RESULT_PROTOCOL'], os.environ['EPOCH_RS_CD_RESULT_HOST'], os.environ['EPOCH_RS_CD_RESULT_PORT'], result_row["workspace_id"], result_row["cd_result_id"]) response = requests.put(api_url, headers=post_headers, data=json.dumps(post_data)) if response.status_code != 200: raise common.UserException( "cd result put error:[{}]".format( response.status_code)) else: # ArgoCDの結果を取得して、状態を確認する # Get the result of ArgoCD and check the status contents = json.loads(result_row["contents"]) # get argocd app name app_name = env_name_to_argo_app_name( result_row["workspace_id"], contents["workspace_info"] ["cd_config"]["environments"], contents["environment_name"]) # ArgoCD app get call api_url = "{}://{}:{}/workspace/{}/argocd/app/{}".format( os.environ['EPOCH_CONTROL_ARGOCD_PROTOCOL'], os.environ['EPOCH_CONTROL_ARGOCD_HOST'], os.environ['EPOCH_CONTROL_ARGOCD_PORT'], result_row["workspace_id"], app_name) response = requests.get(api_url) if response.status_code != 200: raise common.UserException( "argocd app get error:[{}]".format( response.status_code)) # 戻り値を取得 Get the return value ret_argocd_app = json.loads(response.text) # globals.logger.debug("argocd result [{}]".format(ret_argocd_app)) # 対象のオブジェクトがあるかどうかチェックする # Check if there is an object of interest if "sync" not in ret_argocd_app["result"]["status"]: continue if "revision" not in ret_argocd_app["result"]["status"][ "sync"]: continue # manifestのrivisionを元に該当のトレースIDの履歴かチェックする # Check if the history of the corresponding trace ID is based on the revision of the manifest revision = ret_argocd_app["result"]["status"]["sync"][ "revision"] manifest_url = ret_argocd_app["result"]["status"]["sync"][ "comparedTo"]["source"]["repoURL"] git_token = contents["workspace_info"]["cd_config"][ "environments_common"]["git_repositry"]["token"] # ヘッダ情報 header info. post_headers_in_token = { 'private-token': git_token, 'Content-Type': 'application/json', } if contents["workspace_info"]["cd_config"][ "environments_common"]["git_repositry"][ "housing"] == const.HOUSING_INNER: # EPOCH内レジストリ Registry in EPOCH api_url = "{}://{}:{}/commits/{}?git_url={}".format( os.environ['EPOCH_CONTROL_INSIDE_GITLAB_PROTOCOL'], os.environ['EPOCH_CONTROL_INSIDE_GITLAB_HOST'], os.environ['EPOCH_CONTROL_INSIDE_GITLAB_PORT'], revision, urllib.parse.quote(manifest_url)) response = requests.get(api_url, headers=post_headers_in_token) if response.status_code != 200: raise common.UserException( "git commit get error:[{}]".format( response.status_code)) ret_git_commit = json.loads(response.text) commit_message = ret_git_commit["rows"]["message"] else: # GitHub commit get api_url = "{}://{}:{}/commits/{}?git_url={}".format( os.environ['EPOCH_CONTROL_GITHUB_PROTOCOL'], os.environ['EPOCH_CONTROL_GITHUB_HOST'], os.environ['EPOCH_CONTROL_GITHUB_PORT'], revision, urllib.parse.quote(manifest_url)) response = requests.get(api_url, headers=post_headers_in_token) if response.status_code != 200: raise common.UserException( "git commit get error:[{}]".format( response.status_code)) ret_git_commit = json.loads(response.text) # globals.logger.debug("rows:[{}]".format(ret_git_commit["rows"])) commit_message = ret_git_commit["rows"]["commit"][ "message"] globals.logger.debug( "trace_id:[{}] vs commit_message10[{}]".format( contents["trace_id"], commit_message[:10])) # 上10桁が一致している場合のみステータスのチェックを行う if contents["trace_id"] != commit_message[:10]: continue # ArgoCDの戻り値が正常化どうかチェックして該当のステータスを設定 # Check if the return value of ArgoCD is normal and set the corresponding status if ret_argocd_app["result"]["status"]["health"][ "status"] == const.ARGOCD_HEALTH_STATUS_HEALTHY: cd_status = const.CD_STATUS_ARGOCD_SYNCED elif ret_argocd_app["result"]["status"]["health"][ "status"] == const.ARGOCD_HEALTH_STATUS_DEGRADED: cd_status = const.CD_STATUS_ARGOCD_FAILED elif ret_argocd_app["result"]["status"]["health"][ "status"] == const.ARGOCD_HEALTH_STATUS_PROGRESSING: cd_status = const.CD_STATUS_ARGOCD_PROCESSING elif ret_argocd_app["result"]["status"]["health"][ "status"] == const.ARGOCD_HEALTH_STATUS_SUSPENDED: cd_status = const.CD_STATUS_ARGOCD_FAILED elif ret_argocd_app["result"]["status"]["health"][ "status"] == const.ARGOCD_HEALTH_STATUS_MISSING: cd_status = const.CD_STATUS_ARGOCD_FAILED else: cd_status = const.CD_STATUS_ARGOCD_FAILED # 変更したい項目のみ設定(cd_statusは必須) # Set only the items you want to change (cd_status is required) post_data = { "cd_status": cd_status, "argocd_results": ret_argocd_app, } # cd-result put api_url = "{}://{}:{}/workspace/{}/cd/result/{}".format( os.environ['EPOCH_RS_CD_RESULT_PROTOCOL'], os.environ['EPOCH_RS_CD_RESULT_HOST'], os.environ['EPOCH_RS_CD_RESULT_PORT'], result_row["workspace_id"], result_row["cd_result_id"]) response = requests.put(api_url, headers=post_headers, data=json.dumps(post_data)) if response.status_code != 200: raise common.UserException( "cd result put error:[{}]".format( response.status_code)) except common.UserException as e: error_exists = True global_argocd_error_count += 1 globals.logger.debug("UserException error count [{}]".format( global_argocd_error_count)) globals.logger.debug( "UserException Exception error args [{}]".format(e.args)) if not error_exists: # 正常時はエラーをリセット Reset error when normal global_argocd_error_count = 0 except Exception as e: global_argocd_error_count += 1 globals.logger.debug("argocd Exception error count [{}]".format( global_argocd_error_count)) globals.logger.debug("argocd Exception error args [{}]".format(e.args)) return common.serverError(e)
def monitoring_it_automation(): """IT-Automation 監視 Returns: None """ global global_ita_error_count try: globals.logger.debug("monitoring it-automation!") # ヘッダ情報 header info. post_headers = { 'Content-Type': 'application/json', } # IT-Automationの監視する状態は、CD実行開始, ITA予約、ITA実行中とする # The monitoring status of IT-Automation is CD execution start, ITA reservation, and ITA execution. cd_status_in = "{}.{}.{}".format(const.CD_STATUS_START, const.CD_STATUS_ITA_RESERVE, const.CD_STATUS_ITA_EXECUTE) # cd-result get api_url = "{}://{}:{}/cd/result?cd_status_in={}".format( os.environ['EPOCH_RS_CD_RESULT_PROTOCOL'], os.environ['EPOCH_RS_CD_RESULT_HOST'], os.environ['EPOCH_RS_CD_RESULT_PORT'], cd_status_in) response = requests.get(api_url) if response.status_code != 200: raise Exception("cd result get error:[{}]".format( response.status_code)) ret = json.loads(response.text) result_rows = ret["rows"] error_exists = False # 明細数分処理する Process for the number of items for result_row in result_rows: # 繰り返し中のUserExceptionは、データを全件処理するため無視する # UserException during repetition is ignored because all data is processed. try: globals.logger.debug( "cd-result workspace_id:[{}] cd_result_id:[{}] cd_status:[{}]" .format(result_row["workspace_id"], result_row["cd_result_id"], result_row["cd_status"])) workspace_id = result_row["workspace_id"] conductor_instance_id = int( result_row["cd_result_id"] ) # インスタンスIDは、0埋め無しの数値 Instance ID is a number without 0 padding # ステータスが"Start"または"Reserve" or "Excute"の場合はITAから結果を取得する if result_row["cd_status"] == const.CD_STATUS_START or \ result_row["cd_status"] == const.CD_STATUS_ITA_RESERVE or \ result_row["cd_status"] == const.CD_STATUS_ITA_EXECUTE: # cd-result get api_url = "{}://{}:{}/workspace/{}/it-automation/cd/result/{}".format( os.environ['EPOCH_CONTROL_ITA_PROTOCOL'], os.environ['EPOCH_CONTROL_ITA_HOST'], os.environ['EPOCH_CONTROL_ITA_PORT'], workspace_id, conductor_instance_id) response = requests.get(api_url) if response.status_code != 200: raise Exception( "it-automation cd result get error:[{}]".format( response.status_code)) ret = json.loads(response.text) globals.logger.debug( "it-automation cd-result workspace_id:[{}] cd_result_id:[{}] ret[{}]" .format(result_row["workspace_id"], result_row["cd_result_id"], ret)) ita_rows = ret["rows"]["resultdata"] # ステータスIDが存在する場合のみ処理 # Process only if status ID exists if "STATUS_ID" in ita_rows["CONDUCTOR_INSTANCE_INFO"]: # 実行中になった場合は、実行中のステータスに更新 # If it becomes running, update to running status if ita_rows["CONDUCTOR_INSTANCE_INFO"]["STATUS_ID"] == const.ITA_STATUS_ID_EXECUTING or \ ita_rows["CONDUCTOR_INSTANCE_INFO"]["STATUS_ID"] == const.ITA_STATUS_ID_EXEC_DELAY: cd_status = const.CD_STATUS_ITA_EXECUTE # 予約中になった場合は、予約中のステータスに更新 # If it is reserved, it will be updated to the reserved status. elif ita_rows["CONDUCTOR_INSTANCE_INFO"][ "STATUS_ID"] == const.ITA_STATUS_ID_RESERVED: cd_status = const.CD_STATUS_ITA_RESERVE # 緊急停止された場合は、緊急停止のステータスに更新 # In case of emergency stop, update to emergency stop status elif ita_rows["CONDUCTOR_INSTANCE_INFO"][ "STATUS_ID"] == const.ITA_STATUS_ID_EMERGENCY: cd_status = const.CD_STATUS_ITA_EMERGENCY # 正常終了した場合は、正常終了のステータスに更新 # If it ends normally, it will be updated to the status of normal end. elif ita_rows["CONDUCTOR_INSTANCE_INFO"][ "STATUS_ID"] == const.ITA_STATUS_ID_COMPLETE: cd_status = const.CD_STATUS_ITA_COMPLETE # 予約取消となった場合は、キャンセルのステータスに更新 # If the reservation is canceled, it will be updated to the cancellation status. elif ita_rows["CONDUCTOR_INSTANCE_INFO"][ "STATUS_ID"] == const.ITA_STATUS_ID_CANCEL: cd_status = const.CD_STATUS_CANCEL # 異常終了・想定外エラー・警告終了した場合は、失敗のステータスに更新 # Abnormal termination / unexpected error / warning If terminated, update to failure status elif ita_rows["CONDUCTOR_INSTANCE_INFO"]["STATUS_ID"] == const.ITA_STATUS_ID_ABNORMAL_END or \ ita_rows["CONDUCTOR_INSTANCE_INFO"]["STATUS_ID"] == const.ITA_STATUS_ID_UNEXPECTED or \ ita_rows["CONDUCTOR_INSTANCE_INFO"]["STATUS_ID"] == const.ITA_STATUS_ID_WARNING: cd_status = const.CD_STATUS_ITA_FAILED # 未実行の場合は、なにもしない更新 # If not executed, update without doing anything elif ita_rows["CONDUCTOR_INSTANCE_INFO"][ "STATUS_ID"] == const.ITA_STATUS_ID_NOT_EXECUTED: cd_status = result_row["cd_status"] else: # 上記以外はエラー # Errors other than the abov cd_status = const.CD_STATUS_ITA_FAILED else: # 取得失敗 Acquisition failure cd_status = const.CD_STATUS_ITA_FAILED # ステータスが更新されるか、実行中は更新 # Status is updated or updated while running if cd_status != result_row["cd_status"] or \ cd_status == const.CD_STATUS_ITA_EXECUTE: # post_data = json.loads(result_row["contents"]) # cd-result get api_url = "{}://{}:{}/workspace/{}/it-automation/cd/result/{}/logs".format( os.environ['EPOCH_CONTROL_ITA_PROTOCOL'], os.environ['EPOCH_CONTROL_ITA_HOST'], os.environ['EPOCH_CONTROL_ITA_PORT'], workspace_id, conductor_instance_id) response = requests.get(api_url) if response.status_code != 200 and response.status_code != 404: raise Exception( "it-automation cd result logs get error:[{}]". format(response.status_code)) ret_logs = json.loads(response.text) globals.logger.debug( "it-automation cd-result logs[{}]".format( result_row["workspace_id"], result_row["cd_result_id"], ret_logs)) ita_rows["manifest_embedding"] = ret_logs["rows"][ "manifest_embedding"] ita_rows["manifest_commit_push"] = ret_logs["rows"][ "manifest_commit_push"] #globals.logger.debug(post_data) # post_data["cd_status"] = const.CD_STATUS_ITA_COMPLETE post_data = { "cd_status": cd_status, "ita_results": ita_rows, } # cd-result put api_url = "{}://{}:{}/workspace/{}/cd/result/{}".format( os.environ['EPOCH_RS_CD_RESULT_PROTOCOL'], os.environ['EPOCH_RS_CD_RESULT_HOST'], os.environ['EPOCH_RS_CD_RESULT_PORT'], result_row["workspace_id"], result_row["cd_result_id"]) response = requests.put(api_url, headers=post_headers, data=json.dumps(post_data)) if response.status_code != 200: raise common.UserException( "cd result put error:[{}]".format( response.status_code)) except common.UserException as e: error_exists = True global_ita_error_count += 1 globals.logger.debug("UserException error count [{}]".format( global_ita_error_count)) globals.logger.debug( "UserException Exception error args [{}]".format(e.args)) if not error_exists: # 正常時はエラーをリセット Reset error when normal global_ita_error_count = 0 except Exception as e: global_ita_error_count += 1 globals.logger.debug("it-automation Exception error count [{}]".format( global_ita_error_count)) globals.logger.debug("it-automation Exception error args [{}]".format( e.args)) return common.serverError(e)
def cd_result_logs_get(workspace_id, conductor_id): """CD実行結果ログ取得 cd result logs get Args: workspace_id (int): workspace id conductor_id (str): conductor id Returns: Response: HTTP Respose """ try: globals.logger.debug('#' * 50) globals.logger.debug( 'CALL {} workspace_id[{}] conductor_id[{}]'.format( inspect.currentframe().f_code.co_name, workspace_id, conductor_id)) globals.logger.debug('#' * 50) # ワークスペースアクセス情報取得 get workspace access info. access_info = api_access_info.get_access_info(workspace_id) # namespaceの取得 get namespace namespace = common.get_namespace_name(workspace_id) ita_restapi_endpoint = "http://{}.{}.svc:{}/default/menu/07_rest_api_ver1.php".format( EPOCH_ITA_HOST, namespace, EPOCH_ITA_PORT) ita_user = access_info['ITA_USER'] ita_pass = access_info['ITA_PASSWORD'] # POST送信する post sender # HTTPヘッダの生成 HTTP header generation filter_headers = { 'host': EPOCH_ITA_HOST + ':' + EPOCH_ITA_PORT, 'Content-Type': 'application/json', 'Authorization': base64.b64encode( (ita_user + ':' + ita_pass).encode()), 'X-Command': 'DOWNLOAD', } # 実行パラメータ設定 parameter setting data = {"CONDUCTOR_INSTANCE_NO": [str(int(conductor_id) + 1)]} # json文字列に変換 json convert json_data = json.dumps(data) # リクエスト送信 request post exec_response = requests.post(ita_restapi_endpoint + '?no=' + ite_menu_conductor_download, headers=filter_headers, data=json_data) if exec_response.status_code != 200: globals.logger.error(exec_response.text) error_detail = multi_lang.get_text( "EP034-0007", "実行結果ログ取得の呼び出しに失敗しました status:{0}".format( exec_response.status_code), exec_response.status_code) raise common.UserException(error_detail) # globals.logger.debug("-------------------------") # globals.logger.debug("response:") # globals.logger.debug(exec_response) # globals.logger.debug("response_text:") # globals.logger.debug(exec_response.text) # globals.logger.debug("-------------------------") # 戻り値用の器設定 Device setting for return value rows = { "manifest_embedding": {}, "manifest_commit_push": {}, } # 実行してすぐは読込ができない状況があるのでチェックする # Check because there are situations where it cannot be read immediately after execution. if not common.is_json_format(exec_response.text): # 実行途中の正常終了として返す Returns as normal termination during execution globals.logger.debug("not start!") ret_status = 404 # 実行前なので404を返却 Return 404 because it is before execution return jsonify({"result": ret_status, "rows": rows}), ret_status resp_data = json.loads(exec_response.text) # globals.logger.debug(f"resp_data:{resp_data}") if resp_data["status"] != "SUCCEED": globals.logger.error("no={} status:{}".format( ite_menu_conductor_exec, resp_data["status"])) error_detail = multi_lang.get_text( "EP034-0008", "実行結果ログ取得の呼び出しに失敗しました ita-status:{0} resultdata:{1}".format( eresp_data["status"], eresp_data["resultdata"]), eresp_data["status"], eresp_data["resultdata"]) raise common.UserException(error_detail) body_cnt = 0 for body in resp_data["resultdata"]["CONTENTS"]["BODY"]: # download_input_key = body["INPUT_DATA"] # base64_input_log_zip = resp_data["resultdata"]["CONTENTS"]["DOWNLOAD"][download_key] download_result_key = body["RESULT_DATA"] base64_result_log_zip = resp_data["resultdata"]["CONTENTS"][ "DOWNLOAD_FILE"][body_cnt][download_result_key] # globals.logger.debug(f"base64_result_log_zip:{base64_result_log_zip}") binary_result_log_zip = base64.b64decode( base64_result_log_zip.encode()) with tempfile.TemporaryDirectory() as tempdir: # zipファイル生成 Zip file generation path_zip_file = '{}/{}'.format(tempdir, download_result_key) # globals.logger.debug(f"path_zip_file:{path_zip_file}") with open(path_zip_file, mode='bw') as fp: fp.write(binary_result_log_zip) # zipファイルに含まれているファイル名の取得 # Get the file name contained in the zip file with zipfile.ZipFile(path_zip_file) as log_zip: # zipファイルに含まれているファイルのリストを返す # Returns a list of files contained in the zip file for f in log_zip.namelist(): # ファイル名の末尾が"/"じゃない内容を解凍 # Unzip the contents that do not end with "/" in the file name if f[-1:] != "/": # globals.logger.debug(f"f:{f}") # zipファイルに含まれているファイルを取り出す # Extract the files contained in the zip file log_zip.extract(f, tempdir) # 解凍した各フォルダの内容を再度解凍 # Unzip the contents of each unzipped folder again files = glob.glob(tempdir + "/**/*.zip") for file in files: # globals.logger.debug(f"file:{file}") with zipfile.ZipFile(file) as log_zip: for f in log_zip.namelist(): if f == "exec.log": # 実行ログ Execution log # globals.logger.debug(f"f:{f}") with log_zip.open(f) as f_log: exec_logs = f_log.read() # globals.logger.debug(f"logs:{exec_logs}") elif f == "error.log": # エラーログ error log # globals.logger.debug(f"f:{f}") with log_zip.open(f) as f_log: error_logs = f_log.read() # globals.logger.debug(f"logs:{error_logs}") sub_dir_name = os.path.basename(os.path.dirname(file)) # globals.logger.debug(f"sub_dir_name:{sub_dir_name}") if sub_dir_name == "0000000001": # フォルダの1番目は、Manifest埋め込みのログ # The first folder is the Manifest embedded log rows["manifest_embedding"] = { "execute_logs": exec_logs.decode('utf-8'), "error_logs": error_logs.decode('utf-8'), } elif sub_dir_name == "0000000002": # フォルダの2番目は、Manifest Commit&Pushのログ # The second folder is the Manifest Commit & Push log rows["manifest_commit_push"] = { "execute_logs": exec_logs.decode('utf-8'), "error_logs": error_logs.decode('utf-8'), } body_cnt += 1 # globals.logger.debug(f"rows:{rows}") # 正常終了 normal end ret_status = 200 # 戻り値をそのまま返却 return jsonify({"result": ret_status, "rows": rows}), ret_status except common.UserException as e: return common.server_error(e) except Exception as e: return common.server_error(e)
def kym_file_upload(host, auth): """エクスポートファイルのアップロード Args: host (str): ITAのホスト auth (str): ITAの認証情報 Raises: Exception: [description] Returns: [str]: upload id, filename, menu items """ globals.logger.debug('---- upload kym file ----') # インポートファイルのパス設定 upload_filename = 'epoch_initialize.kym' kym_file_path = os.path.dirname(__file__) + "/resource/{}".format( upload_filename) # インポートファイルの内容をすべて取得 with open(kym_file_path, 'rb') as f: kym_binary = f.read() encoded_data = base64.b64encode(kym_binary).decode(encoding='utf-8') upload_filename = os.path.basename(kym_file_path) # POST送信する # ヘッダ情報 header = { 'host': host, 'Content-Type': 'application/json', 'Authorization': auth, 'X-Command': 'UPLOAD', } # 実行パラメータ設定 data = { "zipfile": { "name": upload_filename, "base64": encoded_data, } } # json文字列に変換("utf-8"形式に自動エンコードされる) json_data = json.dumps(data) globals.logger.debug('---- ita file upload ---- HOST:' + host) # リクエスト送信 upload_response = requests.post( 'http://' + host + '/default/menu/07_rest_api_ver1.php?no=2100000212', headers=header, data=json_data) if upload_response.status_code != 200: globals.logger.error("no=2100000212 status_code:{}".format( upload_response.status_code)) globals.logger.error(upload_response.text) raise common.UserException(upload_response.text) # print(upload_response.text) up_resp_data = json.loads(upload_response.text) if up_resp_data["status"] != "SUCCEED": globals.logger.error("no=2100000212 status:{}".format( up_resp_data["status"])) globals.logger.error(upload_response.text) raise common.UserException(upload_response.text) upload_id = up_resp_data["resultdata"]["upload_id"] globals.logger.debug('upload_id: ' + upload_id) menu_items = up_resp_data["resultdata"]["IMPORT_LIST"].items() return upload_id, upload_filename, menu_items
def settings_ita(workspace_id): """IT-Automation 設定 Args: workspace_id (int): workspace id Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "IT-Automation初期設定" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format( inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) ita_db_name = "ita_db" ita_db_user = "******" ita_db_password = "******" # パラメータ情報(JSON形式) payload = request.json.copy() # ワークスペースアクセス情報取得 access_info = api_access_info.get_access_info(workspace_id) # namespaceの取得 namespace = common.get_namespace_name(workspace_id) # *-*-*-* podが立ち上がるのを待つ *-*-*-* start_time = time.time() while True: globals.logger.debug("waiting for ita pod up...") # PodがRunningになったら終了 if is_ita_pod_running(namespace): break # timeout current_time = time.time() if (current_time - start_time) > WAIT_SEC_ITA_POD_UP: globals.logger.debug( "ITA pod start Time out S:{} sec:{}".format( start_time, (current_time - start_time))) error_detail = "IT-Automation 初期設定でタイムアウトしました。再度、実行してください。" raise common.UserException(error_detail) time.sleep(1) # *-*-*-* podが立ち上がるのを待つ *-*-*-* start_time = time.time() while True: globals.logger.debug("waiting for ita mariaDB up...") # PodがRunningになったら終了 if is_ita_mysql_running(namespace, ita_db_user, ita_db_password): break # timeout current_time = time.time() if (current_time - start_time) > WAIT_SEC_ITA_POD_UP: globals.logger.debug( "ITA mariaDB start Time out S:{} sec:{}".format( start_time, (current_time - start_time))) error_detail = "IT-Automation 初期設定でタイムアウトしました。再度、実行してください。" raise common.UserException(error_detail) time.sleep(1) # *-*-*-* パスワード更新済み判定とする *-*-*-* # command = "mysql -u %s -p%s %s < /app/epoch/tmp/ita_table_update.sql" % (ita_db_user, ita_db_password, ita_db_name) command = "mysql -u %s -p%s %s -e'UPDATE A_ACCOUNT_LIST SET PW_LAST_UPDATE_TIME = \"2999-12-31 23:59:58\" WHERE USER_ID = 1;'" % ( ita_db_user, ita_db_password, ita_db_name) stdout_ita = subprocess.check_output([ "kubectl", "exec", "-i", "-n", namespace, "deployment/it-automation", "--", "bash", "-c", command ], stderr=subprocess.STDOUT) # *-*-*-* 認証情報準備 *-*-*-* host = "{}.{}.svc:{}".format(EPOCH_ITA_HOST, namespace, EPOCH_ITA_PORT) user_id = access_info["ITA_USER"] user_init_pass = "******" user_pass = access_info["ITA_PASSWORD"] # パスワード暗号化 init_auth = base64.b64encode((user_id + ':' + user_init_pass).encode()) auth = base64.b64encode((user_id + ':' + user_pass).encode()) # すでに1度でもインポート済みの場合は、処理しない ret_is_import = is_already_imported(host, auth, init_auth) if ret_is_import == 200: globals.logger.debug("ITA initialize Imported.(success)") # 正常終了 ret_status = 200 # 戻り値をそのまま返却 return jsonify({"result": ret_status}), ret_status # 一度もインポートしていないときに処理する if ret_is_import == 0: # *-*-*-* インポート実行(初期パスワードで実行) *-*-*-* task_id = import_process(host, init_auth) # *-*-*-* インポート結果確認 *-*-*-* globals.logger.debug('---- monitoring import dialog ----') # POST送信する # ヘッダ情報 header = { 'host': host, 'Content-Type': 'application/json', 'Authorization': init_auth, 'X-Command': 'FILTER', } # 実行パラメータ設定 data = {"2": {"LIST": [task_id]}} # json文字列に変換("utf-8"形式に自動エンコードされる) json_data = json.dumps(data) start_time = time.time() while True: globals.logger.debug("monitoring...") time.sleep(3) # timeout current_time = time.time() if (current_time - start_time) > WAIT_SEC_ITA_IMPORT: globals.logger.debug("ITA menu import Time out") error_detail = "IT-Automation 初期設定でタイムアウトしました。再度、実行してください。" raise common.UserException(error_detail) # リクエスト送信 dialog_response = requests.post( 'http://' + host + '/default/menu/07_rest_api_ver1.php?no=2100000213', headers=header, data=json_data) if dialog_response.status_code != 200: globals.logger.error("no=2100000213 error:{}".format( dialog_response.status_code)) globals.logger.error(dialog_response.text) error_detail = "IT-Automation 初期設定が失敗しました。再度、実行してください。" # タイミングによって500応答が返されるため継続 # raise common.UserException(error_detail) continue # ファイルがあるメニューのため、response.textをデバッグ出力すると酷い目にあう # print(dialog_response.text) dialog_resp_data = json.loads(dialog_response.text) if dialog_resp_data["status"] != "SUCCEED" or dialog_resp_data[ "resultdata"]["CONTENTS"]["RECORD_LENGTH"] != 1: globals.logger.error("no=2100000213 status:{}".format( dialog_resp_data["status"])) globals.logger.error(dialog_response.text) error_detail = "IT-Automation 初期設定が失敗しました。再度、実行してください。" raise common.UserException(error_detail) record = dialog_resp_data["resultdata"]["CONTENTS"]["BODY"][1] globals.logger.debug(json.dumps(record)) if record[3] == u"完了(異常)": error_detail = "IT-Automation ITAのメニューインポートに失敗しました。" raise common.UserException(error_detail) if record[3] == u"完了": break error_detail = "IT-Automation 初期設定のパスワード初期化に失敗しました。" # *-*-*-* パスワード変更 *-*-*-* command = "mysql -u {} -p{} {} -e'UPDATE A_ACCOUNT_LIST".format(ita_db_user, ita_db_password, ita_db_name) + \ " SET PASSWORD = \"{}\"".format(hashlib.md5((user_pass).encode()).hexdigest()) + \ " WHERE USER_ID = 1;'" stdout_ita = subprocess.check_output([ "kubectl", "exec", "-i", "-n", namespace, "deployment/it-automation", "--", "bash", "-c", command ], stderr=subprocess.STDOUT) error_detail = "IT-Automation 初期設定のユーザー情報生成に失敗しました。" # *-*-*-* EPOCHユーザー更新 *-*-*-* command = "mysql -u {} -p{} {} -e'UPDATE A_ACCOUNT_LIST".format(ita_db_user, ita_db_password, ita_db_name) + \ " SET USERNAME = \"{}\"".format(access_info["ITA_EPOCH_USER"]) + \ " , PASSWORD = \"{}\"".format(hashlib.md5((access_info["ITA_EPOCH_PASSWORD"]).encode()).hexdigest()) + \ " , PW_LAST_UPDATE_TIME = \"2999-12-31 23:59:58\"" + \ " WHERE USER_ID = 2;'" stdout_ita = subprocess.check_output([ "kubectl", "exec", "-i", "-n", namespace, "deployment/it-automation", "--", "bash", "-c", command ], stderr=subprocess.STDOUT) # 正常終了 ret_status = 200 # 戻り値をそのまま返却 return jsonify({"result": ret_status}), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def post_manifest_parameter(workspace_id): """manifest パラメータ登録 manifest parameter registration Args: workspace_id (int): workspace ID Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "manifestパラメータ登録" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format( inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # ヘッダ情報 post header info. post_headers = { 'Content-Type': 'application/json', } # 引数をJSON形式で受け取りそのまま引数に設定 Receive the argument in JSON format and set it as it is post_data = request.json.copy() # send put (workspace data update) apiInfo = "{}://{}:{}".format( os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT']) globals.logger.debug( "workspace put call: worksapce_id:{}".format(workspace_id)) request_response = requests.put( "{}/workspace/{}/manifestParameter".format(apiInfo, workspace_id), headers=post_headers, data=json.dumps(post_data)) # エラーの際は処理しない if request_response.status_code != 200: globals.logger.error("call rs workspace error:{}".format( request_response.status_code)) error_detail = "ワークスペース情報更新失敗" raise common.UserException(error_detail) # ヘッダ情報 post_headers = { 'Content-Type': 'application/json', } # 引数をJSON形式で受け取りそのまま引数に設定 Receive the argument in JSON format and set it as it is post_data = request.json.copy() # 呼び出すapiInfoは、環境変数より取得 apiInfo = "{}://{}:{}".format(os.environ["EPOCH_CONTROL_ITA_PROTOCOL"], os.environ["EPOCH_CONTROL_ITA_HOST"], os.environ["EPOCH_CONTROL_ITA_PORT"]) globals.logger.debug("apiInfo:" + apiInfo) # Manifestパラメータ設定(ITA) globals.logger.debug( "ita/manifestParameter post call: worksapce_id:{}".format( workspace_id)) request_response = requests.post( "{}/workspace/{}/it-automation/manifest/parameter".format( apiInfo, workspace_id), headers=post_headers, data=json.dumps(post_data)) # globals.logger.debug("ita/manifestParameter:response:" + request_response.text.encode().decode('unicode-escape')) ret = json.loads(request_response.text) #ret = request_response.text # globals.logger.debug(ret["result"]) if request_response.status_code != 200: globals.logger.error("call ita/manifestParameter error:{}".format( request_response.status_code)) error_detail = "IT-Automation パラメータ登録失敗" raise common.UserException(error_detail) # 正常終了 normal return code ret_status = 200 return jsonify({"result": ret_status}), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def get_manifest_template_list(workspace_id): """manifest テンプレート登録 manifest template registration Args: workspace_id (int): workspace ID Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "manifestテンプレート取得" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format( inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) resourceProtocol = os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'] resourceHost = os.environ['EPOCH_RS_WORKSPACE_HOST'] resourcePort = os.environ['EPOCH_RS_WORKSPACE_PORT'] apiurl = "{}://{}:{}/workspace/{}/manifests".format( resourceProtocol, resourceHost, resourcePort, workspace_id) # ヘッダ情報 headers = { 'Content-Type': 'application/json', } # GET送信(作成) response = requests.get(apiurl, headers=headers) globals.logger.debug("get_manifests return --------------------") globals.logger.debug(json.loads(response.text)) globals.logger.debug("--------------------") if response.status_code == 200 and common.is_json_format( response.text): # 200(正常)かつ、レスポンスデータがJSON形式の場合は、後続の処理を実行 pass elif response.status_code == 404: error_detail = 'manifest template data not found' raise common.UserException(error_detail) elif response.status_code != 200: # 200(正常), 404(not found) 以外の応答の場合 error_detail = 'CALL responseAPI Error' raise common.UserException(error_detail) ret_manifests = json.loads(response.text) rows = ret_manifests["rows"] # 正常終了 normal return code ret_status = 200 return jsonify({"result": ret_status, "rows": rows}), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def post_ci_pipeline(workspace_id): """CIパイプライン情報設定 Args: workspace_id (int): workspace ID Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "CIパイプライン情報設定" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format(inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # ヘッダ情報 post_headers = { 'Content-Type': 'application/json', } # # 引数をJSON形式で受け取りそのまま引数に設定 # post_data = request.json.copy() # workspace get api_url = "{}://{}:{}/workspace/{}".format(os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT'], workspace_id) response = requests.get(api_url) if response.status_code != 200: error_detail = multi_lang.get_test("EP020-0013", "ワークスペース情報の取得に失敗しました") globals.logger.debug(error_detail) raise common.UserException(error_detail) # 取得したワークスペース情報を退避 Save the acquired workspace information ret = json.loads(response.text) # 取得したworkspace情報をパラメータとして受け渡す Pass the acquired workspace information as a parameter post_data = ret["rows"][0] # ワークスペース状態の取得 Get workspace status api_url = "{}://{}:{}/workspace/{}/status".format(os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT'], workspace_id) response = requests.get(api_url) if response.status_code != 200: error_detail = multi_lang.get_test("EP020-0026", "ワークスペース状態情報の取得に失敗しました") globals.logger.debug(error_detail) raise common.UserException(error_detail) # 取得したワークスペース状態を退避 Save the acquired workspace status get_workspace_status = json.loads(response.text) # 更新で使用する項目のみを展開する Expand only the items used in the update workspace_status = { const.STATUS_CI_SETTING : get_workspace_status[const.STATUS_CI_SETTING] } # 前回の結果が正常終了しているかチェックする # Be sure to execute CI settings except OK if workspace_status[const.STATUS_CI_SETTING] == const.STATUS_OK: # 更新前ワークスペース情報取得 Get workspace before update api_url = "{}://{}:{}/workspace/{}/before".format(os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT'], workspace_id) response = requests.get(api_url) if response.status_code == 200: # 取得したワークスペース情報を退避 Save the acquired workspace information ret = json.loads(response.text) # 取得したworkspace情報をパラメータとして受け渡す Pass the acquired workspace information as a parameter before_data = ret["rows"][0] elif response.status_code == 404: before_data = None elif response.status_code != 200: error_detail = multi_lang.get_test("EP020-0013", "ワークスペース情報の取得に失敗しました") globals.logger.debug(error_detail) raise common.UserException(error_detail) else: # OK以外は、必ずCI設定を実行 # Be sure to execute CI settings except OK before_data = None ci_config_json_after = post_data["ci_config"].copy() if before_data is not None: ci_config_json_before = before_data["ci_config"].copy() # environmentsの情報は比較に必要ないのでJsonから削除 # The environment information is not needed for comparison, so delete it from Json if "environments" in ci_config_json_after: ci_config_json_after.pop("environments") if before_data is not None: if "environments" in ci_config_json_before: ci_config_json_before.pop("environments") ci_config_str_after = json.dumps(ci_config_json_after) if before_data is not None: ci_config_str_before = json.dumps(ci_config_json_before) else: ci_config_str_before = None # 更新前、更新後が一致しない場合にCIパイプラインの設定を行なう # Set up the CI pipeline when the pre-update and post-update do not match if ci_config_str_after != ci_config_str_before: globals.logger.debug("changed ci_config parameter!") # 実行前はNGで更新 Update with NG before execution workspace_status[const.STATUS_CI_SETTING] = const.STATUS_NG # workspace 状態更新 workspace status update api_url = "{}://{}:{}/workspace/{}/status".format(os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT'], workspace_id) response = requests.put(api_url, headers=post_headers, data=json.dumps(workspace_status)) if response.status_code != 200: error_detail = multi_lang.get_test("EP020-0027", "ワークスペース状態情報の更新に失敗しました") globals.logger.debug(error_detail) raise common.UserException(error_detail) # epoch-control-inside-gitlab-api の呼び先設定 api_url_gitlab = "{}://{}:{}/workspace/{}/gitlab".format(os.environ["EPOCH_CONTROL_INSIDE_GITLAB_PROTOCOL"], os.environ["EPOCH_CONTROL_INSIDE_GITLAB_HOST"], os.environ["EPOCH_CONTROL_INSIDE_GITLAB_PORT"], workspace_id) # epoch-control-github-api の呼び先設定 api_url_github = "{}://{}:{}/workspace/{}/github/webhooks".format(os.environ["EPOCH_CONTROL_GITHUB_PROTOCOL"], os.environ["EPOCH_CONTROL_GITHUB_HOST"], os.environ["EPOCH_CONTROL_GITHUB_PORT"], workspace_id) # epoch-control-tekton-api の呼び先設定 api_url_tekton = "{}://{}:{}/workspace/{}/tekton/pipeline".format(os.environ["EPOCH_CONTROL_TEKTON_PROTOCOL"], os.environ["EPOCH_CONTROL_TEKTON_HOST"], os.environ["EPOCH_CONTROL_TEKTON_PORT"], workspace_id) # パイプライン設定(GitLab Create Project) # request_body = json.loads(request.data) request_body = post_data git_projects = [] # アプリケーションコード if request_body['ci_config']['pipelines_common']['git_repositry']['housing'] == 'inner': for pipeline_ap in request_body['ci_config']['pipelines']: ap_data = { 'git_repositry': { 'user': request_body['ci_config']['pipelines_common']['git_repositry']['user'], 'token': request_body['ci_config']['pipelines_common']['git_repositry']['token'], 'url': pipeline_ap['git_repositry']['url'], } } git_projects.append(ap_data) # IaC # if request_body['cd_config']['environments_common']['git_repositry']['housing'] == 'inner': # for pipeline_iac in request_body['cd_config']['environments']: # ap_data = { # 'git_repositry': { # 'user': request_body['cd_config']['environments_common']['git_repositry']['user'], # 'token': request_body['cd_config']['environments_common']['git_repositry']['token'], # 'url': pipeline_iac['git_repositry']['url'], # } # } # git_projects.append(ap_data) for proj_data in git_projects: # gitlab/repos post送信 response = requests.post('{}/repos'.format(api_url_gitlab), headers=post_headers, data=json.dumps(proj_data)) globals.logger.debug("post gitlab/repos response:{}".format(response.text)) if response.status_code != 200 and response.status_code != 201: error_detail = 'gitlab/repos post処理に失敗しました' raise common.UserException(error_detail) if request_body['ci_config']['pipelines_common']['git_repositry']['housing'] == 'outer': # github/webhooks post送信 response = requests.post( api_url_github, headers=post_headers, data=json.dumps(post_data)) globals.logger.debug("post github/webhooks response:{}".format(response.text)) if response.status_code != 200: error_detail = 'github/webhooks post処理に失敗しました' raise common.UserException(error_detail) else: # パイプライン設定(GitLab webhooks) for pipeline_ap in request_body['ci_config']['pipelines']: ap_data = { 'git_repositry': { 'user': request_body['ci_config']['pipelines_common']['git_repositry']['user'], 'token': request_body['ci_config']['pipelines_common']['git_repositry']['token'], 'url': pipeline_ap['git_repositry']['url'], }, 'webhooks_url': pipeline_ap['webhooks_url'], } response = requests.post('{}/webhooks'.format(api_url_gitlab), headers=post_headers, data=json.dumps(ap_data)) globals.logger.debug("post gitlab/webhooks response:{}".format(response.text)) if response.status_code != 200 and response.status_code != 201: error_detail = 'gitlab/webhooks post処理に失敗しました' raise common.UserException(error_detail) # listener post送信 response = requests.post(api_url_tekton, headers=post_headers, data=json.dumps(post_data)) globals.logger.debug("post tekton/pipeline response:{}".format(response.text)) if response.status_code != 200: error_detail = 'tekton/pipeline post処理に失敗しました' raise common.UserException(error_detail) # 実行後はOKで更新 Update with OK after execution workspace_status[const.STATUS_CI_SETTING] = const.STATUS_OK # workspace 状態更新 workspace status update api_url = "{}://{}:{}/workspace/{}/status".format(os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT'], workspace_id) response = requests.put(api_url, headers=post_headers, data=json.dumps(workspace_status)) if response.status_code != 200: error_detail = multi_lang.get_test("EP020-0027", "ワークスペース状態情報の更新に失敗しました") globals.logger.debug(error_detail) raise common.UserException(error_detail) ret_status = 200 # 戻り値をそのまま返却 return jsonify({"result": ret_status}), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def get_git_commits(workspace_id): """Get git commit history - gitコミット履歴取得 Args: workspace_id (int): workspace ID Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "CIパイプラインgit履歴取得" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format(inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # workspace get api_url = "{}://{}:{}/workspace/{}".format(os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT'], workspace_id) response = requests.get(api_url) if response.status_code != 200: error_detail = multi_lang.get_text("EP020-0013", "ワークスペース情報の取得に失敗しました") globals.logger.debug(error_detail) raise common.UserException(error_detail) # 取得したワークスペース情報を退避 Save the acquired workspace information ret = json.loads(response.text) # 取得したworkspace情報をパラメータとして受け渡す Pass the acquired workspace information as a parameter workspace_info = ret["rows"][0] git_token = workspace_info["ci_config"]["pipelines_common"]["git_repositry"]["token"] git_user = workspace_info["ci_config"]["pipelines_common"]["git_repositry"]["user"] # ヘッダ情報 header info. post_headers_in_token = { 'private-token': git_token, 'Content-Type': 'application/json', } rows = [] # パイプライン数分処理する Process for a few minutes in the pipelines for pipeline in workspace_info["ci_config"]["pipelines"]: git_url = pipeline["git_repositry"]["url"] if workspace_info["ci_config"]["pipelines_common"]["git_repositry"]["housing"] == const.HOUSING_INNER: # EPOCH内レジストリ ブランチの一覧取得 Get a list of registry branches in EPOCH api_url = "{}://{}:{}/branches?git_url={}".format(os.environ['EPOCH_CONTROL_INSIDE_GITLAB_PROTOCOL'], os.environ['EPOCH_CONTROL_INSIDE_GITLAB_HOST'], os.environ['EPOCH_CONTROL_INSIDE_GITLAB_PORT'], urllib.parse.quote(git_url)) response = requests.get(api_url, headers=post_headers_in_token) if response.status_code != 200: raise common.UserException("git branches get error:[{}]".format(response.status_code)) ret_git_branches = json.loads(response.text) # ブランチごとにcommit情報を取得する # Get commit information for each branch for branch_row in ret_git_branches["rows"]: # EPOCH内レジストリ Registry in EPOCH api_url = "{}://{}:{}/commits?git_url={}&branch={}".format(os.environ['EPOCH_CONTROL_INSIDE_GITLAB_PROTOCOL'], os.environ['EPOCH_CONTROL_INSIDE_GITLAB_HOST'], os.environ['EPOCH_CONTROL_INSIDE_GITLAB_PORT'], urllib.parse.quote(git_url), urllib.parse.quote(branch_row["name"])) response = requests.get(api_url, headers=post_headers_in_token) if response.status_code != 200: raise common.UserException("git commit get error:[{}]".format(response.status_code)) ret_git_commit = json.loads(response.text) # 取得した情報数分処理する # Process for the number of acquired information for git_row in ret_git_commit["rows"]: web_url = git_row["web_url"] base_url = re.search('^https?://[^/][^/]*/',git_url).group() web_url = web_url.replace("https://gitlab.gitlab.svc/", base_url) # web_url = web_url.replace("https://gitlab.gitlab.svc/", git_url.match("(https?://[^/]+/)")) row = { "git_url": git_url, "repository": "{}/{}".format(git_user, re.search('([^/]+?)(?=.git)', git_url).group()), "branch": branch_row["name"], "commit_id": git_row["id"], "name": git_row["committer_name"], "date": git_row["committed_date"], "message": git_row["message"], "html_url": web_url, } rows.append(row) else: # GitHub branches get api_url = "{}://{}:{}/branches?git_url={}".format(os.environ['EPOCH_CONTROL_GITHUB_PROTOCOL'], os.environ['EPOCH_CONTROL_GITHUB_HOST'], os.environ['EPOCH_CONTROL_GITHUB_PORT'], urllib.parse.quote(git_url)) response = requests.get(api_url, headers=post_headers_in_token) if response.status_code != 200: raise common.UserException("git branches get error:[{}]".format(response.status_code)) ret_git_branches = json.loads(response.text) # ブランチごとにcommit情報を取得する # Get commit information for each branch for branch_row in ret_git_branches["rows"]: # GitHub commit get api_url = "{}://{}:{}/commits?git_url={}&branch={}".format(os.environ['EPOCH_CONTROL_GITHUB_PROTOCOL'], os.environ['EPOCH_CONTROL_GITHUB_HOST'], os.environ['EPOCH_CONTROL_GITHUB_PORT'], urllib.parse.quote(git_url), urllib.parse.quote(branch_row["name"])) response = requests.get(api_url, headers=post_headers_in_token) if response.status_code != 200: raise common.UserException("git commit get error:[{}]".format(response.status_code)) ret_git_commit = json.loads(response.text) # globals.logger.debug("rows:[{}]".format(ret_git_commit["rows"])) # 取得した情報数分処理する # Process for the number of acquired information for git_row in ret_git_commit["rows"]: row = { "git_url": git_url, "repository": "{}/{}".format(git_user, re.search('([^/]+?)(?=.git)', git_url).group()), "branch": branch_row["name"], "commit_id": git_row["sha"], "name": git_row["commit"]["committer"]["name"], "date": git_row["commit"]["committer"]["date"], "message": git_row["commit"]["message"], "html_url": git_row["html_url"], } rows.append(row) response = { "result":"200", "rows" : rows, } ret_status = 200 return jsonify(response), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def settings_manifest_parameter(workspace_id): """manifest parameter setting Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "実行環境取得" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format( inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # パラメータ情報(JSON形式) prameter save payload = request.json.copy() # ワークスペースアクセス情報取得 access_info = api_access_info.get_access_info(workspace_id) # namespaceの取得 namespace = common.get_namespace_name(workspace_id) ita_restapi_endpoint = "http://{}.{}.svc:{}/default/menu/07_rest_api_ver1.php".format( EPOCH_ITA_HOST, namespace, EPOCH_ITA_PORT) ita_user = access_info['ITA_USER'] ita_pass = access_info['ITA_PASSWORD'] # HTTPヘッダの生成 filter_headers = { 'host': EPOCH_ITA_HOST + ':' + EPOCH_ITA_PORT, 'Content-Type': 'application/json', 'Authorization': base64.b64encode( (ita_user + ':' + ita_pass).encode()), 'X-Command': 'FILTER', } edit_headers = { 'host': EPOCH_ITA_HOST + ':' + EPOCH_ITA_PORT, 'Content-Type': 'application/json', 'Authorization': base64.b64encode( (ita_user + ':' + ita_pass).encode()), 'X-Command': 'EDIT', } # globals.logger.debug(payload) # # オペレーションの取得 # opelist_resp = requests.post(ita_restapi_endpoint + '?no=' + ite_menu_operation, headers=filter_headers) opelist_json = json.loads(opelist_resp.text) globals.logger.debug('---- Operation ----') # logger.debug(opelist_resp.text) # logger.debug(opelist_json) # 項目位置の取得 column_indexes_opelist = column_indexes( column_names_opelist, opelist_json['resultdata']['CONTENTS']['BODY'][0]) globals.logger.debug('---- Operation Index ----') # logger.debug(column_indexes_opelist) # # マニフェスト環境パラメータの取得 # content = {"1": {"NORMAL": "0"}} maniparam_resp = requests.post(ita_restapi_endpoint + '?no=' + ita_menu_manifest_param, headers=filter_headers, data=json.dumps(content)) maniparam_json = json.loads(maniparam_resp.text) globals.logger.debug('---- Current Manifest Parameters ----') # logger.debug(maniparam_resp.text) globals.logger.debug(maniparam_json) # 項目位置の取得 column_indexes_maniparam = column_indexes( column_names_manifest_param, maniparam_json['resultdata']['CONTENTS']['BODY'][0]) globals.logger.debug('---- Manifest Parameters Index ----') # logger.debug(column_indexes_maniparam) # Responseデータの初期化 response = { "result": "200", } globals.logger.debug("opelist:{}".format( opelist_json['resultdata']['CONTENTS']['BODY'])) # マニフェスト環境パラメータのデータ成型 maniparam_edit = [] for environment in payload['ci_config']['environments']: idx_ope = -1 # cd_configの同一環境情報からgit_urlを取得する Get git_url from the same environment information in cd_config for cd_environment in payload['cd_config']['environments']: if environment['environment_id'] == cd_environment[ 'environment_id']: globals.logger.debug("git_url:{}".format( cd_environment['git_repositry']['url'])) idx_ope = search_opration( opelist_json['resultdata']['CONTENTS']['BODY'], column_indexes_opelist, cd_environment['git_repositry']['url']) # ITAからオペレーション(=環境)が取得できなければ異常 if idx_ope == -1: error_detail = "CD環境が設定されていません。" raise common.UserException(error_detail) req_maniparam_operation_id = opelist_json['resultdata'][ 'CONTENTS']['BODY'][idx_ope][ column_indexes_common['record_no']] for idx_manifile, row_manifile in enumerate( environment['manifests']): image = None image_tag = None param01 = None param02 = None param03 = None param04 = None param05 = None param06 = None param07 = None param08 = None param09 = None param10 = None param11 = None param12 = None param13 = None param14 = None param15 = None param16 = None param17 = None param18 = None param19 = None param20 = None # parameters成型 for key, value in row_manifile['parameters'].items(): if key == 'image': image = value elif key == 'image_tag': image_tag = value elif key == 'param01': param01 = value elif key == 'param02': param02 = value elif key == 'param03': param03 = value elif key == 'param04': param04 = value elif key == 'param05': param05 = value elif key == 'param06': param06 = value elif key == 'param07': param07 = value elif key == 'param08': param08 = value elif key == 'param09': param09 = value elif key == 'param10': param10 = value elif key == 'param11': param11 = value elif key == 'param12': param12 = value elif key == 'param13': param13 = value elif key == 'param14': param14 = value elif key == 'param15': param15 = value elif key == 'param16': param16 = value elif key == 'param17': param17 = value elif key == 'param18': param18 = value elif key == 'param19': param19 = value elif key == 'param20': param20 = value # 既存データ確認 maniparam_id = -1 for idx_maniparam, row_maniparam in enumerate( maniparam_json['resultdata']['CONTENTS']['BODY']): current_maniparam_operation_id = row_maniparam[ column_indexes_maniparam['operation_id']] current_maniparam_include_index = row_maniparam[ column_indexes_maniparam['indexes']] if current_maniparam_operation_id == req_maniparam_operation_id and \ current_maniparam_include_index == str(idx_manifile + 1): maniparam_id = row_maniparam[ column_indexes_common['record_no']] break if maniparam_id == -1: # 追加処理データの設定 maniparam_edit.append({ str(column_indexes_common['method']): param_value_method_entry, str(column_indexes_maniparam['host']): param_value_host, str(column_indexes_maniparam['operation']): format_opration_info( opelist_json['resultdata']['CONTENTS']['BODY'] [idx_ope], column_indexes_opelist), str(column_indexes_maniparam['indexes']): idx_manifile + 1, str(column_indexes_maniparam['image']): image, str(column_indexes_maniparam['image_tag']): image_tag, str(column_indexes_maniparam['param01']): param01, str(column_indexes_maniparam['param02']): param02, str(column_indexes_maniparam['param03']): param03, str(column_indexes_maniparam['param04']): param04, str(column_indexes_maniparam['param05']): param05, str(column_indexes_maniparam['param06']): param06, str(column_indexes_maniparam['param07']): param07, str(column_indexes_maniparam['param08']): param08, str(column_indexes_maniparam['param09']): param09, str(column_indexes_maniparam['param10']): param10, str(column_indexes_maniparam['param11']): param11, str(column_indexes_maniparam['param12']): param12, str(column_indexes_maniparam['param13']): param13, str(column_indexes_maniparam['param14']): param14, str(column_indexes_maniparam['param15']): param15, str(column_indexes_maniparam['param16']): param16, str(column_indexes_maniparam['param17']): param17, str(column_indexes_maniparam['param18']): param18, str(column_indexes_maniparam['param19']): param19, str(column_indexes_maniparam['param20']): param20, str(column_indexes_maniparam['template_name']): '"{{ TPF_epoch_template_yaml' + str(idx_manifile + 1) + ' }}"', }) globals.logger.debug( '---- Manifest Parameters Item(Add) ----') globals.logger.debug(maniparam_edit[len(maniparam_edit) - 1]) else: # 更新処理 maniparam_edit.append({ str(column_indexes_common['method']): param_value_method_update, str(column_indexes_common['record_no']): maniparam_id, str(column_indexes_maniparam['host']): maniparam_json['resultdata']['CONTENTS']['BODY'] [idx_maniparam][column_indexes_maniparam['host']], str(column_indexes_maniparam['operation']): maniparam_json['resultdata']['CONTENTS']['BODY'] [idx_maniparam][column_indexes_maniparam['operation']], str(column_indexes_maniparam['indexes']): maniparam_json['resultdata']['CONTENTS']['BODY'] [idx_maniparam][column_indexes_maniparam['indexes']], str(column_indexes_maniparam['image']): image, str(column_indexes_maniparam['image_tag']): image_tag, str(column_indexes_maniparam['param01']): param01, str(column_indexes_maniparam['param02']): param02, str(column_indexes_maniparam['param03']): param03, str(column_indexes_maniparam['param04']): param04, str(column_indexes_maniparam['param05']): param05, str(column_indexes_maniparam['param06']): param06, str(column_indexes_maniparam['param07']): param07, str(column_indexes_maniparam['param08']): param08, str(column_indexes_maniparam['param09']): param09, str(column_indexes_maniparam['param10']): param10, str(column_indexes_maniparam['param11']): param11, str(column_indexes_maniparam['param12']): param12, str(column_indexes_maniparam['param13']): param13, str(column_indexes_maniparam['param14']): param14, str(column_indexes_maniparam['param15']): param15, str(column_indexes_maniparam['param16']): param16, str(column_indexes_maniparam['param17']): param17, str(column_indexes_maniparam['param18']): param18, str(column_indexes_maniparam['param19']): param19, str(column_indexes_maniparam['param20']): param20, str(column_indexes_maniparam['template_name']): maniparam_json['resultdata']['CONTENTS']['BODY'] [idx_maniparam][ column_indexes_maniparam['template_name']], str(column_indexes_maniparam['lastupdate']): maniparam_json['resultdata']['CONTENTS']['BODY'] [idx_maniparam][ column_indexes_maniparam['lastupdate']], }) globals.logger.debug( '---- Manifest Parameters Item(Update) ----') globals.logger.debug(maniparam_edit[len(maniparam_edit) - 1]) globals.logger.debug('---- Deleting Manifest Parameters Setting ----') # 既存データをすべて廃止する for idx_maniparam, row_maniparam in enumerate( maniparam_json['resultdata']['CONTENTS']['BODY']): # 1行目無視する if idx_maniparam == 0: continue flgExists = False for idx_edit, row_edit in enumerate(maniparam_edit): # 該当するrecord_noがあれば、チェックする if str(column_indexes_common['record_no']) in row_edit: if row_edit[str( column_indexes_common['record_no'] )] == row_maniparam[column_indexes_common['record_no']]: flgExists = True break # 該当するレコードがない場合は、廃止として追加する if not flgExists: # 削除用のデータ設定 maniparam_edit.append({ str(column_indexes_common['method']): param_value_method_delete, str(column_indexes_common['record_no']): row_maniparam[column_indexes_common['record_no']], str(column_indexes_maniparam['lastupdate']): row_maniparam[column_indexes_maniparam['lastupdate']], }) globals.logger.debug('---- Updating Manifest Parameters ----') # globals.logger.debug(json.dumps(maniparam_edit)) manuparam_edit_resp = requests.post(ita_restapi_endpoint + '?no=' + ita_menu_manifest_param, headers=edit_headers, data=json.dumps(maniparam_edit)) maniparam_json = json.loads(manuparam_edit_resp.text) globals.logger.debug('---- Manifest Parameters Post Response ----') # logger.debug(manuparam_edit_resp.text) # globals.logger.debug(maniparam_json) if maniparam_json["status"] != "SUCCEED" or maniparam_json[ "resultdata"]["LIST"]["NORMAL"]["error"]["ct"] != 0: raise common.UserException( manuparam_edit_resp.text.encode().decode('unicode-escape')) # 正常終了 ret_status = 200 # 戻り値をそのまま返却 return jsonify({"result": ret_status}), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def get_workspace_members(workspace_id): """ワークスペース該当メンバー情報取得 workspace members get Returns: Response: HTTP Respose """ app_name = multi_lang.get_text("EP020-0003", "ワークスペース情報:") exec_stat = multi_lang.get_text("EP020-0004", "メンバー一覧取得") error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format(inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) roles = const.ALL_ROLES stock_user_id = [] ret_users = [] for role in roles: # workspace 参照権限のあるユーザーをすべて取得する Get all users with read permission # 子のロールでは取得できないので割り当てたロールで取得する # Since it cannot be acquired by the child role, it is acquired by the assigned role. api_url = "{}://{}:{}/{}/client/epoch-system/roles/{}/users".format(os.environ['EPOCH_EPAI_API_PROTOCOL'], os.environ['EPOCH_EPAI_API_HOST'], os.environ['EPOCH_EPAI_API_PORT'], os.environ["EPOCH_EPAI_REALM_NAME"], role.format(workspace_id) ) # # get users - ユーザー取得 # response = requests.get(api_url) if response.status_code != 200 and response.status_code != 404: error_detail = multi_lang.get_text("EP020-0008", "ユーザー情報の取得に失敗しました") raise common.UserException("{} Error user get status:{}".format(inspect.currentframe().f_code.co_name, response.status_code)) users = json.loads(response.text) # globals.logger.debug(f"users:{users}") for user in users["rows"]: # すでに同じユーザーがいた場合は処理しない If the same user already exists, it will not be processed # if len(stock_user_id) > 0: if user["user_id"] in stock_user_id: continue # 取得したユーザーのロールを取得 Get the role of the acquired user api_url = "{}://{}:{}/{}/user/{}/roles/epoch-system".format(os.environ['EPOCH_EPAI_API_PROTOCOL'], os.environ['EPOCH_EPAI_API_HOST'], os.environ['EPOCH_EPAI_API_PORT'], os.environ["EPOCH_EPAI_REALM_NAME"], user["user_id"] ) # # get user role - ユーザーロール情報取得 # response = requests.get(api_url) if response.status_code != 200: error_detail = multi_lang.get_text("EP020-0009", "ユーザーロール情報の取得に失敗しました") raise common.UserException("{} Error user role get status:{}".format(inspect.currentframe().f_code.co_name, response.status_code)) ret_roles = json.loads(response.text) # globals.logger.debug(f"roles:{ret_roles}") set_role_kind = [] # 取得したすべてのロールから絞り込む Narrow down from all acquired roles for get_role in ret_roles["rows"]: kind = common.get_role_kind(get_role["name"]) # 該当のロールのみチェック Check only the corresponding role if kind is not None: ex_role = re.match("ws-({}|\d+)-(.+)", get_role["name"]) globals.logger.debug("role_workspace_id:{} kind:{}".format(ex_role[1], ex_role[2])) # 該当のワークスペースのみの絞り込み Narrow down only the applicable workspace if ex_role[1] == str(workspace_id): set_role_kind.append( { "kind" : kind } ) ret_user = { "user_id": user["user_id"], "username": user["user_name"], "roles": set_role_kind } ret_users.append(ret_user) stock_user_id.append(user["user_id"]) # globals.logger.debug(f"users:{ret_users}") rows = ret_users return jsonify({"result": "200", "rows": rows}), 200 except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def merge_workspace_members(workspace_id): """ワークスペース該当メンバー登録 workspace member registration Request: json { "rows": [ { "user_id": "", "roles": [ { "kind": "", } ] }, ], "role_update_at": "", } Returns: Response: HTTP Respose """ app_name = multi_lang.get_text("EP020-0003", "ワークスペース情報:") exec_stat = multi_lang.get_text("EP020-0005", "メンバー登録") error_detail = "" return_code = 500 try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format(inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # 引数はJSON形式 Arguments are in JSON format req_json = request.json.copy() # ヘッダ情報 header info. post_headers = { 'Content-Type': 'application/json', } # workspace get api_url = "{}://{}:{}/workspace/{}".format(os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT'], workspace_id) response = requests.get(api_url, headers=post_headers) if response.status_code == 200 and common.is_json_format(response.text): # 取得したワークスペース情報を退避 Save the acquired workspace information ret = json.loads(response.text) ws_row = ret["rows"][0] elif response.status_code == 404: return_code = 400 error_detail = multi_lang.get_text("EP000-0022", "更新対象(workspace)がありません", "workspace") # 情報取得できない場合はエラー Error if information cannot be obtained raise common.UserException("{} not found workspace !".format(inspect.currentframe().f_code.co_name)) else: if response.status_code == 500 and common.is_json_format(response.text): # 戻り値がJsonの場合は、値を取得 If the return value is Json, get the value ret = json.loads(response.text) # 詳細エラーがある場合は詳細を設定 Set details if there are detailed errors if ret["errorDetail"] is not None: error_detail = ret["errorDetail"] raise common.UserException("{} Error get workspace db status:{}".format(inspect.currentframe().f_code.co_name, response.status_code)) globals.logger.debug("Exclusive check") globals.logger.debug("db[{}] update[{}]".format(str(ws_row["role_update_at"]), req_json["role_update_at"])) # 排他チェック:ロール更新日時が一致しているかチェックする # Exclusive check: Check if the role update datetime match if str(ws_row["role_update_at"]) != req_json["role_update_at"]: return_code = 400 error_detail = multi_lang.get_text("EP000-0023", "対象の情報(workspace)が他で更新されたため、更新できません\n画面更新後、再度情報を入力・選択して実行してください", "workspace") raise common.UserException("{} update exclusive check error".format(inspect.currentframe().f_code.co_name)) ret_status = response.status_code # ログインユーザーの情報取得 Get login user information user_id = common.get_current_user(request.headers) api_url = "{}://{}:{}/{}/user/{}".format(os.environ['EPOCH_EPAI_API_PROTOCOL'], os.environ['EPOCH_EPAI_API_HOST'], os.environ['EPOCH_EPAI_API_PORT'], os.environ["EPOCH_EPAI_REALM_NAME"], user_id ) # # get users - ユーザー取得 # response = requests.get(api_url) if response.status_code != 200 and response.status_code != 404: error_detail = multi_lang.get_text("EP020-0008", "ユーザー情報の取得に失敗しました") raise common.UserException("{} Error user get status:{}".format(inspect.currentframe().f_code.co_name, response.status_code)) users = json.loads(response.text) # globals.logger.debug(f"users:{users}") # 取得したユーザーのロールを取得 # Get the role of the acquired user api_url = "{}://{}:{}/{}/user/{}/roles/epoch-system".format(os.environ['EPOCH_EPAI_API_PROTOCOL'], os.environ['EPOCH_EPAI_API_HOST'], os.environ['EPOCH_EPAI_API_PORT'], os.environ["EPOCH_EPAI_REALM_NAME"], user_id ) # # get user role - ユーザーロール情報取得 # response = requests.get(api_url) if response.status_code != 200: error_detail = multi_lang.get_text("EP020-0009", "ユーザーロール情報の取得に失敗しました") globals.logger.debug(error_detail) raise common.UserException("{} Error user role get status:{}".format(inspect.currentframe().f_code.co_name, response.status_code)) ret_roles = json.loads(response.text) # globals.logger.debug(f"roles:{ret_roles}") bool_owener_role = False # オーナーロール設定可能権限かどうかチェックする # Check if the owner role can be set for get_role in ret_roles["rows"]: # globals.logger.debug('role:{}'.format(get_role["name"])) # ロールがあればチェックOK # Check OK if there is a roll if get_role["name"] == const.ROLE_WS_ROLE_OWNER_ROLE_SETTING[0].format(workspace_id): bool_owener_role = True break # 権限「オーナー変更」保有しているユーザーを抽出する # Extract users who have the authority "change owner" owener_users = api_service_common.get_workspace_members_by_role(workspace_id, const.ROLE_WS_ROLE_OWNER_ROLE_SETTING[0].format(workspace_id)) # globals.logger.debug(f"owener_users{owener_users}") owener_users_id_array = [] # チェック用に配列化 # Arranged for checking for user in owener_users: owener_users_id_array.append(user["user_id"]) # オーナーロール変更以外がオーナーロールありに変更したかチェック # Check if other than the owner role change has changed to have an owner role if not bool_owener_role: bool_auth_error = False for row in req_json["rows"]: globals.logger.debug(f"req_row:{row}") bool_owner_update = False for role in row["roles"]: # オーナー更新ありのフラグをONにする # Turn on the flag with owner update globals.logger.debug("owener_check({}):({})".format(common.get_role_name(role["kind"]), const.ROLE_WS_OWNER[0])) if common.get_role_name(role["kind"]) == const.ROLE_WS_OWNER[0]: bool_owner_update = True # オーナーロールの変更がある場合、権限がないのでエラーとする # If there is a change in the owner role, it will be an error because you do not have the authority. if common.get_role_name(role["kind"]) == const.ROLE_WS_OWNER[0] and \ row["user_id"] not in owener_users_id_array: bool_auth_error = True break # オーナーありのユーザーからオーナー権限を削除した際は権限がないのでエラーとする # If you delete the owner authority from a user who has an owner, you will get an error because you do not have the authority. if not bool_owner_update and row["user_id"] in owener_users_id_array: bool_auth_error = True break # 権限エラーの場合は、処理を抜ける # In case of permission error, exit the process if bool_auth_error: break # 権限エラー # Permission error if bool_auth_error: # ログイン者が唯一のオーナーの時は退去できない # Can't move out when the login person is the only owner error_detail = multi_lang.get_text("EP020-0024", "オーナー権限を変更することはできません") raise common.AuthException(error_detail) else: # オーナーロール変更ありのユーザーが、オーナーロール変更した際、オーナーロールのユーザーが残るかどうか # Check if a user with an owner role change has a user change with an owner role change owner_add_cnt = 0 owner_del_cnt = 0 for row in req_json["rows"]: bool_owner_update = False for role in row["roles"]: # オーナー更新ありのフラグをONにする # Turn on the flag with owner update if common.get_role_name(role["kind"]) == const.ROLE_WS_OWNER[0]: bool_owner_update = True break # オーナーありのユーザーからオーナー権限を削除した件数をカウント # Count the number of cases where the owner authority is deleted from the owner-owned user if not bool_owner_update and row["user_id"] in owener_users_id_array: owner_del_cnt += 1 # 新規オーナーかチェックする # Check if you are a new owner elif bool_owner_update and row["user_id"] not in owener_users_id_array: owner_add_cnt += 1 # オーナーが0人となる場合はエラーとする # If the number of owners is 0, an error will occur. if (len(owener_users) - owner_del_cnt) == 0 and owner_add_cnt == 0: # ログイン者が唯一のオーナーの時は退去できない # Can't move out when the login person is the only owner error_detail = multi_lang.get_text("EP020-0025", "最低1人以上のオーナーは必要です") raise common.AuthException(error_detail) for row in req_json["rows"]: # 登録前にすべてのroleを削除する # Delete all roles before registration roles = const.ALL_ROLES # # ロールの制御のurl - role control url # api_url = "{}://{}:{}/{}/user/{}/roles/epoch-system".format(os.environ['EPOCH_EPAI_API_PROTOCOL'], os.environ['EPOCH_EPAI_API_HOST'], os.environ['EPOCH_EPAI_API_PORT'], os.environ["EPOCH_EPAI_REALM_NAME"], row["user_id"], ) del_roles = [] for role in roles: del_role = { "name": role.format(workspace_id), } del_roles.append(del_role) post_data = { "roles" : del_roles } # # delete workspace role - ワークスペース ロールの削除 # response = requests.delete(api_url, headers=post_headers, data=json.dumps(post_data)) if response.status_code != 200: error_detail = multi_lang.get_text("EP020-0006", "ロールの削除に失敗しました") raise common.UserException("{} Error user role delete status:{}".format(inspect.currentframe().f_code.co_name, response.status_code)) # 登録するroleの情報を編集 # Edit the information of the role to be registered add_roles = [] for role in row["roles"]: add_role = { "name": common.get_role_name(role["kind"]).format(workspace_id), "enabled": True, } add_roles.append(add_role) post_data = { "roles" : add_roles } # # append workspace role - ワークスペース ロールの付与 # response = requests.post(api_url, headers=post_headers, data=json.dumps(post_data)) if response.status_code != 200: error_detail = multi_lang.get_text("EP020-0007", "ロールの登録に失敗しました") globals.logger.debug(error_detail) raise common.UserException("{} Error user role add status:{}".format(inspect.currentframe().f_code.co_name, response.status_code)) # # logs output - ログ出力 # post_data = { "action" : "role update", "role_update_user_id" : row["user_id"], "role_update_user_roles" : add_roles, } api_url = "{}://{}:{}/workspace/{}/member/{}/logs/{}".format(os.environ['EPOCH_RS_LOGS_PROTOCOL'], os.environ['EPOCH_RS_LOGS_HOST'], os.environ['EPOCH_RS_LOGS_PORT'], workspace_id, users["info"]["username"], const.LOG_KIND_UPDATE ) response = requests.post(api_url, headers=post_headers, data=json.dumps(post_data)) if response.status_code != 200: error_detail = multi_lang.get_text("EP020-0023", "ログ出力に失敗しました") globals.logger.debug(error_detail) raise common.UserException("{} Error log output status:{}".format(inspect.currentframe().f_code.co_name, response.status_code)) # # workspace info. Roll update date update - ワークスペース情報 ロール更新日の更新 # post_data = { "role_update_at" : "", } globals.logger.debug("role datetime update Start") api_url = "{}://{}:{}/workspace/{}".format(os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT'], workspace_id) response = requests.patch(api_url, headers=post_headers, data=json.dumps(post_data)) if response.status_code != 200: error_detail = multi_lang.get_text("EP000-0024", "対象の情報({})を更新できませんでした", "workspace") globals.logger.debug(error_detail) raise common.UserException("{} Error workspace-db update status:{}".format(inspect.currentframe().f_code.co_name, response.status_code)) globals.logger.debug("role datetime update Succeed!") return jsonify({"result": "200"}), 200 except common.AuthException as e: return jsonify({"result": 400, "errorDetail": error_detail}), 400 except common.UserException as e: return common.user_error_to_message(e, app_name + exec_stat, error_detail, return_code) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def get_cd_operations(workspace_id): """get cd-operations list Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "Operation情報取得" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format( inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # ワークスペースアクセス情報取得 access_info = api_access_info.get_access_info(workspace_id) # namespaceの取得 namespace = common.get_namespace_name(workspace_id) ita_restapi_endpoint = "http://{}.{}.svc:{}/default/menu/07_rest_api_ver1.php".format( EPOCH_ITA_HOST, namespace, EPOCH_ITA_PORT) ita_user = access_info['ITA_USER'] ita_pass = access_info['ITA_PASSWORD'] # HTTPヘッダの生成 filter_headers = { 'host': EPOCH_ITA_HOST + ':' + EPOCH_ITA_PORT, 'Content-Type': 'application/json', 'Authorization': base64.b64encode( (ita_user + ':' + ita_pass).encode()), 'X-Command': 'FILTER', } # # オペレーションの取得 # opelist_resp = requests.post(ita_restapi_endpoint + '?no=' + ite_menu_operation, headers=filter_headers) globals.logger.debug('---- Operation ----') globals.logger.debug(opelist_resp.text) if common.is_json_format(opelist_resp.text): opelist_json = json.loads(opelist_resp.text) else: error_detail = "Operation情報取得失敗" raise common.UserException(error_detail) rows = opelist_json # 正常終了 ret_status = 200 # 戻り値をそのまま返却 return jsonify({"result": ret_status, "rows": rows}), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def user_get(): """ユーザー情報取得 user info get Returns: dict: user info. """ try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format( inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) user_id = common.get_current_user(request.headers) api_url = "{}://{}:{}/{}/user/{}".format( os.environ['EPOCH_EPAI_API_PROTOCOL'], os.environ['EPOCH_EPAI_API_HOST'], os.environ['EPOCH_EPAI_API_PORT'], os.environ["EPOCH_EPAI_REALM_NAME"], user_id) # # get users - ユーザー取得 # response = requests.get(api_url) if response.status_code != 200 and response.status_code != 404: error_detail = multi_lang.get_text("EP020-0008", "ユーザー情報の取得に失敗しました") raise common.UserException("{} Error user get status:{}".format( inspect.currentframe().f_code.co_name, response.status_code)) users = json.loads(response.text) # globals.logger.debug(f"users:{users}") # 取得したユーザーのロールを取得 Get the role of the acquired user api_url = "{}://{}:{}/{}/user/{}/roles/epoch-system".format( os.environ['EPOCH_EPAI_API_PROTOCOL'], os.environ['EPOCH_EPAI_API_HOST'], os.environ['EPOCH_EPAI_API_PORT'], os.environ["EPOCH_EPAI_REALM_NAME"], user_id) # # get user role - ユーザーロール情報取得 # response = requests.get(api_url) if response.status_code != 200: error_detail = multi_lang.get_text("EP020-0009", "ユーザーロール情報の取得に失敗しました") raise common.UserException( "{} Error user role get status:{}".format( inspect.currentframe().f_code.co_name, response.status_code)) ret_roles = json.loads(response.text) # globals.logger.debug(f"roles:{ret_roles}") sorted_roles = sorted(ret_roles["rows"], key=lambda x: x['name']) # globals.logger.debug(f"sorted_roles:{sorted_roles}") stock_workspace_id = [] set_role_display = [] ret_role = "" all_roles = [] all_composite_roles = [] workspace_name = None # 取得したすべてのロールから絞り込む Narrow down from all acquired roles for get_role in sorted_roles: role_info = common.get_role_info(get_role["name"]) # 該当のロールのみチェック Check only the corresponding role if role_info is not None: # 同じロールは退避しない Do not save the same role if get_role["name"] not in all_roles: all_roles.append(get_role["name"]) ex_role = re.match("ws-({}|\d+)-(.+)", get_role["name"]) globals.logger.debug("role_workspace_id:{} kind:{}".format( ex_role[1], ex_role[2])) # ワークスペースは重複があるので、1回のみ抽出 Workspaces are duplicated, so extract only once # ただし、1回目は設定しない However, do not set the first time if ex_role[ 1] not in stock_workspace_id and workspace_name is not None: # 並んでいる要素をソート Sort the elements in a row set_role_display.sort() # ソート用の文字列カット String cut for sorting role_display = [s[3:] for s in set_role_display] # workspace_id が 変わった際にレコード化 Record when workspace_id changes ret_role = ret_role + ',"{}":["{}"]'.format( workspace_name, '","'.join(role_display)) set_role_display = [] # 取得したロール名を配列にする Make the acquired role name into an array set_role_display.append( f"{role_info[3]:02}:" + multi_lang.get_text(role_info[1], role_info[2])) workspace_id = ex_role[1] stock_workspace_id.append(workspace_id) # workspace get api_url = "{}://{}:{}/workspace/{}".format( os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT'], workspace_id) response = requests.get(api_url) if response.status_code != 200: error_detail = multi_lang.get_text("EP020-0013", "ワークスペース情報の取得に失敗しました") raise common.UserException( "{} Error workspace get status:{}".format( inspect.currentframe().f_code.co_name, response.status_code)) ret_ws = json.loads(response.text) workspace_name = ret_ws["rows"][0]["common"]["name"] # workspace name empty to set fix name if len(workspace_name) == 0: workspace_name = multi_lang.get_text("EP000-0025", "名称未設定") else: # 同じ子ロールは退避しない Do not save the same composite role if get_role["name"] not in all_composite_roles: all_composite_roles.append(get_role["name"]) # 並んでいる要素をソート Sort the elements in a row set_role_display.sort() # ソート用の文字列カット String cut for sorting role_display = [s[3:] for s in set_role_display] ret_role = ret_role + ',"{}":["{}"]'.format(workspace_name, '","'.join(role_display)) ret_role = "{" + ret_role[1:] + "}" ret_user = { "user_id": user_id, "username": users["info"]["username"], "enabled": users["info"]["enabled"], "firstName": users["info"]["firstName"], "lastName": users["info"]["lastName"], "email": users["info"]["email"], "role": ret_role, "roles": all_roles, "composite_roles": all_composite_roles, } # globals.logger.debug(f"ret_user:{ret_user}") return ret_user except common.UserException as e: raise except Exception as e: raise
def get_git_hooks(workspace_id): """Get webhook history - webhook履歴取得 Args: workspace_id (int): workspace ID Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "CIパイプラインwebhook履歴取得" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format(inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # workspace get api_url = "{}://{}:{}/workspace/{}".format(os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT'], workspace_id) response = requests.get(api_url) if response.status_code != 200: error_detail = multi_lang.get_text("EP020-0013", "ワークスペース情報の取得に失敗しました") globals.logger.debug(error_detail) raise common.UserException(error_detail) # 取得したワークスペース情報を退避 Save the acquired workspace information ret = json.loads(response.text) # 取得したworkspace情報をパラメータとして受け渡す Pass the acquired workspace information as a parameter workspace_info = ret["rows"][0] git_token = workspace_info["ci_config"]["pipelines_common"]["git_repositry"]["token"] git_user = workspace_info["ci_config"]["pipelines_common"]["git_repositry"]["user"] # ヘッダ情報 header info. post_headers_in_token = { 'private-token': git_token, 'Content-Type': 'application/json', } rows = [] # パイプライン数分処理する Process for a few minutes in the pipelines for pipeline in workspace_info["ci_config"]["pipelines"]: git_url = pipeline["git_repositry"]["url"] # GitHubのみ対応 Only compatible with GitHub if workspace_info["cd_config"]["environments_common"]["git_repositry"]["housing"] == const.HOUSING_OUTER: # GitHub hooks get api_url = "{}://{}:{}/hooks?git_url={}".format(os.environ['EPOCH_CONTROL_GITHUB_PROTOCOL'], os.environ['EPOCH_CONTROL_GITHUB_HOST'], os.environ['EPOCH_CONTROL_GITHUB_PORT'], urllib.parse.quote(git_url)) response = requests.get(api_url, headers=post_headers_in_token) if response.status_code != 200: raise common.UserException("git hooks get error:[{}]".format(response.status_code)) ret_git_hooks = json.loads(response.text) # globals.logger.debug("rows:[{}]".format(ret_git_hooks["rows"])) # 取得した情報数分処理する # Process for the number of acquired information for hooks_row in ret_git_hooks["rows"]: # GitHub hooks get api_url = "{}://{}:{}/hooks/{}/deliveries?git_url={}".format(os.environ['EPOCH_CONTROL_GITHUB_PROTOCOL'], os.environ['EPOCH_CONTROL_GITHUB_HOST'], os.environ['EPOCH_CONTROL_GITHUB_PORT'], hooks_row["id"], urllib.parse.quote(git_url)) response = requests.get(api_url, headers=post_headers_in_token) if response.status_code != 200: raise common.UserException("git deliveries get error:[{}]".format(response.status_code)) ret_git_deliveries = json.loads(response.text) # globals.logger.debug("deliveries:[{}]".format(ret_git_deliveries["rows"])) # 取得した情報数分処理する # Process for the number of acquired information for deliveries_row in ret_git_deliveries["rows"]: # event push only if deliveries_row["event"].lower() == "push": row = { "git_url": git_url, "repository": "{}/{}".format(git_user, re.search('([^/]+?)(?=.git)', git_url).group()), "branch": "", "url": hooks_row["config"]["url"], "date": deliveries_row["delivered_at"], "status": deliveries_row["status"], "status_code": deliveries_row["status_code"], "event": deliveries_row["event"], } rows.append(row) response = { "result":"200", "rows" : rows, } ret_status = 200 return jsonify(response), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def post_manifest_template(workspace_id): """manifest テンプレート登録 manifest template registration Args: workspace_id (int): workspace ID Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "manifestテンプレート登録" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format( inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # ファイルの存在チェック exists file check if 'manifest_files' not in request.files: error_detail = "アップロードファイルがありません" globals.logger.debug('upload file not found') raise common.UserException(error_detail) apiInfo = "{}://{}:{}".format( os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT']) # ヘッダ情報 post_headers = { 'Content-Type': 'application/json', } # データ情報(追加用) post_data_add = {"manifests": []} # データ情報(更新用) post_data_upd = {"manifests": []} # RsWorkspace API呼び出し(全件取得) response = requests.get("{}/workspace/{}/manifests".format( apiInfo, workspace_id), headers=post_headers) # 戻り値が正常値以外の場合は、処理を終了 if response.status_code != 200: error_detail = "manifestテンプレート情報取得失敗" globals.logger.debug("CALL responseAPI /manifests Error") raise common.UserException(error_detail) ret_manifests = json.loads(response.text) globals.logger.debug("get Filedata ------------------ S") globals.logger.debug(ret_manifests["rows"]) globals.logger.debug("get Filedata ------------------ E") # 送信されたマニフェストファイル数分処理する for manifest_file in request.files.getlist('manifest_files'): file_text = '' # ↓ 2重改行になっているので、変更するかも ↓ for line in manifest_file: file_text += line.decode('utf-8') # ファイル情報(manifest_data) manifest_data = { "file_name": manifest_file.filename, "file_text": file_text } # 同一ファイルがあるかファイルIDを取得 file_id = common.get_file_id(ret_manifests["rows"], manifest_file.filename) # 同一ファイル名が登録されている場合は、更新とする if not file_id: # データ登録情報(manifest_dataと結合) post_data_add['manifests'].append(manifest_data) else: manifest_data["file_id"] = file_id # データ更新情報(manifest_dataと結合) post_data_upd['manifests'].append(manifest_data) globals.logger.debug("post_data_add ------------------ S") globals.logger.debug(post_data_add) globals.logger.debug("post_data_add ------------------ E") globals.logger.debug("post_data_upd ------------------ S") globals.logger.debug(post_data_upd) globals.logger.debug("post_data_upd ------------------ E") # RsWorkspace API呼び出し(削除) # response = requests.delete( apiInfo + "/workspace/" + str(workspace_id) + "/manifests", headers=post_headers) # 更新は1件ずつ実施 for upd in post_data_upd['manifests']: # JSON形式に変換 post_data = json.dumps(upd) # RsWorkspace API呼び出し(更新) response = requests.put("{}/workspace/{}/manifests/{}".format( apiInfo, workspace_id, upd["file_id"]), headers=post_headers, data=post_data) # JSON形式に変換 post_data = json.dumps(post_data_add) # RsWorkspace API呼び出し(登録) response = requests.post("{}/workspace/{}/manifests".format( apiInfo, workspace_id), headers=post_headers, data=post_data) # ITA呼び出し globals.logger.debug("CALL ita_registration Start") response = ita_registration(workspace_id) globals.logger.debug("CALL ita_registration End response:") globals.logger.debug(response) # 正常終了 normal return code ret_status = 200 return jsonify({"result": ret_status, "rows": response}), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def get_registry(workspace_id): """Get container registry information - コンテナレジストリ情報取得 Args: workspace_id (int): workspace ID Returns: Response: HTTP Respose """ app_name = multi_lang.get_text("EP020-0003", "ワークスペース情報:") exec_stat = multi_lang.get_text("EP020-0074", "CIパイプライン コンテナレジストリ情報取得") error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format(inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # Workspace information acquisition URL - ワークスペース情報取得URL api_url = "{}://{}:{}/workspace/{}".format(os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'], os.environ['EPOCH_RS_WORKSPACE_HOST'], os.environ['EPOCH_RS_WORKSPACE_PORT'], workspace_id) # Get Workspace information ― ワークスペース情報取得 response = requests.get(api_url) workspace_json = json.loads(response.text) if response.status_code != 200: error_detail = multi_lang.get_text("EP020-0089", "ワークスペース情報の取得に失敗しました") globals.logger.debug(error_detail) raise common.UserException(error_detail) git_user = workspace_json["rows"][0]["ci_config"]["pipelines_common"]["git_repositry"]["user"] # Request header for getting container registry information # コンテナレジストリ情報取得用 リクエストヘッダ request_headers = { 'Content-Type': 'application/json', 'username': workspace_json["rows"][0]["ci_config"]["pipelines_common"]["container_registry"]["user"], 'password': workspace_json["rows"][0]["ci_config"]["pipelines_common"]["container_registry"]["password"] } # CI result information acquisition URL - CI結果情報取得URL api_url = "{}://{}:{}/workspace/{}/tekton/task".format(os.environ['EPOCH_RS_CI_RESULT_PROTOCOL'], os.environ['EPOCH_RS_CI_RESULT_HOST'], os.environ['EPOCH_RS_CI_RESULT_PORT'], workspace_id) # Get CI result information ― CI結果情報取得 response = requests.get(api_url) ci_result_json = json.loads(response.text) if response.status_code != 200: error_detail = multi_lang.get_text("EP020-0088", "CI結果情報の取得に失敗しました") globals.logger.debug(error_detail) raise common.UserException(error_detail) rows = [] # Extract the repository information from the acquired CI result information and format it # 取得したCI結果情報の内、リポジトリ情報を抜き出して整形 for ci_result in ci_result_json["rows"]: # Container registry information acquisition URL - コンテナレジストリ情報取得URL api_url = "{}://{}:{}/registry/{}".format(os.environ['EPOCH_CONTROL_DOCKERHUB_PROTOCOL'], os.environ['EPOCH_CONTROL_DOCKERHUB_HOST'], os.environ['EPOCH_CONTROL_DOCKERHUB_PORT'], ci_result["container_registry_image"]) # Get container registry information - コンテナレジストリ情報取得 response = requests.post(api_url, headers=request_headers) registry_json = json.loads(response.text) if response.status_code != 200: error_detail = multi_lang.get_text("EP020-0075", "コンテナレジストリ情報の取得に失敗しました") globals.logger.debug(error_detail) raise common.UserException(error_detail) for registry in registry_json["rows"]: # Merge repository information with repository information that matches the registry name and image tag # レジストリ名とイメージタグが一致する、リポジトリ情報と、レジストリ情報をマージする if ci_result["container_registry_image"] in registry["name"] \ and ci_result["container_registry_image_tag"] in registry["tag"]: rows.append( { "registry": registry, "repository": { "name": "{}/{}".format(git_user, re.search('([^/]+?)(?=.git)', ci_result["git_repository_url"]).group()), "url": ci_result["git_repository_url"], "branch": ci_result["git_branch"] } } ) ret_status = 200 return jsonify({ "return": ret_status, "rows": rows }), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def delete_manifest_template(workspace_id, file_id): """manifest テンプレート削除 manifest template delete Args: workspace_id (int): workspace ID file_id (int): file ID Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "manifestテンプレート削除" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format( inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # ヘッダ情報 headers = { 'Content-Type': 'application/json', } # DELETE送信(作成) resourceProtocol = os.environ['EPOCH_RS_WORKSPACE_PROTOCOL'] resourceHost = os.environ['EPOCH_RS_WORKSPACE_HOST'] resourcePort = os.environ['EPOCH_RS_WORKSPACE_PORT'] apiurl = "{}://{}:{}/workspace/{}/manifests/{}".format( resourceProtocol, resourceHost, resourcePort, workspace_id, file_id) response = requests.delete(apiurl, headers=headers) if response.status_code == 200 and common.is_json_format( response.text): # 200(正常)かつ、レスポンスデータがJSON形式の場合は、後続の処理を実行 pass elif response.status_code == 404: # manifestデータが見つからない(404)場合 error_detail = 'manifest template data not found' raise common.UserException(error_detail) elif response.status_code != 200: # 200(正常), 404(not found) 以外の応答の場合 error_detail = 'CALL responseAPI Error' raise common.UserException(error_detail) # ITA呼び出し globals.logger.debug("CALL ita_registration Start") response = ita_registration(workspace_id) globals.logger.debug("CALL ita_registration End response:") globals.logger.debug(response) # 正常終了 normal return code ret_status = 200 return jsonify({"result": ret_status, "rows": response}), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def get_ci_pipeline_result(workspace_id): """Get CI pipeline results (CIパイプライン結果取得) Args: workspace_id (int): WORKSPACE ID Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "CIパイプライン結果取得" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format(inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # Get Query Parameter latest = request.args.get('latest', default='False') # ヘッダ情報 post_headers = { 'Content-Type': 'application/json', } # epoch-control-tekton-api の呼び先設定 api_url_tekton = "{}://{}:{}/workspace/{}/tekton/pipelinerun".format(os.environ["EPOCH_CONTROL_TEKTON_PROTOCOL"], os.environ["EPOCH_CONTROL_TEKTON_HOST"], os.environ["EPOCH_CONTROL_TEKTON_PORT"], workspace_id) # TEKTONパイプライン情報取得 exec_stat = "pipelinerun情報取得" request_response = requests.get(api_url_tekton, params={"latest": latest}) ret = json.loads(request_response.text) if request_response.status_code != 200: if "errorDetail" in ret: exec_detail = ret["errorDetail"] else: exec_detail = "" raise common.UserException(error_detail) rows = [] # globals.logger.debug(f'rows:{ret["rows"]}') for row in ret["rows"]: tasks = [] if row is None: continue if not "tasks" in row: continue for task in row["tasks"]: # globals.logger.debug(f'tasks:{task}') # taskにログがある場合のみ取得 # Get only if task has a log if "taskrun_name" in task: taskrun_name = task["taskrun_name"] # epoch-control-tekton-api の呼び先設定 api_url_tekton = "{}://{}:{}/workspace/{}/tekton/taskrun/{}/logs".format( os.environ["EPOCH_CONTROL_TEKTON_PROTOCOL"], os.environ["EPOCH_CONTROL_TEKTON_HOST"], os.environ["EPOCH_CONTROL_TEKTON_PORT"], workspace_id, taskrun_name) # TEKTONタスク実行ログ情報取得 exec_stat = "taskrunログ情報取得" request_response = requests.get(api_url_tekton, params={"latest": latest}) ret = json.loads(request_response.text) if request_response.status_code != 200: if "errorDetail" in ret: error_detail = ret["errorDetail"] else: error_detail = "" raise common.UserException(error_detail) # 取得したログをtaskの"log"として追加 # Add the acquired log as "log" of task task["log"] = ret["log"] tasks.append(task) # 成形したtaskの情報を上書き # Overwrite the information of the molded task row["tasks"] = tasks rows.append(row) # globals.logger.debug(f'rows:{rows}') ret_status = 200 response = { "result": ret_status, "rows" : rows, } # 戻り値をそのまま返却 return jsonify(response), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def create_ita(workspace_id): """IT-Automation Pod Create Args: workspace_id (int): workspace id Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "IT-Automation環境構築" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format( inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # namespace定義 name = common.get_namespace_name(workspace_id) globals.logger.debug("ita-pod create start") # templateの展開 with tempfile.TemporaryDirectory() as tempdir: file_name = 'ita_install.yaml' yaml_param = { "HTTP_PROXY": os.environ.get("EPOCH_HTTP_PROXY"), "HTTPS_PROXY": os.environ.get("EPOCH_HTTPS_PROXY"), "NO_PROXY": os.environ.get("EPOCH_HOSTNAME"), } yaml_text = render_template(file_name, param=yaml_param) # yaml一時ファイル生成 path_yamlfile = '{}/{}'.format(tempdir, file_name) with open(path_yamlfile, mode='w') as fp: fp.write(yaml_text) # kubectl実行 try: result_kubectl = subprocess.check_output( ['kubectl', 'apply', '-f', path_yamlfile, '-n', name], stderr=subprocess.STDOUT) globals.logger.debug( 'COMMAAND SUCCEED: kubectl apply -f {}\n{}'.format( path_yamlfile, result_kubectl.decode('utf-8'))) except subprocess.CalledProcessError as e: globals.logger.error('COMMAND ERROR RETURN:{}\n{}'.format( e.returncode, e.output.decode('utf-8'))) exec_detail = "IT-AutomationのPodが生成できません。環境を確認してください。" raise common.UserException(exec_detail) except Exception: raise # 対象となるdeploymentを定義 # deployments = [ "deployment/ita-worker" ] # envs = [ # "HTTP_PROXY=" + os.environ['EPOCH_HTTP_PROXY'], # "HTTPS_PROXY=" + os.environ['EPOCH_HTTPS_PROXY'], # "http_proxy=" + os.environ['EPOCH_HTTP_PROXY'], # "https_proxy=" + os.environ['EPOCH_HTTPS_PROXY'] # ] # exec_detail = "環境変数[PROXY]を確認してください" # for deployment_name in deployments: # for env_name in envs: # # 環境変数の設定 # try: # result_kubectl = subprocess.check_output(["kubectl","set","env",deployment_name,"-n",name,env_name],stderr=subprocess.STDOUT) # globals.logger.debug('COMMAAND SUCCEED: kubectl set env {}\n{}'.format(deployment_name, result_kubectl.decode('utf-8'))) # except subprocess.CalledProcessError as e: # globals.logger.error('COMMAND ERROR RETURN:{}\n{}'.format(e.returncode, e.output.decode('utf-8'))) # exec_detail = "{}の環境変数[PROXY]の設定ができません。環境を確認してください。".format(deployment_name) # raise common.UserException(exec_detail) # except Exception: # raise exec_detail = "" # 正常終了 ret_status = 200 # 戻り値をそのまま返却 return jsonify({"result": ret_status}), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def cd_execute_cancel(workspace_id, conductor_id): """CD実行取り消し cd execute cancel Args: workspace_id (int): workspace id conductor_id (str): conductor id Returns: Response: HTTP Respose """ try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format( inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # ワークスペースアクセス情報取得 get workspace access info. access_info = api_access_info.get_access_info(workspace_id) # namespaceの取得 get namespace namespace = common.get_namespace_name(workspace_id) ita_restapi_endpoint = "http://{}.{}.svc:{}/default/menu/07_rest_api_ver1.php".format( EPOCH_ITA_HOST, namespace, EPOCH_ITA_PORT) ita_user = access_info['ITA_USER'] ita_pass = access_info['ITA_PASSWORD'] # HTTPヘッダの生成 HTTP header generation filter_headers = { 'host': EPOCH_ITA_HOST + ':' + EPOCH_ITA_PORT, 'Content-Type': 'application/json', 'Authorization': base64.b64encode( (ita_user + ':' + ita_pass).encode()), 'X-Command': 'CANCEL', } # 実行パラメータ設定 Execution parameter setting data = {"CONDUCTOR_INSTANCE_ID": conductor_id} # json文字列に変換("utf-8"形式に自動エンコードされる) Convert to json string (automatically encoded in "utf-8" format) json_data = json.dumps(data) # リクエスト送信 response = requests.post(ita_restapi_endpoint + '?no=' + ite_menu_conductor_cancel, headers=filter_headers, data=json_data) globals.logger.debug(response.text) resp_data = json.loads(response.text) # Even if it fails, "status" is returned as "SUCCEED", so the error is judged by "RESULTCODE" (success: 0, failure: 2). # 失敗時も"status"は"SUCCEED"で返ってくるため、"RESULTCODE"(成功:0, 失敗:2)でエラーを判断 if resp_data["resultdata"]["RESULTCODE"] == "002": globals.logger.error("no={} status:{}".format( ite_menu_conductor_cancel, resp_data["status"])) error_detail = multi_lang.get_text( "EP034-0004", "CD予約取り消しの呼び出しに失敗しました ita-status:{0} resultdata:{1}".format( resp_data["status"], resp_data["resultdata"]), resp_data["status"], resp_data["resultdata"]) raise common.UserException(error_detail) # 正常終了 Successful completion ret_status = 200 # 戻り値をそのまま返却 Return the return value as it is return jsonify({"result": ret_status}), ret_status except common.UserException as e: return common.server_error(e) except Exception as e: return common.server_error(e)
def is_already_imported(host, auth, init_auth): """新しいパスワードでのimport確認 Args: host (str): ITAのホスト auth (str): ITAの認証情報 init_auth (str): ITAの初期認証情報 Raises: Exception: [description] common.UserException: [description] Returns: int: 200:インポート済み、0:インポート前 """ # *-*-*-* 新しいパスワードでのimport確認 *-*-*-* # POST送信する # ヘッダ情報 header = { 'host': host, 'Content-Type': 'application/json', 'Authorization': auth, 'X-Command': 'FILTER', } # フィルタ条件はなし data = {} # json文字列に変換("utf-8"形式に自動エンコードされる) json_data = json.dumps(data) # インポート結果取得 dialog_response = requests.post( 'http://' + host + '/default/menu/07_rest_api_ver1.php?no=2100000213', headers=header, data=json_data) if dialog_response.status_code != 200 and dialog_response.status_code != 401: globals.logger.error("no=2100000213 status_code:{}".format( dialog_response.status_code)) globals.logger.error(dialog_response.text) raise common.UserException(dialog_response.text) if dialog_response.status_code == 200: dialog_resp_data = json.loads(dialog_response.text) if dialog_resp_data["resultdata"]["CONTENTS"]["RECORD_LENGTH"] > 0: return 200 else: # パスワード変更済み、かつインポートデータが無い状態は異常である raise common.UserException( 'IT-Automation Import error import-file abnormal') # *-*-*-* 初期パスワードでのimport確認 *-*-*-* # POST送信する # ヘッダ情報 header = { 'host': host, 'Content-Type': 'application/json', 'Authorization': init_auth, 'X-Command': 'FILTER', } # フィルタ条件はなし data = {} # json文字列に変換("utf-8"形式に自動エンコードされる) json_data = json.dumps(data) # インポート結果取得 dialog_response = requests.post( 'http://' + host + '/default/menu/07_rest_api_ver1.php?no=2100000213', headers=header, data=json_data) if dialog_response.status_code != 200 and dialog_response.status_code != 401: globals.logger.error("no=2100000213 status_code:{}".format( dialog_response.status_code)) globals.logger.error(dialog_response.text) raise common.UserException(dialog_response.text) if dialog_response.status_code == 200: # 初期パスワードで認証通る場合は、インポート前状態として判定する return 0 # *-*-*-* システムが認識している以外のパスワードになっている *-*-*-* raise common.UserException( 'IT-Automation Import error password not abnormal')
def argocd_settings(workspace_id): """Setting argocd - ArgoCD設定 Args: workspace_id (int): workspace id Returns: Response: HTTP Respose """ app_name = multi_lang.get_text("EP035-0001", "ワークスペース情報:") exec_stat = multi_lang.get_text("EP035-0004", "ArgoCD設定") error_detail = "" try: # ワークスペースアクセス情報取得 access_data = get_access_info(workspace_id) argo_host = 'argocd-server.epoch-ws-{}.svc'.format(workspace_id) argo_id = access_data['ARGOCD_USER'] argo_password = access_data['ARGOCD_PASSWORD'] # 引数で指定されたCD環境を取得 request_json = json.loads(request.data) request_ci_env = request_json["ci_config"]["environments"] request_cd_env = request_json["cd_config"]["environments"] gitUsername = request_json["cd_config"]["environments_common"][ "git_repositry"]["user"] gitPassword = request_json["cd_config"]["environments_common"][ "git_repositry"]["token"] housing = request_json["cd_config"]["environments_common"][ "git_repositry"]["housing"] # # argocd login # globals.logger.debug("argocd login :"******"argocd", "login", argo_host, "--insecure", "--username", argo_id, "--password", argo_password ], stderr=subprocess.STDOUT) globals.logger.debug(stdout_cd.decode('utf-8')) # # repo setting # # リポジトリ情報の一覧を取得する globals.logger.debug("argocd repo list :") stdout_cd = subprocess.check_output( ["argocd", "repo", "list", "-o", "json"], stderr=subprocess.STDOUT) globals.logger.debug(stdout_cd.decode('utf-8')) # 設定済みのリポジトリ情報をクリア repo_list = json.loads(stdout_cd) for repo in repo_list: globals.logger.debug("argocd repo rm [repo] {} :".format( repo['repo'])) stdout_cd = subprocess.check_output( ["argocd", "repo", "rm", repo['repo']], stderr=subprocess.STDOUT) globals.logger.debug(stdout_cd.decode('utf-8')) # 環境群数分処理を実行 for env in request_cd_env: env_name = env["name"] gitUrl = env["git_repositry"]["url"] exec_stat = multi_lang.get_text("EP035-0005", "ArgoCD設定 - リポジトリ作成") error_detail = multi_lang.get_text("EP035-0006", "IaCリポジトリの設定内容を確認してください") # レポジトリの情報を追加 globals.logger.debug("argocd repo add :") if housing == "inner": stdout_cd = subprocess.check_output([ "argocd", "repo", "add", "--insecure-ignore-host-key", gitUrl, "--username", gitUsername, "--password", gitPassword ], stderr=subprocess.STDOUT) else: stdout_cd = subprocess.check_output([ "argocd", "repo", "add", gitUrl, "--username", gitUsername, "--password", gitPassword ], stderr=subprocess.STDOUT) globals.logger.debug(stdout_cd.decode('utf-8')) # # app setting # # アプリケーション情報の一覧を取得する globals.logger.debug("argocd app list :") stdout_cd = subprocess.check_output( ["argocd", "app", "list", "-o", "json"], stderr=subprocess.STDOUT) globals.logger.debug(stdout_cd.decode('utf-8')) # アプリケーション情報を削除する app_list = json.loads(stdout_cd) for app in app_list: globals.logger.debug('argocd app delete [app] {} :'.format( app['metadata']['name'])) stdout_cd = subprocess.check_output( ["argocd", "app", "delete", app['metadata']['name'], "-y"], stderr=subprocess.STDOUT) # アプリケーションが消えるまでWaitする globals.logger.debug("wait : argocd app list clean") for i in range(WAIT_APPLICATION_DELETE): # アプリケーションの一覧を取得し、結果が0件になるまでWaitする stdout_cd = subprocess.check_output( ["argocd", "app", "list", "-o", "json"], stderr=subprocess.STDOUT) app_list = json.loads(stdout_cd) if len(app_list) == 0: break time.sleep(1) # 1秒ごとに確認 # 環境群数分処理を実行 for env in request_cd_env: argo_app_name = get_argo_app_name(workspace_id, env['environment_id']) cluster = env["deploy_destination"]["cluster_url"] namespace = env["deploy_destination"]["namespace"] gitUrl = env["git_repositry"]["url"] # namespaceの存在チェック ret = common.get_namespace(namespace) if ret is None: # 存在しない(None)ならnamespace作成 ret = common.create_namespace(namespace) if ret is None: # namespaceの作成で失敗(None)が返ってきた場合はエラー error_detail = 'create namespace処理に失敗しました' raise common.UserException(error_detail) exec_stat = multi_lang.get_text("EP035-0007", "ArgoCD設定 - アプリケーション作成") error_detail = multi_lang.get_text("EP035-0008", "ArgoCDの入力内容を確認してください") # argocd app create catalogue \ # --repo [repogitory URL] \ # --path ./ \ # --dest-server https://kubernetes.default.svc \ # --dest-namespace [namespace] \ # --auto-prune \ # --sync-policy automated # アプリケーション作成 globals.logger.debug("argocd app create :") stdout_cd = subprocess.check_output([ "argocd", "app", "create", argo_app_name, "--repo", gitUrl, "--path", "./", "--dest-server", cluster, "--dest-namespace", namespace, "--auto-prune", "--sync-policy", "automated", ], stderr=subprocess.STDOUT) globals.logger.debug(stdout_cd.decode('utf-8')) ret_status = 200 # 戻り値をそのまま返却 return jsonify({"result": ret_status}), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def cd_execute(workspace_id): """cd execute Returns: Response: HTTP Respose """ app_name = "ワークスペース情報:" exec_stat = "CD実行" error_detail = "" try: globals.logger.debug('#' * 50) globals.logger.debug('CALL {}'.format( inspect.currentframe().f_code.co_name)) globals.logger.debug('#' * 50) # パラメータ情報(JSON形式) prameter save payload = request.json.copy() # ワークスペースアクセス情報取得 get workspace access info. access_info = api_access_info.get_access_info(workspace_id) # namespaceの取得 get namespace namespace = common.get_namespace_name(workspace_id) ita_restapi_endpoint = "http://{}.{}.svc:{}/default/menu/07_rest_api_ver1.php".format( EPOCH_ITA_HOST, namespace, EPOCH_ITA_PORT) ita_user = access_info['ITA_USER'] ita_pass = access_info['ITA_PASSWORD'] operation_id = payload["operation_id"] conductor_class_no = payload["conductor_class_no"] preserve_datetime = payload["preserve_datetime"] # POST送信する # HTTPヘッダの生成 filter_headers = { 'host': EPOCH_ITA_HOST + ':' + EPOCH_ITA_PORT, 'Content-Type': 'application/json', 'Authorization': base64.b64encode( (ita_user + ':' + ita_pass).encode()), 'X-Command': 'EXECUTE', } # 実行パラメータ設定 data = { "CONDUCTOR_CLASS_NO": conductor_class_no, "OPERATION_ID": operation_id, "PRESERVE_DATETIME": preserve_datetime, } # json文字列に変換("utf-8"形式に自動エンコードされる) json_data = json.dumps(data) # リクエスト送信 exec_response = requests.post(ita_restapi_endpoint + '?no=' + ite_menu_conductor_exec, headers=filter_headers, data=json_data) if exec_response.status_code != 200: globals.logger.error(exec_response.text) error_detail = multi_lang.get_text( "EP034-0001", "CD実行の呼び出しに失敗しました status:{0}".format( exec_response.status_code), exec_response.status_code) raise common.UserException(error_detail) globals.logger.debug("-------------------------") globals.logger.debug("response:") globals.logger.debug(exec_response.text) globals.logger.debug("-------------------------") resp_data = json.loads(exec_response.text) if resp_data["status"] != "SUCCEED": globals.logger.error("no={} status:{}".format( ite_menu_conductor_exec, resp_data["status"])) error_detail = multi_lang.get_text( "EP034-0002", "CD実行の呼び出しに失敗しました ita-status:{0} resultdata:{1}".format( resp_data["status"], resp_data["resultdata"]), resp_data["status"], resp_data["resultdata"]) raise common.UserException(error_detail) if resp_data["status"] != "SUCCEED": globals.logger.error("no={} status:{}".format( ite_menu_conductor_exec, resp_data["status"])) error_detail = multi_lang.get_text( "EP034-0002", "CD実行の呼び出しに失敗しました ita-status:{0} resultdata:{1}".format( resp_data["status"], resp_data["resultdata"]), resp_data["status"], resp_data["resultdata"]) raise common.UserException(error_detail) # 戻り値が"000"以外の場合は、エラーを返す # If the return value is other than "000", an error is returned. if resp_data["resultdata"]["RESULTCODE"] != "000": globals.logger.error("RESULTCODE error: resultdata:{}".format( resp_data["resultdata"])) error_detail = resp_data["resultdata"]["RESULTINFO"] raise common.UserException(error_detail) # 作業IDを退避 cd_result_id = resp_data["resultdata"]["CONDUCTOR_INSTANCE_ID"] # 正常終了 ret_status = 200 # 戻り値をそのまま返却 return jsonify({ "result": ret_status, "cd_result_id": cd_result_id }), ret_status except common.UserException as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail) except Exception as e: return common.server_error_to_message(e, app_name + exec_stat, error_detail)
def cd_result_get(workspace_id, conductor_id): """CD実行結果取得 cd result get Args: workspace_id (int): workspace id conductor_id (str): conductor id Returns: Response: HTTP Respose """ try: globals.logger.debug('#' * 50) globals.logger.debug( 'CALL {} workspace_id[{}] conductor_id[{}]'.format( inspect.currentframe().f_code.co_name, workspace_id, conductor_id)) globals.logger.debug('#' * 50) # ワークスペースアクセス情報取得 get workspace access info. access_info = api_access_info.get_access_info(workspace_id) # namespaceの取得 get namespace namespace = common.get_namespace_name(workspace_id) ita_restapi_endpoint = "http://{}.{}.svc:{}/default/menu/07_rest_api_ver1.php".format( EPOCH_ITA_HOST, namespace, EPOCH_ITA_PORT) ita_user = access_info['ITA_USER'] ita_pass = access_info['ITA_PASSWORD'] # POST送信する post sender # HTTPヘッダの生成 HTTP header generation filter_headers = { 'host': EPOCH_ITA_HOST + ':' + EPOCH_ITA_PORT, 'Content-Type': 'application/json', 'Authorization': base64.b64encode( (ita_user + ':' + ita_pass).encode()), 'X-Command': 'INFO', } # 実行パラメータ設定 parameter setting data = {"CONDUCTOR_INSTANCE_ID": conductor_id} # json文字列に変換 json convert json_data = json.dumps(data) # リクエスト送信 request post exec_response = requests.post(ita_restapi_endpoint + '?no=' + ite_menu_conductor_result, headers=filter_headers, data=json_data) if exec_response.status_code != 200: globals.logger.error(exec_response.text) error_detail = multi_lang.get_text( "EP034-0005", "実行結果取得の呼び出しに失敗しました status:{0}".format( exec_response.status_code), exec_response.status_code) raise common.UserException(error_detail) # globals.logger.debug("-------------------------") # globals.logger.debug("response:") # globals.logger.debug(exec_response.text) # globals.logger.debug("-------------------------") resp_data = json.loads(exec_response.text) if resp_data["status"] != "SUCCEED": globals.logger.error("no={} status:{}".format( ite_menu_conductor_exec, resp_data["status"])) error_detail = multi_lang.get_text( "EP034-0006", "実行結果取得の呼び出しに失敗しました ita-status:{0} resultdata:{1}".format( eresp_data["status"], eresp_data["resultdata"]), eresp_data["status"], eresp_data["resultdata"]) raise common.UserException(error_detail) rows = resp_data # 正常終了 normal end ret_status = 200 # 戻り値をそのまま返却 return to it-automation results return jsonify({"result": ret_status, "rows": rows}), ret_status except common.UserException as e: return common.server_error(e) except Exception as e: return common.server_error(e)