diff --git a/lambda/mbj-newdwh2021-staging-lambda-sap-data-decrypt/Dockerfile b/lambda/mbj-newdwh2021-staging-lambda-sap-data-decrypt/Dockerfile new file mode 100644 index 00000000..329183b1 --- /dev/null +++ b/lambda/mbj-newdwh2021-staging-lambda-sap-data-decrypt/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.9 + +ENV TZ="Asia/Tokyo" + +WORKDIR /function +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt +COPY datadecrypt ./ + +ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ] +CMD [ "main.handler" ] \ No newline at end of file diff --git a/lambda/mbj-newdwh2021-staging-lambda-sap-data-decrypt/datadecrypt/main.py b/lambda/mbj-newdwh2021-staging-lambda-sap-data-decrypt/datadecrypt/main.py new file mode 100644 index 00000000..edee2396 --- /dev/null +++ b/lambda/mbj-newdwh2021-staging-lambda-sap-data-decrypt/datadecrypt/main.py @@ -0,0 +1,210 @@ +import os +import sys +import boto3 +import gnupg +import datetime + +# 環境変数 +SECRET_KEY_FILE_BUCKET_NAME = os.environ["SECRET_KEY_FILE_BUCKET_NAME"] +SECRET_KEY_FILE_PATH = os.environ["SECRET_KEY_FILE_PATH"] +SAP_SUP_BUCKET_NAME = os.environ["SAP_SUP_BUCKET_NAME"] +SAP_FIN_BUCKET_NAME = os.environ["SAP_FIN_BUCKET_NAME"] +SAP_DATA_BACKUP_BUCKET_NAME = os.environ["SAP_DATA_BACKUP_BUCKET_NAME"] +DATA_SOURCE_SAP_SUP = os.environ["DATA_SOURCE_SAP_SUP"] +DATA_SOURCE_SAP_FIN = os.environ["DATA_SOURCE_SAP_FIN"] +NDS_NOTICE_TOPIC = os.environ["NDS_NOTICE_TOPIC"] +NDS_NOTICE_TITLE = os.environ["NDS_NOTICE_TITLE"] + +# 定数 +DIRECTORY_RECV = '/recv/' +DIRECTORY_RECV_ERROR = '/recv_error/' +EXTENSION_ERROR = '.error' +EXTENSION_DECRYPT_ERROR = '.decrypt_error' + +# 変数 +s3_client = boto3.client('s3') +s3_resource = boto3.resource('s3') +sns_client = boto3.client('sns') +event_bucket_name = '' +event_file_path = '' +event_file_name = '' +event_data_source_name = '' + + +def handler(event, context): + # ① 処理開始ログを出力する + try: + info_log('I-01-01', '処理開始 SAPデータ復号処理') + today = datetime.date.today().strftime('%Y/%m/%d') + info_log('I-01-02', f'処理稼働日:{today}') + except Exception as e: + error_log('E-99', f'想定外のエラーが発生しました エラー内容:{e}') + error_process(EXTENSION_ERROR, 'E-99', e) + + # ② 処理開始時に受け取ったイベント情報の以下内容をログに出力しメモリに保持する + try: + info_log('I-02-01', 'SAPデータ復号処理開始') + + s3_event = event["Records"][0]["s3"] + event_bucket_name = s3_event["bucket"]["name"] + event_file_path = s3_event["object"]["key"] + event_file_name = os.path.basename(event_file_path) + event_data_source_name = os.path.dirname(event_file_path).split('/')[0] + info_log('I-02-02', f'バケット名:{event_bucket_name}') + info_log('I-02-03', f'ファイルパス:{event_file_path}') + info_log('I-02-04', f'データソース名:{event_data_source_name}') + except Exception as e: + error_log('E-02-99', f'エラー内容:{e}') + error_process(EXTENSION_ERROR, 'E-02-99', e) + + # ③ S3からPGP暗号化ファイルを読み込む + try: + info_log('I-03-01', f'秘密鍵ファイル読込 読込元:{SECRET_KEY_FILE_BUCKET_NAME}/{SECRET_KEY_FILE_PATH}') + s3_client.download_file(SECRET_KEY_FILE_BUCKET_NAME, SECRET_KEY_FILE_PATH, '/tmp/private.key') + info_log('I-03-02', '秘密鍵ファイルを読み込みました') + except Exception as e: + error_log('E-03-01', '秘密鍵ファイルの読み込みに失敗しました') + error_process(EXTENSION_ERROR, 'I-03-01', e) + + # ④ S3からPGP暗号化ファイルを読み込む + try: + info_log('I-04-01', f'PGP暗号化ファイル読込 読込元:{event_bucket_name}/{event_file_path}') + s3_client.download_file(event_bucket_name, event_file_path, '/tmp/myencryptedfile') + info_log('I-04-02', 'PGP暗号化ファイルを読み込みました') + except Exception as e: + try: + error_log('E-04-01', '秘密鍵ファイルの読み込みに失敗しました') + + result_error_file_name = event_file_name + EXTENSION_ERROR + result_error_key = event_data_source_name + DIRECTORY_RECV + result_error_file_name + result_error_obj = s3_resource.Object(event_bucket_name, result_error_key) + result_error_obj.put(Body='') + error_log('E-04-02', f'recvディレクトリにエラーファイルを作成しました ファイル名:{result_error_file_name} 出力先:{event_bucket_name}/{result_error_key}') + + error_log('E-04-03', f'保守要員に通知します 通知先トピック:{NDS_NOTICE_TOPIC}') + error_msg = f'E-04-01 のエラーが発生しました。ご確認ください\n詳細:{e}' + params = { + 'TopicArn': NDS_NOTICE_TOPIC, + 'Subject': NDS_NOTICE_TITLE, + 'Message': error_msg + } + sns_client.publish(**params) + + error_log('E-04-04', 'エラー終了 処理を中断します') + sys.exit() + except Exception as e: + error_log('E-04-99', f'エラー内容:{e}') + error_process(EXTENSION_ERROR, 'E-04-99', e) + + # ⑤ 「③」で読み込んだ秘密鍵ファイルをPGPライブラリにインポートを行う + try: + info_log('I-05-01', '秘密鍵ファイルインポート') + gpg = gnupg.GPG(gnupghome='/tmp') + key_data = open('/tmp/private.key').read() + priv_key = gpg.import_keys(key_data) + info_log('I-05-02', '秘密鍵ファイルをインポートしました') + except Exception as e: + error_log('E-05-01', '秘密鍵ファイルのインポートに失敗しました') + error_process(EXTENSION_ERROR, 'E-05-01', e) + + # ⑥ 「④」で読み込んだPGP暗号化ファイルを「⑤」でインポートした秘密鍵ファイルで復号する + try: + info_log('I-06-01', 'PGP暗号化ファイルの復号化') + target_file = open('/tmp/myencryptedfile', 'rb') + gpg.decrypt_file(target_file, output='/tmp/decrypt_file') + decrypt_file = open('/tmp/decrypt_file', 'rb') + info_log('I-06-02', 'PGP暗号化ファイルを復号しました') + except Exception as e: + error_log('E-06-01', 'PGP暗号化ファイルの復号化に失敗しました') + error_process(EXTENSION_DECRYPT_ERROR, 'E-06-01', e) + + # ⑦ 各ファイルをS3に出力する + try: + info_log('I-07-01', '各ファイルをS3に出力する') + + # 「⑥」で復号化したファイルをSAPデータ保管用バケットに出力する + decrypt_file_name = event_file_name[:-4] + decrypt_file_key = f'{today}/{decrypt_file_name}' + if event_data_source_name == DATA_SOURCE_SAP_SUP: + decrypt_bucket_name = SAP_SUP_BUCKET_NAME + elif event_data_source_name == DATA_SOURCE_SAP_FIN: + decrypt_bucket_name = SAP_FIN_BUCKET_NAME + info_log('I-07-02', f'復号化ファイル出力 ファイル名:{decrypt_file_name} 出力先:{decrypt_bucket_name}/{decrypt_file_key}') + decrypt_file_obj = s3_resource.Object(decrypt_bucket_name, decrypt_file_key) + decrypt_file_obj.put(Body=decrypt_file) + info_log('I-07-03', '復号化ファイルをS3に出力しました') + except Exception as e: + error_log('E-07-01', '復号化ファイルのS3出力に失敗しました') + error_process(EXTENSION_ERROR, 'E-07-01', e) + + try: + # 「④」で読み込んだPGP暗号化ファイルを以下に移動(コピー削除)する + backup_file_key = f'{event_data_source_name}/{today}/{event_file_name}' + info_log('I-07-04', f'PGP暗号化ファイル出力 ファイル名:{event_file_name} 出力先:{SAP_DATA_BACKUP_BUCKET_NAME}/{backup_file_key}') + decrypt_file_obj = s3_resource.Object(SAP_DATA_BACKUP_BUCKET_NAME, backup_file_key) + decrypt_file_obj.put(Body=decrypt_file) + info_log('I-07-05', 'PGP暗号化ファイル出力をS3に出力しました') + except Exception as e: + error_log('E-07-02', 'PGP暗号化ファイルのS3出力に失敗しました') + error_process(EXTENSION_ERROR, 'E-07-02', e) + + # ⑧ 処理終了ログを出力する + try: + info_log('I-08-01', '処理終了 SAPデータ復号処理') + except Exception as e: + error_log('E-99', f'想定外のエラーが発生しました エラー内容:{e}') + error_process(EXTENSION_ERROR, 'E-99', e) + + +def info_log(log_id, msg): + try: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Info {log_id} {msg}') + except Exception as e: + error_log('E-99', f'想定外のエラーが発生しました エラー内容:{e}') + error_process('E-99', e) + + +def error_log(log_id, msg): + try: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error {log_id} {msg}') + except Exception as e: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-99 想定外のエラーが発生しました エラー内容:{e}') + error_process('E-99', e) + + +def error_process(extension, error_log_id, exception): + # ① エラー処理を行う + try: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-ERR-01 エラー処理開始') + + result_error_file_name = event_file_name + extension + result_error_key = event_data_source_name + DIRECTORY_RECV + result_error_file_name + result_error_obj = s3_resource.Object(event_bucket_name, result_error_key) + result_error_obj.put(Body='') + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-ERR-02 recvディレクトリにエラーファイルを作成しました ファイル名:{result_error_file_name} 出力先:{event_bucket_name}/{result_error_key}') + + copy_source = { + 'Bucket': event_bucket_name, + 'Key': event_file_path + } + error_file_name = f'{datetime.now():%Y%m%d%H%M%S}_{event_file_name}' + error_key = event_data_source_name + DIRECTORY_RECV_ERROR + error_file_name + error_obj = s3_resource.Object(event_bucket_name, error_key) + error_obj.copy(copy_source) + s3_client.delete_object(Bucket=event_bucket_name, Key=event_file_path) + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-ERR-03 recv_errorディレクトリにファイルを移動しました 移動元:{event_bucket_name}/{event_file_path} 移動先:{event_bucket_name}/{error_key}') + + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-ERR-04 処理異常通知の送信指示をしました 通知先トピック:{NDS_NOTICE_TOPIC}') + error_msg = f'{error_log_id} のエラーが発生しました。ご確認ください\n詳細:{exception}' + params = { + 'TopicArn': NDS_NOTICE_TOPIC, + 'Subject': NDS_NOTICE_TITLE, + 'Message': error_msg + } + sns_client.publish(**params) + + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-ERR-05 エラー終了 処理を中断します') + sys.exit() + except Exception as e: + print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Error E-99 想定外のエラーが発生しました エラー内容:{e}') + sys.exit() diff --git a/lambda/mbj-newdwh2021-staging-lambda-sap-data-decrypt/requirements.txt b/lambda/mbj-newdwh2021-staging-lambda-sap-data-decrypt/requirements.txt new file mode 100644 index 00000000..ae60d971 --- /dev/null +++ b/lambda/mbj-newdwh2021-staging-lambda-sap-data-decrypt/requirements.txt @@ -0,0 +1,3 @@ +awslambdaric +boto3 +python-gnupg \ No newline at end of file