ruby-jss 1.2.9 → 1.5.1

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.

Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +196 -1
  3. data/lib/jamf.rb +10 -3
  4. data/lib/jamf/api/abstract_classes/collection_resource.rb +329 -150
  5. data/lib/jamf/api/abstract_classes/generic_reference.rb +9 -1
  6. data/lib/jamf/api/abstract_classes/json_object.rb +107 -83
  7. data/lib/jamf/api/abstract_classes/prestage.rb +55 -30
  8. data/lib/jamf/api/abstract_classes/prestage_skip_setup_items.rb +21 -0
  9. data/lib/jamf/api/abstract_classes/resource.rb +4 -4
  10. data/lib/jamf/api/abstract_classes/singleton_resource.rb +1 -1
  11. data/lib/jamf/api/connection.rb +20 -12
  12. data/lib/jamf/api/connection/api_error.rb +8 -8
  13. data/lib/jamf/api/connection/token.rb +36 -15
  14. data/lib/jamf/api/json_objects/computer_prestage_skip_setup_items.rb +14 -1
  15. data/lib/jamf/api/json_objects/device_enrollment_device.rb +14 -7
  16. data/lib/jamf/api/json_objects/device_enrollment_device_sync_state.rb +81 -0
  17. data/lib/jamf/api/json_objects/locale.rb +59 -0
  18. data/lib/jamf/api/json_objects/md_prestage_skip_setup_items.rb +50 -1
  19. data/lib/jamf/api/json_objects/prestage_location.rb +3 -3
  20. data/lib/jamf/api/json_objects/prestage_purchasing_data.rb +7 -7
  21. data/lib/jamf/api/json_objects/prestage_scope.rb +1 -1
  22. data/lib/jamf/api/{resources/collection_resources → json_objects}/time_zone.rb +9 -23
  23. data/lib/jamf/api/mixins/bulk_deletable.rb +27 -6
  24. data/lib/jamf/api/mixins/change_log.rb +201 -51
  25. data/lib/jamf/api/mixins/filterable.rb +51 -0
  26. data/lib/jamf/api/mixins/pageable.rb +208 -0
  27. data/lib/jamf/api/mixins/sortable.rb +59 -0
  28. data/lib/jamf/api/resources/collection_resources/building.rb +19 -8
  29. data/lib/jamf/api/resources/collection_resources/category.rb +5 -3
  30. data/lib/jamf/api/resources/collection_resources/computer_prestage.rb +11 -4
  31. data/lib/jamf/api/resources/collection_resources/department.rb +1 -1
  32. data/lib/jamf/api/resources/collection_resources/device_enrollment.rb +13 -13
  33. data/lib/jamf/api/resources/collection_resources/inventory_preload_record.rb +11 -3
  34. data/lib/jamf/api/resources/collection_resources/mobile_device_prestage.rb +24 -22
  35. data/lib/jamf/api/resources/collection_resources/script.rb +61 -25
  36. data/lib/jamf/api/resources/singleton_resources/app_store_country_codes.rb +15 -5
  37. data/lib/jamf/api/resources/singleton_resources/client_checkin_settings.rb +14 -14
  38. data/lib/jamf/api/resources/singleton_resources/locales.rb +155 -0
  39. data/lib/jamf/api/resources/singleton_resources/time_zones.rb +213 -0
  40. data/lib/jamf/configuration.rb +7 -9
  41. data/lib/jamf/ruby_extensions.rb +1 -0
  42. data/lib/jamf/ruby_extensions/array.rb +1 -1
  43. data/lib/jamf/ruby_extensions/array/utils.rb +3 -3
  44. data/lib/jamf/ruby_extensions/dig.rb +52 -0
  45. data/lib/jamf/validate.rb +63 -24
  46. data/lib/jamf/version.rb +1 -1
  47. data/lib/jss.rb +4 -1
  48. data/lib/jss/api_connection.rb +110 -397
  49. data/lib/jss/api_object.rb +16 -13
  50. data/lib/jss/api_object/advanced_search.rb +27 -26
  51. data/lib/jss/api_object/app_store_country_codes.rb +298 -0
  52. data/lib/jss/api_object/categorizable.rb +1 -1
  53. data/lib/jss/api_object/computer.rb +5 -1
  54. data/lib/jss/api_object/configuration_profile.rb +34 -3
  55. data/lib/jss/api_object/directory_binding.rb +273 -0
  56. data/lib/jss/api_object/directory_binding_type.rb +96 -0
  57. data/lib/jss/api_object/directory_binding_type/active_directory.rb +539 -0
  58. data/lib/jss/api_object/directory_binding_type/admitmac.rb +594 -0
  59. data/lib/jss/api_object/directory_binding_type/centrify.rb +226 -0
  60. data/lib/jss/api_object/directory_binding_type/open_directory.rb +178 -0
  61. data/lib/jss/api_object/directory_binding_type/powerbroker_identity_services.rb +73 -0
  62. data/lib/jss/api_object/disk_encryption_configurations.rb +114 -0
  63. data/lib/jss/api_object/distribution_point.rb +97 -37
  64. data/lib/jss/api_object/dock_item.rb +143 -0
  65. data/lib/jss/api_object/ebook.rb +1 -2
  66. data/lib/jss/api_object/extendable.rb +68 -32
  67. data/lib/jss/api_object/extension_attribute.rb +4 -3
  68. data/lib/jss/api_object/group.rb +33 -2
  69. data/lib/jss/api_object/mac_application.rb +107 -8
  70. data/lib/jss/api_object/mobile_device.rb +3 -0
  71. data/lib/jss/api_object/mobile_device_application.rb +12 -0
  72. data/lib/jss/api_object/network_segment.rb +195 -70
  73. data/lib/jss/api_object/package.rb +105 -40
  74. data/lib/jss/api_object/patch_source.rb +10 -9
  75. data/lib/jss/api_object/policy.rb +491 -7
  76. data/lib/jss/api_object/printer.rb +446 -0
  77. data/lib/jss/api_object/scopable.rb +10 -15
  78. data/lib/jss/api_object/scopable/scope.rb +386 -71
  79. data/lib/jss/api_object/self_servable.rb +17 -9
  80. data/lib/jss/api_object/uploadable.rb +1 -1
  81. data/lib/jss/api_object/user.rb +42 -1
  82. data/lib/jss/api_object/vpp_account.rb +209 -0
  83. data/lib/jss/api_object/vppable.rb +169 -13
  84. data/lib/jss/composer.rb +1 -1
  85. data/lib/jss/exceptions.rb +3 -0
  86. data/lib/jss/server.rb +15 -0
  87. data/lib/jss/utility.rb +8 -22
  88. data/lib/jss/validate.rb +53 -10
  89. data/lib/jss/version.rb +1 -1
  90. metadata +50 -22
