Class: Jamf::Scopable::Scope
- Defined in:
- lib/jamf/api/classic/api_objects/scopable/scope.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 targets, 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.
This class also provides a way to see if a machine will be included in this scope.
Discussion: Users & User Groups in Scopes:
The Classic API has bugs, as well as non-obvious/historical oddness, regarding the use of Users, UserGroups, Directory Service/Local Users, and Directory Service User Groups in scopes. Here’s a discussion of those issues, and how ruby-jss handles them.
Historical Oddness
Because the concept of ‘scope’ existed before Jamf Pro had ‘Users’ and ‘User Groups’ (Jamf::User and Jamf::UserGroup classes in ruby-jss) there is non-obvious inconsistency between the labels for API data, and the labels for that data in the web UI:
Users
What appears in the UI as ‘Users’ are User objects in Jamf pro, which in ruby-jss are Jamf::User instances.
These will appear in the API data as <jss_users> element with <user> sub-elements (XML) or the ‘jss_users’ array (JSON). These are available as Targets or Exclusions.
In this class, they are also referred to as ‘jss_users’
Directory Service/Local Users
When editing a scope in the UI, in Limitations and Exclusions, you can add arbitrary strings that will be matched to the users assigned to machines, or that appear in any of the defined LDAP servers. These scope items are called ‘Directory Service/Local Users’ but used to be called ‘LDAP/Local Users’
In the API data for scopes, these items appear in the <users> element with <user> sub-elements (XML) or ‘users’ array (JSON) of the limitations and exclusions data
In this class, these items ultimately use the same names they have in the API data: ‘users’ but when specifying that you are setting that value, you can use any of these synonyms, plural or singular:
ldap_users, jamf_ldap_users, directory_service_local_users
User Groups
What appears in the UI as ‘User Groups’ are User Group objects in Jamf Pro, both static and smart. In ruby-jss, these are Jamf::UserGroup instances.
They will appear in the API data as <jss_user_groups> element with <user_group> sub-elements (XML) or the ‘jss_user_groups’ array (JSON). These are available as Targets or Exclusions.
In this class they are also referred to as ‘jss_user_groups’
Directory Service User Groups
When editing a scope in the UI, in Limitations and Exclusions, you can look up and add groups from any of the defined LDAP servers. These scope items are called ‘Directory Service User Groups’ but used to be called ‘LDAP User Groups’
In the API data for scopes, these items appear in the <user_groups> element with <user_group> sub-elements (XML) or ‘user_groups’ array (JSON) of the limitations and exclusions data
In this class, these items ultimately use the same names they have in the API data: ‘user_groups’ but when specifying that you are setting that value, you can use any of these synonyms, singular or plural:
ldap_user_groups, directory_service_user_groups
IMPORTANT: API BUG IN POLICY AND PATCH POLICY SCOPES - CAN CAUSE DATA LOSS
When you GET the data for policies and patch policies from the Classic API the scope data returned will NOT include the ‘jss_users’ and ‘jss_user_groups’ data in the targets or the exclusions, even if they are defined in the web UI.
More importantly, if you try to include those in the XML when you PUT a policy back to make a change via the API, you’ll get an error because the API endpoint doesn’t know what <jss_users> or <jss_user_groups> elements are.
Even more importanly, since you cannot include those elements in your PUT body, if they actually exist in the scope, THEY WILL BE ERASED from the actual scope, because they weren’t in the PUT data. This will always happen if you include the <scope> element in your PUT data, even if you didn’t change the scope.
-
How ruby-jss handles this bug:
Fortunately the Classic API, or at least this part of it, doesn’t fully adhere to the REST standards for PUT, and if you don’t include the <scope> element in the XML, the server will just ignore the scope entirely, and nothing will change.
We make use of that here to allow for editing Policies without fear of erasing those parts of the scope. As long as you don’t change anything about the scope, there will be no <scope> element in the XML sent with a PUT, and the scope is safe from harm.
If you DO change the scope of a policy, this bug cannot be avoided, and you’ll delete any “User”/jss_user and “User Groups/jss_user_groups” defined in the targets or exclusions.
By default, if you try to change the scope of a Policy of PatchPolicy, you’ll get a warning about the possibility of losing data when you save.
You can supress those warnings either by supressing all ruby warnings, or by calling Jamf::Scopable::Scope.do_not_warn_about_policy_scope_bugs
IMPORTANT: API BUG IN OSX CONFIG PROFILE SCOPES - CAN CAUSE DATA LOSS
When fetching the data for OSX Configuration Profiles using JSON (which ruby-jss does) and the scope of the profile contains more than one ‘jss_user_groups` as a target, then only the last one will be returned. If you have more than one such group as a target, and use ruby-jss to make changes to the scope, all but the last jss_user_groups used as targets will be removed.
This only appears to affect scope targets, not exclusions, and only for OSX Config Profiles. Other scopable objects that use jss_user_groups in their API data seem to be OK.
This is due to a long-standing API bug regarding how Arrays in XML are incorrectly translated into Hashes of a single Hash when returning the data as JSON - they shoud be Arrays of Hashes in JSON - one hash for each item.
Even though this bug was first reported to jamf in 2009, it still appears in many places throughout the Classic API. ruby-jss works around some of the worst instances of the bug, but such workarounds are complex requiring re-fetching the data in XML and parsing it manually. At the moment there are no plans to do that for this specific scope bug.
By default, if you try to change the scope of an object affected by this bug, you’ll get a warning about the possibility of losing data when you save.
You can supress those warnings either by supressing all ruby warnings, or by calling Jamf::Scopable::Scope.do_not_warn_about_array_hash_scope_bugs
Constant Summary collapse
- SCOPING_CLASSES =
These are the classes that Scopes can use for defining a scope, keyed by appropriate symbols.
synonyms, including singular/plural forms, are used to allow for more natural language when specifying these scope entities. The key used in the actual API data is usually the plural.
NOTE: user and user_group in Scope data refer to ‘Directory Service/Local User’ and ‘Directory Service User Group’ as labeled in the web-ui. These were formerly labeled as ‘LDAP/Local User’ and ‘LDAP User Group’.
{ computers: Jamf::Computer, computer: Jamf::Computer, computer_groups: Jamf::ComputerGroup, computer_group: Jamf::ComputerGroup, mobile_devices: Jamf::MobileDevice, mobile_device: Jamf::MobileDevice, mobile_device_groups: Jamf::MobileDeviceGroup, mobile_device_group: Jamf::MobileDeviceGroup, buildings: Jamf::Building, building: Jamf::Building, departments: Jamf::Department, department: Jamf::Department, network_segments: Jamf::NetworkSegment, network_segment: Jamf::NetworkSegment, ibeacons: Jamf::IBeacon, ibeacon: Jamf::IBeacon, jss_users: Jamf::User, jss_user: Jamf::User, jss_user_groups: Jamf::UserGroup, jss_user_group: Jamf::UserGroup, users: nil, user: nil, ldap_users: nil, ldap_user: nil, jamf_ldap_users: nil, jamf_ldap_user: nil, directory_service_local_users: nil, directory_service_local_user: nil, user_groups: nil, user_group: nil, ldap_user_groups: nil, ldap_user_group: nil, directory_service_user_groups: nil, directory_service_user_group: nil }.freeze
- JAMF_DATA_LOSS_BUG_CLASSES =
These classes are affected by the jss_users/jss_user_groups bug.
They do not accept jss_users or jss_user_groups in their targets or exclusions, and editing their scope via the API will always delete those items from the scope if they exist.
See discussion in the Scope class comments.
[ Jamf::Policy, Jamf::PatchPolicy ].freeze
- JAMF_DATA_LOSS_BUG_KEYS =
The classes affected by the jss_users/jss_user_groups bug do not include these items in their Target or Exclusion API data, even if the scope has such items defined in the JSS
See discussion in the Scope class comments.
%i[jss_users jss_user_groups].freeze
- LDAP_BASED_KEYS =
In the API data for limitations and exclusions ‘users’ is what appears as Directory Service/Local Users in the web UI and ‘user_groups’ appears as ‘Directory Service User Groups’.
Contrasted with ‘jss_users’ and ‘jss_user_groups’ in the API data for targets and exlcusions, which are Jamf::User and Jamf::UserGroup objects.
%i[users user_groups].freeze
- LDAP_JAMF_USER_KEYS =
These keys always mean :users
%i[ user users ldap_user ldap_users jamf_ldap_user jamf_ldap_users directory_service_local_user directory_service_local_users ].freeze
- LDAP_GROUP_KEYS =
These keys always mean :user_groups
%i[ user_group user_groups ldap_user_group ldap_user_groups directory_service_user_group directory_service_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
- TARGETS =
These can be part of the base target list of the scope, along with the appropriate target and target group keys
%i[buildings departments jss_users jss_user_groups].freeze
- INCLUSIONS =
Backward Compatibility
TARGETS- 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 users user_groups ].freeze
- EXCLUSIONS =
any of them can be excluded
TARGETS + LIMITATIONS
- DEFAULT_SCOPE =
Here’s a default scope as it might come from the API.
{ all_computers: false, all_mobile_devices: false, limitations: {}, exclusions: {} }.freeze
Instance Attribute Summary collapse
-
#all_targets ⇒ Boolean
(also: #all_targets?)
Does this scope cover all targets?.
-
#container ⇒ Jamf::APIObject subclass
A reference to the object that contains this Scope.
-
#exclusions ⇒ Hash{Symbol: Array<Integer, String>}
readonly
The items in these arrays are the exclusions applied to targets in the @targets .
-
#group_class ⇒ Object
readonly
what type of target group is this scope for? ComputerGroups or MobileDeviceGroups?.
-
#limitations ⇒ Hash{Symbol: Array<Integer, String>}
readonly
The items in these arrays are the limitations applied to targets in the @targets .
-
#should_update ⇒ Boolean
(also: #should_update?)
Have changes been made to the scope, that need to be sent to the server?.
-
#target_class ⇒ Object
readonly
what type of target is this scope for? Computers or MobileDevices?.
-
#targets ⇒ Hash{Symbol: Array<Integer>}
(also: #inclusions)
readonly
The items which form the base scope of included targets.
-
#unable_to_verify_ldap_entries ⇒ Boolean
Should we expect a potential 409 Conflict if we can’t connect to LDAP servers for verification?.
Class Method Summary collapse
-
.do_not_warn_about_array_hash_scope_bugs ⇒ Object
call this to suppress warnings about data loss bug in OSXConfigurationProfile scopes when there are jss_user_groups used as targets.
-
.do_not_warn_about_array_hash_scope_bugs? ⇒ Boolean
Has do_not_warn_about_policy_scope_bugs been set?.
-
.do_not_warn_about_policy_scope_bugs ⇒ Object
call this to suppress warnings about data loss bug in Policy and Patch Policy scopes.
-
.do_not_warn_about_policy_scope_bugs? ⇒ Boolean
Has do_not_warn_about_policy_scope_bugs been set?.
Instance Method Summary collapse
-
#add_exclusion(key, item) ⇒ void
Add a single item for exclusions of this scope.
-
#add_limitation(key, item) ⇒ void
Add a single item for limiting this scope.
-
#add_target(key, item = nil) ⇒ void
(also: #add_inclusion)
Add a single item as a target in this scope.
-
#in_scope?(machine) ⇒ Boolean
is a given machine is in this scope?.
-
#initialize(target_key, raw_scope = nil, container: nil) ⇒ Scope
constructor
If raw_scope is empty, a default scope, scoped to no targets, is created, and can be modified as needed.
-
#pretty_print_instance_variables ⇒ Array
Remove large or redundant data structures from the instance_variables used to create pretty-print (pp) output.
-
#remove_exclusion(key, item) ⇒ void
Remove a single item for exclusions of this scope.
-
#remove_limitation(key, item) ⇒ void
Remove a single item for limiting this scope.
-
#remove_target(key, item) ⇒ void
(also: #remove_inclusion)
Remove a single item as a target for 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.
-
#scoped_machines ⇒ Hash{Integer => String}
Return a hash of id => name for all machines in the target class that are within this scope.
-
#set_all_targets(clear = false) ⇒ void
(also: #include_all)
Set the scope’s targets to all.
-
#set_exclusions(key, list) ⇒ void
(also: #set_exclusion)
Replace an exclusion list for this scope.
-
#set_limitations(key, list) ⇒ void
(also: #set_limitation)
Replace a limitation list for this scope.
-
#set_targets(key, list = nil) ⇒ void
(also: #set_target, #set_inclusion, #set_inclusions)
Replace a list of item names for as targets in this scope.
- #to_s ⇒ Object
Constructor Details
#initialize(target_key, raw_scope = nil, container: nil) ⇒ Scope
If raw_scope is empty, a default scope, scoped to no targets, is created, and can be modified as needed.
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 447 def initialize(target_key, raw_scope = nil, container: nil) raw_scope ||= DEFAULT_SCOPE.dup unless TARGETS_AND_GROUPS.key?(target_key) raise Jamf::InvalidDataError, "The target class of a Scope must be one of the symbols :#{TARGETS_AND_GROUPS.keys.join(', :')}" end @should_update = false @container = container @target_key = target_key @target_class = SCOPING_CLASSES[@target_key] @group_key = TARGETS_AND_GROUPS[@target_key] @group_class = SCOPING_CLASSES[@group_key] @target_keys = [@target_key, @group_key] + TARGETS @exclusion_keys = [@target_key, @group_key] + EXCLUSIONS if JAMF_DATA_LOSS_BUG_CLASSES.include?(@container.class) @target_keys -= JAMF_DATA_LOSS_BUG_KEYS @exclusion_keys -= JAMF_DATA_LOSS_BUG_KEYS end parse_targets(raw_scope) parse_limitations(raw_scope) parse_exclusions(raw_scope) end |
Instance Attribute Details
#all_targets ⇒ Boolean Also known as: all_targets?
Does this scope cover all targets?
If this is true, the @targets Hash is ignored, and all targets in the JSS form the base scope.
376 377 378 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 376 def all_targets @all_targets end |
#container ⇒ Jamf::APIObject subclass
A reference to the object that contains this Scope
For telling it when a change is made and an update needed and for accessing its api connection
357 358 359 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 357 def container @container end |
#exclusions ⇒ Hash{Symbol: Array<Integer, String>} (readonly)
The items in these arrays are the exclusions applied to targets in the @targets .
The arrays of ids are:
-
:computers or :mobile_devices (which are directly excluded)
-
:direct_exclusions - a synonym for :mobile_devices or :computers
-
:computer_groups or :mobile_device_groups (which exclude all of their memebers)
-
:group_exclusions - a synonym for :computer_groups or :mobile_device_groups
-
:departments
-
:buildings
-
:network_segments
-
:jss_users
-
:jss_user_groups
-
:users
-
:user_groups #
425 426 427 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 425 def exclusions @exclusions end |
#group_class ⇒ Object (readonly)
what type of target group is this scope for? ComputerGroups or MobileDeviceGroups?
367 368 369 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 367 def group_class @group_class end |
#limitations ⇒ Hash{Symbol: Array<Integer, String>} (readonly)
The items in these arrays are the limitations applied to targets in the @targets .
The arrays of ids are:
-
:network_segments
-
:users
-
:user_groups
-
:ibeacons
408 409 410 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 408 def limitations @limitations end |
#should_update ⇒ Boolean Also known as: should_update?
Returns Have changes been made to the scope, that need to be sent to the server?.
429 430 431 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 429 def should_update @should_update end |
#target_class ⇒ Object (readonly)
what type of target is this scope for? Computers or MobileDevices?
364 365 366 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 364 def target_class @target_class end |
#targets ⇒ Hash{Symbol: Array<Integer>} (readonly) Also known as: inclusions
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:
-
:computers or :mobile_devices (which are directly targeted)
-
:direct_targets - a synonym for :mobile_devices or :computers
-
:computer_groups or :mobile_device_groups (which target all of their memebers)
-
:group_targets - a synonym for :computer_groups or :mobile_device_groups
-
:departments
-
:buildings
-
:jss_users
-
:jss_user_groups
and the values are Arrays of names of those things.
395 396 397 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 395 def targets @targets 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?.
361 362 363 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 361 def unable_to_verify_ldap_entries @unable_to_verify_ldap_entries end |
Class Method Details
.do_not_warn_about_array_hash_scope_bugs ⇒ Object
call this to suppress warnings about data loss bug in OSXConfigurationProfile scopes when there are jss_user_groups used as targets
339 340 341 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 339 def self.do_not_warn_about_array_hash_scope_bugs @do_not_warn_about_array_hash_scope_bugs = true end |
.do_not_warn_about_array_hash_scope_bugs? ⇒ Boolean
Has do_not_warn_about_policy_scope_bugs been set?
344 345 346 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 344 def self.do_not_warn_about_array_hash_scope_bugs? @do_not_warn_about_array_hash_scope_bugs end |
.do_not_warn_about_policy_scope_bugs ⇒ Object
call this to suppress warnings about data loss bug in Policy and Patch Policy scopes
327 328 329 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 327 def self.do_not_warn_about_policy_scope_bugs @do_not_warn_about_policy_scope_bugs = true end |
.do_not_warn_about_policy_scope_bugs? ⇒ Boolean
Has do_not_warn_about_policy_scope_bugs been set?
332 333 334 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 332 def self.do_not_warn_about_policy_scope_bugs? @do_not_warn_about_policy_scope_bugs 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.
835 836 837 838 839 840 841 842 843 844 845 846 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 835 def add_exclusion(key, item) key = pluralize_key(key) item_id = validate_item(:exclusion, key, item) return if @exclusions[key]&.include?(item_id) raise Jamf::AlreadyExistsError, "Can't exclude #{key} scope to '#{item}' because it's already explicitly included." if @targets[key]&.include?(item) raise Jamf::AlreadyExistsError, "Can't exclude #{key} '#{item}' because it's already an explicit limitation." if @limitations[key]&.include?(item) @exclusions[key] << item_id note_pending_changes 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.
743 744 745 746 747 748 749 750 751 752 753 754 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 743 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 Jamf::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion." end @limitations[key] << item_id note_pending_changes end |
#add_target(key, item = nil) ⇒ 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.
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 648 def add_target(key, item = nil) if key == :all set_all_targets return end key = pluralize_key(key) item_id = validate_item(:target, key, item) return if @targets[key]&.include?(item_id) if @exclusions[key]&.include?(item_id) raise Jamf::AlreadyExistsError, "Can't set #{key} target to '#{item}' because it's already an explicit exclusion." end @targets[key] << item_id @all_targets = false note_pending_changes end |
#in_scope?(machine) ⇒ Boolean
is a given machine is in this scope?
For a parameter you may pass either an instantiated Jamf::MobileDevice or Jamf::Computer, or an identifier for one. If an identifier is passed, it is not instantiated, but an API request is made for just the required subsets of data, thus speeding things up a bit when calling this method many times.
WARNING: For scopes that include Jamf Users and Jamf User Groups as targets or exclusions, this method may return an incorrect value. See the discussion in the documentation for the Scopable::Scope class under ‘IMPORTANT - Users & User Groups in Targets and Exclusions’
NOTE: currently in-range iBeacons are transient, and are not reported to the JSS as inventory data. As such they are ignored in this result. If a scope contains iBeacon limitations or exclusions, it is up to the user to be aware of that when evaluating the meaning of this result.
1002 1003 1004 1005 1006 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 1002 def in_scope?(machine) machine_data = fetch_machine_data machine a_target?(machine_data) && within_limitations?(machine_data) && !excluded?(machine_data) end |
#pretty_print_instance_variables ⇒ Array
Remove large or redundant data structures from the instance_variables used to create pretty-print (pp) output.
948 949 950 951 952 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 948 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
859 860 861 862 863 864 865 866 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 859 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 note_pending_changes 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.
769 770 771 772 773 774 775 776 777 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 769 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 note_pending_changes 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.
680 681 682 683 684 685 686 687 688 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 680 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 @targets[key]&.include?(item_id) @targets[key].delete item_id note_pending_changes 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.
874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 874 def scope_xml scope = REXML::Element.new 'scope' scope.add_element(@all_key.to_s).text = @all_targets @target_keys.each do |klass| list = @targets[klass] list.compact! list.delete 0 list_as_hashes = list.map { |i| { id: i } } xml_list = SCOPING_CLASSES[klass].xml_list(list_as_hashes, :id) xml_list.name = 'jss_users' if SCOPING_CLASSES[klass] == Jamf::User xml_list.name = 'jss_user_groups' if SCOPING_CLASSES[klass] == Jamf::UserGroup scope << xml_list end limitations = scope.add_element('limitations') @limitations.each do |klass, list| list.compact! list.delete 0 if klass == :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 == :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') @exclusion_keys.each do |klass| list = @exclusions[klass] list.compact! list.delete 0 if klass == :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 == :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 } } xml_list = SCOPING_CLASSES[klass].xml_list(list_as_hashes, :id) xml_list.name = 'jss_users' if SCOPING_CLASSES[klass] == Jamf::User xml_list.name = 'jss_user_groups' if SCOPING_CLASSES[klass] == Jamf::UserGroup exclusions << xml_list end end scope end |
#scoped_machines ⇒ Hash{Integer => String}
Return a hash of id => name for all machines in the target class that are within this scope.
WARNING: This must instantiate all machines in the target class. It will still be slow, at least the first time for each target class. On the upside, the instantiated machines will be cached, so generating this list for other scopes with the same target class will be much much faster. In tests, 1600 Computers took about 7 minutes the first time, but less than 1 second after caching.
See also the warning for #in_scope?
970 971 972 973 974 975 976 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 970 def scoped_machines scoped_machines = {} @target_class.all_objects(:refresh, cnx: container.cnx).each do |machine| scoped_machines[machine.id] = machine.name if in_scope? machine end scoped_machines end |
#set_all_targets(clear = false) ⇒ void Also known as: include_all
This method returns an undefined value.
Set the scope’s targets to all.
By default, the limitations and exclusions remain. If a non-false parameter is provided, they will be removed also.
551 552 553 554 555 556 557 558 559 560 561 562 563 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 551 def set_all_targets(clear = false) @targets = {} @target_keys.each { |k| @targets[k] = [] } @all_targets = true if clear @limitations = {} LIMITATIONS.each { |k| @limitations[k] = [] } @exclusions = {} @exclusion_keys.each { |k| @exclusions[k] = [] } end note_pending_changes end |
#set_exclusions(key, list) ⇒ void Also known as: set_exclusion
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.
793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 793 def set_exclusions(key, list) key = pluralize_key(key) raise Jamf::InvalidDataError, "List must be an Array of #{key} identifiers, it may be empty." unless list.is_a? Array # check the idents list_of_ids = list.map do |ident| item_id = validate_item(:exclusion, key, ident) case key when *@target_keys if @targets[key]&.include?(item_id) msg = "Can't exclude #{key} '#{ident}' because it's already explicitly included." raise Jamf::AlreadyExistsError, msg end when *LIMITATIONS if @limitations[key]&.include?(item_id) msg = "Can't exclude #{key} '#{ident}' because it's already an explicit limitation." raise Jamf::AlreadyExistsError, msg end end item_id end # each return nil if list_of_ids.sort == @exclusions[key].sort @exclusions[key] = list_of_ids note_pending_changes end |
#set_limitations(key, list) ⇒ void Also known as: set_limitation
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.
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 707 def set_limitations(key, list) key = pluralize_key(key) raise Jamf::InvalidDataError, "List must be an Array of #{key} identifiers, it may be empty." unless list.is_a? Array # check the idents list_of_ids = list.map do |ident| item_id = validate_item(:limitation, key, ident) if @exclusions[key]&.include?(item_id) raise Jamf::AlreadyExistsError, "Can't set #{key} limitation for '#{name}' because it's already an explicit exclusion." end item_id end # each return nil if list_of_ids.sort == @limitations[key].sort @limitations[key] = list_of_ids note_pending_changes end |
#set_targets(key, list = nil) ⇒ 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… Use :all to scope to all targets (the same as calling #set_all_targets)
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 584 def set_targets(key, list = nil) if key == :all set_all_targets return end key = pluralize_key(key) raise Jamf::InvalidDataError, "List must be an Array of #{key} identifiers, it may be empty." unless list.is_a? Array # check the idents list_of_ids = list.map do |ident| item_id = validate_item(:target, key, ident) if @exclusions[key]&.include?(item_id) raise Jamf::AlreadyExistsError, \ "Can't set #{key} target to '#{ident}' because it's already an explicit exclusion." end item_id end # each return nil if list_of_ids.sort == @targets[key].sort @targets[key] = list_of_ids @all_targets = false note_pending_changes end |
#to_s ⇒ Object
1009 1010 1011 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 1009 def to_s "Scope for #{container.class} id #{container.id}" end |