Class: JSS::Scopable::Scope

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

Overview

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 items in scope’s realms: targets, limitations, and exclusions.

IMPORTANT: The classic API has bugs regarding the use of Users, UserGroups, LDAP/Local Users, & LDAP User Groups in scopes. Here’s a discussion of those bugs and how ruby-jss handles them.

Targets/Inclusions

- 'Users' can only be JSS::Users - No LDAP
  - BUG: They do not appear in API data (XML or JSON) and are
    NOT SUPPORTED in ruby-jss.
  - You must use the Web UI to work with them in a Scope.
- 'User Groups' can only be JSS::UserGroups - No LDAP
  - BUG: They do not appear in API data (XML or JSON) and are
    NOT SUPPORTED in ruby-jss.
  - You must use the Web UI to work with them in a Scope.

Limitations

- 'LDAP/Local Users' can be any string
  - The Web UI accepts any string, even if no matching Local or LDAP user.
  - The data shows up in API data in scope=>limitations=>users
    by name only (the string provided), no IDs
- 'LDAP User Groups' can only be LDAP groups that actually exist
  - The Web UI won't let you add a group that doesn't exist in ldap
  - The data shows up in API data in scope=>limitations=>user_groups
    by name and LDAP ID (which may be empty)
  - The data ALSO shows up in API data in scope=>limit_to_users=>user_groups
    by name only, no LDAP IDs. ruby-jss ignores this and looks at
    scope=>limitations=>user_groups

Exclusions, combines the behavior of Inclusions & Limitations

- 'Users' can only be JSS::Users - No LDAP
  - BUG: They do not appear in API data (XML or JSON) and are
    NOT SUPPORTED in ruby-jss.
  - You must use the Web UI to work with them in a Scope.
- 'User Groups' can only be JSS::UserGroups - No LDAP
  - BUG: They do not appear in API data (XML or JSON) and are
    NOT SUPPORTED in ruby-jss.
  - You must use the Web UI to work with them in a Scope.
- 'LDAP/Local Users' can be any string
  - The Web UI accepts any string, even if no matching Local or LDAP user.
  - The data shows up in API data in scope=>exclusions=>users
    by name only (the string provided), no IDs
- 'LDAP User Groups' can only be LDAP groups that actually exist
  - The Web UI won't let you add a group that doesn't exist in ldap
  - The data shows up in API data in scope=>exclusions=>user_groups
    by name and LDAP ID (which may be empty)

How ruby-jss handles this:

 - Methods #set_targets and #add_target will not accept the keys
   :user, :users, :user_group, :user_groups.

 - Method #remove_target will ignore them.

 - Methods #set_limitations, #add_limitation & #remove_limitation will accept:
   - :user, :ldap_user, or :jamf_ldap_user (and their plurals) for working
     with 'LDAP/Local Users'. When setting or adding, the provided
     string(s) must exist as either a JSS::User or an LDAP user
   - :user_group or :ldap_user_group (and their plurals) for working with
     'LDAP User Groups'. When setting or adding, the provided string
     must exist as a group in LDAP.

 - Methods #set_exclusions, #add_exclusion & #remove_exclusion will accept:
   - :user, :ldap_user, or :jamf_ldap_user (and their plurals) for working
     with 'LDAP/Local Users'. When setting or adding, the provided string(s)
     must exist as either a JSS::User or an LDAP user.
   - :user_group or :ldap_user_group (and their plurals) for working with
     'LDAP User Groups''. When setting or adding, the provided string
     must exist as a group in LDAP.

Internally in the Scope instance:

- The limitations and exclusions that match the WebUI's 'LDAP/Local Users'
  are in @limitations[:jamf_ldap_users]  and @exclusions[:jamf_ldap_users]

- The  limitations and exclusions that match the WebUI's 'LDAP User Groups'
  are in @limitations[:ldap_user_groups]  and @exclusions[:ldap_user_groups]

See Also:

Constant Summary collapse

SCOPING_CLASSES =

These are the classes that Scopes can use for defining a scope, keyed by appropriate symbols. NOTE: All the user and group ones don’t actually refer to JSS::User or JSS::UserGroup. See IMPORTANT discussion above.

