open secondary menu close secondary menu

Men & Mice Web Service: SOAP API

The Men & Mice Suite provides a large number of powerful features to manage DNS, DHCP and IP infrastructures of all sizes. All of these features are accessible through the Men & Mice GUI client or the web interface that come with the Suite.

An alternative to using the graphical tools, is to use the Men & Mice web service API to automate repetitive tasks. The web service has even been used to build new custom applications on top of the Men & Mice Suite. In this article, a brief overview of the API is given, followed by a short example to demonstrate how the service can be used.

Overview

The Men & Mice web service API first came out in 2008, and has been in constant development ever since. It uses the Simple Object Access protocol (SOAP) and has a Web Service Description Language (WSDL) definition that describes all operations that can be done. All new features in the Suite are implemented for the web service, so everything that can be done using the GUI tools can also be done through the API. The latest official API documentation can be found here. You can also see what operations are supported by your current release by connecting to the Men & Mice Central server that comes with the Suite (see the official API documentation for further details).

Examples of what users are doing with the Men & Mice web service include:

  • Search for DNS records in all zones that match a particular name.
  • Change the time to live (TTL) for all DNS records containing a certain pattern.
  • Construct a report for DHCP scope options and address pools, and e-mail to responsible personnel.
  • Automatically create DHCP reservations when deploying virtual machines.
  • Create DNS zones in bulk according to a template.
  • Manage a list of blacklisted DNS zones.
  • Run periodically a cleanup of IP addresses that haven't been seen on the network for some fixed time period.
  • Find the next free IP address, and create records and/or reservations through own web portals.

Numerous SOAP clients exist for different programming languages. For this article, we will be using the python programming language and the suds SOAP framework.

The first thing to do, when using the web service is to download the WSDL file from the Men & Mice Central server, that defines what SOAP commands are available for your release. The next step is to log into the system using the Login command to retrieve a session token that will be used to authenticate all subsequent calls to the service. Since the session token has to be used for all requests to the service, it becomes very repetitive to manually include it in all calls. We will, therefore, use a wrapper client, available from the Men & Mice website that will automatically append the token to all subsequent calls, once we have logged onto the system. Suds also requires a slight modification of the SOAP envelope in order to work with the Men & Mice web service, which will be handled by the client.

import suds
from soapCLI import mmSoap
 
try:
    cli = mmSoap(proxy="proxy.example.com",server="central.example.com",
             username="administrator", password="secret")
    cli.login()
except suds.WebFault as e:
    print "Error while logging into the Men & Mice suite: %s" % e.fault.faultstring

The same authentication model applies to users logged in through the web service, as to users using the GUI. The user needs to have permissions to work with a given resource (DNS records, zones, servers, users, etc). Special permissions are also needed to execute commands through the web server interface. The permissions can be granted by an administrator using a GUI, or the web service.

Error handling

The SOAP specification defines a format for messages containing error information and is used by the Men & Mice web service to notify a client when an operation fails. In some cases, we might also get partial failures. If we are for example deleting DNS records from a number of servers, then some of the DNS servers might be unreachable, while other servers successfully remove their corresponding records. In that case the operation will return a collection of error messages describing the errors.

Working with resources

All objects within the Men & Mice Suite, whether they are IP addresses, DNS zones, DNS records, DHCP scopes or any other type of resource, have a unique resource identifier that can be used to reference, retrieve and work with the resource. It is also possible to fetch a collection of items, for example DNS records and search the retrieved items for a specific pattern. Many of the SOAP commands also provide a filter input parameter, in order to filter what records to return from the service. Further details about references and filters can be found in the official
Men & Mice API documentation

Example usage

We will now demonstrate a simple, yet realistic example of how the API might be used.

The example demonstrates a scenario where we need to relocate a large number of websites hosted on different machines to a new web server. Instead of changing each DNS record manually by hand, we will automate the task by using a simple script.

We start by logging into the system using the before mentioned client available from the Men & Mice website. We then create an array of DNS records (arrayOfDNSRecordsToAdd) that will be used to store the new records that we want to add. We also create an array to store unique references to the records that we want to delete (dnsRecordsToRemove), after we have saved the newly created records.

try:
    cli = mmSoap(proxy=proxy,server=server,
             username=username, password=password)
    cli.login()
except suds.WebFault as e:
    print "Error while logging into the Men & Mice suite: %s" % e.fault.faultstring
    return False
    
