I want to automatically login an Azure system to access the virtual machine. I run the following code:
process_1 = subprocess.call(key.SSH_KEY + ' | ' + key.PASSKEY, shell = True) # Login to virtual machine
and receive the following:
/bin/sh: key.PASSKEY: command not found
azureuser#xx.xx.1x.1xx's password:
It believes the key.PASSKEY is another command, when it is the input for the azureuser#xx.xx.1x.1xx's password: part. How do I make sure that the key.PASSKEY is entered as the password automatically when this subprocess command is run?
The answer was found using the following video: https://www.youtube.com/watch?v=8QfD8V_-7ok
I did:
ch = pexpect.spawn(key.SSH_KEY)
ch.logfile = sys.stdout.buffer
ch.expect("azureuser#xx.xx.1x.1xx's password:")
ch.sendline(key.PASSKEY)
ch.expect("azureuser#vm")
ch.sendline('ls')
Related
I am pretty new to Pyvmomi and vsphere automation.
I have been trying to automate the user and group creation in vsphere but could not locate the method in Pyvmomi which could help me automate the process of user creation.
I already have a user created in vcenter (abc#xyz.local)
This user has administrative privileges
Now, I want to create a session with user abc#xyz.local and add new users in Vcenter 'users and groups'. Once the new users are created, I have to add these users to different groups.
All these has to be done via automation using python.
Is there a way to automate this?
Unfortunately, the SSO API is all private and unavailable through pyvmomi and the rest of the SDKs.
As #Kyle Ruddy says, it looks like pyvmomi does not support SSO APIs. However, the golang alternative (govmomi) does. Govmomi also has an a CLI called GOVC which provides a nice wrapper to perform the following (and other things!):
Creating groups
Adding users to groups
Creating users
You could look at GOVCs source code and try and figure out the SOAP calls, but I think that would be more trouble than its worth.
If you are open to the idea of launching a bash commands from python then you could do the following:
import subprocess
import os
# Handy function for GOVC and assume GOVC is on your $PATH
def govc_runner(command):
my_env = os.environ.copy()
# Admin user will need to perform the commmands
my_env["GOVC_USERNAME"] = "abc#xyz.local"
my_env["GOVC_PASSWORD"] = "<ABC_PASSWORD>"
my_env["GOVC_URL"] = "https://<VCENTER>"
my_env["GOVC_INSECURE"] = "true"
process = subprocess.Popen(command, env=my_env, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = process.communicate()
return output, error
# New group and user info
newUserUsername = "praseemol"
newUserPassword = "<PARASEEMOL_PASSWORD>"
newGroup = "prasGroup"
# Creating new group and user
govc_runner("govc sso.group.create " + newGroup)
govc_runner("govc sso.user.create -p '" + newUserPassword + "' '" + newUserUsername + "'")
govc_runner("govc sso.group.update -a " + newUserUsername + " " + newGroup)
# Check if it has worked
output, error = govc_runner("govc sso.user.id " + newUserUsername)
if newGroup in output:
print("Yay, it worked:\n" + output)
else:
print("Something went wrong :(")
Hope that helps!
You can automate shell(vcenter) execution by doing ssh through putty for creation of user in system domain of vcenter and mimic same using paramiko library of python.
Official docs to refer for system domain user creation:
https://docs.vmware.com/en/VMware-vSphere/6.0/com.vmware.vsphere.security.doc/GUID-4FBEA58E-9492-409B-B584-C18477F041D8.html
Commands to be executed on vcenter shell:
/usr/lib/vmware-vmafd/bin/dir-cli user create --account william --first-name william --last-name lam --user-password 'VMware1!'
Refer:https://williamlam.com/2015/05/vcenter-server-6-0-tidbits-part-9-creating-managing-sso-users-using-dir-cli.html
To connect to vcenter using paramiko:
How do you execute multiple commands in a single session in Paramiko? (Python)
Pick the answer by "This".
You can fetch the created user using powercli commands:
Get-VIAccount
While using this be sure to find your created user in system domain.
Get_VIAccount -Domain 'domain_name'
The default domain name is usually like: "vsphere.local"
You can also find your domain by using putty to vcenter, enter shell and write,
"sso-config.sh -get_identity_sources"
You will be able to read Sys_Domain: '......'
You can assign role to user using powercli:
Get-VIPermission
If You can automate local user creation, let me know:
https://docs.vmware.com/en/VMware-vSphere/6.7/com.vmware.vsphere.vcsa.doc/GUID-533AE852-A1F9-404E-8AC6-5D9FD65464E5.html
I would like to securely ask a password to a user and then pass it to subprocess.Popen to run a command that requires it.
I have seen this question and that one, but I wonder if I can securely pass the password via the subprocess environment like that:
import subprocess, os
user_password = input("what is you password?")
my_env = os.environ.copy()
my_env["userpass"] = user_password
my_command = "python --version"
subprocess.Popen(my_command, env=my_env)
Will the password be flushed once the python script is closed ? I have look at the subprocess documentation but it's not explained.
When I add this line print(os.environ['userpass']) at the end of my code to print the OS environment, I can retrieve the user password. Do it means that the password can be access by the other running processes ?
Edit: I can't pipe the password as the command I use doesn't read its password from standard input
I would like to restrict ability to run my Python 3 script to certain host and users on Linux. Is there any Python 3.x build in function or library which would allow me to do this relatively easy please?
Not exactly a Python answer, but a Linux one - you may add all users who can run a script to some group:
groupadd allowed-users
usermod -a -G allowed-users some-user
Then change group of the script and restrict read access to it only for group (if user can't read a script it can't run it).
chown allowed-users script.py
chmod 640 script.py
I'm sure there is a better way of doing that but below is my first attempt.
#!/usr/bin/python3
import getpass
import socket
hostname = socket.gethostname()
username = getpass.getuser()
allowedusers = 'user1'
allowedhosts = 'host1'
if hostname in allowedhosts:
print('hostname allowed')
if username in allowedusers:
print('user allowed')
else:
print('username not allowed')
exit()
else:
print('hostname not allowed')
exit()
print('script will continue to run as hostname and user are allowed')
I am struggling to make a program on Python (Ubuntu) "To get a file from a directly connected Linux machine without prompting for Password"
Right now I am using this command on python but wanna put password in advance so it will not prompt me for password.
import os
os.system("echo 'hello world'")
os.system("rsync -rav pi#192.168.2.34:python ~/")
IP Address of Other Linux Machine is: 192.168.2.34
Password is: raspberry
Hostname: pi
You can achieve this by exchanging private keys. This way you can get a file from a directly connected Linux machine without prompting for Password. Here are the steps to exchange private keys:
Execute command ssh-keygen on your Ubuntu terminal.
Keep on pressing enter until something like this shows up:
The key's randomart image is:
+--[ RSA 2048]----+
| . .*|
| . + +o|
| + * + .|
| o E * * |
| S + + o +|
| o o o |
| . . . |
| |
| |
+-----------------+
After that execute ssh-copy-id pi#192.168.2.34 and enter password i.e., raspberry, if that is the password for the other machine.
Now execute python script as normal and it wont prompt for password.
import os
os.system("echo 'hello world'")
os.system("rsync -rav pi#192.168.2.34:python ~/")
You can try the following using pexpect and subprocess, the pexpect should definitely work, subprocess I am not sure:
cmd = "rsync -rav pi#192.168.2.34:python ~/"
from pexpect import *
run(cmd,events={'(?i)password':'your_password\r'})
from subprocess import PIPE,Popen
cmd = "rsync -rav pi#192.168.2.34:python ~/"
proc = Popen(cmd.split(),stdin=PIPE)
proc.stdin.write('your_pass\r')
proc.stdin.flush()
If you don't have pexpect installed use pip install pexpect
If you are on a private network (it should be as addresses are 192.168..), and if you trust all IP addresses on that network (means that no unauthorized user can spool an IP), you can also use host based authentication.
Extract from man page for ssh (I assume you use it as the underlying protocol for rsync) :
Host-based authentication works as follows: If the machine the user logs in from is listed in /etc/hosts.equiv or /etc/shosts.equiv on the remote machine, and the user names are the same on both sides, or if the files ~/.rhosts or ~/.shosts exist in the user's home directory on the remote machine and contain a line containing the name of the client machine and the name of the user on that machine, the user is considered for login.
That is you put in pi home directory a file .shosts containing one line
name_or_ip_address_of_source_machine user_name_on_source_machine
if the file already exists, just add that line.
But ... you must understand that as for BHAT IRSHAD's solution, it implies that you are now allowed to pass any command on dest machine as user pi without password.
I'm having an error I can't seem to get past. I have a simple fabric task that must be run as a different user on the remote system, e.g:
def update():
env.user = 'otheruser'
#~ env.password = 'otherpass' # this works, but I don't want it here.
with cd(env.sitefolder):
run('hg pull -u')
If I run this with env.password hardcoded it works. If I use fab -p otherpass update it works too. If I omit it the docs say I will get prompted. This is true, but it doesn't work. Every time after entering the password I get this error:
> fab dev update
[darkstar] Executing task 'update'
[darkstar] run: hg pull -u
[darkstar] Login password:
ERROR:paramiko.transport:Exception: Error reading SSH protocol banner
...
Fatal error: Error reading SSH protocol banner
Aborting.
Using fabric 1.2.2 on Ubuntu Natty. I also tried the env.no_keys option but it didn't change anything. Can anyone help?
Prompt for the password yourself!
def update():
env.user = 'otheruser'
env.password = getpass.getpass('Enter password: ')
with cd(env.sitefolder):
run('hg pull -u')
getpass is part of the standard library, it's just a raw_input that doesn't echo what you type
This can also happen if target is out of memory/disk space. Restarting and/or solving memory/disk space problems can solve this.