Home Linux Central_Management Satellite_5
Python script to run a command or script  on one or multiple servers from the satellite
WITH GREAT POWERS COMES GREAT RESPONSABILITIES
Needs to be fixed from old wiki import and tested.

#!/usr/bin/python
# 
# run_from_satellite.py
# 
# run a command or script from the satellite servers to satellite client(s)
# using the rhel satellite api
# 
# 
#  Author: Jean-Louis Girard
#  


#----------------------------- Imports ---------------------------------------
import xmlrpclib
from datetime import date, datetime, time, timedelta
import sys
import getopt
import socket
import os


#-------------------------- Global Varialbles --------------------------------
SATELLITE_URL = "http://<satellite_usr>/rpc/api"
SATELLITE_LOGIN = "<user>"
SATELLITE_PASSWORD = "<passwd>"

SERVERNAMES = ''
COMMAND = ''

CLIENT = ''
KEY = ''

#------------------------------ usage ----------------------------------------
def usage():
  print sys.argv[[0]] , ' -s <servers> -c <command>'
  print ''
  print '       -s <servers> can be a list between double quotes "server1 server2 ..."'
  print '                 or a file containing a list of servers, one per line.'
  print ''
  print '       -c <command> can be a command with optional parameters between double quotes "grep root /etc/sudoers"'
  print '                 or path of a script local to where run_from_satellite.py is running from."'
  print ''

#----------------------------- getArgvs --------------------------------------
def getArgvs(argv):

  if len(sys.argv) == 1:
    usage()

  try:
    # : for parameters , ! make the option mandatory
    opts, args = getopt.getopt(argv,"hs:!c:!",[["server="]])
  except getopt.GetoptError:
    usage()
    sys.exit(2)
  for opt, arg in opts:
    if opt == '-h':
      usage()
      sys.exit()
    elif opt in ( "-s", "--server"):
      global SERVERNAMES
      if os.path.isfile(arg):
        SERVERNAMES = [[line.strip() for line in open(arg, 'r')]]
      else:
        SERVERNAMES = arg.split() # split will make SERVERNAMES into a list from the arg delimited with spaces
    elif opt in ( "-c", "--command"):
      global COMMAND
      if os.path.isfile(arg):
        with open (arg, "r") as f:
          COMMAND = f.read()
        f.close()
      else:
        COMMAND = "#!/bin/bash \n" + arg

  if SERVERNAMES == '' or COMMAND == '':
    usage()
    sys.exit()

#------------------------------- getServerId ---------------------------------
def getServerId(serverName, serverList):
  for system in serverList:
    if system[['name']] == serverName:
      return system[['id']]

  #if the server is not found on this satellite return 0
  return 0

#------------------------------ executeOnServer ------------------------------
def executeOnServer(serverId, command):

  global SATELLITE_URL, SATELLITE_LOGIN, SATELLITE_PASSWORD

  global CLIENT
  global KEY



  earliest_occurrence = xmlrpclib.DateTime()
  ID = CLIENT.system.scheduleScriptRun(KEY, serverId, "root", "root", 300, command, earliest_occurrence)
  return ID
#--------------------------------- Main --------------------------------------
if __name__ == "__main__":
  getArgvs(sys.argv[[1:]])

  CLIENT = xmlrpclib.Server(SATELLITE_URL, verbose=0)
  KEY = CLIENT.auth.login(SATELLITE_LOGIN, SATELLITE_PASSWORD)

  satellite_clients = CLIENT.system.listUserSystems(KEY)

  for servername in SERVERNAMES:

    id = getServerId(servername, satellite_clients)

    if id == 0:
      print servername , "does not exist, skipping ..."
    else:
      execID = executeOnServer(id, COMMAND)
      execIdList.append(execID)
      print servername + " : " , execID

  # if we sent an excecution to any server(s) then print the command to get the results.
  if execIdList:
    print "To get the results run the following command: "
    print "./satellite_getScriptResults.py",
    for oneId in execIdList:
      print oneId,
    print ""


  CLIENT.auth.logout(KEY)