Class: JSS::APIObject

Inherits:
Object show all
Defined in:
lib/jss.rb,
lib/jss/api_object.rb

Overview

This class is the parent to all JSS API objects. It provides standard methods and structures that apply to all API resouces.

See the README.md file for general info about using subclasses of JSS::APIObject

Subclassing

Constructor

In general, subclasses should do any class-specific argument checking before calling super, and then afterwards, use the contents of @init_data to populate any class-specific attributes. @id, @name, @rest_rsrc, and @in_jss are handled here.

If a subclass can be looked up by some key other than :name or :id, the subclass must pass the keys as an Array in the second argument when calling super from #initialize. See Computer#initialize for an example of how to implement this feature.

Object Creation

If a subclass should be able to be created in the JSS be sure to include Creatable

The constructor should verify any extra required data (aside from :name) in the args before or after calling super.

See Creatable for more details.

Object Modification

If a subclass should be modifiable in the JSS, include Updatable, q.v. for details.

Object Deletion

All subclasses can be deleted in the JSS.

Required Constants

Subclasses must provide certain Constants in order to correctly interpret API data and communicate with the API.

RSRC_BASE = [String], The base for REST resources of this class

e.g. ‘computergroups’ in “casper.mycompany.com:8443/JSSResource/computergroups/id/12

RSRC_LIST_KEY = [Symbol] The Hash key for the JSON list output of all objects of this class in the JSS.

e.g. the JSON output of resource “JSSResource/computergroups” is a hash with one item (an Array of computergroups). That item’s key is the Symbol :computer_groups

RSRC_OBJECT_KEY = [Symbol] The Hash key used for individual JSON object output.

It’s also used in various error messages

e.g. the JSON output of the resource “JSSResource/computergroups/id/436” is a hash with one item (another hash with details of one computergroup). That item’s key is the Symbol :computer_group

VALID_DATA_KEYS = [Array<Symbol>] The Hash keys used to verify validity of :data

When instantiating a subclass using :data => somehash, some minimal checks are performed to ensure the data is valid for the subclass

The Symbols in this Array are compared to the keys of the hash provided. If any of these don’t exist in the hash’s keys, then the :data is not valid and an exception is raised.

The keys :id and :name must always exist in the hash. If only :id and :name are valid, VALID_DATA_KEYS should be an empty array.

e.g. for a department, only :id and :name are valid, so VALID_DATA_KEYS is an empty Array ([]) but for a computer group, the keys :computers and :is_smart must be present as well. so VALID_DATA_KEYS will be [:computers, :is_smart]

NOTE Some API objects have data broken into subsections, in which case the VALID_DATA_KEYS are expected in the section :general.

Optional Constants

OTHER_LOOKUP_KEYS = [HashSymbol=>Hash] Every object can be looked up by

:id and :name, but some have other uniq identifiers that can also be used, e.g. :serial_number, :mac_address, and so on. This Hash, if defined, speficies those other keys for the subclass For more details about this hash, see DEFAULT_LOOKUP_KEYS, APIObject.fetch, and APIObject#lookup_object_data

Constant Summary collapse

REQUIRED_DATA_KEYS =

These Symbols are added to VALID_DATA_KEYS for performing the :data validity test described above.

%i[id name].freeze
DEFAULT_LOOKUP_KEYS =

All API objects have an id and a name. As such By these keys are available for object lookups.

Others can be defined by subclasses in their OTHER_LOOKUP_KEYS constant which has the same format, described here:

The merged Hashes DEFAULT_LOOKUP_KEYS and OTHER_LOOKUP_KEYS (as provided by the .all_lookup_keys Class method) define what unique identifiers can be passed as parameters to the fetch method for retrieving an object from the API. They also define the class methods that return a list (Array) of all such identifiers for the class (e.g. the :all_ids class method returns an array of all id’s for an APIObject subclass)

