Cloud credentials in OpenShift-on-OpenStack are stored in a secret in the kube-system
namespace.
Rotating credentials entails:
- Create the new credentials in OpenStack
- Build a
clouds.yaml
with the new credentials - Upload the new
clouds.yaml
to the Kubernetes secret - Let the operators distribute the new secret.
When using application credentials, this translates to:
# Step 0: Get the current credentials for the cluster. Useful later to replace values
# Step 1: Create the new credentials in OpenStack
openstack application credentials create new-creds-1
# Step 2: Build a `clouds.yaml` with the new credentials.
# Get the current credentials from OCP, and replace with the new values from Step 2.
# Save as `c.yaml` for example.
oc -n kube-system get secret openstack-credentials -o jsonpath='{.data.clouds\.yaml}' | base64 -d
# Step 3: Upload the new `clouds.yaml` to the `openstack-credentials` secret
oc set data -n kube-system secret/openstack-credentials clouds.yaml="$(<"c.yaml")"
# Step 4: Enjoy.
Automate clouds.yaml
generation
First, build a script that creates new application credentials and directly outputs a clouds.yaml
based on a template. We asssume that the cloud in question is openstack
, which is what you’ll find in the OpenShift secret.
The script takes two arguments: an arbitrary name for the OpenStack credential, and one existing clouds.yaml
.
openstack-appcreds() {
declare \
name="${1:?Missing positional argument: the name of the new application credential}" \
template="${2:?Missing positional argument: the template where to replace the auth values}"
shift; shift
if [[ ! -r "$template" ]]; then
echo 'The template must be a readable file'
return
fi
yq --yaml-output --slurpfile appcreds <(openstack application credential create -f json "$name" "$@") '.
| del(.clouds.openstack.auth.username)
| del(.clouds.openstack.auth.password)
| del(.clouds.openstack.auth.user_domain_name)
| del(.clouds.openstack.auth.project_id)
| del(.clouds.openstack.auth.project_name)
| del(.clouds.openstack.auth.project_domain_name)
| .clouds.openstack.auth_type="v3applicationcredential"
| .clouds.openstack.auth.application_credential_id=$appcreds[0].id
| .clouds.openstack.auth.application_credential_secret=$appcreds[0].secret
' <(yq '.' "$template")
}
Example:
openstack-appcreds tmp-1 c.yaml
The script passes any further argument to the OpenStack command. Example with expiring credentials:
openstack-appcreds tmp-1 c.yaml --expiration "$(date -d '+1 hour' +%Y-%m-%dT%H:%M:%S --utc)"
This script can take a password-based clouds.yaml
as a template.
Rotate credentials in a single step
By leveraging the script above, the whole process can be compressed in one single command:
oc set data -n kube-system secret/openstack-credentials clouds.yaml="$(
openstack-appcreds 'tmp-1' <(
oc -n kube-system get secret openstack-credentials -o jsonpath='{.data.clouds\.yaml}' | base64 -d
)
)"