@@ -30,6 +30,27 @@ module Jamf
30
30
  # various Setup options in a DEP prestage
31
31
  # The object model here includes the attributes common
32
32
  # to both Computer and MobileDevice prestages
33
+ #
34
+ # To see the current list of settings that are common
35
+ # to both Computers and MobileDevices, run this in irb:
36
+ #
37
+ # Jamf::ComputerPrestage.all.sample[:skipSetupItems].keys & Jamf::MobileDevicePrestage.all.sample[:skipSetupItems].keys
38
+ #
39
+ # => [
40
+ # :Appearance,
41
+ # :AppleID,
42
+ # :Biometric,
43
+ # :Diagnostics,
44
+ # :DisplayTone,
45
+ # :Location,
46
+ # :Payment,
47
+ # :Privacy,
48
+ # :Restore,
49
+ # :ScreenTime,
50
+ # :Siri,
51
+ # :TOS
52
+ # ]
53
+ #
33
54
  class PrestageSkipSetupItems < Jamf::JSONObject
34
55
 
35
56
  extend Jamf::Abstract
@@ -186,7 +186,7 @@ module Jamf
186
186
  #####################################
187
187
 
188
188
  # These methods are allowed to call .new
189
- NEW_CALLERS = ['fetch', 'create', 'all', 'block in all'].freeze
189
+ NEW_CALLERS = ['fetch', 'create', 'all', 'cached_all', 'block in all', 'block in cached_all'].freeze
190
190
 
