Class: JSS::Scopable::Scope
- Defined in:
- lib/jss/api_object/scopable/scope.rb,
lib/jss.rb
Overview
Implement simple LDAP queries using the defined LDAPServers to confirm the existance of users or groups used in limitations and exclusions. As things are now if you add invalid user or group names, you’ll get a 409 conflict error when you try to save your changes to the JSS.
This class represents a Scope in the JSS, as can be applied to Scopable objects like Policies, Profiles, etc. Instances of this class are generally used as the value of the @scope attribute of those objects.
Scope data comes from the API as a hash within the overall object data. The main keys of the hash define the included targets of the scope. A sub-hash defines limitations on those inclusions, and another sub-hash defines explicit exclusions.
This class provides methods for adding, removing, or fully replacing the various parts of the scope’s inclusions, limitations, and exclusions.
Constant Summary collapse
- SCOPING_CLASSES =
These are the classes that Scopes can use for defining a scope, keyed by appropriate symbols.
{ :computers => JSS::Computer, :computer => JSS::Computer, :computer_groups => JSS::ComputerGroup, :computer_group => JSS::ComputerGroup, :mobile_devices => JSS::MobileDevice, :mobile_device => JSS::MobileDevice, :mobile_device_groups => JSS::MobileDeviceGroup, :mobile_device_group => JSS::MobileDeviceGroup, :buildings => JSS::Building, :building => JSS::Building, :departments => JSS::Department, :department => JSS::Department, :network_segments => JSS::NetworkSegment, :network_segment => JSS::NetworkSegment, :users => JSS::User, :user => JSS::User, :user_groups => JSS::UserGroup, :user_group => JSS::UserGroup }
- LDAP_USER_KEYS =
Some things get checked in LDAP as well as the JSS
[:user, :users]
- LDAP_GROUP_KEYS =
[:user_groups, :user_group]
- CHECK_LDAP_KEYS =
LDAP_USER_KEYS + LDAP_GROUP_KEYS
- TARGETS_AND_GROUPS =
This hash maps the availble Scope Target keys from SCOPING_CLASSES to their corresponding target group keys from SCOPING_CLASSES.
{:computers => :computer_groups, :mobile_devices => :mobile_device_groups }
- INCLUSIONS =
These can be part of the base inclusion list of the scope, along with the appropriate target and target group keys
[:buildings, :departments]
- LIMITATIONS =
These can limit the inclusion list
[:network_segments, :users, :user_groups]
- EXCLUSIONS =
any of them can be excluded
INCLUSIONS + LIMITATIONS
- DEFAULT_SCOPE =
Here’s a default scope as it might come from the API.
{ :all_computers => true, :all_mobile_devices => true, :limitations => {}, :exclusions => {} }
Instance Attribute Summary collapse
-
#all_targets ⇒ Boolean
(also: #all_targets?)
readonly
Does this scope cover all targets?.
-
#container ⇒ JSS::APIObject subclass
A reference to the object that contains this Scope.
-
#exclusions ⇒ Hash<Array>
readonly
The items in these arrays are the exclusions applied to targets in the @inclusions .
-
#inclusions ⇒ Hash<Array>
readonly
The items which form the base scope of included targets.
-
#limitations ⇒ Hash<Array>
readonly
The items in these arrays are the limitations applied to targets in the @inclusions .
-
#target_class ⇒ Object
readonly
what type of target is this scope for? Computers or Mobiledevices?.
-
#unable_to_verify_ldap_entries ⇒ Boolean
Should we expect a potential 409 Conflict if we can’t connect to LDAP servers for verification?.
Instance Method Summary collapse
-
#add_exclusion(key, item) ⇒ void
Add a single item for exclusions of this scope.
-
#add_inclusion(key, item) ⇒ void
Add a single item for this inclusion in this scope.
-
#add_limitation(key, item) ⇒ void
Add a single item for limiting this scope.
-
#include_all(clear = false) ⇒ void
Set the scope’s inclusions to all targets.
-
#initialize(target_key, api_scope = nil) ⇒ Scope
constructor
If api_scope is empty, a default scope, scoped to all targets, is created, and can be modified as needed.
-
#remove_exclusion(key, item) ⇒ void
Remove a single item for exclusions of this scope.
-
#remove_inclusion(key, item) ⇒ void
Remove a single item for this scope.
-
#remove_limitation(key, item) ⇒ void
Remove a single item for limiting this scope.
-
#scope_xml ⇒ REXML::Element
private
Return a REXML Element containing the current state of the Scope for adding into the XML of the container.
-
#set_exclusion(key, list) ⇒ void
Replace an exclusion list for this scope.
-
#set_inclusion(key, list) ⇒ void
Replace a list of item names for inclusion in this scope.
-
#set_limitation(key, list) ⇒ void
Replace a limitation list for this scope.
Constructor Details
#initialize(target_key, api_scope = nil) ⇒ Scope
If api_scope is empty, a default scope, scoped to all targets, is created, and can be modified as needed.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/jss/api_object/scopable/scope.rb', line 202 def initialize(target_key, api_scope = nil) api_scope ||= DEFAULT_SCOPE raise JSS::InvalidDataError, "The target class of a Scope must be one of the symbols :#{TARGETS_AND_GROUPS.keys.join(', :')}" unless TARGETS_AND_GROUPS.keys.include? target_key @target_key = target_key @target_class = SCOPING_CLASSES[@target_key] @group_key = TARGETS_AND_GROUPS[@target_key] @group_class = SCOPING_CLASSES[@group_key] @inclusion_keys = [@target_key, @group_key] + INCLUSIONS @exclusion_keys = [@target_key, @group_key] + EXCLUSIONS @all_key = "all_#{target_key}".to_sym @all_targets = api_scope[@all_key] ### Everything gets mapped from an Array of Hashes to an Array of names (or an empty array) ### since names are all that really matter when submitting the scope. @inclusions = {} @inclusion_keys.each{|k| @inclusions[k] = api_scope[k] ? api_scope[k].map{|n| n[:name]} : [] } @limitations = {} if api_scope[:limitations] LIMITATIONS.each{|k| @limitations[k] = api_scope[:limitations][k] ? api_scope[:limitations][k].map{|n| n[:name]} : [] } end @exclusions = {} if api_scope[:exclusions] @exclusion_keys.each{|k| @exclusions[k] = api_scope[:exclusions][k] ? api_scope[:exclusions][k].map{|n| n[:name]} : [] } end @container = nil end |
Instance Attribute Details
#all_targets ⇒ Boolean (readonly) Also known as: all_targets?
Does this scope cover all targets?
If this is true, the @inclusions Hash is ignored, and all targets in the JSS form the base scope.
159 160 161 |
# File 'lib/jss/api_object/scopable/scope.rb', line 159 def all_targets @all_targets end |
#container ⇒ JSS::APIObject subclass
A reference to the object that contains this Scope
For telling it when a change is made and an update needed
129 130 131 |
# File 'lib/jss/api_object/scopable/scope.rb', line 129 def container @container end |
#exclusions ⇒ Hash<Array> (readonly)
The items in these arrays are the exclusions applied to targets in the @inclusions .
The arrays of names are:
-
:targets
-
:target_groups
-
:departments
-
:buildings
-
:network_segments
-
:users
-
:user_groups
187 188 189 |
# File 'lib/jss/api_object/scopable/scope.rb', line 187 def exclusions @exclusions end |
#inclusions ⇒ Hash<Array> (readonly)
The items which form the base scope of included targets
This is the group of targets to which the limitations and exclusions apply. they keys are:
-
:targets
-
:target_groups
-
:departments
-
:buildings
and the values are Arrays of names of those things.
150 151 152 |
# File 'lib/jss/api_object/scopable/scope.rb', line 150 def inclusions @inclusions end |
#limitations ⇒ Hash<Array> (readonly)
The items in these arrays are the limitations applied to targets in the @inclusions .
The arrays of names are:
-
:network_segments
-
:users
-
:user_groups
172 173 174 |
# File 'lib/jss/api_object/scopable/scope.rb', line 172 def limitations @limitations end |
#target_class ⇒ Object (readonly)
what type of target is this scope for? Computers or Mobiledevices?
136 137 138 |
# File 'lib/jss/api_object/scopable/scope.rb', line 136 def target_class @target_class end |
#unable_to_verify_ldap_entries ⇒ Boolean
Returns should we expect a potential 409 Conflict if we can’t connect to LDAP servers for verification?.
133 134 135 |
# File 'lib/jss/api_object/scopable/scope.rb', line 133 def unable_to_verify_ldap_entries @unable_to_verify_ldap_entries end |
Instance Method Details
#add_exclusion(key, item) ⇒ void
This method returns an undefined value.
Add a single item for exclusions of this scope.
The item name will be checked for existence in the JSS, and an exception raised if the item doesn’t exist.
512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
# File 'lib/jss/api_object/scopable/scope.rb', line 512 def add_exclusion (key, item) raise JSS::InvalidDataError, "Exclusion key must be one of :#{@exclusion_keys.join(', :')}" unless @exclusion_keys.include? key raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.kind_of? String return nil if @exclusions[key] and @exclusions[key].include? item ### check the name raise JSS::NoSuchItemError, "No existing #{key} with name '#{item}'" unless check_name key, item raise JSS::AlreadyExistsError, "Can't exclude #{key} scope to '#{item}' because it's already explicitly included." if @inclusions[key] and @inclusions[key].include? item raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{item}' because it's already an explicit limitation." if @limitations[key] and @limitations[key].include? item @exclusions[key] << item @container.should_update if @container end |
#add_inclusion(key, item) ⇒ void
This method returns an undefined value.
Add a single item for this inclusion in this scope.
The item name will be checked for existence in the JSS, and an exception raised if the item doesn’t exist.
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/jss/api_object/scopable/scope.rb', line 317 def add_inclusion (key, item) raise JSS::InvalidDataError, "Inclusion key must be one of :#{@inclusion_keys.join(', :')}" unless @inclusion_keys.include? key raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.kind_of? String return nil if @inclusions[key] and @inclusions[key].include? item ### check the name raise JSS::NoSuchItemError, "No existing #{key} with name '#{item}'" unless check_name key, item raise JSS::AlreadyExistsError, "Can't set #{key} scope to '#{item}' because it's already an explicit exclusion." if @exclusions[key] and @exclusions[key].include? item @inclusions[key] << item @all_targets = false @container.should_update if @container end |
#add_limitation(key, item) ⇒ void
handle ldap user/group lookups
This method returns an undefined value.
Add a single item for limiting this scope.
The item name will be checked for existence in the JSS, and an exception raised if the item doesn’t exist.
415 416 417 418 419 420 421 422 423 424 425 426 427 428 |
# File 'lib/jss/api_object/scopable/scope.rb', line 415 def add_limitation (key, item) raise JSS::InvalidDataError, "Limitation key must be one of :#{LIMITATIONS.join(', :')}" unless LIMITATIONS.include? key raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.kind_of? String return nil if @limitations[key] and @limitations[key].include? item ### check the name raise JSS::NoSuchItemError, "No existing #{key} with name '#{item}'" unless check_name key, item raise JSS::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion." if @exclusions[key] and @exclusions[key].include? item @limitations[key] << item @container.should_update if @container end |
#include_all(clear = false) ⇒ void
This method returns an undefined value.
Set the scope’s inclusions to all targets.
By default, the limitations and exclusions remain. If a non-false parameter is provided, they will be removed also.
246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/jss/api_object/scopable/scope.rb', line 246 def include_all(clear = false) @inclusions = {} @inclusion_keys.each{|k| @inclusions[k] = []} @all_targets = true if clear @limitations = {} LIMITATIONS.each{|k| @limitations[k] = []} @exclusions = {} @exclusion_keys.each{|k| @exclusions[k] = []} end @container.should_update if @container end |
#remove_exclusion(key, item) ⇒ void
This method returns an undefined value.
Remove a single item for exclusions of this scope
539 540 541 542 543 544 545 546 547 |
# File 'lib/jss/api_object/scopable/scope.rb', line 539 def remove_exclusion (key, item) raise JSS::InvalidDataError, "Exclusion key must be one of :#{@exclusion_keys.join(', :')}" unless @exclusion_keys.include? key raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.kind_of? String return nil unless @exclusions[key] and @exclusions[key].include? item @exclusions[key] -= [item] @container.should_update if @container end |
#remove_inclusion(key, item) ⇒ void
This method returns an undefined value.
Remove a single item for this scope.
345 346 347 348 349 350 351 352 353 354 355 356 357 |
# File 'lib/jss/api_object/scopable/scope.rb', line 345 def remove_inclusion (key, item) raise JSS::InvalidDataError, "Inclusion key must be one of :#{@inclusion_keys.join(', :')}" unless @inclusion_keys.include? key raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.kind_of? String return nil unless @inclusions[key] and @inclusions[key].include? item @inclusions[key] -= [item] # if ALL the @inclusion keys are empty, then set all targets to true. @all_targets = @inclusions.values.reject{|a| a.nil? or a.empty?}.empty? @container.should_update if @container end |
#remove_limitation(key, item) ⇒ void
handle ldap user/group lookups
This method returns an undefined value.
Remove a single item for limiting this scope.
444 445 446 447 448 449 450 451 452 |
# File 'lib/jss/api_object/scopable/scope.rb', line 444 def remove_limitation( key, item) raise JSS::InvalidDataError, "Limitation key must be one of :#{LIMITATIONS.join(', :')}" unless LIMITATIONS.include? key raise JSS::InvalidDataError, "Item must be a #{key} name." unless item.kind_of? String return nil unless @limitations[key] and @limitations[key].include? item @limitations[key] -= [item] @container.should_update if @container end |
#scope_xml ⇒ REXML::Element
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Return a REXML Element containing the current state of the Scope for adding into the XML of the container.
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 |
# File 'lib/jss/api_object/scopable/scope.rb', line 556 def scope_xml scope = REXML::Element.new "scope" scope.add_element(@all_key.to_s).text = @all_targets @inclusions.each do |klass,list| list_as_hash = list.map{|i| {:name => i} } scope << SCOPING_CLASSES[klass].xml_list( list_as_hash, :name) end limitations = scope.add_element('limitations') @limitations.each do |klass,list| list_as_hash = list.map{|i| {:name => i} } limitations << SCOPING_CLASSES[klass].xml_list( list_as_hash, :name) end exclusions = scope.add_element('exclusions') @exclusions.each do |klass,list| list_as_hash = list.map{|i| {:name => i} } exclusions << SCOPING_CLASSES[klass].xml_list( list_as_hash, :name) end return scope end |
#set_exclusion(key, list) ⇒ void
This method returns an undefined value.
Replace an exclusion list for this scope
The list must be an Array of names of items of the Class being excluded from the scope Each will be checked for existence in the JSS, and an exception raised if the item doesn’t exist.
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 |
# File 'lib/jss/api_object/scopable/scope.rb', line 471 def set_exclusion (key, list) raise JSS::InvalidDataError, "Exclusion key must be one of :#{@exclusion_keys.join(', :')}" unless @exclusion_keys.include? key raise JSS::InvalidDataError, "List must be an Array of #{key} names, it may be empty." unless list.kind_of? Array return nil if list.sort == @exclusions[key].sort if list.empty? @exclusions[key] = [] @container.should_update if @container return list end ### check the names list.each do |name| raise JSS::NoSuchItemError, "No existing #{key} with name '#{name}'" unless check_name key, name case key when *@inclusion_keys raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{name}' because it's already explicitly included." if @inclusions[key] and @inclusions[key].include? name when *LIMITATIONS raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{name}' because it's already an explicit limitation." if @limitations[key] and @limitations[key].include? name end end # each @exclusions[key] = list @container.should_update if @container end |
#set_inclusion(key, list) ⇒ void
This method returns an undefined value.
Replace a list of item names for inclusion in this scope.
The list must be an Array of names of items of the Class represented by the key. Each will be checked for existence in the JSS, and an exception raised if the item doesn’t exist.
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
# File 'lib/jss/api_object/scopable/scope.rb', line 276 def set_inclusion(key, list) raise JSS::InvalidDataError, "Inclusion key must be one of :#{@inclusion_keys.join(', :')}" unless @inclusion_keys.include? key raise JSS::InvalidDataError, "List must be an Array of #{key} names, it may be empty." unless list.kind_of? Array return nil if list.sort == @inclusions[key].sort # emptying the list? if list.empty? @inclusion[key] = list # if ALL the @inclusion keys are empty, then set all targets to true. @all_targets = @inclusions.values.reject{|a| a.nil? or a.empty?}.empty? @container.should_update if @container return list end ### check the names list.each do |name| raise JSS::NoSuchItemError, "No existing #{key} with name '#{name}'" unless check_name key, name raise JSS::AlreadyExistsError, "Can't set #{key} scope to '#{name}' because it's already an explicit exclusion." if @exclusions[key] and @exclusions[key].include? name end # each @inclusions[key] = list @all_targets = false @container.should_update if @container end |
#set_limitation(key, list) ⇒ void
handle ldap user group lookups
This method returns an undefined value.
Replace a limitation list for this scope.
The list must be an Array of names of items of the Class represented by the key. Each will be checked for existence in the JSS, and an exception raised if the item doesn’t exist.
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
# File 'lib/jss/api_object/scopable/scope.rb', line 377 def set_limitation (key, list) raise JSS::InvalidDataError, "Limitation key must be one of :#{LIMITATIONS.join(', :')}" unless LIMITATIONS.include? key raise JSS::InvalidDataError, "List must be an Array of #{key} names, it may be empty." unless list.kind_of? Array return nil if list.sort == @limitations[key].sort if list.empty? @limitations[key] = [] @container.should_update if @container return list end ### check the names list.each do |name| raise JSS::NoSuchItemError, "No existing #{key} with name '#{name}'" unless check_name key, name raise JSS::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion." if @exclusions[key] and @exclusions[key].include? name end # each @limitations[key] = list @container.should_update if @container end |