ruby-jss 0.6.3

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 (73) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +7 -0
  3. data/CHANGES.md +112 -0
  4. data/LICENSE.txt +174 -0
  5. data/README.md +426 -0
  6. data/THANKS.md +6 -0
  7. data/bin/cgrouper +485 -0
  8. data/bin/subnet-update +400 -0
  9. data/lib/jss-api.rb +2 -0
  10. data/lib/jss.rb +190 -0
  11. data/lib/jss/api_connection.rb +410 -0
  12. data/lib/jss/api_object.rb +616 -0
  13. data/lib/jss/api_object/advanced_search.rb +389 -0
  14. data/lib/jss/api_object/advanced_search/advanced_computer_search.rb +95 -0
  15. data/lib/jss/api_object/advanced_search/advanced_mobile_device_search.rb +96 -0
  16. data/lib/jss/api_object/advanced_search/advanced_user_search.rb +95 -0
  17. data/lib/jss/api_object/building.rb +92 -0
  18. data/lib/jss/api_object/category.rb +147 -0
  19. data/lib/jss/api_object/computer.rb +852 -0
  20. data/lib/jss/api_object/creatable.rb +98 -0
  21. data/lib/jss/api_object/criteriable.rb +189 -0
  22. data/lib/jss/api_object/criteriable/criteria.rb +231 -0
  23. data/lib/jss/api_object/criteriable/criterion.rb +228 -0
  24. data/lib/jss/api_object/department.rb +93 -0
  25. data/lib/jss/api_object/distribution_point.rb +560 -0
  26. data/lib/jss/api_object/extendable.rb +221 -0
  27. data/lib/jss/api_object/extension_attribute.rb +466 -0
  28. data/lib/jss/api_object/extension_attribute/computer_extension_attribute.rb +362 -0
  29. data/lib/jss/api_object/extension_attribute/mobile_device_extension_attribute.rb +189 -0
  30. data/lib/jss/api_object/extension_attribute/user_extension_attribute.rb +117 -0
  31. data/lib/jss/api_object/group.rb +380 -0
  32. data/lib/jss/api_object/group/computer_group.rb +124 -0
  33. data/lib/jss/api_object/group/mobile_device_group.rb +139 -0
  34. data/lib/jss/api_object/group/user_group.rb +139 -0
  35. data/lib/jss/api_object/ldap_server.rb +535 -0
  36. data/lib/jss/api_object/locatable.rb +286 -0
  37. data/lib/jss/api_object/matchable.rb +97 -0
  38. data/lib/jss/api_object/mobile_device.rb +556 -0
  39. data/lib/jss/api_object/netboot_server.rb +148 -0
  40. data/lib/jss/api_object/network_segment.rb +414 -0
  41. data/lib/jss/api_object/osx_configuration_profile.rb +262 -0
  42. data/lib/jss/api_object/package.rb +839 -0
  43. data/lib/jss/api_object/peripheral.rb +335 -0
  44. data/lib/jss/api_object/peripheral_type.rb +295 -0
  45. data/lib/jss/api_object/policy.rb +898 -0
  46. data/lib/jss/api_object/purchasable.rb +316 -0
  47. data/lib/jss/api_object/removable_macaddr.rb +98 -0
  48. data/lib/jss/api_object/scopable.rb +136 -0
  49. data/lib/jss/api_object/scopable/scope.rb +621 -0
  50. data/lib/jss/api_object/script.rb +631 -0
  51. data/lib/jss/api_object/self_servable.rb +356 -0
  52. data/lib/jss/api_object/site.rb +93 -0
  53. data/lib/jss/api_object/software_update_server.rb +109 -0
  54. data/lib/jss/api_object/updatable.rb +117 -0
  55. data/lib/jss/api_object/uploadable.rb +138 -0
  56. data/lib/jss/api_object/user.rb +272 -0
  57. data/lib/jss/client.rb +504 -0
  58. data/lib/jss/compatibility.rb +66 -0
  59. data/lib/jss/composer.rb +185 -0
  60. data/lib/jss/configuration.rb +306 -0
  61. data/lib/jss/db_connection.rb +298 -0
  62. data/lib/jss/exceptions.rb +95 -0
  63. data/lib/jss/ruby_extensions.rb +35 -0
  64. data/lib/jss/ruby_extensions/filetest.rb +43 -0
  65. data/lib/jss/ruby_extensions/hash.rb +79 -0
  66. data/lib/jss/ruby_extensions/ipaddr.rb +91 -0
  67. data/lib/jss/ruby_extensions/pathname.rb +77 -0
  68. data/lib/jss/ruby_extensions/string.rb +59 -0
  69. data/lib/jss/ruby_extensions/time.rb +63 -0
  70. data/lib/jss/server.rb +108 -0
  71. data/lib/jss/utility.rb +478 -0
  72. data/lib/jss/version.rb +31 -0
  73. metadata +187 -0
