Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@
from dstack._internal.server.services.pipelines import PipelineHinterProtocol
from dstack._internal.server.services.runs import get_run_spec
from dstack._internal.server.services.services import (
get_gateway_https,
should_configure_service_https_on_gateway,
should_configure_gateway_endpoint_https_on_gateway_replica,
should_configure_service_https_on_gateway_replica,
)
from dstack._internal.server.utils import tracing
from dstack._internal.utils.common import get_current_datetime, get_or_error, run_async
Expand Down Expand Up @@ -1280,8 +1280,12 @@ async def _register_service(
run_id=run_model.id,
run_name=run_model.run_name,
domain=domain,
service_https=should_configure_service_https_on_gateway(run_spec, gateway_configuration),
gateway_https=get_gateway_https(gateway_configuration),
service_https=should_configure_service_https_on_gateway_replica(
run_spec, gateway_configuration
),
gateway_https=should_configure_gateway_endpoint_https_on_gateway_replica(
gateway_configuration
),
auth=run_spec.configuration.auth,
client_max_body_size=settings.DEFAULT_SERVICE_CLIENT_MAX_BODY_SIZE,
options=service_spec.options,
Expand Down
24 changes: 11 additions & 13 deletions src/dstack/_internal/server/services/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,6 @@ async def _assign_service_to_gateway(
"Cannot run HTTPS service on gateway with no SSL certificates configured"
)

gateway_https = get_gateway_https(gateway_configuration)
gateway_protocol = "https" if gateway_https else "http"

wildcard_domain = gateway.wildcard_domain.lstrip("*.") if gateway.wildcard_domain else None
if wildcard_domain is None:
raise ServerClientError("Domain is required for gateway")
Expand All @@ -146,6 +143,7 @@ async def _assign_service_to_gateway(
if isinstance(run_spec.configuration.model, OpenAIChatModel):
model_url = service_url + run_spec.configuration.model.prefix
else:
gateway_protocol = "https" if gateway_configuration.certificate is not None else "http"
model_url = f"{gateway_protocol}://gateway.{wildcard_domain}"
service_spec = _get_service_spec(
configuration=run_spec.configuration,
Expand Down Expand Up @@ -220,11 +218,11 @@ def _get_service_spec(
return service_spec


def should_configure_service_https_on_gateway(
def should_configure_service_https_on_gateway_replica(
run_spec: RunSpec, configuration: GatewayConfiguration
) -> bool:
"""
Returns `True` if the gateway needs to serve the service with HTTPS.
Returns `True` if the gateway replica needs to serve the service with HTTPS.
May be `False` for HTTPS services, e.g. SSL termination is done on a load balancer.
"""
assert run_spec.configuration.type == "service"
Expand All @@ -244,6 +242,14 @@ def should_configure_service_https_on_gateway(
return True


def should_configure_gateway_endpoint_https_on_gateway_replica(
configuration: GatewayConfiguration,
) -> bool:
return (
configuration.certificate is not None and configuration.certificate.type == "lets-encrypt"
)


def _should_show_service_https(run_spec: RunSpec, configuration: GatewayConfiguration) -> bool:
"""
Returns `True` if the service needs to be accessed via https://.
Expand All @@ -257,11 +263,3 @@ def _should_show_service_https(run_spec: RunSpec, configuration: GatewayConfigur
return False
return True
return https


def get_gateway_https(configuration: GatewayConfiguration) -> bool:
if is_tls_terminated_at_load_balancer(configuration.certificate):
return False
if configuration.certificate is not None and configuration.certificate.type == "lets-encrypt":
return True
return False
14 changes: 7 additions & 7 deletions src/tests/_internal/server/services/services/test_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from dstack._internal.core.models.runs import RunSpec
from dstack._internal.server.services.services import (
_should_show_service_https,
should_configure_service_https_on_gateway,
should_configure_service_https_on_gateway_replica,
)
from dstack._internal.server.testing.common import get_run_spec

Expand Down Expand Up @@ -55,36 +55,36 @@ class TestShouldConfigureServiceHttpsOnGateway:
def test_auto_resolves_to_true_with_lets_encrypt_gateway(self) -> None:
run_spec = _service_run_spec(https="auto")
gw = _gateway_config(certificate=LetsEncryptGatewayCertificate())
assert should_configure_service_https_on_gateway(run_spec, gw) is True
assert should_configure_service_https_on_gateway_replica(run_spec, gw) is True

def test_auto_resolves_to_false_when_gateway_has_no_certificate(self) -> None:
run_spec = _service_run_spec(https="auto")
gw = _gateway_config(certificate=None)
assert should_configure_service_https_on_gateway(run_spec, gw) is False
assert should_configure_service_https_on_gateway_replica(run_spec, gw) is False

def test_auto_resolves_to_false_with_acm_gateway(self) -> None:
run_spec = _service_run_spec(https="auto")
gw = _gateway_config(
certificate=ACMGatewayCertificate(arn="arn:aws:acm:us-east-1:123:cert/abc")
)
assert should_configure_service_https_on_gateway(run_spec, gw) is False
assert should_configure_service_https_on_gateway_replica(run_spec, gw) is False

def test_true_enables_https_when_gateway_has_no_certificate(self) -> None:
run_spec = _service_run_spec(https=True)
gw = _gateway_config(certificate=None)
assert should_configure_service_https_on_gateway(run_spec, gw) is True
assert should_configure_service_https_on_gateway_replica(run_spec, gw) is True

def test_false_disables_https_regardless_of_gateway_certificate(self) -> None:
run_spec = _service_run_spec(https=False)
gw = _gateway_config(certificate=LetsEncryptGatewayCertificate())
assert should_configure_service_https_on_gateway(run_spec, gw) is False
assert should_configure_service_https_on_gateway_replica(run_spec, gw) is False

def test_true_does_not_configure_https_on_acm_gateway(self) -> None:
run_spec = _service_run_spec(https=True)
gw = _gateway_config(
certificate=ACMGatewayCertificate(arn="arn:aws:acm:us-east-1:123:cert/abc")
)
assert should_configure_service_https_on_gateway(run_spec, gw) is False
assert should_configure_service_https_on_gateway_replica(run_spec, gw) is False


class TestShouldShowServiceHttps:
Expand Down
Loading