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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.32.4] - 2026-06-05

### Added
- **README: "Local / IP-based deployment (no domain, no TLS)" section.** Consolidates the rules for evaluating the Endpoint on a bare IP/`localhost` without a domain or certificate: use `http://` not `https://`, use the host's real IP (not internal overlay/pod addresses), the correct ports, profiles without Pelican, rebuilding after updates, and the Kafka/streaming reachability caveat (the Endpoint returns the configured `KAFKA_HOST`/`KAFKA_PORT` verbatim, so clients outside the Docker network need externally reachable values, not internal names like `kafka:9093`).

### Changed
- **Python client and demo-slide examples clarify `http` vs `https`.** The `https://…` `base_url` examples in the automation guide and the demo presentation now note that `https` assumes a real domain with a TLS certificate, and that a bare IP/`localhost` deployment should use `http://`.

### Backwards compatibility
- Documentation only. No API behavior, request/response shapes, or routes change.

## [0.32.3] - 2026-06-05

### Fixed
Expand Down
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,41 @@ PRE_CKAN_API_KEY=your-ndp-preckan-api-key
PRE_CKAN_ORGANIZATION=ep-your-assigned-org-id
```

### 6. Local / IP-based deployment (no domain, no TLS)

If you are evaluating the Endpoint on a plain VM or workstation reached by its
**IP address** (or `localhost`) and you do **not** have a domain name or a TLS
certificate, follow these rules — most first-run problems come from assuming a
domain/HTTPS setup that isn't there:

- **Use `http://`, not `https://`.** A bare IP address cannot present a valid
TLS certificate, so `https://<ip>` fails. This applies to the browser URLs
**and** to the `base_url`/`API_URL` you pass to the Python client, the
streaming client, etc. The `https://my-endpoint…` examples elsewhere in the
docs and slides assume a real domain with a certificate.
- **Use the host's real IP or `localhost`** — not an internal overlay/pod
address (e.g. `10.244.x.x`), which is not reachable from your machine.
- **Pick the right port.** `docker run -p 8001:80` → `http://<host>:8001`;
`docker compose` publishes the API on host port **8002** by default →
`http://<host>:8002`. The container always serves on port 80 internally.
- **Start only the profiles you need** (e.g. `--profile mongodb --profile s3`).
Avoid `--profile full` / `--profile pelican`: the Pelican services need extra
TLS/federation setup and will restart-loop on a fresh machine.
- **Rebuild after updating code** (`docker compose build --no-cache api`, or
`docker pull rbardaji/ndp-ep-api:latest`) — `docker compose up` reuses the
old image otherwise.
- **Kafka / streaming reachability.** The Endpoint hands streaming clients the
`KAFKA_HOST`/`KAFKA_PORT` you configured, **verbatim** (via
`GET /status/kafka-details`). If your client runs **outside** the Docker
network (for example, a notebook on your laptop), those values must be the
**externally reachable** address — the host's IP/hostname and the
externally-published Kafka port — **not** an internal Docker service name
(`kafka`) or an internal-only port. Internal names like `kafka:9093` only
resolve between containers on the same Docker network.

Verify with the `http://` URLs from [Verify Installation](#4-verify-installation)
(`/docs`, `/ui/`, `/health`).

## 🔒 Group-Based Access Control

The API supports optional group-based access control to restrict write operations (POST, PUT, DELETE) to users belonging to specific groups.
Expand Down
2 changes: 1 addition & 1 deletion api/config/swagger_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Settings(BaseSettings):

swagger_title: str = "API Documentation"
swagger_description: str = "This is the API documentation."
swagger_version: str = "0.32.3"
swagger_version: str = "0.32.4"
root_path: str = "" # API root path prefix (e.g., "/test" or "")
is_public: bool = True
metrics_endpoint: str = "https://federation.ndp.utah.edu/metrics/"
Expand Down
1 change: 1 addition & 0 deletions docs/demo/NDP-demo-presentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ pip install ndp-ep
from ndp_ep import APIClient

# 1. Connect to the Endpoint with your token
# (https assumes a real domain + TLS cert; on a bare IP/localhost use http://)
client = APIClient(base_url="https://my-endpoint/ep-api", token="…")

# 2. List organizations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ client.get_token(username="me@my-institution.edu", password="…")
client honours the Endpoint's role checks — what your token can do from code is
exactly what your account can do from the web.

> **`http` vs `https`:** the `https://…` examples above assume the Endpoint is
> served on a real domain with a valid TLS certificate. If you reach it by a
> bare **IP address** (or `localhost`) without a certificate, use `http://`
> instead (e.g. `base_url="http://<host-ip>:8002"`) — `https://<ip>` will fail
> because an IP cannot present a valid certificate.

## Common operations

```python
Expand Down
Loading