Files
govoplan-files/dev/connectors/README.md
T

181 lines
6.2 KiB
Markdown

# Connector Dev Stack
This directory keeps local Docker Compose assets for GovOPlaN file connector
development. The stack is intentionally separate from production deployment and
binds services to localhost high ports.
## Start
```bash
cd /mnt/DATA/git/govoplan-files/dev/connectors
cp .env.example .env
mkdir -p data/smb data/webdav
docker compose up -d nextcloud nextcloud-db webdav smb minio
docker compose up -d seafile-db seafile-memcached seafile
```
If the SMB service was already running before a compose change, recreate it so
the image and share configuration are applied:
```bash
docker compose rm -sf smb
docker compose up -d --build smb
```
Endpoints:
- Nextcloud: `http://127.0.0.1:9081`, WebDAV root
`http://127.0.0.1:9081/remote.php/dav/files/admin/`
- Seafile: `http://127.0.0.1:9082`, WebDAV root
`http://127.0.0.1:9082/seafdav/`
- WebDAV: `http://127.0.0.1:9083`
- SMB: `smb://127.0.0.1:1445/files`
- MinIO/S3 API: `http://127.0.0.1:9000`, console
`http://127.0.0.1:9001`
The local fixture data under `data/` is ignored by git.
## GovOPlaN Profile Config
Connector profiles are read from `GOVOPLAN_FILES_CONNECTOR_PROFILES_JSON` or
`GOVOPLAN_FILES_CONNECTOR_PROFILES_FILE`. This deployment-owned configuration
may reference environment variables only when their exact names are listed in
`GOVOPLAN_CONNECTOR_SECRET_ENV_ALLOWLIST`; profile API responses expose only the
credential source and configured state.
Example local profile file:
```json
{
"profiles": [
{
"id": "dev-seafile",
"label": "Dev Seafile",
"provider": "seafile",
"endpoint_url": "http://127.0.0.1:9082",
"scope_type": "system",
"credential_mode": "basic",
"username": "admin@example.local",
"password_env": "SEAFILE_ADMIN_PASSWORD",
"capabilities": ["browse", "import"],
"metadata": { "webdav_endpoint_url": "http://127.0.0.1:9082/seafdav/" },
"policy": { "allow": { "providers": ["seafile"] } }
},
{
"id": "dev-nextcloud",
"label": "Dev Nextcloud",
"provider": "nextcloud",
"endpoint_url": "http://127.0.0.1:9081/remote.php/dav/files/admin/",
"scope_type": "system",
"credential_mode": "basic",
"username": "admin",
"password_env": "NEXTCLOUD_ADMIN_PASSWORD",
"capabilities": ["browse", "import"],
"policy": { "allow": { "providers": ["nextcloud", "webdav"] } }
},
{
"id": "dev-webdav",
"label": "Dev WebDAV",
"provider": "webdav",
"endpoint_url": "http://127.0.0.1:9083",
"scope_type": "system",
"credential_mode": "basic",
"username": "govoplan",
"password_env": "WEBDAV_PASSWORD",
"capabilities": ["browse", "import"],
"policy": { "allow": { "providers": ["webdav"] } }
},
{
"id": "dev-smb",
"label": "Dev SMB",
"provider": "smb",
"endpoint_url": "smb://127.0.0.1:1445/files",
"scope_type": "system",
"credential_mode": "basic",
"username": "govoplan",
"password_env": "SMB_PASSWORD",
"capabilities": ["browse", "import"],
"policy": { "allow": { "providers": ["smb"] } }
},
{
"id": "dev-s3",
"label": "Dev MinIO",
"provider": "s3",
"endpoint_url": "http://127.0.0.1:9000",
"base_path": "",
"scope_type": "system",
"credential_mode": "basic",
"username": "govoplan",
"password_env": "MINIO_ROOT_PASSWORD",
"capabilities": ["browse", "import"],
"metadata": {
"bucket": "govoplan",
"region": "us-east-1",
"path_style": true,
"verify_tls": false
},
"policy": { "allow": { "providers": ["s3"] } }
}
]
}
```
Start GovOPlaN with:
```bash
export GOVOPLAN_FILES_CONNECTOR_PROFILES_FILE=/mnt/DATA/git/govoplan-files/dev/connectors/profiles.local.json
export GOVOPLAN_CONNECTOR_SECRET_ENV_ALLOWLIST=SEAFILE_ADMIN_PASSWORD,NEXTCLOUD_ADMIN_PASSWORD,WEBDAV_PASSWORD,SMB_PASSWORD,MINIO_ROOT_PASSWORD
export GOVOPLAN_CONNECTOR_ALLOW_PRIVATE_NETWORKS=true
```
## Smoke Test
Run the connector helper smoke checks from an environment where
`govoplan-files` and `httpx` are importable:
```bash
cd /mnt/DATA/git/govoplan-files/dev/connectors
/mnt/DATA/git/govoplan-core/.venv/bin/python smoke.py
```
The script reads `.env` from this directory when present and seeds tiny WebDAV,
Nextcloud, SMB, and MinIO fixtures. WebDAV and Nextcloud use the pinned HTTP
transport. SMB uses the Files-owned `smbprotocol` connection cache so initial
connections, reconnects, aliases, and DFS referral targets are pinned. S3 uses
pinned botocore pools for retries, redirects, discovery, and aliases. Every
socket destination is revalidated when it opens, including when private-network
access is enabled for these local fixtures.
SMB and S3 are optional by default: a missing provider dependency or unavailable
target is reported as `SKIP`. Use `--require-smb` and `--require-s3` to turn such
provider failures into a non-zero smoke result during deployment validation. The
bundled Samba service is a deterministic single-share target, not a DFS
topology. Referral and reconnect behavior is covered by the transport contract
tests; deployments using DFS must additionally run the required SMB smoke check
against their actual referral topology and record the resolved peers.
SMB smoke checks need the optional Python dependency in the environment running
the script:
```bash
/mnt/DATA/git/govoplan-core/.venv/bin/python -m pip install -e /mnt/DATA/git/govoplan-files[smb]
```
S3 smoke checks need the optional boto3 dependency in the environment running
the script:
```bash
/mnt/DATA/git/govoplan-core/.venv/bin/python -m pip install -e /mnt/DATA/git/govoplan-files[s3]
```
The SMB service is built from `dev/connectors/smb/` so the development share is
deterministic: one `files` share backed by `data/smb`, with the credentials from
`.env`.
The SMB image runs as the non-root `govoplan` user with UID/GID `1000` and
listens on unprivileged container port `1445`. The default host endpoint remains
`smb://127.0.0.1:1445/files`. `SMB_USER` must stay `govoplan` unless the image is
rebuilt with a matching user; `SMB_PORT` must be `1024` or higher. `SMB_PASSWORD`
is applied when the image is built, so rebuild the `smb` service after changing
it in `.env`.