Since there’s often a discrepency between the name of the identifier as an attribute (e.g. serial_number) and the REST resource key for retrieving that object (e.g. ../computers/serialnumber/xxxxx) this hash also explicitly provides the REST resource key for a given lookup key, so e.g. both serialnumber and serial_number can be used, and both will have the resource key ‘serialnumber’ and the list method ‘:all_serial_numbers’

Here’s how the Hash is structured, using serialnumber as an example:

LOOKUP_KEYS =

serialnumber: {rsrc_key: :serialnumber, list: :all_serial_numbers,
serial_number: :serialnumber, list: :all_serial_numbers

}

{
  id: { rsrc_key: :id, list: :all_ids },
  name: { rsrc_key: :name, list: :all_names }
}.freeze
OBJECT_HISTORY_TABLE =

This table holds the object history for JSS objects. Object history is not available via the API, only MySQL.

'object_history'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ APIObject

The args hash must include :id, :name, or :data.

  • :id or :name will be looked up via the API

    • if the subclass includes JSS::Creatable, :id can be :new, to create a new object in the JSS. and :name is required

  • :data must be the JSON output of a separate JSS::APIConnection query (a Hash of valid object data)

Some subclasses can accept other options, by pasing their keys in a final Array

Parameters:

  • args (Hash) (defaults to: {})

    the data for looking up, or constructing, a new object.

Options Hash (args):

  • :id (Integer)

    the jss id to look up

  • :name (String)

    the name to look up

  • :data (Hash)

    the JSON output of a separate JSS::APIConnection query NOTE: This arg is deprecated and will be removed in a future release.

Raises:



616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
# File 'lib/jss/api_object.rb', line 616

def initialize(args = {})
  args[:api] ||= JSS.api
  @api = args[:api]
  raise JSS::UnsupportedError, 'JSS::APIObject cannot be instantiated' if self.class == JSS::APIObject

  ####### Previously looked-up JSON data
  # DEPRECATED: pre-lookedup data is never used
  # and support for it will be going away.
  if args[:data]

    @init_data = args[:data]

    validate_external_init_data

  ###### Make a new one in the JSS, but only if we've included the Creatable module
  elsif args[:id] == :new
    validate_init_for_creation(args)
    setup_object_for_creation(args)
    @need_to_update = true
  ###### Look up the data via the API
  else
    @init_data = look_up_object_data(args)
    @need_to_update = false
  end ## end arg parsing

  parse_init_data
end

Instance Attribute Details

#apiJSS::APIConnection (readonly)

Returns the API connection thru which we deal with this object.

Returns:



577
578
579
# File 'lib/jss/api_object.rb', line 577

def api
  @api
end

#idInteger (readonly)

Returns the JSS id number.

Returns:

  • (Integer)

    the JSS id number



584
585
586
# File 'lib/jss/api_object.rb', line 584

def id
  @id
end

#in_jssBoolean (readonly) Also known as: in_jss?

Returns is it in the JSS?.

Returns:

  • (Boolean)

    is it in the JSS?



590
591
592
# File 'lib/jss/api_object.rb', line 590

def in_jss
  @in_jss
end

#init_dataObject (readonly)

Returns the parsed JSON data retrieved from the API when this object was fetched.

Returns:

  • the parsed JSON data retrieved from the API when this object was fetched



581
582
583
# File 'lib/jss/api_object.rb', line 581

def init_data
  @init_data
end

#nameString (readonly)

Returns the name.

Returns:



587
588
589
# File 'lib/jss/api_object.rb', line 587

def name
  @name
end

#rest_rsrcString (readonly)

Returns the Rest resource for API access (the part after “JSSResource/” ).

Returns:

  • (String)

    the Rest resource for API access (the part after “JSSResource/” )



593
594
595
# File 'lib/jss/api_object.rb', line 593

def rest_rsrc
  @rest_rsrc
end

Class Method Details

.all(refresh = false, api: JSS.api) ⇒ Array<Hash{:name=>String, :id=> Integer}>

Return an Array of Hashes for all objects of this subclass in the JSS.

