ruby-jss 1.2.4a3 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ruby-jss might be problematic. Click here for more details.
- 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
|