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.
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 464 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.
393 394 395 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 393 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
374 375 376 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 374 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 #
442 443 444 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 442 def exclusions @exclusions end |
#group_class ⇒ Object (readonly)
what type of target group is this scope for? ComputerGroups or MobileDeviceGroups?
384 385 386 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 384 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
425 426 427 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 425 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?.
446 447 448 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 446 def should_update @should_update end |
#target_class ⇒ Object (readonly)
what type of target is this scope for? Computers or MobileDevices?
381 382 383 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 381 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.
412 413 414 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 412 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?.
378 379 380 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 378 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
356 357 358 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 356 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?
361 362 363 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 361 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
344 345 346 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 344 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?
349 350 351 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 349 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.
850 851 852 853 854 855 856 857 858 859 860 861 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 850 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.
760 761 762 763 764 765 766 767 768 769 770 771 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 760 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.
665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 665 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.
1017 1018 1019 1020 1021 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 1017 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.
963 964 965 966 967 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 963 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
874 875 876 877 878 879 880 881 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 874 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.
786 787 788 789 790 791 792 793 794 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 786 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.
697 698 699 700 701 702 703 704 705 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 697 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.
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 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 889 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?
985 986 987 988 989 990 991 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 985 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.
568 569 570 571 572 573 574 575 576 577 578 579 580 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 568 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.
810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 810 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.map! do |ident| item_id = validate_item(:exclusion, key, ident) case key when *@target_keys if @targets[key] && @exclusions[key].include?(item_id) raise Jamf::AlreadyExistsError, "Can't exclude #{key} '#{ident}' because it's already explicitly included." end when *LIMITATIONS if @limitations[key] && @exclusions[key].include?(item_id) raise Jamf::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 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.
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 724 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.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.sort == @limitations[key].sort @limitations[key] = list 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)
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 601 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.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.sort == @targets[key].sort @targets[key] = list @all_targets = false note_pending_changes end |
#to_s ⇒ Object
1024 1025 1026 |
# File 'lib/jamf/api/classic/api_objects/scopable/scope.rb', line 1024 def to_s "Scope for #{container.class} id #{container.id}" end |