diff --git a/app/extensions/db/repository.py b/app/extensions/db/repository.py index 6e620a2..68e0c12 100644 --- a/app/extensions/db/repository.py +++ b/app/extensions/db/repository.py @@ -51,7 +51,11 @@ def get_by_user_challenge_name(self, userChallengeName: str) -> Optional[UserCha Returns: UserChallenges: 사용자 챌린지 """ - return UserChallenges.query.filter_by(userChallengeName=userChallengeName).first() + user_challenge = UserChallenges.query.filter_by(userChallengeName=userChallengeName).first() + if not user_challenge: + raise InternalServerError(error_msg=f"User challenge {userChallengeName} not found") + return user_challenge + def update_status(self, challenge: UserChallenges, new_status: str) -> bool: """ @@ -73,7 +77,7 @@ def update_status(self, challenge: UserChallenges, new_status: str) -> bool: except SQLAlchemyError as e: # logger.error(f"Error updating challenge status: {e}") self.session.rollback() - return False + raise InternalServerError(error_msg=f"Error updating challenge status: {e}") from e def update_port(self, challenge: UserChallenges, port: int) -> bool: """ diff --git a/app/extensions/k8s/client.py b/app/extensions/k8s/client.py index dcf2c8c..3ce0123 100644 --- a/app/extensions/k8s/client.py +++ b/app/extensions/k8s/client.py @@ -48,86 +48,87 @@ def create_challenge_resource(self, challenge_id, username, namespace="default") ChallengeCreationError: Challenge Custom Resource 생성에 실패했을 때 """ - try: - user_challenge_repo = UserChallengesRepository() + + user_challenge_repo = UserChallengesRepository() - # Challenge definition 조회 - challenge_definition = ChallengeRepository.get_challenge_name(challenge_id) - if not challenge_definition: - raise ChallengeNotFound(error_msg=f"Challenge definition not found for ID: {challenge_id}") + # Challenge definition 조회 + challenge_definition = ChallengeRepository.get_challenge_name(challenge_id) + if not challenge_definition: + raise ChallengeNotFound(error_msg=f"Challenge definition not found for ID: {challenge_id}") - # Challenge name 생성 및 검증 - challenge_name = f"challenge-{challenge_id}-{username}" - if not self._is_valid_k8s_name(challenge_name): - raise UserChallengeCreationError(error_msg=f"Invalid challenge name: {challenge_name}") + # Challenge name 생성 및 검증 + challenge_name = f"challenge-{challenge_id}-{username}" + if not self._is_valid_k8s_name(challenge_name): + raise UserChallengeCreationError(error_msg=f"Invalid challenge name: {challenge_name}") - # Namespace 존재 여부 확인 - try: - self.core_api.read_namespace(namespace) - except Exception as e: - raise UserChallengeCreationError(error_msg=str(e)) + # Namespace 존재 여부 확인 + try: + self.core_api.read_namespace(namespace) + except Exception as e: + raise UserChallengeCreationError(error_msg=str(e)) - # Database에 UserChallenge 생성 - user_challenge = user_challenge_repo.get_by_user_challenge_name(challenge_name) - if not user_challenge: - user_challenge = user_challenge_repo.create(username, challenge_id, challenge_name, 0) - else: - # 이미 실행 중인 Challenge가 있으면 데이터베이스에 저장된 포트 번호 반환 - if user_challenge.status == 'Running': - return user_challenge.port + # Database에 UserChallenge 생성 + user_challenge = user_challenge_repo.get_by_user_challenge_name(challenge_name) + if not user_challenge: + user_challenge = user_challenge_repo.create(username, challenge_id, challenge_name, 0) + else: + # 이미 실행 중인 Challenge가 있으면 데이터베이스에 저장된 포트 번호 반환 + if user_challenge.status == 'Running': + return user_challenge.port - # Challenge manifest 생성 - challenge_manifest = { - "apiVersion": "apps.hexactf.io/v1alpha1", - "kind": "Challenge", - "metadata": { - "name": challenge_name, - "labels": { - "apps.hexactf.io/challengeId": str(challenge_id), - "apps.hexactf.io/user": username - } - }, - "spec": { - "namespace": namespace, - "definition": challenge_definition + # Challenge manifest 생성 + challenge_manifest = { + "apiVersion": "apps.hexactf.io/v1alpha1", + "kind": "Challenge", + "metadata": { + "name": challenge_name, + "labels": { + "apps.hexactf.io/challengeId": str(challenge_id), + "apps.hexactf.io/user": username } + }, + "spec": { + "namespace": namespace, + "definition": challenge_definition } + } - challenge = self.custom_api.create_namespaced_custom_object( + challenge = self.custom_api.create_namespaced_custom_object( + group="apps.hexactf.io", + version="v1alpha1", + namespace=namespace, + plural="challenges", + body=challenge_manifest + ) + + # status 값 가져오기 + status = challenge.get('status', {}) + endpoint = status.get('endpoint') + + # status가 아직 설정되지 않았을 수 있으므로, 필요한 경우 다시 조회 + if not status: + time.sleep(3) + challenge = self.custom_api.get_namespaced_custom_object( group="apps.hexactf.io", version="v1alpha1", namespace=namespace, plural="challenges", - body=challenge_manifest + name=challenge['metadata']['name'] ) - - # status 값 가져오기 status = challenge.get('status', {}) endpoint = status.get('endpoint') - - # status가 아직 설정되지 않았을 수 있으므로, 필요한 경우 다시 조회 - if not status: - time.sleep(3) - challenge = self.custom_api.get_namespaced_custom_object( - group="apps.hexactf.io", - version="v1alpha1", - namespace=namespace, - plural="challenges", - name=challenge['metadata']['name'] - ) - status = challenge.get('status', {}) - endpoint = status.get('endpoint') - - # NodePort 업데이트 - if endpoint: - success = user_challenge_repo.update_port(user_challenge, int(endpoint)) - if not success: - raise UserChallengeCreationError(error_msg=f"Failed to update UserChallenge with NodePort: {endpoint}") - - - return endpoint - except Exception as e: - raise UserChallengeCreationError(error_msg=str(e)) from e + + # NodePort 업데이트 + if not endpoint: + raise UserChallengeCreationError(error_msg=f"Failed to get NodePort for Challenge: {challenge_name}") + + success = user_challenge_repo.update_port(user_challenge, int(endpoint)) + if not success: + raise UserChallengeCreationError(error_msg=f"Failed to update UserChallenge with NodePort: {endpoint}") + + return endpoint + + def _is_valid_k8s_name(self, name: str) -> bool: