Class: JSS::ExtensionAttribute
- Defined in:
- lib/jss/api_object/extension_attribute.rb,
lib/jss.rb
Overview
The parent class of ExtensionAttribute objects in the JSS.
The API extension attribute objects work with the definitions of extension attributes, not the resulting values stored in the JSS with the inventory reports.
This superclass, however, uses the AdvancedSearch subclasses to provide access to the reported values in two ways:
-
A list of target objects with a certain value for the ExtensionAttribute instance. See the #all_with_result method for details
-
A list of the most recent value for this ExtensionAttribute in all targets in the JSS
The ComputerExtensionAttribute subclass offers a ComputerExtensionAttribute#history method providing the history of values for the EA for one computer. This requires MySQL access to the JSS database since that history isn’t available via the API.
Subclasses of ExtensionAttribute must define these constants:
-
TARGET_CLASS - the APIObject subclass to which the extention attribute applies. e.g. Computer
-
ALL_TARGETS_CRITERION - a Criteriable::Criterion instance that will be used in an AdvancedSearch to find all of members of the TARGET_CLASS
Direct Known Subclasses
ComputerExtensionAttribute, MobileDeviceExtensionAttribute, UserExtensionAttribute
Constant Summary collapse
- DATA_TYPE_STRING =
What kinds of data can be created by EAs? Note, Dates must be in the format “YYYY-MM-DD hh:mm:ss”
'String'.freeze
- DATA_TYPE_NUMBER =
'Number'.freeze
- DATA_TYPE_INTEGER =
'Integer'.freeze
- DATA_TYPE_DATE =
'Date'.freeze
- DATA_TYPES =
[DATA_TYPE_STRING, DATA_TYPE_DATE, DATA_TYPE_INTEGER].freeze
- DEFAULT_DATA_TYPE =
DATA_TYPE_STRING- NUMERIC_TYPES =
ExtensionAttributes refer to the numeric data type as “Integer” but the ext. attr values that come with extendable objects refer to that data type as “Number”. Here’s an array with both, so we can work with ether more easily.
[DATA_TYPE_NUMBER, DATA_TYPE_INTEGER].freeze
- INPUT_TYPE_FIELD =
Where does the data come from?
'Text Field'.freeze
- INPUT_TYPE_POPUP =
'Pop-up Menu'.freeze
- INPUT_TYPE_SCRIPT =
'script'.freeze
- INPUT_TYPE_LDAP =
'LDAP Attribute Mapping'.freeze
- INPUT_TYPES =
[INPUT_TYPE_FIELD, INPUT_TYPE_POPUP, INPUT_TYPE_SCRIPT, INPUT_TYPE_LDAP].freeze
- DEFAULT_INPUT_TYPE =
INPUT_TYPE_FIELD- WEB_DISPLAY_CHOICES =
Where can it be displayed in the WebApp? subclasses can add to this list
[ 'General', 'Operating System', 'Hardware', 'User and Location', 'Purchasing', 'Extension Attributes' ].freeze
- DEFAULT_WEB_DISPLAY_CHOICE =
'Extension Attributes'.freeze
- LAST_RECON_FIELD =
'Last Inventory Update'.freeze
- LAST_RECON_FIELD_SYM =
LAST_RECON_FIELD.tr(' ', '_').to_sym
- USERNAME_FIELD =
'Username'.freeze
- USERNAME_FIELD_SYM =
USERNAME_FIELD.to_sym
Instance Attribute Summary collapse
-
#data_type ⇒ String
The type of data created by the EA.
-
#description ⇒ String
(also: #desc)
Description of the ext attrib.
-
#input_type ⇒ String
Where does this data come from? Must be one of the INPUT_TYPES.
-
#need_to_update ⇒ Boolean
included
from Updatable
readonly
Do we have unsaved changes?.
-
#popup_choices ⇒ Array<String>
The choices available in the UI when the @input_type is “Pop-up Menu”.
-
#web_display ⇒ String
In which part of the web UI does the data appear?.
Instance Method Summary collapse
-
#all_with_result(search_type, desired_value) ⇒ Array<Hash{:id=>Integer,:name=>String,:value=>String,Integer,Time}>
Get an Array of Hashes for all inventory objects with a desired result in their latest report for this EA.
-
#clone(new_name, api: nil) ⇒ APIObject
included
from Creatable
make a clone of this API object, with a new name.
- #create ⇒ Object
- #delete ⇒ Object
- #from_ldap? ⇒ Boolean
- #from_popup_menu? ⇒ Boolean
- #from_script? ⇒ Boolean
- #from_text_field? ⇒ Boolean
-
#initialize(args = {}) ⇒ ExtensionAttribute
constructor
A new instance of ExtensionAttribute.
-
#latest_values ⇒ Array<Hash{:id=>Integer,:name=>String,:value=>String,Integer,Time,:as_of=>Time}>
for this EA on all inventory objects in the JSS.
-
#name=(newname) ⇒ void
included
from Updatable
Change the name of this item Remember to #update to push changes to the server.
- #update ⇒ Object
Constructor Details
#initialize(args = {}) ⇒ ExtensionAttribute
Returns a new instance of ExtensionAttribute.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/jss/api_object/extension_attribute.rb', line 140 def initialize(args = {}) super args # @init_data now has the raw data # so fill in our attributes or set defaults @description = @init_data[:description] @data_type = @init_data[:data_type] || DEFAULT_DATA_TYPE @web_display = @init_data[:inventory_display] || DEFAULT_WEB_DISPLAY_CHOICE if @init_data[:input_type] @input_type = @init_data[:input_type][:type] || DEFAULT_INPUT_TYPE @popup_choices = @init_data[:input_type][:popup_choices] # popups can always contain blank @popup_choices << JSS::BLANK if @popup_choices else @input_type = DEFAULT_INPUT_TYPE end # the name of the EA might have spaces and caps, which the will come to us as symbols with the spaces # as underscores, like this. @symbolized_name = @name.gsub(/-| /, '_').to_sym end |
Instance Attribute Details
#data_type ⇒ String
Returns the type of data created by the EA. Must be one of DATA_TYPES.
122 123 124 |
# File 'lib/jss/api_object/extension_attribute.rb', line 122 def data_type @data_type end |
#description ⇒ String Also known as: desc
Returns description of the ext attrib.
119 120 121 |
# File 'lib/jss/api_object/extension_attribute.rb', line 119 def description @description end |
#input_type ⇒ String
Returns where does this data come from? Must be one of the INPUT_TYPES.
125 126 127 |
# File 'lib/jss/api_object/extension_attribute.rb', line 125 def input_type @input_type end |
#need_to_update ⇒ Boolean (readonly) Originally defined in module Updatable
Returns do we have unsaved changes?.
#popup_choices ⇒ Array<String>
Returns the choices available in the UI when the @input_type is “Pop-up Menu”.
128 129 130 |
# File 'lib/jss/api_object/extension_attribute.rb', line 128 def popup_choices @popup_choices end |
#web_display ⇒ String
Returns In which part of the web UI does the data appear?.
131 132 133 |
# File 'lib/jss/api_object/extension_attribute.rb', line 131 def web_display @web_display end |
Instance Method Details
#all_with_result(search_type, desired_value) ⇒ Array<Hash{:id=>Integer,:name=>String,:value=>String,Integer,Time}>
Get an Array of Hashes for all inventory objects with a desired result in their latest report for this EA.
Each Hash is one inventory object (computer, mobile device, user), with these keys:
:id - the computer id
:name - the computer name
:value - the matching ext attr value for the objects latest report.
This is done by creating a temprary AdvancedSearch for objects with matching values in the EA field, then getting the #search_results hash from it.
The AdvancedSearch is then deleted.
must be a member of JSS::Criterion::SEARCH_TYPES
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/jss/api_object/extension_attribute.rb', line 323 def all_with_result(search_type, desired_value) raise JSS::NoSuchItemError, "EA Not In JSS! Use #create to create this #{self.class::RSRC_OBJECT_KEY}." unless @in_jss raise JSS::InvalidDataError, 'Invalid search_type, see JSS::Criteriable::Criterion::SEARCH_TYPES' unless JSS::Criteriable::Criterion::SEARCH_TYPES.include? search_type.to_s begin search_class = self.class::TARGET_CLASS::SEARCH_CLASS acs = search_class.make api: @api, name: "ruby-jss-EA-result-search-#{Time.now.to_jss_epoch}" acs.display_fields = [@name] crit_list = [JSS::Criteriable::Criterion.new(and_or: 'and', name: @name, search_type: search_type.to_s, value: desired_value)] acs.criteria = JSS::Criteriable::Criteria.new crit_list acs.create :get_results results = [] acs.search_results.each do |i| value = case @data_type when 'Date' then JSS.parse_datetime i[@symbolized_name] when 'Integer' then i[@symbolized_name].to_i else i[@symbolized_name] end # case results << { id: i[:id], name: i[:name], value: value } end ensure acs.delete if acs.is_a? self.class::TARGET_CLASS::SEARCH_CLASS end results end |
#clone(new_name, api: nil) ⇒ APIObject Originally defined in module Creatable
make a clone of this API object, with a new name. The class must be creatable
#create ⇒ Object
169 170 171 172 173 174 |
# File 'lib/jss/api_object/extension_attribute.rb', line 169 def create if @input_type == INPUT_TYPE_POPUP raise MissingDataError, 'No popup_choices set for Pop-up Menu input_type.' unless @popup_choices.is_a?(Array) && !@popup_choices.empty? end super end |
#delete ⇒ Object
188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/jss/api_object/extension_attribute.rb', line 188 def delete orig_open_timeout = @api.cnx.[:open_timeout] orig_timeout = @api.cnx.[:timeout] @api.timeout = orig_timeout + 1800 @api.open_timeout = orig_open_timeout + 1800 begin super @api.flushcache self.class ensure @api.timeout = orig_timeout @api.open_timeout = orig_open_timeout end end |
#from_ldap? ⇒ Boolean
210 211 212 |
# File 'lib/jss/api_object/extension_attribute.rb', line 210 def from_ldap? @input_type == INPUT_TYPE_LDAP end |
#from_popup_menu? ⇒ Boolean
206 207 208 |
# File 'lib/jss/api_object/extension_attribute.rb', line 206 def @input_type == INPUT_TYPE_POPUP end |
#from_script? ⇒ Boolean
214 215 216 |
# File 'lib/jss/api_object/extension_attribute.rb', line 214 def from_script? @input_type == INPUT_TYPE_SCRIPT end |
#from_text_field? ⇒ Boolean
202 203 204 |
# File 'lib/jss/api_object/extension_attribute.rb', line 202 def from_text_field? @input_type == INPUT_TYPE_FIELD end |
#latest_values ⇒ Array<Hash{:id=>Integer,:name=>String,:value=>String,Integer,Time,:as_of=>Time}>
for this EA on all inventory objects in the JSS.
Each Hash is one inventory object (computer, mobile device, user), with these keys:
:id - the jss id
:name - the object (computer, user, mobiledevice) name
:value - the most recent ext attr value for the object.
:as_of - the timestamp of when the value was collected (nil for User EAs, or for devices that have never collected inventory)
:username - the username associated with the object
This is done by creating a temporary AdvancedSearch for all objects, with the EA as a display field. The #search_result then contains the desired data.
The AdvancedSearch is then deleted.
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 |
# File 'lib/jss/api_object/extension_attribute.rb', line 376 def latest_values raise JSS::NoSuchItemError, "EA Not In JSS! Use #create to create this #{self.class::RSRC_OBJECT_KEY}." unless @in_jss tmp_advsrch = "ruby-jss-EA-latest-search-#{Time.now.to_jss_epoch}" begin search_class = self.class::TARGET_CLASS::SEARCH_CLASS acs = search_class.make name: tmp_advsrch, api: @api acs.display_fields = self.class::TARGET_CLASS == JSS::User ? [@name, USERNAME_FIELD] : [@name, USERNAME_FIELD, LAST_RECON_FIELD] # search for 'Username like "" ' because all searchable object classes have a "Username" value crit = JSS::Criteriable::Criterion.new(and_or: 'and', name: 'Username', search_type: 'like', value: '') # crit = self.class::ALL_TARGETS_CRITERION acs.criteria = JSS::Criteriable::Criteria.new [crit] acs.create :get_results results = [] acs.search_results.each do |i| value = case @data_type when 'Date' then JSS.parse_datetime i[@symbolized_name] when 'Integer' then i[@symbolized_name].to_i else i[@symbolized_name] end # case as_of = Time.parse(i[LAST_RECON_FIELD_SYM]) if i[LAST_RECON_FIELD_SYM] != '' results << { id: i[:id], name: i[:name], username: i[USERNAME_FIELD_SYM], value: value, as_of: as_of } end # acs.search_results.each ensure if defined? acs acs.delete if acs else search_class.fetch(name: tmp_advsrch, api: @api).delete if search_class.all_names(:refresh, api: @api).include? tmp_advsrch end end results end |
#name=(newname) ⇒ void Originally defined in module Updatable
This method returns an undefined value.
Change the name of this item Remember to #update to push changes to the server.
#update ⇒ Object
178 179 180 181 182 183 184 |
# File 'lib/jss/api_object/extension_attribute.rb', line 178 def update if @input_type == INPUT_TYPE_POPUP raise MissingDataError, 'No popup_choices set for Pop-up Menu input_type.' unless @popup_choices.is_a?(Array) && !@popup_choices.empty? end super @api.flushcache self.class end |