ruby-jss 4.2.0b2 → 4.2.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.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +44 -7
  3. data/README-2.0.0.md +19 -8
  4. data/README.md +43 -30
  5. data/lib/jamf/api/classic/api_objects/patch_title.rb +0 -2
  6. data/lib/jamf/api/jamf_pro/api_objects/api_client.rb +3 -0
  7. data/lib/jamf/api/jamf_pro/api_objects/api_role.rb +3 -0
  8. data/lib/jamf/api/jamf_pro/api_objects/j_package.rb +333 -119
  9. data/lib/jamf/api/jamf_pro/api_objects/managed_software_updates/plan.rb +237 -0
  10. data/lib/jamf/api/jamf_pro/api_objects/managed_software_updates.rb +291 -0
  11. data/lib/jamf/api/jamf_pro/base_classes/oapi_object.rb +24 -3
  12. data/lib/jamf/api/jamf_pro/mixins/collection_resource.rb +23 -3
  13. data/lib/jamf/api/jamf_pro/mixins/filterable.rb +8 -0
  14. data/lib/jamf/api/jamf_pro/mixins/jpapi_resource.rb +17 -3
  15. data/lib/jamf/api/jamf_pro/mixins/macos_managed_updates.rb +2 -0
  16. data/lib/jamf/api/jamf_pro/mixins/prestage.rb +3 -0
  17. data/lib/jamf/api/jamf_pro/oapi_schemas/account_group.rb +123 -0
  18. data/lib/jamf/api/jamf_pro/oapi_schemas/account_preferences_v1.rb +105 -0
  19. data/lib/jamf/api/jamf_pro/oapi_schemas/assign_remove_profile_response_sync_state.rb +112 -0
  20. data/lib/jamf/api/jamf_pro/oapi_schemas/auth_account_v1.rb +159 -0
  21. data/lib/jamf/api/jamf_pro/oapi_schemas/authentication_type.rb +97 -0
  22. data/lib/jamf/api/jamf_pro/oapi_schemas/{device_enrollment_disown_body.rb → available_updates.rb} +14 -10
  23. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_application.rb +124 -0
  24. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_attachment.rb +102 -0
  25. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_certificate.rb +151 -0
  26. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_configuration_profile.rb +118 -0
  27. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_content_caching.rb +372 -0
  28. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_content_caching_alert.rb +120 -0
  29. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_content_caching_cache_detail.rb +97 -0
  30. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_content_caching_data_migration_error.rb +98 -0
  31. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_content_caching_data_migration_error_user_info.rb +89 -0
  32. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_content_caching_parent.rb +131 -0
  33. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_content_caching_parent_alert.rb +105 -0
  34. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_content_caching_parent_capabilities.rb +124 -0
  35. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_content_caching_parent_details.rb +118 -0
  36. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_content_caching_parent_local_network.rb +97 -0
  37. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_disk.rb +143 -0
  38. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_disk_encryption.rb +120 -0
  39. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_extension_attribute.rb +175 -0
  40. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_font.rb +93 -0
  41. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_general.rb +244 -0
  42. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_hardware.rb +264 -0
  43. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_ibeacon.rb +81 -0
  44. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_inventory.rb +276 -0
  45. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_inventory_file_vault.rb +127 -0
  46. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_licensed_software.rb +88 -0
  47. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_local_user_account.rb +196 -0
  48. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_mdm_capability.rb +88 -0
  49. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_operating_system.rb +148 -0
  50. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_package_receipts.rb +97 -0
  51. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_partition.rb +145 -0
  52. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_partition_encryption.rb +94 -0
  53. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_partition_file_vault2_state.rb +97 -0
  54. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_plugin.rb +93 -0
  55. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_prestage_v3.rb +129 -0
  56. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_printer.rb +99 -0
  57. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_purchase.rb +158 -0
  58. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_remote_management.rb +88 -0
  59. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_section.rb +109 -0
  60. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_security.rb +193 -0
  61. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_service.rb +81 -0
  62. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_software_update.rb +93 -0
  63. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_storage.rb +90 -0
  64. data/lib/jamf/api/jamf_pro/oapi_schemas/computer_user_and_location.rb +131 -0
  65. data/lib/jamf/api/jamf_pro/oapi_schemas/dss_declaration.rb +111 -0
  66. data/lib/jamf/api/jamf_pro/oapi_schemas/dss_declarations.rb +88 -0
  67. data/lib/jamf/api/jamf_pro/oapi_schemas/enrollment_method.rb +97 -0
  68. data/lib/jamf/api/jamf_pro/oapi_schemas/group_membership.rb +94 -0
  69. data/lib/jamf/api/jamf_pro/oapi_schemas/inventory_preload_extension_attribute.rb +89 -0
  70. data/lib/jamf/api/jamf_pro/oapi_schemas/location_information.rb +146 -0
  71. data/lib/jamf/api/jamf_pro/oapi_schemas/{package_manifest.rb → location_information_v2.rb} +35 -37
  72. data/lib/jamf/api/jamf_pro/oapi_schemas/managed_software_update_plan.rb +181 -0
  73. data/lib/jamf/api/jamf_pro/oapi_schemas/managed_software_update_plan_event_store.rb +85 -0
  74. data/lib/jamf/api/jamf_pro/oapi_schemas/managed_software_update_plan_group_post.rb +99 -0
  75. data/lib/jamf/api/jamf_pro/oapi_schemas/managed_software_update_plan_post.rb +98 -0
  76. data/lib/jamf/api/jamf_pro/oapi_schemas/managed_software_update_plan_post_response.rb +100 -0
  77. data/lib/jamf/api/jamf_pro/oapi_schemas/managed_software_update_plan_toggle.rb +115 -0
  78. data/lib/jamf/api/jamf_pro/oapi_schemas/managed_software_update_plan_toggle_status.rb +169 -0
  79. data/lib/jamf/api/jamf_pro/oapi_schemas/managed_software_update_plan_toggle_status_wrapper.rb +91 -0
  80. data/lib/jamf/api/jamf_pro/oapi_schemas/managed_software_update_plans.rb +102 -0
  81. data/lib/jamf/api/jamf_pro/oapi_schemas/managed_software_update_status.rb +173 -0
  82. data/lib/jamf/api/jamf_pro/oapi_schemas/managed_software_update_statuses.rb +102 -0
  83. data/lib/jamf/api/jamf_pro/oapi_schemas/mobile_device_prestage_name_v2.rb +94 -0
  84. data/lib/jamf/api/jamf_pro/oapi_schemas/mobile_device_prestage_names_v2.rb +118 -0
  85. data/lib/jamf/api/jamf_pro/oapi_schemas/plan_configuration_post.rb +142 -0
  86. data/lib/jamf/api/jamf_pro/oapi_schemas/plan_device.rb +105 -0
  87. data/lib/jamf/api/jamf_pro/oapi_schemas/plan_device_post.rb +97 -0
  88. data/lib/jamf/api/jamf_pro/oapi_schemas/plan_device_response.rb +96 -0
  89. data/lib/jamf/api/jamf_pro/oapi_schemas/plan_group_post.rb +96 -0
  90. data/lib/jamf/api/jamf_pro/oapi_schemas/plan_search_results.rb +89 -0
  91. data/lib/jamf/api/jamf_pro/oapi_schemas/plan_status.rb +127 -0
  92. data/lib/jamf/api/jamf_pro/oapi_schemas/{device_enrollment_prestage.rb → prestage_purchasing_information.rb} +51 -88
  93. data/lib/jamf/api/jamf_pro/oapi_schemas/prestage_purchasing_information_v2.rb +174 -0
  94. data/lib/jamf/api/jamf_pro/oapi_schemas/prestage_scope_assignment_v2.rb +94 -0
  95. data/lib/jamf/api/jamf_pro/oapi_schemas/v1_site.rb +91 -0
  96. data/lib/jamf/api/jamf_pro/oapi_schemas.rb +24 -1
  97. data/lib/jamf/api/jamf_pro/other_classes/pager.rb +7 -1
  98. data/lib/jamf/composer.rb +114 -107
  99. data/lib/jamf/oapi_validate.rb +1 -0
  100. data/lib/jamf/utility.rb +20 -14
  101. data/lib/jamf/version.rb +1 -1
  102. data/test/bin/runtests +2 -2
  103. data/test/lib/jamf_test/collection_tests.rb +10 -2
  104. data/test/tests/computer_group.rb +29 -12
  105. data/test/tests/{jp_building.rb → j_building.rb} +2 -2
  106. data/test/tests/j_package.rb +47 -0
  107. metadata +87 -8