191
191
  # The resource version for previewing new features
192
192
  RSRC_PREVIEW_VERSION = 'preview'.freeze
@@ -197,7 +197,7 @@ module Jamf
197
197
  # the resource path for this resource
198
198
  # @return [String]
199
199
  def self.rsrc_path
200
- "#{self::RSRC_VERSION}/#{self::RSRC_PATH}"
200
+ @rsrc_path ||= "#{self::RSRC_VERSION}/#{self::RSRC_PATH}"
201
201
  end
202
202
 
203
203
  def self.preview_path
@@ -205,11 +205,11 @@ module Jamf
205
205
  end
206
206
 
207
207
  # Disallow direct use of ruby's .new class method for creating instances.
208
- # Require use of .fetch or .create.
208
+ # Require use of .fetch or .create, or 'all'
209
209
  #
210
210
  def self.new(data, cnx: Jamf.cnx)
211
211
  calling_method = caller_locations(1..1).first.label
212
- raise Jamf::UnsupportedError, "Use .fetch or .create to instantiate Jamf::Resource's" unless NEW_CALLERS.include? calling_method
212
+ raise Jamf::UnsupportedError, "Use .fetch, .create, or .all(instantiate:true) to instantiate Jamf::Resources" unless NEW_CALLERS.include? calling_method
213
213
 
214
214
  super
215
215
  end
@@ -60,7 +60,7 @@ module Jamf
60
60
  cached = cnx.singleton_cache[self]
61
61
  return cached if cached
62
62
 
63
- data = cnx.get "#{self::RSRC_VERSION}/#{self::RSRC_PATH}"
63
+ data = cnx.get rsrc_path
64
64
  cnx.singleton_cache[self] = new data, cnx: cnx
65
65
  end # fetch
66
66
 
@@ -24,9 +24,6 @@
24
24
  require 'faraday' # >= 0.17.0
25
25
  require 'faraday_middleware' # >= 0.13.0
26
26
 
27
- require 'jamf/api/connection/token'
28
- require 'jamf/api/connection/api_error'
29
-
30
27
  # The module
31
28
  module Jamf
32
29
 
@@ -45,10 +42,10 @@ module Jamf
45
42
  #####################################
46
43
 
47
44
  # The start of the path for API resources
48
- RSRC_BASE = 'uapi'.freeze
45
+ RSRC_BASE = 'api'.freeze
49
46
 
50
- # The API version must be this or higher
51
- MIN_JAMF_VERSION = Gem::Version.new('10.15.0')
47
+ # The JamfPro version must be this or higher
48
+ MIN_JAMF_VERSION = Gem::Version.new('10.25.0')
52
49
 
53
50
  HTTPS_SCHEME = 'https'.freeze
54
51
 
@@ -85,6 +82,7 @@ module Jamf
85
82
  TOKEN_REUSE_MIN_LIFE = 60
86
83
 
87
84
  HTTP_ACCEPT_HEADER = 'Accept'.freeze
85
+
88
86
  HTTP_CONTENT_TYPE_HEADER = 'Content-Type'.freeze
89
87
 
90
88
  MIME_JSON = 'application/json'.freeze
@@ -161,7 +159,6 @@ module Jamf
161
159
  #
162
160
  # SingletonResource.fetch will return the instance from here, if it exists,
163
161
  # unless the first parameter is truthy.
164
-
165
162
  attr_reader :singleton_cache
166
163
 
167
164
  # @return [Hash]
@@ -454,7 +451,9 @@ module Jamf
454
451
 
455
452
  # Are we keeping the connection alive?
456
453
  def keep_alive?
457
- @keep_alive_thread&.alive? || false
454
+ return false unless @keep_alive_thread
455
+
456
+ @keep_alive_thread.alive?
458
457
  end
459
458
 
460
459
  # @return [Jamf::Timestamp, nil]
@@ -702,7 +701,11 @@ module Jamf
702
701
 
703
702
  @timeout = params[:timeout]
704
703
  @open_timeout = params[:open_timeout]
