Initial curated ITWorx_MCP_Hub source from 368fba691ea8d23403b4d56b53b5ec670d7c5020
This commit is contained in:
commit
cb5be898ea
663 files changed
+82674
No files matched your search
@@ -0,0 +1,133 @@
|
||||
"""Read-only alias projection from Hub-owned persistence."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from typing import Any, cast
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from pydantic import AnyHttpUrl, TypeAdapter
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from packages.hub_contracts.dataplane import (
|
||||
SUPPORTED_PROTOCOLS,
|
||||
AliasRecord,
|
||||
ClientBinding,
|
||||
EnvironmentName,
|
||||
)
|
||||
|
||||
from .models import (
|
||||
ClientBindingRow,
|
||||
ClientRow,
|
||||
EnvironmentRow,
|
||||
ProjectRow,
|
||||
VirtualServerRow,
|
||||
)
|
||||
|
||||
|
||||
class SqlAlchemyAliasSource:
|
||||
"""Projects only enabled Hub virtual servers and active explicit bindings."""
|
||||
|
||||
def __init__(self, session: Session, *, workspace_id: Any, gateway_base_url: str) -> None:
|
||||
self.session = session
|
||||
self.workspace_id = workspace_id
|
||||
base = TypeAdapter(AnyHttpUrl).validate_python(gateway_base_url)
|
||||
internal_contextforge = (
|
||||
base.scheme == "http"
|
||||
and base.host in {"contextforge", "contextforge-control"}
|
||||
and base.port == 4444
|
||||
and (base.path or "").rstrip("/") == "/mcp"
|
||||
)
|
||||
if (
|
||||
base.username is not None
|
||||
or base.password is not None
|
||||
or (base.scheme != "https" and not internal_contextforge)
|
||||
):
|
||||
raise ValueError("gateway URL must be HTTPS or the fixed internal gateway")
|
||||
self.gateway_base_url = str(base).rstrip("/")
|
||||
self.internal_contextforge = internal_contextforge
|
||||
|
||||
def aliases(self) -> tuple[AliasRecord, ...]:
|
||||
projects = {
|
||||
row.id: row
|
||||
for row in self.session.scalars(
|
||||
select(ProjectRow).where(ProjectRow.workspace_id == self.workspace_id)
|
||||
).all()
|
||||
}
|
||||
environments = {
|
||||
row.id: row
|
||||
for row in self.session.scalars(
|
||||
select(EnvironmentRow).where(EnvironmentRow.workspace_id == self.workspace_id)
|
||||
).all()
|
||||
}
|
||||
clients = {
|
||||
row.id: row
|
||||
for row in self.session.scalars(
|
||||
select(ClientRow).where(ClientRow.workspace_id == self.workspace_id)
|
||||
).all()
|
||||
}
|
||||
bindings_by_server: dict[Any, list[ClientBinding]] = defaultdict(list)
|
||||
for row in self.session.scalars(
|
||||
select(ClientBindingRow).where(
|
||||
ClientBindingRow.workspace_id == self.workspace_id,
|
||||
ClientBindingRow.enabled.is_(True),
|
||||
)
|
||||
).all():
|
||||
client = clients.get(row.client_id)
|
||||
if client is None or client.status != "active":
|
||||
continue
|
||||
bindings_by_server[row.virtual_server_id].append(
|
||||
ClientBinding(
|
||||
client_id=client.id,
|
||||
issuer=client.issuer,
|
||||
subject=client.subject,
|
||||
enabled=True,
|
||||
)
|
||||
)
|
||||
values: list[AliasRecord] = []
|
||||
for server in self.session.scalars(
|
||||
select(VirtualServerRow).where(
|
||||
VirtualServerRow.workspace_id == self.workspace_id,
|
||||
VirtualServerRow.enabled.is_(True),
|
||||
VirtualServerRow.health_state.in_(("healthy", "degraded")),
|
||||
)
|
||||
).all():
|
||||
if self.internal_contextforge and not server.gateway_external_id:
|
||||
continue
|
||||
project = projects.get(server.project_id)
|
||||
environment = environments.get(server.environment_id)
|
||||
if project is None or environment is None:
|
||||
continue
|
||||
if environment.name not in {"dev", "test", "staging", "prod"}:
|
||||
continue
|
||||
metadata = server.record_metadata
|
||||
endpoint_alias = metadata.get("endpointAlias") if isinstance(metadata, dict) else None
|
||||
if not isinstance(endpoint_alias, str):
|
||||
endpoint_alias = f"/mcp/{project.slug}/{environment.name}"
|
||||
try:
|
||||
if self.internal_contextforge:
|
||||
external_id = server.gateway_external_id or ""
|
||||
if not re.fullmatch(r"[0-9a-f]{32}", external_id):
|
||||
raise ValueError("invalid ContextForge server route identifier")
|
||||
parsed = urlsplit(self.gateway_base_url)
|
||||
upstream = f"{parsed.scheme}://{parsed.netloc}/servers/{external_id}/mcp"
|
||||
else:
|
||||
upstream = f"{self.gateway_base_url}{endpoint_alias}"
|
||||
values.append(
|
||||
AliasRecord(
|
||||
project_slug=project.slug,
|
||||
workspace_id=self.workspace_id,
|
||||
project_id=project.id,
|
||||
environment=cast(EnvironmentName, environment.name),
|
||||
alias=endpoint_alias,
|
||||
upstream_url=TypeAdapter(AnyHttpUrl).validate_python(upstream),
|
||||
enabled=True,
|
||||
protocol_revisions=tuple(SUPPORTED_PROTOCOLS),
|
||||
bindings=tuple(bindings_by_server.get(server.id, ())),
|
||||
)
|
||||
)
|
||||
except ValueError:
|
||||
continue
|
||||
return tuple(sorted(values, key=lambda item: (item.project_slug, item.environment)))
|
||||
Reference in new issue
Block a user