I was asked to put up a script that displays an easy way to find a script reference and then start that script. One thing to realize is that the hardest part about the pytwist API, besides some of the obscure functions, is actually finding your references so that you can get the objects to work on.

There are a few ways you can go around doing this. You can use filters and the search capability, you can manually create your ref, or you can find the refs via other objects, like device groups. The last one I mentioned is actually a very good way to loop through a set of systems to perform a task.

I’ll display the first method in this article and write up the other two later.

The first thing we need to do is get our script reference. Every object you work with in SA generally has a reference object and what I call the ‘virtual object’ ( or whatever VO really stands for ). The VO contains all the important attributes where as the reference only contains the id of the object in SA and the name. There are some methods contained in the VO, but the pytwist API makes common use of a ‘Service’ interface for specific types of objects, like the ServerService, the ServerScriptService, the SearchService, JobService, DeviceGroupService and so on that contain the methods that really make use of the VOs.

This first script enables us to run a known SA script on a known host thru SA from a command line. Note that the command line can be any host that has an agent – this doesn’t need to be run from the core.

I’ll show the script first, then explain it. This script is a version that can be run from an agent that has the Python 2 API Access for Server module installed.

import sys
from optparse import OptionParser
from getpass import getpass
sys.path.append('/opt/opsware/smopylibs2')
sys.path.append('/opt/opsware/agent_tools/') 

import agenttools_common
from pytwist import *
from pytwist.com.opsware.server import ServerRef
from pytwist.com.opsware.script import ServerScriptRef
from pytwist.com.opsware.custattr import NoSuchFieldException

ts = twistserver.TwistServer()

ss = ts.server.ServerService
scs = ts.script.ServerScriptService

# This is the same basic authentication scheme used in most of
# my scripts.  You can tear this out and just use the
# ts.authenticate method with the values already filled in.
parser = OptionParser()
parser.add_option("-u","--user",dest="sauser",
                  help="SA login id")
parser.add_option("-p","--pass",dest="sapasswd",
                  help="SA login password")
parser.add_option("-r","--prompt",action="store_true",dest="readstdin",
                  help="Prompt for passwords instead of using arguments")

(options, args) = parser.parse_args()

if not options.sapasswd and not options.readstdin:
        print "You must specify a password to login to SA."
        sys.exit(1)

if not options.sauser:
        print "You must specify a username to login to SA."
        sys.exit(1)

if options.readstdin:
    options.sapasswd = getpass("Enter Opsware Password: ")

ts.authenticate(options.sauser, options.sapasswd)

# Now the real work starts

# Create a reference to a script we know the ID of
# The ID can be obtained from the SA Gui
scriptRef = ServerScriptRef(22530102)

# Create a reference to a server we know about
serverRef = ServerRef(730102)

# In order to run the script, we'll use the startServerScript method
# from the ServerScriptService.  It requires the script ref, an arugments
# object.  We can optionally give it a tag that it will put under
# the ticket ID.  There are also optional arguments for a job notification
# and job schedule that I won't cover here.
#
# We have the reference already, so we need to create the job argument
# object.  We only need to set the list of targets, although there are
# options for setting the username and password of the script

# Creates the object
scriptArgs = com.opsware.script.ServerScriptJobArgs()

# Requires a list of scriptableRefs, which can be ServerRefs,
# DeviceGroupRefs or HypervisorRefs.  In our case, ServerRefs
scriptArgs.targets = [serverRef]

# Now we can run the job
runScript = scs.startServerScript(scriptRef, scriptArgs, 'Ticket ID #001', None, None)
print "Job started as id %d" % runScript.id

So, besides the basic authentication and argument parsing, there isn’t too much to this script. We have to create the references needed and we do that by importing the references in from pytwist and then using them as constructors like so:

from pytwist.com.opsware.server import ServerRef
from pytwist.com.opsware.script import ServerScriptRef
...
scriptRef = ServerScriptRef(22530102)
serverRef = ServerRef(730102)

In order to run the script, we need to call the startServerScript, which is part of the ServerScriptService interface. But, in order to call it, we need to create one more object, the ServerScriptJobArgs object. We create the object by calling the constructor directly:

scriptArgs = com.opsware.script.ServerScriptJobArgs()

You should note that we could have done the same things with the ServerRef and ScriptRef constructors. Instead of importing them and then calling them, we could have simply done this:

scriptRef = com.opsware.script.ScriptRef(22530102)
serverRef = com.opsware.server.ServerRef(730102)

Generally I’m using alot of server refs, so I like to import to save on typing. Either way, we now have a blank ServerScriptJobArgs object that we need to fill. In our case, we only need to fill out the targets attribute, which is actually a list of any Scriptable Ref. This tells our script which targets it’s going to run on. As mentioned in the comments, a scriptable reference is either a DeviceGroupRef, a ServerRef or a HypervisorRef. Since we have a ServerRef, we just need to contain it in a list and assign it to the targets attribute:

scriptArgs.targets = [serverRef]

Everything is setup now, so I can just call the startServerScript method. The method takes 5 arguments, 3 of which are optional. The 3 optional requires are a ticket id tag, a job notification object and a job schedule object. The ticket id tag is just a string, so it’s easy to create but I’m not going to bother with the other two, so our call looks like this:

runScript = scs.startServerScript(scriptRef, scriptArgs, 'Ticket ID #001'
, None, None)

Remember that the ‘scs’ is just a shortcut to the ServerScriptService. We could have called this method another way:

runScript = scs.startServerScript(scriptRef, scriptArgs, 'Ticket ID #001', None, None)

Again, I prefer the former just to save on typing if I plan on using the service multiple times. The method returns a Run Server Script instance, which we can do other things with, but that’ll have to wait for another article. In the example, I print out the job ID so that I can find and verify the job in the GUI easily.

That’s it for now – in the next article I’ll show how you can use the filter to give the user a way to specify the name of the script they want to run and on which servers.

This entry was posted in Coding, Software, Work and tagged . Bookmark the permalink.

5 Responses to HP SA – Running a known script from pytwist

  1. Arun says:

    Steve,
    Works Good!!!

    Thanks
    Arun

  2. Arun says:

    Steve,

    How are you doing?

    I have a doubt in running a known script on managed servers.
    Scenario1:
    Consider a scenario, managed server is unreachable, am running a script against the server.

    Scenario2:
    Consider the script takes too long time to execute the command and it get timed out.

    I can able to see the Exception in Opsware Sas Client (for both scenarios). How to capture it python script using pytwist?


    Thanks
    Arun

  3. steve says:

    Hey Arun,

    So get to job status, you have to look at the JobService portion of pytwist. I’ll try and post something in the next few weeks about how to get more detailed information on the job and how to test for the state of the job.

  4. Paul says:

    Hi Steve,

    How would I go about capturing stdout from the script ? I can run a script and verify JobID in the GUI; however, I would like to capture stdout from that script. It does show up in SA GUI.

  5. Paul says:

    Looks like getServerScriptJobOutput
    did the job.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Browse by Topic