ruby-jss 0.6.3

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.

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