Пример «скрипта» python, который управляет различными сервисами на нескольких удаленных серверах:
Ниже приведен взломанный сценарий, который можно использовать для управления различными службами на серверах, к которым у вас есть доступ по SSH.
В идеале вам захочется запустить ssh-agent, или вы будете много раз вводить парольную фразу.
Для команд, которым требуются повышенные привилегии на удаленном компьютере, вы можете видеть, что вызывается «sudo». Это означает, что вам нужно изменить файл sudoers на каждом удаленном компьютере и добавить записи, подобные этой (при условии, что ваше имя пользователя == deploy
):
Defaults:deploy !requiretty
Defaults:deploy !authenticate
deploy ALL=\
/sbin/service httpd status,\
/sbin/service httpd configtest,\
/sbin/service httpd graceful
Первые две строки позволяют пользователю deploy
запускать sudo
без ввода tty или повторного ввода пароля - это означает, что его можно запустить прямо через ssh без дальнейшего ввода. Вот пример команды python для использования sudo
на удаленном компьютере:
CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd graceful'))
В любом случае, это не «прямой» ответ на ваш вопрос, а скорее иллюстрация того, насколько легко вы можете использовать python и пару других методов для создания инструмента управления системами, который на 100% адаптирован к вашим конкретным потребностям.
И, между прочим, следующий скрипт «громко и ясно говорит вам», если какая-либо из команд вернула статус выхода> 0, так что вы можете самостоятельно проанализировать вывод.
Это было взломано вместе, когда проект, с которым я работал, начал использовать балансировщик нагрузки, и больше не было справедливо запускать все команды на каждом сервере. Вы можете изменить или расширить это для работы с rsync для развертывания файлов или даже для развертывания обновлений в сценариях, которые вы размещаете на удаленных серверах, чтобы «выполнить работу».
#!/usr/bin/python
from optparse import OptionParser
import subprocess
import sys
def die(sMessage):
print
print sMessage
print
sys.exit(2)
###################################################################################################
# Settings
# The user@host: for the SourceURLs (NO TRAILING SLASH)
RemoteUsers = [
"deploy@ac10.example.com",
"deploy@ac11.example.com",
]
###################################################################################################
# Global Variables
# optparse.Parser instance
Parser = None
# optparse.Values instance full of command line options
Opt = None
# List of command line arguments
Arg = None
###################################################################################################
Parser = OptionParser(usage="%prog [options] [Command[, Subcommand]]")
Parser.add_option("--interactive",
dest = "Interactive",
action = "store_true",
default = False,
help = "Ask before doing each operation."
)
# Parse command line
Opt, Arg = Parser.parse_args()
def HelpAndExit():
print "This command is used to run commands on the application servers."
print
print "Usage:"
print " deploy-control [--interactive] Command"
print
print "Options:"
print " --interactive :: will ask before executing each operation"
print
print "Servers:"
for s in RemoteUsers: print " " + s
print
print "Web Server Commands:"
print " deploy-control httpd status"
print " deploy-control httpd configtest"
print " deploy-control httpd graceful"
print " deploy-control loadbalancer in"
print " deploy-control loadbalancer out"
print
print "App Server Commands:"
print " deploy-control 6x6server status"
print " deploy-control 6x6server stop"
print " deploy-control 6x6server start"
print " deploy-control 6x6server status"
print " deploy-control wb4server stop"
print " deploy-control wb4server start"
print " deploy-control wb4server restart"
print " deploy-control wb4server restart"
print
print "System Commands:"
print " deploy-control disk usage"
print " deploy-control uptime"
print
sys.exit(2)
def YesNo(sPrompt):
while True:
s = raw_input(sPrompt)
if s in ('y', 'yes'):
return True
elif s in ('n', 'no'):
return False
else:
print "Invalid input!"
# Implicitly verified below in if/else
Command = tuple(Arg)
if Command in (('help',), ()):
HelpAndExit()
ResultList = []
###################################################################################################
for UH in RemoteUsers:
print "-"*80
print "Running %s command on: %s" % (Command, UH)
if Opt.Interactive and not YesNo("Do you want to run this command? "):
print "Skipping!"
print
continue
#----------------------------------------------------------------------------------------------
if Command == ('httpd', 'configtest'):
CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd configtest'))
#----------------------------------------------------------------------------------------------
elif Command == ('httpd', 'graceful'):
CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd graceful'))
#----------------------------------------------------------------------------------------------
elif Command == ('httpd', 'status'):
CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd status'))
#----------------------------------------------------------------------------------------------
elif Command == ('loadbalancer', 'in'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/loadbalancer-in'))
#----------------------------------------------------------------------------------------------
elif Command == ('loadbalancer', 'out'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/loadbalancer-out'))
#----------------------------------------------------------------------------------------------
elif Command == ('disk', 'usage'):
CommandResult = subprocess.call(('ssh', UH, 'df -h'))
#----------------------------------------------------------------------------------------------
elif Command == ('uptime',):
CommandResult = subprocess.call(('ssh', UH, 'uptime'))
#----------------------------------------------------------------------------------------------
elif Command == ('6x6server', 'status'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/6x6server-status'))
if CommandResult > 0:
print "Servers not running!!!"
#----------------------------------------------------------------------------------------------
elif Command == ('6x6server', 'stop'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/6x6server-stop'))
#----------------------------------------------------------------------------------------------
elif Command == ('6x6server', 'start'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/6x6server-start'))
#----------------------------------------------------------------------------------------------
elif Command == ('6x6server', 'restart'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/6x6server-restart'))
#----------------------------------------------------------------------------------------------
elif Command == ('wb4server', 'status'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/wb4server-status'))
if CommandResult > 0:
print "Servers not running!!!"
#----------------------------------------------------------------------------------------------
elif Command == ('wb4server', 'stop'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/wb4server-stop'))
#----------------------------------------------------------------------------------------------
elif Command == ('wb4server', 'start'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/wb4server-start'))
#----------------------------------------------------------------------------------------------
elif Command == ('wb4server', 'restart'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/wb4server-restart'))
#----------------------------------------------------------------------------------------------
else:
print
print "#"*80
print
print "Error: invalid command"
print
HelpAndExit()
#----------------------------------------------------------------------------------------------
ResultList.append(CommandResult)
print
###################################################################################################
if any(ResultList):
print "#"*80
print "#"*80
print "#"*80
print
print "ERRORS FOUND. SEE ABOVE"
print
sys.exit(0)
else:
print "-"*80
print
print "Looks OK!"
print
sys.exit(1)