Skip to content

JNUC2019 Intro and Overview

Chris Lasell edited this page Oct 21, 2019 · 13 revisions

Hands On, Real-time Classic API Using ruby-jss

Jamf Nation User Conference 2019, Hyatt Regency Minneapolis

Interactive Lab, Thursday, Nov. 14, 10:15am, Regency Room (Home)

Welcome to ruby-jss

Jamf Pro's Classic API provides RESTful, programmatic access to much of what's available in the Jamf Pro web interface, in either JSON or XML format.

While the API's existence is a boon for automating lots of Jamf Pro-related tasks, using it via bash scripts can be unwieldy, hard to grasp, and difficult to troubleshoot and maintain.

Take, for example, the task of changing the assigned user for all computers in a smart group

bash:

GROUP_NAME='myGroupName'
NEW_COMPUTER_USER='jbleaux'
NEW_COMPUTER_USER_REAL_NAME='Jeaux Bleaux'

API_USER="api_username"
read -p "API pw for $API_USER: " API_PW

API_URL_BASE="https://jss.server:8443/JSSResource"

raw_group_xml=`curl -H 'Accept: application/xml' -sk -u "${API_USER}:${API_PW}" -X GET "${API_URL_BASE}/computergroups/name/${GROUP_NAME}"`

member_count=`echo "$raw_group_xml" | xmllint --xpath 'count(/computer_group/computers/computer)' -`

for (( i=1; i <= $member_count; i++ )); do
  computer_id=`echo "$raw_group_xml" | xmllint --xpath "/computer_group/computers/computer[$i]/id/text()" -`
  change_xml="<computer><location><username>$NEW_COMPUTER_USER</username><realname>$NEW_COMPUTER_USER_REAL_NAME</realname></location></computer>"
  curl -H 'Content-Type: application/xml' -u "${API_USER}:${API_PW}" -X PUT "${API_URL_BASE}/computers/id/${computer_id}" -d "$change_xml"
done

ruby using ruby-jss:

require 'ruby-jss'

GROUP_NAME = 'myGroupName'
NEW_COMPUTER_USER = 'jbleaux'
NEW_COMPUTER_USER_REAL_NAME = 'Jeaux Bleaux'

JSS.api.connect server: 'jss.server', user: 'api_username', pw: :prompt

computer_group = JSS::ComputerGroup.fetch name: GROUP_NAME

computer_group.member_ids.each do |comp_id|
  computer = JSS::Computer.fetch id: comp_id
  computer.username = NEW_COMPUTER_USER
  computer.real_name = NEW_COMPUTER_USER_REAL_NAME
  computer.save
end

Which one would your mother understand more easily?

Not only your mother, which one will you understand more easily in 2 years, when you need to make some changes to the script or adapt it for some other purpose? Or your co-workers who need to work with it while you're on vacation trekking in the Himalayas?

When using ruby-jss, you don't have to worry about the details like connection headers, parsing or formatting XML or JSON, GET vs PUT vs POST, the URL paths for related API items, and so on.

All of that is handled 'under the hood' for you. You can focus on the objects in your JSS - the computers, devices, groups, policies, packages, profiles, etc, and their properties and actions. Your code will reflect them and their attributes at a conceptual level, increasing the writability, readability, and maintainability of your code.

Ruby's syntax may be a bit different from Bash, but it isn't hard to learn, especially when you have API tasks to automate. If you have experience with Python or Javascript, it'll be even easier.

Not only will it be easier to write programs to automate repeated tasks, you can also use ruby-jss with Interactive Ruby, a.k.a. irb to act as a sort of live 'shell' to your Jamf Pro server. This allows you to easily perform all sorts of one-off tasks using the Classic API in real-time.

The JNUC Interactive Lab

In the 2019 JNUC interactive lab Hands on, Real-time Classic API Using ruby-jss we're going to do just that.

We'll use irb and ruby-jss to connect to a live Jamf Pro server and do things in realtime.

The things we do in irb are apply directly to writing programs for automating repeated tasks. Just like bash code can be run live in a shell, or executed from a file, so can ruby be run live in irb, or exectuted from a file; the code is the same in both situations.

Here's what we'll cover:

  • Installing ruby-jss and launching irb
  • Realtime ruby-jss tasks
    • Listing Jamf Pro Objects
    • Fetching Jamf Pro Objects
    • Changing & Updating Jamf Pro Objects
    • Deleting Jamf Pro Objects
  • Ruby Basics we'll see along the way
    • Classes (object types) & Methods (functions)
    • Collections: Arrays & Hashes
    • Iterators: Easy looping through collections
  • Scripted Tasks
    • Maintaining 'dynamic' static groups between object types
  • A quick look at the documentation, and how to read it.

More advanced stuff we won't cover in the lab, but may be mentioned:

  • Client-side coding
  • Scoping & Scope objects
  • Criteria & Criterion objects
  • Multiple simultaneous API connections
  • Security considerations
  • The Jamf Pro API
  • Server Clustering
Clone this wiki locally