-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Documentation; JSON catalogs; cli.py cleanup [some]
Add catalog.json, replacing ad-hoc lists of providers in cli.py & setup.py. catalog.py for easy use of the catalog, including loading known providers. Add sewer.json info replaces __version__.py; sewer_about in lib to access it.
- Loading branch information
Showing
17 changed files
with
793 additions
and
294 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
## Driver Catalog | ||
|
||
The driver catalog, `sewer/catalog.json`, replaces scattered facilities that | ||
were used to stitch things together. The import farms in `sewer.__init__` | ||
and `sewer.dns_providers.__init__` have already been removed; with the | ||
catalog in place, redundant lists in cli.py and setup.py are also removed, | ||
replaced by use of the catalog's data and a few lines of code. The | ||
`dns_provider_name` is deprecated in favor of the catalog as well. | ||
|
||
`catalog.py` wraps the catalog in a class, adding some convenience methods | ||
for listing the known drivers, looking up a driver's data by name, and | ||
loading a driver's implementation class by name. But using the catalog | ||
without `catalog.py` is as easy as loading it using the standard lib's json | ||
facilities - it's all lists & dicts (see eg. setup.py which loads the | ||
catalog this way to avoid potential issues with trying to call into the | ||
package's code before it's installed). | ||
|
||
### Catalog structure | ||
|
||
The catalog resides in a JSON file that loads as an array of dictionaries, | ||
one element for each registered driver. The per-driver record contains the | ||
following items (some optional): | ||
|
||
- **name** The name used to identify this driver, eg., `--provider <name>` | ||
to `sewer-cli`. These names need to be unique, but are not required to | ||
match the module or implementing class names. (legacy DNS drivers usually | ||
matched the module name, but not always) | ||
- **desc** A brief description of the driver, intended for display to humans | ||
to help them understand what each driver is, eg. in --known_providers output | ||
- **chals** list of strings for the type of challenge(s) this driver | ||
handles. (if more than one type, in order of preference?) | ||
- **args** A list of the driver-specific [parameters](#args-parameter-descriptors) | ||
- **path** The path to use to import the driver's Python module. | ||
_Default_ is `sewer.providers.{name}` | ||
- **cls** Name of module attribute which is called with parameters to get a | ||
working instance of the driver. Usually a class, but a factory function | ||
may be used. _Default_ is `Provider`. | ||
- **features** - a list of strings that name the optional features that this | ||
driver supports. _Default_ is an empty list. | ||
- **memo** Additional text/comments about the driver, the descriptor, etc. | ||
- **deps** list of additional projects this driver requires (for setup) | ||
|
||
### args - parameter desciptors | ||
|
||
This is a bit of a mess due to legacy drivers that ignored the established | ||
conventions. To be fair to them, those conventions weren't clearly | ||
documented (then - see below). This adds some complications to preserve | ||
compatibility, as usual. Let's begin with a minimal descriptor for a driver | ||
that conforms to the new convention (hint: it's imaginary at this time): | ||
|
||
{ | ||
"name": "well_behaved", | ||
"desc": "made-up example driver that's mostly defaults", | ||
"chals": ["dns-01"], | ||
"args": [ | ||
{ "name": "api_id", "req": 1 }, | ||
{ "name": "api_key", "req": 1}, | ||
], | ||
"features": [ "alias" ], | ||
} | ||
|
||
This describes a dns-01 challenge driver that is found in the module | ||
`sewer.providers.well_behaved`, constructed from a class named `Provider`. | ||
The constructor takes two required arguments, `api_id` and `api_key`, which | ||
the program should accept from environment variables `WELL_BEHAVED_API_ID" | ||
and "WELL_BEHAVED_API_KEY". Since it is a `dns-01` challenge provider and | ||
up to date, it adds the claim that it supports the `alias` feature. It | ||
doesn't support the "unpropagated" feature - perhaps the DNS service has no | ||
API to check the propagation of changes. | ||
|
||
If this had been a difficult old legacy driver, the descriptor might have | ||
looked more like this: | ||
|
||
{ | ||
"name": "difficult", | ||
"desc": "made-up example driver that's as non-default as can be", | ||
"chals": ["dns-01"], | ||
"args": [ | ||
{ "name": "api_id", | ||
"req": 1, | ||
"param": "difficult_api_id", | ||
"envvar": "DIFFICULT_DNS_API_ID", | ||
}, | ||
{ "name": "api_key", | ||
"req": 1, | ||
"param": "DIFFICULT_API_KEY", | ||
"envvar": "DIFFICULT_DNS_API_KEY"}, | ||
}, | ||
{ "name": "api_base_url", | ||
"param": "API_BASE_URL", | ||
"envvar": "", | ||
}, | ||
], | ||
"path": "sewer.dns_providers.difficultdns", | ||
"cls": "DifficultDNSDns", | ||
"features": [], | ||
"memo", "difficult, indeed..." | ||
} | ||
|
||
This driver has both parameter names and envvar names that defy convention, | ||
so both the parameter and envvar name must be given explicitly. There is | ||
also an optional parameter that has never had an associated envvar that the | ||
implementation used. | ||
|
||
### driver parameter and environment variable names | ||
|
||
The convention is that the envvar name (if any) SHOULD be formed from the | ||
driver name and the individual args' names (see the first envvar rule | ||
below). This gives envvar names similar to, sometimes identical to, the | ||
ones already used with legacy DNS drivers. One thing that is changing is | ||
that the parameter names, which in the old convention were | ||
THE_SAME_AS_ENVVAR_NAMES, are changing to be lower case and losing | ||
driver-name prefixes, etc. Where appropriate, the new names will use just a | ||
few shared names, viz., `id`, `key`, `token`. | ||
|
||
Obviously the drivers and envvar names are not so consistent among the | ||
legacy DNS drivers. Therefore the descriptor has both `param` and `envvar` | ||
values, along with a set of rules for resolving the names to be used. | ||
|
||
#### parameter name rules | ||
|
||
1. `descriptor.args[n].name` is the "modern" name for the nth parameter | ||
2. if `param` is given, it overrides the "modern" name | ||
|
||
#### environment name rules | ||
|
||
1. f"{descriptor.name}_{descriptor.args[n].name}".upper() is the default | ||
2. if `envvar` is given, it overrides the default | ||
|
||
Two guidelines for the use of envvars: | ||
|
||
1. If `envvar` is given, is not the empty string, and the so-named envvar is | ||
not found, the invoking code MAY also look for the default-named envvar | ||
before reporting a missing envvar. | ||
|
||
2. If `envvar` is set to the empty string, then catalog using code will not | ||
look for a matching envvar at all. | ||
|
||
### catalog representation in Python | ||
|
||
For now, see the brief implementation in sewer/catalog.py for the way the | ||
JSON structure is mapped into a ProviderDescriptor instance. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
## route53 - driver for AWS DNS service | ||
|
||
### Command line use | ||
|
||
route53 has never been wired into `sewer-cli`, and that hasn't really | ||
changed in 0.8.3. It does appear in the list of "known providers", but it | ||
isn't usable, and raises an exception if named by `--provider`. | ||
|
||
Adding that integration is on the list, but seeing as no one has complained | ||
about this lack up to now it's nowhere near the top. :-( | ||
|
||
### Programmatic use | ||
|
||
Apparently everyone using sewer's route53 has been rolling their own | ||
wrapper, since it has only been available for such use to date. There is a | ||
patch to extend that Route53Dns.__init__ to allow additional AWS-specific | ||
methods of authentication which I expect will ship in 0.8.3. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,21 @@ | ||
## unbound_ssh legacy DNS driver | ||
|
||
A working, if somewhat quirky, driver to setup challenges in the unbound | ||
server, using ssh to connect to an account able to run unbound-control | ||
commands. The driver does NOT handle the login authorization, assuming that | ||
it is running interactively and ssh will prompt for your input, or that a | ||
key agent (eg., ssh-agent) is active to supply the cryptographic | ||
credentials. | ||
A working, if somewhat quirky, driver to setup challenges in local data of | ||
the [unbound](https://nlnetlabs.nl/projects/unbound/about/) caching | ||
resolver. As the name suggests, it relies upon ssh to provide an | ||
authenticated connection the server; inside that connection the | ||
`unbound-control` program is used to add and remove the records. The driver | ||
does NOT handle the login authorization, assuming that it is running | ||
interactively and ssh will prompt for your input, or that a key agent (eg., | ||
ssh-agent) is active to supply the cryptographic credentials. That's the | ||
_somewhat quirky_ part! | ||
|
||
### `__init__(self, *, ssh_des, **kwargs)` | ||
|
||
There is one REQUIRED parameter, `ssh_des`, which is the login target, such | ||
as [email protected]. This is simply passed to the ssh command, | ||
with the unbound-control commands passed as the command to execute remotely. | ||
along with the `unbound-control` commands to be executed on the destination | ||
machine. | ||
|
||
### Driver features | ||
|
||
|
@@ -38,3 +42,7 @@ Sadly, This was written using the old paradigm where both the module name | |
and the class name were more-or-less the same name aside from | ||
capitalization... and often less predictable changes. Should have been | ||
unbound_ssh.Provider ... | ||
|
||
The `unbound-control` commands generated could be run locally with not very | ||
much change to the driver. Perhaps that will become part of a demonstration | ||
of some different features in the future. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.