data/lib/jamf/composer.rb CHANGED
@@ -1,97 +1,104 @@
1
- ### Copyright 2025 Pixar
2
-
3
- ###
4
- ### Licensed under the Apache License, Version 2.0 (the "Apache License")
5
- ### with the following modification; you may not use this file except in
6
- ### compliance with the Apache License and the following modification to it:
7
- ### Section 6. Trademarks. is deleted and replaced with:
8
- ###
9
- ### 6. Trademarks. This License does not grant permission to use the trade
10
- ### names, trademarks, service marks, or product names of the Licensor
11
- ### and its affiliates, except as required to comply with Section 4(c) of
12
- ### the License and to reproduce the content of the NOTICE file.
13
- ###
14
- ### You may obtain a copy of the Apache License at
15
- ###
16
- ### http://www.apache.org/licenses/LICENSE-2.0
17
- ###
18
- ### Unless required by applicable law or agreed to in writing, software
19
- ### distributed under the Apache License with the above modification is
20
- ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
- ### KIND, either express or implied. See the Apache License for the specific
22
- ### language governing permissions and limitations under the Apache License.
23
- ###
24
- ###
25
-
26
- ###
1
+ # Copyright 2025 Pixar
2
+
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "Apache License")
5
+ # with the following modification; you may not use this file except in
6
+ # compliance with the Apache License and the following modification to it:
7
+ # Section 6. Trademarks. is deleted and replaced with:
8
+ #
9
+ # 6. Trademarks. This License does not grant permission to use the trade
10
+ # names, trademarks, service marks, or product names of the Licensor
11
+ # and its affiliates, except as required to comply with Section 4(c) of
12
+ # the License and to reproduce the content of the NOTICE file.
13
+ #
14
+ # You may obtain a copy of the Apache License at
15
+ #
16
+ # http://www.apache.org/licenses/LICENSE-2.0
17
+ #
18
+ # Unless required by applicable law or agreed to in writing, software
19
+ # distributed under the Apache License with the above modification is
20
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+ # KIND, either express or implied. See the Apache License for the specific
22
+ # language governing permissions and limitations under the Apache License.
23
+ #
24
+ #
25
+
27
26
  module Jamf
