Apex: Fix CSIT snapshot files path
[releng.git] / utils / lab-reconfiguration / reconfigUcsNet.py
index 282eca0..0dd902f 100755 (executable)
 # -p PASSWORD, --password=PASSWORD
 #                       [Mandatory] Account Password for UCSM Login
 # -f FILE, --file=FILE
-#                       [Optional] Yaml file with network config you want to set for POD
-#                       If not present only current network config will be printed
+#                       [Optional] Yaml file with network config you
+#                       want to set for POD
+#                       If not present only current network config
+#                       will be printed
 #
 
 import getpass
@@ -31,8 +33,13 @@ import optparse
 import platform
 import yaml
 import time
-from UcsSdk import *
-from collections import defaultdict
+import sys
+from UcsSdk import LsmaintAck, LsPower, LsServer, OrgOrg
+from UcsSdk import UcsHandle, VnicEther, VnicEtherIf, YesOrNo
+
+
+POD_PREFIX = "POD-2"
+INSTALLER = "POD-21"
 
 
 def getpassword(prompt):
@@ -48,25 +55,56 @@ def get_servers(handle=None):
     """
     Return list of servers
     """
-    orgObj = handle.GetManagedObject(None, OrgOrg.ClassId(), {OrgOrg.DN : "org-root"})[0]
+    orgObj = handle.GetManagedObject(
+        None, OrgOrg.ClassId(), {OrgOrg.DN: "org-root"})[0]
     servers = handle.GetManagedObject(orgObj, LsServer.ClassId())
     for server in servers:
-        if server.Type == 'instance' and "POD-2" in server.Dn:
+        if server.Type == 'instance' and POD_PREFIX in server.Dn:
             yield server
 
 
+def set_boot_policy(handle=None, server=None, policy=None):
+    """
+    Modify Boot policy of server
+    """
+    obj = handle.GetManagedObject(None, LsServer.ClassId(), {
+        LsServer.DN: server.Dn})
+    handle.SetManagedObject(obj, LsServer.ClassId(), {
+        LsServer.BOOT_POLICY_NAME: policy})
+    print(" Configured boot policy: {}".format(policy))
+
+
 def ack_pending(handle=None, server=None):
     """
     Acknowledge pending state of server
     """
-    handle.AddManagedObject(server, LsmaintAck.ClassId(), {LsmaintAck.DN: server.Dn + "/ack", LsmaintAck.DESCR:"", LsmaintAck.ADMIN_STATE:"trigger-immediate", LsmaintAck.SCHEDULER:"", LsmaintAck.POLICY_OWNER:"local"}, True)
+    handle.AddManagedObject(server, LsmaintAck.ClassId(), {
+        LsmaintAck.DN: server.Dn + "/ack",
+        LsmaintAck.DESCR: "",
+        LsmaintAck.ADMIN_STATE: "trigger-immediate",
+        LsmaintAck.SCHEDULER: "",
+        LsmaintAck.POLICY_OWNER: "local"}, True)
+    print(" Pending-reboot -> Acknowledged.")
+
+
+def boot_server(handle=None, server=None):
+    """
+    Boot server (when is in power-off state)
+    """
+    obj = handle.GetManagedObject(
+        None, LsServer.ClassId(), {LsServer.DN: server.Dn})
+    handle.AddManagedObject(obj, LsPower.ClassId(), {
+        LsPower.DN: server.Dn + "/power",
+        LsPower.STATE: "admin-up"}, True)
+    print(" Booting.")
 
 
 def get_vnics(handle=None, server=None):
     """
     Return list of vnics for given server
     """
-    vnics = handle.ConfigResolveChildren(VnicEther.ClassId(), server.Dn, None, YesOrNo.TRUE)
+    vnics = handle.ConfigResolveChildren(
+        VnicEther.ClassId(), server.Dn, None, YesOrNo.TRUE)
     return vnics.OutConfigs.GetChild()
 
 
@@ -74,27 +112,36 @@ def get_network_config(handle=None):
     """
     Print current network config
     """
-    print "\nCURRENT NETWORK CONFIG:"
-    print " d - default, t - tagged"
+    print("\nCURRENT NETWORK CONFIG:")
+    print(" d - default, t - tagged")
     for server in get_servers(handle):