705
- @base_url = URI.parse "https://#{@host}:#{@port}/#{RSRC_BASE}"
704
+
705
+ # TEMPORARY ? the tryitout host still uses `uapi` rather than the
706
+ # new `api` for regular servers
707
+ rsrc_base = @host == Token::JAMF_TRYITOUT_HOST ? 'uapi' : RSRC_BASE
708
+ @base_url = URI.parse "https://#{@host}:#{@port}/#{rsrc_base}"
706
709
 
707
710
  # ssl opts for faraday
708
711
  # TODO: implement all of faraday's options
@@ -764,7 +767,7 @@ module Jamf
764
767
  cnx.response :json, parser_options: { symbolize_names: true } if parse_json
765
768
  cnx.options[:timeout] = @timeout
766
769
  cnx.options[:open_timeout] = @open_timeout
767
- cnx.use Faraday::Adapter::NetHttp
770
+ cnx.adapter Faraday::Adapter::NetHttp
768
771
  end
769
772
  end
770
773
 
@@ -806,7 +809,9 @@ module Jamf
806
809
  # @return [void]
807
810
  #
808
811
  def stop_keep_alive
809
- @keep_alive_thread&.kill
812
+ return unless @keep_alive_thread
813
+
814
+ @keep_alive_thread.kill if @keep_alive_thread.alive?
810
815
  @keep_alive_thread = nil
811
816
  end
812
817
 
@@ -853,7 +858,10 @@ module Jamf
853
858
  end
854
859
 
855
860
  def self.disconnect
856
- @active_connection&.disconnect
861
+ @active_connection.disconnect if @active_connection
857
862
  end
858
863
 
859
864
  end # module Jamf
865
+
866
+ require 'jamf/api/connection/token'
867
+ require 'jamf/api/connection/api_error'
@@ -83,18 +83,18 @@ module Jamf
83
83
  def initialize(http_response)
84
84
  @http_response = http_response
85
85
  @httpStatus = http_response.status
86
-
87
86
  @errors =
88
- if @http_response.body.dig :errors
89
- @http_response.body[:errors].map { |e| ErrorInfo.new e }
90
- else
91
- []
87
+ if @http_response.body.is_a? String
88
+ JSON.parse(@http_response.body)[:errors]
89
+ elsif @http_response.body.is_a?(Hash)
90
+ @http_response.body[:errors]
92
91
  end
92
+ @errors &&= @errors.map { |e| ErrorInfo.new e }
93
93
 
94
- if @errors.empty?
94
+ unless @errors
95
95
  code = @httpStatus
96
- desc = @httpStatus == 404 ? RSRC_NOT_FOUND : @http_response.reason_phrase
97
- @errors << ErrorInfo.new(code: code, field: nil, description: desc, id: nil)
96
+ desc = code == 404 ? RSRC_NOT_FOUND : @http_response.reason_phrase
97
+ @errors = [ErrorInfo.new(code: code, field: nil, description: desc, id: nil)]
98
98
  end
99
99
 
100
100
  super
@@ -32,18 +32,29 @@ module Jamf
32
32
 
33
33
  JAMF_VERSION_RSRC = 'v1/jamf-pro-version'.freeze
34
34
 
35
+ AUTH_RSRC_VERSION = 'v1'.freeze
36
+
35
37
  AUTH_RSRC = 'auth'.freeze
36
38
 
37
- NEW_TOKEN_RSRC = "#{AUTH_RSRC}/tokens".freeze
39
+ NEW_TOKEN_RSRC = "#{AUTH_RSRC_VERSION}/#{AUTH_RSRC}/token".freeze
38
40
 
39
- KEEP_ALIVE_RSRC = "#{AUTH_RSRC}/keepAlive".freeze
41
+ KEEP_ALIVE_RSRC = "#{AUTH_RSRC_VERSION}/#{AUTH_RSRC}/keep-alive".freeze
40
42
 
41
- INVALIDATE_RSRC = "#{AUTH_RSRC}/invalidateToken".freeze
43
+ INVALIDATE_RSRC = "#{AUTH_RSRC_VERSION}/#{AUTH_RSRC}/invalidate-token".freeze
42
44
 
43
45
  # this string is prepended to the token data when used for
44
46
  # transaction authorization.
45
47
  AUTH_TOKEN_PFX = 'jamf-token '.freeze