28
27
 
29
- ###
30
- ### This module provides two methods for building very simple Casper-happy .pkg and .dmg packages for deployment.
31
- ###
32
- ### Unlike Composer.app from JAMF, this module currently doesn't offer a way to do a before/after disk scan
33
- ### and use the differences to build the root folder from which the package is built. Nor does the module support
34
- ### editing the pre/post install scripts in .pkgs.
35
- ###
36
- ### The 'root folder', a folder representing the root filesystem of the target machine where the package will be installed,
37
- ### must already exist and be fully populated and with correct permissions.
38
- ###
28
+ # This module provides two methods for building very simple Casper-happy .pkg and .dmg
29
+ # packages for deployment.
30
+ #
31
+ # Unlike Composer.app from JAMF, this module currently doesn't offer a way to do a
32
+ # before/after disk scan
33
+ # and use the differences to build the root folder from which the package is built.
34
+ # Nor does the module support
35
+ # editing the pre/post install scripts in .pkgs.
36
+ #
37
+ # The 'root folder', a folder representing the root filesystem of the target machine
38
+ # where the package will be installed,
39
+ # must already exist and be fully populated and with correct permissions.
40
+ #
41
+ #
42
+ # TODO: Support building Distribution-style packages using the 'productbuild' tool,
43
+ # since they are needed for deploying packages via MDM - Component packages created
44
+ # by pkgbuild are not supported for MDM deployment.
45
+ #
39
46
  module Composer
40
47
 
41
48
  #####################################
42
- ### Constants
49
+ # Constants
43
50
  #####################################
44
51
 
45
- ### the apple pkgutil tool
52
+ # the apple pkgutil tool
46
53
  PKG_UTIL = Pathname.new '/usr/sbin/pkgutil'
47
54
 
48
- ### The location of the cli tool for making .pkgs
55
+ # The location of the cli tool for making .pkgs
49
56
  PKGBUILD = Pathname.new '/usr/bin/pkgbuild'
50
57
 
51
- ### the default bundle identifier prefix for pkgs
58
+ # the default bundle identifier prefix for pkgs
52
59
  PKG_BUNDLE_ID_PFX = 'ruby-jss-composer'.freeze
53
60
 