-        print ' {}'.format(server.Name)
+        print(' {}'.format(server.Name))
+        print('  Boot policy: {}'.format(server.OperBootPolicyName))
         for vnic in get_vnics(handle, server):
-            print '  {}'.format(vnic.Name)
-            print '   {}'.format(vnic.Addr)
-            vnicIfs = handle.ConfigResolveChildren(VnicEtherIf.ClassId(), vnic.Dn, None, YesOrNo.TRUE)
+            print('  {}'.format(vnic.Name))
+            print('   {}'.format(vnic.Addr))
+            vnicIfs = handle.ConfigResolveChildren(
+                VnicEtherIf.ClassId(), vnic.Dn, None, YesOrNo.TRUE)
             for vnicIf in vnicIfs.OutConfigs.GetChild():
                 if vnicIf.DefaultNet == 'yes':
-                    print '    Vlan: {}d'.format(vnicIf.Vnet)
+                    print('    Vlan: {}d'.format(vnicIf.Vnet))
                 else:
-                    print '    Vlan: {}t'.format(vnicIf.Vnet)
+                    print('    Vlan: {}t'.format(vnicIf.Vnet))
 
 
-def add_interface(handle=None, lsServerDn=None, vnicEther=None, templName=None, order=None, macAddr=None):
+def add_interface(handle=None,
+                  lsServerDn=None,
+                  vnicEther=None,
+                  templName=None,
+                  order=None,
+                  macAddr=None):
     """
     Add interface to server specified by server.DN name
     """