{
  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,
  ibeacon: JSS::IBeacon,
  ibeacons: JSS::IBeacon,
  user: nil,
  users: nil,
  ldap_user: nil,
  ldap_users: nil,
  jamf_ldap_user: nil,
  jamf_ldap_users: nil,
  user_group: nil,
  user_groups: nil,
  ldap_user_group: nil,
  ldap_user_groups: nil
}.freeze
LDAP_JAMF_USER_KEYS =

These keys always mean :jamf_ldap_users

%i[
  user
  users
  ldap_user
  ldap_users
  jamf_ldap_user
  jamf_ldap_users
].freeze
LDAP_GROUP_KEYS =

These keys always mean :ldap_user_groups

%i[
  user_group
  user_groups
  ldap_user_group
  ldap_user_groups
].freeze
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 }.freeze
ESS =

added to the ends of singular key names if needed, e.g. computer_group => computer_groups

's'.freeze
INCLUSIONS =

These can be part of the base inclusion list of the scope, along with the appropriate target and target group keys

%i[buildings departments].freeze
LIMITATIONS =

These can limit the inclusion list These are the keys that come from the API the :users key from the API is what we call :jamf_ldap_users and the :user_groups key from the API we call :ldap_user_groups See the IMPORTANT discussion above.

%i[
  ibeacons
  network_segments
  jamf_ldap_users
  ldap_user_groups
].freeze
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: {}
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target_key, raw_scope = nil) ⇒ Scope

If raw_scope is empty, a default scope, scoped to all targets, is created, and can be modified as needed.

Parameters:

  • target_key (Symbol)

    the kind of thing we’re scoping, one of TARGETS_AND_GROUPS

  • raw_scope (Hash) (defaults to: nil)

    the JSON :scope data from an API query that is scopable, e.g. a Policy.



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
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
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# File 'lib/jss/api_object/scopable/scope.rb', line 291

def initialize(target_key, raw_scope = nil)
  raw_scope ||= DEFAULT_SCOPE.dup
  unless TARGETS_AND_GROUPS.key?(target_key)
    raise JSS::InvalidDataError, "The target class of a Scope must be one of the symbols :#{TARGETS_AND_GROUPS.keys.join(', :')}"
  end

  @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 = raw_scope[@all_key]

  # Everything gets mapped from an Array of Hashes to
  # an Array of ids
  @inclusions = {}
  @inclusion_keys.each do |k|
    raw_scope[k] ||= []
    @inclusions[k] = raw_scope[k].compact.map { |n| n[:id].to_i }
  end # @inclusion_keys.each do |k|

  # the  :users key from the API is what we call :jamf_ldap_users
  # and the :user_groups key from the API we call :ldap_user_groups
  # See the IMPORTANT discussion above.
  @limitations = {}
  if raw_scope[:limitations]

    LIMITATIONS.each do |k|
      # :jamf_ldap_users comes from :users in the API data
      if k == :jamf_ldap_users
        api_data = raw_scope[:limitations][:users]
        api_data ||= []
        @limitations[k] = api_data.compact.map { |n| n[:name].to_s }

      # :ldap_user_groups comes from :user_groups in the API data
      elsif k == :ldap_user_groups
        api_data = raw_scope[:limitations][:user_groups]
        api_data ||= []
        @limitations[k] = api_data.compact.map { |n| n[:name].to_s }

      # others handled normally.
      else
        api_data = raw_scope[:limitations][k]
        api_data ||= []
        @limitations[k] = api_data.compact.map { |n| n[:id].to_i }
      end
    end # LIMITATIONS.each do |k|
  end # if raw_scope[:limitations]

  # the  :users key from the API is what we call :jamf_ldap_users
  # and the :user_groups key from the API we call :ldap_user_groups
  # See the IMPORTANT discussion above.
  @exclusions = {}
  if raw_scope[:exclusions]

    @exclusion_keys.each do |k|
      # :jamf_ldap_users comes from :users in the API data
      if k == :jamf_ldap_users
        api_data = raw_scope[:exclusions][:users]
        api_data ||= []
        @exclusions[k] = api_data.compact.map { |n| n[:name].to_s }

      # :ldap_user_groups comes from :user_groups in the API data
      elsif k == :ldap_user_groups
        api_data = raw_scope[:exclusions][:user_groups]
        api_data ||= []
        @exclusions[k] = api_data.compact.map { |n| n[:name].to_s }

      # others handled normally.
      else
        api_data = raw_scope[:exclusions][k]
        api_data ||= []
        @exclusions[k] = api_data.compact.map { |n| n[:id].to_i }
      end # if ...elsif... else
    end # @exclusion_keys.each
  end # if raw_scope[:exclusions]

  @container = nil