arrayOfDNSRecordsToAdd = cli.create("ArrayOfDNSRecord")
dnsRecordsToRemove = cli.create("ArrayOfObjRef")

In order to get all DNS records, we need to fetch all DNS zones in the system using the GetDNSZones command. Once we have an object identifier for each zone (dnsZoneRef), we can use the GetDNSRecords SOAP command to retrieve all DNS records that are in the zone. Two filters are used. The first filter is used to make sure that only master zones are retrieved. The second filter is used to limit the results to records of type "A". If a record points to any of the servers we are migrating from (IP addresses 10.1.1.10, 10.1.1.11 or 1.1.1.1), then we add the record to the collection of records we want to remove and create a new DNS record pointing to the web server we are migrating to (IP address 10.0.0.1).

# Retrieve all master zones
(_, arrayOfDNSZone), (_, totalResults)  = cli.GetDNSZones(filter="type:Master")
if totalResults == 0:
    print "No DNS zones found."
    return True
for dnsZone in arrayOfDNSZone.dnsZone:
    # Fetch all A records from the zone 
    (_, arrayOfDNSRecord), (_, totalResults) = cli.GetDNSRecords(dnsZoneRef=dnsZone.ref, filter="type:^A$")
    if totalResults > 0:
        for dnsRecord in arrayOfDNSRecord.dnsRecord:
            if dnsRecord.data in ["10.0.0.10", "10.1.1.11", "1.1.1.1"]:
                # Modify records to point to new server
                dnsRecordsToRemove.ref.append(dnsRecord.ref)
                dnsRecord.ref = None
                dnsRecord.data = "10.0.0.1"
                arrayOfDNSRecordsToAdd.dnsRecord.append(dnsRecord)

Once we have created all the records, we add them to the system using the AddDNSRecords command. The command returns an array of record references for each new DNS record that has been added, along with an array of errors, if any. The references are used as a parameter to the GetDNSRecord command, that we use to get further information about the records.

The retrieved arrayOfDNSRecordRef will have the same record order as the arrayOfDNSRecordsToAdd that was passed to the SOAP command. If an error occurred when creating a particular record, then a "null" reference "{#0-#0}" will be returned for that record instead. The results could be used to make sure that any old records that correspond to the ones we were unable to add, will not be removed in the next step when we delete old records. We will, however, omit that step for this example and instead prompt the user to do a manual cleanup in case of any errors.

if len(arrayOfDNSRecordsToAdd.dnsRecord) > 0:
    # Create new records
    (_, arrayOfDNSRecordRef), (_, addRecordArrayOfErrors) = cli.AddDNSRecords(dnsRecords=arrayOfDNSRecordsToAdd, 
                                                                                saveComment='Modifying DNS records to point to host "10.0.0.1".')
    if len(arrayOfDNSRecordRef.ref) > 0:
        for recordRef in arrayOfDNSRecordRef.ref:
            if recordRef == "{#0-#0}":
                # Caused by a record that was not added due to some error
                continue
            try:
                print "Added record:", cli.GetDNSRecord(dnsRecordRef=recordRef)
            except suds.WebFault as e:
                print 'Unable to retrieve record with ref "%s" due to the following error: %s' % (recordRef, e.fault.faultstring)

If any errors came up while adding new records, then we instruct the user to do a manual clean up. Note that the error property from the AddDNSRecords response is "nillable". That means that it might not be present in the response. We therefore check if it has been set, before using it.

If no errors came up while adding new records, then we remove the old records using the RemoveObjects operation. The RemoveObjects command can be used to delete almost any object in the system, given that we have a resource reference to the object.

if hasattr(addRecordArrayOfErrors, "error") and len(addRecordArrayOfErrors.error) > 0:
    print """One or more errors occurred while adding records: %s.
 Old records will not be deleted. Please check manually and delete old records that were successfully migrated.""" % addRecordArrayOfErrors.error
    return False
else:       
    # No errors came up during migration, we delete the old records
    removeRecordErrors = cli.RemoveObjects(objRefs=dnsRecordsToRemove,
                                            saveComment="Removing records that now point to host %s." % addressTo)
    if len(removeRecordErrors) > 0:
       print "The following errors occurred while removing old records:", removeRecordErrors
       return False

The complete example can be downloaded here.

Summary

The Men & Mice web service API can be used to automate repetitive DNS, DHCP and IP address management tasks and can be used to write custom applications on top of the Men & Mice Suite. The service can be used by most common programming languages, and as demonstrated, is easy to use.