def get_trail_event_selectors(trace_id, check_history_id, organization_id, project_id, awsaccount, region_name, trail_client, cloud_trail): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, awsaccount, "CloudTrail_EventSelectors_" + region_name + "_" + cloud_trail["Name"] + ".json") event_selectors = [] # Check Exist File リソース情報ファイル if (aws_common.check_exists_file_s3(trace_id, "S3_CHECK_BUCKET", s3_file_name)) is True: try: event_selectors = FileUtils.read_json(trace_id, "S3_CHECK_BUCKET", s3_file_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) else: event_selectors = CloudTrailUtils.get_event_selectors( trace_id, awsaccount, trail_client, region_name, cloud_trail["TrailARN"]) # Upload File リソース情報ファイル try: FileUtils.upload_s3(trace_id, event_selectors, s3_file_name, True) except PmError as e: pm_logger.error("[%s/%s] CloudTrailのイベントセレクタ情報のS3保存に失敗しました。", awsaccount, region_name) raise common_utils.write_log_pm_error(e, pm_logger) return event_selectors
def execute_confirm_awscoop(task_id): pm_logger = common_utils.begin_logger(task_id, __name__, inspect.currentframe()) coop_id = organizationTask_logic.check_process_status(task_id) if coop_id is None: pm_logger.error("組織タスク情報取得に失敗しました。: TaskID=%s", task_id) raise PmError() try: awscoop = pm_awsAccountCoops.query_awscoop_coop_key(task_id, coop_id) except PmError as e: pm_logger.error("AWSアカウント連携情報取得に失敗しました。: CoopID=%s", coop_id) raise common_utils.write_log_pm_error(e, pm_logger, exc_info=True) if (not awscoop): pm_logger.warning("AWSアカウント連携情報がありません。: CoopID=%s", coop_id) raise PmError() try: aws_common.create_session_client(task_id, awscoop['AWSAccount'], awscoop['RoleName'], awscoop['ExternalID']) pm_logger.info("クレデンシャルが正常に取得されました。: CoopID=%s", coop_id) except PmError as err: pm_logger.error("クレデンシャル取得に失敗しました。: CoopID=%s", coop_id) try: attribute = {'Effective': {"Value": Effective.Disable.value}} pm_awsAccountCoops.update_awscoops(task_id, coop_id, attribute) except PmError as e: pm_logger.error("AWSアカウント連携情報の更新に失敗しました。: CoopID=%s", coop_id) raise common_utils.write_log_pm_error(err, pm_logger, exc_info=True)
def get_bucket_acl(trace_id, check_history_id, organization_id, project_id, aws_account, region_name, bucket_name, s3_client): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, aws_account, "ASC/S3_ACL_" + region_name + "_" + bucket_name + ".json") # リソース情報取得 if (aws_common.check_exists_file_s3(trace_id, "S3_CHECK_BUCKET", s3_file_name)) is True: try: bucket_acl = FileUtils.read_json(trace_id, "S3_CHECK_BUCKET", s3_file_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) else: try: bucket_acl = S3Utils.get_bucket_acl( trace_id, s3_client, bucket_name, aws_account, region_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) # 取得したS3バケットのアクセスコントロールリスト情報をS3に保存する。(アクセスコントロールリスト情報) try: FileUtils.upload_json(trace_id, "S3_CHECK_BUCKET", bucket_acl, s3_file_name) except PmError as e: pm_logger.error("[%s] S3バケットACL情報のS3保存に失敗しました。(%s)/(%s)", aws_account, region_name, bucket_name) return bucket_acl
def get_account_password_policy(trace_id, check_history_id, organization_id, project_id, awsaccount, session, result_json_path): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, awsaccount, "IBP/IAM_AccountPasswordPolicy.json") # リソース情報取得 if (aws_common.check_exists_file_s3(trace_id, "S3_CHECK_BUCKET", s3_file_name)) is True: try: account_password_policy = FileUtils.read_json( trace_id, "S3_CHECK_BUCKET", s3_file_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) else: try: account_password_policy = IAMUtils.get_account_password_policy( trace_id, session, awsaccount) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) # アカウントパスワードポリシー情報をS3に保存します。 try: FileUtils.upload_json(trace_id, "S3_CHECK_BUCKET", account_password_policy, s3_file_name) except PmError as e: pm_logger.error("[%s] アカウントパスワードポリシー情報のS3保存に失敗しました。", awsaccount) raise common_utils.write_log_pm_error(e, pm_logger) return account_password_policy
def delete_user(trace_id, organization_id, user_id, email): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) # check the deletion condition if user_id == trace_id: try: count = pm_affiliation.query_users_check_authority_count( trace_id, user_id, organization_id, Authority.Owner) except PmError as e: return common_utils.error_exception( MsgConst.ERR_402, HTTPStatus.INTERNAL_SERVER_ERROR, e, pm_logger, True) if count == 0: return common_utils.error_common(MsgConst.ERR_REQUEST_203, HTTPStatus.PRECONDITION_FAILED, pm_logger) # get user to delete try: user = pm_affiliation.query(user_id, organization_id) except PmError as e: return common_utils.error_exception(MsgConst.ERR_402, HTTPStatus.INTERNAL_SERVER_ERROR, e, pm_logger, True) if not user: return common_utils.error_common(MsgConst.ERR_301, HTTPStatus.NOT_FOUND, pm_logger) # delete user try: pm_affiliation.delete_affiliation(user_id, organization_id) except PmError as e: return common_utils.error_exception(MsgConst.ERR_DB_405, HTTPStatus.INTERNAL_SERVER_ERROR, e, pm_logger, True) # set task informaiton request delete in Organization Tasks task_id = str(uuid.uuid4()) target = CommonConst.TARGET_DELETE_ORG_USER.format(user_id, organization_id) try: # create task informaiton request delete in Organization Tasks pm_organizationTasks.create_organizationTask( trace_id, task_id, CommonConst.TASK_TYPE_CODE_DELETE_ORG_USER, target, trace_id, email, Status.Waiting.value, 0, 3) except PmError as e: return common_utils.error_exception(MsgConst.ERR_DB_403, HTTPStatus.INTERNAL_SERVER_ERROR, e, pm_logger, True) try: # Send message to organization topic task aws_common.sns_organization_topic( trace_id, task_id, CommonConst.TASK_TYPE_CODE_DELETE_ORG_USER) except PmError as e: common_utils.write_log_pm_error(e, pm_logger, exc_info=True) response = common_utils.get_response_by_response_body( HTTPStatus.NO_CONTENT, None) return common_utils.response(response, pm_logger)
def main(argv): # コマンドラインパラメータ try: check_history_id = argv[1] log_id = CommonConst.BLANK language = CommonConst.LANGUAGE_DEFAULT if(len(argv) > 2): log_id = argv[2] if(len(argv) > 3 and argv[3] in CommonConst.LANGUAGE_SUPPORT): language = argv[3] except Exception as e: pm_logger = common_utils.begin_logger(None, __name__, inspect.currentframe()) common_utils.write_log_exception(e, pm_logger, True) sys.exit(CommonConst.EXIT_CODE_ERROR) # バッチ処理開始 pm_logger = common_utils.begin_logger(check_history_id, __name__, inspect.currentframe()) error_code = None pm_logger.info("** バッチアプリケーション起動 ***************") pm_logger.info("== バッチアプリケーション処理開始 ================") pm_logger.info("チェック履歴ID: " + check_history_id) pm_logger.info("ログID: " + log_id) pm_logger.info("==================================================") try: awsResourceAggregate_logic.aws_resource_aggregate( check_history_id, log_id) except PmError as e: common_utils.write_log_pm_error(e, pm_logger, exc_info=True) error_code = e.message except Exception as e: common_utils.write_log_exception(e, pm_logger, True) error_code = 'CKEX_SECURITY-999' # チェック処理結果を記録 exit_code = CommonConst.EXIT_CODE_SUCCESS try: check_status = CheckStatus.CheckCompleted if (error_code is None): check_status = CheckStatus.SummaryCompleted awsResourceChecker_logic.processing_finish(check_history_id, error_code, check_status) if (error_code is not None): exit_code = CommonConst.EXIT_CODE_ERROR # チェック結果通知処理 awsResourceAggregate_logic.check_result_notification( check_history_id, language) except PmError as e: common_utils.write_log_pm_error(e, pm_logger, exc_info=True) exit_code = CommonConst.EXIT_CODE_ERROR except Exception as e: common_utils.write_log_exception(e, pm_logger, True) exit_code = CommonConst.EXIT_CODE_ERROR pm_logger.info("-- 最新チェック結果作成終了 ----") sys.exit(exit_code)
def execute_send_result_email(trace_id, check_history_id, aws_request_id, language): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) try: send_result_email(trace_id, check_history_id, language) except PmError as e: common_utils.write_log_pm_error(e, pm_logger, exc_info=True) publish_error_message(trace_id, check_history_id, aws_request_id, e.message)
def execute_security_check_with_executed_type(trace_id, organization_id, project_id, user_id, email, executed_type): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) # リソース関連性のバリデーションチェックを行います。 try: project = pm_projects.get_projects_by_organization_id( trace_id, project_id, organization_id) except PmError as e: return common_utils.error_exception(MsgConst.ERR_402, HTTPStatus.INTERNAL_SERVER_ERROR, e, pm_logger, True) if not project: return common_utils.error_common( MsgConst.ERR_AWS_401, HTTPStatus.UNPROCESSABLE_ENTITY, pm_logger) try: check_history_id = common_utils.get_uuid4() executed_date_time = common_utils.get_current_date() pm_checkHistory.create(trace_id, check_history_id, organization_id, project_id, CHECK_SECURITY, CheckStatus.Waiting, None, executed_type, None, executed_date_time, None, user_id) except PmError as e: return common_utils.error_exception(MsgConst.ERR_DB_403, HTTPStatus.INTERNAL_SERVER_ERROR, e, pm_logger, True) try: topic_arn = common_utils.get_environ( CommonConst.SECURITYCHECK_EXECUTE_TOPIC) subject = "USER : {0}".format(user_id) message = { 'CheckHistoryId': check_history_id } # Publish message aws_common.aws_sns(trace_id, subject, json.dumps(message), topic_arn) except PmError as e: common_utils.write_log_pm_error(e, pm_logger, exc_info=True) try: check_history = pm_checkHistory.query_key(trace_id, check_history_id, True) except PmError as e: return common_utils.error_exception(MsgConst.ERR_402, HTTPStatus.INTERNAL_SERVER_ERROR, e, pm_logger, True) # return data response response = common_utils.get_response_by_response_body( HTTPStatus.CREATED, check_history) return common_utils.response(response, pm_logger)
def execute_delete_organization_user(task_id): pm_logger = common_utils.begin_logger(task_id, __name__, inspect.currentframe()) # タスク情報を取得します。 # タスク情報のステータスチェックを行います。 target = organizationTask_logic.check_process_status(task_id) if target is None: pm_logger.error("組織タスク情報取得に失敗しました。: TaskID=%s", task_id) raise PmError() # タスク情報から処理対象(ユーザーID,組織ID)を取得します。 target = target.split(CommonConst.COMMA) user_id = target[0] organization_id = target[1] # 削除処理 # 組織別通知メール宛先テーブル(PM_OrgNotifyMailDestinations)に組織ID{organization_id}をキーとしてクエリを実行し、対象情報を取得する。 try: org_notify_mail_destinations = pm_orgNotifyMailDestinations.query_key( task_id, organization_id, CommonConst.NOTIFY_CODE) except PmError as e: pm_logger.error("組織別通知メール宛先情報取得に失敗しました。: OrganizationID=%s", organization_id) raise common_utils.write_log_pm_error(e, pm_logger) # キーに合致するレコードが存在しなかった場合 if (not org_notify_mail_destinations): # 処理を正常終了する。 return # 取得したレコードのDestinationsのListデータを編集する。 destinations = jmespath.search( "[?UserID != '{0}']".format(user_id), org_notify_mail_destinations['Destinations']) # 編集後のDestinationsは、組織別通知メール宛先テーブル(PM_OrgNotifyMailDestinations)へ組織ID{organization_id}をキーとしてupdate_itemで更新する。(UpdatedAtも現在日時で更新する) try: if (len(destinations) == 0): # 編集後のDestinationsのListデータが0件になる場合、組織別通知メール宛先テーブル(PM_OrgNotifyMailDestinations)の該当レコードを削除する。 pm_orgNotifyMailDestinations.delete(task_id, organization_id, CommonConst.NOTIFY_CODE) else: attribute = {'Destinations': {"Value": destinations}} pm_orgNotifyMailDestinations.update(task_id, organization_id, CommonConst.NOTIFY_CODE, attribute) except PmError as e: pm_logger.error("組織別通知メール宛先情報の更新に失敗しました。: OrganizationID=%s", organization_id) raise common_utils.write_log_pm_error(e, pm_logger)
def main(argv): # コマンドラインパラメータ try: check_history_id = argv[1] log_id = CommonConst.BLANK if (len(argv) > 2): log_id = argv[2] except Exception as e: pm_logger = common_utils.begin_logger(None, __name__, inspect.currentframe()) common_utils.write_log_exception(e, pm_logger, True) sys.exit(CommonConst.EXIT_CODE_ERROR) # バッチ処理開始 pm_logger = common_utils.begin_logger(check_history_id, __name__, inspect.currentframe()) error_code = None pm_logger.info("** バッチアプリケーション起動 ***************") pm_logger.info("== バッチアプリケーション処理開始 ================") pm_logger.info("チェック履歴ID: " + check_history_id) pm_logger.info("ログID: " + log_id) pm_logger.info("==================================================") try: awsResourceChecker_logic.aws_resource_checker(check_history_id, log_id) except PmError as e: error_code = e.message if error_code != "CKEX_SECURITY-900": common_utils.write_log_pm_error(e, pm_logger, exc_info=True) except Exception as e: common_utils.write_log_exception(e, pm_logger, True) error_code = 'CKEX_SECURITY-999' # チェック処理結果を記録 exit_code = CommonConst.EXIT_CODE_SUCCESS try: check_status = CheckStatus.Waiting if (error_code is None): check_status = CheckStatus.CheckCompleted awsResourceChecker_logic.processing_finish(check_history_id, error_code, check_status) if (error_code is not None): exit_code = CommonConst.EXIT_CODE_ERROR except PmError as e: common_utils.write_log_pm_error(e, pm_logger, exc_info=True) exit_code = CommonConst.EXIT_CODE_ERROR except Exception as e: common_utils.write_log_exception(e, pm_logger, True) exit_code = CommonConst.EXIT_CODE_ERROR pm_logger.info("** バッチアプリケーション終了 ***************") sys.exit(exit_code)
def update_check_results(trace_id, check_history_id, check_result_id, ok_count, critical_count, ng_count, managed_count, error_count): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) attribute = { 'OKCount': { "Value": ok_count }, 'CriticalCount': { "Value": critical_count }, 'NGCount': { "Value": ng_count }, 'ManagedCount': { "Value": managed_count }, 'ErrorCount': { "Value": error_count } } try: pm_checkResults.update(trace_id, check_result_id, attribute) except PmError as e: pm_logger.error( "チェック結果の集計値の更新に失敗しました。: CheckHistoryID=%s, CheckResultID=%s", check_history_id, check_result_id) raise common_utils.write_log_pm_error(e, pm_logger, "AGG_SECURITY-006")
def list_subscriptions_by_topic(trace_id, check_history_id, organization_id, project_id, awsaccount, region_name, sns_client, topic_arn): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) topic_name = topic_arn.split(":")[5] s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, awsaccount, "SNS_Topic_Subscriptions_Info_" + region_name + "_" + topic_name + ".json") subscriptions = [] # リソース情報取得 if (aws_common.check_exists_file_s3(trace_id, "S3_CHECK_BUCKET", s3_file_name)) is True: try: subscriptions = FileUtils.read_json(trace_id, "S3_CHECK_BUCKET", s3_file_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) else: # 対象のAWSアカウントのリージョンごと(GovCloud、北京を除く)にCloudTrail情報を取得する。 try: subscriptions = SNSUtils.list_subscriptions_by_topic( trace_id, sns_client, awsaccount, region_name, topic_arn) except PmError as e: data_body = {'TopicArn': topic_arn} e.pm_notification_error = PmNotificationError( code_error=CommonConst.KEY_CODE_ERROR_GET_SUBSCRIPTIONS, data_body=data_body) raise common_utils.write_log_pm_error(e, pm_logger) # 取得したSNS Topicサブスクリプション情報情報をS3に保存する(リソース情報ファイル) try: FileUtils.upload_json(trace_id, "S3_CHECK_BUCKET", subscriptions, s3_file_name) except PmError as e: pm_logger.error("[%s/%s] SNS Topicサブスクリプション情報の情報のS3保存に失敗しました。", awsaccount, region_name) raise common_utils.write_log_pm_error(e, pm_logger) # 情報の取得件数が0でした。 if (len(subscriptions) == 0): pm_logger.warning("[%s/%s] SNS Topicサブスクリプション情報情報の取得件数が0でした。", awsaccount, region_name) return subscriptions
def execute_send_checkerror_email(trace_id, aws_request_id, aws_account, check_history_id, organization_id, project_id, error_code, execute_user_id, region_name, check_code_item, data_body): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) try: send_checkerror_email(trace_id, aws_account, check_history_id, organization_id, project_id, error_code, execute_user_id, region_name, check_code_item, data_body) except PmError as e: common_utils.write_log_pm_error(e, pm_logger, exc_info=True) publish_error_message_send_checkerror_email(trace_id, check_history_id, organization_id, project_id, aws_request_id, e.message)
def describe_metric_filters(trace_id, check_history_id, organization_id, project_id, awsaccount, region_name, logs_client, cloud_trail_log_group_name): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, awsaccount, "CloudWatch_Logs_Metric_Filters_Info_" + region_name + "_" + cloud_trail_log_group_name.replace( CommonConst.SLASH, "-SLASH-") + ".json") metric_filters = [] # リソース情報取得 if (aws_common.check_exists_file_s3(trace_id, "S3_CHECK_BUCKET", s3_file_name)) is True: try: metric_filters = FileUtils.read_json(trace_id, "S3_CHECK_BUCKET", s3_file_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) else: try: metric_filters = LogsUtils.describe_metric_filters( trace_id, logs_client, awsaccount, region_name, cloud_trail_log_group_name) except PmError as e: data_body = {'CloudTrailLogGroupName': cloud_trail_log_group_name} e.pm_notification_error = PmNotificationError( code_error=CommonConst.KEY_CODE_ERROR_GET_METRIC_FILTERS, data_body=data_body) raise common_utils.write_log_pm_error(e, pm_logger) try: FileUtils.upload_json(trace_id, "S3_CHECK_BUCKET", metric_filters, s3_file_name) except PmError as e: pm_logger.error("[%s/%s] メトリクスフィルタ情報のS3保存に失敗しました。", awsaccount, region_name) raise common_utils.write_log_pm_error(e, pm_logger) # 情報の取得件数が0でした。 if (len(metric_filters) == 0): pm_logger.warning("[%s/%s] メトリクスフィルタ情報の取得件数が0でした。", awsaccount, region_name) return metric_filters
def get_cloud_trails(trace_id, check_history_id, organization_id, project_id, awsaccount, region_name, session): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, awsaccount, "CloudTrail_" + region_name + ".json") cloud_trails = [] # Check Exist File S3 CloudTrail_{region_name}.json if (aws_common.check_exists_file_s3(trace_id, "S3_CHECK_BUCKET", s3_file_name)) is True: try: cloud_trails = FileUtils.read_json(trace_id, "S3_CHECK_BUCKET", s3_file_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) else: # 対象のAWSアカウントのリージョンごと(GovCloud、北京を除く)にCloudTrail情報を取得する。 trail_client = CloudTrailUtils.get_trail_client( trace_id, session, region_name, awsaccount) try: cloud_trails = CloudTrailUtils.describe_cloud_trails( trace_id, awsaccount, trail_client, region_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) if (len(cloud_trails) == 0): pm_logger.warning("[%s/%s] CloudTrail情報の取得件数が0でした。", awsaccount, region_name) # 取得したCloudTrail情報をS3に保存する(リソース情報ファイル) try: FileUtils.upload_json(trace_id, "S3_CHECK_BUCKET", cloud_trails, s3_file_name) except PmError as e: pm_logger.error("[%s/%s] CloudTrailの情報のS3保存に失敗しました。", awsaccount, region_name) raise common_utils.write_log_pm_error(e, pm_logger) return cloud_trails
def describe_alarms(trace_id, check_history_id, organization_id, project_id, awsaccount, region_name, cloudwatch_client): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, awsaccount, "CloudWatch_Alarm_Info_" + region_name + ".json") metric_alarms = [] # リソース情報取得 if (aws_common.check_exists_file_s3(trace_id, "S3_CHECK_BUCKET", s3_file_name)) is True: try: metric_alarms = FileUtils.read_json(trace_id, "S3_CHECK_BUCKET", s3_file_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) else: try: metric_alarms = CloudWatchlUtils.describe_alarms( trace_id, awsaccount, cloudwatch_client, region_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) # 取得したCloudWatchAlarm情報をS3に保存する(リソース情報ファイル) try: FileUtils.upload_json(trace_id, "S3_CHECK_BUCKET", metric_alarms, s3_file_name) except PmError as e: pm_logger.error("[%s/%s] CloudWatchAlarmの情報のS3保存に失敗しました。", awsaccount, region_name) raise common_utils.write_log_pm_error(e, pm_logger) # 情報の取得件数が0でした。 if (len(metric_alarms) == 0): pm_logger.warning("[%s/%s] CloudWatchAlarm情報の取得件数が0でした。", awsaccount, region_name) return metric_alarms
def get_trails_status(trace_id, awsaccount, trail_client, region_name, trail_arn): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) try: status = trail_client.get_trail_status(Name=trail_arn) except ClientError as e: pm_logger.error("[%s/%s] CloudTrailのステータス情報の取得に失敗しました。", awsaccount, region_name) data_body = {'TrailARN': trail_arn} pm_error = common_utils.write_log_exception(e, pm_logger) pm_error.pm_notification_error = PmNotificationError( code_error=CommonConst.KEY_CODE_ERROR_GET_TRAIL_STATUS, data_body=data_body) raise common_utils.write_log_pm_error(pm_error, pm_logger) return status
def get_event_selectors(trace_id, awsaccount, trail_client, region_name, trail_arn): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) event_selectors = [] try: result = trail_client.get_event_selectors(TrailName=trail_arn) except ClientError as e: pm_logger.error("[%s/%s] CloudTrailのイベントセレクタ情報の取得に失敗しました。", awsaccount, region_name) data_body = {'TrailARN': trail_arn} pm_error = common_utils.write_log_exception(e, pm_logger) pm_error.pm_notification_error = PmNotificationError( code_error=CommonConst.KEY_CODE_ERROR_GET_EVENT_SELECTORS, data_body=data_body) raise common_utils.write_log_pm_error(pm_error, pm_logger) if common_utils.check_key("EventSelectors", result): event_selectors = result["EventSelectors"] return event_selectors
def send_result_email(trace_id, check_history_id, language): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) # チェック結果テーブルのCheckHistoryIndexから、チェック履歴ID{CheckHistoryId}をキーとしてチェック結果一覧を取得します。 try: list_check_result = pm_checkResults.query_history_index( trace_id, check_history_id) except PmError as e: msg_err = "チェック結果の取得に失敗しました。" pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err) if (not list_check_result): msg_err = "チェック結果の取得に失敗しました。" pm_logger.error(msg_err) raise PmError(message=msg_err) # チェック結果一覧のうちの一つから、組織IDを取得します。 organization_id = list_check_result[0]['OrganizationID'] organization_name = list_check_result[0]['OrganizationName'] project_name = list_check_result[0]['ProjectName'] # 宛先ユーザーの確認をします。ユーザー所属テーブルのOrganizationIndexから、組織IDをキー try: users = pm_affiliation.query_users_organization_index( trace_id, organization_id, InvitationStatus.Belong) except PmError as e: msg_err = "ユーザー所属情報の取得に失敗しました。:OrganizationID={0}".format( organization_id) pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err) # 組織別通知メール宛先テーブルから、組織ID、通知コードCHECK_CISをキーとして宛先情報を取得します。 try: org_notify_mail_destinations = pm_orgNotifyMailDestinations.query_key( trace_id, organization_id, CommonConst.NOTIFY_CODE) except PmError as e: msg_err = "宛先情報の取得に失敗しました。:OrganizationID={0}, CheckCode={1}".format( organization_id, CommonConst.NOTIFY_CODE) pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err) if (not org_notify_mail_destinations): msg_err = "宛先情報の取得に失敗しました。:OrganizationID={0}, CheckCode={1}".format( organization_id, CommonConst.NOTIFY_CODE) pm_logger.error(msg_err) raise PmError(message=msg_err) destinations = [] for destination in org_notify_mail_destinations['Destinations']: for user in users: if destination['UserID'] == user['UserID']: destinations.append(destination) break try: if (len(destinations) == 0): pm_orgNotifyMailDestinations.delete(trace_id, organization_id, CommonConst.NOTIFY_CODE) else: attribute = {'Destinations': {"Value": destinations}} pm_orgNotifyMailDestinations.update(trace_id, organization_id, CommonConst.NOTIFY_CODE, attribute) except PmError as e: msg_err = "通知メール宛先ユーザーの更新に失敗しました。:OrganizationID={0}, CheckCode={1}".format( organization_id, CommonConst.NOTIFY_CODE) pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err) # S3から通知メール送信設定ファイルを取得します。 try: config = FileUtils.read_yaml(trace_id, CommonConst.S3_SETTING_BUCKET, CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL) except PmError as e: msg_err = "通知メール送信設定ファイルの取得に失敗しました。:s3://{0}/{1}".format( common_utils.get_environ(CommonConst.S3_SETTING_BUCKET), CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL) pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err) language_mail = CommonConst.LANGUAGE_DEFAULT if language in CommonConst.LANGUAGE_SUPPORT: language_mail = language path_file_template = config[CommonConst.KEY_GET_PATH_FILE_TEMPLATE_MAIL. format(language=language_mail)] mail_subject_config = config[CommonConst.KEY_MAIL_SUBJECT.format( language=language_mail)] # 通知メール本文を作成 try: template_body = FileUtils.read_decode(trace_id, CommonConst.S3_SETTING_BUCKET, path_file_template) except PmError as e: msg_err = "知メール本文テンプレートファイルの取得に失敗しました。:s3://{0}/{1}".format( common_utils.get_environ(CommonConst.S3_SETTING_BUCKET), path_file_template) pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err) # 通知メール件名を作成 subject_template = Template(mail_subject_config) mail_subject = subject_template.render(project_name=project_name) # メール本文 executed_date_time = date_utils.toString( date_utils.toDate(list_check_result[0]['ExecutedDateTime'], date_utils.UTC), date_utils.PATTERN_YYYYMMDDHHMM, date_utils.ASIA_TOKYO) executed_date_time_utc = date_utils.toString( date_utils.toDate(list_check_result[0]['ExecutedDateTime'], date_utils.UTC), date_utils.PATTERN_YYYYMMDDHHMM, date_utils.UTC) check_results = [] for check_result in list_check_result: account_aws = CommonConst.AWS_ACCOUNT_MAIL.format( check_result['AWSAccount'][:4], check_result['AWSAccount'][4:8]) check_result = { "accountAWS": account_aws, "okCount": check_result['OKCount'], "ngCount": check_result['NGCount'], "criticalCount": check_result['CriticalCount'], "managedCount": check_result['ManagedCount'], "errorCount": check_result['ErrorCount'] } check_results.append(check_result) template = Template(template_body) context = { 'organizationName': organization_name, 'projectName': project_name, 'executedDateTime': executed_date_time, 'executedDateTimeUTC': executed_date_time_utc, 'checkResults': check_results } body = template.render(context) # SESで通知メールを送信します。 list_bcc_addresses = [] bcc_addresses = [] for index, destination in enumerate(destinations): bcc_addresses.append(destination['MailAddress']) if (len(bcc_addresses) >= 50 or len(destinations) == index + 1): list_bcc_addresses.append(bcc_addresses) bcc_addresses = [] for index, bcc_addresses in enumerate(list_bcc_addresses): try: aws_common.send_email(trace_id, config['ses.region'], config['mail.from'], bcc_addresses, mail_subject, body) except PmError as e: msg_err = "通知メール送信に失敗しました。({0}/{1})".format( index + 1, len(list_bcc_addresses)) pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err)
def send_checkerror_email(trace_id, aws_account, check_history_id, organization_id, project_id, error_code, execute_user_id, region_name, check_code_item, data_body): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) # 組織情報を取得する。 try: organization = pm_organizations.get_organization( trace_id, organization_id) except PmError as e: msg_err = "組織情報の取得に失敗しました。OrganizationID={0}".format(organization_id) pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err) # プロジェクト情報を取得する。 try: project = pm_projects.query_key(trace_id, project_id) except PmError as e: msg_err = "プロジェクト情報の取得に失敗しました。ProjectID={0}".format(project_id) pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err) # チェック実行ユーザーのメールアドレスと言語を取得します。 try: user_info = aws_common.get_cognito_user_info_by_user_name( trace_id, execute_user_id) except PmError as e: msg_err = "Cognitoから情報取得に失敗しました。" pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err) language = jmespath.search("[?Name=='locale'].Value | [0]", user_info['UserAttributes']) mail_execute_user = jmespath.search("[?Name=='email'].Value | [0]", user_info['UserAttributes']) # S3から通知メール送信設定ファイルを取得します。 try: config = FileUtils.read_yaml(trace_id, CommonConst.S3_SETTING_BUCKET, CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL) except PmError as e: msg_err = "通知メール送信設定ファイルの取得に失敗しました。:s3://{0}/{1}".format( common_utils.get_environ(CommonConst.S3_SETTING_BUCKET), CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL) pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err) language_mail = CommonConst.LANGUAGE_ENGLISH if language in CommonConst.LANGUAGE_SUPPORT: language_mail = language path_file_template_check_error_notice_mail = config[ CommonConst.KEY_GET_PATH_FILE_TEMPLATE_CHECK_ERROR_NOTICE_MAIL.format( language=language_mail)] path_file_message_notice_error_execute_check_security = config[ CommonConst.KEY_GET_PATH_MESSAGE_NOTICE_ERROR_EXECUTE_CHECK_SECURITY. format(language=language_mail)] mail_subject_config = config[ CommonConst.KEY_CHECK_ERROR_NOTICE_MAIL_SUBJECT.format( language=language_mail)] # エラー通知内容設定ファイルを取得します。 try: messages_notice_error_execute_check_security = FileUtils.read_yaml( trace_id, CommonConst.S3_SETTING_BUCKET, path_file_message_notice_error_execute_check_security) except PmError as e: msg_err = "エラー通知内容設定ファイルの取得に失敗しました。:s3://{0}/{1}".format( common_utils.get_environ(CommonConst.S3_SETTING_BUCKET), path_file_message_notice_error_execute_check_security) pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err) # S3から通知メール本文テンプレートファイルを取得します。 try: template_body = FileUtils.read_decode( trace_id, CommonConst.S3_SETTING_BUCKET, path_file_template_check_error_notice_mail) except PmError as e: msg_err = "通知メール本文テンプレートファイルの取得に失敗しました。:s3://{0}/{1}".format( common_utils.get_environ(CommonConst.S3_SETTING_BUCKET), path_file_template_check_error_notice_mail) pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err) # に該当する通知内容を取得します。 content_message = messages_notice_error_execute_check_security[ CommonConst.KEY_GET_MESSAGE_NOTICE_ERROR_EXECUTE_CHECK_SECURITY.format( errorCode=error_code)] if data_body is not None: content_message = content_message.format_map(data_body) # 通知メール件名を作成 subject_template = Template(mail_subject_config) project_name = project['ProjectName'] mail_subject = subject_template.render(project_name=project_name) if check_code_item is not None: check_code_item = CommonConst.LIST_CHECK_ITEM_CODE_CONVERT[ check_code_item] template = Template(template_body) context = { 'organizationName': organization['OrganizationName'], 'projectName': project_name, 'checkCodeItem': check_code_item, 'awsAccount': aws_account, 'regionName': region_name, 'contentMessage': content_message } body = template.render(context) # SESで通知メールを送信します bcc_addresses = [mail_execute_user] try: aws_common.send_email(trace_id, config['ses.region'], config['mail.from'], bcc_addresses, mail_subject, body) except PmError as e: msg_err = "通知メール送信に失敗しました。" pm_logger.error(msg_err) raise common_utils.write_log_pm_error(e, pm_logger, msg_err)
def aws_resource_aggregate(check_history_id, log_id): trace_id = check_history_id pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) # バリデーションチェック if common_utils.is_null(check_history_id): pm_logger.error("チェック履歴IDが指定されていません。") raise PmError(message="AGG_SECURITY-001") # ログストリーム名取得 if common_utils.is_null(log_id) is False: try: awsResourceChecker_logic.update_log_stream_name_to_s3( trace_id, check_history_id, log_id) except PmError as e: common_utils.write_log_pm_error(e, pm_logger, exc_info=True) # チェック履歴情報の取得とステータス更新 pm_logger.info("-- チェック履歴情報取得処理開始 ----") try: check_history = pm_checkHistory.query_key(trace_id, check_history_id) except PmError as e: pm_logger.error("チェック履歴情報の取得に失敗しました。: CheckHistoryID=%s", check_history_id) raise common_utils.write_log_pm_error(e, pm_logger, "AGG_SECURITY-002") if (not check_history): pm_logger.error("チェック履歴情報がありません。: CheckHistoryID=%s", check_history_id) pm_error = PmError(message="AGG_SECURITY-002") raise pm_error pm_logger.info("-- チェック履歴情報取得処理終了 ----") # 取得したチェック履歴情報のステータスをチェックします。 pm_logger.info("-- チェック履歴情報ステータスチェック開始 ----") if (check_history['CheckStatus'] != CheckStatus.CheckCompleted): pm_logger.error( "チェック実行ステータスが一致しません。: CheckHistoryID=%s, CheckStatus=%s", check_history_id, check_history['CheckStatus']) pm_error = PmError(message="AGG_SECURITY-003") raise pm_error # チェック履歴情報のステータスを更新します。 attribute = {'CheckStatus': {"Value": CheckStatus.SummaryProgress}} try: pm_checkHistory.update(trace_id, check_history_id, attribute, check_history['UpdatedAt']) pm_logger.info("-- チェック履歴情報ステータスチェック終了 ----") except PmError as e: pm_logger.error("チェック履歴情報のステータス更新に失敗しました。: CheckHistoryID=%s", check_history_id) raise common_utils.write_log_pm_error(e, pm_logger, "AGG_SECURITY-004") # 個別チェック結果取得 pm_logger.info("-- 個別チェック結果取得開始 ----") try: list_check_result_items = pm_checkResultItems.query_check_history_index_fiter_ne_exclusion_flag( trace_id, check_history_id, ExclusionFlag.Enable) except PmError as e: pm_logger.error("個別チェック結果取得に失敗しました。: CheckHistoryID=%s", check_history_id) raise common_utils.write_log_pm_error(e, pm_logger, "AGG_SECURITY-005") if (not list_check_result_items): pm_logger.error("個別チェック結果がありません。: CheckHistoryID=%s", check_history_id) raise PmError(message="AGG_SECURITY-005") pm_logger.info("-- 個別チェック結果取得終了 ----") # 個別チェック結果集計 / チェック結果更新 pm_logger.info("-- 個別チェック結果集計開始 ----") list_check_result_items = sorted(list_check_result_items, key=itemgetter('CheckResultID')) check_result_id = list_check_result_items[0]['CheckResultID'] ok_count = critical_count = ng_count = managed_count = error_count = 0 count = 0 for check_result_item in list_check_result_items: count += 1 check_result = check_result_item['CheckResult'] if (check_result_item['CheckResultID'] == check_result_id): if check_result == CheckResult.Normal: ok_count += 1 elif check_result == CheckResult.MinorInadequacies: ng_count += 1 elif check_result == CheckResult.CriticalDefect: critical_count += 1 elif check_result == CheckResult.MembersManagement: managed_count += 1 elif check_result == CheckResult.Error: error_count += 1 else: update_check_results(trace_id, check_history_id, check_result_id, ok_count, critical_count, ng_count, managed_count, error_count) check_result_id = check_result_item['CheckResultID'] ok_count = critical_count = ng_count = managed_count = error_count = 0 if check_result == CheckResult.Normal: ok_count += 1 elif check_result == CheckResult.MinorInadequacies: ng_count += 1 elif check_result == CheckResult.CriticalDefect: critical_count += 1 elif check_result == CheckResult.MembersManagement: managed_count += 1 elif check_result == CheckResult.Error: error_count += 1 # update data PM_CheckResults if (count == len(list_check_result_items)): update_check_results(trace_id, check_history_id, check_result_id, ok_count, critical_count, ng_count, managed_count, error_count) pm_logger.info("-- 個別チェック結果集計終了 ----") # 最新チェック結果作成 pm_logger.info("-- 最新チェック結果作成開始 ----") organization_id = check_history['OrganizationID'] project_id = check_history['ProjectID'] try: pm_latestCheckResult.create(trace_id, organization_id, project_id, check_history_id) except PmError as e: pm_logger.error("最新チェック結果テーブルのレコード作成に失敗しました。: CheckHistoryID=%s", check_history_id) raise common_utils.write_log_pm_error(e, pm_logger, "AGG_SECURITY-007")
def check_asc_item_12_01(trace_id, check_history_id, organization_id, project_id, aws_account, session, result_json_path): cw_logger = common_utils.begin_cw_logger(trace_id, __name__, inspect.currentframe()) check_results = [] is_authorized = True # 取得したクレデンシャル情報を使用して、S3クライアントを作成します。 try: s3_client = S3Utils.get_s3_client(trace_id, session, aws_account, is_cw_logger=True) except PmError as e: raise common_utils.write_log_pm_error(e, cw_logger) # S3バケット一覧を取得します。 try: list_buckets = S3Utils.list_buckets(trace_id, s3_client, aws_account, is_cw_logger=True) except PmError as e: return CheckResult.Error # S3バケット一覧情報をS3に保存します。 try: s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, aws_account, "ASC/S3_ListBuckets.json") FileUtils.upload_json(trace_id, "S3_CHECK_BUCKET", list_buckets, s3_file_name, is_cw_logger=True) except PmError as e: cw_logger.error("[%s] S3バケット一覧情報のS3保存に失敗しました。", aws_account) return CheckResult.Error for bucket in list_buckets["Buckets"]: bucket_name = bucket['Name'] region_name = None try: # 取得したS3バケット一覧情報ファイルをもとに、各バケットのリージョンを取得する。 region_name = S3Utils.get_bucket_location(trace_id, s3_client, bucket_name, aws_account, is_cw_logger=True) if region_name is None: region_name = CommonConst.US_EAST_REGION # 取得したS3バケット一覧情報ファイルをもとに、該当のS3バケットのアクセスコントロールリストを取得する。 bucket_acl = S3Utils.get_bucket_acl(trace_id, s3_client, bucket_name, aws_account, region_name) # 取得したS3バケット情報ファイルをもとに、該当のS3バケットのバケットポリシーを取得する。 bucket_policy = S3Utils.get_bucket_policy(trace_id, s3_client, bucket_name, aws_account, region_name, is_cw_logger=True) if bucket_policy is None: continue except PmError as e: if e.cause_error.response['Error'][ 'Code'] in CommonConst.S3_SKIP_EXCEPTION: error_operation = e.cause_error.operation_name, error_code = e.cause_error.response['Error']['Code'], error_message = e.cause_error.response['Error']['Message'] if region_name is None: region_name = CommonConst.ERROR check_results.append( asc_item_common_logic.get_error_authorized_result( region_name, bucket_name, error_operation, error_code, error_message)) is_authorized = False continue else: return CheckResult.Error # 取得したS3バケットのアクセスコントロールリスト情報をS3に保存する。(アクセスコントロールリスト情報) try: s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, aws_account, "ASC/S3_ACL_" + region_name + "_" + bucket_name + ".json") FileUtils.upload_json(trace_id, "S3_CHECK_BUCKET", bucket_acl, s3_file_name, is_cw_logger=True) except PmError as e: cw_logger.error("[%s] S3バケットACL情報のS3保存に失敗しました。(%s)/(%s)", aws_account, region_name, bucket_name) return CheckResult.Error # 取得したS3バケットのバケットポリシー情報をS3に保存する。(バケットポリシー情報) try: s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, aws_account, "ASC/S3_Bucketpolicy_" + region_name + "_" + bucket_name + ".json") FileUtils.upload_json(trace_id, "S3_CHECK_BUCKET", bucket_policy, s3_file_name, is_cw_logger=True) except PmError as e: cw_logger.error("[%s] S3バケットポリシー情報のS3保存に失敗しました。(%s/%s)", aws_account, region_name, bucket_name) return CheckResult.Error # チェック処理 bucket_acl_abnormity = False bucket_policy_abnormity = False try: # Check-1. ACLによりAllUsersに操作権限が与えられたS3バケットが存在するか # Check-2. ACLによりAuthenticatedUsersに操作権限が与えられたS3バケットが存在するか for grant in bucket_acl["Grants"]: if (common_utils.check_key("URI", grant['Grantee'])): if grant['Grantee']["URI"] in ACL_URI: bucket_acl_abnormity = True break # Check-3. バケットポリシーのプリンシパルにて全てのユーザに操作権限が与えられたS3バケットが存在するか bucket_policy = ast.literal_eval(bucket_policy['Policy']) for statement in bucket_policy["Statement"]: if (statement["Effect"] == CommonConst.ALLOW and statement["Principal"] == CommonConst.ALL): bucket_policy_abnormity = True break if bucket_acl_abnormity is True or bucket_policy_abnormity is True: check_results.append( get_check_accessible_result(region_name, bucket_acl_abnormity, bucket_policy_abnormity, bucket_name)) except Exception as e: cw_logger.error("[%s] チェック処理中にエラーが発生しました。(%s/%s)", aws_account, region_name, bucket_name) return CheckResult.Error # Export File CHECK_ASC_ITEM_12_01.json try: current_date = date_utils.get_current_date_by_format( date_utils.PATTERN_YYYYMMDDHHMMSS) check_bucket = { 'AWSAccount': aws_account, 'CheckResults': check_results, 'DateTime': current_date } FileUtils.upload_s3(trace_id, check_bucket, result_json_path, format_json=True, is_cw_logger=True) except Exception as e: cw_logger.error("[%s] チェック結果JSONファイルの保存に失敗しました。", aws_account) return CheckResult.Error # チェック結果 if is_authorized is False: return CheckResult.Error if len(check_results) > 0: return CheckResult.CriticalDefect return CheckResult.Normal
def check_asc_item_07_01(trace_id, check_history_id, organization_id, project_id, aws_account, session, result_json_path): cw_logger = common_utils.begin_cw_logger(trace_id, __name__, inspect.currentframe()) check_results = [] try: regions = aws_common.get_regions(trace_id, session, is_cw_logger=True) except PmError as e: cw_logger.error("Regionの情報の取得に失敗しました。") raise common_utils.write_log_pm_error(e, cw_logger) for region in regions: region_name = region["RegionName"] if region_name in REGION_IGNORE: continue ec2_client = Ec2Utils.get_ec2_client(trace_id, session, region_name, aws_account, is_cw_logger=True) try: # EBS情報を取得する。 ebs_volumes = Ec2Utils.describe_volumes(trace_id, aws_account, ec2_client, region_name, is_cw_logger=True) except PmError as e: return CheckResult.Error # 取得件数が0件の場合、ログを出力し、次のリージョンの処理に進みます。 if (len(ebs_volumes) == 0): cw_logger.info("[%s/%s] EBSボリューム情報の取得件数が0でした。", aws_account, region_name) continue try: # 取得したEBS情報をS3に保存する(EBS情報ファイル)。 s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, aws_account, "ASC/EBS_Volumes_" + region_name + ".json") FileUtils.upload_s3(trace_id, ebs_volumes, s3_file_name, True, is_cw_logger=True) except PmError as e: cw_logger.error("[%s/%s] EBSボリューム情報情報のS3保存に失敗しました。", aws_account, region_name) return CheckResult.Error # チェックルール try: for ebs_volume in ebs_volumes: if (ebs_volume['Encrypted'] is False): check_result = get_check_asc_item_07_01_result( ebs_volume, region_name) check_results.append(check_result) except PmError as e: cw_logger.error("[%s/%s] チェック処理中にエラーが発生しました。", aws_account, region_name) return CheckResult.Error # Export File ASC/CHECK_ ASC_ITEM_07_01.json try: current_date = date_utils.get_current_date_by_format( date_utils.PATTERN_YYYYMMDDHHMMSS) check_acs_item_7_01 = { 'AWSAccount': aws_account, 'CheckResults': check_results, 'DateTime': current_date } FileUtils.upload_s3(trace_id, check_acs_item_7_01, result_json_path, format_json=True, is_cw_logger=True) except Exception as e: cw_logger.error("[%s] チェック結果JSONファイルの保存に失敗しました。", aws_account) return CheckResult.Error # チェック結果 if len(check_results) > 0: return CheckResult.CriticalDefect return CheckResult.Normal
def execute_security_group_port(trace_id, check_history_id, organization_id, project_id, awsaccount, session, result_json_path, port, check_item_code, excluded_resources): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) check_results = [] # Export File VPC_SecurityGroups_{region}.json try: regions = aws_common.get_regions(trace_id, session) except PmError as e: pm_logger.error("Regionの情報の取得に失敗しました。") e.pm_notification_error = PmNotificationError( check_item_code=check_item_code, code_error=CommonConst.KEY_CODE_ERROR_DEFAULT) raise common_utils.write_log_pm_error(e, pm_logger) for region in regions: region_name = region["RegionName"] try: if region_name in REGION_IGNORE: continue ec2_client = Ec2Utils.get_ec2_client(trace_id, session, region_name, awsaccount) s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, awsaccount, "VPC_SecurityGroups_" + region_name + ".json") if (aws_common.check_exists_file_s3(trace_id, "S3_CHECK_BUCKET", s3_file_name)) is True: try: security_groups = FileUtils.read_json( trace_id, "S3_CHECK_BUCKET", s3_file_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) else: try: security_groups = Ec2Utils.describe_security_groups( trace_id, awsaccount, ec2_client, region_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) if (len(security_groups) == 0): pm_logger.info("[%s/%s] セキュリティグループ情報の取得件数が0でした。", awsaccount, region_name) continue try: FileUtils.upload_s3(trace_id, security_groups, s3_file_name, True) except PmError as e: pm_logger.error("[%s/%s] セキュリティグループ情報のS3保存に失敗しました。", awsaccount, region_name) raise common_utils.write_log_pm_error(e, pm_logger) try: for security_group in security_groups: # check excluded resources resource_name = security_group['GroupId'] if common_utils.check_excluded_resources( check_item_code, region_name, ResourceType.GroupId, resource_name, excluded_resources): continue for ip_permission in security_group['IpPermissions']: if ip_permission['IpProtocol'] != '-1': if ip_permission['IpProtocol'] != CommonConst.TCP: continue if common_utils.check_key( 'FromPort', ip_permission ) is False or ip_permission['FromPort'] > port: continue if common_utils.check_key( 'ToPort', ip_permission ) is False or ip_permission['ToPort'] < port: continue for ip_range in ip_permission['IpRanges']: if common_utils.check_key('CidrIp', ip_range): if (CommonConst.CIDR_IP_NOT_SECURITY == ip_range['CidrIp']): check_result = get_check_result( security_group, ip_permission, ip_range, region_name) check_results.append(check_result) break except Exception as e: pm_logger.error("[%s/%s] チェック処理中にエラーが発生しました。", awsaccount, region_name) raise common_utils.write_log_pm_error(e, pm_logger) except Exception as e: pm_error = common_utils.write_log_exception(e, pm_logger) pm_error.pm_notification_error = PmNotificationError( check_item_code=check_item_code, region=region_name, code_error=CommonConst.KEY_CODE_ERROR_DEFAULT) raise common_utils.write_log_pm_error(pm_error, pm_logger) result_security_group = CheckResult.Normal if (len(check_results) > 0): result_security_group = CheckResult.CriticalDefect # 検出結果を1つのチェック結果JSONファイルに保存する。 try: current_date = date_utils.get_current_date_by_format( date_utils.PATTERN_YYYYMMDDHHMMSS) check_rule_security_group = { 'AWSAccount': awsaccount, 'CheckResults': check_results, 'DateTime': current_date } FileUtils.upload_s3(trace_id, check_rule_security_group, result_json_path, True) except Exception as e: pm_logger.error("[%s] チェック結果JSONファイルの保存に失敗しました。", awsaccount) pm_error = common_utils.write_log_exception(e, pm_logger) pm_error.pm_notification_error = PmNotificationError( check_item_code=check_item_code, code_error=CommonConst.KEY_CODE_ERROR_DEFAULT) raise common_utils.write_log_pm_error(pm_error, pm_logger) return result_security_group
def check_cis_item_4_03(trace_id, check_history_id, organization_id, project_id, awsaccount, session, result_json_path, check_item_code, excluded_resources): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) check_results = [] try: regions = aws_common.get_regions(trace_id, session) except PmError as e: pm_logger.error("Regionの情報の取得に失敗しました。") e.pm_notification_error = PmNotificationError( check_item_code=check_item_code, code_error=CommonConst.KEY_CODE_ERROR_DEFAULT) raise common_utils.write_log_pm_error(e, pm_logger) for region in regions: region_name = region["RegionName"] try: if region_name in REGION_IGNORE: continue ec2_client = Ec2Utils.get_ec2_client(trace_id, session, region_name, awsaccount) # 対象のAWSアカウントのリージョンごと(GovCloud、北京を除く)にセキュリティグループ情報を取得する。 s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, awsaccount, "VPC_SecurityGroups_" + region_name + ".json") if (aws_common.check_exists_file_s3(trace_id, "S3_CHECK_BUCKET", s3_file_name)) is True: try: security_groups = FileUtils.read_json( trace_id, "S3_CHECK_BUCKET", s3_file_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) else: try: security_groups = Ec2Utils.describe_security_groups( trace_id, awsaccount, ec2_client, region_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) if (len(security_groups) == 0): pm_logger.info("[%s/%s] セキュリティグループ情報の取得件数が0でした。", awsaccount, region_name) try: if (len(security_groups) > 0): FileUtils.upload_s3(trace_id, security_groups, s3_file_name, True) except PmError as e: pm_logger.error("[%s/%s] セキュリティグループ情報のS3保存に失敗しました。", awsaccount, region_name) raise common_utils.write_log_pm_error(e, pm_logger) # 対象のAWSアカウントのリージョンごと(GovCloud、北京を除く)にEC2インスタンス情報を取得する。 s3_file_name_iam_instances = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, awsaccount, "IAM_Instances_" + region_name + ".json") if (aws_common.check_exists_file_s3( trace_id, "S3_CHECK_BUCKET", s3_file_name_iam_instances)) is True: try: reservation_instances = FileUtils.read_json( trace_id, "S3_CHECK_BUCKET", s3_file_name_iam_instances) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) else: try: reservation_instances = Ec2Utils.describe_instances( trace_id, awsaccount, ec2_client, region_name) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) if (len(reservation_instances) == 0): pm_logger.info("[%s/%s] EC2インスタンス情報の取得件数が0でした。", awsaccount, region_name) try: if (len(reservation_instances) > 0): s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, awsaccount, "VPC_SG_Instances_" + region_name + ".json") FileUtils.upload_s3(trace_id, reservation_instances, s3_file_name, True) except PmError as e: pm_logger.error("[%s/%s] EC2インスタンス情報のS3保存に失敗しました。", awsaccount, region_name) raise common_utils.write_log_pm_error(e, pm_logger) check1 = [] check2 = [] try: # リソース情報ファイルのセキュリティグループ情報から、インバウンドルール、アウトバウンドルールを設定しているdefaultセキュリティグループを検出する。 for security_group in security_groups: # check excluded resources resource_name = security_group['GroupId'] if common_utils.check_excluded_resources( check_item_code, region_name, ResourceType.GroupId, resource_name, excluded_resources): continue if (security_group['GroupName'] == CommonConst.DEFAULT and len(security_group['IpPermissions']) > 0 and len(security_group['IpPermissionsEgress']) > 0): check1.append(security_group['GroupId']) # リソース情報ファイルのEC2インスタンス情報から、defaultセキュリティグループをアタッチしたEC2インスタンスを検出する、。 for reservation_instance in reservation_instances: for instance in reservation_instance['Instances']: for security_group in instance['SecurityGroups']: if security_group[ 'GroupName'] == CommonConst.DEFAULT: if common_utils.check_key('Tags', instance) is True: name_tag = next( filter( lambda tag: tag['Key'] == 'Name', instance['Tags']), None) instance[ 'InstanceName'] = None if name_tag is None else name_tag[ 'Value'] check2.append(instance) if (len(check1) > 0 or len(check2) > 0): check_results.append( get_check_cis_item_4_03_result(check1, check2, region_name)) except Exception as e: pm_logger.error("[%s/%s] チェック処理中にエラーが発生しました。", awsaccount, region_name) raise common_utils.write_log_pm_error(e, pm_logger) except Exception as e: pm_error = common_utils.write_log_exception(e, pm_logger) pm_error.pm_notification_error = PmNotificationError( check_item_code=check_item_code, region=region_name, code_error=CommonConst.KEY_CODE_ERROR_DEFAULT) raise common_utils.write_log_pm_error(pm_error, pm_logger) # Export File CHECK_CIS12_ITEM_4_03.json try: current_date = date_utils.get_current_date_by_format( date_utils.PATTERN_YYYYMMDDHHMMSS) check_cis_item_4_03 = { 'AWSAccount': awsaccount, 'CheckResults': check_results, 'DateTime': current_date } FileUtils.upload_s3(trace_id, check_cis_item_4_03, result_json_path, True) except Exception as e: pm_logger.error("[%s] チェック結果JSONファイルの保存に失敗しました。", awsaccount) pm_error = common_utils.write_log_exception(e, pm_logger) pm_error.pm_notification_error = PmNotificationError( check_item_code=check_item_code, code_error=CommonConst.KEY_CODE_ERROR_DEFAULT) raise common_utils.write_log_pm_error(pm_error, pm_logger) # チェック結果 if len(check_results) > 0: return CheckResult.MinorInadequacies return CheckResult.Normal
def execute_send_result_slack(trace_id, check_history_id, language): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) # チェック結果テーブルのCheckHistoryIndexから、チェック履歴ID{CheckHistoryId}をキーとしてチェック結果一覧を取得します。 try: list_check_result = pm_checkResults.query_history_index( trace_id, check_history_id) except PmError as e: msg_err = "チェック結果の取得に失敗しました。" pm_logger.error(msg_err) common_utils.write_log_pm_error(e, pm_logger, msg_err) return if (not list_check_result): msg_err = "チェック結果の取得に失敗しました。" pm_logger.error(msg_err) return # チェック結果一覧のうちの一つから、組織IDを取得します。 organization_id = list_check_result[0]['OrganizationID'] organization_name = list_check_result[0]['OrganizationName'] project_name = list_check_result[0]['ProjectName'] # 組織別Slack通知設定テーブルから、組織ID、通知コードCHECK_CISをキーとして設定情報を取得します。 try: org_notify_slack = pm_orgNotifySlack.query_key(trace_id, organization_id, CommonConst.NOTIFY_CODE) except PmError as e: msg_err = "Slack設定情報の取得に失敗しました。:OrganizationID={0}, CheckCode={1}".format( organization_id, CommonConst.NOTIFY_CODE) pm_logger.error(msg_err) common_utils.write_log_pm_error(e, pm_logger, msg_err) return if (not org_notify_slack): msg_err = "Slack設定情報の取得に失敗しました。:OrganizationID={0}, CheckCode={1}".format( organization_id, CommonConst.NOTIFY_CODE) pm_logger.error(msg_err) return # S3から通知Slack設定ファイルを取得します。 try: config = FileUtils.read_yaml(trace_id, CommonConst.S3_SETTING_BUCKET, CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL) except PmError as e: msg_err = "通知Slack設定ファイルの取得に失敗しました。:s3://{0}/{1}".format( common_utils.get_environ(CommonConst.S3_SETTING_BUCKET), CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL) pm_logger.error(msg_err) common_utils.write_log_pm_error(e, pm_logger, msg_err) return if language not in CommonConst.LANGUAGE_SUPPORT: language = CommonConst.LANGUAGE_DEFAULT path_file_template = config[ CommonConst.KEY_GET_PATH_FILE_TEMPLATE_SLACK.format(language=language)] # メッセージ本文を作成します。 try: template_message = FileUtils.read_decode(trace_id, CommonConst.S3_SETTING_BUCKET, path_file_template) except PmError as e: msg_err = "Slack通知本文テンプレートファイルの取得に失敗しました。:s3://{0}/{1}".format( common_utils.get_environ(CommonConst.S3_SETTING_BUCKET), path_file_template) pm_logger.error(msg_err) common_utils.write_log_pm_error(e, pm_logger, msg_err) return executed_date_time = date_utils.toString( date_utils.toDate(list_check_result[0]['ExecutedDateTime'], date_utils.UTC), date_utils.PATTERN_YYYYMMDDHHMM, date_utils.get_time_zone_by_language(language)) check_results = [] for check_result in list_check_result: account_aws = CommonConst.AWS_ACCOUNT_MAIL.format( check_result['AWSAccount'][:4], check_result['AWSAccount'][4:8]) check_result = { "accountAWS": account_aws, "okCount": check_result['OKCount'], "ngCount": check_result['NGCount'], "criticalCount": check_result['CriticalCount'], "managedCount": check_result['ManagedCount'], "errorCount": check_result['ErrorCount'] } check_results.append(check_result) template = Template(template_message) context = { 'organizationName': organization_name, 'projectName': project_name, 'executedDateTime': executed_date_time, 'checkResults': check_results } body = template.render(context) mentions = slack_common.convert_command_slack(org_notify_slack['Mentions']) body = CommonConst.KEY_BODY_MESSAGE_SLACK.format(mentions=mentions, body=body) notify_slack = { "username": config[CommonConst.KEY_USER_NAME_SLACK.format(language=language)], "icon_url": config['slack.iconurl'], "text": body } notify_slack = json.dumps(notify_slack) try: slack_common.send_message_slack(trace_id, org_notify_slack['WebhookURL'], notify_slack) except PmError as e: msg_err = "Slack通知のリクエスト送信に失敗しました。:OrganizationID={0}, CheckCode={1}".format( organization_id, CommonConst.NOTIFY_CODE) pm_logger.warning(msg_err) common_utils.write_log_pm_error(e, pm_logger, msg_err)
def check_cis_metric(trace_id, check_history_id, organization_id, project_id, awsaccount, session, result_json_path, check_item_code, level_code, check_result): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) check_results = [] is_all_region_enable = False is_check5_successful = False # Get all region try: regions = aws_common.get_regions(trace_id, session) except PmError as e: pm_logger.error("Regionの情報の取得に失敗しました。") e.pm_notification_error = PmNotificationError( check_item_code=check_item_code, code_error=CommonConst.KEY_CODE_ERROR_DEFAULT) raise common_utils.write_log_pm_error(e, pm_logger) for region in regions: try: region_name = region["RegionName"] if region_name in REGION_IGNORE: continue # Default value check is_region_error = True try: cloud_trails = cis_item_common_logic.get_cloud_trails( trace_id, check_history_id, organization_id, project_id, awsaccount, region_name, session) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) logs_client = LogsUtils.get_logs_client(trace_id, session, region_name, awsaccount) cloudwatch_client = CloudWatchlUtils.get_cloudwatch_client( trace_id, session, region_name, awsaccount) sns_client = SNSUtils.get_sns_client(trace_id, session, region_name, awsaccount) trail_client = CloudTrailUtils.get_trail_client( trace_id, session, region_name, awsaccount) for cloud_trail in cloud_trails: try: # Check-0. マルチリージョン設定されたCloudTrailが存在するか。 trail_status = cis_item_common_logic.get_trails_status( trace_id, check_history_id, organization_id, project_id, awsaccount, region_name, trail_client, cloud_trail) if (len(trail_status) == 0): continue event_selectors = cis_item_common_logic.get_trail_event_selectors( trace_id, check_history_id, organization_id, project_id, awsaccount, region_name, trail_client, cloud_trail) # 全リージョンに対し有効なCloudTrailが存在するか # ロギングが有効か if (is_all_region_enable is False and cloud_trail['IsMultiRegionTrail'] is True and trail_status['IsLogging'] is True): # すべての管理操作の書き込みが有効か for event_selector in event_selectors: if (event_selector['IncludeManagementEvents'] is True and event_selector['ReadWriteType'] == CommonConst.EVENT_SELECTOR_READ_WRITE_TYPE_ALL): is_all_region_enable = True break if (is_all_region_enable is False): continue # Check-1. CloudTrailのロググループに対してメトリクスは設定されているか。 if common_utils.check_key( 'CloudWatchLogsLogGroupArn', cloud_trail ) is False or not cloud_trail['CloudWatchLogsLogGroupArn']: continue # Check-2. 許可されていないAPIコールに対するメトリクスは設定されているか。 metric_filters = describe_metric_filters( trace_id, check_history_id, organization_id, project_id, awsaccount, region_name, logs_client, cloud_trail['CloudWatchLogsLogGroupArn'].split(":")[6]) list_filter_pattern_result = get_list_filter_pattern_match_result( trace_id, check_item_code, metric_filters) if (not list_filter_pattern_result): continue # Check-3. メトリクスに対しアラームは設定されているか。 metric_alarms = describe_alarms( trace_id, check_history_id, organization_id, project_id, awsaccount, region_name, cloudwatch_client) metric_names = [] for filter_pattern_result in list_filter_pattern_result: metric_names.extend( jmespath.search( 'metricTransformations[*].metricName', filter_pattern_result)) metric_alarms_matching = [] for metric_alarm in metric_alarms: pm_logger.info( "アラーム名=%s", common_utils.get_value("AlarmName", metric_alarm)) if (common_utils.check_key('MetricName', metric_alarm) is True and metric_alarm['MetricName'] in metric_names): metric_alarms_matching.append(metric_alarm) if not metric_alarms_matching: continue # Check-4. アラームからキックされたSNSに対し通知先は設定されているか。 for metric_alarm in metric_alarms_matching: for alarm_action in metric_alarm['AlarmActions']: if alarm_action.startswith(CommonConst.ARN_SNS): subscriptions = list_subscriptions_by_topic( trace_id, check_history_id, organization_id, project_id, awsaccount, region_name, sns_client, alarm_action) if len(subscriptions) > 0: is_region_error = False break # Check-5. 設定されたCloudTrailは全Region有効なTrailか。 if (is_region_error is False and is_all_region_enable is True): is_check5_successful = True break except Exception as e: pm_logger.error("[%s/%s] チェック処理中にエラーが発生しました。", awsaccount, region_name) raise common_utils.write_log_exception(e, pm_logger) if is_check5_successful is True: check_results = [] break if (is_region_error is True): result = {'Region': region_name, 'Level': level_code} check_results.append(result) except Exception as e: pm_error = common_utils.write_log_exception(e, pm_logger) if not pm_error.pm_notification_error: pm_error.pm_notification_error = PmNotificationError( check_item_code=check_item_code, region=region_name, code_error=CommonConst.KEY_CODE_ERROR_DEFAULT) else: pm_error.pm_notification_error.check_item_code = check_item_code pm_error.pm_notification_error.aws_account = awsaccount pm_error.pm_notification_error.region = region_name raise common_utils.write_log_pm_error(pm_error, pm_logger) # 検出結果を1つのチェック結果JSONファイルに保存する。 try: current_date = date_utils.get_current_date_by_format( date_utils.PATTERN_YYYYMMDDHHMMSS) check_cis_item_3 = { 'AWSAccount': awsaccount, 'CheckResults': check_results, 'DateTime': current_date } FileUtils.upload_s3(trace_id, check_cis_item_3, result_json_path, True) except Exception as e: pm_logger.error("[%s] チェック結果JSONファイルの保存に失敗しました。", awsaccount) pm_error = common_utils.write_log_exception(e, pm_logger) pm_error.pm_notification_error = PmNotificationError( check_item_code=check_item_code, code_error=CommonConst.KEY_CODE_ERROR_DEFAULT) raise common_utils.write_log_pm_error(pm_error, pm_logger) if len(check_results) > 0: return check_result return CheckResult.Normal
def check_asc_item_16_01(trace_id, check_history_id, organization_id, project_id, aws_account, session, result_json_path): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) check_results = [] is_authorized = True # 取得したクレデンシャル情報を使用して、S3クライアントを作成します。 try: s3_client = S3Utils.get_s3_client(trace_id, session, aws_account) except PmError as e: raise common_utils.write_log_pm_error(e, pm_logger) # S3バケット一覧を取得します。 try: list_buckets = asc_item_common_logic.get_list_buckets( trace_id, check_history_id, organization_id, project_id, s3_client, aws_account) except PmError as e: return CheckResult.Error for bucket in list_buckets["Buckets"]: bucket_name = bucket['Name'] region_name = None try: # 取得したS3バケット一覧情報ファイルをもとに、各バケットのリージョンを取得する。 region_name = S3Utils.get_bucket_location(trace_id, s3_client, bucket_name, aws_account) if region_name is None: region_name = CommonConst.US_EAST_REGION # 取得したS3バケット情報ファイルをもとに、該当のS3バケットのアクセスコントロールリストを取得する。 bucket_acl = get_bucket_acl( trace_id, check_history_id, organization_id, project_id, aws_account, region_name, bucket_name, s3_client) # 取得したS3バケット情報をもとに、S3のロギング情報を取得する。 bucket_logging = S3Utils.get_bucket_logging( trace_id, aws_account, s3_client, bucket_name, region_name) except PmError as e: if e.cause_error.response['Error'][ 'Code'] in CommonConst.S3_SKIP_EXCEPTION: error_operation = e.cause_error.operation_name, error_code = e.cause_error.response['Error']['Code'], error_message = e.cause_error.response['Error']['Message'] if region_name is None: region_name = CommonConst.ERROR check_results.append( asc_item_common_logic.get_error_authorized_result( region_name, bucket_name, error_operation, error_code, error_message)) is_authorized = False continue else: return CheckResult.Error # 取得したS3ロギング情報をS3に保存する(リソース情報ファイル)。 try: s3_file_name = CommonConst.PATH_CHECK_RAW.format( check_history_id, organization_id, project_id, aws_account, "ASC/S3_ClientLogging_" + region_name + "_" + bucket_name + ".json") FileUtils.upload_json(trace_id, "S3_CHECK_BUCKET", bucket_logging, s3_file_name) except PmError as e: pm_logger.error("[%s] S3バケットロギング情報の取得に失敗しました。(%s/%s)", aws_account, region_name, bucket_name) return CheckResult.Error # チェック処理 bucket_abnormity = True try: # Check-1. ACLによりLogDeliveryに操作権限が与えられたS3バケットが存在するか for grant in bucket_acl["Grants"]: if (common_utils.check_key("URI", grant['Grantee']) and grant['Grantee']["URI"] == LOG_DELIVERY_URI): bucket_abnormity = False break # Check-2. S3バケットでログ記録が有効になっていないものは存在するか if bucket_abnormity is True and len(bucket_logging) == 0: result = { 'Region': region_name, 'Level': CommonConst.LEVEL_CODE_21, 'DetectionItem': { 'BucketName': bucket_name } } check_results.append(result) except Exception as e: pm_logger.error("[%s] チェック処理中にエラーが発生しました。(%s/%s)", aws_account, region_name, bucket_name) return CheckResult.Error # Export File CHECK_ASC_ITEM_16_01.json try: current_date = date_utils.get_current_date_by_format( date_utils.PATTERN_YYYYMMDDHHMMSS) check_asc_item_16_01 = { 'AWSAccount': aws_account, 'CheckResults': check_results, 'DateTime': current_date } FileUtils.upload_s3(trace_id, check_asc_item_16_01, result_json_path, True) except Exception as e: pm_logger.error("[%s] チェック結果JSONファイルの保存に失敗しました。", aws_account) return CheckResult.Error # チェック結果 if is_authorized is False: return CheckResult.Error if len(check_results) > 0: return CheckResult.CriticalDefect return CheckResult.Normal
def update_awscoop(trace_id, project_id, organization_id, coop_id, data_body): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) # Parse JSON try: body_object = json.loads(data_body) aws_account = body_object["awsAccount"] role_name = body_object["roleName"] description = body_object["description"] aws_account_name = body_object['awsAccountName'] except Exception as e: return common_utils.error_exception(MsgConst.ERR_REQUEST_202, HTTPStatus.BAD_REQUEST, e, pm_logger, True) # Validate list_error = validate_update_awscoop(aws_account, role_name) if list_error: return common_utils.error_validate(MsgConst.ERR_REQUEST_201, HTTPStatus.UNPROCESSABLE_ENTITY, list_error, pm_logger) # Get data AWSアカウント連携 try: awscoops_item = pm_awsAccountCoops.get_awscoops_update( trace_id, coop_id, project_id, organization_id) except PmError as e: return common_utils.error_exception(MsgConst.ERR_402, HTTPStatus.INTERNAL_SERVER_ERROR, e, pm_logger, True) # 組織情報を取得します。 if awscoops_item is None: return common_utils.error_common(MsgConst.ERR_301, HTTPStatus.NOT_FOUND, pm_logger) # ロールのアクセス確認 if common_utils.is_null(description): description = None if common_utils.is_null(aws_account_name): aws_account_name = None external_id = awscoops_item['ExternalID'] effective = Effective.Disable.value members = None if (checkaccess.check_access_to_aws(trace_id, aws_account, role_name, external_id)): effective = Effective.Enable.value # IAMクライアントを用いて、IAMロールcm-membersportalを取得します。 try: session = aws_common.create_session_client(trace_id, aws_account, role_name, external_id) members = IAMUtils.get_membership_aws_account( trace_id, session, aws_account) except PmError as e: common_utils.write_log_pm_error(e, pm_logger, exc_info=True) # update project attribute = { 'AWSAccount': { "Value": aws_account }, 'RoleName': { "Value": role_name }, 'Description': { "Value": description }, 'Effective': { "Value": effective }, 'AWSAccountName': { "Value": aws_account_name } } if (members is not None): attribute['Members'] = {"Value": members} updated_at = awscoops_item['UpdatedAt'] try: pm_awsAccountCoops.update_awscoops(trace_id, coop_id, attribute, updated_at) except PmError as e: return common_utils.error_exception(MsgConst.ERR_DB_403, HTTPStatus.INTERNAL_SERVER_ERROR, e, pm_logger, True) # Get data response try: awscoops_item = pm_awsAccountCoops.query_awscoop_coop_key( trace_id, coop_id, convert_response=True) except PmError as e: return common_utils.error_exception(MsgConst.ERR_402, HTTPStatus.INTERNAL_SERVER_ERROR, e, pm_logger, True) # return data response response = common_utils.get_response_by_response_body( HTTPStatus.OK, awscoops_item) return common_utils.response(response, pm_logger)
def execute_delete_invalid_user(trace_id): pm_logger = common_utils.begin_logger(trace_id, __name__, inspect.currentframe()) # Get Cognito UserPools status UNCONFIRMED try: list_user_unconfirmed = aws_common.get_cognito_user_pools( trace_id, CommonConst.COGNITO_STATUS_UNCONFIRMED, attribute_filter=CommonConst.ATTRIBUTE_FILTER_USER_STATUS) except PmError as e: pm_logger.error("[%s]Cognitoユーザー一覧情報取得に失敗しました。", CommonConst.COGNITO_STATUS_UNCONFIRMED) raise common_utils.write_log_pm_error(e, pm_logger) # get current date current_date_time = date_utils.toDate( date_utils.get_current_date_by_format( date_utils.PATTERN_YYYYMMDDHHMMSS), date_utils.UTC) # loop user cognito UserPools status UNCONFIRMED for user_unconfirmed in list_user_unconfirmed: user_create_date = date_utils.toDate( date_utils.toString(user_unconfirmed['UserCreateDate'], date_utils.PATTERN_YYYYMMDDHHMM), date_utils.UTC) if date_utils.difference_days( user_create_date, current_date_time) > CommonConst.TERM_USER_UNCONFIRMED_DAY: # delete Cognito UserPools status UNCONFIRMED update period greater than 1 days try: aws_common.delete_cognito_user_by_user_name( trace_id, user_unconfirmed['Username']) except PmError as e: pm_logger.warning("CognitoでUserName = %sのユーザー削除に失敗しました。", user_unconfirmed['Username']) raise common_utils.write_log_pm_error(e, pm_logger) # Get Cognito UserPools status FORCE_CHANGE_PASSWORD try: list_user_force_change_password = aws_common.get_cognito_user_pools( trace_id, CommonConst.COGNITO_STATUS_FORCE_CHANGE_PASSWORD, attribute_filter=CommonConst.ATTRIBUTE_FILTER_USER_STATUS) except PmError as e: pm_logger.error("[%s]Cognitoユーザー一覧情報取得に失敗しました。", CommonConst.COGNITO_STATUS_FORCE_CHANGE_PASSWORD) raise common_utils.write_log_pm_error(e, pm_logger) current_date = date_utils.toDate( date_utils.toString(current_date_time, date_utils.PATTERN_YYYYMMDD_SLASH), date_utils.UTC) # loop user cognito UserPools status FORCE_CHANGE_PASSWORD for user_force_change_password in list_user_force_change_password: user_create_date = date_utils.toDate( date_utils.toString(user_force_change_password['UserCreateDate'], date_utils.PATTERN_YYYYMMDD_SLASH), date_utils.UTC) if date_utils.difference_days( user_create_date, current_date ) > CommonConst.TERM_USER_FORCE_CHANGE_PASSWORD_DAY: # get list affiliations try: affiliations = pm_affiliation.query_userid_key( trace_id, user_force_change_password['Username']) except PmError as e: pm_logger.warning( "PM_Affiliationテーブルにて、UserID = %sのレコード取得に失敗しました。", user_force_change_password['Username']) raise common_utils.write_log_pm_error(e, pm_logger) # delete affiliations user status FORCE_CHANGE_PASSWORD update period greater than 6 days for affiliation in affiliations: try: pm_affiliation.delete_affiliation( affiliation['UserID'], affiliation['OrganizationID']) except PmError as e: pm_logger.warning( "PM_Affiliationテーブルのレコード削除に失敗しました。UserID : %s / OrganizationID : %s", affiliation['UserID'], affiliation['OrganizationID']) raise common_utils.write_log_pm_error(e, pm_logger) # delete Cognito UserPools status FORCE_CHANGE_PASSWORD update period greater than 6 days try: aws_common.delete_cognito_user_by_user_name( trace_id, user_force_change_password['Username']) except PmError as e: pm_logger.warning("CognitoでUserName = %sのユーザー削除に失敗しました。", user_force_change_password['Username']) raise common_utils.write_log_pm_error(e, pm_logger)