summaryrefslogtreecommitdiff
path: root/src/caas/services/passwordservice.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/caas/services/passwordservice.py')
-rw-r--r--src/caas/services/passwordservice.py180
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