Class: Jamf::Resource Abstract
- Inherits:
-
JSONObject
- Object
- JSONObject
- Jamf::Resource
- Extended by:
- BaseClass
- Defined in:
- lib/jamf/api/base_classes/resource.rb
Overview
Jamf::Resource represents a thing directly accessible in the API. It will contain one or more API endpoints.
A resource has a base URI path in the API used for interacting with the resource and directly-related sub-resources.
For example, the device-reenrollment settings are a resource at the url path
> …/uapi/v1/reenrollment
and the related sub-resource for the change history of the reenrollment settings is at
> …/uapi/v1/reenrollment/history
All resources based at …/uapi/v1/reenrollment are encapsulated in the class ReEnrollmentSettings, a descendent of Jamf::Resource
There are two types of resources: Singletons and Collections.
**Singleton resources** have only one instance available in the API, and they cannot be create or deleted, only fetched and usually updated, tho some cant be updated either, e.g. Jamf::AppStoreCountryCodes. The device-reenrollment settings mentioned above are an example of a Singleton resource. When the resource is fetched from the API, it is cached, and (usually) future fetching will return the same instance. See SingletonResource for details.
**Collection resources** have more than one resource within them, and those can (usually) be created and deleted as well as fetched and updated. The entire collection (or a part of it) can also be fetched as an Array. When the whole collection is fetched, the result is cached for future use. See CollectionResource for details.
# Instantiating Resources
For all subclasses of Jamf::Resource, using the ruby standard .new class method to instantiate an object will raise an exception. We do this to avoid the ambiguity of the word 'new' in this context.
Normally in ruby, .new means 'make a new instance of this class in memory'. But with Jamf Resoureces, when making a new instance in memory, we might be making an instance of a resource that already exists in Jamf Pro, or perhaps making an instance of a 'new' thing that we want to create in Jamf Pro, but doesn't exist there at the moment.
While we could look at the parameters passed to decide which of those two things we're doing, (and require specific parameters for each action), that doesn't change the fact that a human reading the line:
a_building = Jamf::Building.new name: 'Main Building'
sounds like we want to create a new building in the JSS, when in fact we're just retrieving one that's already there.
To make the code more readable and totally clear, .new is not allowed for making instances of Jamf::Resources. Instead, use the class method .fetch to retrieve existing resources, like so:
a_building = Jamf::Building.fetch name: 'Main Building'
This makes it clear what the code is doing, and when you get the error that there's no building with that name, the error makes sense, which it wouldn't if you were creating a new building in the JSS.
Likewise, to make a new one in Jamf Pro, use .create, as in:
a_building = Jamf::Building.create name: 'Main Building'
This makes it obvious that we're creating a new building in the JSS
In both cases, the instance method #save is used to send your changes to the API. If the resource already exists, the changes will be applied to the server with #save. If it doesn't yet exist, it will be created by #save.
# Subclassing
### Required Constant: RSRC_VERSION
The version of the resource model supported by ruby-jss for this class.
Every resource in the Jamf Pro API has a version as part of its URL path. For example, in the full resource URL:
https://your.jamf.server:port/uapi/v1/reenrollment
the resource version is `v1`. At any given time, the API may have many versions of a resource available - v2 might be released with new values available or deprecated values removed, but v1 remains and is unchanged.
Each subclass of Jamf::Resource must define RSRC_VERSION as a String, e.g. 'v1', which defines the version supported by the subclass.
As new versions are released by Jamf, when the changes are implemented in ruby-jss, the RSRC_VERSION is updated.
## Required Constant: OBJECT_MODEL
This is required of all JSONObject subclasses. Refer to that documentation for full details about implementing the OBJECT_MODEL constant.
## Required Constant: RSRC_PATH
This is the URI path to the resource, relative to the API base and version ('uapi/vX/').
Examples:
1. For SingletonResource class {Jamf::Settings::ReEnrollment}, the URL to
the resource is:
https://your.jamf.server:port/uapi/v1/reenrollment
and that URL is used to GET and PUT data, and as a base for the change
log data.
The constant {Jamf::Settings::ReEnrollment::RSRC_PATH} must be
`'reenrollment'`
2. For CollectionResource class {Jamf::MobileDevice}, the URL to the
collection Array is:
https://your.jamf.server:port/uapi/v1/mobile-devices
and that URL is used to GET lists of mobileDevice data and POST data
to create a new mobile device.
It is also the base URL for GET, PATCH, PUT and DELETE for individual
mobileDevices, and their details and change log data.
The constant {Jamf::MobileDevice::RSRC_PATH} must be
`'mobile-devices'`
## Required Constant: RSRC_VERSION
As shown in the examples above, the URL paths for resources have a version number between 'uapi' and the RSRC_PATH
Both SingletonResources and CollectionResources must defing the constant RSRC_VERSION as a string containing that version, e.g. 'v1'
ruby-jss doesn't support the older resource paths that don't have a version in their path.
Direct Known Subclasses
Constant Summary collapse
- NEW_CALLERS =
These methods are allowed to call .new
['fetch', 'create', 'all', 'cached_all', 'block in all', 'block in cached_all'].freeze
- RSRC_PREVIEW_VERSION =
The resource version for previewing new features
'preview'.freeze
Instance Attribute Summary collapse
-
#cnx ⇒ Jamf::Connection
readonly
The API connection thru which we deal with this resource.
-
#rsrc_path ⇒ String
readonly
The resouce path for this object.
Class Method Summary collapse
-
.allocate(*args, &block) ⇒ Object
extended
from BaseClass
Can't allocate if base class.
- .base_class? ⇒ Boolean extended from BaseClass
-
.new(data, cnx: Jamf.cnx) ⇒ Object
Disallow direct use of ruby's .new class method for creating instances.
- .preview_path ⇒ Object
-
.rsrc_path ⇒ String
the resource path for this resource.
-
.stop_if_base_class(action = DEFAULT_ACTION) ⇒ Object
extended
from BaseClass
raise an exception if this class is a base class.
Instance Method Summary collapse
-
#save ⇒ Object
TODO: error handling.
Constructor Details
This class inherits a constructor from Jamf::JSONObject
Instance Attribute Details
#cnx ⇒ Jamf::Connection (readonly)
Returns the API connection thru which we deal with this resource.
222 223 224 |
# File 'lib/jamf/api/base_classes/resource.rb', line 222 def cnx @cnx end |
#rsrc_path ⇒ String (readonly)
Returns the resouce path for this object.
225 226 227 |
# File 'lib/jamf/api/base_classes/resource.rb', line 225 def rsrc_path @rsrc_path end |
Class Method Details
.allocate(*args, &block) ⇒ Object Originally defined in module BaseClass
Can't allocate if base class
.base_class? ⇒ Boolean Originally defined in module BaseClass
.new(data, cnx: Jamf.cnx) ⇒ Object
Disallow direct use of ruby's .new class method for creating instances. Require use of .fetch or .create, or 'all'
210 211 212 213 214 215 |
# File 'lib/jamf/api/base_classes/resource.rb', line 210 def self.new(data, cnx: Jamf.cnx) stop_if_base_class calling_method = caller_locations(1..1).first.label raise Jamf::UnsupportedError, "Use .fetch, .create, or .all(instantiate:true) to instantiate Jamf::Resources" unless NEW_CALLERS.include? calling_method super end |
.preview_path ⇒ Object
203 204 205 |
# File 'lib/jamf/api/base_classes/resource.rb', line 203 def self.preview_path "#{RSRC_PREVIEW_VERSION}/#{self::RSRC_PATH}" end |
.rsrc_path ⇒ String
the resource path for this resource
199 200 201 |
# File 'lib/jamf/api/base_classes/resource.rb', line 199 def self.rsrc_path @rsrc_path ||= "#{self::RSRC_VERSION}/#{self::RSRC_PATH}" end |
Instance Method Details
#save ⇒ Object
TODO: error handling
231 232 233 234 235 236 237 238 239 240 |
# File 'lib/jamf/api/base_classes/resource.rb', line 231 def save raise Jamf::UnsupportedError, "#{self.class} objects cannot be changed" unless self.class.mutable? return unless unsaved_changes? exist? ? update_in_jamf : create_in_jamf clear_unsaved_changes @id || :saved end |