46
48
 
49
+ # Recognize the tryitout server, cuz its /auth endpoint
50
+ # is disabled, and it needs no tokens
51
+ JAMF_TRYITOUT_HOST = "tryitout#{Jamf::Connection::JAMFCLOUD_DOMAIN}".freeze
52
+
53
+ JAMF_TRYITOUT_TOKEN_BODY = {
54
+ token: 'This is a fake token, tryitout.jamfcloud.com uses internal tokens',
55
+ expires: 2_000_000_000_000
56
+ }.freeze
57
+
47
58
  # @return [String] The user who generated this token
48
59
  attr_reader :user
49
60
 
@@ -81,7 +92,9 @@ module Jamf
81
92
  @timeout = params[:timeout] || Jamf::Connection::DFT_TIMEOUT
82
93
  @ssl_options = params[:ssl_options] || {}
83
94
 
84
- if params[:pw]
95
+ if @base_url.host == JAMF_TRYITOUT_HOST
96
+ init_jamf_tryitout
97
+ elsif params[:pw]
85
98
  init_from_pw params[:pw]
86
99
  elsif params[:token_string]
87
100
  init_from_token_string params[:token_string]
@@ -90,6 +103,15 @@ module Jamf
90
103
  end
91
104
  end # init
92
105
 
106
+ # Initialize from password
107
+ def init_jamf_tryitout
108
+ @token_response_body = JAMF_TRYITOUT_TOKEN_BODY
109
+ @auth_token = AUTH_TOKEN_PFX + @token_response_body[:token]
110
+ @expires = Jamf::Timestamp.new @token_response_body[:expires]
111
+ @login_time = Jamf::Timestamp.new Time.now
112
+ @valid = true
113
+ end # init_from_pw
114
+
93
115
  # Initialize from password
94
116
  def init_from_pw(pw)
