Zen and the Art of the 8.73 API

franton
Valued Contributor III

Hi All,

I've successfully pulled information out of our JSS using the API. Now I have a new challenge: setting an extension attribute via the API. Is this even possible?

1 ACCEPTED SOLUTION

DerekB
New Contributor II
New Contributor II

Hi Guys,

I wanted to chime in here and let you know that populating an extension attribute is possible via the API. It is a little bit of a round about way to do this as we do need to use the computer computer record to make this work.

To give you an idea of what you can do is you could populate an XML file to be formatted like the following:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><computer><extension_attributes><attribute><name>'"${ea_name}"'</name><value>'"${ea_value}"'</value></attribute></extension_attributes></computer>

Where we have "${ea_name}" would be the name of Extension Attribute we want to populate the data for and the "${ea_value}" variable would be what we want the value to be for the extension attribute.

If we know the ID of the computer we want to change this attribute for we could use a curl command formatted like the following to fill in this information.

/usr/bin/curl -k -u ${jss_username}:${jss_password} ${jss_url}/JSSResource/computers/id/${id} -T "/tmp/ea.xml" -X PUT

It sounds like you guys have worked with the API some, but we should be able to alter any data we can pull via the API by using a PUT command. We just need to follow the same XML format as the data we want to populate.

Let us know if you have any more questions.

Derek Brost

View solution in original post

13 REPLIES 13

mm2270
Legendary Contributor III

I don't know how much, if any, difference there is in the API between 8.71 (what we're running) and 8.73, but assuming they're the same, this will be either impossible or very hard.
EAs don't have their own category in the API since they are part of, and tied to a computer record., so I think the only feasible way to update one, let alone create one, would be to download a complete API computer record, make the modifications to that file using some complex scripting methods, and then use a PUT command to re-upload the modified XML file for the computer into the JSS. Not sure about you, but that sounds way too complicated to me.

Maybe there is some other way, but if there is the its not going to be via the normal API methods. Just doesn't seem feasible from what I know of it.

However, I'd love to be proven wrong.

franton
Valued Contributor III

Thanks for that. Made my task a lot more difficult sadly.

jstrauss
Contributor

