Articles
profile image
Greg Fazekas

IP infrastructure automation in action: the REST(ful) API

We demonstrate the flexibility and simplicity of using the REST API for automation within the Men&Mice Suite.

Mar 10th, 2020

The REST API is one of the API methods you can use to automate your DNS, DHCP, and IP address management with the Men&Mice Suite. In this post, we take a closer look at its structure and syntax, and why it’s so powerful and valuable for our customers.

REST implementation and terminology

As mentioned in our overview article, REST is an architectural style. Where SOAP is an actual standard, with all the requirements for features and strict implementation, REST comes with a lot less baggage.

The Men&Mice REST API is RESTful because it adheres to the architectural constraints of REST. (Put it simply: REST is the theory, RESTful is the practice.)

Resources

Endpoints for the REST API are URLs — which is short for Uniform Resource Locator. Thus, these endpoints are referred to as ‘resources.’

The structure for the REST URLs is

http(s)://subdomain.domain.tld/mmws/api/Resource

Where “http://subdomain.domain.tld” is the URL for the Men&Mice Web Application.

Often the structure is extended with references (arguments or filters) and further resources. For example, to move a specific object to a specific folder (a feature in the Men&Mice Suite for organization) the URL to use would be

http(s)://subdomain.domain.tld/mmws/api/DNSZones/{ref}/Folders/{folderRef}

Operations

As REST has been developed in tandem with the HTTP protocol, it relies on the basic HTTP operations: GET, PUT, POST, and DELETE.

  • GET: read a resource
  • PUT: modify an existing resource
  • POST: create a new resource
  • DELETE: remove an existing resource

That’s it. This makes REST easier to work with: all you need is a browser (to GET only) or a simple command-line tool like curl.

There are, of course, more advanced applications like Postman, or the option to use a scripting language such as Python to create complex operation flows. And we have it good authority that Men&Mice will get integration with Ansible playbooks soon enough! 😉

IP Infrastructure automation with the REST API

Enough theory, let’s take a look at some examples of the REST API in action.

WARNING: Don’t experiment in production or live environments! Automation, by nature, is designed to work without human intervention. For this reason, the API, no matter which incarnation, provides direct control over resources. As long as the user has sufficient permissions and can authenticate, the API will let them do what they tell it to do, no questions asked.

Also, note that API calls need to be authenticated to run. User access levels, therefore, can vary the responses, from simply the range of data available to view or modify all the way to the API command being rejected.

Locate DNS records quickly

Let’s start with something simple.

To list all DNS zones:

GET http(s)://subdomain.domain.tld/mmws/api/DNSZones

This is possibly the most basic example, but a useful one.

Being able to get this data with a single operation (and not click through several UI elements) saves much time. Especially since you can do it for multiple items.

Let’s say you’re looking for a specific subset of DNS records, such as those with a specific subdomain:

GET http(s)://subdomain.domain.tld/mmws/api/DNSZones/domain.com./DNSRecords?filter=type=A AND name=@voip

(Note the trailing dot in the DNS zone name. It represents the root domain, and while generally omitted, it’s the proper way to end a domain name.)

This will list all A records that contain’ voip’ within that DNS zone.

The value of automation, however, is not the ability to do this. It’s the fact that the response comes in a structured format. REST, by default, uses the JSON format to return data, unless asked to do so otherwise. The returned data for the last example would look something like this:

{
  "result": {
    "dnsRecords": [
      {
        "ref": "DNSRecords/344620",
        "name": "voip",
        "type": "A",
        "ttl": "",
        "data": "10.0.17.2",
        "comment": "",
        "enabled": true,
        "dnsZoneRef": "DNSZones/2206"
      }
    ],
    "totalResults": 1
  }
}

Because of this structure, it’s easy to take the returned data and use it somewhere else. For example, getting the IP addresses attached to the DNS records listed.

Speaking of which…

Handling IP addresses with REST API

Let’s say we want to check on all the IP address histories for the IP addresses attached to DNS records. Taking the “data” value from the response above, we can feed that into another API call:

GET http(s)://subdomain.domain.tld/mmws/api/IPAMrecords/10.0.17.2