end

Instance Attribute Details

#all_targetsBoolean (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.

Returns:

  • (Boolean)


253
254
255
# File 'lib/jss/api_object/scopable/scope.rb', line 253

def all_targets
  @all_targets
end

#containerJSS::APIObject subclass

A reference to the object that contains this Scope

For telling it when a change is made and an update needed

Returns:



223
224
225
# File 'lib/jss/api_object/scopable/scope.rb', line 223

def container
  @container
end

#exclusionsHash<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

Returns:



279
280
281
# File 'lib/jss/api_object/scopable/scope.rb', line 279

def exclusions
  @exclusions
end

#inclusionsHash<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.

Returns:



244
245
246
# File 'lib/jss/api_object/scopable/scope.rb', line 244

def inclusions
  @inclusions
end

#limitationsHash<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

Returns:



264
265
266
# File 'lib/jss/api_object/scopable/scope.rb', line 264

def limitations
  @limitations
end

#target_classObject (readonly)

what type of target is this scope for? Computers or Mobiledevices?



230
231
232
# File 'lib/jss/api_object/scopable/scope.rb', line 230

def target_class
  @target_class
end

#unable_to_verify_ldap_entriesBoolean

Returns should we expect a potential 409 Conflict if we can’t connect to LDAP servers for verification?.

Returns:

  • (Boolean)

    should we expect a potential 409 Conflict if we can’t connect to LDAP servers for verification?



227
228
229
# File 'lib/jss/api_object/scopable/scope.rb', line 227

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.

Examples:

add_exclusion(:network_segments, "foo")

Parameters:

  • key (Symbol)

    the type of item being added to the exclusions, :computer, :building, etc…

  • item (String, integer)

    a valid identifier of the item being added

Raises:



632
633
634
635
636
637
638
639
640
641
642
643
# File 'lib/jss/api_object/scopable/scope.rb', line 632

def add_exclusion(key, item)
  key = pluralize_key(key)
  item_id = validate_item(:exclusion, key, item)
  return if @exclusions[key]&.include?(item_id)

  raise JSS::AlreadyExistsError, "Can't exclude #{key} scope to '#{item}' because it's already explicitly included." if @inclusions[key]&.include?(item)

  raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{item}' because it's already an explicit limitation." if @limitations[key]&.include?(item)

  @exclusions[key] << item_id
  @container&.should_update
end

#add_limitation(key, item) ⇒ void

TODO:

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.

Examples:

add_limitation(:network_segments, "foo")

Parameters:

  • key (Symbol)

    the type of item being added, :computer, :building, etc…

  • item (String, integer)

    a valid identifier of the item being added



545
546
547
548
549
550
551
552
553
554
555
556
# File 'lib/jss/api_object/scopable/scope.rb', line 545

def add_limitation(key, item)
  key = pluralize_key(key)
  item_id = validate_item(:limitation, key, item)
  return nil if @limitations[key]&.include?(item_id)

  if @exclusions[key]&.include?(item_id)
    raise JSS::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion."
  end

  @limitations[key] << item_id
  @container&.should_update
end

#add_target(key, item) ⇒ void Also known as: add_inclusion

This method returns an undefined value.

Add a single item as a target in this scope.

The item name will be checked for existence in the JSS, and an exception

raised if the item doesn't exist.

Examples:

add_target(:computers, "mantis")
add_target(:computer_groups, 2342)

Parameters:

  • key (Symbol)

    the key from #SCOPING_CLASSES for the kind of item being added, :computer, :building, etc…

  • item (String, integer)

    a valid identifier of the item being added