This method is only valid in subclasses of JSS::APIObject, and is the parsed JSON output of an API query for the resource defined in the subclass’s RSRC_BASE, e.g. for JSS::Computer, with the RSRC_BASE of :computers, This method retuens the output of the ‘JSSResource/computers’ resource, which is a list of all computers in the JSS.

Each item in the Array is a Hash with at least two keys, :id and :name. The class methods .all_ids and .all_names provide easier access to those data as mapped Arrays.

Some API classes provide other data in each Hash, e.g. :udid (for computers and mobile devices) or :is_smart (for groups).

Subclasses implementing those API classes should provide .all_xxx class methods for accessing those other values as mapped Arrays, e.g. JSS::Computer.all_udids

The results of the first query for each subclass is stored in the .object_list_cache of the given JSS::APIConnection and returned at every future call, so as to not requery the server every time.

To force requerying to get updated data, provided a non-false argument. I usually use :refresh, so that it’s obvious what I’m doing, but true, 1, or anything besides false or nil will work.

To query an APIConnection other than the currently active one, provide one via the api: named parameter.

Parameters:

  • refresh (Boolean) (defaults to: false)

    should the data be re-queried from the API?

  • api (JSS::APIConnection) (defaults to: JSS.api)

    an API connection to use for the query. Defaults to the corrently active API. See JSS::APIConnection

Returns:

Raises:



163
164
165
166
167
168
# File 'lib/jss/api_object.rb', line 163

def self.all(refresh = false, api: JSS.api)
  raise JSS::UnsupportedError, '.all can only be called on subclasses of JSS::APIObject' if self == JSS::APIObject
  api.object_list_cache[self::RSRC_LIST_KEY] = nil if refresh
  return api.object_list_cache[self::RSRC_LIST_KEY] if api.object_list_cache[self::RSRC_LIST_KEY]
  api.object_list_cache[self::RSRC_LIST_KEY] = api.get_rsrc(self::RSRC_BASE)[self::RSRC_LIST_KEY]
end

.all_ids(refresh = false, api: JSS.api) ⇒ Array<Integer>

Returns an Array of the JSS id numbers of all the members of the subclass.

e.g. When called from subclass JSS::Computer, returns the id’s of all computers in the JSS

Parameters:

  • refresh (Boolean) (defaults to: false)

    should the data be re-queried from the API?

  • api (JSS::APIConnection) (defaults to: JSS.api)

    an API connection to use for the query. Defaults to the corrently active API. See JSS::APIConnection

Returns:

  • (Array<Integer>)

    the ids of all it1ems of this subclass in the JSS



183
184
185
# File 'lib/jss/api_object.rb', line 183

def self.all_ids(refresh = false, api: JSS.api)
  all(refresh, api: api).map { |i| i[:id] }
end

.all_lookup_keysHash

The combined DEFAULT_LOOKUP_KEYS and OTHER_LOOKUP_KEYS (which may be defined in subclasses)

Returns:

  • (Hash)

    See DEFAULT_LOOKUP_KEYS constant



412
413
414
415
# File 'lib/jss/api_object.rb', line 412

def self.all_lookup_keys
  return DEFAULT_LOOKUP_KEYS.merge(self::OTHER_LOOKUP_KEYS) if defined? self::OTHER_LOOKUP_KEYS
  DEFAULT_LOOKUP_KEYS
end

.all_names(refresh = false, api: JSS.api) ⇒ Array<String>

Returns an Array of the JSS names of all the members of the subclass.

e.g. When called from subclass JSS::Computer, returns the names of all computers in the JSS

Parameters:

  • refresh (Boolean) (defaults to: false)

    should the data be re-queried from the API?

  • api (JSS::APIConnection) (defaults to: JSS.api)

    an API connection to use for the query. Defaults to the corrently active API. See JSS::APIConnection

Returns:

  • (Array<String>)

    the names of all item of this subclass in the JSS



200
201
202
# File 'lib/jss/api_object.rb', line 200

def self.all_names(refresh = false, api: JSS.api)
  all(refresh, api: api).map { |i| i[:name] }