54
- ### Apple's hdiutil for making dmgs
61
+ # Apple's hdiutil for making dmgs
55
62
  HDI_UTIL = '/usr/bin/hdiutil'.freeze
56
63
 
57
- ### Where to save the output ?
64
+ # Where to save the output ?
58
65
  DEFAULT_OUT_DIR = Pathname.new '/Users/Shared'
59
66
 
60
- ### Make a casper-happy .pkg out of a root folder, permissions are assumed to be correct.
61
- ###
62
- ### @param name[String] the name of the .pkg. The .pkg suffix will be added if not present
63
- ###
64
- ### @param version[String] the version of the .pkg, needed for building the .pkg
65
- ###
66
- ### @param root[String, Pathname] the path to the 'root folder' representing
67
- ### the root file system of the target install drive
68
- ###
69
- ### @param opts[Hash] the options for building the .pkg
70
- ###
71
- ### @options opts :pkg_id[String] the full package if for the new pkg.
72
- ### e.g. 'com.mycompany.myapp'
73
- ###
74
- ### @option opts :bundle_id_prefix[String] the pkg bundle identifier prefix.
75
- ### If no :pkg_id is provided, one is made using this prefix and
76
- ### the name provided. e.g. 'com.mycompany'
77
- ### Defaults to '{PKG_BUNDLE_ID_PFX}'. See 'man pkgbuild' for more info
78
- ###
79
- ### @option opts :out_dir[String,Pathname] he folder in which the .pkg will be
80
- ### created. Defaults to {DEFAULT_OUT_DIR}
81
- ###
82
- ### @option opts :preserve_ownership[Boolean] If true, the owner/group of the
83
- ### rootpath are preserved.
84
- ### Default is false: they become the pkgbuild/installer 'recommended'
85
- ### (root/wheel or root/admin)
86
- ###
87
- ### @option opts :signing_identity[String] the optional name of the signing identity (certificate) to
88
- ### use for signing the pkg. See `man pkgbuild` for details
89
- ###
90
- ### @option opts :signing_options[String] the optional string of options to pass to pkgbuild.
91
- ### See `man pkgbuild` for details
92
- ###
93
- ### @return [Pathname] the local path to the new .pkg
94
- ###
67
+ # Make a casper-happy .pkg out of a root folder, permissions are assumed to be correct.
68
+ #
69
+ # @param name[String] the name of the .pkg. The .pkg suffix will be added if not present
70
+ #
71
+ # @param version[String] the version of the .pkg, needed for building the .pkg
72
+ #
73
+ # @param root[String, Pathname] the path to the 'root folder' representing
74
+ # the root file system of the target install drive
75
+ #
76
+ # @param opts[Hash] the options for building the .pkg
77
+ #
78
+ # @options opts :pkg_id[String] the full package if for the new pkg.
79
+ # e.g. 'com.mycompany.myapp'
80
+ #
81
+ # @option opts :bundle_id_prefix[String] the pkg bundle identifier prefix.
82
+ # If no :pkg_id is provided, one is made using this prefix and
83
+ # the name provided. e.g. 'com.mycompany'
84
+ # Defaults to '{PKG_BUNDLE_ID_PFX}'. See 'man pkgbuild' for more info
85
+ #
86
+ # @option opts :out_dir[String,Pathname] he folder in which the .pkg will be
87
+ # created. Defaults to {DEFAULT_OUT_DIR}
88
+ #
89
+ # @option opts :preserve_ownership[Boolean] If true, the owner/group of the
90
+ # rootpath are preserved.
91
+ # Default is false: they become the pkgbuild/installer 'recommended'
92
+ # (root/wheel or root/admin)
93
+ #
94
+ # @option opts :signing_identity[String] the optional name of the signing identity (certificate) to
95
+ # use for signing the pkg. See `man pkgbuild` for details
96
+ #
97
+ # @option opts :signing_options[String] the optional string of options to pass to pkgbuild.
98
+ # See `man pkgbuild` for details
99
+ #
100
+ # @return [Pathname] the local path to the new .pkg
101
+ #
95
102
  def self.mk_pkg(name, version, root, **opts)
96
103
  raise NoSuchItemError, "Missing pkgbuild tool. Please make sure you're running 10.8 or later." unless PKGBUILD.executable?
97
104
 
@@ -111,28 +118,28 @@ module Jamf
111
118
  signing = ''
