charms.proxylib 0.0.0
Charm library for juju-*-proxy model config
Requires Python: >=3.10
Keywords: juju, charming, operators, systemd, web-proxy, validation

# charms.proxylib

Use this model when your charm needs to conform to the `KU-158` spec from
[specs.canonical.com](https://specs.canonical.com).

The library provides a view and model for the following juju model configs:
* `JUJU_CHARM_HTTP_PROXY`
* `JUJU_CHARM_HTTPS_PROXY`
* `JUJU_CHARM_NO_PROXY`

The exposed views render the model as a mapping
* http_proxy = `$JUJU_CHARM_HTTP_PROXY`
* https_proxy = `$JUJU_CHARM_HTTPS_PROXY`
* no_proxy = `$JUJU_CHARM_NO_PROXY`

and optionally the uppercase versions of the same model
* HTTP_PROXY = `$JUJU_CHARM_HTTP_PROXY`
* HTTPS_PROXY = `$JUJU_CHARM_HTTPS_PROXY`
* NO_PROXY = `$JUJU_CHARM_NO_PROXY`

### Validation
It will validate the values in `JUJU_CHARM_HTTP(S)_PROXY`:
* the value can be empty ""
* the value must be a URL of schema http or https
* the value must have a network location to proxy to

### Views

#### Craft an Environment

Calling `charms.proxylib.environ` validates values from the juju model-config.
returning a object to be treated as a dictionary.  If the model-config values
are invalid, errors are present in the objects `error` attribute.

Example usage )

```python
env = charms.proxylib.environ(enabled=enabled)
if env.error:
    # Charm can block here or ignore if it likes
    ...
```

#### Environment Replacement

Using `charms.proxylib.environ` as a with-context to replace the existing
`os.environ` temporarily with the validated values from the juju model-config.

Example to replace `os.environ` )

```python
with charms.proxylib.environ(enabled=enabled) as proxy_env:
    if err := proxy_env.error:
        log_err("Error while getting proxy settings: {}", err)
        status.blocked(err)
    # Do what you like here, os.environ is updated
    ...
```

Example to replace a custom `env` )

```python
env = {}
with charms.proxylib.environ(env, enabled=enabled) as proxy_env:
    if err := proxy_env.error:
        log_err("Error while getting proxy settings: {}", err)
        status.blocked(err)
    # Do what you like here, env is updated
    ...
```

#### `systemd` Environment file

Using `charms.proxylib.systemd` creates file content for a systemd service.

Example to create a `/etc/systemd/system/my-service.d/web-proxy.conf` )

```python
env = charms.proxylib.environ(enabled=enabled)
if env.error:
    raise ValueError(f"Service {service} {env.error}")
content = charms.proxylib.systemd(env, service)
```

Generates

```
[Service]
# Autogenerated by juju_app='<my-app>' for service='<my-service>'
Environment="http_proxy=http://example.com:8080"
Environment="HTTP_PROXY=http://example.com:8080"
Environment="https_proxy=https://example.com:8080"
Environment="HTTPS_PROXY=https://example.com:8080"
Environment="no_proxy=localhost"
Environment="NO_PROXY=localhost"
```

#### POD Specification for `lightkube` objects

Using `charms.proxylib.container_vars` will create a list of `EnvVar` objects
to be used by lightkube to apply to a podspec for `Deployments` or
`DaemonSets` or the like...

```python
container: lightkube.models.core_v1.Container
env = charms.proxylib.environ(enabled=enabled)
container.env.extend(charms.proxylib.container_vars(env))
```

## Options

the `charms.proxylib.environ` can be called with the following parameters.

### Returns

An object that behaves like a `dict[str,str]` but also with an `error` attribute
in case the `JUJU_CHARM_*` environment variables aren't valid.

### Positional arguments:
* `source`
  -  **description** - the object updated when used as a with-context
  -  **default** - `os.environ` - defaults to the callers OS environment
  -  **type** - `dict[str, str]`

###  Keyword arguments:
* `enabled`
  - **description** - Whether or not to validate and apply the model-config
  - **type** - `bool`
* `uppercase`
  - **description** - Whether the returned structure includes uppercase values.
    If set to `False`, the values `HTTPS_PROXY`, `HTTP_PROXY`, `NO_PROXY` won't
    be present.
  - **default** - `True` - defaults to include the uppercase values
  - **type** - `bool`
* `add_no_proxies`
  - **description** - a list of no_proxy hostnames to add to the produced set in
  addition to the ones provided by `JUJU_CHARM_NO_PROXY`. This is useful when
  the charmed executable should **NEVER** use a web-proxy to reach the listed
  host.
  - **default** - `[]` - includes no additional no-proxies by default
  - **type** - `list[str]`