From 6da3d8ee0eda8b1550b3c699524c5303184cffaa Mon Sep 17 00:00:00 2001 From: Victor Hu Date: Thu, 5 Feb 2015 15:57:37 -0500 Subject: [PATCH] getslnodes.py was using argparse, which is not included on centos6.5 and not available in python 2.6... switched to using docopt for command line interface argument parsing. This python library is pulled in by the SoftLayer python bindings so it's not an extra step. --- xCAT-SoftLayer/bin/getslnodes.py | 137 +++++++++++++++++++------------ 1 file changed, 83 insertions(+), 54 deletions(-) diff --git a/xCAT-SoftLayer/bin/getslnodes.py b/xCAT-SoftLayer/bin/getslnodes.py index dd911dd38..51ee03662 100755 --- a/xCAT-SoftLayer/bin/getslnodes.py +++ b/xCAT-SoftLayer/bin/getslnodes.py @@ -1,28 +1,36 @@ #!/usr/bin/env python -# Query the softlayer account for info about all of the bare metal servers and -# put the info in mkdef stanza format, so the node can be defined in the xcat db -# so that xcat can manage/deploy them. +""" +Usage: getslnodes.py [-h] [-v] [] + +Description: +Query your SoftLayer account and get attributes for each bare metal server. +The attributes can be piped to 'mkdef -z' to define the nodes into the xCAT +Database so that xCAT can manage them. + +getslnodes requires a the .softlayer configuration file defined which can +be set by running "sl config setup" on the command line. + +positional arguments: + hostname-match Select servers that include this partial hostname. + +Optional: + -h, --help show this help message and exit + -v, --verbose display verbose output +""" + +import sys try: - import sys + import docopt import pprint - import argparse import SoftLayer except ImportError as e: - print 'Error: install missing python module before running this command: '+str(e) + print 'Error: install missing python module before running this command: ' + str(e) sys.exit(2) -# Process the cmd line args -# --help is automatically provided by this -parser = argparse.ArgumentParser(description="Query your SoftLayer account and get attributes for each bare metal server. The attributes can be piped to 'mkdef -z' to define the nodes in the xCAT DB so that xCAT can manage them. getslnodes requires a .softlayer file in your home directory that contains your SoftLayer username, api_key, and optionally endpoint_url.") -parser.add_argument('hnmatch', metavar='hostname-match', nargs='?', help='Select servers that include this partial hostname.') -parser.add_argument('-v', "--verbose", action="store_true", help="display verbose output") -args = parser.parse_args() -hnmatch = args.hnmatch # if they specified a hostname match, only show svrs that start with that +def get_sl_servers(): -# Get info from softlayer -try: # username, api_key, endpoint_url come from the .softlayer file client = SoftLayer.Client() @@ -30,53 +38,74 @@ try: operatingSystem.id, operatingSystem.passwords.username, operatingSystem.passwords.password, \ remoteManagementAccounts.username, remoteManagementAccounts.password, remoteManagementComponent.ipmiIpAddress, \ primaryBackendNetworkComponent.primaryIpAddress, primaryBackendNetworkComponent.macAddress" + # # If they specified hnmatch, it would be faster to have softlayer filter the response with something like: # filter={'hardware': {'hostname': {'operation': '*= '+hostname}, 'domain': {'operation': '*= '+domain}}} # But those 2 operations are ANDed together, so it will not work. And currently, filtering does not work on fullyQualifiedDomainName. + # servers = client['Account'].getHardware(mask=mask) - if args.verbose: pprint.pprint(servers) -except SoftLayer.exceptions.SoftLayerAPIError as e: - print 'Error: '+str(e) + return servers + +def print_xcat_node_stanza(servers, hnmatch): -# print info out in xcat node stanza format -for server in servers: - if hnmatch and server['fullyQualifiedDomainName'].find(hnmatch) == -1: continue - print "\n"+server['hostname']+":" - print "\tobjtype=node" - print "\tgroups=slnode,ipmi,all" - print "\tmgt=ipmi" - print "\tbmc="+server['remoteManagementComponent']['ipmiIpAddress'] + for server in servers: + if hnmatch and server['fullyQualifiedDomainName'].find(hnmatch) == -1: + continue - # I have seen svrs with no remoteManagementAccounts entries - if len(server['remoteManagementAccounts']): - print "\tbmcusername="+server['remoteManagementAccounts'][0]['username'] - print "\tbmcpassword="+server['remoteManagementAccounts'][0]['password'] + print "\n"+server['hostname']+":" + print "\tobjtype=node" + print "\tgroups=slnode,ipmi,all" + print "\tmgt=ipmi" + print "\tbmc="+server['remoteManagementComponent']['ipmiIpAddress'] - print "\tip="+server['primaryBackendNetworkComponent']['primaryIpAddress'] - print "\tmac="+server['primaryBackendNetworkComponent']['macAddress'] - print "\tserial="+server['manufacturerSerialNumber'] - print "\tnetboot=xnba" - print "\tarch=x86_64" + # I have seen svrs with no remoteManagementAccounts entries + if len(server['remoteManagementAccounts']): + print "\tbmcusername="+server['remoteManagementAccounts'][0]['username'] + print "\tbmcpassword="+server['remoteManagementAccounts'][0]['password'] - # Find the root or Administrator username and pw - username = None - password = None - for entry in server['operatingSystem']['passwords']: - if entry['username'] == 'root' or entry['username'] == 'Administrator': - # found it - username = entry['username'] - password = entry['password'] - break - elif not username: - # save the 1st entry, in case we never find root or Administrator - username = entry['username'] - password = entry['password'] - if username and password: userStr = ", user:"+username+", pw:"+password - print "\tusercomment=hostname:"+server['fullyQualifiedDomainName']+userStr -sys.exit(0) + print "\tip="+server['primaryBackendNetworkComponent']['primaryIpAddress'] + print "\tmac="+server['primaryBackendNetworkComponent']['macAddress'] + print "\tserial="+server['manufacturerSerialNumber'] + print "\tnetboot=xnba" + print "\tarch=x86_64" + + # Find the root or Administrator username and pw + username = None + password = None + for entry in server['operatingSystem']['passwords']: + if entry['username'] == 'root' or entry['username'] == 'Administrator': + # found it + username = entry['username'] + password = entry['password'] + break + elif not username: + # save the 1st entry, in case we never find root or Administrator + username = entry['username'] + password = entry['password'] + + if username and password: + userStr = ", user:"+username+", pw:"+password + + print "\tusercomment=hostname:"+server['fullyQualifiedDomainName']+userStr -def verbose(text): - '''Print msg only if -v was specified.''' - if args.verbose: print text + +if __name__ == '__main__': + try: + arguments = (docopt.docopt(__doc__, version="1.0")) + # print arguments + + servers = get_sl_servers() + if arguments['--verbose']: + pprint.pprint(servers) + + print_xcat_node_stanza(servers, arguments['']) + + except docopt.DocoptExit as e: + print e + except SoftLayer.exceptions.SoftLayerAPIError as e: + print e + + sys.exit(1) +