112
119
  end # if opts[:signing_identity]
113
120
 
114
- ### first, run 'analyze' to get a 'component plist' in which we can change some settings
115
- ### for any bundles in the root (bundles like .apps, frameworks, plugins, etc..)
116
- ###
117
- ### we edit the settings thus:
118
- ### BundleOverwriteAction = upgrade, totally replace any version current on disk
119
- ### BundleIsVersionChecked = false, allow us to install regardless of what version is currently installed
120
- ### BundleIsRelocatable = false, if there's a version of this in some other location, Do Not move this one there after installation
121
- ### BundleHasStrictIdentifier = false, don't care if there's something at the install path with a different bundle id.
122
- ###
123
- ### In other words, just install the thing!
124
- ### (see 'man pkgbuild' for more info)
125
- ###
126
- ###
121
+ # first, run 'analyze' to get a 'component plist' in which we can change some settings
122
+ # for any bundles in the root (bundles like .apps, frameworks, plugins, etc..)
123
+ #
124
+ # we edit the settings thus:
125
+ # BundleOverwriteAction = upgrade, totally replace any version current on disk
126
+ # BundleIsVersionChecked = false, allow us to install regardless of what version is currently installed
127
+ # BundleIsRelocatable = false, if there's a version of this in some other location, Do Not move this one there after installation
128
+ # BundleHasStrictIdentifier = false, don't care if there's something at the install path with a different bundle id.
129
+ #
130
+ # In other words, just install the thing!
131
+ # (see 'man pkgbuild' for more info)
132
+ #
133
+ #
127
134
  comp_plist_out = Pathname.new "/tmp/#{PKG_BUNDLE_ID_PFX}-#{pkg_filename}.plist"
128
135
  system "#{PKGBUILD} --analyze --root '#{root}' '#{comp_plist_out}'"
129
136
  comp_plist = JSS.parse_plist comp_plist_out
130
137
 
131
- ### if the plist is empty, there are no bundles in the pkg
138
+ # if the plist is empty, there are no bundles in the pkg
132
139
  if comp_plist[0].nil?
133
140
  comp_plist_arg = ''
134
141
  else
135
- ### otherwise, edit the bundle dictionaries
142
+ # otherwise, edit the bundle dictionaries
136
143
  comp_plist.each do |bndl|
137
144
  bndl.delete 'ChildBundles' if bndl['ChildBundles']
138
145
  bndl['BundleOverwriteAction'] = 'upgrade'
@@ -140,12 +147,12 @@ module Jamf
140
147
  bndl['BundleIsRelocatable'] = false
141
148
  bndl['BundleHasStrictIdentifier'] = false
142
149
  end
143
- ### write out the edits
150
+ # write out the edits
144
151
  comp_plist_out.open('w') { |f| f.write JSS.xml_plist_from(comp_plist) }
145
152
  comp_plist_arg = "--component-plist '#{comp_plist_out}'"
146
153
  end
147
154
 
148
- ### now build the pkg
155
+ # now build the pkg
149
156
  begin
150
157
  it_built = system "#{PKGBUILD} --identifier '#{pkg_id}' --version '#{version}' --ownership #{pkg_ownership} --install-location / --root '#{root}' #{signing} #{comp_plist_arg} '#{pkg_out}'"
151
158
 
@@ -157,18 +164,18 @@ module Jamf
157
164
  Pathname.new pkg_out
158
165
  end # mk_dot_pkg
159
166
 
160
- ###
161
- ### Make a casper-happy .dmg out of a root folder, permissions are assumed to be correct.
162
- ###
163
- ### @param name[String] The name of the .dmg, the suffix will be added if needed
164
- ###
165
- ### @param root[String, Pathname] the path to the "root folder" representing the root file system of the target install drive
166
- ###
167
- ### @param out_dir[String, Pathname] the folder in which the .pkg will be created. Defaults to {DEFAULT_OUT_DIR}
168
- ###
169
- ### @return [Pathname] the local path to the new .dmg
170
- ###
171
- ###
167
+ #
168
+ # Make a casper-happy .dmg out of a root folder, permissions are assumed to be correct.
169
+ #
170
+ # @param name[String] The name of the .dmg, the suffix will be added if needed
171
+ #
172
+ # @param root[String, Pathname] the path to the "root folder" representing the root file system of the target install drive
173
+ #
174
+ # @param out_dir[String, Pathname] the folder in which the .pkg will be created. Defaults to {DEFAULT_OUT_DIR}
175
+ #
176
+ # @return [Pathname] the local path to the new .dmg
177
+ #
178
+ #
172
179
  def self.mk_dmg(name, root, out_dir = DEFAULT_OUT_DIR)