And this would return a response like the following:

{
  "result": {
    "ipamRecord": {
      "addrRef": "IPAMRecords/145949",
      "address": "10.0.17.2",
      "claimed": false,
      "dnsHosts": [
        {
          "dnsRecord": {
            "ref": "DNSRecords/344561",
            "name": "domain.tld. [corporate-domain]",
            "type": "A",
            "ttl": "3600",
            "data": "10.0.17.2",
            "comment": "",
            "enabled": true,
            "dnsZoneRef": "DNSZones/3261"
          },
          "ptrStatus": "OK",
          "relatedRecords": [
            {
              "ref": "DNSRecords/344562",
              "name": "voip.domain.tld.",
              "type": "CNAME",
              "ttl": "3600",
              "data": "domain.tld.",
              "comment": "",
              "enabled": true,
              "dnsZoneRef": "DNSZones/3261"
            },
            {
              "ref": "DNSRecords/344565",
              "name": "10.0.17.2.in-addr.arpa.",
              "type": "PTR",
              "ttl": "3600",
              "data": "domain.tld.",
              "comment": "",
              "enabled": true,
              "dnsZoneRef": "DNSZones/3267"
            }
          ]
        }
      ],
      "dhcpReservations": [],
      "dhcpLeases": [],
      "discoveryType": "Ping",
      "lastSeenDate": "",
      "lastDiscoveryDate": "Feb 12, 2018 15:56:49",
      "lastKnownClientIdentifier": "",
      "device": "",
      "interface": "",
      "ptrStatus": "OK",
      "extraneousPTR": false,
      "customProperties": {},
      "state": "Assigned",
      "usage": 16390
    }
  }
}

Or, if you need the range that this IP address belongs to:

GET http(s)://subdomain.domain.tld/mmws/api/IPAMRecords/10.0.17.2/Range

Which would return:

{
  "result": {
    "range": {
      "ref": "Ranges/289",
      "name": "10.0.17.0/24",
      "from": "10.0.17.0",
      "to": "10.0.17.255",
      "parentRef": "Ranges/278",
      "childRanges": [],
      "dhcpScopes": [
        {
          "ref": "DHCPScopes/68",
          "objType": "DHCPScopes",
          "name": "10.0.17.0/24"
        },
        {
          "ref": "DHCPScopes/69",
          "objType": "DHCPScopes",
          "name": "10.0.17.0/24"
        }
      ],
      "authority": {
        "name": "Failover [dhcp16.domain.tld.,dhcp2.domain.tld.]",
        "sources": [
          {
            "name": "dhcp16.domain.tld.",
            "type": "Failover",
            "ref": "DHCPServers/19",
            "enabled": true
          },
          {
            "name": "dhcp2.domain.tld.",
            "type": "Failover",
            "ref": "DHCPServers/13",
            "enabled": true
          }
        ]
      },
      "subnet": true,
      "locked": false,
      "autoAssign": false,
      "hasSchedule": false,
      "hasMonitor": true,
      "customProperties": {
        "Region": "AMER",
        "Country": "United States",
        "City": "New York City",
        "Title": "10.0.17.0/24"
      },
      "inheritAccess": true,
      "isContainer": false,
      "utilizationPercentage": 12,
      "hasRogueAddresses": false
    }
  }
}

As you can see, the structure of the API call for IP addresses is the same as before, and so is that of the JSON response. This makes retrieving specific information from it, to repurpose in another form or application, easy.

Automate creatively

The snippets above demonstrate the flexibility and simplicity of the REST API. But automation is powerful because we can chain together multiple operations into a workflow, and use a single script to run through it.

The Men&Mice API handles data, no matter where it’s kept. It’s just a matter of programming sophistication how that data is used.

The possibilities are nearly endless: every operation you can do within the Men&Mice Suite’s user interface, you can automate through the API. Including features from the Advanced Reporting and Workflow modules (‘ReportDefinitions‘ and ‘ChangeRequests,’ respectively) as well as user and access control management.

To find out what’s possible, a list of all accessible REST API resources for your environment is always available on the URL http(s)://subdomain.domain.tld/mmws/api/doc/