Raises:



458
459
460
461
462
463
464
465
466
467
468
# File 'lib/jss/api_object/scopable/scope.rb', line 458

def add_target(key, item)
  key = pluralize_key(key)
  item_id = validate_item(:target, key, item)
  return if @inclusions[key]&.include?(item_id)

  raise JSS::AlreadyExistsError, "Can't set #{key} target to '#{item}' because it's already an explicit exclusion." if @exclusions[key]&.include?(item_id)

  @inclusions[key] << item_id
  @all_targets = false
  @container&.should_update
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.

Parameters:

  • clear (Boolean) (defaults to: false)

    Should the limitations and exclusions be removed also?



384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/jss/api_object/scopable/scope.rb', line 384

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
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



734
735
736
737
738
# File 'lib/jss/api_object/scopable/scope.rb', line 734

def pretty_print_instance_variables
  vars = instance_variables.sort
  vars.delete :@container
  vars
end

#remove_exclusion(key, item) ⇒ void

This method returns an undefined value.

Remove a single item for exclusions of this scope

Examples:

remove_exclusion(:network_segments, "foo")

Parameters:

  • key (Symbol)

    the type of item being removed from the excludions, :computer, :building, etc…

  • item (String, integer)

    a valid identifier of the item being removed



656
657
658
659
660
661
662
663
# File 'lib/jss/api_object/scopable/scope.rb', line 656

def remove_exclusion(key, item)
  key = pluralize_key(key)
  item_id = validate_item :exclusion, key, item, error_if_not_found: false
  return unless @exclusions[key]&.include?(item_id)

  @exclusions[key].delete item_id
  @container&.should_update
end

#remove_limitation(key, item) ⇒ void

TODO:

handle ldap user/group lookups

This method returns an undefined value.

Remove a single item for limiting this scope.

Examples:

remove_limitation(:network_segments, "foo")

Parameters:

  • key (Symbol)

    the type of item being removed, :computer, :building, etc…

  • item (String, integer)

    a valid identifier of the item being removed



571
572
573
574
575
576
577
578
579
# File 'lib/jss/api_object/scopable/scope.rb', line 571

def remove_limitation(key, item)
  key = pluralize_key(key)
  item_id = validate_item :limitation, key, item, error_if_not_found: false
  return unless item_id
  return unless @limitations[key]&.include?(item_id)

  @limitations[key].delete item_id
  @container&.should_update
end

#remove_target(key, item) ⇒ void Also known as: remove_inclusion

This method returns an undefined value.

Remove a single item as a target for this scope.

Examples:

remove_target(:computer, "mantis")

Parameters:

  • key (Symbol)

    the key from #SCOPING_CLASSES for the kind of item being removed, :computer, :building, etc…

  • item (String, integer)

    a valid identifier of the item being removed



482
483
484
485
486
487
488
489
490
# File 'lib/jss/api_object/scopable/scope.rb', line 482

def remove_target(key, item)
  key = pluralize_key(key)
  item_id = validate_item :target, key, item, error_if_not_found: false
  return unless item_id
  return unless @inclusions[key]&.include?(item_id)

  @inclusions[key].delete item_id
  @container&.should_update
end

#scope_xmlREXML::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.

Returns:

  • (REXML::Element)


671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
# File 'lib/jss/api_object/scopable/scope.rb', line 671

