Code Walkthru

As we discuss each source file, have your browser open it in another window so you can have it next to
this discussion.


At the top, we import some python modules need, starting with sys,

We then have commented out some code to use the ups "" module to setup ups products and/or
to setup a given version of python; folks may need to uncomment these on various installations to
get a version of python that can run the suds package,
which is the underpinning of this whole suite

Next we import modules from our source directory, HelpDesk (the underlying connection storing object),
HelpDeskException (the exception class it raises), SubmitTicket and ConfigParser objects, which will
be described a bit further down in detail, and finall the
os and (redundantly) sys again (that second sys import should be able to be dropped).

Next we define a CreateEntry object, which takes as paramters the arguments that will be used when creating the servicedesk ticket; the arguments of its init method correspond to the command line arguments of the script, and the config file


In the init method we first build a ConfigParser object out of our config file, and extract some extra parameters
from it. This look kind of goofy, until you realize that this script is trying to be backwards compatible, and
it needed information that the original version did not take on the command line.

So after we extract assorted values from the config file, we pick some things out from the command line parameters.
In particular ciname (Configuration Item Name) which is converted to upper case (which is how they are stored in the database) and several parameters which are ignored if given on the command line.

Next we create a SubmitTicket object, passing in ticke values, and then set a few more fields (the CIName and Notes)
and also a few optional items, if they are present in the config file, "service", "category", "type" and "item";
and finally we have teh SubmitTicket Object actually submit the ticket, and print the returned ticket number.

Finally, if this script was invokeed directly from the command line ( __name__== '__main__' ) we create a
helpdesk connection singleton, and call create entry with our command line parameters.


This file has the connection object that holds soap connections. The generalClient and submitClient are actually the same SOAP service in Service-NOw, but they used to be separate in Remedy, so that wierdness survives.

The imports for this module are straigthforward, we have the import of the suds Client module, which is the SOAP client library we're using, and also the WebFault class from the same package. Finally, we impot our HelpDeskConfig class, which is pretty much a wrapper around the python ConfigParser,
and the logging package, which we use to turn on the logging in suds if needed.

We make a constant string HELPDESK for the name of the config file section that has url's we need, etc.

class HelpDesk

This is a singleton class that holds our connection objects for making servicedesk requests; so that if you make multiple tickets you don't get multiple connections. The first bit is the class variable for the singleton object.

__init__ method

THe init method fills in data members from the config file object, and turns on suds loggin if the "sudsDump" config option is present.

create method

This is the method used to create the singleton. Once it's been called, and the Helpdesk.singleton object has
been set, you always get the same one back.

getSubmitClient and getGeneralClient methods

These make suds connection objects if needed and return them. It turns out that with ServiceNow these could really be the same connection object; as they both use the same SOAP interface, they are different because this is a rework of the Remedy module where it was a different SOAP interface to update tickets than to submit new ones.

getAcct and getPasswd methods

Basic accessor methods, which just return the values. Not sure anything actually uses them...

HelpDeskException class

Just a subclass of the python Exception class.


This module has a class which is just a subclass of ConfigParser which uses an environment varible ($HELPDESK_CFG_FILE) (or a passed in environment variable) to find the config file if no pathname to find it is passed in.


THis module is the one used to modify existing tickets. It starts off with the usual imports, then has a list of what it thinks are the field names in incidents. In a Perfect World, it would actually look at the suds connection stuff to get the list from the WSDL, but instead it is currently hard coded.

ModifyTicket class

This is the class you use to modify an existing ticket. You make a ModifyTicket instance, set fields that you want to modify via the various setXxx methods,, and tell it to actually make the modification by calling the Modify method.

__init__ method

Here we just initialize an empty arguments map, and keep a reference to the Helpdesk connection wrapper, and grab a reference to its general client.

setModifyArgs method

This method adds things to self.args, after running them through the RemedyCompat routine, which translates certain Remedy fieldnames into Service-Now fieldnames

setImpactType, setUrgencyType, setStatusType methods

These set fields making sure it is a valid value using __verifyParameter

setNotes method

This sets the notes (Description) field of the ticket

getTicket method

Fetches a particular ticket by ticket number and returns the dictionary of the fields. It calls getRecords which
returns a list of ticket dictionaries, so it returns the zeroth element of the list.

RemedyCompat method

This converts Remedy field names to ServiceNow names for some fields. This was an attempt to let some of the
code that used the Remedy calls to continue unmodified. Probably it could be dropped at some point.
If multiple fields map to the same destination, it combines them with newlines, since the work_notes field
is a single field in ServiceNow, but has a Summary and NOtes part in Remedy...

Modify method

This actually does the change. If it's given arguments, it does the setModifyArgs call to merge them into self.args.
Then it gets the existing values for the ticket with getTicket, and it makes a local args dictionary with the
fields from the original ticket, overlaid with the self.args values, and then it uses the update SOAP call
to set the fields on the ticket. If we don't get a response we like back, or if anythign went wrong, we raise exceptions.

__verifyParameter method

Just checks a parameter against a list of allowed values, and raises an exception if it isn't found.


This sets the external contact fields on a ticket. In Service now this could just as easily be done with ModifyTicket, but in the old Remedy stuff this was yet a third, custom SOAP interface, so there was a separate call and access class for it in the Remedy version and we have it here for completeness. In the Service-Now implementation, it is a subclass of ModifyTicket that lets you lookup tickets by external ticket number, etc.

It gets used by the footprints_forwarder, but might be useful for any interface that wants to put in a reference to a ticket in another support center.

getExt method

This grabs a ticket with getTicet and returns its external_ticket_number field

getExtByExt method

This does a lookup using the external ticket number and support center and returns the local ticket number
(if any).

setExt method

This just uses SetModifyArgs to add external ticket number fields to the change, and actually modifies the ticket.


This is the class we use to submit new tickets.

We start with imports of the builting string, and datetime libraries, as well as our Helpdesk connection
class, and the suds WebFault for exceptions.

SubmitTicket class

__init__ method

This tries to be compatable with 3 different branches of the {remedy,servicenow}_soap code that grew up at one point, so it takes unspecified keyword args, and looks for values in them, as well as some attempts at Remedy compatability (I.e. allowing Last_Name and First_Name or caller...)

Note the datetime incantation setting self.opened_at -- this tries to force us to UCT. we NEED the account used for creating/updating tickets to have it's timezone set to UCT as well, otherwise we get dates shifting 5 or 6 hours
everytime tickets are updated...

setXxx methods

There are about 16 methods to set various fields in the ticket which can be called separately, once the SubmitTicket object has been created, they just squirrel away the data for the...

submit method

This actually creates the ticket, using the insert method in the SOAP interface. Slightly odd bits are stuck in here:

  1. the categorization is the category, type, and item smushed together with -- symbols; this probalby needs to be
    fixed up to allow the upper level categories to be used, where you don't want an extra '--' or two.
  2. Note that we set u_monitored_ci_name instead of cmdb_ci, this is to let the Service-Now folks filter it before it goes
    into the regular cmdb_ci field.
  3. we of course raise exceptions of anything appears to go wrong.
  4. we have the same __verifyParameter method thta ModifyTicket does, and quite possbily we should use it :-).