ruby-jss 1.2.9 → 1.5.1
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 +196 -1
- data/lib/jamf.rb +10 -3
- data/lib/jamf/api/abstract_classes/collection_resource.rb +329 -150
- data/lib/jamf/api/abstract_classes/generic_reference.rb +9 -1
- data/lib/jamf/api/abstract_classes/json_object.rb +107 -83
- data/lib/jamf/api/abstract_classes/prestage.rb +55 -30
- data/lib/jamf/api/abstract_classes/prestage_skip_setup_items.rb +21 -0
- data/lib/jamf/api/abstract_classes/resource.rb +4 -4
- data/lib/jamf/api/abstract_classes/singleton_resource.rb +1 -1
- data/lib/jamf/api/connection.rb +20 -12
- data/lib/jamf/api/connection/api_error.rb +8 -8
- data/lib/jamf/api/connection/token.rb +36 -15
- data/lib/jamf/api/json_objects/computer_prestage_skip_setup_items.rb +14 -1
- data/lib/jamf/api/json_objects/device_enrollment_device.rb +14 -7
- data/lib/jamf/api/json_objects/device_enrollment_device_sync_state.rb +81 -0
- data/lib/jamf/api/json_objects/locale.rb +59 -0
- data/lib/jamf/api/json_objects/md_prestage_skip_setup_items.rb +50 -1
- data/lib/jamf/api/json_objects/prestage_location.rb +3 -3
- data/lib/jamf/api/json_objects/prestage_purchasing_data.rb +7 -7
- data/lib/jamf/api/json_objects/prestage_scope.rb +1 -1
- data/lib/jamf/api/{resources/collection_resources → json_objects}/time_zone.rb +9 -23
- data/lib/jamf/api/mixins/bulk_deletable.rb +27 -6
- data/lib/jamf/api/mixins/change_log.rb +201 -51
- data/lib/jamf/api/mixins/filterable.rb +51 -0
- data/lib/jamf/api/mixins/pageable.rb +208 -0
- data/lib/jamf/api/mixins/sortable.rb +59 -0
- data/lib/jamf/api/resources/collection_resources/building.rb +19 -8
- data/lib/jamf/api/resources/collection_resources/category.rb +5 -3
- data/lib/jamf/api/resources/collection_resources/computer_prestage.rb +11 -4
- data/lib/jamf/api/resources/collection_resources/department.rb +1 -1
- data/lib/jamf/api/resources/collection_resources/device_enrollment.rb +13 -13
- data/lib/jamf/api/resources/collection_resources/inventory_preload_record.rb +11 -3
- data/lib/jamf/api/resources/collection_resources/mobile_device_prestage.rb +24 -22
- data/lib/jamf/api/resources/collection_resources/script.rb +61 -25
- data/lib/jamf/api/resources/singleton_resources/app_store_country_codes.rb +15 -5
- data/lib/jamf/api/resources/singleton_resources/client_checkin_settings.rb +14 -14
- data/lib/jamf/api/resources/singleton_resources/locales.rb +155 -0
- data/lib/jamf/api/resources/singleton_resources/time_zones.rb +213 -0
- data/lib/jamf/configuration.rb +7 -9
- data/lib/jamf/ruby_extensions.rb +1 -0
- data/lib/jamf/ruby_extensions/array.rb +1 -1
- data/lib/jamf/ruby_extensions/array/utils.rb +3 -3
- data/lib/jamf/ruby_extensions/dig.rb +52 -0
- data/lib/jamf/validate.rb +63 -24
- data/lib/jamf/version.rb +1 -1
- data/lib/jss.rb +4 -1
- data/lib/jss/api_connection.rb +110 -397
- data/lib/jss/api_object.rb +16 -13
- data/lib/jss/api_object/advanced_search.rb +27 -26
- data/lib/jss/api_object/app_store_country_codes.rb +298 -0
- data/lib/jss/api_object/categorizable.rb +1 -1
- data/lib/jss/api_object/computer.rb +5 -1
- data/lib/jss/api_object/configuration_profile.rb +34 -3
- data/lib/jss/api_object/directory_binding.rb +273 -0
- data/lib/jss/api_object/directory_binding_type.rb +96 -0
- data/lib/jss/api_object/directory_binding_type/active_directory.rb +539 -0
- data/lib/jss/api_object/directory_binding_type/admitmac.rb +594 -0
- data/lib/jss/api_object/directory_binding_type/centrify.rb +226 -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 +97 -37
- data/lib/jss/api_object/dock_item.rb +143 -0
- data/lib/jss/api_object/ebook.rb +1 -2
- data/lib/jss/api_object/extendable.rb +68 -32
- data/lib/jss/api_object/extension_attribute.rb +4 -3
- data/lib/jss/api_object/group.rb +33 -2
- data/lib/jss/api_object/mac_application.rb +107 -8
- data/lib/jss/api_object/mobile_device.rb +3 -0
- data/lib/jss/api_object/mobile_device_application.rb +12 -0
- data/lib/jss/api_object/network_segment.rb +195 -70
- data/lib/jss/api_object/package.rb +105 -40
- data/lib/jss/api_object/patch_source.rb +10 -9
- data/lib/jss/api_object/policy.rb +491 -7
- data/lib/jss/api_object/printer.rb +446 -0
- data/lib/jss/api_object/scopable.rb +10 -15
- data/lib/jss/api_object/scopable/scope.rb +386 -71
- data/lib/jss/api_object/self_servable.rb +17 -9
- data/lib/jss/api_object/uploadable.rb +1 -1
- data/lib/jss/api_object/user.rb +42 -1
- data/lib/jss/api_object/vpp_account.rb +209 -0
- data/lib/jss/api_object/vppable.rb +169 -13
- data/lib/jss/composer.rb +1 -1
- data/lib/jss/exceptions.rb +3 -0
- data/lib/jss/server.rb +15 -0
- data/lib/jss/utility.rb +8 -22
- data/lib/jss/validate.rb +53 -10
- data/lib/jss/version.rb +1 -1
- metadata +50 -22
|
@@ -121,9 +121,31 @@ module JSS
|
|
|
121
121
|
# @return [Array<String>] The current file names
|
|
122
122
|
#
|
|
123
123
|
def self.all_filenames(api: JSS.api)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
all_filenames_by(:id, api: api).values
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# A Hash of all dist-point filenames used by all JSS packages, keyed by
|
|
128
|
+
# package name or id
|
|
129
|
+
#
|
|
130
|
+
# Slow cuz we have to instantiate every pkg
|
|
131
|
+
#
|
|
132
|
+
# @param key[Symbol] either :id, or :name
|
|
133
|
+
#
|
|
134
|
+
# @param api[JSS::APIConnection] an API connection to use
|
|
135
|
+
# Defaults to the corrently active API. See {JSS::APIConnection}
|
|
136
|
+
#
|
|
137
|
+
# @return [Hash{Ingeter,String => String}] The current file names by key
|
|
138
|
+
#
|
|
139
|
+
def self.all_filenames_by(key, api: JSS.api)
|
|
140
|
+
raise ArgumentError, 'key must be :id or :name' unless %i[id name].include? key
|
|
141
|
+
|
|
142
|
+
files_in_use = {}
|
|
143
|
+
all_ids(:refresh).each do |pkg_id|
|
|
144
|
+
pkg = fetch id: pkg_id, api: api
|
|
145
|
+
files_in_use[pkg.send(key)] = pkg.filename
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
files_in_use
|
|
127
149
|
end
|
|
128
150
|
|
|
129
151
|
# An array of String filenames for all files DIST_POINT_PKGS_FOLDER
|
|
@@ -140,14 +162,17 @@ module JSS
|
|
|
140
162
|
# @param api[JSS::APIConnection] an API connection to use
|
|
141
163
|
# Defaults to the corrently active API. See {JSS::APIConnection}
|
|
142
164
|
#
|
|
165
|
+
# @param dist_point [String,Integer] the name or id of the distribution
|
|
166
|
+
# point to use. Defaults to the Master Dist. Point
|
|
167
|
+
#
|
|
143
168
|
# @return [Array<String>] The orphaned files
|
|
144
169
|
#
|
|
145
|
-
def self.orphaned_files(ro_pw, unmount = true, api: JSS.api)
|
|
146
|
-
|
|
147
|
-
pkgs_dir =
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
170
|
+
def self.orphaned_files(ro_pw, unmount = true, api: JSS.api, dist_point: nil)
|
|
171
|
+
dp = fetch_dist_point(dist_point, api: api)
|
|
172
|
+
pkgs_dir = dp.mount(ro_pw, :ro) + DIST_POINT_PKGS_FOLDER
|
|
173
|
+
files_on_dp = pkgs_dir.children.map { |f| f.basename.to_s }
|
|
174
|
+
dp.unmount if unmount
|
|
175
|
+
files_on_dp - all_filenames(api: api)
|
|
151
176
|
end
|
|
152
177
|
|
|
153
178
|
# An array of String filenames for all filenames in any
|
|
@@ -164,14 +189,18 @@ module JSS
|
|
|
164
189
|
# @param api[JSS::APIConnection] an API connection to use
|
|
165
190
|
# Defaults to the corrently active API. See {JSS::APIConnection}
|
|
166
191
|
#
|
|
192
|
+
# @param dist_point [String,Integer] the name or id of the distribution
|
|
193
|
+
# point to use. Defaults to the Master Dist. Point
|
|
194
|
+
#
|
|
195
|
+
#
|
|
167
196
|
# @return [Array<String>] The orphaned files
|
|
168
197
|
#
|
|
169
|
-
def self.missing_files(ro_pw, unmount = true, api: JSS.api)
|
|
170
|
-
|
|
171
|
-
pkgs_dir =
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
all_filenames(api: api) -
|
|
198
|
+
def self.missing_files(ro_pw, unmount = true, api: JSS.api, dist_point: nil)
|
|
199
|
+
dp = fetch_dist_point(dist_point, api: api)
|
|
200
|
+
pkgs_dir = dp.mount(ro_pw, :ro) + DIST_POINT_PKGS_FOLDER
|
|
201
|
+
files_on_dp = pkgs_dir.children.map { |f| f.basename.to_s }
|
|
202
|
+
dp.unmount if unmount
|
|
203
|
+
all_filenames(api: api) - files_on_dp
|
|
175
204
|
end
|
|
176
205
|
|
|
177
206
|
# Given a file path, and hash type, generate the checksum for an arbitrary
|
|
@@ -189,6 +218,18 @@ module JSS
|
|
|
189
218
|
CHECKSUM_HASH_TYPES[type].file(filepath).hexdigest
|
|
190
219
|
end
|
|
191
220
|
|
|
221
|
+
# @param dist_point [String,Integer] the name or id of the distribution
|
|
222
|
+
# point to use. Defaults to the Master Dist. Point
|
|
223
|
+
#
|
|
224
|
+
# @return [JSS::DistributionPoint]
|
|
225
|
+
def self.fetch_dist_point(dist_point, api: JSS.api)
|
|
226
|
+
if dist_point
|
|
227
|
+
JSS::DistributionPoint.fetch dist_point, api: api
|
|
228
|
+
else
|
|
229
|
+
JSS::DistributionPoint.master_distribution_point api: api
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
192
233
|
# Attributes
|
|
193
234
|
#####################################
|
|
194
235
|
|
|
@@ -324,7 +365,7 @@ module JSS
|
|
|
324
365
|
new_val = nil if new_val == ''
|
|
325
366
|
new_val ||= @name
|
|
326
367
|
return nil if new_val == @filename
|
|
327
|
-
|
|
368
|
+
|
|
328
369
|
@filename = new_val
|
|
329
370
|
@need_to_update = true
|
|
330
371
|
end
|
|
@@ -590,13 +631,17 @@ module JSS
|
|
|
590
631
|
# @param chksum [String] the constants CHECKSUM_HASH_TYPE_SHA512 or
|
|
591
632
|
# CHECKSUM_HASH_TYPE_MD5. Anything else means don't calc.
|
|
592
633
|
#
|
|
634
|
+
# @param dist_point [String,Integer] the name or id of the distribution
|
|
635
|
+
# point to use. Defaults to the Master Dist. Point
|
|
636
|
+
#
|
|
593
637
|
# @return [void]
|
|
594
638
|
#
|
|
595
|
-
def upload_master_file(local_file_path, rw_pw, unmount = true, chksum: DEFAULT_CHECKSUM_HASH_TYPE )
|
|
639
|
+
def upload_master_file(local_file_path, rw_pw, unmount = true, chksum: DEFAULT_CHECKSUM_HASH_TYPE, dist_point: nil)
|
|
596
640
|
raise JSS::NoSuchItemError, 'Please create this package in the JSS before uploading it.' unless @in_jss
|
|
597
641
|
|
|
598
|
-
|
|
599
|
-
|
|
642
|
+
dp = self.class.fetch_dist_point(dist_point, api: @api)
|
|
643
|
+
|
|
644
|
+
destination = dp.mount(rw_pw, :rw) + "#{DIST_POINT_PKGS_FOLDER}/#{@filename}"
|
|
600
645
|
|
|
601
646
|
local_path = Pathname.new local_file_path
|
|
602
647
|
raise JSS::NoSuchItemError, "Local file '#{@local_file}' doesn't exist" unless local_path.exist?
|
|
@@ -637,11 +682,11 @@ module JSS
|
|
|
637
682
|
|
|
638
683
|
if CHECKSUM_HASH_TYPES.keys.include? chksum
|
|
639
684
|
@checksum_type = chksum
|
|
640
|
-
@checksum = calculate_checksum local_file: local_path, type: chksum, unmount: false
|
|
685
|
+
@checksum = calculate_checksum local_file: local_path, type: chksum, unmount: false, dist_point: dist_point
|
|
641
686
|
@need_to_update = true
|
|
642
687
|
end
|
|
643
688
|
update if @need_to_update
|
|
644
|
-
|
|
689
|
+
dp.unmount if unmount
|
|
645
690
|
end # upload master file
|
|
646
691
|
|
|
647
692
|
# Using either a local file, or the file on the master dist. point,
|
|
@@ -658,7 +703,7 @@ module JSS
|
|
|
658
703
|
#
|
|
659
704
|
# @return [void]
|
|
660
705
|
#
|
|
661
|
-
def reset_checksum(type: nil, local_file: nil, rw_pw: nil, ro_pw: nil, unmount: true)
|
|
706
|
+
def reset_checksum(type: nil, local_file: nil, rw_pw: nil, ro_pw: nil, unmount: true, dist_point: nil )
|
|
662
707
|
type ||= DEFAULT_CHECKSUM_HASH_TYPE
|
|
663
708
|
|
|
664
709
|
new_checksum = calculate_checksum(
|
|
@@ -666,7 +711,8 @@ module JSS
|
|
|
666
711
|
local_file: local_file,
|
|
667
712
|
rw_pw: rw_pw,
|
|
668
713
|
ro_pw: ro_pw,
|
|
669
|
-
unmount: unmount
|
|
714
|
+
unmount: unmount,
|
|
715
|
+
dist_point: dist_point
|
|
670
716
|
)
|
|
671
717
|
return if @checksum == new_checksum
|
|
672
718
|
|
|
@@ -694,11 +740,14 @@ module JSS
|
|
|
694
740
|
# @param unmount [Boolean] Unmount the master dist point after using it.
|
|
695
741
|
# Only used if the dist point is mounted. default: true
|
|
696
742
|
#
|
|
743
|
+
# @param dist_point [String,Integer] the name or id of the distribution
|
|
744
|
+
# point to use. Defaults to the Master Dist. Point
|
|
745
|
+
#
|
|
697
746
|
# @return [String] The calculated checksum
|
|
698
747
|
#
|
|
699
|
-
def calculate_checksum(type: nil, local_file: nil, rw_pw: nil, ro_pw: nil, unmount: true )
|
|
748
|
+
def calculate_checksum(type: nil, local_file: nil, rw_pw: nil, ro_pw: nil, unmount: true, dist_point: nil )
|
|
700
749
|
type ||= DEFAULT_CHECKSUM_HASH_TYPE
|
|
701
|
-
|
|
750
|
+
dp = self.class.fetch_dist_point(dist_point, api: @api)
|
|
702
751
|
|
|
703
752
|
if local_file
|
|
704
753
|
file_to_calc = local_file
|
|
@@ -712,10 +761,10 @@ module JSS
|
|
|
712
761
|
else
|
|
713
762
|
raise ArgumentError, 'Either rw_pw: or ro_pw: must be provided'
|
|
714
763
|
end
|
|
715
|
-
file_to_calc =
|
|
764
|
+
file_to_calc = dp.mount(dppw, mnt) + "#{DIST_POINT_PKGS_FOLDER}/#{@filename}"
|
|
716
765
|
end
|
|
717
766
|
new_checksum = self.class.calculate_checksum(file_to_calc, type)
|
|
718
|
-
|
|
767
|
+
dp.unmount if unmount && dp.mounted?
|
|
719
768
|
new_checksum
|
|
720
769
|
end
|
|
721
770
|
|
|
@@ -734,17 +783,21 @@ module JSS
|
|
|
734
783
|
# @param unmount [Boolean] Unmount the master dist point after using it.
|
|
735
784
|
# Only used if the dist point is mounted. default: true
|
|
736
785
|
#
|
|
786
|
+
# @param dist_point [String,Integer] the name or id of the distribution
|
|
787
|
+
# point to use. Defaults to the Master Dist. Point
|
|
788
|
+
#
|
|
737
789
|
# @return [Boolean] false if there is no checksum for this pkg, otherwise,
|
|
738
790
|
# does the calculated checksum match the one stored for the pkg?
|
|
739
791
|
#
|
|
740
|
-
def checksum_valid?(local_file: nil, rw_pw: nil, ro_pw: nil, unmount: true)
|
|
792
|
+
def checksum_valid?(local_file: nil, rw_pw: nil, ro_pw: nil, unmount: true, dist_point: nil )
|
|
741
793
|
return false unless @checksum
|
|
742
794
|
new_checksum = calculate_checksum(
|
|
743
795
|
type: @checksum_type,
|
|
744
796
|
local_file: local_file,
|
|
745
797
|
rw_pw: rw_pw,
|
|
746
798
|
ro_pw: ro_pw,
|
|
747
|
-
unmount: unmount
|
|
799
|
+
unmount: unmount,
|
|
800
|
+
dist_point: dist_point
|
|
748
801
|
)
|
|
749
802
|
new_checksum == @checksum
|
|
750
803
|
end
|
|
@@ -760,12 +813,16 @@ module JSS
|
|
|
760
813
|
# @param rw_pw[String,Symbol] the password for the read/write account on the master Distribution Point,
|
|
761
814
|
# or :prompt, or :stdin# where # is the line of stdin containing the password See {JSS::DistributionPoint#mount}
|
|
762
815
|
#
|
|
816
|
+
# @param dist_point [String,Integer] the name or id of the distribution
|
|
817
|
+
# point to use. Defaults to the Master Dist. Point
|
|
818
|
+
#
|
|
763
819
|
# @return [nil]
|
|
764
820
|
#
|
|
765
|
-
def update_master_filename(old_file_name, new_file_name, rw_pw, unmount = true)
|
|
821
|
+
def update_master_filename(old_file_name, new_file_name, rw_pw, unmount = true, dist_point: nil)
|
|
766
822
|
raise JSS::NoSuchItemError, "#{old_file_name} does not exist in the jss." unless @in_jss
|
|
767
|
-
|
|
768
|
-
|
|
823
|
+
dp = self.class.fetch_dist_point(dist_point, api: @api)
|
|
824
|
+
|
|
825
|
+
pkgs_dir = dp.mount(rw_pw, :rw) + DIST_POINT_PKGS_FOLDER.to_s
|
|
769
826
|
old_file = pkgs_dir + old_file_name
|
|
770
827
|
raise JSS::NoSuchItemError, "File not found on the master distribution point at #{DIST_POINT_PKGS_FOLDER}/#{old_file_name}." unless \
|
|
771
828
|
old_file.exist?
|
|
@@ -775,7 +832,7 @@ module JSS
|
|
|
775
832
|
new_file = pkgs_dir + (new_file_name + old_file.extname) if new_file.extname.empty?
|
|
776
833
|
|
|
777
834
|
old_file.rename new_file
|
|
778
|
-
|
|
835
|
+
dp.unmount if unmount
|
|
779
836
|
nil
|
|
780
837
|
end # update_master_filename
|
|
781
838
|
|
|
@@ -791,18 +848,21 @@ module JSS
|
|
|
791
848
|
#
|
|
792
849
|
# @param unmount[Boolean] whether or not ot unount the distribution point when finished.
|
|
793
850
|
#
|
|
851
|
+
# @param dist_point [String,Integer] the name or id of the distribution
|
|
852
|
+
# point to use. Defaults to the Master Dist. Point
|
|
853
|
+
#
|
|
794
854
|
# @return [Boolean] was the file deleted?
|
|
795
855
|
#
|
|
796
|
-
def delete_master_file(rw_pw, unmount = true)
|
|
797
|
-
|
|
798
|
-
file =
|
|
856
|
+
def delete_master_file(rw_pw, unmount = true, dist_point: nil)
|
|
857
|
+
dp = self.class.fetch_dist_point(dist_point, api: @api)
|
|
858
|
+
file = dp.mount(rw_pw, :rw) + "#{DIST_POINT_PKGS_FOLDER}/#{@filename}"
|
|
799
859
|
if file.exist?
|
|
800
860
|
file.delete
|
|
801
861
|
did_it = true
|
|
802
862
|
else
|
|
803
863
|
did_it = false
|
|
804
864
|
end # if exists
|
|
805
|
-
|
|
865
|
+
dp.unmount if unmount
|
|
806
866
|
did_it
|
|
807
867
|
end # delete master file
|
|
808
868
|
|
|
@@ -816,9 +876,13 @@ module JSS
|
|
|
816
876
|
#
|
|
817
877
|
# @param unmount[Boolean] whether or not ot unount the distribution point when finished.
|
|
818
878
|
#
|
|
819
|
-
|
|
879
|
+
# @param dist_point [String,Integer] the name or id of the distribution
|
|
880
|
+
# point to use. Defaults to the Master Dist. Point
|
|
881
|
+
#
|
|
882
|
+
# @return [void]
|
|
883
|
+
def delete(delete_file: false, rw_pw: nil, unmount: true, dist_point: nil)
|
|
820
884
|
super()
|
|
821
|
-
delete_master_file(rw_pw, unmount) if delete_file
|
|
885
|
+
delete_master_file(rw_pw, unmount, dist_point: dist_point) if delete_file
|
|
822
886
|
end
|
|
823
887
|
|
|
824
888
|
# Install this package via the jamf binary 'install' command from the
|
|
@@ -885,7 +949,7 @@ module JSS
|
|
|
885
949
|
|
|
886
950
|
# we'll re-add the filename below if needed.
|
|
887
951
|
src_path = args[:alt_download_url].chomp "/#{@filename}"
|
|
888
|
-
|
|
952
|
+
using_http = true
|
|
889
953
|
# use our appropriate dist. point for download
|
|
890
954
|
else
|
|
891
955
|
mdp = JSS::DistributionPoint.my_distribution_point api: @api
|
|
@@ -1021,6 +1085,7 @@ module JSS
|
|
|
1021
1085
|
|
|
1022
1086
|
private
|
|
1023
1087
|
|
|
1088
|
+
|
|
1024
1089
|
# Return the REST XML for this pkg, with the current values,
|
|
1025
1090
|
# for saving or updating
|
|
1026
1091
|
#
|
|
@@ -120,30 +120,31 @@ module JSS
|
|
|
120
120
|
|
|
121
121
|
# Fetch either an internal or external patch source
|
|
122
122
|
#
|
|
123
|
-
# BUG: there's an API bug: fetching a non-existent
|
|
123
|
+
# BUG: there's an API bug: fetching a non-existent
|
|
124
124
|
# which is why we rescue internal server errors.
|
|
125
125
|
#
|
|
126
126
|
# @see APIObject.fetch
|
|
127
127
|
#
|
|
128
|
-
def self.fetch(
|
|
128
|
+
def self.fetch(searchterm = nil, **args)
|
|
129
129
|
if self == JSS::PatchSource
|
|
130
130
|
begin
|
|
131
|
-
fetched = JSS::PatchInternalSource.fetch
|
|
132
|
-
rescue
|
|
131
|
+
fetched = JSS::PatchInternalSource.fetch searchterm, **args
|
|
132
|
+
rescue
|
|
133
133
|
fetched = nil
|
|
134
134
|
end
|
|
135
135
|
unless fetched
|
|
136
136
|
begin
|
|
137
|
-
fetched = JSS::PatchExternalSource.fetch
|
|
138
|
-
rescue
|
|
137
|
+
fetched = JSS::PatchExternalSource.fetch searchterm, **args
|
|
138
|
+
rescue
|
|
139
139
|
raise JSS::NoSuchItemError, 'No matching PatchSource found'
|
|
140
140
|
end
|
|
141
141
|
end
|
|
142
142
|
return fetched
|
|
143
143
|
end # if self == JSS::PatchSource
|
|
144
|
+
|
|
144
145
|
begin
|
|
145
|
-
super
|
|
146
|
-
rescue
|
|
146
|
+
super searchterm, **args
|
|
147
|
+
rescue JSS::NoSuchItemError
|
|
147
148
|
raise JSS::NoSuchItemError, "No matching #{self::RSRC_OBJECT_KEY} found"
|
|
148
149
|
end
|
|
149
150
|
end
|
|
@@ -211,7 +212,7 @@ module JSS
|
|
|
211
212
|
begin
|
|
212
213
|
# TODO: remove this and adjust parsing when jamf fixes the JSON
|
|
213
214
|
raw = JSS::XMLWorkaround.data_via_xml(rsrc, AVAILABLE_TITLES_DATA_MAP, api)
|
|
214
|
-
rescue
|
|
215
|
+
rescue JSS::NoSuchItemError
|
|
215
216
|
return []
|
|
216
217
|
end
|
|
217
218
|
|
|
@@ -148,6 +148,12 @@ module JSS
|
|
|
148
148
|
monthly: 'Once every month'
|
|
149
149
|
}.freeze
|
|
150
150
|
|
|
151
|
+
RETRY_EVENTS = {
|
|
152
|
+
none: 'none',
|
|
153
|
+
checkin: 'check-in',
|
|
154
|
+
trigger: 'trigger'
|
|
155
|
+
}.freeze
|
|
156
|
+
|
|
151
157
|
RESTART_WHEN = {
|
|
152
158
|
if_pkg_requires: 'Restart if a package or update requires it',
|
|
153
159
|
now: 'Restart immediately',
|
|
@@ -174,7 +180,9 @@ module JSS
|
|
|
174
180
|
change_pw: 'specified',
|
|
175
181
|
generate_pw: 'random',
|
|
176
182
|
enable_fv2: 'fileVaultEnable',
|
|
177
|
-
disable_fv2: 'fileVaultDisable'
|
|
183
|
+
disable_fv2: 'fileVaultDisable',
|
|
184
|
+
reset_random: 'resetRandom',
|
|
185
|
+
reset_pw: 'reset'
|
|
178
186
|
}.freeze
|
|
179
187
|
|
|
180
188
|
PACKAGE_ACTIONS = {
|
|
@@ -191,6 +199,12 @@ module JSS
|
|
|
191
199
|
after: 'After'
|
|
192
200
|
}.freeze
|
|
193
201
|
|
|
202
|
+
DISK_ENCRYPTION_ACTIONS = {
|
|
203
|
+
apply: "apply",
|
|
204
|
+
remediate: "remediate",
|
|
205
|
+
none: "none"
|
|
206
|
+
}
|
|
207
|
+
|
|
194
208
|
PRINTER_ACTIONS = {
|
|
195
209
|
map: 'install',
|
|
196
210
|
unmap: 'uninstall'
|
|
@@ -541,6 +555,7 @@ module JSS
|
|
|
541
555
|
|
|
542
556
|
# @return [String] the message shown the user at policy end
|
|
543
557
|
attr_reader :user_message_finish
|
|
558
|
+
alias user_message_end user_message_finish
|
|
544
559
|
|
|
545
560
|
# @return [Hash]
|
|
546
561
|
#
|
|
@@ -604,7 +619,6 @@ module JSS
|
|
|
604
619
|
|
|
605
620
|
if @in_jss
|
|
606
621
|
gen = @init_data[:general]
|
|
607
|
-
@frequency = gen[:frequency]
|
|
608
622
|
@target_drive = gen[:target_drive]
|
|
609
623
|
@offline = gen[:offline]
|
|
610
624
|
@enabled = gen[:enabled]
|
|
@@ -620,6 +634,10 @@ module JSS
|
|
|
620
634
|
trigger_enrollment_complete: gen[:trigger_enrollment_complete],
|
|
621
635
|
trigger_other: gen[:trigger_other]
|
|
622
636
|
}
|
|
637
|
+
@frequency = gen[:frequency]
|
|
638
|
+
@retry_event = gen[:retry_event]
|
|
639
|
+
@retry_attempts = gen[:retry_attempts]
|
|
640
|
+
@notify_failed_retries = gen[:notify_on_each_failed_retry]
|
|
623
641
|
|
|
624
642
|
dtl = gen[:date_time_limitations]
|
|
625
643
|
|
|
@@ -670,6 +688,7 @@ module JSS
|
|
|
670
688
|
@disk_encryption = @init_data[:disk_encryption]
|
|
671
689
|
|
|
672
690
|
@printers = @init_data[:printers]
|
|
691
|
+
@printers.shift
|
|
673
692
|
|
|
674
693
|
# Not in jss yet
|
|
675
694
|
end
|
|
@@ -735,8 +754,93 @@ module JSS
|
|
|
735
754
|
# @return [void]
|
|
736
755
|
#
|
|
737
756
|
def frequency=(freq)
|
|
738
|
-
raise JSS::InvalidDataError, "New frequency must be one of :#{FREQUENCIES.keys.join ', :'}" unless FREQUENCIES.key?(freq)
|
|
739
|
-
|
|
757
|
+
raise JSS::InvalidDataError, "New frequency must be one of :#{FREQUENCIES.keys.join ', :'}" unless FREQUENCIES.key?(freq) || FREQUENCIES.value?(freq)
|
|
758
|
+
|
|
759
|
+
freq = freq.is_a?(Symbol) ? FREQUENCIES[freq] : freq
|
|
760
|
+
return if freq == @frequency
|
|
761
|
+
|
|
762
|
+
@frequency = freq
|
|
763
|
+
@need_to_update = true
|
|
764
|
+
end
|
|
765
|
+
|
|
766
|
+
# @return [String] The event that causes a policy retry
|
|
767
|
+
def retry_event
|
|
768
|
+
return RETRY_EVENTS[:none] unless FREQUENCIES[:once_per_computer] == @frequency
|
|
769
|
+
|
|
770
|
+
@retry_event
|
|
771
|
+
end
|
|
772
|
+
|
|
773
|
+
# Set the event that causes a retry if the policy fails.
|
|
774
|
+
# One of the ways to turn off policy retry is to set this to :none
|
|
775
|
+
# The other is to set the retry_attempts to 0
|
|
776
|
+
#
|
|
777
|
+
# @param [Symbol, String] A key or value from RETRY_EVENTS
|
|
778
|
+
# @return [void]
|
|
779
|
+
#
|
|
780
|
+
def retry_event=(evt)
|
|
781
|
+
validate_retry_opt
|
|
782
|
+
raise JSS::InvalidDataError, "Retry event must be one of :#{RETRY_EVENTS.keys.join ', :'}" unless RETRY_EVENTS.key?(evt) || RETRY_EVENTS.value?(evt)
|
|
783
|
+
|
|
784
|
+
evt = evt.is_a?(Symbol) ? RETRY_EVENTS[evt] : evt
|
|
785
|
+
return if evt == @retry_event
|
|
786
|
+
|
|
787
|
+
# if the event is not 'none' and attempts is <= 0,
|
|
788
|
+
# set events to 1, or the API won't accept it
|
|
789
|
+
unless evt == RETRY_EVENTS[:none]
|
|
790
|
+
@retry_attempts = 1 unless @retry_attempts.positive?
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
@retry_event = evt
|
|
794
|
+
@need_to_update = true
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
# @return [Integer] How many times wil the policy be retried if it fails.
|
|
798
|
+
# -1 means no retries, otherwise, an integer from 1 to 10
|
|
799
|
+
def retry_attempts
|
|
800
|
+
return 0 unless FREQUENCIES[:once_per_computer] == @frequency
|
|
801
|
+
|
|
802
|
+
@retry_attempts
|
|
803
|
+
end
|
|
804
|
+
|
|
805
|
+
# Set the number of times to retry if the policy fails.
|
|
806
|
+
# One of the ways to turn off policy retry is to set this to 0 or -1
|
|
807
|
+
# The other is to set retry_event to :none
|
|
808
|
+
#
|
|
809
|
+
# @param [Integer] From -1 to 10
|
|
810
|
+
# @return [void]
|
|
811
|
+
#
|
|
812
|
+
def retry_attempts=(int)
|
|
813
|
+
validate_retry_opt
|
|
814
|
+
raise JSS::InvalidDataError, 'Retry attempts must be an integer from 0-10' unless int.is_a?(Integer) && (-1..10).include?(int)
|
|
815
|
+
|
|
816
|
+
# if zero or -1, turn off retries
|
|
817
|
+
if int <= 0
|
|
818
|
+
@retry_event = RETRY_EVENTS[:none]
|
|
819
|
+
int = -1
|
|
820
|
+
end
|
|
821
|
+
return if @retry_attempts == int
|
|
822
|
+
|
|
823
|
+
@retry_attempts = int
|
|
824
|
+
@need_to_update = true
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
# @return [Boolean] Should admins be notified of failed retry attempts
|
|
828
|
+
def notify_failed_retries?
|
|
829
|
+
return false unless FREQUENCIES[:once_per_computer] == @frequency
|
|
830
|
+
|
|
831
|
+
@notify_failed_retries
|
|
832
|
+
end
|
|
833
|
+
alias notify_failed_retries notify_failed_retries?
|
|
834
|
+
alias notify_on_each_failed_retry notify_failed_retries?
|
|
835
|
+
|
|
836
|
+
# @param bool[Boolean] Should admins be notified of failed retry attempts
|
|
837
|
+
# @return [void]
|
|
838
|
+
def notify_failed_retries=(bool)
|
|
839
|
+
validate_retry_opt
|
|
840
|
+
bool = JSS::Validate.boolean bool
|
|
841
|
+
return if @notify_failed_retries == bool
|
|
842
|
+
|
|
843
|
+
@notify_failed_retries = bool
|
|
740
844
|
@need_to_update = true
|
|
741
845
|
end
|
|
742
846
|
|
|
@@ -914,6 +1018,30 @@ module JSS
|
|
|
914
1018
|
end
|
|
915
1019
|
alias message= reboot_message=
|
|
916
1020
|
|
|
1021
|
+
# Set User Start Message
|
|
1022
|
+
#
|
|
1023
|
+
# @param user_message[String] Text of User Message
|
|
1024
|
+
#
|
|
1025
|
+
# @return [void] description of returned object
|
|
1026
|
+
def user_message_start=(message)
|
|
1027
|
+
raise JSS::InvalidDataError, 'User message must be a String' unless message.is_a? String
|
|
1028
|
+
@user_message_start = message
|
|
1029
|
+
@need_to_update = true
|
|
1030
|
+
end
|
|
1031
|
+
|
|
1032
|
+
# Set User Finish Message
|
|
1033
|
+
#
|
|
1034
|
+
# @param user_message[String] Text of User Message
|
|
1035
|
+
#
|
|
1036
|
+
# @return [void] description of returned object
|
|
1037
|
+
def user_message_end=(message)
|
|
1038
|
+
raise JSS::InvalidDataError, 'User message must be a String' unless message.is_a? String
|
|
1039
|
+
@user_message_finish = message
|
|
1040
|
+
@need_to_update = true
|
|
1041
|
+
end
|
|
1042
|
+
|
|
1043
|
+
alias user_message_finish= user_message_end=
|
|
1044
|
+
|
|
917
1045
|
# Set Startup Disk
|
|
918
1046
|
# Only Supports 'Specify Local Startup Disk' at the moment
|
|
919
1047
|
#
|
|
@@ -1180,7 +1308,7 @@ module JSS
|
|
|
1180
1308
|
|
|
1181
1309
|
# Remove a package from this policy by name or id
|
|
1182
1310
|
#
|
|
1183
|
-
# @param
|
|
1311
|
+
# @param identifier [String,Integer] the name or id of the package to remove
|
|
1184
1312
|
#
|
|
1185
1313
|
# @return [Array, nil] the new packages array or nil if no change
|
|
1186
1314
|
#
|
|
@@ -1270,7 +1398,7 @@ module JSS
|
|
|
1270
1398
|
|
|
1271
1399
|
# Remove a script from this policy by name or id
|
|
1272
1400
|
#
|
|
1273
|
-
# @param
|
|
1401
|
+
# @param identifier [String,Integer] the name or id of the script to remove
|
|
1274
1402
|
#
|
|
1275
1403
|
# @return [Array, nil] the new scripts array or nil if no change
|
|
1276
1404
|
#
|
|
@@ -1292,6 +1420,49 @@ module JSS
|
|
|
1292
1420
|
@directory_bindings.map { |p| p[:name] }
|
|
1293
1421
|
end
|
|
1294
1422
|
|
|
1423
|
+
# Add a Directory Bidning to the list of directory_bindings handled by this policy.
|
|
1424
|
+
# If the directory binding already exists in the policy, nil is returned and
|
|
1425
|
+
# no changes are made.
|
|
1426
|
+
#
|
|
1427
|
+
# @param [String,Integer] identifier the name or id of the directory binding to add to this policy
|
|
1428
|
+
#
|
|
1429
|
+
# @param position [Symbol, Integer] where to add this directory binding among the list of
|
|
1430
|
+
# directory_bindings. Zero-based, :start and 0 are the same, as are :end and -1.
|
|
1431
|
+
# Defaults to :end
|
|
1432
|
+
#
|
|
1433
|
+
# @return [Array, nil] the new @directory_bindings array, nil if directory_binding was already in the policy
|
|
1434
|
+
#
|
|
1435
|
+
def add_directory_binding(identifier, **opts)
|
|
1436
|
+
id = validate_directory_binding_opts identifier, opts
|
|
1437
|
+
|
|
1438
|
+
return nil if @directory_bindings.map { |s| s[:id] }.include? id
|
|
1439
|
+
|
|
1440
|
+
name = JSS::DirectoryBinding.map_all_ids_to(:name, api: @api)[id]
|
|
1441
|
+
|
|
1442
|
+
directory_binding_data = {
|
|
1443
|
+
id: id,
|
|
1444
|
+
name: name
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
@directory_bindings.insert opts[:position], directory_binding_data
|
|
1448
|
+
|
|
1449
|
+
@need_to_update = true
|
|
1450
|
+
@directory_bindings
|
|
1451
|
+
end
|
|
1452
|
+
|
|
1453
|
+
|
|
1454
|
+
# Remove a directory binding from this policy by name or id
|
|
1455
|
+
#
|
|
1456
|
+
# @param identifier [String,Integer] the name or id of the directory binding to remove
|
|
1457
|
+
#
|
|
1458
|
+
# @return [Array, nil] the new directory bindings array or nil if no change
|
|
1459
|
+
#
|
|
1460
|
+
def remove_directory_binding(identifier)
|
|
1461
|
+
removed = @directory_bindings.delete_if { |s| s[:id] == identifier || s[:name] == identifier }
|
|
1462
|
+
@need_to_update = true if removed
|
|
1463
|
+
removed
|
|
1464
|
+
end
|
|
1465
|
+
|
|
1295
1466
|
###### Dock items
|
|
1296
1467
|
|
|
1297
1468
|
# @return [Array] the id's of the dock_items handled by the policy
|
|
@@ -1304,6 +1475,86 @@ module JSS
|
|
|
1304
1475
|
@dock_items.map { |p| p[:name] }
|
|
1305
1476
|
end
|
|
1306
1477
|
|
|
1478
|
+
|
|
1479
|
+
###### Printers
|
|
1480
|
+
|
|
1481
|
+
# Add a specific printer object to the policy.
|
|
1482
|
+
#
|
|
1483
|
+
# @author Tyler Morgan
|
|
1484
|
+
#
|
|
1485
|
+
# @param newvalue [String,Integer] The name or the id of the printer to be added to this policy.
|
|
1486
|
+
#
|
|
1487
|
+
# @param position [Symbol, Integer] where to add this printer object among the list of printer
|
|
1488
|
+
# objects. Zero-based, :start and 0 are the same, as are :end and -1.
|
|
1489
|
+
# Defaults to :end
|
|
1490
|
+
#
|
|
1491
|
+
# @param action [Symbol] One of the PRINTER_ACTIONS symbols. What you want done with the printer object upon policy execution.
|
|
1492
|
+
#
|
|
1493
|
+
# @param make_default [TrueClass,FalseClass] Should this printer object be set to default.
|
|
1494
|
+
# Defaults to false
|
|
1495
|
+
#
|
|
1496
|
+
# @return [String] The new printers array or nil if the printer was already in the policy
|
|
1497
|
+
def add_printer(identifier, **opts)
|
|
1498
|
+
id = validate_printer_opts identifier, opts
|
|
1499
|
+
|
|
1500
|
+
return nil if @printers.map { |p| p[:id] }.include? id
|
|
1501
|
+
|
|
1502
|
+
name = JSS::Printer.map_all_ids_to(:name, api: @api)[id]
|
|
1503
|
+
|
|
1504
|
+
printer_data = {
|
|
1505
|
+
id: id,
|
|
1506
|
+
name: name,
|
|
1507
|
+
action: PRINTER_ACTIONS[opts[:action]],
|
|
1508
|
+
make_default: opts[:make_default]
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
@printers.insert opts[:position], printer_data
|
|
1512
|
+
|
|
1513
|
+
@need_to_update = true
|
|
1514
|
+
@printers
|
|
1515
|
+
end
|
|
1516
|
+
|
|
1517
|
+
|
|
1518
|
+
# Remove a specific printer object from the policy.
|
|
1519
|
+
#
|
|
1520
|
+
# @author Tyler Morgan
|
|
1521
|
+
#
|
|
1522
|
+
# @param identifier [String,Integer] The name or id of the printer to be removed.
|
|
1523
|
+
#
|
|
1524
|
+
# @return [Array, nil] The new printers array or nil if no change.
|
|
1525
|
+
def remove_printer(identifier)
|
|
1526
|
+
removed = @printers.delete_if { |p| p[:id] == identifier || p[:name] == identifier }
|
|
1527
|
+
|
|
1528
|
+
@need_to_update = true
|
|
1529
|
+
removed
|
|
1530
|
+
end
|
|
1531
|
+
|
|
1532
|
+
# Add a dock item to the policy
|
|
1533
|
+
def add_dock_item(identifier, action)
|
|
1534
|
+
id = JSS::DockItem.valid_id identifier, api: @api
|
|
1535
|
+
|
|
1536
|
+
raise JSS::NoSuchItemError, "No Dock Item matches '#{identifier}'" unless id
|
|
1537
|
+
|
|
1538
|
+
raise JSS::InvalidDataError, "Action must be one of: :#{DOCK_ITEM_ACTIONS.keys.join ', :'}" unless DOCK_ITEM_ACTIONS.include? action
|
|
1539
|
+
|
|
1540
|
+
return nil if @dock_items.map { |d| d[:id] }.include? id
|
|
1541
|
+
|
|
1542
|
+
name = JSS::DockItem.map_all_ids_to(:name, api: @api)[id]
|
|
1543
|
+
|
|
1544
|
+
@dock_items << {id: id, name: name, action: DOCK_ITEM_ACTIONS[action]}
|
|
1545
|
+
|
|
1546
|
+
@need_to_update = true
|
|
1547
|
+
@dock_items
|
|
1548
|
+
end
|
|
1549
|
+
|
|
1550
|
+
# Remove a dock item from the policy
|
|
1551
|
+
def remove_dock_item(identifier)
|
|
1552
|
+
# TODO: Add validation against JSS::DockItem
|
|
1553
|
+
removed = @dock_items.delete_if { |d| d[:id] == identifier || d[:name] == identifier }
|
|
1554
|
+
@need_to_update = true if removed
|
|
1555
|
+
removed
|
|
1556
|
+
end
|
|
1557
|
+
|
|
1307
1558
|
# @return [Array] the id's of the printers handled by the policy
|
|
1308
1559
|
def printer_ids
|
|
1309
1560
|
begin
|
|
@@ -1312,7 +1563,7 @@ module JSS
|
|
|
1312
1563
|
return []
|
|
1313
1564
|
end
|
|
1314
1565
|
end
|
|
1315
|
-
|
|
1566
|
+
|
|
1316
1567
|
# @return [Array] the names of the printers handled by the policy
|
|
1317
1568
|
def printer_names
|
|
1318
1569
|
begin
|
|
@@ -1322,6 +1573,130 @@ module JSS
|
|
|
1322
1573
|
end
|
|
1323
1574
|
end
|
|
1324
1575
|
|
|
1576
|
+
|
|
1577
|
+
|
|
1578
|
+
###### Disk Encryption
|
|
1579
|
+
|
|
1580
|
+
# Sets the Disk Encryption application to "Remediate" and sets the remediation key type to individual.
|
|
1581
|
+
#
|
|
1582
|
+
# @author Tyler Morgan
|
|
1583
|
+
#
|
|
1584
|
+
# @return [Void]
|
|
1585
|
+
#
|
|
1586
|
+
def reissue_key()
|
|
1587
|
+
if @disk_encryption[:action] != DISK_ENCRYPTION_ACTIONS[:remediate]
|
|
1588
|
+
# Setting New Action
|
|
1589
|
+
hash = {
|
|
1590
|
+
action: DISK_ENCRYPTION_ACTIONS[:remediate],
|
|
1591
|
+
remediate_key_type: "Individual"
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
@disk_encryption = hash
|
|
1595
|
+
@need_to_update = true
|
|
1596
|
+
|
|
1597
|
+
else
|
|
1598
|
+
# Update
|
|
1599
|
+
return
|
|
1600
|
+
end
|
|
1601
|
+
|
|
1602
|
+
end
|
|
1603
|
+
|
|
1604
|
+
|
|
1605
|
+
# Sets the Disk Encryption application to "Apply" and sets the correct disk encryption configuration ID using either the name or id.
|
|
1606
|
+
#
|
|
1607
|
+
# @author Tyler Morgan
|
|
1608
|
+
#
|
|
1609
|
+
# @return [Void]
|
|
1610
|
+
#
|
|
1611
|
+
def apply_encryption_configuration(identifier)
|
|
1612
|
+
|
|
1613
|
+
id = JSS::DiskEncryptionConfiguration.valid_id identifier
|
|
1614
|
+
|
|
1615
|
+
return if id.nil?
|
|
1616
|
+
|
|
1617
|
+
hash = {
|
|
1618
|
+
action: DISK_ENCRYPTION_ACTIONS[:apply],
|
|
1619
|
+
disk_encryption_configuration_id: id,
|
|
1620
|
+
auth_restart: false
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
@disk_encryption = hash
|
|
1624
|
+
@need_to_update = true
|
|
1625
|
+
end
|
|
1626
|
+
|
|
1627
|
+
|
|
1628
|
+
# Removes the Disk Encryption settings associated with this specific policy.
|
|
1629
|
+
#
|
|
1630
|
+
# @author Tyler Morgan
|
|
1631
|
+
#
|
|
1632
|
+
# @return [Void]
|
|
1633
|
+
#
|
|
1634
|
+
def remove_encryption_configuration()
|
|
1635
|
+
hash = {
|
|
1636
|
+
action: DISK_ENCRYPTION_ACTIONS[:none]
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
@disk_encryption = hash
|
|
1640
|
+
@need_to_update = true
|
|
1641
|
+
end
|
|
1642
|
+
|
|
1643
|
+
# Interact with management account settings
|
|
1644
|
+
#
|
|
1645
|
+
# @param action [Key] one of the MGMT_ACCOUNT_ACTIONS keys
|
|
1646
|
+
#
|
|
1647
|
+
# @return The current specified management settings.
|
|
1648
|
+
#
|
|
1649
|
+
# Reference: https://developer.jamf.com/documentation#resources-with-passwords
|
|
1650
|
+
#
|
|
1651
|
+
def set_management_account(action, **opts)
|
|
1652
|
+
# TODO: Add proper error handling
|
|
1653
|
+
raise JSS::InvalidDataError, "Action must be one of: :#{MGMT_ACCOUNT_ACTIONS.keys.join ', :'}" unless MGMT_ACCOUNT_ACTIONS.include? action
|
|
1654
|
+
|
|
1655
|
+
management_data = {}
|
|
1656
|
+
|
|
1657
|
+
if action == :change_pw || action == :reset_pw
|
|
1658
|
+
raise JSS::MissingDataError, ":password must be provided when changing management account password" if opts[:password].nil?
|
|
1659
|
+
|
|
1660
|
+
management_data = {
|
|
1661
|
+
action: MGMT_ACCOUNT_ACTIONS[action],
|
|
1662
|
+
managed_password: opts[:password]
|
|
1663
|
+
}
|
|
1664
|
+
elsif action == :reset_random || action == :generate_pw
|
|
1665
|
+
raise JSS::MissingDataError, ":password_length must be provided when setting a random password" if opts[:password_length].nil?
|
|
1666
|
+
raise JSS::InvalidDataError, ":password_length must be an Integer" unless opts[:password_length].is_a? Integer
|
|
1667
|
+
|
|
1668
|
+
management_data = {
|
|
1669
|
+
action: MGMT_ACCOUNT_ACTIONS[action],
|
|
1670
|
+
managed_password_length: opts[:password_length]
|
|
1671
|
+
}
|
|
1672
|
+
else
|
|
1673
|
+
management_data = {
|
|
1674
|
+
action: MGMT_ACCOUNT_ACTIONS[action]
|
|
1675
|
+
}
|
|
1676
|
+
end
|
|
1677
|
+
|
|
1678
|
+
@management_account = management_data
|
|
1679
|
+
|
|
1680
|
+
@need_to_update = true
|
|
1681
|
+
|
|
1682
|
+
@management_account
|
|
1683
|
+
|
|
1684
|
+
end
|
|
1685
|
+
|
|
1686
|
+
# Check if management password matches provided password
|
|
1687
|
+
#
|
|
1688
|
+
# @param password[String] the password that is SHA256'ed to compare to the one from the API.
|
|
1689
|
+
#
|
|
1690
|
+
# @return [Boolean] The result of the comparison of the management password and provided text.
|
|
1691
|
+
#
|
|
1692
|
+
def verify_management_password(password)
|
|
1693
|
+
raise JSS::InvalidDataError, "Management password must be a string." unless password.is_a? String
|
|
1694
|
+
|
|
1695
|
+
raise JSS::UnsupportedError, "'#{@management_account[:action].to_s}' does not support management passwords." unless @management_account[:action] == MGMT_ACCOUNT_ACTIONS[:change_pw] || @management_account[:action] == MGMT_ACCOUNT_ACTIONS[:reset_pw]
|
|
1696
|
+
|
|
1697
|
+
return Digest::SHA256.hexdigest(password).to_s == @management_account[:managed_password_sha256].to_s
|
|
1698
|
+
end
|
|
1699
|
+
|
|
1325
1700
|
###### Actions
|
|
1326
1701
|
|
|
1327
1702
|
# Try to execute this policy on this machine.
|
|
@@ -1375,6 +1750,17 @@ module JSS
|
|
|
1375
1750
|
|
|
1376
1751
|
private
|
|
1377
1752
|
|
|
1753
|
+
# raise an error if a trying to set retry options when
|
|
1754
|
+
# frequency is not 'once per comptuer'
|
|
1755
|
+
#
|
|
1756
|
+
# @return [void]
|
|
1757
|
+
#
|
|
1758
|
+
def validate_retry_opt
|
|
1759
|
+
return if FREQUENCIES[:once_per_computer] == @frequency
|
|
1760
|
+
|
|
1761
|
+
raise JSS::UnsupportedError, 'Policy retry is only available when frequency is set to :once_per_computer'
|
|
1762
|
+
end
|
|
1763
|
+
|
|
1378
1764
|
# raise an error if a package being added isn't valid
|
|
1379
1765
|
#
|
|
1380
1766
|
# @see #add_package
|
|
@@ -1439,6 +1825,64 @@ module JSS
|
|
|
1439
1825
|
id
|
|
1440
1826
|
end
|
|
1441
1827
|
|
|
1828
|
+
# raise an error if the directory binding being added isn't valid
|
|
1829
|
+
#
|
|
1830
|
+
# @see #add_directory_binding
|
|
1831
|
+
#
|
|
1832
|
+
# @return [Integer, nil] the valid id for the package
|
|
1833
|
+
#
|
|
1834
|
+
def validate_directory_binding_opts(identifier, opts)
|
|
1835
|
+
opts[:position] ||= -1
|
|
1836
|
+
|
|
1837
|
+
opts[:position] =
|
|
1838
|
+
case opts[:position]
|
|
1839
|
+
when :start then 0
|
|
1840
|
+
when :end then -1
|
|
1841
|
+
else JSS::Validate.integer(opts[:position])
|
|
1842
|
+
end
|
|
1843
|
+
|
|
1844
|
+
# if the given position is past the end, set it to -1 (the end)
|
|
1845
|
+
opts[:position] = -1 if opts[:position] > @directory_bindings.size
|
|
1846
|
+
|
|
1847
|
+
id = JSS::DirectoryBinding.valid_id identifier, api: @api
|
|
1848
|
+
raise JSS::NoSuchItemError, "No directory binding matches '#{identifier}'" unless id
|
|
1849
|
+
id
|
|
1850
|
+
end
|
|
1851
|
+
|
|
1852
|
+
# Raises an error if the printer being added isn't valid, additionally checks the options and sets defaults where possible.
|
|
1853
|
+
#
|
|
1854
|
+
# @see #add_printer
|
|
1855
|
+
#
|
|
1856
|
+
# @return [Integer, nil] the valid id for the package
|
|
1857
|
+
#
|
|
1858
|
+
def validate_printer_opts(identifier, opts)
|
|
1859
|
+
opts[:position] ||= -1
|
|
1860
|
+
|
|
1861
|
+
opts[:position] =
|
|
1862
|
+
case opts[:position]
|
|
1863
|
+
when :start then 0
|
|
1864
|
+
when :end then -1
|
|
1865
|
+
else JSS::Validate.integer(opts[:position])
|
|
1866
|
+
end
|
|
1867
|
+
|
|
1868
|
+
# If the given position is past the end, set it to -1 (the end)
|
|
1869
|
+
opts[:position] = -1 if opts[:position] > @printers.size
|
|
1870
|
+
|
|
1871
|
+
# Checks if action to be done with the printer object is provided and valid.
|
|
1872
|
+
raise JSS::MissingDataError, "action must be provided, must be one of :#{PRINTER_ACTIONS.keys.join(':,')}." if opts[:action].nil?
|
|
1873
|
+
raise JSS::InvalidDataError, "action must be one of :#{PRINTER_ACTIONS.keys.join(',:')}." unless PRINTER_ACTIONS.keys.include? opts[:action]
|
|
1874
|
+
|
|
1875
|
+
|
|
1876
|
+
# Checks if the make_default option is valid, and sets the default if needed.
|
|
1877
|
+
raise JSS::InvalidDataError, "make_default must be either true or false." unless opts[:make_default].is_a?(TrueClass) || opts[:make_default].is_a?(FalseClass) || opts[:make_default].nil?
|
|
1878
|
+
|
|
1879
|
+
opts[:make_default] = false if opts[:make_default].nil?
|
|
1880
|
+
|
|
1881
|
+
id = JSS::Printer.valid_id identifier, api: @api
|
|
1882
|
+
raise JSS::NoSuchItemError, "No printer matches '#{identifier}'" unless id
|
|
1883
|
+
id
|
|
1884
|
+
end
|
|
1885
|
+
|
|
1442
1886
|
def rest_xml
|
|
1443
1887
|
doc = REXML::Document.new APIConnection::XML_HEADER
|
|
1444
1888
|
obj = doc.add_element RSRC_OBJECT_KEY.to_s
|
|
@@ -1447,6 +1891,10 @@ module JSS
|
|
|
1447
1891
|
general.add_element('name').text = @name
|
|
1448
1892
|
general.add_element('enabled').text = @enabled
|
|
1449
1893
|
general.add_element('frequency').text = @frequency
|
|
1894
|
+
general.add_element('retry_event').text = @retry_event
|
|
1895
|
+
general.add_element('retry_attempts').text = @retry_attempts.to_s
|
|
1896
|
+
general.add_element('notify_on_each_failed_retry').text = @notify_failed_retries.to_s
|
|
1897
|
+
|
|
1450
1898
|
general.add_element('target_drive').text = @target_drive
|
|
1451
1899
|
general.add_element('offline').text = @offline
|
|
1452
1900
|
|
|
@@ -1475,6 +1923,22 @@ module JSS
|
|
|
1475
1923
|
maint.add_element('user_cache').text = @user_cache.to_s
|
|
1476
1924
|
maint.add_element('verify').text = @verify_startup_disk.to_s
|
|
1477
1925
|
|
|
1926
|
+
acct_maint = obj.add_element 'account_maintenance'
|
|
1927
|
+
|
|
1928
|
+
mgmt_acct = acct_maint.add_element 'management_account'
|
|
1929
|
+
JSS.hash_to_rexml_array(@management_account).each { |x| mgmt_acct << x }
|
|
1930
|
+
|
|
1931
|
+
directory_bindings = acct_maint.add_element 'directory_bindings'
|
|
1932
|
+
@directory_bindings.each do |b|
|
|
1933
|
+
directory_binding = directory_bindings.add_element 'binding'
|
|
1934
|
+
dbdeets = JSS.hash_to_rexml_array b
|
|
1935
|
+
dbdeets.each { |d| directory_binding << d }
|
|
1936
|
+
end
|
|
1937
|
+
|
|
1938
|
+
user_interaction = obj.add_element 'user_interaction'
|
|
1939
|
+
user_interaction.add_element('message_start').text = @user_message_start.to_s
|
|
1940
|
+
user_interaction.add_element('message_finish').text = @user_message_finish.to_s
|
|
1941
|
+
|
|
1478
1942
|
files_processes = obj.add_element 'files_processes'
|
|
1479
1943
|
JSS.hash_to_rexml_array(@files_processes).each { |f| files_processes << f }
|
|
1480
1944
|
|
|
@@ -1493,6 +1957,26 @@ module JSS
|
|
|
1493
1957
|
sdeets.each { |d| script << d }
|
|
1494
1958
|
end
|
|
1495
1959
|
|
|
1960
|
+
disk_encryption = obj.add_element 'disk_encryption'
|
|
1961
|
+
|
|
1962
|
+
@disk_encryption.each do |k,v|
|
|
1963
|
+
disk_encryption.add_element(k.to_s).text = v.to_s
|
|
1964
|
+
end
|
|
1965
|
+
|
|
1966
|
+
printers = obj.add_element 'printers'
|
|
1967
|
+
@printers.each do |pr|
|
|
1968
|
+
printer = printers.add_element 'printer'
|
|
1969
|
+
pdeets = JSS.hash_to_rexml_array pr
|
|
1970
|
+
pdeets.each { |d| printer << d }
|
|
1971
|
+
end
|
|
1972
|
+
|
|
1973
|
+
dock_items = obj.add_element 'dock_items'
|
|
1974
|
+
@dock_items.each do |d|
|
|
1975
|
+
dock_item = dock_items.add_element 'dock_item'
|
|
1976
|
+
ddeets = JSS.hash_to_rexml_array d
|
|
1977
|
+
ddeets.each { |de| dock_item << de }
|
|
1978
|
+
end
|
|
1979
|
+
|
|
1496
1980
|
add_self_service_xml doc
|
|
1497
1981
|
add_site_to_xml doc
|
|
1498
1982
|
|