def scope_xml
  scope = REXML::Element.new 'scope'
  scope.add_element(@all_key.to_s).text = @all_targets

  @inclusions.each do |klass, list|
    list.compact!
    list.delete 0
    list_as_hashes = list.map { |i| { id: i } }
    scope << SCOPING_CLASSES[klass].xml_list(list_as_hashes, :id)
  end

  limitations = scope.add_element('limitations')
  @limitations.each do |klass, list|
    list.compact!
    list.delete 0
    if klass == :jamf_ldap_users
      users_xml = limitations.add_element 'users'
      list.each do |name|
        user_xml = users_xml.add_element 'user'
        user_xml.add_element('name').text = name
      end
    elsif klass == :ldap_user_groups
      user_groups_xml = limitations.add_element 'user_groups'
      list.each do |name|
        user_group_xml = user_groups_xml.add_element 'user_group'
        user_group_xml.add_element('name').text = name
      end
    else
      list_as_hashes = list.map { |i| { id: i } }
      limitations << SCOPING_CLASSES[klass].xml_list(list_as_hashes, :id)
    end
  end

  exclusions = scope.add_element('exclusions')
  @exclusions.each do |klass, list|
    list.compact!
    list.delete 0
    if klass == :jamf_ldap_users
      users_xml = exclusions.add_element 'users'
      list.each do |name|
        user_xml = users_xml.add_element 'user'
        user_xml.add_element('name').text = name
      end
    elsif klass == :ldap_user_groups
      user_groups_xml = exclusions.add_element 'user_groups'
      list.each do |name|
        user_group_xml = user_groups_xml.add_element 'user_group'
        user_group_xml.add_element('name').text = name
      end
    else
      list_as_hashes = list.map { |i| { id: i } }
      exclusions << SCOPING_CLASSES[klass].xml_list(list_as_hashes, :id)
    end
  end
  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.

Examples:

set_exclusion(:network_segments, ['foo','bar'])

Parameters:

  • key (Symbol)

    the type of item being excluded, :computer, :building, etc…

  • list (Array)

    the identifiers of the items being set

Raises:



595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
# File 'lib/jss/api_object/scopable/scope.rb', line 595

def set_exclusion(key, list)
  key = pluralize_key(key)
  raise JSS::InvalidDataError, "List must be an Array of #{key} identifiers, it may be empty." unless list.is_a? Array

  # check the idents
  list.map! do |ident|
    item_id = validate_item(:exclusion, key, ident)
    case key
    when *@inclusion_keys
      raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{ident}' because it's already explicitly included." if @inclusions[key]&.include?(item_id)
    when *LIMITATIONS
      if @limitations[key]&.include?(item_id)
        raise JSS::AlreadyExistsError, "Can't exclude #{key} '#{ident}' because it's already an explicit limitation."
      end
    end
    item_id
  end # each

  return nil if list.sort == @exclusions[key].sort

  @exclusions[key] = list
  @container&.should_update
end

#set_limitation(key, list) ⇒ void Also known as: set_limitations

TODO:

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.

Examples:

set_limitation(:network_segments, ['foo',231])

Parameters:

  • key (Symbol)

    the type of items being set as limitations, :network_segments, :users, etc…

  • list (Array)

    the identifiers of the items being set as limitations

Raises:



509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
# File 'lib/jss/api_object/scopable/scope.rb', line 509

def set_limitation(key, list)
  key = pluralize_key(key)
  raise JSS::InvalidDataError, "List must be an Array of #{key} identifiers, it may be empty." unless list.is_a? Array

  # check the idents
  list.map! do |ident|
    item_id = validate_item(:limitation, key, ident)
    if @exclusions[key]&.include?(item_id)
      raise JSS::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion."
    end

    item_id
  end # each

  return nil if list.sort == @limitations[key].sort

  @limitations[key] = list
  @container&.should_update
end

#set_targets(key, list) ⇒ void Also known as: set_target, set_inclusion, set_inclusions

This method returns an undefined value.

Replace a list of item names for as targets 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.

being included, :computer, :building, etc…

Examples:

set_targets(:computers, ['kimchi','mantis'])

Parameters:

  • key (Symbol)

    the key from #SCOPING_CLASSES for the kind of items

  • list (Array)

    identifiers of the items being added

Raises:



415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
# File 'lib/jss/api_object/scopable/scope.rb', line 415

def set_targets(key, list)
  key = pluralize_key(key)
  raise JSS::InvalidDataError, "List must be an Array of #{key} identifiers, it may be empty." unless list.is_a? Array

  # check the idents
  list.map! do |ident|
    item_id = validate_item(:target, key, ident)

    if @exclusions[key]&.include?(item_id)
      raise JSS::AlreadyExistsError, \
            "Can't set #{key} target to '#{ident}' because it's already an explicit exclusion."
    end

    item_id
  end # each

  return nil if list.sort == @inclusions[key].sort

  @inclusions[key] = list
  @all_targets = false
  @container&.should_update
end