Any API gurus here?

chris_kemp
Contributor III

Trying to work out some simple cURL commands for interacting with the API. If I might pick your brain...mmm, brains...

7 REPLIES 7

bpavlov
Honored Contributor

May want to post some more details before someone can help you along with what you have done already and isn't working...

mm2270
Legendary Contributor III

Yeah, let us know what you're trying to do, at least generally speaking, and I'm sure one of us can help.

rderewianko
Valued Contributor II

@chris.kemp a great starting place for interacting with the API is: @brysontyrrell unofficial api docs. I also like to use PAW when building my queries

chris_kemp
Contributor III

Well basically, I want to either set a custom extension attribute OR add/remove a computer from a static group (whichever works).

I'm trying to set up a way that we can have machines designated as being in temp storage. Some machines go out for a few months on a project, then come back & sit for awhile until they are re-assigned. We need a way to mark these as such, so that when we look at computers that haven't checked in for (x) weeks, we can see that they are stored & not having some kind of problem.

The reason for the API call would be to bring a computer out of the storage group. We can have them manually checked in, but the idea is that when they are wiped & re-deployed, the process would automatically put them in an "active" status if it was previously "stored". I can think of a few ways to approach this with an EA, and maybe a temp file or something - but I think it would be cleaner (and maybe a bit more bullet-proof) just to script it moving out of a group when appropriate.

chris_kemp
Contributor III

@rderewianko Thanks for that! This is probably just the first task, the more I can learn about the API the more I can leverage it. :)

mike_paul
Contributor III
Contributor III

