Vault
- Canonical Telco
Channel | Revision | Published | Runs on |
---|---|---|---|
latest/edge | 89 | 31 Jan 2024 | |
latest/edge | 9 | 27 Jan 2023 | |
1.16/stable | 280 | 04 Oct 2024 | |
1.16/candidate | 280 | 04 Oct 2024 | |
1.16/beta | 280 | 04 Oct 2024 | |
1.16/edge | 313 | 20 Dec 2024 | |
1.15/stable | 248 | 24 Jul 2024 | |
1.15/candidate | 248 | 24 Jul 2024 | |
1.15/beta | 248 | 24 Jul 2024 | |
1.15/edge | 248 | 10 Jul 2024 |
juju deploy vault-k8s --channel 1.16/stable
Deploy Kubernetes operators easily with Juju, the Universal Operator Lifecycle Manager. Need a Kubernetes cluster? Install MicroK8s to create a full CNCF-certified Kubernetes system in under 60 seconds.
Platform:
charms.vault_k8s.v0.vault_kv
-
- Last updated 19 Dec 2024
- Revision Library version 0.15
Library for the vault-kv relation.
This library contains the Requires and Provides classes for handling the vault-kv interface.
Getting Started
From a charm directory, fetch the library using charmcraft
:
charmcraft fetch-lib charms.vault_k8s.v0.vault_kv
Requirer charm
The requirer charm is the charm requiring a secret value store. In this example, the requirer charm is requiring a secret value store.
import secrets
from charms.vault_k8s.v0 import vault_kv
from ops.charm import CharmBase, InstallEvent
from ops.main import main
from ops.model import ActiveStatus, BlockedStatus
NONCE_SECRET_LABEL = "nonce"
class ExampleRequirerCharm(CharmBase):
def __init__(self, *args):
super().__init__(*args)
self.interface = vault_kv.VaultKvRequires(
self,
"vault-kv",
"my-suffix",
)
self.framework.observe(self.on.install, self._on_install)
self.framework.observe(self.interface.on.connected, self._on_connected)
self.framework.observe(self.interface.on.ready, self._on_ready)
self.framework.observe(self.interface.on.gone_away, self._on_gone_away)
self.framework.observe(self.on.update_status, self._on_update_status)
def _on_install(self, event: InstallEvent):
self.unit.add_secret(
{"nonce": secrets.token_hex(16)},
label=NONCE_SECRET_LABEL,
description="Nonce for vault-kv relation",
)
self.unit.status = BlockedStatus("Waiting for vault-kv relation")
def _on_connected(self, event: vault_kv.VaultKvConnectedEvent):
relation = self.model.get_relation(event.relation_name, event.relation_id)
egress_subnets = [str(subnet) for subnet in self.model.get_binding(relation).network.egress_subnets][0].subnet]
egress_subnets.append(str(self.model.get_binding(relation).network.interfaces[0].subnet))
self.interface.request_credentials(relation, egress_subnets, self.get_nonce())
def _on_ready(self, event: vault_kv.VaultKvReadyEvent):
relation = self.model.get_relation(event.relation_name, event.relation_id)
if relation is None:
return
vault_url = self.interface.get_vault_url(relation)
ca_certificate = self.interface.get_ca_certificate(relation)
mount = self.interface.get_mount(relation)
unit_credentials = self.interface.get_unit_credentials(relation)
# unit_credentials is a juju secret id
secret = self.model.get_secret(id=unit_credentials)
secret_content = secret.get_content(refresh=True)
role_id = secret_content["role-id"]
role_secret_id = secret_content["role-secret-id"]
self._configure(vault_url, ca_certificate, mount, role_id, role_secret_id)
self.unit.status = ActiveStatus()
def _on_gone_away(self, event: vault_kv.VaultKvGoneAwayEvent):
self.unit.status = BlockedStatus("Waiting for vault-kv relation")
def _configure(
self,
vault_url: str,
ca_certificate: str,
mount: str,
role_id: str,
role_secret_id: str,
):
pass
def _on_update_status(self, event):
# Check somewhere that egress subnet has not changed i.e. pod has not been rescheduled
# Update status might not be the best place
binding = self.model.get_binding("vault-kv")
if binding is not None:
egress_subnets = [str(subnet) for subnet in self.model.get_binding(relation).network.egress_subnets][0].subnet]
egress_subnets.append(str(self.model.get_binding(relation).network.interfaces[0].subnet))
relation = self.model.get_relation(relation_name="vault-kv")
self.interface.request_credentials(relation, egress_subnets, self.get_nonce())
def get_nonce(self):
secret = self.model.get_secret(label=NONCE_SECRET_LABEL)
nonce = secret.get_content(refresh=True)["nonce"]
return nonce
if __name__ == "__main__":
main(ExampleRequirerCharm)
You can integrate both charms by running:
juju integrate <vault provider charm> <vault requirer charm>
class LogAdapter
Description
Adapter for the logger to prepend a prefix to all log lines. None
Methods
LogAdapter. process( self , msg: str , kwargs: MutableMapping )
Description
Decides the format for the prepended text. None
class VaultKvProviderSchema
Description
Provider side of the vault-kv interface. None
class AppVaultKvRequirerSchema
Description
App schema of the requirer side of the vault-kv interface. None
class UnitVaultKvRequirerSchema
Description
Unit schema of the requirer side of the vault-kv interface. None
class ProviderSchema
Description
The schema for the provider side of this interface. None
class RequirerSchema
Description
The schema for the requirer side of this interface. None
class KVRequest
Description
This class represents a kv request from an interface Requirer. None
def get_egress_subnets_list_from_relation_data(relation_databag)
Return the egress_subnet as a list.
Arguments
the relation databag of the unit or the app.
Description
This function converts the string with values separated by commas to a list.
def
is_requirer_data_valid(
app_data,
unit_data
)
Description
Return whether the requirer data is valid. None
def is_provider_data_valid(data)
Description
Return whether the provider data is valid. None
class VaultKvGoneAwayEvent
Description
VaultKvGoneAwayEvent Event. None
class VaultKvClientDetachedEvent
Description
VaultKvClientDetachedEvent Event. None
Methods
VaultKvClientDetachedEvent. __init__( self , handle , unit_name: str )
VaultKvClientDetachedEvent. snapshot( self )
Description
Return snapshot data that should be persisted. None
VaultKvClientDetachedEvent. restore( self , snapshot )
Description
Restore the event from a snapshot. None
class NewVaultKvClientAttachedEvent
Description
New vault kv client attached event. None
Methods
NewVaultKvClientAttachedEvent. __init__( self , handle , relation , app_name: str , unit_name: str , mount_suffix: str , egress_subnets , nonce: str )
NewVaultKvClientAttachedEvent. snapshot( self )
Description
Return snapshot data that should be persisted. None
NewVaultKvClientAttachedEvent. restore( self , snapshot )
Description
Restore the value state from a given snapshot. None
class VaultKvProviderEvents
Description
List of events that the Vault Kv provider charm can leverage. None
class VaultKvProvides
Description
Class to be instanciated by the providing side of the relation. None
Methods
VaultKvProvides. __init__( self , charm , relation_name: str )
VaultKvProvides. remove_unit_credentials( self , relation , nonce )
Description
Remove nonce(s) from the relation. None
VaultKvProvides. get_credentials( self , relation )
Description
Get the unit credentials from the app relation data and load it as a dict. None
VaultKvProvides. get_kv_requests( self , relation_id )
Description
Get all KV requests for the relation. None
VaultKvProvides. set_kv_data( self , relation , mount: str , ca_certificate: str , vault_url: str , nonce: str , credentials_juju_secret_id: str )
Description
Set the kv data on the relation. None
class VaultKvBaseEvent
Description
Base class for VaultKV requirer events. None
Methods
VaultKvBaseEvent. __init__( self , handle , relation_id: int , relation_name: str , relation )
VaultKvBaseEvent. snapshot( self )
Description
Return snapshot data that should be persisted. None
VaultKvBaseEvent. restore( self , snapshot )
Description
Restore the value state from a given snapshot. None
class VaultKvConnectedEvent
Description
VaultKvConnectedEvent Event. None
class VaultKvReadyEvent
Description
VaultKvReadyEvent Event. None
class VaultKvRequireEvents
Description
List of events that the Vault Kv requirer charm can leverage. None
class VaultKvRequires
Description
Class to be instanciated by the requiring side of the relation. None
Methods
VaultKvRequires. __init__( self , charm , relation_name: str , mount_suffix: str )
VaultKvRequires. request_credentials( self , relation , egress_subnet , nonce: str )
Request credentials from the vault-kv relation.
Arguments
The relation object or the relation id.
The egress subnets requesting the credentials for.
The nonce that identifies the unit.
Description
Credentials are tied to the unit egress_subnet, so if the egress_subnet changes a new secret id must be generated.
A change in egress_subnets can happen when the pod is rescheduled to a different node by the underlying substrate without a change from Juju.
VaultKvRequires. get_vault_url( self , relation )
Description
Return the vault_url from the relation. None
VaultKvRequires. get_ca_certificate( self , relation )
Description
Return the ca_certificate from the relation. None
VaultKvRequires. get_mount( self , relation )
Description
Return the mount from the relation. None
VaultKvRequires. get_unit_credentials( self , relation )
Return the unit credentials from the relation.
Description
Unit credentials are stored in the relation data as a Juju secret id.