end

.all_objects(refresh = false, api: JSS.api) ⇒ Hash{Integer => Object}

Return an Array of JSS::APIObject subclass instances e.g when called on JSS::Package, return all JSS::Package objects in the JSS.

NOTE: This may be slow as it has to look up each object individually! use it wisely.

Parameters:

  • refresh (Boolean) (defaults to: false)

    should the data re-queried from the API?

  • api (JSS::APIConnection) (defaults to: JSS.api)

    an API connection to use for the query. Defaults to the corrently active API. See JSS::APIConnection

Returns:

  • (Hash{Integer => Object})

    the objects requested



253
254
255
256
257
# File 'lib/jss/api_object.rb', line 253

def self.all_objects(refresh = false, api: JSS.api)
  objects_key = "#{self::RSRC_LIST_KEY}_objects".to_sym
  return api.object_list_cache[objects_key] unless refresh || api.object_list_cache[objects_key].nil?
  api.object_list_cache[objects_key] = all(refresh, api: api).map { |o| fetch id: o[:id], api: api }
end

.delete(victims, api: JSS.api) ⇒ Array<Integer>

Delete one or more API objects by jss_id without instantiating them. Non-existent id’s are skipped and an array of skipped ids is returned.

If an Array is provided, it is passed through #uniq! before being processed.

Parameters:

  • victims (Integer, Array<Integer>)

    An object id or an array of them to be deleted

  • api (JSS::APIConnection) (defaults to: JSS.api)

    the API connection to use. Defaults to the corrently active API. See JSS::APIConnection

Returns:

  • (Array<Integer>)

    The id’s that didn’t exist when we tried to delete them.

Raises:



500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
# File 'lib/jss/api_object.rb', line 500

def self.delete(victims, api: JSS.api)
  raise JSS::UnsupportedError, '.delete can only be called on subclasses of JSS::APIObject' if self == JSS::APIObject
  raise JSS::InvalidDataError, 'Parameter must be an Integer ID or an Array of them' unless victims.is_a?(Integer) || victims.is_a?(Array)

  case victims
  when Integer
    victims = [victims]
  when Integer
    victims = [victims]
  when Array
    victims.uniq!
  end

  skipped = []
  current_ids = all_ids :refresh, api: api
  victims.each do |vid|
    if current_ids.include? vid
      api.delete_rsrc "#{self::RSRC_BASE}/id/#{vid}"
    else
      skipped << vid
    end # if current_ids include v
  end # each victim

  skipped
end

.exist?(identifier, refresh = false, api: JSS.api) ⇒ Boolean

Return true or false if an object of this subclass with the given Identifier exists on the server

one of the available lookup_keys

Parameters:

  • identfier (String, Integer)

    An identifier for an object, a value for

  • refresh (Boolean) (defaults to: false)

    Should the data be re-read from the server

  • api (JSS::APIConnection) (defaults to: JSS.api)

    an API connection to use for the query. Defaults to the corrently active API. See JSS::APIConnection

Returns:

  • (Boolean)

    does an object with the given identifier exist?



272
273
274
# File 'lib/jss/api_object.rb', line 272

def self.exist?(identifier, refresh = false, api: JSS.api)
  !valid_id(identifier, refresh, api: api).nil?
end

.fetch(arg, api: JSS.api) ⇒ APIObject

Retrieve an object from the API.

This is the preferred way to retrieve existing objects from the JSS. It’s a wrapper for using APIObject.new and avoids the confusion of using ruby’s .new class method when you’re not creating a new object.

For creating new objects in the JSS, use make

Parameters:

  • args (Hash)

    The data for fetching an object, such as id: or name: See #initialize

Returns:

  • (APIObject)

    The ruby-instance of a JSS object

Raises:



440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
# File 'lib/jss/api_object.rb', line 440