@mm2270][/url][/url is right when he says impossible. An extension attribute needs to execute on the target machine for a <result> to be populated in the computer record, so just GETing the computer record, modifying it, and PUTting it back up wouldn't make a difference unless you knew what the results of the executed EA were going to be ahead of time, since all that's stored in the computer record is the result of the script execution, not the script itself.

Sad face.

DerekB
New Contributor II
New Contributor II

Hi Guys,

I wanted to chime in here and let you know that populating an extension attribute is possible via the API. It is a little bit of a round about way to do this as we do need to use the computer computer record to make this work.

To give you an idea of what you can do is you could populate an XML file to be formatted like the following:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><computer><extension_attributes><attribute><name>'"${ea_name}"'</name><value>'"${ea_value}"'</value></attribute></extension_attributes></computer>

Where we have "${ea_name}" would be the name of Extension Attribute we want to populate the data for and the "${ea_value}" variable would be what we want the value to be for the extension attribute.

If we know the ID of the computer we want to change this attribute for we could use a curl command formatted like the following to fill in this information.

/usr/bin/curl -k -u ${jss_username}:${jss_password} ${jss_url}/JSSResource/computers/id/${id} -T "/tmp/ea.xml" -X PUT

It sounds like you guys have worked with the API some, but we should be able to alter any data we can pull via the API by using a PUT command. We just need to follow the same XML format as the data we want to populate.

Let us know if you have any more questions.

Derek Brost

mm2270
Legendary Contributor III

@derek.brost
thanks for that bit of information. I think part of the confusion around the API stems from the lack of proper documentation in most cases of how to use it. The basic information you get from the JSS doesn't really lend itself to figuring out the proper methods to do these kinds of things on one's own.

I can see how only uploading the specific portion of the xml that pertains to the EA for a computer record could work, so thanks for pointing that out. Personally, I'd like to see some more accessible methods of adding or changing computer record values with the API. What you just outlined above, the actual format of the xml file needed, has been generally a mystery to most of us not within JAMF. Why doesn't the API page show examples like the above in almost all cases? I don't expect that you should answer that directly, but its a valid question for JAMF I feel.

The API is powerful, but if good instructions are not available on how to use it, its not going to be used much. Simple stuff.

franton
Valued Contributor III

This will be very helpful, especially as i'm dealing with a "yes/no" type condition and I need to come up with a button to flip between the two.

jstrauss
Contributor

@derek.brost][/url][/url][/url I didn't consider just populating that <extension_attribute> element for the purpose of PUTting data that you already expect, I was only considering the possibility of adding an extension attribute straight up through the API and having it execute on machines to return unknown data. So, yes, @franton][/url][/url][/url, if all you want to do is PUT data in an EA field in the JSS for identification of some kind without an actual extension attribute running to gather data you don't know yet, then it's possible and Derek's method is simple.

EDIT: Question @derek.brost, I haven't tried this, but if you populate the <name> of an extension attribute via the API but not the <value>, would the extension attribute actually run on that machine? You could get unknown results that way and have a way to scope the EA to individual machines.

DerekB
New Contributor II
New Contributor II

@mm2270 I agree with you that our documentation may not be the greatest, but I do think that the examples in the 8.x series give us better examples than in the 9.x series. There is a feature request that @jstrauss has posted that if you have not yet voted on I suggest voting up:

https://jamfnation.jamfsoftware.com/featureRequest.html?id=1452

For me the best way I learned about using the API was to play with it and see what I could do, if it didn't work the way we would expect it to feel free to ping us, we are more than happy to help answer the basics on the API.

@jstrauss There are actually three different types of extension attributes to think about here: Text Field, Popup and Script. You mentioned having an extension attribute "run" so I wanted to clarify that not all extension attributes actually run a script. The first two actually are manual and is why I believe @franton was looking into the API.

Using the API I would expect that we would only be setting/changing a value for a popup or a text field. Using the API to populate a script extension attribute wouldn't make much sense since there is a script running at every inventory to return these results. If I am understanding your steps here you are suggesting that you can add an extension attribute to a single computer. If this is the case this is not possible.

If we want to use the API to set an extension attribute it has to already be created in the system. We can not create an extension attribute by running a PUT command with CURL.

Examples that I have worked with clients to use the API to populate an extension attribute would be to set a default setting for your popup menu, or populate a text field for multiple computers for a one time entry to a text field.

I hope this helps and if I am missing something here let me know.

jstrauss
Contributor

@derek.brost Yeah you're totally right. I rarely use pop-up or text input, so those are never on my mind. Good lookin' out!

franton
Valued Contributor III

Utterly correct @derek.brost . The use case is as follows:

Extension attribute set as a pop-up with two values. Enabled and Disabled.

I'm attempting to write a script to flip the value in this ea via a script, so enabled becomes disabled and vise versa. The idea is we have an attribute that is changeable by users in Self Service and we know from reporting what computers are set to which setting.

mm2270
Legendary Contributor III

@franton

If all you're looking to do is flip a value from one to another, there are of course ways to do this with a simple script that writes a value into a file somewhere on the system that then gets picked up by an Extension Attribute using a script to capture the value in the file. You could even easily make the value toggle from one value to the other depending on what's already there, in the local file.
The major downside is the recon aspect, since a full inventory collection is required to grab that one value (blah!), so if you're looking to avoid that, then I can see why you'd want to use the API. I guess it all depends on what the end experience needs to be.

gabester
Contributor III

@derek.brost][/url Derek, thank you for posting this, it couldn't have been more timely to my needs. I just wish I'd discovered this before trawling the net for roughly 6 hours trying to figure out how to get then parse the xml from my jss api to find and change certain values - in my case on v.9 for distribution points - via sed, awk, grep, or build my own instance of xmlstarlet or learn python... had I read this earlier it would have saved me a lot of time and allowed my organization to execute better on a time-critical deployment project.

This can be generalized even more... perhaps to anything you can PUT into your JSS (and you JAMFers can hopefully confirm!):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<accounts..smtpserver>
  <key>$key_value</key>
  <otherkey/>
</accounts..smtpserver>

DerekB
New Contributor II
New Contributor II

@Sterritt][/url We can put anything that is noted with a PUT entry when we look at the API Rest pages of our JSS.

For your example here the format for setting up/changing the SMTP Server would be as follows:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<smtp_server>
  <host/>
  <port>25</port>
  <timeout>0</timeout>
  <authorization_required>true</authorization_required>
  <username/>
  <password/>
  <ssl>false</ssl>
  <tls>false</tls>
  <send_from_name>JAMF Software Server</send_from_name>
  <send_from_email/>
</smtp_server>

So as long as our XML format would follow this outline we should be able to PUT any key we want.

To see what we have the ability to do either a GET, PUT, POST or DELETE we can go to URLs like the following with our JSS URL's:

Version 8.x https://mycompany.com:8443/apiIntro.rest
https://mycompany.com:8443/apiFrontPage.rest

Version 9.x

https://mycompany.com:8443/api

Hopefully this is the additional information is helpful.