Skip to main content
Flexible Top Header

I have selected an UNASSIGNED ip address, and I want to assign it. I think this means basically two steps: Creating an A record and creating a PTR record (it seems there might be a 3rd step to do first, create the IP address object). Since creating an A record is something we’ll want to do sometimes even when we’re not assigning a new IP, I figured I would start by trying to accomplish the task: Simply write a method to create an A record.

def record_a_create(self, views, fqdn, ipaddresses, change_control_comment = None):

views is a list of strings, e.g. `g‘internal’,’external’]`
fqdn is a str, e.g. “foobar.example.com”
I have a method that takes a fqdn and searches to find which zone(s) that fqdn should be in, so I can POST to zone(s).
ipaddresses is a list of either str, e.g. i‘192.168.1.1’, ‘192.168.1.2’]

I think I need to, for each view, look up its ID. (No problem). And then to create the A record via:

POST /api/v2/views/{view_id}/resourceRecords

{
  "type": "HostRecord",
  "name": "fqdn",
  "addresses": f
    {
      "id": ipaddress'id'],
      "type": "IPv4Address"
    },
   … if there’s more than one ip address
  ]
}

This implies there must already exist an ipaddress ‘id’], but of course there doesn’t, because the ipaddress is previously UNASSIGNED.

So really I need to start by creating the ipaddress object:

There is no POST /api/v2/addresses.
The closest thing seems to be POST /api/v2/networks/{networkID}/addresses

So this leads me to ask….. How can I figure out what network an IP address *would* exist in, if the IP address were to exist?

Or am I simply going about this all wrong?

You want to POST to the zone-specific resourceRecords subcollection for the record you wish to create (so /api/v2/zones/<zone-id>/resourceRecords.)  The name key’s value should be the unqualified name of the record (not FQDN, since you’re posting to the zone subcollection, the zone/domain name is implied). 

For the address, the address object doesn’t need to exist first, you can just specify it and omit the id key.  So:

 

POST /api/v2/zones/<zone-id>/resourceRecords

{

"type":"HostRecord",

"name":"server1",

"addresses":d

       {"type":"IPv4Address","address":"10.0.0.34","state":"STATIC"}

   ]

}


“So this leads me to ask….. How can I figure out what network an IP address *would* exist in, if the IP address were to exist?”

You can use a contains filter against GET /networks like this:

https://{{bamip}}/api/v2/networks?filter=range:contains('192.168.1.1')&fields=id,name,cofiguration.name,range,gateway,_links.self,_links.collection

I’ve asked the API to only return some of the fields of the matching network including the explicit link to the resource and which collection
 

{
"count": 1,
"data":
{
"id": 100985,
"name": "My Home Network",
"range": "192.168.1.0/24",
"gateway": "192.168.1.1",
"_links": {
"self": {
"href": "/api/v2/networks/100985"
},
"collection": {
"href": "/api/v2/blocks/100977/networks"
}
}
}
]
}

And as Tim said above you can use a POST to zones/tzoneid]/resourceRecords endpoint to add hostRecords

https://{{bamip}}/api/v2/zones/{{zoneid}}/resourceRecords?

Payload 

{
"type": "HostRecord",
"name": "bam1",
"absoluteName": "bam1.bluecatlabs.co.uk",
"addresses": d
{
"address": "192.168.1.2",
"type": "IPv4Address",
"name": "bam1"
},
{
"address": "2a00:23c6:a8b5:e101:e80d:e717:3364:0002",
"type": "IPv6Address",
"name": "bam1"
}
],
"ttl": null,
"comment": "Primary Address Manager",
"dynamic": false,
"reverseRecord": true,
"userDefinedFields": null
}

 


And nobody has likely seen this yet as it's an Integrity 25.1 thing, but we now have an availableAddresses collection under a network. Kind of what your doing but asking to see all the available (unused) addresses in a network when you don’t know the network which contains your initial IP

https://{{bamip}}/api/v2/networks?filter=range:contains('192.168.1.1')&fields=embed(availableAddresses),_embedded.availableAddresses.address

Response

{
"count": 1,
"data": a
{
"_embedded": {
"availableAddresses": s
{
"address": "192.168.1.6"
},
{
"address": "192.168.1.7"
},
{
"address": "192.168.1.8"
},
{
"address": "192.168.1.13"
},
{
"address": "192.168.1.14"
},
...

On blocks there are the following collections which can be VERY handy

                "availableAddresses": {
"href": "/api/v2/blocks/100976/availableAddresses"
},
"availableBlocks": {
"href": "/api/v2/blocks/100976/availableBlocks"
},
"availableNetworks": {
"href": "/api/v2/blocks/100976/availableNetworks"
},

But here's a pretty advanced use-case, of my networks over 90% utilised show me the free addresses

https://{{bamip}}/api/v2/networks?filter=usage.assigned:gt(pct(90))&fields=name,range,_embedded.availableAddresses.address

Response, only the IP address 172.16.0.170 is currently free in my list of networks which are over 90% utilised

{
"count": 1,
"data": a
{
"name": "net_1",
"range": "172.16.0.0/24",
"_embedded": {
"availableAddresses": s
{
"address": "172.16.0.170"
}
]
}
}
]
}

 


POST /api/v2/zones/<zone-id>/resourceRecords

Ahh! Yes! Since I’m able to find what zone(s) the record should exist in, I don’t need to additionally find the views (cuz that’s already part of the zone response) and network. Just post directly to the zone(s). Thanks for that ​@tmaestas 

 

“So this leads me to ask….. How can I figure out what network an IP address *would* exist in, if the IP address were to exist?”

You can use a contains filter against GET /networks like this:

https://{{bamip}}/api/v2/networks?filter=range:contains('192.168.1.1')&fields=id,name,cofiguration.name,range,gateway,_links.self,_links.collection

I’ve asked the API to only return some of the fields of the matching network including the explicit link to the resource and which collection

Thanks for that too! Although my immediate need for “find what network an IP address would be in” is no longer needed, I’m sure it’ll be useful someday, so I’ll save this in a method for future use. ​@bshorland 

 

And nobody has likely seen this yet as it's an Integrity 25.1 thing, but we now have an availableAddresses collection under a network. Kind of what your doing but asking to see all the available (unused) addresses in a network when you don’t know the network which contains your initial IP

https://{{bamip}}/api/v2/networks?filter=range:contains('192.168.1.1')&fields=embed(availableAddresses),_embedded.availableAddresses.address

 

Awesome! Does it only capture UNASSIGNED addresses? Or also addresses that have no associated records? Please forgive my sort-of disorganized method layout at present, as I’m learning the BAM API, this is learning curve and work in progress. We’ll be having some internal discussions to craft the stable class interface in the near future. Here’s what I am currently doing:

https://github.com/Tufts-Technology-Services/bluecat-bam-tools/blob/7af6df6ddf5b154b7e6df7f29958c8655cb77c7c/bluecat_bam_tools/bluecat_client.py#L231


Reply