def self.fetch(arg, api: JSS.api)
  raise JSS::UnsupportedError, 'JSS::APIObject cannot be instantiated' if self.class == JSS::APIObject

  # if given a hash (or a colletion of named params)
  # pass to .new
  if arg.is_a? Hash
    raise ArgumentError, 'Use .make to create new JSS objects' if arg[:id] == :new
    arg[:api] ||= api
    return new arg
  end

  # loop thru the lookup_key list methods for this class
  # and if it's result includes the desired value,
  # the pass they key and arg to .new
  lookup_key_list_methods.each do |key, method_name|
    return new(key => arg, :api => api) if method_name && send(method_name).include?(arg)
  end # each key

  # if we're here, we couldn't find a matching object
  raise NoSuchItemError, "No #{self::RSRC_OBJECT_KEY} found matching '#{arg}'"
end

.get_name(a_thing) ⇒ String

Some API objects contain references to other API objects. Usually those references are a Hash containing the :id and :name of the target. Sometimes, however the reference is just the name of the target.

A Script has a property :category, which comes from the API as a String, the name of the category for that script. e.g. “GoodStuff”

A Policy also has a property :category, but it comes from the API as a Hash with both the name and id, e.g. {:id => 8, :name => “GoodStuff”}

When that reference is to a single thing (like the category to which something belongs) APIObject subclasses usually store only the name, and use the name when returning data to the API.

When an object references a list of related objects (like the computers assigned to a user) that list will be and Array of Hashes as above, with both the :id and :name

This method is just a handy way to extract the name regardless of how it comes from the API. Most APIObject subclasses use it in their #initialize method

Parameters:

  • a_thing (String, Array)

    the api data from which we’re extracting the name

Returns:

  • (String)

    the name extracted from a_thing



371
372
373
374
375
376
377
378
379
380
# File 'lib/jss/api_object.rb', line 371

def self.get_name(a_thing)
  case a_thing
  when String
    a_thing
  when Hash
    a_thing[:name]
  when nil
    nil
  end
end

.lookup_key_list_methodsHash

Returns the available lookup keys mapped to the appropriate list class method (e.g. id: :all_ids ).

Returns:

  • (Hash)

    the available lookup keys mapped to the appropriate list class method (e.g. id: :all_ids )



420
421
422
423
424
# File 'lib/jss/api_object.rb', line 420

def self.lookup_key_list_methods
  hash = {}
  all_lookup_keys.each { |key, deets| hash[key] = deets[:list] }
  hash
end

.lookup_keysArray<Symbol>

What are all the lookup keys available for this class?

Returns:

  • (Array<Symbol>)

    the DEFAULT_LOOKUP_KEYS plus any OTHER_LOOKUP_KEYS defined for this class



387
388
389
390
# File 'lib/jss/api_object.rb', line 387

def self.lookup_keys
  return DEFAULT_LOOKUP_KEYS.keys unless defined? self::OTHER_LOOKUP_KEYS
  DEFAULT_LOOKUP_KEYS.keys + self::OTHER_LOOKUP_KEYS.keys
end

.make(**args) ⇒ APIObject

Make a ruby instance of a not-yet-existing APIObject.

This is the preferred way to create new objects in the JSS. It’s a wrapper for using APIObject.new with the ‘id: :new’ parameter. and helps avoid the confusion of using ruby’s .new class method for making ruby instances.

For retrieving existing objects in the JSS, use fetch

For actually creating the object in the JSS, see APIObject#create

Parameters:

  • args (Hash)

    The data for creating an object, such as name: See #initialize

Returns:

  • (APIObject)

    The un-created ruby-instance of a JSS object

Raises:



478
479
480
481
482
483
484
# File 'lib/jss/api_object.rb', line 478

def self.make(**args)
  args[:api] ||= JSS.api
  raise JSS::UnsupportedError, 'JSS::APIObject cannot be instantiated' if self.class == JSS::APIObject
  raise ArgumentError, "Use '#{self.class}.fetch id: xx' to retrieve existing JSS objects" if args[:id]
  args[:id] = :new
  new args
end

.map_all_ids_to(other_key, refresh = false, api: JSS.api) ⇒ Hash{Integer => Oject}

