Hi, if it makes any difference, I do have a support contract with Bluecat, so I can open official support requests if that’s a good approach for me. I haven’t done that yet. I figured I’d reach out to the community first.
My first question is to ensure the direction I’m going is the most recommended direction. I have BlueCat Address Manager. I’m not sure which of these version strings is useful when asking a question here in the forum. ;-) When I browse to the BAM and click on Help, there is no “About” to simply tell me the version of BAM we have. There is Help > API Documentation, it says version “9.5 RESTful v2 API.” I couldn’t figure out how to query system-info using API v2, but when I query the version from “/system-info” via API v1, I get version string “'9.5.1-049.GA.bcn'”.
I want to automate creation/deletion of CNAME records to support cert automation. I can use any language or tool, including python, terraform, or anything else. My first question is what’s recommended? So far, I have identified 4 possible paths forward. I haven’t chosen one yet, and I’m open to additional options:
- bluecat-libraries pip module
- My reading of the docs, and my experimentation with code seem to suggest API v1 is fully mature, but it’s considered legacy, and I am hesitant to build infrastructure on it, if it’s going to be deprecated. API v2 might be a more powerful API, but the module has very little of it implemented. Am I wrong about any of this?
- On the API Documentation page of the BAM, there is `openapi.json`. I was able to download it and build the SDK via `openapi-generator`. I don’t know if this is better, worse, the same, or different, from the bluecat-libraries pip module.
- I found the bluecat terraform provider https://registry.terraform.io/providers/bluecatlabs/bluecat/latest/docs. It looks great, but it says “The Terraform provider uses BlueCat's REST API version 25.0.0 or above.” which seems to conflict with the API version number I mentioned at the top of this thread. So I haven’t spent any real time trying to use it yet.
- I could DIY using `requests` module or whatever. The API Docs are actually pretty excellent. But I did start working in that direction, and I did get confused at some point. I wanted to find an unused IP address in a CIDR block; I was able to get the address info, but then I got lost trying to figure out how I could query what name(s) pointed to this IP address.
Thanks for your experience, comments, or suggestions.
The version number is at the bottom of the BAM GUI.
You mention automated CNAME for cert automation. Would you happen to be using Let’s Encrypt? If so the LEGO ACME client has support for BlueCat. If not, then it’s fairly simple to just use the API using Python. The v2 API works for creating and deleting CNAMEs.
BlueCat has a series of videos on the topic and has sample code. See https://github.com/bluecatlabs/making-apis-work-for-you I believe that’s for v1 but it’s easy to start there and then update to v2 APIs later.
Someone from Bluecat can speak to the completeness and appropriateness of the bluecat-libraries module and the terraform provider. My personal preference is the DIY route, as you are not then dependent on the functioning of outside code. However, as you’ve found, it does require you understand the APIs functioning as there is nothing abstracting it for you. Having a firm understanding of Bluecat Address Manager and its object hierarchy to begin with helps, but if you’re new at both the API and Bluecat in general I can understand there being a somewhat steep learning curve. Feel free to post specific questions regarding the v2 API here and usually someone can help you.
Regarding how to find resource records pointed to a specific IP, you get this from the resourceRecords collection of the IP object (once you have it). - e.g. /api/v2/addresses/<object id>/resourceRecords (although you said you were looking for an unused IP in a CIDR block, so by definition an unused address wouldn’t have any resource records linked to it).
-Tim
@dittman The bottom of my BAM gui just says “9.5.1”. We use InCommon Sectigo, and acme with letsencrypt, but occasionally there are problems with either one of them, so we’re adding support for a 3rd CA option for our organization. Zerossl has a pretty nice API that allows us to run another CA in parallel with the others, because it’s not acme, there are never any conflicts over _acme-challenge records. So we can reserve acme for LE, and do all the zerossl stuff over API exclusively.
Thanks for links to videos. I’ll definitely follow up with those.
@tmaestas I’ve done a lot of BAM usage over the years in the GUI, and work with other APIs from other products, but this is the first I’m working on automating BAM. In the GUI, when I search for a CIDR and browse the network, some IP addresses are unassigned. I’m able to find these easily in the API; they have `address ‘id’]` is None, and `address ‘state’] == ‘UNASSIGNED’`.
Great. That’s a good start. But frequently, when people delete a record, they delete the `A` record, and human-error neglect to click the checkbox “Delete linked IP address if orphaned.” This results in having IP addresses that don’t appear as officially Unassigned, yet have no associated A or PTR records. In the GUI, this just means it appears with a blue icon that says “static” instead of a gray icon that says “unassigned.” We consider these IP addresses to be free for the taking.
To find A records or PTR records that point at a particular IP address, I am just guessing from the API, that would be /api/v2/resourceRecords, but I certainly don’t want *all* records, and I could maybe figure out how to insert a proper filter there, but I’m just guessing “all records filtered” is probably computationally inefficient on the server side. I would expect some kind of endpoint that does a table lookup or some such, for an O(1) query response time. Could be my expectation is wrong and I actually need to keep going down this path.
Ah, understood. Like I said, you can request /api/v2/addresses/<address id>/resourceRecords to find if the address in question has any records associated to it (note this would not return “Generic” A records if they were created that way as they have no linkage - only HostRecords).
Hi
Let me see if I can clarify some points
- bluecat-libraries pip module
- My reading of the docs, and my experimentation with code seem to suggest API v1 is fully mature, but it’s considered legacy, and I am hesitant to build infrastructure on it, if it’s going to be deprecated. API v2 might be a more powerful API, but the module has very little of it implemented. Am I wrong about any of this?
This is the pythonic library (extracted from our gateway product) which is free to use. You are correct in that it only wrapping v1 API calls. The v1 API was a functional API not a resource based API like the v2, hence it made perfect sense to pythonically wrap to older v1 functions. The expectation is you use the requests library for make v2 API calls.
- On the API Documentation page of the BAM, there is `openapi.json`. I was able to download it and build the SDK via `openapi-generator`. I don’t know if this is better, worse, the same, or different, from the bluecat-libraries pip module.
The v2 API is described in the openapi.json, this has no relation at all to the bluecat-libraries python module
- I found the bluecat terraform provider https://registry.terraform.io/providers/bluecatlabs/bluecat/latest/docs. It looks great, but it says “The Terraform provider uses BlueCat's REST API version 25.0.0 or above.” which seems to conflict with the API version number I mentioned at the top of this thread. So I haven’t spent any real time trying to use it yet.
BlueCat's REST API version 25.0.0, this has no correlation to the product’s v1 or v2 APIs on the Address Manager at all, it's a wrapper class used by some of our field developed plugins and code. I understand the naming is confusing, trust me I’ve tried to get the internal field engineering team to stop using this naming!
- I could DIY using `requests` module or whatever. The API Docs are actually pretty excellent. But I did start working in that direction, and I did get confused at some point. I wanted to find an unused IP address in a CIDR block; I was able to get the address info, but then I got lost trying to figure out how I could query what name(s) pointed to this IP address.
This would actually be my recommendation, the same as Tim, using the v2 RESTFul API and requests in python. The v2 RESTFul is very uniform in its response and is as of Integrity 25.1 the basis for the entire Address Manager user interface.
https://{{bamip}}/api/v2/resourceRecords
is a global collection endpoint, in that it will return ALL records in the system regardless of configuration. It can be filtered etc
https://{{bamip}}/api/v2/zones/100994/resourceRecords
This in an explicit URI for a zone, and it sub-collection of resourceRecords
Filters are fully supported as per https://docs.bluecatnetworks.com/r/Address-Manager-RESTful-v2-API-Guide/Filter/25.1.0 and can be combined using predicates
If you need anything else, let me know and I can help construct the v2 API calls if you need further help
@bshorland Thank you for all the info! That is most helpful.
One follow-up question: It sounds like the terraform provider should actually be good to use, right? The API versioning numbers were in fact confusing, but if I ignore that, it should work for my BAM, right?
Also, since the recommendation is to use the V2 API via `requests`, I think I’ll play around with this `openapi` generated SDK and see what value that adds compared to using `requests` directly.
@rahvee Yes, the terraform provider should be good to go