Since I feel partially responsible for the lack of documentation out there on the API (namely I haven't created any) i'll chime in with a few tips to possibly help get you going. For your goal, extension attributes seem to make a lot of sense since its easily modifiable both via the JSS and via the API.

You could make some Pop-up (drop down) menus with some options within the extension attributes section of the respective device (this can work for OSX and iOS devices) and then make smart groups based off of the EA values and any other criteria you may want.

Lets say you make an Extension Attribute named 'Repair Status' with some pop-up options of 'Missing' and 'Out for Repair' and whatever other values you feel like. I'd recommend having them displayed in the Extension Attributes section of the device record vs the default option of General (easier to grab just that subset of information this way via GETs).

So in order to know how the data you are inputing through the API needs to be formatted, lets pull down that xml from the JSS. (We can do GETs in XML and JSON, but only PUTs and POSTs in XML and you said 'simple' so were going in XML)

So lets pull down the Extension Attributes with a basic curl:

curl -k -u username:password https://jssserveraddress.company.com:8443/JSSResource/computers/serialnumber/C02KXXSXXXXX/subset/extension_attributes > /private/var/tmp/ComputerEA.xml

INFO:

  1. -k means allow invalid certificate if you dont have a trusted 3rd party cert.

  2. GET (read) is the default value for a curl so you dont have to call it out like we will with the PUT (update) and POST (create)

  3. You can do the GET/PUT/POST off of any unique identifier in the JSS: e.g. JSS ID, Serial Number, Mac Address, UDID and Name. Just replace 'serialnumber' with that correct term and provide that value. Different objects have different identifiers and some make more sense for things than others, depending on what you are doing and how you are identifying the devices/data you want to interact with. JSS ID is always unique for all objects but its only known to the JSS. Mac address can be duplicates due to ethernet adaptors. Serials can be blank when returned from repair. Names can be duplicates for devices but unique for objects like Extension attributes, buildings and departments.

To figure out what objects use what specific values for unique identifiers check your https://jssaddress.company.com:8443/api page and it will give you some formatting examples.

With that curl you may get something along the lines of:

<?xml version="1.0" encoding="UTF-8"?><computer><extension_attributes><extension_attribute><id>1</id><name>Repair Status</name><type>String</type><value>Missing</value></extension_attribute><extension_attribute><id>2</id><name>Verify Certificate Based Communication</name><type>String</type><value>Enabled</value></extension_attribute></extension_attributes></computer>

I only have two EA's in this JSS so my data may be less than yours but it gives us the basic formatting needed.

If I removed all the extra stuff I am left with just my 'Repair Status' data

<?xml version="1.0" encoding="UTF-8"?><computer><extension_attributes><extension_attribute><id>1</id><name>Repair Status</name><type>String</type><value>Missing</value></extension_attribute><extension_attribute></computer>

The main thing to note is that I have the xml header at the beginning and that all the required tags are there surrounding the value we want. Extra data like the Type can actually be removed since were not trying to modify that in our PUT. You can either remove Name or ID and their corresponding tags as well. You just have to call out one Unique Identifier for that thing were modifying. Since EAs allow both JSS ID and Name as a unique, we can omit one or the other for this PUT, like I did below by removing ID and just using the Name as the identifier.. So I can be left with something minimal like the following:

<?xml version="1.0" encoding="UTF-8"?><computer><extension_attributes><extension_attribute><name>Repair Status</name><value>Missing</value></extension_attribute><extension_attribute></computer>

-Note how name and value are both located within the extension_attribute tag, which is within the extension_attributes tag, which is within the computer tag. This is required since its going into the specific extension attribute within the extension attributes section of a computer record. If you dont tell it where to go, it doesnt know and errors out.

If I saved that ComputerEA.xml file with the extra data removed I could do a PUT with it with a command similar to the following:

curl -k -u username:password https://jssserveraddress.company.com:8443/JSSResource/computers/serialnumber/C02KXXSXXXXX -T /private/var/tmp/ComputerEA.xml -X PUT

INFO:

  1. -T for transfer, synonymous with --upload-file: "-T /path/to/file.xml"

  2. -X specifies the request type, PUT (update), POST (create), DELETE (delete) and even GET (read) if you want to call it out.

Now if you wanted to do it in-line without having to write out an xml prior you could do something like the following (have to know the tags and formatting first):

curl -k -H "Content-Type: application/xml" -u username:password https://jssserveraddress.company.com:8443/JSSResource/computers/serialnumber/C02KXXSXXXXX -d  "<computer><extension_attributes><extension_attribute><name>Repair Status</name><value>Missing</value></extension_attribute></extension_attributes></computer>" -X PUT

or for 'Out For Repair'

curl -k -H "Content-Type: application/xml" -u username:password https://jssserveraddress.company.com:8443/JSSResource/computers/serialnumber/C02KXXSXXXXX -d  "<computer><extension_attributes><extension_attribute><name>Repair Status</name><value>Out For Repair</value></extension_attribute></extension_attributes></computer>" -X PUT

or 'No Value' to reset it to nothing:

curl -k -H "Content-Type: application/xml" -u username:password https://jssserveraddress.company.com:8443/JSSResource/computers/serialnumber/C02KXXSXXXXX -d  "<computer><extension_attributes><extension_attribute><name>Repair Status</name><value></value></extension_attribute></extension_attributes></computer>" -X PUT

INFO:

  1. -H means header. So -H "Content-Type: application/xml" makes it so you don't have to type out the xml header, <?xml version="1.0" encoding="UTF-8"?>, which can be annoying to escape the spaces and quotes.

  2. -d means data to send in the requested PUT or POST, you can use this to pass values in-line without it having to read from a file.

So taking all of this, I would recommend making a script that prompts you for your JSS credentials (specific accounts for API are good, lock them to the things they are doing), device identifier, and the 'value' you were looking to send for that EA. You can choose the language of your choice, bash or python or whatever you want. If your looking to get deeper into parsing data from GETs, look into things like xpath or xlint for xml and something like JQ for json. Lots of other options out there and some google searches should help shed some light on that but its a discussion for another post.

Lot of different ways to get at this, this is just one method. But hopefully this helps and isn't too verbose

chris_kemp
Contributor III

Thanks very much! The inline stuff is more what I was looking for - I'll probably take a slightly different tack, but that helps me see how the syntax is structured.