ruby-jss 1.2.4a3 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +180 -1
- data/README.md +4 -2
- data/bin/cgrouper +1 -1
- data/bin/jamfHelperBackgrounder +1 -1
- data/bin/netseg-update +1 -1
- data/data/ruby-jss.conf.example +1 -1
- data/lib/jamf.rb +2 -1
- data/lib/jamf/api/abstract_classes/advanced_search.rb +1 -1
- data/lib/jamf/api/abstract_classes/collection_resource.rb +54 -38
- data/lib/jamf/api/abstract_classes/generic_reference.rb +1 -1
- data/lib/jamf/api/abstract_classes/json_object.rb +16 -10
- data/lib/jamf/api/abstract_classes/prestage.rb +111 -35
- data/lib/jamf/api/abstract_classes/prestage_skip_setup_items.rb +1 -1
- data/lib/jamf/api/abstract_classes/resource.rb +1 -1
- data/lib/jamf/api/abstract_classes/singleton_resource.rb +1 -1
- data/lib/jamf/api/attribute_classes/ip_address.rb +1 -1
- data/lib/jamf/api/attribute_classes/timestamp.rb +1 -1
- data/lib/jamf/api/connection.rb +166 -69
- data/lib/jamf/api/connection/api_error.rb +1 -1
- data/lib/jamf/api/connection/api_error_styleguide.rb +1 -1
- data/lib/jamf/api/connection/token.rb +87 -16
- data/lib/jamf/api/json_objects/account_prefs.rb +1 -1
- data/lib/jamf/api/json_objects/android_details.rb +1 -1
- data/lib/jamf/api/json_objects/appletv_details.rb +1 -1
- data/lib/jamf/api/json_objects/attachment.rb +1 -1
- data/lib/jamf/api/json_objects/cellular_network.rb +1 -1
- data/lib/jamf/api/json_objects/change_log_entry.rb +1 -1
- data/lib/jamf/api/json_objects/computer_prestage_skip_setup_items.rb +1 -1
- data/lib/jamf/api/json_objects/country.rb +1 -1
- data/lib/jamf/api/json_objects/criterion.rb +1 -1
- data/lib/jamf/api/json_objects/device_enrollment_device.rb +6 -4
- data/lib/jamf/api/json_objects/device_enrollment_sync_status.rb +1 -1
- data/lib/jamf/api/json_objects/extension_attribute_value.rb +1 -1
- data/lib/jamf/api/json_objects/installed_application.rb +1 -1
- data/lib/jamf/api/json_objects/installed_certificate.rb +1 -1
- data/lib/jamf/api/json_objects/installed_configuration_profile.rb +1 -1
- data/lib/jamf/api/json_objects/installed_ebook.rb +1 -1
- data/lib/jamf/api/json_objects/installed_provisioning_profile.rb +1 -1
- data/lib/jamf/api/json_objects/inventory_preload_extension_attribute.rb +1 -1
- data/lib/jamf/api/json_objects/ios_details.rb +1 -1
- data/lib/jamf/api/json_objects/location.rb +1 -1
- data/lib/jamf/api/json_objects/md_prestage_name.rb +1 -1
- data/lib/jamf/api/json_objects/md_prestage_names.rb +1 -1
- data/lib/jamf/api/json_objects/md_prestage_skip_setup_items.rb +1 -1
- data/lib/jamf/api/json_objects/mobile_device_details.rb +1 -1
- data/lib/jamf/api/json_objects/mobile_device_security.rb +1 -1
- data/lib/jamf/api/json_objects/prestage_assignment.rb +5 -3
- data/lib/jamf/api/json_objects/prestage_location.rb +1 -1
- data/lib/jamf/api/json_objects/prestage_purchasing_data.rb +1 -1
- data/lib/jamf/api/json_objects/prestage_scope.rb +1 -1
- data/lib/jamf/api/json_objects/prestage_sync_status.rb +1 -1
- data/lib/jamf/api/json_objects/purchasing_data.rb +1 -1
- data/lib/jamf/api/mixins/abstract.rb +1 -1
- data/lib/jamf/api/mixins/bulk_deletable.rb +1 -1
- data/lib/jamf/api/mixins/change_log.rb +3 -1
- data/lib/jamf/api/mixins/extendable.rb +1 -1
- data/lib/jamf/api/mixins/immutable.rb +1 -1
- data/lib/jamf/api/mixins/locatable.rb +1 -1
- data/lib/jamf/api/mixins/lockable.rb +1 -1
- data/lib/jamf/api/mixins/referable.rb +1 -1
- data/lib/jamf/api/mixins/searchable.rb +3 -3
- data/lib/jamf/api/mixins/uncreatable.rb +1 -1
- data/lib/jamf/api/mixins/undeletable.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/account.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/advanced_mobile_device_search.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/advanced_user_search.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/building.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/category.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/computer.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/computer_prestage.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/department.rb +2 -1
- data/lib/jamf/api/resources/collection_resources/device_enrollment.rb +110 -18
- data/lib/jamf/api/resources/collection_resources/extension_attribute.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/inventory_preload_record.rb +9 -2
- data/lib/jamf/api/resources/collection_resources/mobile_device.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/mobile_device_prestage.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/script.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/site.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/time_zone.rb +119 -0
- data/lib/jamf/api/resources/singleton_resources/app_store_country_codes.rb +1 -1
- data/lib/jamf/api/resources/singleton_resources/authorization.rb +1 -1
- data/lib/jamf/api/resources/singleton_resources/client_checkin_settings.rb +1 -1
- data/lib/jamf/api/resources/singleton_resources/reenrollment_settings.rb +1 -1
- data/lib/jamf/client.rb +59 -4
- data/lib/jamf/client/jamf_binary.rb +1 -1
- data/lib/jamf/client/jamf_helper.rb +1 -1
- data/lib/jamf/client/management_action.rb +1 -1
- data/lib/jamf/compatibility.rb +1 -1
- data/lib/jamf/composer.rb +1 -1
- data/lib/jamf/configuration.rb +6 -8
- data/lib/jamf/exceptions.rb +6 -1
- data/lib/jamf/ruby_extensions.rb +2 -1
- data/lib/jamf/ruby_extensions/array.rb +2 -2
- data/lib/jamf/ruby_extensions/array/predicates.rb +1 -1
- data/lib/jamf/ruby_extensions/array/utils.rb +4 -3
- data/lib/jamf/ruby_extensions/dig.rb +52 -0
- data/lib/jamf/ruby_extensions/filetest.rb +1 -1
- data/lib/jamf/ruby_extensions/filetest/predicates.rb +1 -1
- data/lib/jamf/ruby_extensions/hash.rb +1 -1
- data/lib/jamf/ruby_extensions/hash/backports.rb +2 -2
- data/lib/jamf/ruby_extensions/ipaddr.rb +1 -1
- data/lib/jamf/ruby_extensions/ipaddr/utils.rb +1 -1
- data/lib/jamf/ruby_extensions/object.rb +1 -1
- data/lib/jamf/ruby_extensions/object/predicates.rb +1 -1
- data/lib/jamf/ruby_extensions/pathname.rb +1 -1
- data/lib/jamf/ruby_extensions/pathname/predicates.rb +1 -1
- data/lib/jamf/ruby_extensions/pathname/utils.rb +1 -1
- data/lib/jamf/ruby_extensions/string.rb +1 -1
- data/lib/jamf/ruby_extensions/string/backports.rb +1 -1
- data/lib/jamf/ruby_extensions/string/conversions.rb +1 -1
- data/lib/jamf/ruby_extensions/string/predicates.rb +14 -4
- data/lib/jamf/utility.rb +1 -1
- data/lib/jamf/validate.rb +1 -1
- data/lib/jamf/version.rb +2 -2
- data/lib/jpapi.rb +1 -1
- data/lib/jss-api.rb +1 -1
- data/lib/jss.rb +5 -2
- data/lib/jss/api_connection.rb +3 -30
- data/lib/jss/api_object.rb +16 -3
- data/lib/jss/api_object/account.rb +1 -1
- data/lib/jss/api_object/advanced_search.rb +1 -1
- data/lib/jss/api_object/advanced_search/advanced_computer_search.rb +1 -1
- data/lib/jss/api_object/advanced_search/advanced_mobile_device_search.rb +1 -1
- data/lib/jss/api_object/advanced_search/advanced_user_search.rb +1 -1
- data/lib/jss/api_object/building.rb +1 -1
- data/lib/jss/api_object/categorizable.rb +1 -1
- data/lib/jss/api_object/category.rb +1 -1
- data/lib/jss/api_object/computer.rb +12 -6
- data/lib/jss/api_object/computer/application_installs.rb +1 -1
- data/lib/jss/api_object/computer_invitation.rb +1 -1
- data/lib/jss/api_object/configuration_profile.rb +4 -2
- data/lib/jss/api_object/configuration_profile/mobile_device_configuration_profile.rb +1 -1
- data/lib/jss/api_object/configuration_profile/osx_configuration_profile.rb +1 -1
- data/lib/jss/api_object/creatable.rb +1 -1
- data/lib/jss/api_object/criteriable.rb +10 -5
- data/lib/jss/api_object/criteriable/criteria.rb +26 -10
- data/lib/jss/api_object/criteriable/criterion.rb +1 -1
- data/lib/jss/api_object/department.rb +1 -1
- data/lib/jss/api_object/directory_binding.rb +273 -0
- data/lib/jss/api_object/directory_binding_type.rb +90 -0
- data/lib/jss/api_object/directory_binding_type/active_directory.rb +502 -0
- data/lib/jss/api_object/directory_binding_type/admitmac.rb +525 -0
- data/lib/jss/api_object/directory_binding_type/centrify.rb +212 -0
- data/lib/jss/api_object/directory_binding_type/open_directory.rb +178 -0
- data/lib/jss/api_object/directory_binding_type/powerbroker_identity_services.rb +73 -0
- data/lib/jss/api_object/disk_encryption_configurations.rb +114 -0
- data/lib/jss/api_object/distribution_point.rb +96 -36
- data/lib/jss/api_object/dock_item.rb +137 -0
- data/lib/jss/api_object/ebook.rb +1 -1
- data/lib/jss/api_object/extendable.rb +67 -28
- data/lib/jss/api_object/extension_attribute.rb +1 -1
- data/lib/jss/api_object/extension_attribute/computer_extension_attribute.rb +1 -1
- data/lib/jss/api_object/extension_attribute/mobile_device_extension_attribute.rb +1 -1
- data/lib/jss/api_object/extension_attribute/user_extension_attribute.rb +1 -1
- data/lib/jss/api_object/group.rb +1 -1
- data/lib/jss/api_object/group/computer_group.rb +1 -1
- data/lib/jss/api_object/group/mobile_device_group.rb +1 -1
- data/lib/jss/api_object/group/user_group.rb +1 -1
- data/lib/jss/api_object/ibeacon.rb +1 -1
- data/lib/jss/api_object/ldap_server.rb +1 -1
- data/lib/jss/api_object/locatable.rb +1 -1
- data/lib/jss/api_object/mac_application.rb +1 -1
- data/lib/jss/api_object/management_history.rb +23 -22
- data/lib/jss/api_object/management_history/audit_event.rb +1 -1
- data/lib/jss/api_object/management_history/casper_imaging_log.rb +1 -1
- data/lib/jss/api_object/management_history/casper_remote_log.rb +1 -1
- data/lib/jss/api_object/management_history/computer_usage_log.rb +1 -1
- data/lib/jss/api_object/management_history/ebook.rb +1 -1
- data/lib/jss/api_object/management_history/hashlike.rb +1 -1
- data/lib/jss/api_object/management_history/mac_app_store_app.rb +1 -1
- data/lib/jss/api_object/management_history/mdm_command.rb +1 -1
- data/lib/jss/api_object/management_history/mobile_device_app.rb +1 -1
- data/lib/jss/api_object/management_history/policy_log.rb +1 -1
- data/lib/jss/api_object/management_history/screen_sharing_log.rb +1 -1
- data/lib/jss/api_object/management_history/user_location_change.rb +1 -1
- data/lib/jss/api_object/matchable.rb +1 -1
- data/lib/jss/api_object/mdm.rb +1 -1
- data/lib/jss/api_object/mobile_device.rb +29 -6
- data/lib/jss/api_object/mobile_device_application.rb +13 -1
- data/lib/jss/api_object/netboot_server.rb +1 -1
- data/lib/jss/api_object/network_segment.rb +153 -59
- data/lib/jss/api_object/package.rb +107 -42
- data/lib/jss/api_object/patch_policy.rb +1 -1
- data/lib/jss/api_object/patch_source.rb +1 -1
- data/lib/jss/api_object/patch_source/patch_external_source.rb +1 -1
- data/lib/jss/api_object/patch_source/patch_internal_source.rb +1 -1
- data/lib/jss/api_object/patch_title.rb +1 -1
- data/lib/jss/api_object/patch_title/version.rb +1 -1
- data/lib/jss/api_object/peripheral.rb +1 -1
- data/lib/jss/api_object/peripheral_type.rb +1 -1
- data/lib/jss/api_object/policy.rb +380 -5
- data/lib/jss/api_object/printer.rb +440 -0
- data/lib/jss/api_object/purchasable.rb +1 -1
- data/lib/jss/api_object/removable_macaddr.rb +1 -1
- data/lib/jss/api_object/restricted_software.rb +1 -1
- data/lib/jss/api_object/scopable.rb +1 -1
- data/lib/jss/api_object/scopable/scope.rb +257 -37
- data/lib/jss/api_object/script.rb +1 -1
- data/lib/jss/api_object/self_servable.rb +7 -7
- data/lib/jss/api_object/self_servable/icon.rb +1 -1
- data/lib/jss/api_object/sitable.rb +6 -2
- data/lib/jss/api_object/site.rb +1 -1
- data/lib/jss/api_object/software_update_server.rb +1 -1
- data/lib/jss/api_object/updatable.rb +1 -1
- data/lib/jss/api_object/uploadable.rb +1 -1
- data/lib/jss/api_object/user.rb +5 -3
- data/lib/jss/api_object/vppable.rb +1 -1
- data/lib/jss/api_object/webhook.rb +1 -1
- data/lib/jss/client.rb +1 -1
- data/lib/jss/client/jamf_binary.rb +1 -1
- data/lib/jss/client/jamf_helper.rb +1 -1
- data/lib/jss/client/management_action.rb +1 -1
- data/lib/jss/compatibility.rb +1 -1
- data/lib/jss/composer.rb +2 -2
- data/lib/jss/configuration.rb +1 -1
- data/lib/jss/db_connection.rb +1 -1
- data/lib/jss/exceptions.rb +1 -1
- data/lib/jss/ruby_extensions.rb +1 -1
- data/lib/jss/ruby_extensions/array.rb +1 -1
- data/lib/jss/ruby_extensions/filetest.rb +1 -1
- data/lib/jss/ruby_extensions/hash.rb +1 -1
- data/lib/jss/ruby_extensions/ipaddr.rb +1 -1
- data/lib/jss/ruby_extensions/pathname.rb +1 -1
- data/lib/jss/ruby_extensions/string.rb +1 -1
- data/lib/jss/ruby_extensions/string/backports.rb +1 -1
- data/lib/jss/ruby_extensions/string/conversions.rb +1 -1
- data/lib/jss/ruby_extensions/string/predicates.rb +14 -4
- data/lib/jss/ruby_extensions/time.rb +1 -1
- data/lib/jss/server.rb +1 -1
- data/lib/jss/utility.rb +9 -23
- data/lib/jss/validate.rb +1 -1
- data/lib/jss/version.rb +2 -2
- data/lib/jss/xml_workaround.rb +1 -1
- data/lib/ruby-jss.rb +1 -1
- data/test/bin/runtests +1 -1
- data/test/lib/testhelper.rb +1 -1
- data/test/lib/testhelper/auth.rb +1 -1
- data/test/lib/testhelper/patch_mgmt.rb +1 -1
- data/test/specs/api_connection_spec.rb +1 -1
- data/test/specs/patch01_source_spec.rb +1 -1
- data/test/specs/patch02_internal_source_spec.rb +1 -1
- data/test/specs/patch03_external_source_spec.rb +1 -1
- data/test/specs/patch04_titles_spec.rb +1 -1
- data/test/specs/patch05_policies_spec.rb +1 -1
- data/test/specs/patch06_cleanup_spec.rb +1 -1
- data/test/specs/policy_spec.rb +1 -1
- metadata +16 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2020 Pixar
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "Apache License")
|
|
4
4
|
# with the following modification; you may not use this file except in
|
|
@@ -482,7 +482,7 @@ module Jamf
|
|
|
482
482
|
# have an alias without the 'is' so :isManaged will have
|
|
483
483
|
# getters isManaged? and managed?
|
|
484
484
|
#
|
|
485
|
-
PREDICATE_RE = /^is([A-Z]\w
|
|
485
|
+
PREDICATE_RE = /^is([A-Z]\w+)$/.freeze
|
|
486
486
|
|
|
487
487
|
# Public Class Methods
|
|
488
488
|
#####################################
|
|
@@ -524,7 +524,7 @@ module Jamf
|
|
|
524
524
|
#
|
|
525
525
|
def self.attr_key_for_alias(als)
|
|
526
526
|
validate_not_abstract
|
|
527
|
-
self::OBJECT_MODEL.each { |k, deets| return k if k == als || deets[:aliases]
|
|
527
|
+
self::OBJECT_MODEL.each { |k, deets| return k if k == als || deets[:aliases].to_a.include?(als) }
|
|
528
528
|
nil
|
|
529
529
|
end
|
|
530
530
|
|
|
@@ -575,10 +575,11 @@ module Jamf
|
|
|
575
575
|
else
|
|
576
576
|
define_method(attr_name) { instance_variable_get("@#{attr_name}") }
|
|
577
577
|
|
|
578
|
-
# all booleans get a predicate alias
|
|
579
|
-
alias_method("#{attr_name}?", attr_name) if attr_def[:class] == :boolean
|
|
580
578
|
end
|
|
581
579
|
|
|
580
|
+
# all booleans get predicate aliases
|
|
581
|
+
define_predicates(attr_name) if attr_def[:class] == :boolean
|
|
582
|
+
|
|
582
583
|
return unless attr_def[:aliases]
|
|
583
584
|
|
|
584
585
|
# aliases
|
|
@@ -586,6 +587,15 @@ module Jamf
|
|
|
586
587
|
end # create getters
|
|
587
588
|
private_class_method :create_getters
|
|
588
589
|
|
|
590
|
+
# create the default aliases for booleans
|
|
591
|
+
##############################
|
|
592
|
+
def self.define_predicates(attr_name)
|
|
593
|
+
alias_method("#{attr_name}?", attr_name)
|
|
594
|
+
return unless attr_name.to_s =~ PREDICATE_RE
|
|
595
|
+
|
|
596
|
+
alias_method("#{Regexp.last_match(1).downcase}?", attr_name)
|
|
597
|
+
end
|
|
598
|
+
|
|
589
599
|
# create setter(s) for an attribute, and any aliases needed
|
|
590
600
|
##############################
|
|
591
601
|
def self.create_setters(attr_name, attr_def)
|
|
@@ -727,7 +737,7 @@ module Jamf
|
|
|
727
737
|
|
|
728
738
|
attr_def[:aliases].each { |al| alias_method "#{al}_delete_if", "#{attr_name}_delete_if" }
|
|
729
739
|
end # create_insert_setters
|
|
730
|
-
private_class_method :
|
|
740
|
+
private_class_method :create_delete_if_setters
|
|
731
741
|
|
|
732
742
|
# Raise an exception if this is an abstract class
|
|
733
743
|
# Used in class methods that are defined in abstract classes.
|
|
@@ -762,13 +772,9 @@ module Jamf
|
|
|
762
772
|
#
|
|
763
773
|
# Otherwise, the value is returned unchanged.
|
|
764
774
|
#
|
|
765
|
-
# If the attribute is defined as an identifier, it must be unique among
|
|
766
|
-
# the other objects of this subclass in the JSS.
|
|
767
|
-
#
|
|
768
775
|
# This method only validates single values. When called from multi-value
|
|
769
776
|
# setters, it is used for each value individually.
|
|
770
777
|
#
|
|
771
|
-
#
|
|
772
778
|
# @param attr_name[Symbol], a top-level key from OBJECT_MODEL for this class
|
|
773
779
|
#
|
|
774
780
|
# @param value [Object] the value to validate for that attribute.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2020 Pixar
|
|
2
2
|
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "Apache License")
|
|
@@ -235,17 +235,17 @@ module Jamf
|
|
|
235
235
|
#
|
|
236
236
|
def self.serials_for_prestage(prestage_ident, refresh = false, cnx: Jamf.cnx)
|
|
237
237
|
id = valid_id prestage_ident, cnx: cnx
|
|
238
|
-
raise Jamf::NoSuchItemError, "No #{self} matching '#{
|
|
238
|
+
raise Jamf::NoSuchItemError, "No #{self} matching '#{prestage_ident}'" unless id
|
|
239
239
|
|
|
240
240
|
serials_by_prestage_id(refresh, cnx: cnx).select { |_sn, psid| id == psid }.keys
|
|
241
241
|
end
|
|
242
242
|
|
|
243
243
|
# The id of the prestage to which the given serialNumber is assigned.
|
|
244
|
-
# nil if not assigned
|
|
244
|
+
# nil if not assigned or not in DEP.
|
|
245
245
|
#
|
|
246
246
|
# NOTE: If a serial number isn't assigned to any prestage, it may really be
|
|
247
|
-
# unassigned or it may not exist in your DEP.
|
|
248
|
-
#
|
|
247
|
+
# unassigned or it may not exist in your DEP. To see if a SN exists in one
|
|
248
|
+
# of your Device Enrollment instances, use Jamf::DeviceEnrollment.include?
|
|
249
249
|
#
|
|
250
250
|
# @param sn [String] the serial number to look for
|
|
251
251
|
#
|
|
@@ -263,8 +263,8 @@ module Jamf
|
|
|
263
263
|
# given prestage if a prestage_ident is specified?
|
|
264
264
|
#
|
|
265
265
|
# NOTE: If a serial number isn't assigned to any prestage, it may really be
|
|
266
|
-
# unassigned or it may not exist in your DEP.
|
|
267
|
-
#
|
|
266
|
+
# unassigned or it may not exist in your DEP. To see if a SN exists in one
|
|
267
|
+
# of your Device Enrollment instances, use Jamf::DeviceEnrollment.include?
|
|
268
268
|
#
|
|
269
269
|
# @param sn [String] the serial number to look for
|
|
270
270
|
#
|
|
@@ -283,10 +283,10 @@ module Jamf
|
|
|
283
283
|
return false unless assigned_id
|
|
284
284
|
|
|
285
285
|
if prestage_ident
|
|
286
|
-
|
|
287
|
-
raise Jamf::NoSuchItemError, "No #{self} matching '#{prestage_ident}'" unless
|
|
286
|
+
psid = valid_id prestage_ident, cnx: cnx
|
|
287
|
+
raise Jamf::NoSuchItemError, "No #{self} matching '#{prestage_ident}'" unless psid
|
|
288
288
|
|
|
289
|
-
return
|
|
289
|
+
return psid == assigned_id
|
|
290
290
|
end
|
|
291
291
|
|
|
292
292
|
true
|
|
@@ -305,13 +305,84 @@ module Jamf
|
|
|
305
305
|
Jamf::DeviceEnrollment.device_sns(type: type, cnx: cnx) - serials_by_prestage_id(:refresh, cnx: cnx).keys
|
|
306
306
|
end
|
|
307
307
|
|
|
308
|
-
# @return [Array<String>] The serial numbers of
|
|
308
|
+
# @return [Array<String>] The serial numbers of known hardware not in DEP
|
|
309
309
|
# at all
|
|
310
310
|
def self.sns_not_in_device_enrollment
|
|
311
311
|
# type = self == Jamf::MobileDevicePrestage ? :mobiledevices : :computers
|
|
312
|
-
nil # TODO: this, once MobileDevice
|
|
312
|
+
nil # TODO: this, once MobileDevice & Computer classes are implemented
|
|
313
313
|
end
|
|
314
314
|
|
|
315
|
+
# Assign one or more serialNumber to a prestage
|
|
316
|
+
# @return [Jamf::PrestageScope] the new scope for the prestage
|
|
317
|
+
def self.assign(*sns_to_assign, to_prestage:, cnx: Jamf.cnx)
|
|
318
|
+
prestage_id = valid_id to_prestage
|
|
319
|
+
raise Jamf::NoSuchItemError, "No #{self} matching '#{to_prestage}'" unless prestage_id
|
|
320
|
+
|
|
321
|
+
# all sns_to_assign must be in DEP
|
|
322
|
+
not_in_dep = sns_to_assign - Jamf::DeviceEnrollment.device_sns
|
|
323
|
+
raise Jamf::UnsupportedError, "These SNs are not in any Device Enrollment instance: #{not_in_dep.join ', '}" unless not_in_dep.empty?
|
|
324
|
+
|
|
325
|
+
# all sns_to_assign must currently be unassigned.
|
|
326
|
+
already_assigned = sns_to_assign - unassigned_sns
|
|
327
|
+
raise Jamf::UnsupportedError, "These SNs are already assigned to a prestage: #{already_assigned.join ', '}" unless already_assigned.empty?
|
|
328
|
+
|
|
329
|
+
# upcase all sns
|
|
330
|
+
sns_to_assign.map!(&:to_s)
|
|
331
|
+
sns_to_assign.map!(&:upcase)
|
|
332
|
+
|
|
333
|
+
# get the prestage name
|
|
334
|
+
prestage_name = map_all(:id, to: :displayName)[prestage_id]
|
|
335
|
+
|
|
336
|
+
scope_rsrc = "#{self::RSRC_VERSION}/#{self::RSRC_PATH}/#{prestage_id}/#{SCOPE_RSRC}"
|
|
337
|
+
scope = Jamf::PrestageScope.new cnx.get(scope_rsrc)
|
|
338
|
+
|
|
339
|
+
# add the new sns to the existing ones
|
|
340
|
+
new_scope_sns = scope.assignments.map(&:serialNumber)
|
|
341
|
+
new_scope_sns += sns_to_assign
|
|
342
|
+
new_scope_sns.uniq!
|
|
343
|
+
|
|
344
|
+
update_scope(prestage_name, scope_rsrc, new_scope_sns, scope.versionLock, cnx)
|
|
345
|
+
end # self.assign
|
|
346
|
+
|
|
347
|
+
# Unassign one or more serialNumber from a prestage
|
|
348
|
+
# @return [Jamf::PrestageScope] the new scope for the prestage
|
|
349
|
+
def self.unassign(*sns_to_unassign, from_prestage:, cnx: Jamf.cnx)
|
|
350
|
+
prestage_id = valid_id from_prestage
|
|
351
|
+
raise Jamf::NoSuchItemError, "No #{self} matching '#{from_prestage}'" unless prestage_id
|
|
352
|
+
|
|
353
|
+
# upcase all sns
|
|
354
|
+
sns_to_unassign.map!(&:to_s)
|
|
355
|
+
sns_to_unassign.map!(&:upcase)
|
|
356
|
+
|
|
357
|
+
# get the prestage name
|
|
358
|
+
prestage_name = map_all(:id, to: :displayName)[prestage_id]
|
|
359
|
+
|
|
360
|
+
scope_rsrc = "#{self::RSRC_VERSION}/#{self::RSRC_PATH}/#{prestage_id}/#{SCOPE_RSRC}"
|
|
361
|
+
scope = Jamf::PrestageScope.new cnx.get(scope_rsrc)
|
|
362
|
+
|
|
363
|
+
new_scope_sns = scope.assignments.map(&:serialNumber)
|
|
364
|
+
new_scope_sns -= sns_to_unassign
|
|
365
|
+
|
|
366
|
+
update_scope(prestage_name, scope_rsrc, new_scope_sns, scope.versionLock, cnx)
|
|
367
|
+
end # self.unassign
|
|
368
|
+
|
|
369
|
+
# Provate Class Methods
|
|
370
|
+
#####################################
|
|
371
|
+
|
|
372
|
+
# used by assign and unassign
|
|
373
|
+
def self.update_scope(prestage_name, scope_rsrc, new_scope_sns, vlock, cnx)
|
|
374
|
+
assignment_data = {
|
|
375
|
+
serialNumbers: new_scope_sns,
|
|
376
|
+
versionLock: vlock
|
|
377
|
+
}
|
|
378
|
+
Jamf::PrestageScope.new cnx.put(scope_rsrc, assignment_data)
|
|
379
|
+
rescue Jamf::Connection::APIError => e
|
|
380
|
+
raise Jamf::VersionLockError, "The #{self} '#{prestage_name}' was modified by another process during this operation. Please try again" if e.status == 409
|
|
381
|
+
|
|
382
|
+
raise e
|
|
383
|
+
end
|
|
384
|
+
private_class_method :update_scope
|
|
385
|
+
|
|
315
386
|
# Instance Methods
|
|
316
387
|
#####################################
|
|
317
388
|
|
|
@@ -351,19 +422,24 @@ module Jamf
|
|
|
351
422
|
|
|
352
423
|
# Assign
|
|
353
424
|
def assign(*sns_to_assign)
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
425
|
+
@scope = self.class.assign(sns_to_assign, to_prestage: @id, cnx: @cnx)
|
|
426
|
+
@versionLock = @scope.versionLock
|
|
427
|
+
|
|
428
|
+
# sns_to_assign.map!(&:to_s)
|
|
429
|
+
# new_scope_sns = assigned_sns
|
|
430
|
+
# new_scope_sns += sns_to_assign
|
|
431
|
+
# new_scope_sns.uniq!
|
|
432
|
+
# update_scope(new_scope_sns)
|
|
359
433
|
end
|
|
360
434
|
alias add assign
|
|
361
435
|
|
|
362
436
|
def unassign(*sns_to_unassign)
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
437
|
+
@scope = self.class.unassign(sns_to_unassign, from_prestage: @id, cnx: @cnx)
|
|
438
|
+
@versionLock = @scope.versionLock
|
|
439
|
+
# sns_to_unassign.map!(&:to_s)
|
|
440
|
+
# new_scope_sns = assigned_sns
|
|
441
|
+
# new_scope_sns -= sns_to_unassign
|
|
442
|
+
# update_scope(new_scope_sns)
|
|
367
443
|
end
|
|
368
444
|
alias remove unassign
|
|
369
445
|
|
|
@@ -382,20 +458,20 @@ module Jamf
|
|
|
382
458
|
@scope_rsrc ||= "#{self.class::RSRC_VERSION}/#{self.class::RSRC_PATH}/#{@id}/#{SCOPE_RSRC}"
|
|
383
459
|
end
|
|
384
460
|
|
|
385
|
-
def update_scope(new_scope_sns)
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
end
|
|
461
|
+
# def update_scope(new_scope_sns)
|
|
462
|
+
# assignment_data = {
|
|
463
|
+
# serialNumbers: new_scope_sns,
|
|
464
|
+
# versionLock: @scope.versionLock
|
|
465
|
+
# }
|
|
466
|
+
# begin
|
|
467
|
+
# @scope = Jamf::PrestageScope.new @cnx.put(scope_rsrc, assignment_data)
|
|
468
|
+
# rescue Jamf::Connection::APIError => e
|
|
469
|
+
# raise Jamf::VersionLockError, "The #{self.class} '#{name}' has been modified since it was fetched. Please refetch and try again" if e.status == 409
|
|
470
|
+
#
|
|
471
|
+
# raise e
|
|
472
|
+
# end # begin
|
|
473
|
+
# @versionLock = @scope.versionLock
|
|
474
|
+
# end
|
|
399
475
|
|
|
400
476
|
end # class
|
|
401
477
|
|
data/lib/jamf/api/connection.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2020 Pixar
|
|
2
2
|
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "Apache License")
|
|
@@ -48,7 +48,7 @@ module Jamf
|
|
|
48
48
|
RSRC_BASE = 'uapi'.freeze
|
|
49
49
|
|
|
50
50
|
# The API version must be this or higher
|
|
51
|
-
|
|
51
|
+
MIN_JAMF_VERSION = Gem::Version.new('10.15.0')
|
|
52
52
|
|
|
53
53
|
HTTPS_SCHEME = 'https'.freeze
|
|
54
54
|
|
|
@@ -77,17 +77,17 @@ module Jamf
|
|
|
77
77
|
DFT_SSL_VERSION = 'TLSv1_2'.freeze
|
|
78
78
|
|
|
79
79
|
# refresh token if less than this many seconds until
|
|
80
|
-
# expiration. Default is
|
|
81
|
-
DFT_TOKEN_REFRESH =
|
|
80
|
+
# expiration. Default is 5 minutes if not specified
|
|
81
|
+
DFT_TOKEN_REFRESH = 300
|
|
82
82
|
|
|
83
83
|
# pre-existing tokens must have this many seconds before
|
|
84
84
|
# before they expire
|
|
85
85
|
TOKEN_REUSE_MIN_LIFE = 60
|
|
86
86
|
|
|
87
|
-
HTTP_ACCEPT_HEADER = 'Accept'
|
|
88
|
-
HTTP_CONTENT_TYPE_HEADER = 'Content-Type'
|
|
87
|
+
HTTP_ACCEPT_HEADER = 'Accept'.freeze
|
|
88
|
+
HTTP_CONTENT_TYPE_HEADER = 'Content-Type'.freeze
|
|
89
89
|
|
|
90
|
-
MIME_JSON = 'application/json'
|
|
90
|
+
MIME_JSON = 'application/json'.freeze
|
|
91
91
|
|
|
92
92
|
SLASH = '/'.freeze
|
|
93
93
|
|
|
@@ -111,6 +111,7 @@ module Jamf
|
|
|
111
111
|
@login_time
|
|
112
112
|
@keep_alive
|
|
113
113
|
@token_refresh
|
|
114
|
+
@pw_fallback
|
|
114
115
|
].freeze
|
|
115
116
|
|
|
116
117
|
# Attributes
|
|
@@ -140,6 +141,10 @@ module Jamf
|
|
|
140
141
|
# @return [String, nil]
|
|
141
142
|
attr_reader :base_url
|
|
142
143
|
|
|
144
|
+
# @return [Boolean] if token refresh/keepaliave fails, try to get a new one
|
|
145
|
+
# with the passwd used with .connect. Defaults to true
|
|
146
|
+
attr_reader :pw_fallback
|
|
147
|
+
|
|
143
148
|
# @return [Boolean]
|
|
144
149
|
attr_reader :connected
|
|
145
150
|
alias connected? connected
|
|
@@ -227,14 +232,13 @@ module Jamf
|
|
|
227
232
|
# ### Tokens
|
|
228
233
|
# Instead of a user and password, you may specify a valid 'token:', either:
|
|
229
234
|
#
|
|
230
|
-
# A Jamf::Connection::Token object, which
|
|
235
|
+
# A Jamf::Connection::Token object, which can be extracted from an active
|
|
231
236
|
# Jamf::Connection via its #token method
|
|
232
237
|
#
|
|
233
238
|
# or
|
|
234
239
|
#
|
|
235
240
|
# A token string e.g. "eyJhdXR...6EKoo" from any source can also be used.
|
|
236
241
|
#
|
|
237
|
-
#
|
|
238
242
|
# Any values available via Jamf.config will be used if they are not provided
|
|
239
243
|
# in the parameters.
|
|
240
244
|
#
|
|
@@ -251,6 +255,19 @@ module Jamf
|
|
|
251
255
|
#
|
|
252
256
|
# @param token: [Jamf::Connection::Token, String] An existing, valid token.
|
|
253
257
|
# When used, there's no need to provide user: or pw:.
|
|
258
|
+
# NOTE if using pw_fallback:true (the default) while providing a token
|
|
259
|
+
# you will also need to provide the password for the token user in the pw:
|
|
260
|
+
# parameter, or be prompted for it. If you don't have the pw for the
|
|
261
|
+
# token user, be sure to set pw_fallback to false.
|
|
262
|
+
#
|
|
263
|
+
# @param token_refresh: [Integer] Refresh the token this many seconds before
|
|
264
|
+
# it expires. Must be >= DFT_TOKEN_REFRESH
|
|
265
|
+
#
|
|
266
|
+
# @pararm pw_fallback: [Boolean] Default is true. Use the password provided
|
|
267
|
+
# to refresh the token if regular refresh doesn't work (e.g. token is expired).
|
|
268
|
+
# NOTE: This causes the password to be kept in memory. If you don't want
|
|
269
|
+
# this, explicitly set pw_fallback to false, however long-running processes
|
|
270
|
+
# may lose connection if token refresh fails for any reason.
|
|
254
271
|
#
|
|
255
272
|
# @param open_timeout: [Integer] The number of seconds for initial contact
|
|
256
273
|
# with the host.
|
|
@@ -268,7 +285,8 @@ module Jamf
|
|
|
268
285
|
# This sets all the instance vars to nil, and flushes/creates the caches
|
|
269
286
|
disconnect
|
|
270
287
|
|
|
271
|
-
#
|
|
288
|
+
# If there's a Token object in :token, this sets @token,
|
|
289
|
+
# and adds host, port, user from that token
|
|
272
290
|
parse_token params
|
|
273
291
|
|
|
274
292
|
# Get host, port, user and pw from a URL, add to params if needed
|
|
@@ -277,6 +295,8 @@ module Jamf
|
|
|
277
295
|
# apply defaults from config, client, and then this class.
|
|
278
296
|
apply_connection_defaults params
|
|
279
297
|
|
|
298
|
+
# Once we're here, all params have been parsed & defaulted into the
|
|
299
|
+
# params hash, so
|
|
280
300
|
# make sure we have the minimum needed params for a connection
|
|
281
301
|
verify_basic_params params
|
|
282
302
|
|
|
@@ -285,15 +305,20 @@ module Jamf
|
|
|
285
305
|
|
|
286
306
|
# if no @token already, get one from from
|
|
287
307
|
# either a token string or a pw
|
|
288
|
-
@token
|
|
308
|
+
unless @token
|
|
289
309
|
if params[:token].is_a? String
|
|
290
|
-
|
|
310
|
+
@token = token_from :token_string, params[:token]
|
|
291
311
|
# get the user from the token
|
|
292
|
-
@user =
|
|
293
|
-
|
|
312
|
+
@user = @toke.user
|
|
313
|
+
# if @pw_fallback, the pw must be acquired, since it isn't in
|
|
314
|
+
# the token
|
|
315
|
+
@pw = acquire_password(params[:pw]) if @pw_fallback
|
|
294
316
|
else
|
|
295
|
-
|
|
317
|
+
pw = acquire_password(params[:pw])
|
|
318
|
+
@token = token_from :pw, pw
|
|
319
|
+
@pw = pw if @pw_fallback
|
|
296
320
|
end
|
|
321
|
+
end
|
|
297
322
|
|
|
298
323
|
# Now get some values from our token
|
|
299
324
|
@base_url = @token.base_url
|
|
@@ -303,46 +328,56 @@ module Jamf
|
|
|
303
328
|
@rest_cnx = create_connection
|
|
304
329
|
|
|
305
330
|
# make sure versions are good
|
|
306
|
-
|
|
331
|
+
validate_jamf_version
|
|
307
332
|
|
|
308
333
|
@connected = true
|
|
309
334
|
|
|
310
335
|
# start keepalive if needed
|
|
311
|
-
@keep_alive = params[:keep_alive].nil? ? false : params[:keep_alive]
|
|
312
336
|
start_keep_alive if @keep_alive
|
|
313
337
|
|
|
314
338
|
# return our string output
|
|
315
339
|
to_s
|
|
316
340
|
end # connect
|
|
317
341
|
|
|
342
|
+
# reset all values to nil or empty
|
|
318
343
|
def disconnect
|
|
319
|
-
# reset everything except the name & timeouts
|
|
320
344
|
@connected = false
|
|
345
|
+
@name = NOT_CONNECTED
|
|
321
346
|
@login_time = nil
|
|
347
|
+
|
|
348
|
+
stop_keep_alive
|
|
349
|
+
|
|
322
350
|
@host = nil
|
|
323
351
|
@port = nil
|
|
324
352
|
@user = nil
|
|
325
|
-
@
|
|
353
|
+
@timeout = nil
|
|
354
|
+
@open_timeout = nil
|
|
326
355
|
@base_url = nil
|
|
356
|
+
@token = nil
|
|
327
357
|
@rest_cnx = nil
|
|
328
358
|
@ssl_options = {}
|
|
329
359
|
@keep_alive = nil
|
|
360
|
+
@token_refresh = nil
|
|
361
|
+
@pw_fallback = nil
|
|
362
|
+
@pw = nil
|
|
363
|
+
|
|
330
364
|
flushcache
|
|
331
365
|
end
|
|
332
366
|
|
|
333
|
-
# Same as disconnect, but invalidates the token
|
|
367
|
+
# Same as disconnect, but invalidates the token on the server first
|
|
334
368
|
def logout
|
|
335
369
|
@token.destroy
|
|
336
370
|
disconnect
|
|
337
371
|
end
|
|
338
372
|
|
|
373
|
+
# Get a resource
|
|
339
374
|
def get(rsrc)
|
|
340
375
|
validate_connected
|
|
341
376
|
resp = @rest_cnx.get rsrc
|
|
342
377
|
@last_http_response = resp
|
|
343
378
|
return resp.body if resp.success?
|
|
344
379
|
|
|
345
|
-
raise Jamf::Connection::APIError
|
|
380
|
+
raise Jamf::Connection::APIError, resp
|
|
346
381
|
end
|
|
347
382
|
|
|
348
383
|
# GET a rsrc without doing any JSON parsing, using
|
|
@@ -353,7 +388,7 @@ module Jamf
|
|
|
353
388
|
@last_http_response = resp
|
|
354
389
|
return resp.body if resp.success?
|
|
355
390
|
|
|
356
|
-
raise Jamf::Connection::APIError
|
|
391
|
+
raise Jamf::Connection::APIError, resp
|
|
357
392
|
end
|
|
358
393
|
|
|
359
394
|
def post(rsrc, data)
|
|
@@ -364,7 +399,7 @@ module Jamf
|
|
|
364
399
|
@last_http_response = resp
|
|
365
400
|
return resp.body if resp.success?
|
|
366
401
|
|
|
367
|
-
raise Jamf::Connection::APIError
|
|
402
|
+
raise Jamf::Connection::APIError, resp
|
|
368
403
|
end
|
|
369
404
|
|
|
370
405
|
def put(rsrc, data)
|
|
@@ -375,7 +410,7 @@ module Jamf
|
|
|
375
410
|
@last_http_response = resp
|
|
376
411
|
return resp.body if resp.success?
|
|
377
412
|
|
|
378
|
-
raise Jamf::Connection::APIError
|
|
413
|
+
raise Jamf::Connection::APIError, resp
|
|
379
414
|
end
|
|
380
415
|
|
|
381
416
|
def patch(rsrc, data)
|
|
@@ -386,7 +421,7 @@ module Jamf
|
|
|
386
421
|
@last_http_response = resp
|
|
387
422
|
return resp.body if resp.success?
|
|
388
423
|
|
|
389
|
-
raise Jamf::Connection::APIError
|
|
424
|
+
raise Jamf::Connection::APIError, resp
|
|
390
425
|
end
|
|
391
426
|
|
|
392
427
|
def delete(rsrc)
|
|
@@ -395,7 +430,7 @@ module Jamf
|
|
|
395
430
|
@last_http_response = resp
|
|
396
431
|
return resp.body if resp.success?
|
|
397
432
|
|
|
398
|
-
raise Jamf::Connection::APIError
|
|
433
|
+
raise Jamf::Connection::APIError, resp
|
|
399
434
|
end
|
|
400
435
|
|
|
401
436
|
# A useful string about this connection
|
|
@@ -403,13 +438,50 @@ module Jamf
|
|
|
403
438
|
# @return [String]
|
|
404
439
|
#
|
|
405
440
|
def to_s
|
|
406
|
-
|
|
441
|
+
str =
|
|
442
|
+
if connected?
|
|
443
|
+
"#{@base_url}, Token expires: #{@token ? @token.expires : '<token missing>'}"
|
|
444
|
+
else
|
|
445
|
+
NOT_CONNECTED
|
|
446
|
+
end
|
|
447
|
+
"Jamf::Connection '#{@name == NOT_CONNECTED ? object_id : @name}': #{str}"
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
# Reset the name
|
|
451
|
+
def name=(new_name)
|
|
452
|
+
@name = new_name.to_s
|
|
407
453
|
end
|
|
408
454
|
|
|
455
|
+
# Are we keeping the connection alive?
|
|
409
456
|
def keep_alive?
|
|
410
|
-
|
|
457
|
+
return false unless @keep_alive_thread
|
|
458
|
+
|
|
459
|
+
@keep_alive_thread.alive?
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
# @return [Jamf::Timestamp, nil]
|
|
463
|
+
def next_refresh
|
|
464
|
+
return unless keep_alive?
|
|
465
|
+
|
|
466
|
+
@token.expires - @token_refresh
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
# @return [Float, nil]
|
|
470
|
+
def secs_to_refresh
|
|
471
|
+
return unless keep_alive?
|
|
472
|
+
|
|
473
|
+
next_refresh - Time.now
|
|
411
474
|
end
|
|
412
475
|
|
|
476
|
+
# @return [String, nil] e.g. "1 week 6 days 23 hours 49 minutes 56 seconds"
|
|
477
|
+
def time_to_refresh
|
|
478
|
+
return unless keep_alive?
|
|
479
|
+
return 0 if secs_to_refresh.negative?
|
|
480
|
+
|
|
481
|
+
Jamf.humanize_secs secs_to_refresh
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
# Turn keepalive on or offs
|
|
413
485
|
def keep_alive=(bool)
|
|
414
486
|
bool ? start_keep_alive : stop_keep_alive
|
|
415
487
|
end
|
|
@@ -422,8 +494,12 @@ module Jamf
|
|
|
422
494
|
@token_refresh = secs
|
|
423
495
|
end
|
|
424
496
|
|
|
425
|
-
def
|
|
426
|
-
@token.
|
|
497
|
+
def jamf_version
|
|
498
|
+
@token.jamf_version
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
def jamf_build
|
|
502
|
+
@token.jamf_build
|
|
427
503
|
end
|
|
428
504
|
|
|
429
505
|
# Flush the collection and/or ea cache for the given class,
|
|
@@ -458,18 +534,17 @@ module Jamf
|
|
|
458
534
|
####################################
|
|
459
535
|
private
|
|
460
536
|
|
|
461
|
-
|
|
462
537
|
# raise exception if not connected
|
|
463
538
|
def validate_connected
|
|
464
539
|
raise Jamf::InvalidConnectionError, 'Not Connected. Use .connect first.' unless connected?
|
|
465
540
|
end
|
|
466
541
|
|
|
467
542
|
# raise exception if API version is too low.
|
|
468
|
-
def
|
|
469
|
-
vers =
|
|
470
|
-
return if Gem::Version.new(vers) >=
|
|
543
|
+
def validate_jamf_version
|
|
544
|
+
vers = jamf_version
|
|
545
|
+
return if Gem::Version.new(vers) >= MIN_JAMF_VERSION
|
|
471
546
|
|
|
472
|
-
raise Jamf::InvalidConnectionError, "API version '#{vers}' too low, must be >= '#{
|
|
547
|
+
raise Jamf::InvalidConnectionError, "API version '#{vers}' too low, must be >= '#{MIN_JAMF_VERSION}'"
|
|
473
548
|
end
|
|
474
549
|
|
|
475
550
|
##### Parse Params
|
|
@@ -499,7 +574,7 @@ module Jamf
|
|
|
499
574
|
raise "Cannot use token: it expires in less than #{TOKEN_REUSE_MIN_LIFE} seconds" if token.secs_remaining < TOKEN_REUSE_MIN_LIFE
|
|
500
575
|
end
|
|
501
576
|
|
|
502
|
-
# Get host, port, user and pw from a URL,
|
|
577
|
+
# Get host, port, user and pw from a URL, overriding any already in the params
|
|
503
578
|
#
|
|
504
579
|
# @return [String, nil] the pw if present
|
|
505
580
|
#
|
|
@@ -509,27 +584,29 @@ module Jamf
|
|
|
509
584
|
url = URI.parse url.to_s
|
|
510
585
|
raise ArgumentError, 'Invalid url, scheme must be https' unless url.scheme == HTTPS_SCHEME
|
|
511
586
|
|
|
512
|
-
params[:host]
|
|
513
|
-
params[:port]
|
|
514
|
-
params[:user]
|
|
515
|
-
params[:pw]
|
|
587
|
+
params[:host] = url.host
|
|
588
|
+
params[:port] = url.port
|
|
589
|
+
params[:user] = url.user if url.user
|
|
590
|
+
params[:pw] = url.password if url.password
|
|
516
591
|
end
|
|
517
592
|
|
|
518
|
-
# Apply defaults
|
|
519
|
-
#
|
|
593
|
+
# Apply defaults to the unset params for the #connect method
|
|
594
|
+
# First apply them from from the Jamf.config,
|
|
595
|
+
# then from the Jamf::Client (read from the jamf binary config),
|
|
520
596
|
# then from the Jamf module defaults
|
|
521
|
-
# to the unset params for the #connect method
|
|
522
597
|
#
|
|
523
598
|
# @param params[Hash] The params for #connect
|
|
524
599
|
#
|
|
525
600
|
# @return [Hash] The params with defaults applied
|
|
526
601
|
#
|
|
527
602
|
def apply_connection_defaults(params)
|
|
528
|
-
#
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
#
|
|
532
|
-
|
|
603
|
+
# must have a host, but accept legacy :server as well as :host
|
|
604
|
+
params[:host] ||= params[:server]
|
|
605
|
+
|
|
606
|
+
# if we have no port set by this point, set to cloud port
|
|
607
|
+
# if host is a cloud host. But leave port nil for other hosts
|
|
608
|
+
# (will be set via client defaults or module defaults)
|
|
609
|
+
params[:port] ||= JAMFCLOUD_PORT if params[:host].to_s.end_with?(JAMFCLOUD_DOMAIN)
|
|
533
610
|
|
|
534
611
|
apply_defaults_from_config(params)
|
|
535
612
|
|
|
@@ -583,11 +660,12 @@ module Jamf
|
|
|
583
660
|
# @return [Hash] The params with defaults applied
|
|
584
661
|
#
|
|
585
662
|
def apply_module_defaults(params)
|
|
586
|
-
# if we have no port set by this point, assume on-prem
|
|
663
|
+
# if we have no port set by this point, assume on-prem.
|
|
587
664
|
params[:port] ||= ON_PREM_SSL_PORT
|
|
588
665
|
params[:timeout] ||= DFT_TIMEOUT
|
|
589
666
|
params[:open_timeout] ||= DFT_OPEN_TIMEOUT
|
|
590
667
|
params[:ssl_version] ||= DFT_SSL_VERSION
|
|
668
|
+
params[:token_refresh] ||= DFT_TOKEN_REFRESH
|
|
591
669
|
# if we have a TTY, pw defaults to :prompt
|
|
592
670
|
params[:pw] ||= :prompt if STDIN.tty?
|
|
593
671
|
end
|
|
@@ -603,32 +681,38 @@ module Jamf
|
|
|
603
681
|
# and is already parsed
|
|
604
682
|
return if @token
|
|
605
683
|
|
|
606
|
-
# must have a host
|
|
607
|
-
params[:host] ||= params[:server]
|
|
684
|
+
# must have a host
|
|
608
685
|
raise Jamf::MissingDataError, 'No Jamf :host specified, or in configuration.' unless params[:host]
|
|
609
686
|
|
|
610
687
|
# no need for user or pass if using a token string
|
|
611
688
|
return if params[:token].is_a? String
|
|
612
689
|
|
|
690
|
+
# must have user and pw
|
|
613
691
|
raise Jamf::MissingDataError, 'No Jamf :user specified, or in configuration.' unless params[:user]
|
|
614
692
|
raise Jamf::MissingDataError, "No :pw specified for user '#{params[:user]}'" unless params[:pw]
|
|
615
693
|
end
|
|
616
694
|
|
|
695
|
+
# Turn the connection parameters into instance vars
|
|
617
696
|
def parse_connect_params(params)
|
|
618
697
|
@host = params[:host]
|
|
619
698
|
@port = params[:port]
|
|
620
|
-
@port ||= @host.end_with?(JAMFCLOUD_DOMAIN) ? JAMFCLOUD_PORT : ON_PREM_SSL_PORT
|
|
621
699
|
@user = params[:user]
|
|
622
|
-
|
|
623
|
-
@
|
|
624
|
-
@
|
|
700
|
+
|
|
701
|
+
@keep_alive = params[:keep_alive].nil? ? false : params[:keep_alive]
|
|
702
|
+
@pw_fallback = params[:pw_fallback].nil? ? true : params[:pw_fallback]
|
|
703
|
+
@token_refresh = params[:token_refresh].to_i
|
|
704
|
+
|
|
705
|
+
@timeout = params[:timeout]
|
|
706
|
+
@open_timeout = params[:open_timeout]
|
|
625
707
|
@base_url = URI.parse "https://#{@host}:#{@port}/#{RSRC_BASE}"
|
|
708
|
+
|
|
626
709
|
# ssl opts for faraday
|
|
627
710
|
# TODO: implement all of faraday's options
|
|
628
711
|
@ssl_options = {
|
|
629
712
|
verify: params[:verify_cert],
|
|
630
713
|
version: params[:ssl_version]
|
|
631
714
|
}
|
|
715
|
+
|
|
632
716
|
@name = "#{@user}@#{@host}:#{@port}" if @name == NOT_CONNECTED
|
|
633
717
|
end
|
|
634
718
|
|
|
@@ -659,16 +743,18 @@ module Jamf
|
|
|
659
743
|
# @return [String] The password for the connection
|
|
660
744
|
#
|
|
661
745
|
def acquire_password(param_pw)
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
param_pw.
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
746
|
+
pw =
|
|
747
|
+
if param_pw == :prompt
|
|
748
|
+
Jamf.prompt_for_password "Enter the password for Jamf user #{@user}@#{@host}:"
|
|
749
|
+
elsif param_pw.is_a?(Symbol) && param_pw.to_s.start_with?('stdin')
|
|
750
|
+
param_pw.to_s =~ /^stdin(\d+)$/
|
|
751
|
+
line = Regexp.last_match(1)
|
|
752
|
+
line ||= 1
|
|
753
|
+
Jamf.stdin line
|
|
754
|
+
else
|
|
755
|
+
param_pw
|
|
756
|
+
end # if
|
|
757
|
+
pw
|
|
672
758
|
end # acquire pw
|
|
673
759
|
|
|
674
760
|
# create the faraday connection object
|
|
@@ -702,9 +788,16 @@ module Jamf
|
|
|
702
788
|
Thread.new do
|
|
703
789
|
loop do
|
|
704
790
|
sleep 60
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
791
|
+
begin
|
|
792
|
+
next if @token.secs_remaining > @token_refresh
|
|
793
|
+
|
|
794
|
+
@token.refresh @pw
|
|
795
|
+
# make sure faraday uses the new token
|
|
796
|
+
@rest_cnx.headers[:authorization] = @token.auth_token
|
|
797
|
+
rescue
|
|
798
|
+
# TODO: Some kind of error reporting
|
|
799
|
+
next
|
|
800
|
+
end
|
|
708
801
|
end # loop
|
|
709
802
|
end # thread
|
|
710
803
|
end
|
|
@@ -717,7 +810,7 @@ module Jamf
|
|
|
717
810
|
def stop_keep_alive
|
|
718
811
|
return unless @keep_alive_thread
|
|
719
812
|
|
|
720
|
-
@keep_alive_thread.kill
|
|
813
|
+
@keep_alive_thread.kill if @keep_alive_thread.alive?
|
|
721
814
|
@keep_alive_thread = nil
|
|
722
815
|
end
|
|
723
816
|
|
|
@@ -763,4 +856,8 @@ module Jamf
|
|
|
763
856
|
@active_connection = connection
|
|
764
857
|
end
|
|
765
858
|
|
|
859
|
+
def self.disconnect
|
|
860
|
+
@active_connection.disconnect if @active_connection
|
|
861
|
+
end
|
|
862
|
+
|
|
766
863
|
end # module Jamf
|