Skip to content
Draft
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
18 changes: 2 additions & 16 deletions osism/commands/loadbalancer.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,9 @@ def _load_octavia_database_password():
return None

try:
from osism.tasks.conductor.utils import get_vault
from osism.tasks.conductor.utils import load_yaml_file

vault = get_vault()

with open(secrets_path, "rb") as f:
file_data = f.read()

if vault.is_encrypted(file_data):
decrypted_data = vault.decrypt(file_data).decode()
logger.debug(f"Successfully decrypted secrets file: {secrets_path}")
else:
decrypted_data = file_data.decode()
logger.debug(
f"Secrets file is not encrypted (development mode): {secrets_path}"
)

secrets = yaml.safe_load(decrypted_data)
secrets = load_yaml_file(secrets_path)

if not secrets or not isinstance(secrets, dict):
logger.error("Empty or invalid secrets file")
Expand Down
18 changes: 2 additions & 16 deletions osism/commands/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,30 +104,16 @@ def _load_kolla_configuration(self):

def _load_database_password(self):
"""Load and decrypt the database password from secrets.yml"""
from osism.tasks.conductor.utils import get_vault

secrets_path = "/opt/configuration/environments/kolla/secrets.yml"

if not os.path.exists(secrets_path):
logger.error(f"Secrets file not found: {secrets_path}")
return None

try:
vault = get_vault()

with open(secrets_path, "rb") as f:
file_data = f.read()

if vault.is_encrypted(file_data):
decrypted_data = vault.decrypt(file_data).decode()
logger.debug(f"Successfully decrypted secrets file: {secrets_path}")
else:
decrypted_data = file_data.decode()
logger.debug(
f"Secrets file is not encrypted (development mode): {secrets_path}"
)
from osism.tasks.conductor.utils import load_yaml_file

secrets = yaml.safe_load(decrypted_data)
secrets = load_yaml_file(secrets_path)

if not secrets or not isinstance(secrets, dict):
logger.error("Empty or invalid secrets file")
Expand Down
29 changes: 29 additions & 0 deletions osism/tasks/conductor/utils.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# SPDX-License-Identifier: Apache-2.0

import os

from ansible import constants as ansible_constants
from ansible.parsing.vault import VaultLib, VaultSecret
from loguru import logger

from osism import utils
import sushy
import urllib3
import yaml


def deep_compare(a, b, updates):
Expand Down Expand Up @@ -88,6 +91,32 @@ def get_vault():
return vault


def load_yaml_file(path):
"""Load a YAML file and only request the vault secret when needed."""
if not os.path.exists(path):
logger.error(f"YAML file not found: {path}")
return None

try:
with open(path, "rb") as f:
file_data = f.read()

if VaultLib().is_encrypted(file_data):
decrypted_data = get_vault().decrypt(file_data).decode()
logger.debug(f"Successfully decrypted vault-encrypted YAML file: {path}")
else:
decrypted_data = file_data.decode()
logger.debug(f"YAML file is not encrypted: {path}")

return yaml.safe_load(decrypted_data)
except yaml.YAMLError as exc:
logger.error(f"Failed to parse YAML file {path}: {exc}")
return None
except Exception as exc:
logger.error(f"Failed to load YAML file {path}: {exc}")
return None


def get_redfish_connection(
hostname, username=None, password=None, ignore_ssl_errors=True, timeout=None
):
Expand Down
50 changes: 4 additions & 46 deletions osism/tasks/openstack.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from osism import settings, utils
from osism.tasks import Config, run_command
from osism.tasks.conductor.utils import get_vault
from osism.tasks.conductor.utils import load_yaml_file

app = Celery("openstack")
app.config_from_object(Config)
Expand Down Expand Up @@ -432,51 +432,9 @@ def get_cloud_password(cloud):
logger.warning(f"Secrets file not found: {secrets_path}")
return None

# Get vault instance for decryption
vault = get_vault()

# Load the secrets file
with open(secrets_path, "rb") as f:
file_data = f.read()

decrypted_secrets = None

# Try to decrypt the file if it's vault encrypted
try:
if vault.is_encrypted(file_data):
# File is encrypted, decrypt it
decrypted_data = vault.decrypt(file_data).decode()
logger.debug(f"Successfully decrypted secrets file: {secrets_path}")
else:
# File is not encrypted, use as-is
decrypted_data = file_data.decode()
logger.debug(
f"Secrets file is not encrypted (development mode): {secrets_path}"
)

# Parse the YAML content safely
try:
decrypted_secrets = yaml.safe_load(decrypted_data)
except yaml.YAMLError as yaml_exc:
logger.error(
f"Failed to parse YAML content from secrets file: {yaml_exc}"
)
return None

except Exception as decrypt_exc:
# If decryption fails, try reading as plain YAML (development fallback)
logger.warning(
f"Failed to decrypt secrets file, attempting to read as plain YAML: {decrypt_exc}"
)
try:
with open(secrets_path, "r") as f:
decrypted_secrets = yaml.safe_load(f)
logger.debug(
f"Successfully loaded unencrypted secrets file (development mode): {secrets_path}"
)
except Exception as plain_exc:
logger.error(f"Failed to read secrets file as plain YAML: {plain_exc}")
return None
decrypted_secrets = load_yaml_file(secrets_path)
if decrypted_secrets is None:
return None

if not decrypted_secrets or not isinstance(decrypted_secrets, dict):
logger.warning(
Expand Down
19 changes: 2 additions & 17 deletions osism/utils/rabbitmq.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import subprocess

from loguru import logger
import yaml

from osism.utils.inventory import get_hosts_from_inventory, get_inventory_path

Expand Down Expand Up @@ -150,23 +149,9 @@ def load_rabbitmq_password():
return None

try:
from osism.tasks.conductor.utils import get_vault
from osism.tasks.conductor.utils import load_yaml_file

vault = get_vault()

with open(secrets_path, "rb") as f:
file_data = f.read()

if vault.is_encrypted(file_data):
decrypted_data = vault.decrypt(file_data).decode()
logger.debug(f"Successfully decrypted secrets file: {secrets_path}")
else:
decrypted_data = file_data.decode()
logger.debug(
f"Secrets file is not encrypted (development mode): {secrets_path}"
)

secrets = yaml.safe_load(decrypted_data)
secrets = load_yaml_file(secrets_path)

if not secrets or not isinstance(secrets, dict):
logger.error("Empty or invalid secrets file")
Expand Down