Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit d3ab6fa6 authored by Arkadiusz SZCZECINSKI's avatar Arkadiusz SZCZECINSKI
Browse files

:sparkles: add password registration and vault connection validators

parent f2ecbe2d
No related branches found
No related tags found
1 merge request!148Draft: Netbox password rotation service
Pipeline #272708 passed
...@@ -24,7 +24,7 @@ services: ...@@ -24,7 +24,7 @@ services:
- ACTIVATE_WORKER_AND_HOUSEKEEPING=1 - ACTIVATE_WORKER_AND_HOUSEKEEPING=1
netbox-pr: netbox-pr:
image: code.europa.eu:4567/digit-c4/netbox-plugins/psw_rotation:psw-rotation image: code.europa.eu:4567/digit-c4/netbox-plugins/psw_rotation:psw-rotation
env_file: env/netbox.env env_file: env/psw_rotation.env
depends_on: depends_on:
netbox: netbox:
condition: service_healthy condition: service_healthy
......
...@@ -3,14 +3,14 @@ FROM netboxcommunity/netbox:v3.6.9-2.7.0 ...@@ -3,14 +3,14 @@ FROM netboxcommunity/netbox:v3.6.9-2.7.0
RUN mkdir /opt/netbox/plugins RUN mkdir /opt/netbox/plugins
# COPY ../requirements.txt /opt/netbox/plugins # COPY ../requirements.txt /opt/netbox/plugins
COPY netbox_configuration/ansible.sh /opt/netbox/ansible.sh # COPY netbox_configuration/ansible.sh /opt/netbox/ansible.sh
RUN chmod +x /opt/netbox/ansible.sh # RUN chmod +x /opt/netbox/ansible.sh
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
ADD netbox-operations /opt/netbox/netbox-operations ADD netbox-operations /opt/netbox/netbox-operations
RUN rm /etc/apt/sources.list.d/unit.list # RUN rm /etc/apt/sources.list.d/unit.list
COPY docker/sources.list /etc/apt/sources.list # COPY docker/sources.list /etc/apt/sources.list
RUN apt-get update && apt-get install -y cron jq vim # RUN apt-get update && apt-get install -y cron jq vim
RUN pip install ansible RUN pip install ansible
RUN pip install ansible-modules-hashivault RUN pip install ansible-modules-hashivault
......
VAULT_ADDR=https://sam-hcpvault.cec.eu.int VAULT_ADDR=https://sam-hcpvault.cec.eu.int
VAULT_PATH=netbox_operations/netbox/password_rotation/all VAULT_PATH=netbox_operations/netbox/password_rotation/all
DEFAULT_VAULT_PATH=netbox_operations/netbox/password_rotation/all/snet
NETBOX_USERNAME=admin NETBOX_USERNAME=admin
\ No newline at end of file
#!/bin/bash #!/bin/bash
# Function to check Vault connectivity
check_vault_connection() {
local response
response=$(curl -s -o /dev/null -w "%{http_code}" "${VAULT_ADDR}/v1/sys/health")
if [[ "$response" -ne 200 && "$response" -ne 429 && "$response" -ne 472 && "$response" -ne 473 && "$response" -ne 501 ]]; then
echo "[$(date)] ERROR: Vault is unreachable. Response code: $response"
exit 1
fi
}
# Function to check if the password exists in Vault
check_vault_password() {
local response
response=$(curl -s \
-H "X-Vault-Token: $VAULT_TOKEN" \
-H "X-Vault-Namespace: ${VAULT_NAMESPACE}" \
-X GET "${VAULT_ADDR}/v1/${VAULT_LOGIN_MOUNT_POINT}/data/${VAULT_PATH}/${NETBOX_USERNAME}")
if echo "$response" | jq -e '.data' > /dev/null; then
echo "[$(date)] Vault password exists under ${VAULT_LOGIN_MOUNT_POINT}/${VAULT_PATH}/${NETBOX_USERNAME}."
return 0
else
echo "[$(date)] No password found under ${VAULT_LOGIN_MOUNT_POINT}/${VAULT_PATH}/${NETBOX_USERNAME}. Registering default password."
register_default_password
return 1
fi
}
# Function to get default password and store it in Vault
register_default_password() {
DEFAULT_PASSWORD=$(curl -s \
-H "X-Vault-Token: $VAULT_TOKEN" \
-H "X-Vault-Namespace: ${VAULT_NAMESPACE}" \
-X GET "${VAULT_ADDR}/v1/${VAULT_LOGIN_MOUNT_POINT}/data/${DEFAULT_VAULT_PATH}/${NETBOX_USERNAME}" | jq -r '.data.password')
if [[ -z "$DEFAULT_PASSWORD" || "$DEFAULT_PASSWORD" == "null" ]]; then
echo "[$(date)] ERROR: Failed to retrieve default password from ${VAULT_LOGIN_MOUNT_POINT}/${DEFAULT_VAULT_PATH}/${NETBOX_USERNAME}. Exiting."
exit 1
fi
echo "[$(date)] Storing default password under ${VAULT_PATH}/${NETBOX_USERNAME}."
curl -s \
-H "X-Vault-Token: $VAULT_TOKEN" \
-H "X-Vault-Namespace: ${VAULT_NAMESPACE}" \
-H "Content-Type: application/json" \
-X POST \
--data "{\"password\": \"${DEFAULT_PASSWORD}\"}" \
"${VAULT_ADDR}/v1/${VAULT_LOGIN_MOUNT_POINT}/data/${VAULT_PATH}/${NETBOX_USERNAME}"
echo "[$(date)] Default password stored successfully."
}
while true; do while true; do
# Get the current day of the week (7=Sunday) and current hour # Get the current day of the week (7=Sunday) and current hour
DAY=$(date +%u) # 7 = Sunday on some systems, use 7 if needed DAY=$(date +%u) # 7 = Sunday on some systems, use 7 if needed
HOUR=$(date +%H) HOUR=$(date +%H)
MIN=$(date +%M) MIN=$(date +%M)
# Validate Vault connection before proceeding
check_vault_connection
# Check if it's Sunday (7) and the time is 02:00 AM # Check if it's Sunday (7) and the time is 02:00 AM
if [[ "$DAY" -eq 7 && "$HOUR" -eq 02 ]]; then if [[ "$DAY" -eq 7 && "$HOUR" -eq 02 ]]; then
echo "Executing action at $(date)" echo "[$(date)] Executing password rotation script."
JSON_DATA="{\"role_id\":\"${VAULT_ROLE_ID}\",\"secret_id\":\"${VAULT_SECRET_ID}\"}" JSON_DATA="{\"role_id\":\"${VAULT_ROLE_ID}\",\"secret_id\":\"${VAULT_SECRET_ID}\"}"
export VAULT_TOKEN=`curl -s \ export VAULT_TOKEN=$(curl -s \
-H X-Vault-Namespace:${VAULT_NAMESPACE} \ -H "X-Vault-Namespace:${VAULT_NAMESPACE}" \
-X POST \ -X POST \
--tlsv1.2 \ --tlsv1.2 \
--data "${JSON_DATA}" \ --data "${JSON_DATA}" \
${VAULT_ADDR}/v1/auth/approle/login | "${VAULT_ADDR}/v1/auth/approle/login" |
jq '.auth.client_token' | \ jq -r '.auth.client_token')
sed 's/\"//g' `
if [[ -z "$VAULT_TOKEN" || "$VAULT_TOKEN" == "null" ]]; then
ansible-playbook /opt/netbox/netbox-operations/playbooks/change_users_password/change_users_password.yml --extra-vars "{ echo "[$(date)] ERROR: Failed to retrieve Vault token. Exiting."
"netbox": { exit 1
"base_url": "http://netbox:8080/api", fi
"name": "${VAULT_PATH}",
"admin": { # Check if password exists, if not register default password
"username": "${NETBOX_USERNAME}" check_vault_password
# Proceed with password rotation
ansible-playbook /opt/netbox/netbox-operations/playbooks/change_users_password/change_users_password.yml --extra-vars "{
\"netbox\": {
\"base_url\": \"http://netbox:8080/api\",
\"name\": \"${VAULT_PATH}\",
\"admin\": {
\"username\": \"${NETBOX_USERNAME}\"
} }
}, },
"usernames": [ \"usernames\": [
"${NETBOX_USERNAME}" \"${NETBOX_USERNAME}\"
], ],
"vault": { \"vault\": {
"mount_point": "cmdb" \"mount_point\": \"cmdb\"
} }
}" }"
echo "[$(date)] Password rotation completed successfully."
# Sleep for 1 hour to avoid multiple executions in the same minute # Sleep for 1 hour to avoid multiple executions in the same minute
sleep 3600 sleep 3600
fi fi
# Sleep for 5 minute before checking again # Sleep for 5 minutes before checking again
sleep 300 sleep 300
done done
...@@ -534,6 +534,3 @@ ignored-argument-names = "_.*|^ignored_|^unused_" ...@@ -534,6 +534,3 @@ ignored-argument-names = "_.*|^ignored_|^unused_"
# List of qualified module names which can have objects that can redefine # List of qualified module names which can have objects that can redefine
# builtins. # builtins.
redefining-builtins-modules = ["six.moves", "past.builtins", "future.builtins", "builtins", "io"] redefining-builtins-modules = ["six.moves", "past.builtins", "future.builtins", "builtins", "io"]
[tool.ansible-lint]
exclude_paths = ["netbox-operations"]
\ No newline at end of file
...@@ -31,3 +31,11 @@ stdout_logfile_maxbytes=0 ...@@ -31,3 +31,11 @@ stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0 stderr_logfile_maxbytes=0
priority=900 priority=900
[program:netbox-psw-rotation]
command=/opt/netbox/ansible.sh
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
priority=900
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment