diff options
| author | ckonstanski <kostcarl@isu.edu> | 2026-07-30 18:17:14 -0600 |
|---|---|---|
| committer | ckonstanski <kostcarl@isu.edu> | 2026-07-30 18:17:14 -0600 |
| commit | 640ff61422bc0ee3966941b93d9889ddbbd38d77 (patch) | |
| tree | abf1c08f5d38ee53ec8b29dc4f425722517505e6 /src/caas/services/passwordservice.py | |
| parent | 22dae02a86c1fce71091bfa5289cf99abba1b217 (diff) | |
Diffstat (limited to 'src/caas/services/passwordservice.py')
| -rw-r--r-- | src/caas/services/passwordservice.py | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/caas/services/passwordservice.py b/src/caas/services/passwordservice.py new file mode 100644 index 0000000..ab666c8 --- /dev/null +++ b/src/caas/services/passwordservice.py @@ -0,0 +1,180 @@ +import csv +import hashlib +import os +from io import TextIOWrapper +from django.conf import settings +from ..models import Cluster, Server, Credential, Chassis, Blade, Vendor +import logging + +logger = logging.getLogger("caas") + +class PasswordService(): + @staticmethod + def import_password_data(filehandle): + f = TextIOWrapper(filehandle, encoding = "ascii", errors = "replace") + csv_reader = csv.reader(f, delimiter=",") + for row in csv_reader: + serial_number_chassis = "ILO%s" % row[1] + serial_number_blade = "ILO%s" % row[2] + password = row[3] + credential_kwargs = {"bmc_password_admin_default": password, + "bmc_password_admin__isnull": True, + "bmc_username__isnull": True, + "bmc_password__isnull": True} + credential, credential_created = Credential.objects.get_or_create(**credential_kwargs) + chassis_kwargs = {"serial_number": serial_number_chassis} + chassis, chassis_created = Chassis.objects.get_or_create(**chassis_kwargs) + blade_kwargs = {"serial_number": serial_number_blade} + blade, blade_created = Blade.objects.get_or_create(**blade_kwargs) + blade.credential = credential + blade.chassis = chassis + credential.save() + chassis.save() + blade.save() + + @staticmethod + def get_server_link_data(ilo_host_address): + try: + server_kwargs = {"ilo_host_address": ilo_host_address} + server = Server.objects.get(**server_kwargs) + except Server.DoesNotExist: + logger.error("FAILED: while linking server to blade: failed to look up server ilo_host_address=%s" % ilo_host_address) + return None + try: + blade_kwargs = {"id": server.blade.pk} + blade = Blade.objects.get(**blade_kwargs) + except Blade.DoesNotExist: + logger.error("FAILED: while linking server to blade: failed to look up blade ilo_host_address=%s" % ilo_host_address) + return None + try: + vendor_kwargs = {"id": blade.vendor.pk} + vendor = Vendor.objects.get(**vendor_kwargs) + except Vendor.DoesNotExist: + logger.error("FAILED: while linking server to blade: failed to look up vendor ilo_host_address=%s" % ilo_host_address) + return None + return {"vendor": vendor.vendor_name, + "serial_number": blade.serial_number, + "ilo_host_address": server.ilo_host_address} + + @staticmethod + def link_server_to_blade(vendor_name, serial_number, ilo_host_address): + try: + server_kwargs = {"ilo_host_address": ilo_host_address} + server = Server.objects.get(**server_kwargs) + except Server.DoesNotExist: + logger.error("FAILED: while linking server to blade: failed to look up server! ilo_host_address=%s" % ilo_host_address) + return None + try: + blade_kwargs = {"serial_number": serial_number} + blade = Blade.objects.get(**blade_kwargs) + except Blade.DoesNotExist: + logger.error("FAILED: while linking server to blade: failed to look up blade! ilo_host_address=%s" % ilo_host_address) + return None + try: + vendor_kwargs = {"vendor_name": vendor_name} + vendor = Vendor.objects.get(**vendor_kwargs) + except Vendor.DoesNotExist: + logger.error("FAILED: while linking server to blade: failed to look up vendor! ilo_host_address=%s" % ilo_host_address) + return None + server.blade = blade + blade.vendor = vendor + server.save() + blade.save() + return server + + @staticmethod + def is_server_linked_to_blade(ilo_host_address): + try: + server_kwargs = {"ilo_host_address": ilo_host_address} + server = Server.objects.get(**server_kwargs) + except Server.DoesNotExist: + return True # server doesn't exist, no action should be triggered + + if server.blade is None or server.pxe_mac_address is None: + return False # server is not yet linked with blade + else: + return True # server is already linked with blade + + @staticmethod + def generate_unique_password(): + m = hashlib.sha1() + m.update(os.urandom(16)) + return m.hexdigest()[:20] + + @staticmethod + def create_bmc_admin_password(serial_number): + try: + blade_kwargs = {"serial_number": serial_number} + blade = Blade.objects.get(**blade_kwargs) + except Blade.DoesNotExist: + logger.error("FAILED: while creating BMC account: failed to look up blade for serial %s" % serial_number) + return -1 + if blade.credential is None: + logger.error("FAILED: while creating BMC account: failed to look up credential for serial %s" % serial_number) + return -1 + if blade.credential.bmc_password is None: + # We don't want to update this Credential because it will affect + # every Blade that is tied to it. We need to create a new + # Credential and link the Blade to the new Credential. + admin_password = PasswordService.generate_unique_password() + ospctl_password = PasswordService.generate_unique_password() + credential_kwargs = {"bmc_password_admin_default": blade.credential.bmc_password_admin_default} + credential, credential_created = Credential.objects.get_or_create(**credential_kwargs) + blade.credential = credential + credential.bmc_password_admin = admin_password + credential.bmc_username = settings.BMC_USERNAME + credential.bmc_password = ospctl_password + blade.save() + credential.save() + logger.debug("OK: passwords created for serial %s" % serial_number) + return 0 + logger.debug("OK: no-op for serial %s" % serial_number) + return 0 + + @staticmethod + def central_server_p(ilo_host_address): + try: + server_kwargs = {"ilo_host_address": ilo_host_address} + server = Server.objects.get(**server_kwargs) + except Server.DoesNotExist: + logger.error("FAILED: while determining if the server with ilo_host_address %s is a central server: server not found." % ilo_host_address) + return True + try: + cluster_kwargs = {"id": server.cluster.pk} + cluster = Cluster.objects.get(**cluster_kwargs) + except Cluster.DoesNotExist: + logger.error("FAILED: while determining if the server with ilo_host_address %s is a central server: cluster not found." % ilo_host_address) + return True + return False if cluster.is_central_controller==0 else True + + @staticmethod + def fix_creds(): + bad_creds = Credential.objects.raw(""" +with dupes (bmc_password_admin_default, zahl) as ( + select bmc_password_admin_default, + count(bmc_password_admin_default) as zahl + from caas_credential + group by bmc_password_admin_default +) +select c.id, + c.bmc_password_admin_default, + c.bmc_password_admin, + c.bmc_username, + c.bmc_password +from caas_credential c +left outer join dupes d + on c.bmc_password_admin_default = d.bmc_password_admin_default +where d.zahl > 1 + and bmc_password is null""") + for bad_cred in bad_creds: + good_cred_kwargs = {"bmc_password_admin_default": bad_cred.bmc_password_admin_default, + "bmc_password__isnull": False} + good_cred = Credential.objects.get(**good_cred_kwargs) + try: + blade_kwargs = {"credential_id": bad_cred.id} + blade = Blade.objects.get(**blade_kwargs) + blade.credential_id = good_cred.pk + blade.save() + bad_cred.delete() + except Blade.DoesNotExist: + pass |
