Secrets¶
A secret is a set of name/value pairs where the value is encrypted. When you create a secret, it will have a name associated with it. The secret is also created in a specific namespace.
You should query the user for secret values so that the values are not embedded in source code.
from getpass import getpass
import pprint
from k9.core import (
set_default_namespace,
create_namespace,
delete_namespace,
create_secret,
delete_secret
)
try:
# Name everything that we will later delete first.
ns = "tomcat-dev"
secret_name = "database-secrets"
# Create a namespace for this test
set_default_namespace(ns)
create_namespace()
print("Database Secrets Setup")
print("----------------------")
# Collect three super secret values: url, username and password
url = getpass("Enter database URL:")
username = getpass("Enter username [postgres]:")
if len(username.strip()) < 1:
username = 'postgres'
password = getpass("Enter database password:")
# Create the secret object
secrets = {
'url': url,
'username': username,
'password': password
}
result = create_secret(secret_name, secrets)
# Show the resulting secret
pp = pprint.PrettyPrinter(indent=2)
pp.pprint(result)
finally:
# Since this is a test, we are removing everything we just created
delete_secret(secret_name)
delete_namespace(ns)
Example Output:
{'api_version': 'v1',
'data': {'password': 'TXlTdXBlclNlY3JldFBhc3N3b3Jk',
'url': 'aHR0cHM6Ly9sb2NhbGhvc3Q=',
'username': 'cG9zdGdyZXM='},
'kind': 'Secret',
'metadata': {'annotations': None,
'cluster_name': None,
'creation_timestamp': datetime.datetime(2019, 10, 23, 20, 10, tzinfo=tzutc()),
'deletion_grace_period_seconds': None,
'deletion_timestamp': None,
'finalizers': None,
'generate_name': None,
'generation': None,
'initializers': None,
'labels': None,
'managed_fields': None,
'name': 'database-secrets',
'namespace': 'tomcat-dev',
'owner_references': None,
'resource_version': '2857937',
'self_link': '/api/v1/namespaces/tomcat-dev/secrets/database-secrets',
'uid': '1769123c-f5d1-11e9-aa89-025000000001'},
'string_data': None,
'type': 'Opaque'}
Secrets are most often passed to deployments through environment variables. Here is an example of how that is done in a deployment.yml file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-dev
spec:
replicas: 2
selector:
matchLabels:
app: tomcat
env: dev
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
minReadySeconds: 5
template:
metadata:
labels:
app: tomcat
env: dev
spec:
containers:
- name: tomcat
image: tomcat:8
ports:
- containerPort: 8080
env:
- name: DS_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: url
- name: DS_USR
valueFrom:
secretKeyRef:
name: database-secrets
key: username
- name: DS_PWD
valueFrom:
secretKeyRef:
name: database-secrets
key: password
Take note of the fact that the environment value is taken from a secret, specifying the secret database name and key of each value. These values are then assigned to the specified environment variable.
- k9.core.list_secrets(namespace: Optional[str] = None)[source]¶
Lists secrets in a given namespace.
- Parameters
namespace – Namespace you want to search. If None, the default namespace is used.
- Returns
A list of dictionaries with name, type, data (for number of entries), and age
- k9.core.secret_exists(name: str, namespace: Optional[str] = None)[source]¶
Determines if a secret exists.
- Parameters
name – Name of secret
namespace – Namespace to search, if None, uses default namespace
- Returns
True if specfied secret exists.
- k9.core.get_secret(name: str, namespace: Optional[str] = None)[source]¶
Gets a secret’s metadata and value(s).
- Parameters
name – Name of secret
namespace – Namespace to search, if None, uses default namespace
- Returns
None if not found, otherwise V1Secret
- k9.core.create_secret(name: str, secrets: dict, namespace: Optional[str] = None)[source]¶
Creates a secret.
- Parameters
name – Name of secret
secrets – Dictionary containing name value pairs of secrets
namespace –
- Returns
Example:
# Note that you should not embed secrets in your source code, this is # simply to illustrate how the function call works. secret_name = "tomcat-dev" secrets = { 'ds-url': 'https://some/url', 'password': 'My1SecretPassword', 'username': 'postgres' } # Test create_secret() result = create_secret(secret_name, secrets)
Output:
{'api_version': 'v1', 'data': {'ds-url': 'aHR0cHM6Ly9zb21lL3VybA==', 'password': 'TXkxU2VjcmV0UGFzc3dvcmQ=', 'username': 'cG9zdGdyZXM='}, 'kind': 'Secret', 'metadata': {'annotations': None, 'cluster_name': None, 'creation_timestamp': datetime.datetime(2019, 10, 17, 17, 20, 56, tzinfo=tzutc()), 'deletion_grace_period_seconds': None, 'deletion_timestamp': None, 'finalizers': None, 'generate_name': None, 'generation': None, 'initializers': None, 'labels': None, 'managed_fields': None, 'name': 'tomcat-dev', 'namespace': 'default', 'owner_references': None, 'resource_version': '2053051', 'self_link': '/api/v1/namespaces/default/secrets/tomcat-dev', 'uid': '7ab378c0-f102-11e9-a715-025000000001'}, 'string_data': None, 'type': 'Opaque'}