Return a hash of all objects of this subclass in the JSS where the key is the id, and the value is some other key in the data items returned by the JSS::APIObject.all.

If the other key doesn’t exist in the API data, (eg :udid for JSS::Department) the values will be nil.

Use this method to map ID numbers to other identifiers returned by the API list resources. Invert its result to map the other identfier to ids.

Examples:

JSS::Computer.map_all_ids_to(:name)

# Returns, eg {2 => "kimchi", 5 => "mantis"}

JSS::Computer.map_all_ids_to(:name).invert

# Returns, eg {"kimchi" => 2, "mantis" => 5}

Parameters:

  • other_key (Symbol)

    the other data key with which to associate each id

  • refresh (Boolean) (defaults to: false)

    should the data re-queried from the API?

  • api (JSS::APIConnection) (defaults to: JSS.api)

    an API connection to use for the query. Defaults to the corrently active API. See JSS::APIConnection

Returns:

  • (Hash{Integer => Oject})

    the associated ids and data



233
234
235
236
237
# File 'lib/jss/api_object.rb', line 233

def self.map_all_ids_to(other_key, refresh = false, api: JSS.api)
  h = {}
  all(refresh, api: api).each { |i| h[i[:id]] = i[other_key] }
  h
end

.rsrc_keysHash

Returns the available lookup keys mapped to the appropriate resource key for building a REST url to retrieve an object.

Returns:

  • (Hash)

    the available lookup keys mapped to the appropriate resource key for building a REST url to retrieve an object.



395
396
397
398
399
# File 'lib/jss/api_object.rb', line 395

def self.rsrc_keys
  hash = {}
  all_lookup_keys.each { |key, deets| hash[key] = deets[:rsrc_key] }
  hash
end

.valid_id(identifier, refresh = false, api: JSS.api) ⇒ Integer?

Return an id or nil if an object of this subclass with the given name or id exists on the server

one of the available lookup_keys

Parameters:

  • identfier (String, Integer)

    An identifier for an object, a value for

  • refresh (Boolean) (defaults to: false)

    Should the data be re-read from the server

  • api (JSS::APIConnection) (defaults to: JSS.api)

    an API connection to use for the query. Defaults to the corrently active API. See JSS::APIConnection

Returns:

  • (Integer, nil)

    the id of the matching object, or nil if it doesn’t exist



289
290
291
292
293
294
295
296
297
298
# File 'lib/jss/api_object.rb', line 289

def self.valid_id(identifier, refresh = false, api: JSS.api)
  return identifier if all_ids(refresh, api: api).include? identifier
  id = nil
  all_lookup_keys.keys.each do |key|
    next if key == :id
    id = map_all_ids_to(key).invert[identifier]
    return id if id
  end # do key
  id
end

.xml_list(array, content = :name) ⇒ REXML::Element

Convert an Array of Hashes of API object data to a REXML element.

Given an Array of Hashes of items in the subclass where each Hash has at least an :id or a :name key, (as what comes from the .all class method) return a REXML <classes> element with one <class> element per Hash member.

Examples:

# for class JSS::Computer
some_comps = [{:id=>2, :name=>"kimchi"},{:id=>5, :name=>"mantis"}]
xml_names = JSS::Computer.xml_list some_comps
puts xml_names  # output manually formatted for clarity, xml.to_s has no newlines between elements

<computers>
  <computer>
    <name>kimchi</name>
  </computer>
  <computer>
    <name>mantis</name>
  </computer>
</computers>

xml_ids = JSS::Computer.xml_list some_comps, :id
puts xml_names  # output manually formatted for clarity, xml.to_s has no newlines between elements

<computers>
  <computer>
    <id>2</id>
  </computer>
  <computer>
    <id>5</id>
  </computer>
</computers>

