Metadata-Version: 2.4
Name: devnomads-cli
Version: 0.5.1
Summary: Manage your DevNomads services from the command line
Author-email: DevNomads <support@devnomads.nl>
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: typer>=0.12
Requires-Dist: httpx>=0.27
Requires-Dist: rich>=13
Requires-Dist: cryptography>=42
Requires-Dist: devnomads[acme]>=0.2.3
Dynamic: license-file

# dncli

Manage your [DevNomads](https://devnomads.nl) services from the
command line: inspect your services, manage DNS zones and records,
and move zones over from other providers - from a shell or a script.

The command is **`dncli`** - named to avoid clashing with the macOS
`dnctl` traffic-shaper at `/usr/sbin/dnctl`. Install it from PyPI
as **`devnomads-cli`**.

## Install

```sh
pip install devnomads-cli
```

For a global, isolated install (recommended on workstations), use
[uv](https://docs.astral.sh/uv/) or pipx instead - same result, no
interference with system packages:

```sh
uv tool install devnomads-cli   # or: pipx install devnomads-cli
```

Enable shell completion (bash, zsh, fish, PowerShell):

```sh
dncli --install-completion
```

## Getting started

Create an API key in the [DevNomads
portal](https://portal.devnomads.nl) under **Profiel -> API
Sleutels**, then store it:

```sh
dncli configure
```

The key is written to `~/.config/dncli/credentials`, readable only
by you. From here every command works:

```sh
dncli services list
dncli domains list
dncli containers show <id>
```

Every DevNomads product has its own command group - `apps`,
`buckets`, `containers`, `databases`, `domains`, `emails`,
`forwards`, `proxies`, `servers`, `sites` and more. Explore with
`dncli --help` and `dncli <group> --help`.

Commands accept any unambiguous prefix: `dncli e l` is `dncli emails
list`. An ambiguous prefix lists the candidates.

## Managing DNS

```sh
dncli dns zones list
dncli dns zones show example.com
dncli dns records list example.com
dncli dns records set example.com www A 192.0.2.1 --ttl 3600
dncli dns records delete example.com www A
```

## Moving a zone from another provider

`dncli dns transfer` copies a zone from your current DNS provider
into DevNomads. It reads the records at the source (never writes
there), shows you the changes, and applies them after confirmation:

```sh
dncli configure --provider transip       # store source credentials
dncli dns transfer --from transip --zone example.com --dry-run
dncli dns transfer --from transip --zone example.com
```

Supported source providers: TransIP and AuroraDNS. The zone must
already exist at DevNomads; register or transfer the domain in the
portal first.

## Multiple accounts

Store each account as a named profile and select it per command or
per shell:

```sh
dncli configure --profile acme
dncli services list --profile acme
export DN_PROFILE=acme
```

## Scripting

Output is a human-readable table on a terminal and JSON when piped,
so pipelines get parseable output without any flags; `--output
json|table` forces either. Data goes to stdout, everything else
(warnings, prompts, status messages) to stderr, so `dncli ... | jq .`
is always safe.

In CI and pipelines, skip the credentials file and pass the key via
the environment:

```sh
export DN_API_KEY=...        # beats any stored profile
dncli services list | jq -r '.[].entity'
```

## Certificates

`dncli` issues Let's Encrypt certificates using the DNS-01 challenge:

```sh
dncli cert issue example.com -d www.example.com -d "*.example.com"
```

The first argument is the primary domain (the certificate CN); add
extra names (SANs) by repeating `--san`/`-d`. Every name must live in
one of your DevNomads DNS zones, and that zone must be delegated to the
DevNomads nameservers (`one.dns.infrapod.nl`, `two.dns.infrapod.nl`,
`three.dns.infrapod.eu`) - otherwise issuance is refused, since the
DNS-01 challenge records would not be visible to the CA.

The certificate is always written to `~/.config/dncli/certs/<domain>/`
as `cert.pem`, `fullchain.pem`, `chain.pem`, and `privkey.pem` (0600).
Pass `--out <file>` to additionally export a single PEM bundle of
exactly three blocks - the key, the certificate, and the issuing
intermediate, in that order. Add `-v`/`--verbose` for detailed ACME
progress.

Keys are ECDSA P-384 by default. Pick another with `--key-type`
(`ecdsa256`, `ecdsa384`, `ecdsa521`, `rsa2048`, `rsa4096`).

Re-running `cert issue` is a no-op while the existing certificate is
still valid for more than 21 days; pass `--force` to re-issue anyway.

List what you have issued and re-export any of them - as a PEM bundle
or a PKCS#12 (`.pfx`) file - without re-issuing:

```sh
dncli cert list
dncli cert export example.com --out bundle.pem    # omit --out to print
dncli cert export example.com --format pfx --out bundle.pfx
dncli cert export example.com --format pfx --out bundle.pfx --passphrase secret
```

The `.pfx` is unencrypted unless you pass `--passphrase` (alias
`--password`). Both bundle formats carry the same three items: key,
certificate, and the issuing intermediate.

A dehydrated-compatible DNS-01 hook ships as `dncli-dns-hook`:

```sh
# dehydrated/config
CHALLENGETYPE="dns-01"
HOOK="dncli-dns-hook"
```

## License

MIT.
