Ansible: Add CIMC/IPMI/COBBLER
[csit.git] / resources / tools / testbed-setup / cimc / cimclib.py
diff --git a/resources/tools/testbed-setup/cimc/cimclib.py b/resources/tools/testbed-setup/cimc/cimclib.py
deleted file mode 100644 (file)
index f91832e..0000000
+++ /dev/null
@@ -1,414 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (c) 2016 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import requests
-import xml.etree.ElementTree as et
-import re
-
-from requests.packages.urllib3.exceptions import InsecureRequestWarning
-requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
-
-BASEDN = "sys/rack-unit-1"
-
-###
-### Helper function - iterate through a list in pairs
-###
-def chunks(lst, chunksize):
-    """Yield successive n-sized chunks from l."""
-    for i in range(0, len(lst), chunksize):
-        yield lst[i:i+chunksize]
-
-###
-### Helper function: Perform an XML request to CIMC
-###
-def xml_req(ip, xml, debug=False):
-    if debug:
-        print "DEBUG: XML-REQUEST:"
-        et.dump(xml)
-    headers = {'Content-Type': 'text/xml'}
-    req = requests.post('https://' + ip + '/nuova', headers=headers,
-                        verify=False, data=et.tostring(xml))
-    resp = et.fromstring(req.content)
-    if debug:
-        print "DEBUG: XML-RESPONSE:"
-        et.dump(resp)
-
-    if resp.tag == 'error':
-        if debug:
-            print "XML response contains error:"
-            et.dump(error)
-        raise RuntimeError('XML response contains error')
-    return resp
-
-###
-### Authenticate (Log-In) to CIMC and obtain a cookie
-###
-def login(ip, username, password):
-    reqxml = et.Element('aaaLogin',
-                        attrib={'inName':username, 'inPassword':password})
-    respxml = xml_req(ip, reqxml)
-    try:
-        cookie = respxml.attrib['outCookie']
-    except:
-        print "Cannot find cookie in CIMC server response."
-        print "CIMC server output:"
-        et.dump(respxml)
-        raise
-
-    return cookie
-
-###
-### Log out from CIMC.
-###
-### Note: There is a maximum session limit in CIMC and sessions to take a long
-### time (10 minutes) to time out. Therefore, calling this function during
-### testing is essential, otherwise one will quickly exhaust all available
-### sessions.
-###
-def logout(ip, cookie):
-    reqxml = et.Element('aaaLogout', attrib={'cookie': cookie,
-                                             'inCookie': cookie})
-    xml_req(ip, reqxml)
-
-###
-### Power off the host
-###
-def powerOff(ip, cookie, debug=False):
-    reqxml = et.Element('configConfMo',
-                        attrib={'cookie': cookie, 'inHierarchical': 'false',
-                                'dn': BASEDN})
-    inconfig = et.SubElement(reqxml, 'inConfig')
-    et.SubElement(inconfig, 'computeRackUnit',
-                  attrib={'adminPower': 'down', 'dn': BASEDN})
-    respxml = xml_req(ip, reqxml, debug)
-    return respxml
-
-###
-### Power on the host
-###
-def powerOn(ip, cookie, debug=False):
-    reqxml = et.Element('configConfMo',
-                        attrib={'cookie': cookie, 'inHierarchical': 'false',
-                                'dn': BASEDN})
-    inconfig = et.SubElement(reqxml, 'inConfig')
-    et.SubElement(inconfig, 'computeRackUnit',
-                  attrib={'adminPower': 'up', 'dn': BASEDN})
-    respxml = xml_req(ip, reqxml, debug)
-    return respxml
-
-###
-### Restore BIOS to default settings
-###
-def restoreBiosDefaultSettings(ip, cookie, debug=False):
-    reqxml = et.Element('configResolveClass',
-                        attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                'classId': 'biosPlatformDefaults'})
-    respxml = xml_req(ip, reqxml, debug)
-
-    configs = respxml.find('outConfigs')
-    defaults = configs.find('biosPlatformDefaults')
-
-    reqxml = et.Element('configConfMo',
-                        attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                'dn': "{}/bios/bios-settings".format(BASEDN)})
-    inconfig = et.SubElement(reqxml, 'inConfig')
-    biosset = et.SubElement(inconfig, 'biosSettings')
-    biosset.extend(defaults)
-
-    respxml = xml_req(ip, reqxml, debug)
-    return respxml
-
-###
-### Apply specified BIOS settings.
-###
-### These must be a list of strings in XML format. Not currently very
-### user friendly. Format can either be obtained from CIMC
-### documention, or by setting them manually and then fetching
-### BIOS settings via CIMC XML API.
-###
-def setBiosSettings(ip, cookie, settings, debug=False):
-    reqxml = et.Element('configConfMo',
-                        attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                'dn': "{}/bios/bios-settings".format(BASEDN)})
-    inconfig = et.SubElement(reqxml, 'inConfig')
-    biosset = et.SubElement(inconfig, 'biosSettings')
-    print "Applying settings:"
-    print settings
-    for s in settings:
-        x = et.fromstring(s)
-        et.dump(x)
-        biosset.append(et.fromstring(s))
-
-    respxml = xml_req(ip, reqxml, debug)
-    return respxml
-###
-### Delete any existing virtual drives
-###
-### WARNING: THIS WILL ERASE ALL DATA ON ALL DISKS, WITHOUT ANY CONFIRMATION
-### QUESTION.
-###
-### The server must be POWERED ON for this to succeed.
-###
-def deleteAllVirtualDrives(ip, cookie, debug=False):
-    reqxml = et.Element('configResolveClass',
-                        attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                'classId': 'storageController'})
-    respxml = xml_req(ip, reqxml, debug)
-
-    configs = respxml.find('outConfigs')
-    for sc in configs.iter('storageController'):
-        if debug:
-            print "DEBUG: SC DN {} ID {}".format(sc.attrib['dn'],
-                                                 sc.attrib['id'])
-        reqxml = et.Element('configConfMo',
-                            attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                    'dn': sc.attrib['dn']})
-        inconfig = et.SubElement(reqxml, 'inConfig')
-        et.SubElement(inconfig, 'storageController',
-                      attrib={'adminAction': 'delete-all-vds-reset-pds',
-                              'dn': sc.attrib['dn']})
-        xml_req(ip, reqxml, debug)
-
-###
-### Create a single RAID-10 across all drives.
-###
-### The server must be POWERED ON for this to succeed.
-###
-def createRaid10_all(ip, cookie, debug=False):
-    reqxml = et.Element('configResolveClass',
-                        attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                'classId': 'storageController'})
-    respxml = xml_req(ip, reqxml, debug)
-
-    configs = respxml.find('outConfigs')
-    for sc in configs.iter('storageController'):
-        if debug:
-            print "DEBUG: SC DN {} ID {}".format(sc.attrib['dn'],
-                                                 sc.attrib['id'])
-        #
-        # Find disk size and number of disks
-        #
-        disks = []
-        total_size = 0
-        for pd in sc.iter('storageLocalDisk'):
-            if debug:
-                print "DEBUG: PD {} size {}".format(pd.attrib['id'],
-                                                    pd.attrib['coercedSize'])
-            disks.append(pd.attrib['id'])
-            total_size += int(pd.attrib['coercedSize'].split(' ')[0])
-
-        #
-        # Create a RAID10 array of all available disks, as in:
-        # [1,2][3,4][5,6][7,8][9,10][11,12][13,14][15,16][17,18]
-        #
-        raid_size = total_size/2
-        raid_span = ''
-        for p in list(chunks(disks, 2)):
-            raid_span += "[{},{}]".format(p[0], p[1])
-
-        reqxml = et.Element('configConfMo',
-                            attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                    'dn': sc.attrib['dn']})
-        inconfig = et.SubElement(reqxml, 'inConfig')
-        et.SubElement(inconfig,
-                      'storageVirtualDriveCreatorUsingUnusedPhysicalDrive',
-                      attrib={'virtualDriveName': 'raid10-all',
-                              'size': str(raid_size)+' MB',
-                              'raidLevel': '10', 'driveGroup': raid_span,
-                              'adminState': 'trigger'})
-
-        xml_req(ip, reqxml, debug)
-
-###
-### Create a single RAID across from empty drives as provided.
-###
-### The server must be POWERED ON for this to succeed.
-###
-def createRaid(ip, cookie, name, raidlevel, size, drives, debug=False):
-    reqxml = et.Element('configResolveClass',
-                        attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                'classId': 'storageController'})
-    respxml = xml_req(ip, reqxml, debug)
-
-    configs = respxml.find('outConfigs')
-    for sc in configs.iter('storageController'):
-        if debug:
-            print "DEBUG: SC DN {} ID {}".format(sc.attrib['dn'],
-                                                 sc.attrib['id'])
-
-        reqxml = et.Element('configConfMo',
-                            attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                    'dn': sc.attrib['dn']})
-        inconfig = et.SubElement(reqxml, 'inConfig')
-        et.SubElement(inconfig,
-                      'storageVirtualDriveCreatorUsingUnusedPhysicalDrive',
-                      attrib={'virtualDriveName': name,
-                              'size': str(size)+' MB',
-                              'raidLevel': raidlevel,
-                              'driveGroup': drives,
-                              'adminState': 'trigger'})
-
-        xml_req(ip, reqxml, debug)
-
-###
-### Enable Serial-Over-LAN (SOL) console and redirect BIOS output to
-### serial console
-###
-def enableConsoleRedir(ip, cookie, debug=False):
-    reqxml = et.Element('configConfMo',
-                        attrib={'cookie': cookie, 'inHierarchical': 'false',
-                                'dn': "{}/bios/bios-settings".format(BASEDN)})
-    inconfig = et.SubElement(reqxml, 'inConfig')
-    bs = et.SubElement(inconfig, 'biosSettings',
-                       attrib={'dn': "{}/bios/bios-settings".format(BASEDN)})
-    et.SubElement(bs,
-                  'biosVfConsoleRedirection',
-                  attrib={'vpConsoleRedirection': 'com-0',
-                          'vpBaudRate': '115200'})
-    respxml = xml_req(ip, reqxml, debug)
-    reqxml = et.Element('configConfMo',
-                        attrib={'cookie': cookie, 'inHierarchical': 'false',
-                                'dn': BASEDN+'/sol-if'})
-    inconfig = et.SubElement(reqxml, 'inConfig')
-    et.SubElement(inconfig, 'solIf',
-                  attrib={'dn': BASEDN+'/sol-if', 'adminState': 'enable',
-                          'speed': '115200', 'comport': 'com0'})
-    respxml = xml_req(ip, reqxml, debug)
-    return respxml
-
-###
-### Boot into UEFI bootloader (we may use this to "park" the host in
-### powered-on state)
-###
-def bootIntoUefi(ip, cookie, debug=False):
-    reqxml = et.Element('configConfMo',
-                        attrib={'cookie': cookie, 'inHierarchical': 'false',
-                                'dn': BASEDN+'/boot-policy'})
-    inconfig = et.SubElement(reqxml, 'inConfig')
-    bootDef = et.SubElement(inconfig, 'lsbootDef',
-                            attrib={'dn': BASEDN+'/boot-policy',
-                                    'rebootOnUpdate': 'yes'})
-    et.SubElement(bootDef, 'lsbootEfi',
-                  attrib={'rn': 'efi-read-only', 'order': '1',
-                          'type': 'efi'})
-
-    respxml = xml_req(ip, reqxml, debug)
-    return respxml
-
-###
-### Boot via PXE. Reboot immediately.
-###
-def bootPXE(ip, cookie, debug=False):
-    reqxml = et.Element('configConfMo',
-                        attrib={'cookie': cookie, 'inHierarchical': 'false',
-                                'dn': BASEDN+'/boot-policy'})
-    inconfig = et.SubElement(reqxml, 'inConfig')
-    bootDef = et.SubElement(inconfig, 'lsbootDef',
-                            attrib={'dn': BASEDN+'/boot-policy',
-                                    'rebootOnUpdate': 'yes'})
-    et.SubElement(bootDef, 'lsbootLan',
-                  attrib={'rn': 'lan-read-only', 'order': '1',
-                          'type': 'lan', 'prot': 'pxe'})
-
-    respxml = xml_req(ip, reqxml, debug)
-    return respxml
-
-
-###
-### Boot via Local HDD first, then via PXE. Do not reboot immediately.
-###
-def bootHDDPXE(ip, cookie, debug=False):
-    reqxml = et.Element('configConfMo',
-                        attrib={'cookie': cookie, 'inHierarchical': 'false',
-                                'dn': BASEDN+'/boot-policy'})
-    inconfig = et.SubElement(reqxml, 'inConfig')
-    bootDef = et.SubElement(inconfig, 'lsbootDef',
-                            attrib={'dn': BASEDN+'/boot-policy',
-                                    'rebootOnUpdate': 'no'})
-    storage = et.SubElement(bootDef, 'lsbootStorage',
-                            attrib={'rn': 'storage-read-write',
-                                    'access': 'read-write',
-                                    'order': '1', 'type': 'storage'})
-    et.SubElement(storage, 'lsbootLocalStorage',
-                  attrib={'rn': 'local-storage'})
-    et.SubElement(bootDef, 'lsbootLan',
-                  attrib={'rn': 'lan-read-only', 'order': '2',
-                          'type': 'lan', 'prot': 'pxe'})
-
-    respxml = xml_req(ip, reqxml, debug)
-    return respxml
-
-###
-### Return LOM port 1 MAC address
-###
-def getLOMMacAddress(ip, cookie, debug=False):
-    reqxml = et.Element('configResolveClass',
-                        attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                'classId': 'networkAdapterUnit'})
-    respxml = xml_req(ip, reqxml, debug)
-    reqxml = et.Element('configResolveDn',
-                        attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                'dn': BASEDN+'/network-adapter-L/eth-1'})
-    respxml = xml_req(ip, reqxml, debug)
-
-    oc = respxml.find('outConfig')
-    netw = oc.find('networkAdapterEthIf')
-    if debug:
-        print "DEBUG: MAC address is {}".format(netw.get('mac'))
-    return netw.get('mac')
-
-###
-### Return all port MAC addresses
-###
-def getMacAddresses(ip, cookie, debug=False):
-    maclist = {}
-    reqxml = et.Element('configResolveClass',
-                        attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                'classId': 'networkAdapterUnit'})
-    respxml = xml_req(ip, reqxml, debug)
-    oc = respxml.find('outConfigs')
-    for adapter in oc.iter('networkAdapterUnit'):
-        if debug:
-            print "DEBUG: ADAPTER SLOT {} MODEL {}".format(adapter.attrib['slot'],
-                                                           adapter.attrib['model'])
-        slot = adapter.attrib['slot']
-        maclist[slot] = {}
-        for port in adapter.iter('networkAdapterEthIf'):
-            if debug:
-                print "DEBUG:    SLOT {} PORT {} MAC {}".format(slot,
-                                                                port.attrib['id'],
-                                                                port.attrib['mac'])
-            maclist[slot][port.attrib['id']] = port.attrib['mac'].lower()
-
-    reqxml = et.Element('configResolveClass',
-                        attrib={'cookie': cookie, 'inHierarchical': 'true',
-                                'classId': 'adaptorUnit'})
-    respxml = xml_req(ip, reqxml, debug)
-    oc = respxml.find('outConfigs')
-    for adapter in oc.iter('adaptorUnit'):
-        if debug:
-            print "DEBUG: VIC ADAPTER SLOT {} MODEL {}".format(adapter.attrib['pciSlot'],
-                                                               adapter.attrib['model'])
-        slot = adapter.attrib['pciSlot']
-        maclist[slot] = {}
-        for port in adapter.iter('adaptorHostEthIf'):
-            portnum = int(re.sub('eth([0-9]+)', '\\1', port.attrib['name']))+1
-            if debug:
-                print "DEBUG:    VIC SLOT {} PORT {} MAC {}".format(slot,
-                                                                    portnum,
-                                                                    port.attrib['mac'])
-            maclist[slot][portnum] = port.attrib['mac'].lower()
-
-    return maclist