Parameters:

  • array (Array<Hash{:name=>String, :id =>Integer, Symbol=>#to_s}>)

    the Array of subclass data to convert

  • content (Symbol) (defaults to: :name)

    the Hash key to use as the inner element for each member of the Array

Returns:

  • (REXML::Element)

    the XML element representing the data



342
343
344
# File 'lib/jss/api_object.rb', line 342

def self.xml_list(array, content = :name)
  JSS.item_list_to_rexml_list self::RSRC_LIST_KEY, self::RSRC_OBJECT_KEY, array, content
end

Instance Method Details

#add_object_history_entry(user: nil, notes: nil, details: nil) ⇒ void

This method returns an undefined value.

Make an entry in this object’s Object History. For this to work, the APIObject subclass must define OBJECT_HISTORY_OBJECT_TYPE, an integer indicating the object type in the OBJECT_HISTORY_TABLE in the database (e.g. for computers, the object type is 1)

NOTE: Object history is not available via the API,

so access is only available through direct MySQL
connections

Also: the ‘details’ column in the table shows up in the

'notes' column of the Web UI.  and the 'object_description'
column of the table shows up in the 'details' column of
the UI, under the 'details' button.

The params below reflect the UI, not the table.

Parameters:

  • user (String) (defaults to: nil)

    the username creating the entry.

  • notes (String) (defaults to: nil)

    A string that appears as a ‘note’ in the history

  • details (String) (defaults to: nil)

    A string that appears as the ‘details’ in the history

Raises:



802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
# File 'lib/jss/api_object.rb', line 802

def add_object_history_entry(user: nil, notes: nil, details: nil)
  validate_object_history_available

  raise JSS::MissingDataError, 'A user: must be provided to make the entry' unless user

  raise JSS::MissingDataError, 'Either notes: must be provided to make the entry' unless notes

  user = "'#{Mysql.quote user.to_s}'"
  notes =  "'#{Mysql.quote notes.to_s}'"
  obj_type = self.class::OBJECT_HISTORY_OBJECT_TYPE

  field_list = 'object_type, object_id, username, details, timestamp_epoch'
  value_list = "#{obj_type}, #{@id}, #{user}, #{notes}, #{Time.now.to_jss_epoch}"

  if details
    field_list << ', object_description'
    value_list << ", '#{Mysql.quote details.to_s}'"
  end # if details

  q = "INSERT INTO #{OBJECT_HISTORY_TABLE}
    (#{field_list})
  VALUES
    (#{value_list})"

  JSS::DB_CNX.db.query q
end

#categorizable?Boolean

Returns See Categorizable.

Returns:



681
682
683
# File 'lib/jss/api_object.rb', line 681

def categorizable?
  defined? self.class::CATEGORIZABLE
end

#creatable?Boolean

Returns See Creatable.

Returns:



671
672
673
# File 'lib/jss/api_object.rb', line 671

def creatable?
  defined? self.class::CREATABLE
end

#criterable?Boolean

Returns See Criteriable.

Returns:



696
697
698
# File 'lib/jss/api_object.rb', line 696

def criterable?
  defined? self.class::CRITERIABLE
end

#deletevoid

This method returns an undefined value.

Delete this item from the JSS.

one or more objects by id without needing to instantiate

Subclasses may want to redefine this method, first calling super, then setting other attributes to nil, false, empty, etc..



746
747
748
749
750
751
752
753
754
# File 'lib/jss/api_object.rb', line 746

def delete
  return nil unless @in_jss
  @api.delete_rsrc @rest_rsrc
  @rest_rsrc = "#{self.class::RSRC_BASE}/name/#{CGI.escape @name}"
  @id = nil
  @in_jss = false
  @need_to_update = false
  :deleted
end

#extendable?Boolean

Returns See extendable.

Returns:

  • (Boolean)

    See extendable



706
707
708
# File 'lib/jss/api_object.rb', line 706

def extendable?
  defined? self.class::EXTENDABLE
end

#locatable?Boolean

Returns See Locatable.

Returns:



716
717
718
# File 'lib/jss/api_object.rb', line 716

def locatable?
  defined? self.class::LOCATABLE
end

#matchable?Boolean

Returns See Matchable.

Returns:



711
712
713
# File 'lib/jss/api_object.rb', line 711

def matchable?
  defined? self.class::MATCHABLE
end

#object_historyArray<Hash>

the object history for this object, an array of hashes one per history entry, in order of creation. Each hash contains:

user: String, the username that created the entry
notes:  String, the notes for the entry
date: Time, the timestamp for the entry
details: String or nil, any details provided for the entry

Returns:



839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
# File 'lib/jss/api_object.rb', line 839

def object_history
  validate_object_history_available

  q = "SELECT username, details, timestamp_epoch, object_description
  FROM #{OBJECT_HISTORY_TABLE}
  WHERE object_type = #{self.class::OBJECT_HISTORY_OBJECT_TYPE}
  AND object_id = #{@id}
  ORDER BY object_history_id ASC"

  result = JSS::DB_CNX.db.query q
  history = []
  result.each do |entry|
    history << {
      user: entry[0],
      notes: entry[1],
      date: JSS.epoch_to_time(entry[2]),
      details: entry[3]
    }
  end # each do entry
  history
end

#ppxvoid

This method returns an undefined value.

Print the rest_xml value of the object to stdout, with indentation. Useful for debugging.



866
867
868
869
870
# File 'lib/jss/api_object.rb', line 866

def ppx
  return nil unless creatable? || updatable?
  REXML::Document.new(rest_xml).write $stdout, 2
  puts
end

#pretty_print_instance_variablesArray

Remove the init_data and api object from the instance_variables used to create pretty-print (pp) output.

Returns:

  • (Array)

    the desired instance_variables



770
771
772
773
774
775
# File 'lib/jss/api_object.rb', line 770

def pretty_print_instance_variables
  vars = instance_variables.sort
  vars.delete :@api
  vars.delete :@init_data
  vars
end

#purchasable?Boolean

Returns See Purchasable.

Returns:



721
722
723
# File 'lib/jss/api_object.rb', line 721

def purchasable?
  defined? self.class::PURCHASABLE
end

#saveInteger

Either Create or Update this object in the JSS

If this item is creatable or updatable, then create it if needed, or update it if it already exists.

Returns:

  • (Integer)

    the id of the item created or updated



654
655
656
657
658
659
660
661
662
# File 'lib/jss/api_object.rb', line 654

def save
  if @in_jss
    raise JSS::UnsupportedError, 'Updating this object in the JSS is currently not supported by ruby-jss' unless updatable?
    update
  else
    raise JSS::UnsupportedError, 'Creating this object in the JSS is currently not supported by ruby-jss' unless creatable?
    create
  end
end

#scopable?Boolean

Returns See Scopable.

Returns:



726
727
728
# File 'lib/jss/api_object.rb', line 726

def scopable?
  defined? self.class::SCOPABLE
end

#self_servable?Boolean

Returns See SelfServable.

Returns:



691
692
693
# File 'lib/jss/api_object.rb', line 691

def self_servable?
  defined? self.class::SELF_SERVABLE
end

#sitable?Boolean

Returns See Sitable.

Returns:



701
702
703
# File 'lib/jss/api_object.rb', line 701

def sitable?
  defined? self.class::SITABLE
end

#to_sString

A meaningful string representation of this object

Returns:



760
761
762
# File 'lib/jss/api_object.rb', line 760

def to_s
  "#{self.class}, name: #{@name}, id: #{@id}"
end

#updatable?Boolean

Returns See Updatable.

Returns:



676
677
678
# File 'lib/jss/api_object.rb', line 676

def updatable?
  defined? self.class::UPDATABLE
end

#uploadable?Boolean

Returns See Uploadable.

Returns:



731
732
733
# File 'lib/jss/api_object.rb', line 731

def uploadable?
  defined? self.class::UPLOADABLE
end

#vppable?Boolean

Returns See VPPable.

Returns:



686
687
688
# File 'lib/jss/api_object.rb', line 686

def vppable?
  defined? self.class::VPPABLE
end