diff --git a/nhn/urls.py b/nhn/urls.py index 8b251f7..45aac6d 100644 --- a/nhn/urls.py +++ b/nhn/urls.py @@ -31,6 +31,8 @@ urlpatterns = [ # ==================== Floating IP ==================== path("floatingip/", views.FloatingIpListView.as_view(), name="floatingip-list"), + path("floatingip//attach/", views.FloatingIpAttachView.as_view(), name="floatingip-attach"), + path("floatingip//detach/", views.FloatingIpDetachView.as_view(), name="floatingip-detach"), # ==================== Security Group ==================== path("securitygroup/", views.SecurityGroupListView.as_view(), name="securitygroup-list"), diff --git a/nhn/views.py b/nhn/views.py index 856cab1..175a7f3 100644 --- a/nhn/views.py +++ b/nhn/views.py @@ -599,6 +599,58 @@ class FloatingIpListView(NHNBaseView): return Response({"error": e.message}, status=status.HTTP_400_BAD_REQUEST) +class FloatingIpAttachView(NHNBaseView): + """Floating IP를 로드밸런서에 연결""" + + @swagger_auto_schema( + operation_summary="Floating IP를 로드밸런서 VIP 포트에 연결", + manual_parameters=[region_header, token_header], + responses={200: "연결된 Floating IP 정보"}, + ) + def post(self, request, floating_ip_id): + headers = get_nhn_headers(request) + loadbalancer_id = request.data.get("loadbalancer_id") + if not loadbalancer_id: + return Response({"error": "loadbalancer_id가 필요합니다."}, status=status.HTTP_400_BAD_REQUEST) + + try: + # LB 상세 조회하여 vip_port_id 추출 + lb_api = ApiLoadBalancer(headers["region"], headers["token"]) + lb_info = lb_api.get_loadbalancer_info(loadbalancer_id) + vip_port_id = lb_info.get("loadbalancer", {}).get("vip_port_id") + if not vip_port_id: + return Response({"error": "로드밸런서 VIP 포트를 찾을 수 없습니다."}, status=status.HTTP_400_BAD_REQUEST) + + # FIP를 VIP 포트에 연결 + vpc_api = ApiVpc(headers["region"], headers["token"]) + result = vpc_api.attach_floating_ip(floating_ip_id, vip_port_id) + logger.info(f"[FIP] Floating IP {floating_ip_id} → LB {loadbalancer_id} (port={vip_port_id}) 연결 성공") + return Response(result) + except NHNCloudAPIError as e: + logger.error(f"[FIP] Floating IP 연결 실패 - error={e.message}") + return Response({"error": e.message}, status=status.HTTP_400_BAD_REQUEST) + + +class FloatingIpDetachView(NHNBaseView): + """Floating IP 연결 해제""" + + @swagger_auto_schema( + operation_summary="Floating IP 연결 해제", + manual_parameters=[region_header, token_header], + responses={200: "해제된 Floating IP 정보"}, + ) + def post(self, request, floating_ip_id): + headers = get_nhn_headers(request) + try: + vpc_api = ApiVpc(headers["region"], headers["token"]) + result = vpc_api.detach_floating_ip(floating_ip_id) + logger.info(f"[FIP] Floating IP {floating_ip_id} 연결 해제 성공") + return Response(result) + except NHNCloudAPIError as e: + logger.error(f"[FIP] Floating IP 연결 해제 실패 - error={e.message}") + return Response({"error": e.message}, status=status.HTTP_400_BAD_REQUEST) + + # ==================== Security Group API ==================== diff --git a/version b/version index faa66db..8da573f 100644 --- a/version +++ b/version @@ -1 +1 @@ -v0.0.15 \ No newline at end of file +v0.0.16 \ No newline at end of file