Implement Exoscale onboarding API endpoint #199

Merged
rixx merged 14 commits from 37-exoscale-onboarding into main 2025-10-03 07:04:44 +00:00
5 changed files with 64 additions and 71 deletions
Showing only changes of commit 0a591f352a - Show all commits

View file

@ -11,7 +11,6 @@ from servala.core.models import (
Organization, Organization,
OrganizationMembership, OrganizationMembership,
OrganizationOrigin, OrganizationOrigin,
Plan,
Service, Service,
ServiceCategory, ServiceCategory,
ServiceDefinition, ServiceDefinition,
@ -99,11 +98,6 @@ class ServiceCategoryAdmin(admin.ModelAdmin):
autocomplete_fields = ("parent",) autocomplete_fields = ("parent",)
class PlanInline(admin.TabularInline):
model = Plan
extra = 1
@admin.register(Service) @admin.register(Service)
class ServiceAdmin(admin.ModelAdmin): class ServiceAdmin(admin.ModelAdmin):
list_display = ("name", "category") list_display = ("name", "category")
@ -230,14 +224,6 @@ class ControlPlaneAdmin(admin.ModelAdmin):
test_kubernetes_connection.short_description = _("Test Kubernetes connection") test_kubernetes_connection.short_description = _("Test Kubernetes connection")
@admin.register(Plan)
class PlanAdmin(admin.ModelAdmin):
list_display = ("name", "service_offering", "term")
list_filter = ("service_offering", "term")
search_fields = ("name", "description")
autocomplete_fields = ("service_offering",)
@admin.register(ServiceDefinition) @admin.register(ServiceDefinition)
class ServiceDefinitionAdmin(admin.ModelAdmin): class ServiceDefinitionAdmin(admin.ModelAdmin):
form = ServiceDefinitionAdminForm form = ServiceDefinitionAdminForm
@ -317,7 +303,4 @@ class ServiceOfferingAdmin(admin.ModelAdmin):
list_filter = ("service", "provider") list_filter = ("service", "provider")
search_fields = ("description",) search_fields = ("description",)
autocomplete_fields = ("service", "provider") autocomplete_fields = ("service", "provider")
inlines = ( inlines = (ControlPlaneCRDInline,)
ControlPlaneCRDInline,
PlanInline,
)

View file

@ -1,22 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("core", "0007_controlplane_user_info_and_more"),
]
operations = [
migrations.AddField(
model_name="organization",
name="osb_guid",
field=models.CharField(
blank=True,
help_text="Open Service Broker GUID, used for organizations created via OSB API",
max_length=100,
null=True,
verbose_name="OSB GUID",
),
),
]

View file

@ -0,0 +1,49 @@
# Generated by Django 5.2.6 on 2025-10-02 07:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("core", "0007_controlplane_user_info_and_more"),
]
operations = [
migrations.AddField(
model_name="organization",
name="osb_guid",
field=models.CharField(
blank=True,
help_text="Open Service Broker GUID, used for organizations created via OSB API",
max_length=100,
null=True,
verbose_name="OSB GUID",
),
),
migrations.AddField(
model_name="service",
name="osb_service_id",
field=models.CharField(
blank=True,
help_text="Open Service Broker service ID for API matching",
max_length=100,
null=True,
verbose_name="OSB Service ID",
),
),
migrations.AddField(
model_name="serviceoffering",
name="osb_plan_id",
field=models.CharField(
blank=True,
help_text="Open Service Broker plan ID for API matching",
max_length=100,
null=True,
verbose_name="OSB Plan ID",
),
),
migrations.DeleteModel(
name="Plan",
),
]

View file

@ -9,7 +9,6 @@ from .service import (
CloudProvider, CloudProvider,
ControlPlane, ControlPlane,
ControlPlaneCRD, ControlPlaneCRD,
Plan,
Service, Service,
ServiceCategory, ServiceCategory,
ServiceDefinition, ServiceDefinition,
@ -27,7 +26,6 @@ __all__ = [
"OrganizationMembership", "OrganizationMembership",
"OrganizationOrigin", "OrganizationOrigin",
"OrganizationRole", "OrganizationRole",
"Plan",
"Service", "Service",
"ServiceCategory", "ServiceCategory",
"ServiceInstance", "ServiceInstance",

View file

@ -80,6 +80,13 @@ class Service(ServalaModelMixin, models.Model):
"Featured links will be shown on the service list page, all other links will only show on the service and offering detail pages." "Featured links will be shown on the service list page, all other links will only show on the service and offering detail pages."
), ),
) )
osb_service_id = models.CharField(
max_length=100,
null=True,
blank=True,
verbose_name=_("OSB Service ID"),
help_text=_("Open Service Broker service ID for API matching"),
)
class Meta: class Meta:
verbose_name = _("Service") verbose_name = _("Service")
@ -297,35 +304,6 @@ class CloudProvider(ServalaModelMixin, models.Model):
return self.name return self.name
class Plan(ServalaModelMixin, models.Model):
"""
Each service offering can have multiple plans, e.g. for different tiers.
"""
name = models.CharField(max_length=100, verbose_name=_("Name"))
description = models.TextField(blank=True, verbose_name=_("Description"))
# TODO schema
features = models.JSONField(verbose_name=_("Features"), null=True, blank=True)
# TODO schema
pricing = models.JSONField(verbose_name=_("Pricing"), null=True, blank=True)
term = models.PositiveIntegerField(
verbose_name=_("Term"), help_text=_("Term in months")
)
service_offering = models.ForeignKey(
to="ServiceOffering",
on_delete=models.PROTECT,
related_name="plans",
verbose_name=_("Service offering"),
)
class Meta:
verbose_name = _("Plan")
verbose_name_plural = _("Plans")
def __str__(self):
return self.name
def validate_api_definition(value): def validate_api_definition(value):
required_fields = ("group", "version", "kind") required_fields = ("group", "version", "kind")
return validate_dict(value, required_fields) return validate_dict(value, required_fields)
@ -533,6 +511,13 @@ class ServiceOffering(ServalaModelMixin, models.Model):
verbose_name=_("Provider"), verbose_name=_("Provider"),
) )
description = models.TextField(blank=True, verbose_name=_("Description")) description = models.TextField(blank=True, verbose_name=_("Description"))
osb_plan_id = models.CharField(
max_length=100,
null=True,
blank=True,
verbose_name=_("OSB Plan ID"),
help_text=_("Open Service Broker plan ID for API matching"),
)
class Meta: class Meta:
verbose_name = _("Service offering") verbose_name = _("Service offering")