v0.0.22 | NHN Cloud 프로젝트 수정 API 추가
Some checks failed
Build And Test / build-and-push (push) Failing after 49s
Some checks failed
Build And Test / build-and-push (push) Failing after 49s
- PUT /api/auth/nhn-cloud/projects/{id}/ 수정 API
- GET /api/auth/nhn-cloud/projects/{id}/ 상세 조회 API
- 프로젝트 생성 로직 수정 (encrypted_password 설정)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -503,7 +503,9 @@ class NHNCloudProjectListView(APIView):
|
|||||||
storage_account=storage_account,
|
storage_account=storage_account,
|
||||||
is_active=is_first,
|
is_active=is_first,
|
||||||
)
|
)
|
||||||
project.save_credentials(password)
|
# 암호화된 비밀번호 설정 후 저장
|
||||||
|
project.encrypted_password = project.encrypt_password(password)
|
||||||
|
project.save()
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"[NHN PROJECT CREATE] user={email} | project={name} | is_active={is_first} | IP={ip} | UA={ua}"
|
f"[NHN PROJECT CREATE] user={email} | project={name} | is_active={is_first} | IP={ip} | UA={ua}"
|
||||||
@ -528,7 +530,7 @@ class NHNCloudProjectListView(APIView):
|
|||||||
|
|
||||||
|
|
||||||
class NHNCloudProjectDetailView(APIView):
|
class NHNCloudProjectDetailView(APIView):
|
||||||
"""NHN Cloud 프로젝트 상세 (삭제)"""
|
"""NHN Cloud 프로젝트 상세 (조회/수정/삭제)"""
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def get_project(self, request, project_id):
|
def get_project(self, request, project_id):
|
||||||
@ -538,6 +540,96 @@ class NHNCloudProjectDetailView(APIView):
|
|||||||
except NHNCloudProject.DoesNotExist:
|
except NHNCloudProject.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get(self, request, project_id):
|
||||||
|
"""프로젝트 상세 조회"""
|
||||||
|
with tracer.start_as_current_span("NHNCloudProjectDetailView GET") as span:
|
||||||
|
email, ip, ua = get_request_info(request)
|
||||||
|
|
||||||
|
project = self.get_project(request, project_id)
|
||||||
|
if not project:
|
||||||
|
return Response({"error": "프로젝트를 찾을 수 없습니다."}, status=404)
|
||||||
|
|
||||||
|
span.add_event("NHN project retrieved", attributes={"email": email, "project": project.name})
|
||||||
|
|
||||||
|
return Response({
|
||||||
|
"id": project.id,
|
||||||
|
"name": project.name,
|
||||||
|
"tenant_id": project.tenant_id,
|
||||||
|
"username": project.username,
|
||||||
|
"storage_account": project.storage_account or "",
|
||||||
|
"is_active": project.is_active,
|
||||||
|
"created_at": project.created_at.isoformat(),
|
||||||
|
})
|
||||||
|
|
||||||
|
def put(self, request, project_id):
|
||||||
|
"""프로젝트 수정"""
|
||||||
|
with tracer.start_as_current_span("NHNCloudProjectDetailView PUT") as span:
|
||||||
|
email, ip, ua = get_request_info(request)
|
||||||
|
|
||||||
|
project = self.get_project(request, project_id)
|
||||||
|
if not project:
|
||||||
|
logger.warning(
|
||||||
|
f"[NHN PROJECT UPDATE] user={email} | status=fail | reason=not_found | IP={ip} | UA={ua}"
|
||||||
|
)
|
||||||
|
return Response({"error": "프로젝트를 찾을 수 없습니다."}, status=404)
|
||||||
|
|
||||||
|
# 수정 가능한 필드
|
||||||
|
name = request.data.get("name")
|
||||||
|
tenant_id = request.data.get("tenant_id")
|
||||||
|
username = request.data.get("username")
|
||||||
|
password = request.data.get("password") # 비어있으면 변경 안함
|
||||||
|
storage_account = request.data.get("storage_account")
|
||||||
|
|
||||||
|
# 필수 필드 검증
|
||||||
|
if not name or not tenant_id or not username:
|
||||||
|
return Response(
|
||||||
|
{"error": "name, tenant_id, username은 필수입니다."},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
|
# tenant_id 중복 체크 (자기 자신 제외)
|
||||||
|
if NHNCloudProject.objects.filter(
|
||||||
|
user=request.user, tenant_id=tenant_id
|
||||||
|
).exclude(id=project_id).exists():
|
||||||
|
return Response(
|
||||||
|
{"error": "이미 등록된 Tenant ID입니다."},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
project.name = name
|
||||||
|
project.tenant_id = tenant_id
|
||||||
|
project.username = username
|
||||||
|
if storage_account is not None:
|
||||||
|
project.storage_account = storage_account
|
||||||
|
|
||||||
|
# 비밀번호가 제공된 경우에만 변경
|
||||||
|
if password:
|
||||||
|
project.encrypted_password = project.encrypt_password(password)
|
||||||
|
|
||||||
|
project.save()
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"[NHN PROJECT UPDATE] user={email} | project={name} | IP={ip} | UA={ua}"
|
||||||
|
)
|
||||||
|
span.add_event("NHN project updated", attributes={"email": email, "project": name})
|
||||||
|
|
||||||
|
return Response({
|
||||||
|
"id": project.id,
|
||||||
|
"name": project.name,
|
||||||
|
"tenant_id": project.tenant_id,
|
||||||
|
"username": project.username,
|
||||||
|
"storage_account": project.storage_account or "",
|
||||||
|
"is_active": project.is_active,
|
||||||
|
"created_at": project.created_at.isoformat(),
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(
|
||||||
|
f"[NHN PROJECT UPDATE] user={email} | status=fail | reason=exception | IP={ip} | UA={ua}"
|
||||||
|
)
|
||||||
|
return Response({"error": f"프로젝트 수정 실패: {str(e)}"}, status=500)
|
||||||
|
|
||||||
def delete(self, request, project_id):
|
def delete(self, request, project_id):
|
||||||
"""프로젝트 삭제"""
|
"""프로젝트 삭제"""
|
||||||
with tracer.start_as_current_span("NHNCloudProjectDetailView DELETE") as span:
|
with tracer.start_as_current_span("NHNCloudProjectDetailView DELETE") as span:
|
||||||
|
|||||||
Reference in New Issue
Block a user