173
180
  dmg_filename = "#{name}.dmg"
174
181
  dmg_vol = name
@@ -178,7 +185,7 @@ module Jamf
178
185
  dmg_out.rename mv_to
179
186
  end # if dmg out exist
180
187
 
181
- ### TODO - this may need to be sudo'd to handle proper internal permissions.
188
+ # TODO: - this may need to be sudo'd to handle proper internal permissions.
182
189
  system "#{HDI_UTIL} create -volname '#{dmg_vol}' -scrub -srcfolder '#{root}' '#{dmg_out}'"
183
190
 
184
191
  raise 'There was an error building the .dmg' unless $?.exitstatus.zero?
@@ -163,6 +163,7 @@ module Jamf
163
163
 
164
164
  # try to instantiate the class with the value. It should raise an error
165
165
  # if not good
166
+ # TODO: Does this method name need to be in Jamf::JPAPIResource::NEW_CALLERS
166
167
  klass.new val
167
168
  rescue => e
168
169
  raise_invalid_data_error(msg || "#{attr_name} value must be a #{klass}, or #{klass}.new must accept it as the only parameter, but #{klass}.new raised: #{e.class}: #{e}")
data/lib/jamf/utility.rb CHANGED
@@ -65,27 +65,33 @@ module Jamf
65
65
  #
66
66
  # 12 is the default for the current OS and higher
67
67
  # (and hoping apple doesn't release, e.g., 11.13)
68
+ #
69
+ # There is no 16-25 because in 2025 Apple changed the numbering
70
+ # scheme to match the year after release. So the OS released in
71
+ # 2025 is versino 26, not 16.
72
+ #
73
+ # This array should take us thru to 2039.
68
74
  MAC_OS_MAXS = {
69
75
  11 => 12,
70
76
  12 => 12,
71
77
  13 => 12,
72
78
  14 => 12,
73
79
  15 => 12,
74
- 16 => 12,
75
- 17 => 12,
76
- 18 => 12,
77
- 19 => 12,
78
- 20 => 12,
79
- 21 => 12,
80
- 22 => 12,
81
- 23 => 12,
82
- 24 => 12,
83
- 25 => 12,
84
80
  26 => 12,
85
81
  27 => 12,
86
82
  28 => 12,
87
83
  29 => 12,
88
- 30 => 12
84
+ 30 => 12,
85
+ 31 => 12,
86
+ 32 => 12,
87
+ 33 => 12,
88
+ 34 => 12,
89
+ 35 => 12,
90
+ 36 => 12,
91
+ 37 => 12,
92
+ 38 => 12,
93
+ 39 => 12,
94
+ 40 => 12
89
95
  }
90
96
 
91
97
  # Converts an OS Version into an Array of equal or higher OS versions, up to
@@ -188,7 +194,7 @@ module Jamf
188
194
  # e.g. 11.x, or 11.x.x
189
195
  # expand to 11.x, 12.x, 13.x, ... 30.x
190
196
  if minor == 'x'
191
- ((major.to_i)..MAC_OS_MAXS.keys.max).each { |v| ok_oses << "#{v}.x" }
197
+ ((major.to_i)..MAC_OS_MAXS.keys.max).each { |v| ok_oses << "#{v}.x" unless (16..25).include?(v) } # skip 16-25
192
198
 
193
199
  # e.g. 11.2.x
194
200
  # expand to 11.2.x, 11.3.x, ... 11.12.x,
@@ -202,7 +208,7 @@ module Jamf
202
208
  end # each m
203
209
 
204
210
  # then add the majors out to 20
205
- ((major.to_i + 1)...MAC_OS_MAXS.keys.max).each { |v| ok_oses << "#{v}.x" }
211
+ ((major.to_i + 1)...MAC_OS_MAXS.keys.max).each { |v| ok_oses << "#{v}.x" unless (16..25).include?(v) }
206
212
 
207
213
  # e.g. 11.2.3
208
214
  # expand to 11.2.3, 11.2.4, ... 11.2.10,
