website/hub/broker/views.py

115 lines
4.3 KiB
Python
Raw Normal View History

2025-01-31 15:34:10 +01:00
import logging
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.decorators import action
from django.shortcuts import get_object_or_404
from hub.services.models import ServiceOffering, Lead
from hub.services.odoo import OdooAPI
from .models import ServiceInstance, ServiceBrokerUser
from .serializers import ServiceInstanceProvisioningSerializer
from .authentication import ServiceBrokerAuthentication
logger = logging.getLogger(__name__)
class ServiceBrokerViewSet(viewsets.ViewSet):
authentication_classes = [ServiceBrokerAuthentication]
def _create_lead_from_provision_data(self, offering, plan, parameters, context):
"""Create a lead in Odoo from provisioning data"""
# Get the first user from parameters as the main contact
user_data = parameters["users"][0]
lead = Lead(
service=offering.service,
offering=offering,
plan=plan,
name=user_data["full_name"],
company=context["organization_display_name"],
email=user_data["email"],
phone="", # Not provided in broker API
)
try:
odoo = OdooAPI()
lead.odoo_lead_id = odoo.create_lead(lead)
lead.save()
return lead
except Exception as e:
logger.error(f"Failed to create lead in Odoo: {str(e)}")
raise
@action(
detail=False,
methods=["put"],
url_path="service_instances/(?P<instance_id>[^/.]+)",
)
def provision_instance(self, request, instance_id):
# Validate request data
serializer = ServiceInstanceProvisioningSerializer(data=request.data)
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# Get broker user and check offering access
broker_user = get_object_or_404(ServiceBrokerUser, user=request.user)
offering = serializer.validated_data["service_id"] # This is now the offering
if not broker_user.allowed_offerings.filter(id=offering.id).exists():
return Response(
{"error": "Service offering not available for this user"},
status=status.HTTP_403_FORBIDDEN,
)
# Check if instance already exists
if ServiceInstance.objects.filter(instance_id=instance_id).exists():
return Response(status=status.HTTP_200_OK)
try:
# Create lead in Odoo
lead = self._create_lead_from_provision_data(
offering=offering,
plan=serializer.validated_data["plan_id"],
parameters=serializer.validated_data["parameters"],
context=serializer.validated_data["context"],
)
# Create service instance
instance = ServiceInstance.objects.create(
instance_id=instance_id,
offering=offering,
plan=serializer.validated_data["plan_id"],
organization_guid=serializer.validated_data["organization_guid"],
space_guid=serializer.validated_data["space_guid"],
organization_name=serializer.validated_data["context"][
"organization_name"
],
parameters=serializer.validated_data["parameters"],
context=serializer.validated_data["context"],
lead=lead,
)
return Response(
{
"dashboard_url": f"/services/{offering.service.slug}",
"operation": "provision",
},
status=status.HTTP_201_CREATED,
)
except Exception as e:
logger.error(f"Error provisioning instance: {str(e)}")
return Response(
{"error": "Failed to provision service instance"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
@action(
detail=False,
methods=["delete"],
url_path="service_instances/(?P<instance_id>[^/.]+)",
)
def deprovision_instance(self, request, instance_id):
instance = get_object_or_404(ServiceInstance, instance_id=instance_id)
instance.delete()
return Response(status=status.HTTP_200_OK)