-    print " Adding interface: {}, template: {}, server.Dn: {}".format(vnicEther, templName, lsServerDn)
-    obj = handle.GetManagedObject(None, LsServer.ClassId(), {LsServer.DN:lsServerDn})
+    print(" Adding interface: {}, template: {}, server.Dn: {}".format(
+        vnicEther, templName, lsServerDn))
+    obj = handle.GetManagedObject(
+        None, LsServer.ClassId(), {LsServer.DN: lsServerDn})
     vnicEtherDn = lsServerDn + "/ether-" + vnicEther
     params = {
         VnicEther.STATS_POLICY_NAME: "default",
@@ -114,8 +161,9 @@ def remove_interface(handle=None, vnicEtherDn=None):
     """
     Remove interface specified by Distinguished Name (vnicEtherDn)
     """
-    print " Removing interface: {}".format(vnicEtherDn)
-    obj = handle.GetManagedObject(None, VnicEther.ClassId(), {VnicEther.DN:vnicEtherDn})
+    print(" Removing interface: {}".format(vnicEtherDn))
+    obj = handle.GetManagedObject(
+        None, VnicEther.ClassId(), {VnicEther.DN: vnicEtherDn})
     handle.RemoveManagedObject(obj)
 
 
@@ -125,7 +173,7 @@ def read_yaml_file(yamlFile):
     """
     # TODO: add check if vnic templates specified in file exist on UCS
     with open(yamlFile, 'r') as stream:
-        return yaml.load(stream)
+        return yaml.safe_load(stream)
 
 
 def set_network(handle=None, yamlFile=None):
@@ -133,22 +181,37 @@ def set_network(handle=None, yamlFile=None):
     Configure VLANs on POD according specified network
     """
     # add interfaces and bind them with vNIC templates
-    print "\nRECONFIGURING VNICs..."
-    network = read_yaml_file(yamlFile)
+    print("\nRECONFIGURING VNICs...")
+    pod_data = read_yaml_file(yamlFile)
+    network = pod_data['network']
+
     for index, server in enumerate(get_servers(handle)):
+        # Assign template to interface
         for iface, data in network.iteritems():
-            add_interface(handle, server.Dn, iface, data['template'], data['order'], data['mac-list'][index])
-        # Remove other interfaces which have not assigned required vnic template
+            add_interface(handle, server.Dn, iface, data['template'], data[
+                          'order'], data['mac-list'][index])
+
+        # Remove other interfaces which have not assigned required vnic
+        # template
         vnics = get_vnics(handle, server)
         for vnic in vnics:
-            if not any(data['template'] in vnic.OperNwTemplName for iface, data in network.iteritems()):
+            if not any(data['template'] in vnic.OperNwTemplName for
+                       iface, data in network.iteritems()):
                 remove_interface(handle, vnic.Dn)
-                print "  {} removed, template: {}".format(vnic.Name, vnic.OperNwTemplName)
+                print("  {} removed, template: {}".format(
+                    vnic.Name, vnic.OperNwTemplName))
+
+        # Set boot policy template
+        if INSTALLER not in server.Dn:
+            set_boot_policy(handle, server, pod_data['boot-policy'])
 
 
 if __name__ == "__main__":
+    print("\n*** SKIPING RECONFIGURATION.***\n")
+    sys.exit(0)
     # Latest urllib2 validate certs by default
-    # The process wide "revert to the old behaviour" hook is to monkeypatch the ssl module
+    # The process wide "revert to the old behaviour" hook is to monkeypatch
+    # the ssl module
     # https://bugs.python.org/issue22417
     import ssl
     if hasattr(ssl, '_create_unverified_context'):
@@ -156,14 +219,15 @@ if __name__ == "__main__":
     try:
         handle = UcsHandle()
         parser = optparse.OptionParser()
-        parser.add_option('-i', '--ip',dest="ip",
-                        help="[Mandatory] UCSM IP Address")
-        parser.add_option('-u', '--username',dest="userName",
-                        help="[Mandatory] Account Username for UCSM Login")
-        parser.add_option('-p', '--password',dest="password",
-                        help="[Mandatory] Account Password for UCSM Login")
-        parser.add_option('-f', '--file',dest="yamlFile",
-                        help="[Optional] Yaml file contains network config you want to set on UCS POD1")
+        parser.add_option('-i', '--ip', dest="ip",
+                          help="[Mandatory] UCSM IP Address")
+        parser.add_option('-u', '--username', dest="userName",
+                          help="[Mandatory] Account Username for UCSM Login")
+        parser.add_option('-p', '--password', dest="password",
+                          help="[Mandatory] Account Password for UCSM Login")
+        parser.add_option('-f', '--file', dest="yamlFile",
+                          help=("[Optional] Yaml file contains network "
+                                "config you want to set on UCS POD1"))
         (options, args) = parser.parse_args()
 
         if not options.ip:
@@ -173,43 +237,44 @@ if __name__ == "__main__":
             parser.print_help()
             parser.error("Provide UCSM UserName")
         if not options.password:
-            options.password=getpassword("UCSM Password:")
+            options.password = getpassword("UCSM Password:")
 
         handle.Login(options.ip, options.userName, options.password)
 
         # Change vnic template if specified in cli option
-        if (options.yamlFile != None):
+        if (options.yamlFile is not None):
             set_network(handle, options.yamlFile)
+            time.sleep(5)
 
-        time.sleep(3)
-
-        print "\nCheck if acknowledge is needed..."
-        for server in get_servers(handle):
-            print " {}: {}".format(server.Dn, server.OperState)
-            if server.OperState == "pending-reboot":
-                ack_pending(handle,server)
-                print " Acknowledged."
-
-        print "\nWait until Overall Status of all nodes is OK..."
-        timeout = time.time() + 60*5   #5 minutes timeout
+        print("\nWait until Overall Status of all nodes is OK...")
+        timeout = time.time() + 60 * 10  # 10 minutes timeout
         while True:
             list_of_states = []
             for server in get_servers(handle):
+                if server.OperState == "power-off":
+                    boot_server(handle, server)
+                if server.OperState == "pending-reboot":
+                    ack_pending(handle, server)
                 list_of_states.append(server.OperState)
-            print " {}".format(list_of_states)
-            if all(state == "ok" for state in list_of_states) or time.time() > timeout:
+            print(" {}, {} seconds remains.".format(
+                list_of_states, round(timeout - time.time())))
+            if all(state == "ok" for state in list_of_states):
                 break
-            time.sleep(2)
+            if time.time() > timeout:
+                raise Exception("Timeout reached while waiting for OK status.")
+            time.sleep(10)
 
         # Show current vnic MACs and VLANs
         get_network_config(handle)
 
         handle.Logout()
 
-    except Exception, err:
+    except Exception as err:
         handle.Logout()
-        print "Exception:", str(err)
-        import traceback, sys
-        print '-'*60
+        print("Exception:", str(err))
+        import traceback
+        import sys
+        print('-' * 60)
         traceback.print_exc(file=sys.stdout)
-        print '-'*60
+        print('-' * 60)
+        sys.exit(1)