Use new osb_id fields to match API requests
All checks were successful
Tests / test (push) Successful in 32s
All checks were successful
Tests / test (push) Successful in 32s
This commit is contained in:
parent
4be6eeb18f
commit
e459047622
3 changed files with 70 additions and 70 deletions
|
|
@ -14,7 +14,7 @@ from django.views.decorators.csrf import csrf_exempt
|
||||||
from servala.api.permissions import OSBBasicAuthPermission
|
from servala.api.permissions import OSBBasicAuthPermission
|
||||||
from servala.core.exoscale import get_exoscale_origin
|
from servala.core.exoscale import get_exoscale_origin
|
||||||
from servala.core.models import BillingEntity, Organization, User
|
from servala.core.models import BillingEntity, Organization, User
|
||||||
from servala.core.models.service import Plan, Service
|
from servala.core.models.service import Service, ServiceOffering
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -90,11 +90,13 @@ class OSBServiceInstanceView(OSBBasicAuthPermission, View):
|
||||||
return self._error(f"Unable to create user: {e}")
|
return self._error(f"Unable to create user: {e}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
service = Service.objects.get(id=service_id)
|
service = Service.objects.get(osb_service_id=service_id)
|
||||||
plan = Plan.objects.get(id=plan_id, service_offering__service=service)
|
service_offering = ServiceOffering.objects.get(
|
||||||
|
osb_plan_id=plan_id, service=service
|
||||||
|
)
|
||||||
except Service.DoesNotExist:
|
except Service.DoesNotExist:
|
||||||
return self._error(f"Unknown service_id: {service_id}")
|
return self._error(f"Unknown service_id: {service_id}")
|
||||||
except Plan.DoesNotExist:
|
except ServiceOffering.DoesNotExist:
|
||||||
return self._error(
|
return self._error(
|
||||||
f"Unknown plan_id: {plan_id} for service_id: {service_id}"
|
f"Unknown plan_id: {plan_id} for service_id: {service_id}"
|
||||||
)
|
)
|
||||||
|
|
@ -104,7 +106,9 @@ class OSBServiceInstanceView(OSBBasicAuthPermission, View):
|
||||||
organization = Organization.objects.get(
|
organization = Organization.objects.get(
|
||||||
osb_guid=organization_guid, origin=exoscale_origin
|
osb_guid=organization_guid, origin=exoscale_origin
|
||||||
)
|
)
|
||||||
self._send_service_welcome_email(request, organization, user, service, plan)
|
self._send_service_welcome_email(
|
||||||
|
request, organization, user, service, service_offering
|
||||||
|
)
|
||||||
return JsonResponse({"message": "Service already enabled"}, status=200)
|
return JsonResponse({"message": "Service already enabled"}, status=200)
|
||||||
|
|
||||||
odoo_data = {
|
odoo_data = {
|
||||||
|
|
@ -126,7 +130,7 @@ class OSBServiceInstanceView(OSBBasicAuthPermission, View):
|
||||||
|
|
||||||
self._send_invitation_email(request, organization, user)
|
self._send_invitation_email(request, organization, user)
|
||||||
self._send_service_welcome_email(
|
self._send_service_welcome_email(
|
||||||
request, organization, user, service, plan
|
request, organization, user, service, service_offering
|
||||||
)
|
)
|
||||||
|
|
||||||
return JsonResponse(
|
return JsonResponse(
|
||||||
|
|
@ -159,8 +163,10 @@ The Servala Team"""
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _send_service_welcome_email(self, request, organization, user, service, plan):
|
def _send_service_welcome_email(
|
||||||
service_path = f"{organization.urls.services}{service.slug}/offering/{plan.service_offering.id}/"
|
self, request, organization, user, service, service_offering
|
||||||
|
):
|
||||||
|
service_path = f"{organization.urls.services}{service.slug}/offering/{service_offering.id}/"
|
||||||
service_url = request.build_absolute_uri(service_path)
|
service_url = request.build_absolute_uri(service_path)
|
||||||
|
|
||||||
subject = f"Get started with {service.name} - {organization.name}"
|
subject = f"Get started with {service.name} - {organization.name}"
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ from servala.core.models import (
|
||||||
)
|
)
|
||||||
from servala.core.models.service import (
|
from servala.core.models.service import (
|
||||||
CloudProvider,
|
CloudProvider,
|
||||||
Plan,
|
|
||||||
Service,
|
Service,
|
||||||
ServiceCategory,
|
ServiceCategory,
|
||||||
ServiceOffering,
|
ServiceOffering,
|
||||||
|
|
@ -56,6 +55,7 @@ def test_service(test_service_category):
|
||||||
slug="redis",
|
slug="redis",
|
||||||
category=test_service_category,
|
category=test_service_category,
|
||||||
description="Redis database service",
|
description="Redis database service",
|
||||||
|
osb_service_id="test-service-123",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -73,18 +73,7 @@ def test_service_offering(test_service, test_cloud_provider):
|
||||||
service=test_service,
|
service=test_service,
|
||||||
provider=test_cloud_provider,
|
provider=test_cloud_provider,
|
||||||
description="Redis on Exoscale",
|
description="Redis on Exoscale",
|
||||||
)
|
osb_plan_id="test-plan-123",
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def test_plan(test_service_offering):
|
|
||||||
return Plan.objects.create(
|
|
||||||
name="Small",
|
|
||||||
description="Small Redis plan",
|
|
||||||
term=1,
|
|
||||||
service_offering=test_service_offering,
|
|
||||||
features={"memory": "1GB", "connections": 100},
|
|
||||||
pricing={"monthly": 10.0},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,16 +50,16 @@ def test_successful_onboarding_new_organization(
|
||||||
mock_odoo_success,
|
mock_odoo_success,
|
||||||
osb_client,
|
osb_client,
|
||||||
test_service,
|
test_service,
|
||||||
test_plan,
|
test_service_offering,
|
||||||
valid_osb_payload,
|
valid_osb_payload,
|
||||||
exoscale_origin,
|
exoscale_origin,
|
||||||
instance_id,
|
instance_id,
|
||||||
):
|
):
|
||||||
valid_osb_payload["service_id"] = test_service.id
|
valid_osb_payload["service_id"] = test_service.osb_service_id
|
||||||
valid_osb_payload["plan_id"] = test_plan.id
|
valid_osb_payload["plan_id"] = test_service_offering.osb_plan_id
|
||||||
|
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(valid_osb_payload),
|
data=json.dumps(valid_osb_payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -102,7 +102,7 @@ def test_successful_onboarding_new_organization(
|
||||||
def test_duplicate_organization_returns_existing(
|
def test_duplicate_organization_returns_existing(
|
||||||
osb_client,
|
osb_client,
|
||||||
test_service,
|
test_service,
|
||||||
test_plan,
|
test_service_offering,
|
||||||
valid_osb_payload,
|
valid_osb_payload,
|
||||||
exoscale_origin,
|
exoscale_origin,
|
||||||
instance_id,
|
instance_id,
|
||||||
|
|
@ -113,11 +113,11 @@ def test_duplicate_organization_returns_existing(
|
||||||
origin=exoscale_origin,
|
origin=exoscale_origin,
|
||||||
)
|
)
|
||||||
|
|
||||||
valid_osb_payload["service_id"] = test_service.id
|
valid_osb_payload["service_id"] = test_service.osb_service_id
|
||||||
valid_osb_payload["plan_id"] = test_plan.id
|
valid_osb_payload["plan_id"] = test_service_offering.osb_plan_id
|
||||||
|
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(valid_osb_payload),
|
data=json.dumps(valid_osb_payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -133,15 +133,15 @@ def test_duplicate_organization_returns_existing(
|
||||||
def test_unauthenticated_osb_api_request_fails(
|
def test_unauthenticated_osb_api_request_fails(
|
||||||
client,
|
client,
|
||||||
test_service,
|
test_service,
|
||||||
test_plan,
|
test_service_offering,
|
||||||
valid_osb_payload,
|
valid_osb_payload,
|
||||||
instance_id,
|
instance_id,
|
||||||
):
|
):
|
||||||
valid_osb_payload["service_id"] = test_service.id
|
valid_osb_payload["service_id"] = test_service.osb_service_id
|
||||||
valid_osb_payload["plan_id"] = test_plan.id
|
valid_osb_payload["plan_id"] = test_service_offering.osb_plan_id
|
||||||
|
|
||||||
response = client.put(
|
response = client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(valid_osb_payload),
|
data=json.dumps(valid_osb_payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -169,14 +169,14 @@ def test_unauthenticated_osb_api_request_fails(
|
||||||
def test_missing_required_fields_error(
|
def test_missing_required_fields_error(
|
||||||
osb_client,
|
osb_client,
|
||||||
test_service,
|
test_service,
|
||||||
test_plan,
|
test_service_offering,
|
||||||
valid_osb_payload,
|
valid_osb_payload,
|
||||||
field_to_remove,
|
field_to_remove,
|
||||||
expected_error,
|
expected_error,
|
||||||
instance_id,
|
instance_id,
|
||||||
):
|
):
|
||||||
valid_osb_payload["service_id"] = test_service.id
|
valid_osb_payload["service_id"] = test_service.osb_service_id
|
||||||
valid_osb_payload["plan_id"] = test_plan.id
|
valid_osb_payload["plan_id"] = test_service_offering.osb_plan_id
|
||||||
|
|
||||||
if isinstance(field_to_remove, tuple):
|
if isinstance(field_to_remove, tuple):
|
||||||
if field_to_remove[0] == "context":
|
if field_to_remove[0] == "context":
|
||||||
|
|
@ -188,7 +188,7 @@ def test_missing_required_fields_error(
|
||||||
del valid_osb_payload[field_to_remove]
|
del valid_osb_payload[field_to_remove]
|
||||||
|
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(valid_osb_payload),
|
data=json.dumps(valid_osb_payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -204,7 +204,7 @@ def test_invalid_service_id_error(osb_client, valid_osb_payload, instance_id):
|
||||||
valid_osb_payload["plan_id"] = 1
|
valid_osb_payload["plan_id"] = 1
|
||||||
|
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(valid_osb_payload),
|
data=json.dumps(valid_osb_payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -218,11 +218,11 @@ def test_invalid_service_id_error(osb_client, valid_osb_payload, instance_id):
|
||||||
def test_invalid_plan_id_error(
|
def test_invalid_plan_id_error(
|
||||||
osb_client, test_service, valid_osb_payload, instance_id
|
osb_client, test_service, valid_osb_payload, instance_id
|
||||||
):
|
):
|
||||||
valid_osb_payload["service_id"] = test_service.id
|
valid_osb_payload["service_id"] = test_service.osb_service_id
|
||||||
valid_osb_payload["plan_id"] = 99999
|
valid_osb_payload["plan_id"] = 99999
|
||||||
|
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(valid_osb_payload),
|
data=json.dumps(valid_osb_payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -230,21 +230,21 @@ def test_invalid_plan_id_error(
|
||||||
assert response.status_code == 400
|
assert response.status_code == 400
|
||||||
response_data = json.loads(response.content)
|
response_data = json.loads(response.content)
|
||||||
assert (
|
assert (
|
||||||
f"Unknown plan_id: 99999 for service_id: {test_service.id}"
|
f"Unknown plan_id: 99999 for service_id: {test_service.osb_service_id}"
|
||||||
in response_data["error"]
|
in response_data["error"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_empty_users_array_error(
|
def test_empty_users_array_error(
|
||||||
osb_client, test_service, test_plan, valid_osb_payload, instance_id
|
osb_client, test_service, test_service_offering, valid_osb_payload, instance_id
|
||||||
):
|
):
|
||||||
valid_osb_payload["service_id"] = test_service.id
|
valid_osb_payload["service_id"] = test_service.osb_service_id
|
||||||
valid_osb_payload["plan_id"] = test_plan.id
|
valid_osb_payload["plan_id"] = test_service_offering.osb_plan_id
|
||||||
valid_osb_payload["parameters"]["users"] = []
|
valid_osb_payload["parameters"]["users"] = []
|
||||||
|
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(valid_osb_payload),
|
data=json.dumps(valid_osb_payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -256,17 +256,17 @@ def test_empty_users_array_error(
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_multiple_users_error(
|
def test_multiple_users_error(
|
||||||
osb_client, test_service, test_plan, valid_osb_payload, instance_id
|
osb_client, test_service, test_service_offering, valid_osb_payload, instance_id
|
||||||
):
|
):
|
||||||
valid_osb_payload["service_id"] = test_service.id
|
valid_osb_payload["service_id"] = test_service.osb_service_id
|
||||||
valid_osb_payload["plan_id"] = test_plan.id
|
valid_osb_payload["plan_id"] = test_service_offering.osb_plan_id
|
||||||
valid_osb_payload["parameters"]["users"] = [
|
valid_osb_payload["parameters"]["users"] = [
|
||||||
{"email": "user1@example.com", "full_name": "User One"},
|
{"email": "user1@example.com", "full_name": "User One"},
|
||||||
{"email": "user2@example.com", "full_name": "User Two"},
|
{"email": "user2@example.com", "full_name": "User Two"},
|
||||||
]
|
]
|
||||||
|
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(valid_osb_payload),
|
data=json.dumps(valid_osb_payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -278,16 +278,16 @@ def test_multiple_users_error(
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_empty_email_address_error(
|
def test_empty_email_address_error(
|
||||||
osb_client, test_service, test_plan, valid_osb_payload, instance_id
|
osb_client, test_service, test_service_offering, valid_osb_payload, instance_id
|
||||||
):
|
):
|
||||||
valid_osb_payload["service_id"] = test_service.id
|
valid_osb_payload["service_id"] = test_service.osb_service_id
|
||||||
valid_osb_payload["plan_id"] = test_plan.id
|
valid_osb_payload["plan_id"] = test_service_offering.osb_plan_id
|
||||||
valid_osb_payload["parameters"]["users"] = [
|
valid_osb_payload["parameters"]["users"] = [
|
||||||
{"email": "", "full_name": "User With No Email"},
|
{"email": "", "full_name": "User With No Email"},
|
||||||
]
|
]
|
||||||
|
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(valid_osb_payload),
|
data=json.dumps(valid_osb_payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -300,7 +300,7 @@ def test_empty_email_address_error(
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_invalid_json_error(osb_client, instance_id):
|
def test_invalid_json_error(osb_client, instance_id):
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data="invalid json{",
|
data="invalid json{",
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -315,17 +315,17 @@ def test_user_creation_with_name_parsing(
|
||||||
mock_odoo_success,
|
mock_odoo_success,
|
||||||
osb_client,
|
osb_client,
|
||||||
test_service,
|
test_service,
|
||||||
test_plan,
|
test_service_offering,
|
||||||
valid_osb_payload,
|
valid_osb_payload,
|
||||||
exoscale_origin,
|
exoscale_origin,
|
||||||
instance_id,
|
instance_id,
|
||||||
):
|
):
|
||||||
valid_osb_payload["service_id"] = test_service.id
|
valid_osb_payload["service_id"] = test_service.osb_service_id
|
||||||
valid_osb_payload["plan_id"] = test_plan.id
|
valid_osb_payload["plan_id"] = test_service_offering.osb_plan_id
|
||||||
valid_osb_payload["parameters"]["users"][0]["full_name"] = "John Doe Smith"
|
valid_osb_payload["parameters"]["users"][0]["full_name"] = "John Doe Smith"
|
||||||
|
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(valid_osb_payload),
|
data=json.dumps(valid_osb_payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -341,17 +341,17 @@ def test_email_normalization(
|
||||||
mock_odoo_success,
|
mock_odoo_success,
|
||||||
osb_client,
|
osb_client,
|
||||||
test_service,
|
test_service,
|
||||||
test_plan,
|
test_service_offering,
|
||||||
valid_osb_payload,
|
valid_osb_payload,
|
||||||
exoscale_origin,
|
exoscale_origin,
|
||||||
instance_id,
|
instance_id,
|
||||||
):
|
):
|
||||||
valid_osb_payload["service_id"] = test_service.id
|
valid_osb_payload["service_id"] = test_service.osb_service_id
|
||||||
valid_osb_payload["plan_id"] = test_plan.id
|
valid_osb_payload["plan_id"] = test_service_offering.osb_plan_id
|
||||||
valid_osb_payload["parameters"]["users"][0]["email"] = " TEST@EXAMPLE.COM "
|
valid_osb_payload["parameters"]["users"][0]["email"] = " TEST@EXAMPLE.COM "
|
||||||
|
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(valid_osb_payload),
|
data=json.dumps(valid_osb_payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -366,16 +366,16 @@ def test_odoo_integration_failure_handling(
|
||||||
mock_odoo_failure,
|
mock_odoo_failure,
|
||||||
osb_client,
|
osb_client,
|
||||||
test_service,
|
test_service,
|
||||||
test_plan,
|
test_service_offering,
|
||||||
valid_osb_payload,
|
valid_osb_payload,
|
||||||
exoscale_origin,
|
exoscale_origin,
|
||||||
instance_id,
|
instance_id,
|
||||||
):
|
):
|
||||||
valid_osb_payload["service_id"] = test_service.id
|
valid_osb_payload["service_id"] = test_service.osb_service_id
|
||||||
valid_osb_payload["plan_id"] = test_plan.id
|
valid_osb_payload["plan_id"] = test_service_offering.osb_plan_id
|
||||||
|
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(valid_osb_payload),
|
data=json.dumps(valid_osb_payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
@ -387,11 +387,16 @@ def test_odoo_integration_failure_handling(
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_organization_creation_with_context_only(
|
def test_organization_creation_with_context_only(
|
||||||
mock_odoo_success, osb_client, test_service, test_plan, exoscale_origin, instance_id
|
mock_odoo_success,
|
||||||
|
osb_client,
|
||||||
|
test_service,
|
||||||
|
test_service_offering,
|
||||||
|
exoscale_origin,
|
||||||
|
instance_id,
|
||||||
):
|
):
|
||||||
payload = {
|
payload = {
|
||||||
"service_id": test_service.id,
|
"service_id": test_service.osb_service_id,
|
||||||
"plan_id": test_plan.id,
|
"plan_id": test_service_offering.osb_plan_id,
|
||||||
"context": {
|
"context": {
|
||||||
"organization_guid": "fallback-org-guid",
|
"organization_guid": "fallback-org-guid",
|
||||||
"organization_name": "Fallback Organization",
|
"organization_name": "Fallback Organization",
|
||||||
|
|
@ -407,7 +412,7 @@ def test_organization_creation_with_context_only(
|
||||||
}
|
}
|
||||||
|
|
||||||
response = osb_client.put(
|
response = osb_client.put(
|
||||||
f"/v2/service_instances/{instance_id}",
|
f"/api/osb/v2/service_instances/{instance_id}",
|
||||||
data=json.dumps(payload),
|
data=json.dumps(payload),
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue