Munge operations
Contents
Munge operations#
The slurmctld
charm contains an internal etcd3 server
that, among other uses, stores the Munge
key.
The etcd server has authentication enabled by default, to protect the Munge
key. In order to be able to retrieve the Munge key, an etcd account is
required. OSD provides the Juju action etcd-create-munge-account
on the
slurmctld
charm to automate the creation of such an account.
By default, etcd is started using plain HTTP. It is possible to use HTTPS by
supplying the necessary certificates to slurmctld
.
Creating an etcd account#
To create an etcd account to query the Munge key requires a username and password to be specified:
$ juju run-action slurmctld/leader etcd-create-munge-account user="theusername" password="aVerySafePassword!" --wait
unit-slurmctld-7:
UnitId: slurmctld/7
id: "654"
results:
Stdout: |
User theusername created
Role munge-readers is granted to user theusername
created-new-user: theusername
status: completed
timing:
completed: 2022-05-12 17:57:44 +0000 UTC
enqueued: 2022-05-12 17:57:41 +0000 UTC
started: 2022-05-12 17:57:44 +0000 UTC
Querying the munge key#
The etcd server is running on the slurmctld
node and listening on the port
2379
. The Munge key is stored at munge/key
entry. The Munge key is
binary data and is stored encoded in a base 64 representation. The examples
below demonstrate how to query the secret key and decode them to be used.
Using Bash#
It is possible to get the Munge key using Bash, with curl
and jq
.
First, you need to get an access token for your username and then query the
key:
user=theusername
pass=aVerySafePassword!
host=10.107.185.126
port=2379
token=$(curl -L -s -X POST "$host:$port/v3/auth/authenticate" -d '{"name":"'"$user"'", "password":"'"$pass"'"}' | jq .token | tr -d '"')
key=$(printf munge/key | base64)
munge_key=$(curl -L -s -X POST "$host:$port/v3/kv/range" -H "Authorization: ${token}" -d '{"key":"'$key'"}' | jq .kvs[0].value | tr -d '"' | base64 -d)
As an example, running the above commands will result in:
$ echo $munge_key # it is base64 encoded
+CzBbB5c+WduA0bSNb5x6+U3Mj/QuladAFH5vqyyQyvyA5YUcUikz64YEakqB852D7Ml5jmCOuxpa0VXoYMeiaRFRw2WFyR+6H66buQeCBClgfk4t0QQKKRZsaPjVojkmhoNTgQz/8mseHDnrOpxyTEsFeAw9kMzhraK1fvHOgMbDDDnkmN1oOscNhBmnreQmcr+gy2NliGiRjCjyMh6TgwJqQCBU/4LCSs+cetbvKLMdj+7X8PbYpSALx8x4JXUjNj9sv1jLLu3f684P/G3unB709hhNvj3NoSPTZ68FhgjxqUFtXF91/Dce0hJForv9EAwgyTHmCJ+WNUI5ag+1P454nWFYqJkXTSX5gvPYBCwTGbOAjgLdyPa+SGOXeHutpCJtPjbpOtL9PkP+T5+mQrgDE1KjkDYLdlIyobVNUXfziPH82uSZft8ZRuke+vP+GpExSWsdj7sYuVAhUu9Utkfiyy1hVdmKoXeppJopjnj2J+Zmaa8/qvxYXNhmrbPdp8hadSdu2XRrNGu0AbYAGUsLrvSOSKc9J8+tkjFa5Qzcn8xR8HSWK12/mjF941NyCxDLqkfD6066KmL3ARqxdU7qVjZSMlIF8UzCiKIH2WDHkZa5LIV7Cj7ZxUTaAIjdAxmwr4ajnRqK1GFI736F+BqTWLRAuXM18S4r7KDjBYSUMNiXdL7qqY3Ao/LkniraGr4CxIBApicV0SuWfMafwoCb59oMNzyaCAiuI/JjFPqxD0Tn36ngtRHgdQnESuZeTSV68b7tOBc+MkzbUhBzmWy9TGSF2gsq6hoxIRj1oYdrTpwPQrfut4VLOkiWnJuJtaKX55z3c/o3bDZ1Ykd/unUL1vdDjlyo6VrNRu+/ijttiWAGm0PJOoMMe3PEqBjDBJAHdudlyez+bsUvH+Mm3Vnuu1gIlQ4vzxNcX1kUQC/8Mef7LjaRhD1DwUhPFw0E/AEhW0wKRuPD5vEGU1nlJLZbGcEy5x6I0qhyV/pr/SbLj5W6fTuQ5XVoHbKe5fh4U7iX7JDb1UlRZWoqZ9jbHqoWwwwkTe1VEr+tXtDFU4PJ8aEcyO4qRrSibKfXd+EYWJQ0Y+BRt+iRohXjy5CV9PMctwuciZhWMP0DGoYPfsObqoCLgLF56Gu6uVOhyC0AFrEm2LAOWzVlsxENCK4jYMtznwrRV4mwPVsFLZqCVIaAwW/KDfse7Bs2Y8RcA6Jl/Rv/kk2byyFhy230GqMcXiNEtCCViJvC/H6+V58IygJkpftrncFXafQ0u+ti/4U3ZRDD4Hfy3tepKxo9Sj9p8BBHZT7jVFYsQh3TVJqZow5lPRuumM0rz2k4izC9nW/TxGe/bmvPGzQxfQDYiEgQg==
# decode the key and save it to a file:
$ echo $munge_key | base64 -d > munge.key
Note
The etcd key must be base64 encoded when using curl
.
Note
If the server is using HTTPS with a self-signed certificate, or a non-public
Certificate Authority (CA), you need to supply the public certificate in the
curl
commands by adding --cacert path/to/cert.crt
.
Using Python#
To get the Munge key in Python, we suggest using the etcd3gw as a starting point:
from etcd3gw.client import Etcd3Client
from etcd3gw.exceptions import Etcd3Exception
class Etcd3AuthClient(Etcd3Client):
"""Handle etcd3 requests with auth."""
def __init__(self, host='localhost', port=2379, protocol="http",
ca_cert=None, cert_key=None, cert_cert=None, timeout=None,
username=None, password=None, api_path="/v3/"):
"""Initialize class."""
super(Etcd3AuthClient, self).__init__(host=host, port=port,
protocol=protocol,
ca_cert=ca_cert,
cert_key=cert_key,
cert_cert=cert_cert,
timeout=timeout,
api_path=api_path)
self.username = username
self.password = password
def authenticate(self):
"""Authenticate the client."""
if 'Authorization' in self.session.headers:
del self.session.headers['Authorization']
response = super(Etcd3AuthClient, self).post(
self.get_url('/auth/authenticate'),
json={"name": self.username, "password": self.password}
)
self.session.headers['Authorization'] = response['token']
def post(self, *args, **kwargs):
"""Wrap the internal post function with authentication."""
try:
return super(Etcd3AuthClient, self).post(*args, **kwargs)
except Etcd3Exception as e:
if self.username and self.password:
print("# etcd: Might need to (re)authenticate: %r:\n%s",
e, e.detail_text)
self.authenticate()
return super(Etcd3AuthClient, self).post(*args, **kwargs)
raise
client = Etcd3AuthClient(host="10.107.185.126",
username="theusername",
password="aVerySafePassword!")
client.authenticate()
munge_key_encoded = client.get(key="munge/key")[0]
munge_key = b64decode(munge_key_encoded)
Note
The Python3 code does not automatically identify if the connection uses HTTP
or HTTPS. By default, the library assumes HTTP. If the server is using HTTPS
you need to specify protocol="https"
when instantiating the client:
client = Etcd3AuthClient(host="10.107.185.126", protocol="https",
username="theusername",
password="aVerySafePassword!")
Configuring HTTPS#
To use HTTPS for the connection, you need to supply the TLS certificates to
slurmctld-charm
via Juju Configuration options. You need to supply the
public certificate (a .crt
file) and the private key (a .key
file).
Additionally, you must provide the Certificate Authority's (CA) public
certificate (another .crt
file) if using self-signed certificates or a
non-public CA.
To configure these certificates:
# the public and private TLS files
$ juju config slurmctld tls-cert="$(cat tls.crt)"
$ juju config slurmctld tls-key="$(cat tls.key)"
# the optional CA public certificate
$ juju config slurmctld tls-ca-cert="$(cat CA.crt)"