Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add vault-kv interface #97

Merged
merged 13 commits into from
Sep 13, 2023
Merged
81 changes: 81 additions & 0 deletions docs/json_schemas/vault_kv/v0/provider.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"title": "ProviderSchema",
"description": "The schema for the provider side of this interface.",
"type": "object",
"properties": {
"unit": {
"$ref": "#/definitions/BaseModel"
},
"app": {
"$ref": "#/definitions/VaultKvProviderSchema"
}
},
"required": [
"app"
],
"definitions": {
"BaseModel": {
"title": "BaseModel",
"type": "object",
"properties": {}
},
"UnitCredentialsSchema": {
"title": "UnitCredentialsSchema",
"type": "object",
"properties": {
"role_id": {
"title": "Role Id",
"description": "The role ID to use to authenticate to Vault.",
"type": "string"
},
"role_secret_id": {
"title": "Role Secret Id",
"description": "The role secret ID to use to authenticate to Vault.",
"type": "string"
}
},
"required": [
"role_id",
"role_secret_id"
]
},
"CredentialsSchema": {
"title": "CredentialsSchema",
"default": "Units' credentials",
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/UnitCredentialsSchema"
}
},
"VaultKvProviderSchema": {
"title": "VaultKvProviderSchema",
"type": "object",
"properties": {
"vault_url": {
"title": "Vault Url",
"description": "The URL of the Vault server to connect to.",
"type": "string"
},
"kv_mountpoint": {
"title": "Kv Mountpoint",
"description": "The mountpoint of the KV store to use.",
"type": "string"
},
"credentials": {
"title": "Credentials",
"description": "The credentials to use to authenticate to Vault.",
"allOf": [
{
"$ref": "#/definitions/CredentialsSchema"
}
]
}
},
"required": [
"vault_url",
"kv_mountpoint",
"credentials"
]
}
}
}
41 changes: 41 additions & 0 deletions docs/json_schemas/vault_kv/v0/requirer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"title": "RequirerSchema",
"description": "The schema for the requirer side of this interface.",
"type": "object",
"properties": {
"unit": {
"$ref": "#/definitions/UnitVaultKvRequirerSchema"
},
"app": {
"$ref": "#/definitions/AppVaultKvProviderSchema"
}
},
"required": [
"unit",
"app"
],
"definitions": {
"UnitVaultKvRequirerSchema": {
"title": "UnitVaultKvRequirerSchema",
"type": "object",
"properties": {
"egress_subnet": {
"title": "Egress Subnet",
"default": "Egress subnet to use, in CIDR notation.",
"type": "string"
}
}
},
"AppVaultKvProviderSchema": {
"title": "AppVaultKvProviderSchema",
"type": "object",
"properties": {
"secret_backend": {
"title": "Secret Backend",
"default": "The name of the secret backend to use.",
"type": "string"
}
}
}
}
}
67 changes: 67 additions & 0 deletions interfaces/vault_kv/v0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# `vault-kv`

## Usage

Some charms require a secure key value store. This relation interface describes the expected behavior of any charm claiming to interact with Vault Key Value stores.

## Direction

```mermaid
flowchart TD
Requirer -- secret_backend, egress_subnet --> Provider
Provider -- vault_url, kv_mountpoint, credentials --> Requirer
```

## Behavior

Both the Requirer and the Provider need to adhere to criteria to be considered compatible with the interface.

### Provider

Provider expectations

- Must provide the vault url
- Must provide a key value mountpoint
- Must provide a role_id and role_secret_id for each unit, with access protected by unit's egress_subnet
gboutry marked this conversation as resolved.
Show resolved Hide resolved

### Requirer

Requirer expectations

- Must provide a secret backend name, which must start with "charm-"
simskij marked this conversation as resolved.
Show resolved Hide resolved
gboutry marked this conversation as resolved.
Show resolved Hide resolved
- Must provide an egress subnet for each unit used to protect access to the secret backend

## Relation Data

Describe the contents of the databags, and provide schemas for them.

[\[Pydantic Schema\]](./schema.py)

#### Example

```yaml
provider:
app:
vault_url: http://10.152.183.104:8200
kv_mountpoint: charm-barbican
credentials: |
gruyaume marked this conversation as resolved.
Show resolved Hide resolved
{
"barbican-0": {
"role_id": 158778a2-04fc-39c5-ba13-0cb5faddb5eb",
"role_secret_id": "41c3e4eb-39ec-5c68-2f41-fbc1bc1e9c52"
},
"barbican-1": {
"role_id": "38eb72db-60d0-082a-4847-6b9d1690cf02",
"role_secret_id": "fa1db047-3c90-e614-7ca0-76ce2ec1b6fc"
}
}
unit: {}
requirer:
app:
secret_backend: charm-barbican
unit:
barbican-0:
egress_subnet: 10.1.166.206/32
barbican-1:
egress_subnet: 10.1.166.230/32
```
5 changes: 5 additions & 0 deletions interfaces/vault_kv/v0/charms.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
providers: []

# list of charms using this interface as requirers.
# same structure as providers
requirers: []
52 changes: 52 additions & 0 deletions interfaces/vault_kv/v0/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""This file defines the schemas for the provider and requirer sides of this relation interface.

It must expose two interfaces.schema_base.DataBagSchema subclasses called:
- ProviderSchema
- RequirerSchema
"""

from typing import Mapping

from pydantic import BaseModel, Field, Json

from interface_tester.schema_base import DataBagSchema


class UnitCredentialsSchema(BaseModel):
role_id: str = Field(description="The role ID to use to authenticate to Vault.")
role_secret_id: str = Field(
description="The role secret ID to use to authenticate to Vault."
)


class CredentialsSchema(BaseModel):
__root__: Mapping[str, UnitCredentialsSchema] = Field("Units' credentials")


class VaultKvProviderSchema(BaseModel):
vault_url: str = Field(description="The URL of the Vault server to connect to.")
kv_mountpoint: str = Field(description="The mountpoint of the KV store to use.")
credentials: Json[CredentialsSchema] = Field(
description="The credentials to use to authenticate to Vault."
)


class AppVaultKvProviderSchema(BaseModel):
secret_backend: str = Field("The name of the secret backend to use.")


class UnitVaultKvRequirerSchema(BaseModel):
egress_subnet: str = Field("Egress subnet to use, in CIDR notation.")


class ProviderSchema(DataBagSchema):
"""The schema for the provider side of this interface."""

app: VaultKvProviderSchema


class RequirerSchema(DataBagSchema):
"""The schema for the requirer side of this interface."""

app: AppVaultKvProviderSchema
unit: UnitVaultKvRequirerSchema