@@ -219,7 +225,7 @@ module Jamf
219
225
  ((minor.to_i + 1)..max_minor_for_major).each { |min| ok_oses << "#{major}.#{min}.x" }
220
226
 
221
227
  # then add the majors out to 20
222
- ((major.to_i + 1)..MAC_OS_MAXS.keys.max).each { |v| ok_oses << "#{v}.x" }
228
+ ((major.to_i + 1)..MAC_OS_MAXS.keys.max).each { |v| ok_oses << "#{v}.x" unless (16..25).include?(v) }
223
229
  end
224
230
 
225
231
  ok_oses
data/lib/jamf/version.rb CHANGED
@@ -27,6 +27,6 @@
27
27
  module Jamf
28
28
 
29
29
  ### The version of ruby-jss
30
- VERSION = '4.2.0b2'.freeze
30
+ VERSION = '4.2.1'.freeze
31
31
 
32
32
  end # module
data/test/bin/runtests CHANGED
@@ -80,7 +80,7 @@ class App
80
80
  OPTS = GetoptLong.new(
81
81
  ['--host', '-h', GetoptLong::REQUIRED_ARGUMENT],
82
82
  ['--port', '-p', GetoptLong::REQUIRED_ARGUMENT],
83
- ['--re-save', '-r', GetoptLong::REQUIRED_ARGUMENT],
83
+ ['--re-save', '-r', GetoptLong::NO_ARGUMENT],
84
84
  ['--help', '-H', GetoptLong::NO_ARGUMENT]
85
85
  )
86
86
 
@@ -154,7 +154,7 @@ class App
154
154
 
155
155
  ###################################
156
156
  def connect
157
- JamfTest::Auth.delete_api_creds(@api_server) if @re_save_creds
157
+ JamfTest::Auth.delete_api_creds(host: @api_server) if @re_save_creds
158
158
  JamfTest::Auth.connect_to_api host: @api_server, port: @api_port
159
159
  end
160
160
 
@@ -329,9 +329,17 @@ module JamfTest
329
329
 
330
330
  ################
331
331
  def validate_fetched
332
- raise 'Original ruby object created with .create is not == to the one re-fetched after saving!' unless @fetched_new_object == @unsaved_new_object
332
+ # TODO: this doesn't work for some JPAPI classes, which compare sha1 hashes.
333
+ # See TODO in oapi_object.rb -> <=> method
333
334
 
334
- say "Fetched instance of #{collection_class} is == to the original one we made with .create"
335
+ if @unsaved_new_object.respond_to? :sha1_hash
336
+ say "unsaved_new_object instance of #{collection_class} sha1 is #{@unsaved_new_object.sha1_hash}"
337
+ say "fetched_new_object instance of #{collection_class} sha1 is #{@fetched_new_object.sha1_hash}"
338
+ else
339
+ raise 'Original ruby object created with .create is not == to the one re-fetched after saving!' unless @fetched_new_object == @unsaved_new_object
340
+
341
+ say "Fetched instance of #{collection_class} is == to the original one we made with .create"
342
+ end
335
343
  end
336
344
 
337
345
  ################
@@ -47,29 +47,44 @@ module JamfTest
47
47
  ################
48
48
  def add_data_to_new
49
49
  @all_comps_shuffled = Jamf::Computer.all.dup.shuffle
50
+ if @all_comps_shuffled.empty?
51
+ say 'No computers found in Jamf to add to the new Static Group!'
52
+ return
53
+ end
54
+
50
55
  @comps_added_to_static_group = []
51
56
 
52
57
  comp_1 = @all_comps_shuffled.shift
53
- @unsaved_new_object.add_member comp_1[:id]
54
- @comps_added_to_static_group << comp_1[:id]
55
- say "Added computer id #{comp_1[:id]} to unsaved Static Group"
58
+ if comp_1
59
+ @unsaved_new_object.add_member comp_1[:id]
60
+ @comps_added_to_static_group << comp_1[:id]
61
+ say "Added computer id #{comp_1[:id]} to unsaved Static Group"
62
+ end
56
63
 
57
64
  comp_2 = @all_comps_shuffled.shift
58
- @unsaved_new_object.add_member comp_2[:name]
59
- @comps_added_to_static_group << comp_2[:name]
60
- say "Added computer name #{comp_2[:name]} to unsaved Static Group"
65
+ if comp_2
66
+ @unsaved_new_object.add_member comp_2[:name]
67
+ @comps_added_to_static_group << comp_2[:name]
68
+ say "Added computer name #{comp_2[:name]} to unsaved Static Group"
69
+ end
61
70
 