95
117
  resp = token_connection(
@@ -134,12 +156,14 @@ module Jamf
134
156
 
135
157
  # @return [String]
136
158
  def jamf_version
137
- raw_jamf_version.split('-').first
159
+ fetch_jamf_version unless @jamf_version
160
+ @jamf_version
138
161
  end
139
162
 
140
163
  # @return [String]
141
164
  def jamf_build
142
- raw_jamf_version.split('-').last
165
+ fetch_jamf_version unless @jamf_build
166
+ @jamf_build
143
167
  end
144
168
 
145
169
  # @return [Boolean]
@@ -244,15 +268,12 @@ module Jamf
244
268
  end
245
269
 
246
270
  # @return [String]
247
- def raw_jamf_version
248
- # TODO: Remove this once we require Jamf Pro 10.19 and up
249
- # the rsrc for getting the version used to be nothing (the
250
- # base url itself returnedit) but now its JAMF_VERSION_RSRC
251
- resp = token_connection(Jamf::BLANK, token: @auth_token).get # .body # [:version]
252
- return resp.body[:version] if resp.success?
253
-
271
+ def fetch_jamf_version
254
272
  resp = token_connection(JAMF_VERSION_RSRC, token: @auth_token).get
255
- return resp.body[:version] if resp.success?
273
+ if resp.success?
274
+ @jamf_version, @jamf_build = resp.body[:version].split('-')
275
+ return
276
+ end
256
277
 
257
278
  raise Jamf::InvalidConnectionError, 'Unable to read Jamf version from the API'
258
279
  end
@@ -271,7 +292,7 @@ module Jamf
271
292
  else
272
293
  con.basic_auth @user, pw
273
294
  end
274
- con.use Faraday::Adapter::NetHttp
295
+ con.adapter Faraday::Adapter::NetHttp
275
296
  end # Faraday.new
276
297
  end # token_connection
277
298
 
@@ -26,7 +26,13 @@
26
26
  # The module
27
27
  module Jamf
28
28
 
29
- # A 'location' for a computer prestage in Jamf Pro
29
+ # The 'skip Setup Items' for a computer prestage in Jamf Pro
30
+ # The ones in common with Mobile Devices are in the superclass
31
+ # To see the ones that should be here, remove anything that's in
32
+ # mobile device's list from the computer ones, thus:
33
+ #
34
+ # > Jamf::ComputerPrestage.all.sample[:skipSetupItems].keys - Jamf::MobileDevicePrestage.all.sample[:skipSetupItems].keys
35
+ # => [:FileVault, :iCloudDiagnostics, :Accessibility, :Registration, :iCloudStorage]
30
36
  class ComputerPrestageSkipSetupItems < Jamf::PrestageSkipSetupItems
31
37
 
32
38
  OBJECT_MODEL = superclass::OBJECT_MODEL.merge(
@@ -57,6 +63,13 @@ module Jamf
57
63
  Registration: {
58
64
  class: :boolean,
59
65
  aliases: %i[registration]
66
+ },
67
+
68
+ # @!attribute Registration
69
+ # @return [Boolean]
70
+ Accessibility: {
71
+ class: :boolean,
72
+ aliases: %i[accessibility]
60
73
  }
61
74
  ).freeze
62
75
 
@@ -68,25 +68,25 @@ module Jamf
68
68
  OBJECT_MODEL = {
69
69
 
70
70
  # @!attribute id
71
- # @return [Integer]
71
+ # @return [String]
72
72
  id: {
73
- class: :integer,
73
+ class: :j_id,
74
74
  identifier: true
75
75
  },
76
76
 
77
77
  # @!attribute deviceEnrollmentProgramInstanceId
78
- # @return [Integer]
78
+ # @return [String]
79
79
  deviceEnrollmentProgramInstanceId: {
80
- class: :integer,
80
+ class: :j_id,
81
81
  aliases: %i[instanceId]
82
82
  },
83
83
 
84
84
  # @!attribute prestageId
85
85
  # The most recent prestage this device was assigned to, even if
86
86
  # currently unassigned to any prestage.
87
- # @return [Integer]
87
+ # @return [String]
88
88
  prestageId: {
89
- class: :integer
89
+ class: :j_id
90
90
  },
91
91
 
92
92
  # @!attribute serialNumber
@@ -122,7 +122,14 @@ module Jamf
122
122
  # @!attribute profileStatus
123
123
  # @return [String]
124
124
  profileStatus: {
125
- class: :string
125
+ class: :string,
126
+ enum: PROFILE_STATUSES
127
+ },
128
+
129
+ # @!attribute syncState
130
+ # @return [DeviceEnrollmentDeviceSyncState]
131
+ syncState: {
132
+ class: Jamf::DeviceEnrollmentDeviceSyncState
126
133
  },
127
134
 
128
135
  # @!attribute profileAssignTime
@@ -0,0 +1,81 @@
1
+ # Copyright 2020 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
+ # The module
27
+ module Jamf
28
+
29
+ # The status of a device from Apple's POV, regarding its
30
+ # assignment or removal from ADE. Such assignment is done via
31
+ # a profile from apple, this data is the state of that profile.
32
+ class DeviceEnrollmentDeviceSyncState < Jamf::JSONObject
33
+
34
+ extend Jamf::Immutable
35
+
36
+ OBJECT_MODEL = {
37
+
38
+ # @!attribute id
39
+ # NOTE: this is not a jamf object id, it comes from Apple, therefore
40
+ # it is an Integer, not a :j_id
41
+ # @return [Integer]
42
+ id: {
43
+ class: :integer
44
+ },
45
+
46
+ # @!attribute serialNumber
47
+ # @return [String]
48
+ serialNumber: {
49
+ class: :string
50
+ },
51
+
52
+ # @!attribute profileUUID
53
+ # @return [String]
54
+ profileUUID: {
55
+ class: :string
56
+ },
57
+
58
+ # @!attribute syncStatus
59
+ # @return [String]
60
+ syncStatus: {
61
+ class: :string
62
+ },
63
+
64
+ # @!attribute failureCount
65
+ # @return [Integer]
66
+ failureCount: {
67
+ class: :integer
68
+ },
69
+
70
+ # @!attribute timestamp
71
+ # @return [Jamf::Timestamp]
72
+ timestamp: {
73
+ class: Jamf::Timestamp
74
+ }
75
+ }.freeze
76
+
77
+ parse_object_model
78
+
79
+ end # class Country
80
+
81
+ end # module