@@ -0,0 +1,335 @@
1
+ ### Copyright 2016 Pixar
2
+ ###
3
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
+ ### with the following modification; you may not use this file except in
5
+ ### compliance with the Apache License and the following modification to it:
6
+ ### Section 6. Trademarks. is deleted and replaced with:
7
+ ###
8
+ ### 6. Trademarks. This License does not grant permission to use the trade
9
+ ### names, trademarks, service marks, or product names of the Licensor
10
+ ### and its affiliates, except as required to comply with Section 4(c) of
11
+ ### the License and to reproduce the content of the NOTICE file.
12
+ ###
13
+ ### You may obtain a copy of the Apache License at
14
+ ###
15
+ ### http://www.apache.org/licenses/LICENSE-2.0
16
+ ###
17
+ ### Unless required by applicable law or agreed to in writing, software
18
+ ### distributed under the Apache License with the above modification is
19
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20
+ ### KIND, either express or implied. See the Apache License for the specific
21
+ ### language governing permissions and limitations under the Apache License.
22
+ ###
23
+ ###
24
+
25
+ ###
26
+ module JSS
27
+
28
+ #####################################
29
+ ### Module Variables
30
+ #####################################
31
+
32
+ #####################################
33
+ ### Module Methods
34
+ #####################################
35
+
36
+ #####################################
37
+ ### Classes
38
+ #####################################
39
+
40
+ ###
41
+ ### A peripheral in the JSS
42
+ ###
43
+ ### @see JSS::APIObject
44
+ ###
45
+ class Peripheral < JSS::APIObject
46
+
47
+ #####################################
48
+ ### MixIns
49
+ #####################################
50
+
51
+ include JSS::Creatable
52
+ include JSS::Updatable
53
+
54
+ ### periphs have a purchasing subset
55
+ include JSS::Purchasable
56
+
57
+ ### periphs have a location subset, which will be
58
+ ### stored in primary attributes.
59
+ include JSS::Locatable
60
+
61
+ ### periphs can take uploaded files.
62
+ include JSS::Uploadable
63
+
64
+ #####################################
65
+ ### Class Methods
66
+ #####################################
67
+
68
+ #####################################
69
+ ### Class Constants
70
+ #####################################
71
+
72
+ ### The base for REST resources of this class
73
+ RSRC_BASE = "peripherals"
74
+
75
+ ### the hash key used for the JSON list output of all objects in the JSS
76
+ RSRC_LIST_KEY = :peripherals
77
+
78
+ ### The hash key used for the JSON object output.
79
+ ### It's also used in various error messages
80
+ RSRC_OBJECT_KEY = :peripheral
81
+
82
+ ### these keys, as well as :id and :name, are present in valid API JSON data for this class
83
+ VALID_DATA_KEYS = [:type, :bar_code_1, :computer_id ]
84
+
85
+
86
+ #####################################
87
+ ### Class Variables
88
+ #####################################
89
+
90
+ #####################################
91
+ ### Class Methods
92
+ #####################################
93
+
94
+ #####################################
95
+ ### Attributes
96
+ #####################################
97
+
98
+ ### @return [String] the type of peripheral
99
+ attr_reader :type
100
+
101
+ ### @return [String] the "bar code 1" value
102
+ attr_reader :bar_code_1
103
+
104
+
105
+ ### @return [String] the "bar code 2" value
106
+ attr_reader :bar_code_2
107
+
108
+
109
+ ### @return [Integer] the id number of the computer to which this periph is connected
110
+ attr_reader :computer_id
111
+
112
+ #####################################
113
+ ### Instance Methods
114
+ #####################################
115
+
116
+ ###
117
+ ### @see APIObject
118
+ ###
119
+ def initialize (args = {})
120
+
121
+ ### periphs don't really have names, and the JSS module list method for
122
+ ### periphs gives the computer_id as the name, so give it a temp
123
+ ### name of "-1", which shouldn't ever exist in the JSS
124
+ args[:name] ||= "-1"
125
+
126
+ super
127
+
128
+ if args[:id] == :new
129
+ raise JSS::InvalidDataError, "New Peripherals must have a :type, which must be one of those defined in the JSS." unless args[:type]
130
+ @type = args[:type]
131
+ raise JSS::InvalidDataError, "No peripheral type '#{@type}' in the JSS" unless JSS::PeripheralType.all_names(:refresh).include? @type
132
+ @fields = {}
133
+ @rest_rsrc = 'peripherals/id/-1'
134
+ @site = "None"
135
+ return
136
+ end
137
+
138
+ @type = @init_data[:general][:type]
139
+ @site = JSS::APIObject.get_name(@init_data[:general][:site])
140
+ @bar_code_1 = @init_data[:general][:bar_code_1]
141
+ @bar_code_2 = @init_data[:general][:bar_code_2]
142
+ @computer_id = @init_data[:general][:computer_id]
143
+
144
+ ### fill in the fields
145
+ @fields = {}
146
+ @init_data[:general][:fields].each{|f| @fields[f[:name]] = f[:value] }
147
+
148
+ ### get the field defs for this PeriphType, omitting the leading nil
149
+ @field_defs ||= JSS::PeripheralType.new(:name => @type).fields.compact
150
+
151
+ parse_location
152
+ parse_purchasing
153
+
154
+ end # initialize
155
+
156
+
157
+ ###
158
+ ### reset the restrsrc after creation
159
+ ###
160
+ ### @see JSS::Creatable#create
161
+ ###
162
+ def create
163
+ super
164
+ @rest_rsrc = "peripherals/id/#{@id}"
165
+ @id
166
+ end
167
+
168
+ ###
169
+ ### periphs don't have names
170
+ ###
171
+ def name= (newname)
172
+ raise JSS::UnsupportedError, "Peripherals don't have names."
173
+ end
174
+
175
+ ###
176
+ ###
177
+ ### @return [Hash] the field values of the peripheral
178
+ ### Each key is the fields name, as a String
179
+ ### and the value is the fields value, also as a String
180
+ ###
181
+ def fields
182
+ @fields
183
+ end
184
+
185
+ ###
186
+ ### Set the value of a field. It will be checked to ensure validity.
187
+ ###
188
+ ### @param field[String] the field to set
189
+ ###
190
+ ### @param value[String] the new value for the field
191
+ ###
192
+ ### @return [void]
193
+ ###
194
+ def set_field(field, value)
195
+ check_field(field, value)
196
+ @fields[field] = value
197
+ @need_to_update = true
198
+ end
199
+
200
+ ###
201
+ ### Set the value of barcode 1
202
+ ###
203
+ ### @param new_value[String] the new barcode value
204
+ ###
205
+ ### @return [void]
206
+ ###
207
+ def bar_code_1= (new_value)
208
+ @bar_code_1 = new_value
209
+ @need_to_update = true
210
+ end
211
+
212
+
213
+ ###
214
+ ### Set the value of barcode 2
215
+ ###
216
+ ### @param new_value[String] the new barcode value
217
+ ###
218
+ ### @return [void]
219
+ ###
220
+ def bar_code_2= (new_value)
221
+ @bar_code_2 = new_value
222
+ @need_to_update = true
223
+ end
224
+
225
+
226
+ ###
227
+ ### Associate this peripheral with a computer.
228
+ ###
229
+ ### @param computer[String,Integer] the name or id of a computer in the JSS
230
+ ###
231
+ ### @return [void]
232
+ ###
233
+ def associate(computer)
234
+ if computer =~ /^d+$/
235
+ raise JSS::NoSuchItemError, "No computer in the JSS with id #{computer}" unless JSS::Computer.all_ids.include? computer
236
+ @computer_id = computer
237
+ else
238
+ raise JSS::NoSuchItemError, "No computer in the JSS with name #{computer}" unless JSS::Computer.all_names.include? computer
239
+ @computer_id = JSS::Computer.map_all_ids_to(:name).invert[computer]
240
+ end
241
+ @need_to_update = true
242
+ end
243
+
244
+
245
+ ###
246
+ ### Disassociate this peripheral from any computer.
247
+ ###
248
+ ### This seems to have no effect in the JSS,
249
+ ### the computer/user/location data always shows the most recent.
250
+ ###
251
+ ### @return [void]
252
+ ###
253
+ def disassociate
254
+ @computer_id = nil
255
+ @need_to_update = true
256
+ end
257
+
258
+
259
+ #################################
260
+ ### Private Methods below here
261
+ private
262
+
263
+ ###
264
+ ### check a field, the field name must match those defined in
265
+ ### the appropriate peripheral type.
266
+ ### If a field is a menu field, the value must also be one of those defined
267
+ ### in the periph type.
268
+ ### Raise an exception if wrong.
269
+ ###
270
+ def check_field(field, value)
271
+ ### get the field defs for this PeriphType, omitting the leading nil
272
+ @field_defs ||= JSS::PeripheralType.new(:name => @type).fields.compact
273
+
274
+ ### we must have the right number of fields, and they must have the same names
275
+ ### as the definition
276
+ required_fields = @field_defs.map{|f| f[:name]}
277
+ raise JSS::InvalidDataError, "Peripherals of type '#{@type}' doesn't have a field '#{field}', they only have: #{required_fields.join(', ')}" unless required_fields.include? field
278
+
279
+ ### any menu fields can only have values as defined by the type.
280
+ menu_flds = @field_defs.select{|f| f[:type] == "menu" }
281
+ menu_flds.each do |mf|
282
+ next unless mf[:name] == field
283
+ raise JSS::InvalidDataError, "The value for field '#{field}' must be one of: #{mf[:choices].join(', ')}" unless mf[:choices].include? value
284
+ end #if menu_flds.include? field
285
+
286
+ end # check fields
287
+
288
+ ###
289
+ ### Return the REST XML for this pkg, with the current values,
290
+ ### for saving or updating
291
+ ###
292
+ def rest_xml
293
+ doc = REXML::Document.new APIConnection::XML_HEADER
294
+ periph = doc.add_element RSRC_OBJECT_KEY.to_s
295
+
296
+ general = periph.add_element('general')
297
+ general.add_element('type').text = @type
298
+ general.add_element('site').add_element('name').text = @site
299
+ general.add_element('bar_code_1').text = @bar_code_1
300
+ general.add_element('bar_code_2').text = @bar_code_2
301
+ general.add_element('computer_id').text = @computer_id
302
+
303
+ fields = general.add_element('fields')
304
+ @fields.each do |n,v|
305
+ fld = fields.add_element('field')
306
+ fld.add_element('name').text = n
307
+ fld.add_element('value').text = v
308
+ end
309
+
310
+ if has_location?
311
+ periph << location_xml
312
+ end
313
+ if has_purchasing?
314
+ periph << purchasing_xml
315
+ end
316
+
317
+ return doc.to_s
318
+ end # rest xml
319
+
320
+ ### Aliases
321
+ alias barcode_1 bar_code_1
322
+ alias barcode1 bar_code_1
323
+ alias barcode_1= bar_code_1=
324
+ alias barcode1= bar_code_1=
325
+
326
+ alias barcode_2 bar_code_2
327
+ alias barcode2 bar_code_2
328
+ alias barcode_2= bar_code_2=
329
+ alias barcode2= bar_code_2=
330
+
331
+ alias assign_to associate
332
+ alias unassign disassociate
333
+
334
+ end # class Peripheral
335
+ end # module
@@ -0,0 +1,295 @@
1
+ ### Copyright 2016 Pixar
2
+ ###
3
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
+ ### with the following modification; you may not use this file except in
5
+ ### compliance with the Apache License and the following modification to it:
6
+ ### Section 6. Trademarks. is deleted and replaced with:
7
+ ###
8
+ ### 6. Trademarks. This License does not grant permission to use the trade
9
+ ### names, trademarks, service marks, or product names of the Licensor
10
+ ### and its affiliates, except as required to comply with Section 4(c) of
11
+ ### the License and to reproduce the content of the NOTICE file.
12
+ ###
13
+ ### You may obtain a copy of the Apache License at
14
+ ###
15
+ ### http://www.apache.org/licenses/LICENSE-2.0
16
+ ###
17
+ ### Unless required by applicable law or agreed to in writing, software
18
+ ### distributed under the Apache License with the above modification is
19
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20
+ ### KIND, either express or implied. See the Apache License for the specific
21
+ ### language governing permissions and limitations under the Apache License.
22
+ ###
23
+ ###
24
+
25
+ ###
26
+ module JSS
27
+
28
+ #####################################
29
+ ### Classes
30
+ #####################################
31
+
32
+ ###
33
+ ### A peripheral_type in the JSS.
34
+ ###
35
+ ### A PeripheralType (as opposed to an individual {JSS::Peripheral}) is just an id, a name, and an Array of
36
+ ### Hashes describing the fields of data to be stored for peripherals of this type.
37
+ ###
38
+ ### See {#fields} for a desciption of how field definitions are stored.
39
+ ###
40
+ ### For manipulating the fields, see {#fields=}, {#set_field}, {#append_field}, {#prepend_field}, {#insert_field}, and {#delete_field}
41
+ ###
42
+ ### @see JSS::APIObject
43
+ ###
44
+ class PeripheralType < JSS::APIObject
45
+
46
+ #####################################
47
+ ### MixIns
48
+ #####################################
49
+
50
+ include JSS::Creatable
51
+ include JSS::Updatable
52
+
53
+ #####################################
54
+ ### Class Methods
55
+ #####################################
56
+
57
+ #####################################
58
+ ### Class Constants
59
+ #####################################
60
+
61
+ ### The base for REST resources of this class
62
+ RSRC_BASE = "peripheraltypes"
63
+
64
+ ### the hash key used for the JSON list output of all objects in the JSS
65
+ RSRC_LIST_KEY = :peripheral_types
66
+
67
+ ### The hash key used for the JSON object output.
68
+ ### It's also used in various error messages
69
+ RSRC_OBJECT_KEY = :peripheral_type
70
+
71
+ ### these keys, as well as :id and :name, are present in valid API JSON data for this class
72
+ VALID_DATA_KEYS = [:fields]
73
+
74
+ ### field types can be one of these, either String or Symbol
75
+ FIELD_TYPES = [:text, :menu]
76
+
77
+ #####################################
78
+ ### Attributes
79
+ #####################################
80
+
81
+ #####################################
82
+ ### Instance Methods
83
+ #####################################
84
+
85
+ ###
86
+ ### Initialize
87
+ ###
88
+ def initialize (args = {})
89
+
90
+ super
91
+
92
+ @fields = []
93
+ if @init_data[:fields]
94
+ @init_data[:fields].each{ |f| @fields[f[:order]] = f }
95
+ end
96
+ end # initialize
97
+
98
+ ### The definitions of the fields stored for this peripheral type.
99
+ ###
100
+ ### Each Hash defines a field of data to store. The keys are:
101
+ ### - :name, String, the name of the field
102
+ ### - :type, String or Symbol, the kind of data to be stored in the field, either :text or :menu
103
+ ### - :choices, Array of Strings - if type is :menu, these are the menu choices.
104
+ ### - :order, the one-based index of this field amongst it's peers.
105
+ ###
106
+ ### Since Arrays are zero-based, and the field order is one-based, keeping
107
+ ### a nil at the front of the Array will keep the :order number in sync with the
108
+ ### Array index of each field definition. This is done automatically by the field-editing
109
+ ### methods: {#fields=}, {#set_field}, {#append_field}, {#prepend_field}, {#insert_field},
110
+ ### and {#delete_field}.
111
+ ###
112
+ ### So the Array from the API comes like this:
113
+ ### [ {:type=>"text", :order=>1, :choices=>[], :name=>"make"},
114
+ ### {:type=>"text", :order=>2, :choices=>[], :name=>"model"},
115
+ ### {:type=>"text", :order=>3, :choices=>[], :name=>"family"},
116
+ ### {:type=>"text", :order=>4, :choices=>[], :name=>"serialnum"} ]
117
+ ### But will be stored in a PeripheralType instance like this:
118
+ ### [ nil,
119
+ ### {:type=>"text", :order=>1, :choices=>[], :name=>"make"},
120
+ ### {:type=>"text", :order=>2, :choices=>[], :name=>"model"},
121
+ ### {:type=>"text", :order=>3, :choices=>[], :name=>"family"},
122
+ ### {:type=>"text", :order=>4, :choices=>[], :name=>"serialnum"} ]
123
+ ###
124
+ ### therefore
125
+ ### myPerifType.fields[2]
126
+ ### will get you the second field, which has :order => 2.
127
+ ###
128
+ ### @return [Array<Hash>] The field definitions
129
+ ###
130
+ def fields
131
+ @fields
132
+ end
133
+
134
+ ###
135
+ ### Replace the entire Array of field definitions.
136
+ ### The :order of each will be set based on the indexes of the
137
+ ### Array provided.
138
+ ###
139
+ ### @param new_fields[Array<Hash>] the new field definitions
140
+ ###
141
+ ### @return [void]
142
+ ###
143
+ def fields= (new_fields)
144
+ unless new_fields.kind_of? Array and new_fields.reject{|c| c.kind_of? Hash }.empty?
145
+ raise JSS::InvalidDataError, "Argument must be an Array of Hashes."
146
+ end
147
+ raise "A peripheral type can have a maximmum of 20 fields" if new_fields.count > 20
148
+ new_fields.each{ |f| field_ok? f }
149
+ @fields = new_fields
150
+ order_fields
151
+ @need_to_update = true
152
+ end
153
+
154
+ ###
155
+ ### Replace the details of one specific field.
156
+ ###
157
+ ### The order must already exist. Otherwise use
158
+ ### {#append_field}, {#prepend_field}, or {#insert_field}
159
+ ###
160
+ ### @param order[Integer] which field are we replacing?
161
+ ###
162
+ ### @param field[Hash] the new field data
163
+ ###
164
+ ### @return [void]
165
+ ###
166
+ def set_field(order, field = {})
167
+ raise JSS::NoSuchItemError, "No field with number '#{order}'. Use #append_field, #prepend_field, or #insert_field" unless @fields[order]
168
+ field_ok? field
169
+ @fields[order] = field
170
+ @need_to_update = true
171
+ end
172
+
173
+ ###
174
+ ### Add a new field to the end of the field list
175
+ ###
176
+ ### @param field[Hash] the new field data
177
+ ###
178
+ ### @return [void]
179
+ ###
180
+ def append_field(field = {})
181
+ field_ok? field
182
+ @fields << field
183
+ order_fields
184
+ @need_to_update = true
185
+ end
186
+
187
+ ###
188
+ ### Add a new field to the beginning of the field list
189
+ ###
190
+ ### @param field[Hash] the new field data
191
+ ###
192
+ ### @return [void]
193
+ ###
194
+ def prepend_field(field = {})
195
+ field_ok? field
196
+ @fields.unshift field
197
+ order_fields
198
+ @need_to_update = true
199
+ end
200
+
201
+ ###
202
+ ### Add a new field to the middle of the fields Array.
203
+ ###
204
+ ### @param order[Integer] where does the new field go?
205
+ ###
206
+ ### @param field[Hash] the new field data
207
+ ###
208
+ ### @return [void]
209
+ ###
210
+ def insert_field(order,field = {})
211
+ field_ok? field
212
+ @fields.insert((order -1), field)
213
+ order_fields
214
+ @need_to_update = true
215
+ end
216
+
217
+ ###
218
+ ### Remove a field from the array of fields.
219
+ ###
220
+ ### @param order[Integer] which field to remove?
221
+ ###
222
+ ### @return [void]
223
+ ###
224
+ def delete_field(order)
225
+ if @fields[order]
226
+ raise JSS::MissingDataError, "Fields can't be empty" if @fields.count == 1
227
+ @fields.delete_at index
228
+ order_fields
229
+ @need_to_update = true
230
+ end
231
+ end
232
+
233
+
234
+
235
+ ##############################
236
+ ### private methods
237
+ ##############################
238
+ private
239
+
240
+ ###
241
+ ### is a Hash of field data OK for use in the JSS?
242
+ ### Return true or raise an exception
243
+ ###
244
+ def field_ok?(field)
245
+ raise JSS::InvalidDataError, "Field elements must be hashes with :name, :type, and possibly :choices" unless field.kind_of? Hash
246
+ raise JSS::InvalidDataError, "Fields require names" if field[:name].to_s.empty?
247
+ raise JSS::InvalidDataError, "Fields :type must be one of: :#{FIELD_TYPES.join(', :')}" unless FIELD_TYPES.include? field[:type].to_sym
248
+
249
+ if field[:type].to_sym == :menu
250
+ unless field[:choices].kind_of? Array and field[:choices].reject{|c| c.kind_of? String}.empty?
251
+ raise JSS::InvalidDataError, "Choices for menu fields must be an Array of Strings"
252
+ end # unless
253
+ else
254
+ field[:choices] = []
255
+ end # if type -- menu
256
+ true
257
+ end # def field ok?
258
+
259
+ ###
260
+ ### Close up gaps in the field order, and make each field's :order match it's array index
261
+ ###
262
+ def order_fields
263
+ @fields.compact!
264
+ @fields.each_index{|i| @fields[i][:order] = i+1}
265
+ @fields.unshift nil
266
+ end
267
+
268
+
269
+ ###
270
+ ###
271
+ ###
272
+ def rest_xml
273
+ order_fields
274
+ doc = REXML::Document.new APIConnection::XML_HEADER
275
+ pkg = doc.add_element RSRC_OBJECT_KEY.to_s
276
+ pkg.add_element('id').text = @id
277
+ pkg.add_element('name').text = @name
278
+ fields = pkg.add_element 'fields'
279
+
280
+ flds = @fields.compact
281
+ flds.each_index do |i|
282
+ field = fields.add_element 'field'
283
+ field.add_element('order').text =flds[i][:order]
284
+ field.add_element('name').text = flds[i][:name]
285
+ field.add_element('type').text = flds[i][:type].to_s
286
+ choices = field.add_element('choices')
287
+ unless flds[i][:choices].empty?
288
+ flds[i][:choices].each{|c| choices.add_element('choice').text = c}
289
+ end
290
+ end # each index do i
291
+ return doc.to_s
292
+ end # rest xml
293
+
294
+ end # class Peripheral
295
+ end # module