62
71
  comp_3 = @all_comps_shuffled.shift
63
- @unsaved_new_object.add_member comp_3[:serial_number]
64
- @comps_added_to_static_group << comp_3[:serial_number]
65
- say "Added computer serial_number #{comp_3[:serial_number]} to unsaved Static Group"
72
+ if comp_3
73
+ @unsaved_new_object.add_member comp_3[:serial_number]
74
+ @comps_added_to_static_group << comp_3[:serial_number]
75
+ say "Added computer serial_number #{comp_3[:serial_number]} to unsaved Static Group"
76
+ end
66
77
 
67
78
  comp_4 = @all_comps_shuffled.shift
68
- @unsaved_new_object.add_member comp_4[:udid]
69
- @comps_added_to_static_group << comp_4[:udid]
70
- say "Added computer udid #{comp_4[:udid]} to unsaved Static Group"
79
+ if comp_4
80
+ @unsaved_new_object.add_member comp_4[:udid]
81
+ @comps_added_to_static_group << comp_4[:udid]
82
+ say "Added computer udid #{comp_4[:udid]} to unsaved Static Group"
83
+ end
71
84
 
72
85
  comp_5 = @all_comps_shuffled.shift
86
+ return unless comp_5
87
+
73
88
  @unsaved_new_object.add_member comp_5[:mac_address]
74
89
  @comps_added_to_static_group << comp_5[:mac_address]
75
90
  say "Added computer mac_address #{comp_5[:mac_address]} to unsaved Static Group"
@@ -109,6 +124,8 @@ module JamfTest
109
124
  say "Modified/saved/refetched instance of #{collection_class} has correct membership."
110
125
 
111
126
  # Test the class method for changing membership without instantiating/saving
127
+ return unless @all_comps_shuffled.size > 4
128
+
112
129
  adds = []
113
130
  adds << @all_comps_shuffled.shift[:id]
114
131
  adds << @all_comps_shuffled.shift[:serial_number]
@@ -25,11 +25,11 @@
25
25
 
26
26
  module JamfTest
27
27
 
28
- class JpBuilding < JamfTest::APITest
28
+ class JBuilding < JamfTest::APITest
29
29
 
30
30
  include JamfTest::CollectionTests
31
31
 
32
- COLLECTION_CLASS = Jamf::JpBuilding
32
+ COLLECTION_CLASS = Jamf::JBuilding
33
33
 
34
34
  # run the tests
35
35
  def run_class_tests
@@ -0,0 +1,47 @@
1
+ ### Copyright 2025 Pixar
2
+
3
+ ###
4
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
5
+ ### with the following modification; you may not use this file except in
6
+ ### compliance with the Apache License and the following modification to it:
7
+ ### Section 6. Trademarks. is deleted and replaced with:
8
+ ###
9
+ ### 6. Trademarks. This License does not grant permission to use the trade
10
+ ### names, trademarks, service marks, or product names of the Licensor
11
+ ### and its affiliates, except as required to comply with Section 4(c) of
12
+ ### the License and to reproduce the content of the NOTICE file.
13
+ ###
14
+ ### You may obtain a copy of the Apache License at
15
+ ###
16
+ ### http://www.apache.org/licenses/LICENSE-2.0
17
+ ###
18
+ ### Unless required by applicable law or agreed to in writing, software
19
+ ### distributed under the Apache License with the above modification is
20
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+ ### KIND, either express or implied. See the Apache License for the specific
22
+ ### language governing permissions and limitations under the Apache License.
23
+ ###
24
+ ###
25
+
26
+ module JamfTest
27
+
28
+ class JPackage < JamfTest::APITest
29
+
30
+ include JamfTest::CollectionTests
31
+
32
+ COLLECTION_CLASS = Jamf::JPackage
33
+
34
+ # run the tests
35
+ def run_class_tests
36
+ run_collection_tests
37
+ end
38
+
39
+ def create_new
40
+ @unsaved_new_object = collection_class.create packageName: test_object_name
41
+ @unsaved_new_object.fileName = "#{test_object_name}.pkg"
42
+ say "Created new #{collection_class}, to be saved in Jamf."
43
+ end
44
+
45
+ end # class
46
+
47
+ end # module JamfTest