Enumerate Clusters and Set One Password

July 8, 2020

by Ed McAndrew

Intended Audience Level: Beginner/Intro

Code Sample Type: Snippet

Nutanix Technologies: Prism Central, Prism Element

Minimum Product Version: AOS 5.10.x or higher and AHV

Script/Code Language: Python

REST API Sample? No

REST API Version: N/A

Enumerate all Nutanix Clusters registered to Prism Central, connect to destination VIP address, set AHV root password along with CVM nutanix password and reset logon count before moving on.

Code Sample Details

This section may be empty if additional code sample details are not available.
# -*- coding: utf-8 -*-
#.notes
#################################################
#		Enumerate Clusters and Set One Password
#		Script Version :         1.0.0
#################################################
#.prerequisites
#		1. AOS 5.10 or above
#		2. AHV Hypervisor
#		3. Prism Central
#		4. Prism Element Registrations to Prism Central
#.synopsis
#		Enumerate all Nutanix Clusters registered to Prism Central, connect to destination VIP address, set AHV root password along with CVM nutanix password and reset logon count before moving on.
#.disclaimer
#		This code is intended as a standalone example. Subject to licensing restrictions defined on nutanix.dev, this can be downloaded, copied and/or modified in any way you see fit.
#
#		Please be aware that all public code samples provided by Nutanix are unofficial in nature, are provided as examples only, are unsupported and will need to be heavily scrutinized and potentially modified before they can be used in a production environment. All such code samples are provided on an as-is basis, and Nutanix expressly disclaims all warranties, express or implied.
#
#		All code samples are © Nutanix, Inc., and are provided as-is under the MIT license. (https://opensource.org/licenses/MIT)
#
#################################################
import crypt
import pexpect
import subprocess
import sys

my_method = crypt.METHOD_SHA512
my_default_password = 'nutanix/4u' # Remove this, leave the single quotes to be prompted for a password later.  Or change it to your password here.

def main():
        print '\nNutanix Password Change Script'
        print '\nThis will enumerate all clusters registered to Prism Central\nand Change CVM "nutanix" and AHV "root" user accounts.\n'

        my_new_password = raw_input('Please Enter New Password: ')
        my_new_password_confirm = raw_input('Please Confirm New Password: ')

        if my_new_password != my_new_password_confirm:
                sys.exit('New passwords do not match, terminating... \n')

        my_encrypted_password = crypt.crypt(my_new_password, crypt.mksalt(my_method))
        my_escaped_my_encrypted_password = my_encrypted_password.replace('$','\$')
        print '\nEncrypted String: ' + my_escaped_my_encrypted_password
        print '\nQuerying NCLI for registered clusters'

        my_cluster_vips = subprocess.check_output('/home/nutanix/prism/cli/ncli multicluster get-cluster-state | /usr/bin/grep External | /usr/bin/awk \'{print $NF}\'', shell=True)

        for my_line in my_cluster_vips.split('\n'):
                if len(my_line.strip()) > 0:
                        my_ip_address = my_line
                        print('\nConnecting to: ' + my_line)
                        if not my_default_password:
                                my_cluster_password = raw_input('\nPlease enter cluster password for ' + my_ip_address + ': ')
                        else:
                                my_cluster_password = my_default_password

                        try:
                                print('\n')
                                my_ssh = pexpect.spawn('ssh -t nutanix@' + my_line)
                                my_ssh.setecho(False)
                                my_ssh.logfile_read = sys.stdout

                                my_ssh.expect('assword:')
                                my_ssh.sendline(my_cluster_password)

                                my_ssh.expect('((?:nutanix@NTNX-).+(?:CVM:).+:~\$)')
                                my_ssh.sendline(
                                        '/usr/bin/echo;'\
                                        'for i in $(/usr/local/nutanix/cluster/bin/hostips);do '\
                                        '/usr/bin/ssh root@$i "/usr/bin/echo "-Setting \"root\" password on host: $i" && '\
                                        '/usr/sbin/chpasswd -e <<< \'root:' + my_escaped_my_encrypted_password + '\' && '\
                                        '/usr/bin/echo "--Resetting \"root\" account login count." && /usr/sbin/faillock --user root --reset";done && '\
                                        'for j in $(/usr/local/nutanix/cluster/bin/svmips);do '\
                                        '/usr/bin/ssh nutanix@$j "/usr/bin/echo "-Setting \"nutanix\" password on CVM: $j" && '\
                                        '/usr/bin/sudo /usr/sbin/chpasswd -e <<< \'nutanix:' + my_escaped_my_encrypted_password + '\' && '\
                                        '/usr/bin/echo "--Resetting \"nutanix\" account login count." && /usr/bin/sudo /usr/sbin/faillock --user nutanix --reset";'\
                                        'done && exit'
                                )
                                my_ssh.expect(pexpect.EOF)
                        except pexpect.ExceptionPexpect as e:
                                print("\nERROR: pxssh failed on login!\n")
                                #print(e)

if __name__ == "__main__":
        main()