Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions certificate_mgmt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ See [this doc](https://docs.vmware.com/en/VMware-Avi-Load-Balancer/30.2/Configur

## vault_cert_management.py

This is a Certificate Management Profile script for Hashicorp Vault acting as a Certificate Authority (PKI Secrets Engine).
This is a Certificate Management Profile script for Hashicorp Vault acting as a Certificate Authority (PKI Secrets Engine). Must use either vault_token or (role_name, role_id, secret_id)

The Certificate Management Profile should be configured with the following parameters:

Expand All @@ -22,11 +22,27 @@ API path for the **sign** API endpoint for the specific PKI secrets engine and r
Example: /v1/pki_int/sign/contoso-com-role

*vault_token*:\
**REQUIRED**\
**OPTIONAL**\
An API token with sufficient access to call the signing API.

Note: It is strongly recommended to mark this parameter as "sensitive".

Vault Token may be omitted if all these are specified:

*role_name*:\
**OPTIONAL**\
Role Name to be used in authentication path for role.

*role_id*:\
**OPTIONAL**\
Role ID to be used in authentication path for role.

*secret_id*:\
**OPTIONAL**\
Secret ID to be used in authentication path for role.

Note: It is strongly recommended to mark this parameter as "sensitive".

The following optional parameters may be specified:

*vault_namespace*:\
Expand Down
47 changes: 43 additions & 4 deletions certificate_mgmt/vault_cert_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,70 @@
REQUESTS_ERROR=3
TEMP_FILE_ERROR=4

def get_vault_token_with_approle(vault_addr, role_name, role_id, secret_id, vault_namespace=None, api_timeout=20):
"""
Authenticate with Vault using AppRole and retrieve a token.
"""
url = f'{vault_addr}/v1/auth/{role_name}/login'
headers = {}
if vault_namespace:
headers['X-Vault-Namespace'] = vault_namespace

data = {
'role_id': role_id,
'secret_id': secret_id
}

try:
r = requests.post(url, headers=headers, json=data, timeout=api_timeout)
if r.status_code >= 400:
try:
r_errors = ' | '.join(r.json()['errors'])
except (JSONDecodeError, KeyError):
r_errors = r.text
sys.stderr.write(f'Error during AppRole authentication: {r_errors}')
sys.exit(REMOTE_API_ERROR)

return r.json()['auth']['client_token']
except Exception as e:
sys.stderr.write(f'Error during AppRole authentication request: {str(e)}')
sys.exit(REQUESTS_ERROR)

def certificate_request(csr, common_name, args_dict):
if 'vault_addr' not in args_dict:
sys.stderr.write('Vault API Root Address (vault_addr) not specified')
sys.exit(PARAMS_ERROR)

if 'vault_token' not in args_dict:
sys.stderr.write('Vault Token (vault_token) not specified')
if 'vault_token' not in args_dict and ('role_id' not in args_dict or 'secret_id' not in args_dict or 'role_name' not in args_dict):
sys.stderr.write('Vault Token (vault_token), AppRole credentials (role_name, role_id, and secret_id), or role_name not specified')
sys.exit(PARAMS_ERROR)

if 'vault_path' not in args_dict:
sys.stderr.write('Vault Sign API Path (vault_path) not specified')
sys.exit(PARAMS_ERROR)

vault_addr = args_dict['vault_addr']
vault_token = args_dict['vault_token']
vault_token = args_dict.get('vault_token', None)
vault_path = args_dict['vault_path']
if vault_path.startswith('/'):
vault_path = vault_path[1:]
vault_namespace = args_dict.get('vault_namespace', None)
verify_endpoint = args_dict.get('verify_endpoint', None)
api_timeout = args_dict.get('api_timeout', 20)

if 'role_name' in args_dict and 'role_id' in args_dict and 'secret_id' in args_dict:
role_name = args_dict['role_name']
role_id = args_dict['role_id']
secret_id = args_dict['secret_id']
vault_token = get_vault_token_with_approle(
vault_addr, role_name, role_id, secret_id, vault_namespace, api_timeout
)

headers = {'X-Vault-Token': vault_token}
if vault_namespace:
headers['X-Vault-Namespace'] = vault_namespace

url = f'{vault_addr}{vault_path}'
url = f'{vault_addr}/{vault_path}'
api_data = {
'common_name': common_name,
'csr': csr
Expand Down