jss-api 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/lib/jss-api.rb +1 -191
  2. metadata +16 -146
  3. data/.yardopts +0 -7
  4. data/CHANGES.md +0 -88
  5. data/LICENSE.txt +0 -174
  6. data/README.md +0 -396
  7. data/THANKS.md +0 -6
  8. data/bin/cgrouper +0 -485
  9. data/bin/subnet-update +0 -400
  10. data/lib/jss-api/api_connection.rb +0 -400
  11. data/lib/jss-api/api_object.rb +0 -616
  12. data/lib/jss-api/api_object/advanced_search.rb +0 -389
  13. data/lib/jss-api/api_object/advanced_search/advanced_computer_search.rb +0 -95
  14. data/lib/jss-api/api_object/advanced_search/advanced_mobile_device_search.rb +0 -96
  15. data/lib/jss-api/api_object/advanced_search/advanced_user_search.rb +0 -95
  16. data/lib/jss-api/api_object/building.rb +0 -92
  17. data/lib/jss-api/api_object/category.rb +0 -147
  18. data/lib/jss-api/api_object/computer.rb +0 -852
  19. data/lib/jss-api/api_object/creatable.rb +0 -98
  20. data/lib/jss-api/api_object/criteriable.rb +0 -189
  21. data/lib/jss-api/api_object/criteriable/criteria.rb +0 -231
  22. data/lib/jss-api/api_object/criteriable/criterion.rb +0 -228
  23. data/lib/jss-api/api_object/department.rb +0 -93
  24. data/lib/jss-api/api_object/distribution_point.rb +0 -560
  25. data/lib/jss-api/api_object/extendable.rb +0 -221
  26. data/lib/jss-api/api_object/extension_attribute.rb +0 -457
  27. data/lib/jss-api/api_object/extension_attribute/computer_extension_attribute.rb +0 -362
  28. data/lib/jss-api/api_object/extension_attribute/mobile_device_extension_attribute.rb +0 -189
  29. data/lib/jss-api/api_object/extension_attribute/user_extension_attribute.rb +0 -117
  30. data/lib/jss-api/api_object/group.rb +0 -380
  31. data/lib/jss-api/api_object/group/computer_group.rb +0 -124
  32. data/lib/jss-api/api_object/group/mobile_device_group.rb +0 -139
  33. data/lib/jss-api/api_object/group/user_group.rb +0 -139
  34. data/lib/jss-api/api_object/ldap_server.rb +0 -535
  35. data/lib/jss-api/api_object/locatable.rb +0 -286
  36. data/lib/jss-api/api_object/matchable.rb +0 -97
  37. data/lib/jss-api/api_object/mobile_device.rb +0 -556
  38. data/lib/jss-api/api_object/netboot_server.rb +0 -148
  39. data/lib/jss-api/api_object/network_segment.rb +0 -414
  40. data/lib/jss-api/api_object/osx_configuration_profile.rb +0 -261
  41. data/lib/jss-api/api_object/package.rb +0 -812
  42. data/lib/jss-api/api_object/peripheral.rb +0 -335
  43. data/lib/jss-api/api_object/peripheral_type.rb +0 -295
  44. data/lib/jss-api/api_object/policy.rb +0 -898
  45. data/lib/jss-api/api_object/purchasable.rb +0 -316
  46. data/lib/jss-api/api_object/removable_macaddr.rb +0 -98
  47. data/lib/jss-api/api_object/scopable.rb +0 -136
  48. data/lib/jss-api/api_object/scopable/scope.rb +0 -621
  49. data/lib/jss-api/api_object/script.rb +0 -631
  50. data/lib/jss-api/api_object/self_servable.rb +0 -355
  51. data/lib/jss-api/api_object/site.rb +0 -93
  52. data/lib/jss-api/api_object/software_update_server.rb +0 -109
  53. data/lib/jss-api/api_object/updatable.rb +0 -117
  54. data/lib/jss-api/api_object/uploadable.rb +0 -138
  55. data/lib/jss-api/api_object/user.rb +0 -272
  56. data/lib/jss-api/client.rb +0 -504
  57. data/lib/jss-api/compatibility.rb +0 -66
  58. data/lib/jss-api/composer.rb +0 -171
  59. data/lib/jss-api/configuration.rb +0 -306
  60. data/lib/jss-api/db_connection.rb +0 -298
  61. data/lib/jss-api/exceptions.rb +0 -95
  62. data/lib/jss-api/ruby_extensions.rb +0 -35
  63. data/lib/jss-api/ruby_extensions/filetest.rb +0 -43
  64. data/lib/jss-api/ruby_extensions/hash.rb +0 -79
  65. data/lib/jss-api/ruby_extensions/ipaddr.rb +0 -91
  66. data/lib/jss-api/ruby_extensions/pathname.rb +0 -77
  67. data/lib/jss-api/ruby_extensions/string.rb +0 -59
  68. data/lib/jss-api/ruby_extensions/time.rb +0 -63
  69. data/lib/jss-api/server.rb +0 -108
  70. data/lib/jss-api/utility.rb +0 -416
  71. data/lib/jss-api/version.rb +0 -31
@@ -1,228 +0,0 @@
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
- module Criteriable
29
-
30
- #####################################
31
- ### Module Variables
32
- #####################################
33
-
34
- #####################################
35
- ### Module Methods
36
- #####################################
37
-
38
- #####################################
39
- ### Classes
40
- #####################################
41
-
42
- ### This class defines a single criterion used in advanced searches and
43
- ### smart groups throughout the JSS module.
44
- ###
45
- ### They are used within {JSS::Criteriable::Criteria} instances which store an
46
- ### array of these objects and provides methods for working with them as a group.
47
- ###
48
- ### The classes that mix-in {JSS::Criteriable} each have a :criteria attribute which
49
- ### holds one {JSS::Criteriable::Criteria}
50
- ###
51
- ### See {JSS::Criteriable} for examples
52
- ###
53
- class Criterion
54
-
55
- #####################################
56
- ### Mix Ins
57
- #####################################
58
-
59
- include Comparable # this allows us compare instances using <=>
60
-
61
- #####################################
62
- ### Class Constants
63
- #####################################
64
-
65
- ### These are the available search-types for building criteria
66
- SEARCH_TYPES = [
67
- "is",
68
- "is not",
69
- "like",
70
- "not like",
71
- "has",
72
- "does not have",
73
- "more than",
74
- "less than",
75
- "before (yyyy-mm-dd)",
76
- "after (yyyy-mm-dd)",
77
- "more than x days ago",
78
- "less than x days ago",
79
- "in more than x days",
80
- "in less than x days",
81
- "member of",
82
- "not member of",
83
- "current",
84
- "not current"
85
- ]
86
-
87
- ### the acceptable symboles for and/or
88
- AND_OR = [:and, :or]
89
-
90
- #####################################
91
- ### Attributes
92
- #####################################
93
-
94
- ### @return [Integer] zero-based index of this criterion within an array of criteria
95
- ### used for an advanced search or smart group.
96
- ### This is maintained automaticaly by the enclosing Criteria object
97
- attr_accessor :priority
98
-
99
- ### @return [Symbol] :and or :or - the and_or value for associating this criterion with the previous one
100
- attr_reader :and_or
101
-
102
- ### @return [String] the name of the field being searched
103
- attr_accessor :name
104
-
105
- ### @return [String] the comparator between the field and the value, must be one of SEARCH_TYPES
106
- ### @see #criteria=
107
- attr_reader :search_type
108
-
109
- ### @return [String] the value being searched for in the field named by :name
110
- attr_reader :value
111
-
112
- ###
113
- ### @param args[Hash] a hash of settings for the new criterion
114
- ### @option args :and_or [String, Symbol] :and, or :or. How should this criterion be join with its predecessor?
115
- ### @option args :name [String] the name of a Criterion as is visible in the JSS webapp.
116
- ### @option args :search_type [String] one of SEARCH_TYPES, the comparison between the stored value and :value
117
- ### @option args :value [String] the value to compare with that stored for :name
118
- ###
119
- ### @note :priority is maintained by the JSS::Criteriable::Criteria object holding this instance
120
- ###
121
- def initialize(args = {})
122
-
123
- @priority = args[:priority]
124
-
125
- if args[:and_or]
126
- @and_or = args[:and_or].to_sym
127
- raise JSS::InvalidDataError, ":and_or must be 'and' or 'or'." unless AND_OR.include? @and_or
128
- end
129
-
130
- @name = args[:name]
131
-
132
- if args[:search_type]
133
- raise JSS::InvalidDataError, "Invalid :search_type" unless SEARCH_TYPES.include? args[:search_type]
134
- @search_type = args[:search_type]
135
- end
136
-
137
- @value = args[:value]
138
- end # init
139
-
140
- ###
141
- ### Set a new and_or for the criteron
142
- ###
143
- ### @param new_val[Symbol] the new and_or
144
- ###
145
- ### @return [void]
146
- ###
147
- def and_or= (new_val)
148
- @and_or = new_val.to_sym
149
- raise JSS::InvalidDataError, ":and_or must be 'and' or 'or'." unless AND_OR.include? @and_or.to_sym
150
- end
151
-
152
- ###
153
- ### Set a new search type for the criteron
154
- ###
155
- ### @param new_val[String] the new search type
156
- ###
157
- ### @return [void]
158
- ###
159
- def search_type= (new_val)
160
- raise JSS::InvalidDataError, "Invalid :search_type" unless SEARCH_TYPES.include? new_val
161
- @search_type = new_val
162
- end
163
-
164
- ###
165
- ### Set a new value for the criteron
166
- ###
167
- ### @param new_val[Integer,String] the new value
168
- ###
169
- ### @return [void]
170
- ###
171
- def value=(new_val)
172
- case @search_type
173
-
174
- when *["more than", "less than", "more than x days ago", "less than x days ago"]
175
- raise JSS::InvalidDataError, "Value must be an integer for search type '#{new_val}'" unless new_val =~ /^\d+$/
176
-
177
- when *["before (yyyy-mm-dd)", "after (yyyy-mm-dd)"]
178
- raise JSS::InvalidDataError, "Value must be a a date in the format yyyy-mm-dd for search type '#{new_val}'" unless new_val =~ /^\d\d\d\d-\d\d-\d\d$/
179
-
180
- end # case
181
-
182
- @value = new_val
183
-
184
- end
185
-
186
- ###
187
- ### @return [String] All our values except priority joined together
188
- ### for comparing this Criterion to another for equality and order
189
- ###
190
- ### @see #<=>
191
- ###
192
- def signature
193
- [@and_or, @name, @search_type, @value].join ","
194
- end
195
-
196
-
197
- ###
198
- ### Comparison - allows the Comparable module to do its work
199
- ###
200
- ### @return [Integer] -1, 0, or 1
201
- ###
202
- ### @see Comparable
203
- ###
204
- def <=>(other)
205
- self.signature <=> other.signature
206
- end
207
-
208
- ###
209
- ### @api private
210
- ###
211
- ### @return [REXML::Element] The xml element for the criterion, to be embeded in that of
212
- ### a Criteria instance
213
- ###
214
- ### @note For this class, rest_xml can't be a private method.
215
- ###
216
- def rest_xml
217
- crn = REXML::Element.new 'criterion'
218
- crn.add_element('priority').text = @priority
219
- crn.add_element('and_or').text = @and_or
220
- crn.add_element('name').text = @name
221
- crn.add_element('search_type').text = @search_type
222
- crn.add_element('value').text = @value
223
- return crn
224
- end
225
-
226
- end # class criterion
227
- end # module Criteriable
228
- end # module
@@ -1,93 +0,0 @@
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 department in the JSS.
42
- ### These are simple, in that they only have an ID and a name
43
- ###
44
- ### @see JSS::APIObject
45
- ###
46
- class Department < JSS::APIObject
47
-
48
- #####################################
49
- ### Mix-Ins
50
- #####################################
51
- include JSS::Creatable
52
- include JSS::Updatable
53
-
54
- #####################################
55
- ### Class Methods
56
- #####################################
57
-
58
- #####################################
59
- ### Class Constants
60
- #####################################
61
-
62
- ### The base for REST resources of this class
63
- RSRC_BASE = "departments"
64
-
65
- ### the hash key used for the JSON list output of all objects in the JSS
66
- RSRC_LIST_KEY = :departments
67
-
68
- ### The hash key used for the JSON object output.
69
- ### It's also used in various error messages
70
- RSRC_OBJECT_KEY = :department
71
-
72
- ### these keys, as well as :id and :name, are present in valid API JSON data for this class
73
- VALID_DATA_KEYS = []
74
-
75
- #####################################
76
- ### Attributes
77
- #####################################
78
-
79
- #####################################
80
- ### Constructor
81
- #####################################
82
-
83
- ###
84
- ### See JSS::APIObject#initialize
85
- ###
86
-
87
- #####################################
88
- ### Public Instance Methods
89
- #####################################
90
-
91
- end # class department
92
-
93
- end # module
@@ -1,560 +0,0 @@
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
- ### the master dist. point, see JSS.master_distribution_point
33
- @@master_distribution_point = nil
34
-
35
- ### the dist point for this machine right now
36
- @@my_distribution_point =nil
37
-
38
- #####################################
39
- ### Module Methods
40
- #####################################
41
-
42
-
43
-
44
- ###
45
- ### A Distribution Point in the JSS
46
- ###
47
- ### As well as the normal Class and Instance methods for {APIObject} subclasses, the
48
- ### DistributionPoint class provides more interaction with other parts of the API.
49
- ###
50
- ### Beyond the standard listing methods DistributionPoint.all, .all_ids, etc, every JSS
51
- ### has a single "master" distribution point. The Class method {DistributionPoint.master_distribution_point} will
52
- ### return the JSS::DistributionPoint object for that master.
53
- ###
54
- ### Also, some network segments have specific DistributionPoints assigned to them. Calling the Class method
55
- ### {DistributionPoint.my_distribution_point} will return a JSS::DistributionPoint object for your local IP address.
56
- ###
57
- ### Once you have an instance of JSS::DistributionPoint, you can mount it (on a Mac) by calling its {#mount} method
58
- ### and unmount it with {#unmount}. The {JSS::Package} and possibly {JSS::Script} classes use this to upload
59
- ### items to the master.
60
- ###
61
- ### @see JSS::APIObject
62
- ###
63
- class DistributionPoint < JSS::APIObject
64
-
65
- #####################################
66
- ### Mix-Ins
67
- #####################################
68
-
69
- #####################################
70
- ### Class Constants
71
- #####################################
72
-
73
- ### The base for REST resources of this class
74
- RSRC_BASE = "distributionpoints"
75
-
76
- ### the hash key used for the JSON list output of all objects in the JSS
77
- ### its also used in various error messages
78
- RSRC_LIST_KEY = :distribution_points
79
-
80
- ### The hash key used for the JSON object output.
81
- ### It's also used in various error messages
82
- RSRC_OBJECT_KEY = :distribution_point
83
-
84
- ### these keys, as well as :id and :name, are present in valid API JSON data for this class
85
- VALID_DATA_KEYS = [:read_only_username, :ssh_username, :is_master ]
86
-
87
- ### what are the mount options? these are comma-separated, and are passed with -o
88
- MOUNT_OPTIONS = 'nobrowse'
89
-
90
- ### An empty SHA256 digest
91
- EMPTY_PW_256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
92
-
93
-
94
-
95
- #####################################
96
- ### Class Variables
97
- #####################################
98
-
99
- @@master_distribution_point = nil
100
-
101
- @@my_distribution_point = nil
102
-
103
- #####################################
104
- ### Class Methods
105
- #####################################
106
-
107
- ### Get the DistributionPoint instance for the master
108
- ### distribution point in the JSS. If there's only one
109
- ### in the JSS, return it even if not marked as master.
110
- ###
111
- ### @return [JSS::DistributionPoint]
112
- ###
113
- def self.master_distribution_point(refresh = false)
114
- @@master_distribution_point = nil if refresh
115
- return @@master_distribution_point if @@master_distribution_point
116
-
117
- case self.all.count
118
- when 0
119
- raise JSS::NoSuchItemError, "No distribution points defined"
120
- when 1
121
- self.new :id => self.all_ids[0]
122
- else
123
- self.new :id => :master
124
- end
125
- end
126
-
127
- ### Get the DistributionPoint instance for the machine running
128
- ### this code, based on its IP address. If none is defined for this IP address,
129
- ### use the result of master_distribution_point
130
- ###
131
- ### @param refresh[Boolean] should the distribution point be re-queried?
132
- ###
133
- ### @return [JSS::DistributionPoint]
134
- ###
135
- def self.my_distribution_point(refresh = false)
136
- @@my_distribution_point = nil if refresh
137
- return @@my_distribution_point if @@my_distribution_point
138
-
139
- my_net_seg = JSS::NetworkSegment.my_network_segment[0]
140
- specific = if my_net_seg
141
- JSS::NetworkSegment.new(:id => my_net_seg).distribution_point
142
- else
143
- nil
144
- end
145
- return specific ? self.new(:name => specific) : self.master_distribution_point
146
- end
147
-
148
- #####################################
149
- ### Class Attributes
150
- #####################################
151
-
152
- ### @return [String] the hostname of this DP
153
- attr_reader :ip_address
154
-
155
- ### @return [String] the local path on the server to the distribution point directory
156
- attr_reader :local_path
157
-
158
- ### @return [String] load balanacing enabled?
159
- attr_reader :enable_load_balancing
160
-
161
- ### @return [Integer] the id of the DP to use for failover
162
- attr_reader :failover_point
163
-
164
- ### @return [Boolean] is this the master DP?
165
- attr_reader :is_master
166
-
167
- ### FileService Access
168
-
169
- ### @return [String] Protocol for fileservice access (e.g. AFP, SMB)
170
- attr_reader :connection_type
171
-
172
- ### @return [Integer] the port for fileservice access
173
- attr_reader :share_port
174
-
175
- ### @return [String] the name of the fileservice sharepoint
176
- attr_reader :share_name
177
-
178
- ### @return [String] the read-write username for fileservice access
179
- attr_reader :read_write_username
180
-
181
- ### @return [String] the read-write password as a SHA256 digest
182
- attr_reader :read_write_password_sha256
183
-
184
- ### @return [String] read-only username for fileservice
185
- attr_reader :read_only_username
186
-
187
- ### @return [String] read-only password as a SHA256 digest
188
- attr_reader :read_only_password_sha256
189
-
190
- ### @return [String] work group or domain for SMB
191
- attr_reader :workgroup_or_domain
192
-
193
- ### http(s) access
194
-
195
- ### @return [Boolean] are http downloads available from this DP?
196
- attr_reader :http_downloads_enabled
197
-
198
- ### @return [String] the protocol to use for http downloads (http/https)
199
- attr_reader :protocol
200
-
201
- ### @return [Integer] the port for http access
202
- attr_reader :port
203
-
204
- ### @return [String] the "context" for http downloads (what goes after the hostname part of the URL)
205
- attr_reader :context
206
-
207
- ### @return [Boolean] do http downloads work without auth?
208
- attr_reader :no_authentication_required
209
-
210
- ### @return [Boolean] do http downloads use cert. authentication?
211
- attr_reader :certificate_required
212
-
213
- ### @return [Boolean] do http downloads use user/pw auth?
214
- attr_reader :username_password_required
215
-
216
- ### @return [String] the username to use for http downloads if needed for user/pw auth
217
- attr_reader :http_username
218
-
219
- ### @return [String] the password for http downloads, if needed, as a SHA256 digest
220
- attr_reader :http_password_sha256
221
-
222
- ### @return [String] the name of the cert. used for http cert. auth.
223
- attr_reader :certificate
224
-
225
- ### @return [String] the URL for http downloads
226
- attr_reader :http_url
227
-
228
- ### @return [String] the URL to use if this one doesn't work
229
- attr_reader :failover_point_url
230
-
231
- ### ssh (scp, rsync, sftp) access
232
-
233
- ### @return [String] ssh username
234
- attr_reader :ssh_username
235
-
236
- ### @return [String] the ssh password as a SHA256 digest
237
- attr_reader :ssh_password_sha256
238
-
239
- ###
240
- ### As well as the standard :id, :name, and :data, you can
241
- ### instantiate this class with :id => :master, in which case you'll
242
- ### get the Master Distribution Point as defined in the JSS.
243
- ### An error will be raised if one hasn't been defined.
244
- ###
245
- ### You can also do this more easily by calling JSS.master_distribution_point
246
- ###
247
- def initialize(args = {})
248
-
249
- @init_data = nil
250
-
251
- ### looking for master?
252
- if args[:id] == :master
253
-
254
- self.class.all_ids.each do |id|
255
- @init_data = JSS::API.get_rsrc("#{RSRC_BASE}/id/#{id}")[RSRC_OBJECT_KEY]
256
- if @init_data[:is_master]
257
- @id = @init_data[:id]
258
- @name = @init_data[:name]
259
- break
260
- end # if data is master
261
- @init_data = nil
262
- end # each id
263
- end # if args is master
264
-
265
- if @init_data.nil?
266
- super(args)
267
- end
268
-
269
- @ip_address = @init_data[:ip_address]
270
- @local_path = @init_data[:local_path]
271
- @enable_load_balancing = @init_data[:enable_load_balancing]
272
- @failover_point = @init_data[:failover_point]
273
- @is_master = @init_data[:is_master]
274
-
275
- @connection_type = @init_data[:connection_type]
276
- @share_port = @init_data[:share_port]
277
- @share_name = @init_data[:share_name]
278
- @workgroup_or_domain = @init_data[:workgroup_or_domain]
279
-
280
- @read_write_username = @init_data[:read_write_username]
281
- @read_write_password_sha256 = @init_data[:read_write_password_sha256]
282
- @read_only_username = @init_data[:read_only_username]
283
- @read_only_password_sha256 = @init_data[:read_only_password_sha256]
284
- @ssh_username = @init_data[:ssh_username]
285
- @ssh_password_sha256 = @init_data[:ssh_password_sha256]
286
- @http_username = @init_data[:http_username]
287
- @http_password_sha256 = @init_data[:http_password_sha256]
288
-
289
-
290
- @http_downloads_enabled = @init_data[:http_downloads_enabled]
291
- @protocol = @init_data[:protocol]
292
- @port = @init_data[:port]
293
- @context = @init_data[:context]
294
- @no_authentication_required = @init_data[:no_authentication_required]
295
- @certificate_required = @init_data[:certificate_required]
296
- @username_password_required = @init_data[:username_password_required]
297
- @certificate = @init_data[:certificate]
298
- @http_url = @init_data[:http_url]
299
- @failover_point_url = @init_data[:failover_point_url]
300
-
301
-
302
- @port = @init_data[:ssh_password]
303
-
304
- ### Note, as of Casper 9.3:
305
- ### :management_password_md5=>"xxxxx"
306
- ### and
307
- ### :management_password_sha256=> "xxxxxxxxxx"
308
- ### Are the read/write password
309
- ###
310
- ### An empty passwd is
311
- ### MD5 = d41d8cd98f00b204e9800998ecf8427e
312
- ### SHA256 = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
313
- ###
314
- ### Seemms the read-only pw isn't available in the API
315
-
316
-
317
- ### if we mount for fileservice, where's the mountpoint?
318
- @mountpoint = Pathname.new "/Volumes/CasperDistribution-id-#{@id}"
319
-
320
- end #init
321
-
322
- ###
323
- ### Check the validity of a password.
324
- ###
325
- ### @param user[Symbol] one of :ro, :rw, :ssh, :http
326
- ###
327
- ### @param pw[String] the password to check for the given user
328
- ###
329
- ### @return [Boolean,Nil] was the password correct?
330
- ### nil is returned if there is no password set in the JSS.
331
- ###
332
- def check_pw(user, pw)
333
- raise JSS::InvalidDataError, "The first parameter must be one of :ro, :rw, :ssh, :http" unless [:ro, :rw, :ssh, :http].include? user
334
- sha256 = case user
335
- when :rw then @read_write_password_sha256
336
- when :ro then @read_only_password_sha256
337
- when :http then @http_password_sha256
338
- when :ssh then @ssh_password_sha256
339
- end # case
340
-
341
- return nil if sha256 == EMPTY_PW_256
342
-
343
- sha256 == Digest::SHA2.new(256).update(pw).to_s
344
- end
345
-
346
- ### Check to see if this dist point is reachable for downloads (read-only)
347
- ### via either http, if available, or filesharing.
348
- ###
349
- ### @param pw[String] the read-only password to use for checking the connection
350
- ### If http downloads are enabled, and no http password is required
351
- ### this can be omitted.
352
- ###
353
- ### @param check_http[Boolean] should we try the http download first, if enabled?
354
- ### If you're intentionally using the ro password for filesharing, and want to check
355
- ### only filesharing, then set this to false.
356
- ###
357
- ### @return [FalseClass, Symbol] false if not reachable, otherwise :http or :mountable
358
- ###
359
- def reachable_for_download? (pw = '', check_http = true)
360
- pw ||= ''
361
- http_checked = ""
362
- if check_http && http_downloads_enabled
363
- if @username_password_required
364
- # we don't check the pw here, because if the connection fails, we'll
365
- # drop down below to try the password for mounting.
366
- # we'll escape all the chars that aren't unreserved
367
- reserved_chars = Regexp.new("[^#{URI::REGEXP::PATTERN::UNRESERVED}]")
368
- user_pass = "#{URI.escape @http_username,reserved_chars}:#{URI.escape ro_pw, reserved_chars}@"
369
- url = @http_url.sub "://#{@ip_address}", "://#{user_pass}#{@ip_address}"
370
- else
371
- url = @http_url
372
- end
373
-
374
- begin
375
- open(url).read
376
- return :http
377
- rescue
378
- http_checked = "http and "
379
- end
380
- end # if check_http && http_downloads_enabled
381
-
382
- return :mountable if mounted?
383
-
384
- return false unless check_pw :ro , pw
385
-
386
- begin
387
- mount pw, :ro
388
- return :mountable
389
- rescue
390
- return false
391
- ensure
392
- unmount
393
- end
394
- end
395
-
396
- ### Check to see if this dist point is reachable for uploads (read-write)
397
- ### via filesharing.
398
- ###
399
- ### @param pw[String] the read-write password to use for checking the connection
400
- ###
401
- ### @return [FalseClass, Symbol] false if not reachable, otherwise :mountable
402
- ###
403
- def reachable_for_upload? (pw)
404
- return :mountable if mounted?
405
- return false unless check_pw :rw , pw
406
- begin
407
- mount pw, :rw
408
- return :mountable
409
- rescue
410
- return false
411
- ensure
412
- unmount
413
- end
414
- end
415
-
416
-
417
- ###
418
- ### Mount this distribution point locally.
419
- ###
420
- ### @param pw[String,Symbol] the read-only or read-write password for this DistributionPoint
421
- ### If :prompt, the user is promted on the commandline to enter the password for the :user.
422
- ### If :stdin#, the password is read from a line of std in represented by the digits at #,
423
- ### so :stdin3 reads the passwd from the third line of standard input. defaults to line 2,
424
- ### if no digit is supplied. see {JSS.stdin}
425
- ###
426
- ### @param access[Symbol] how to mount the DistributionPoint, and which password to expect.
427
- ### :ro (or anything else) = read-only, :rw = read-write
428
- ###
429
- ### @return [Pathname] the mountpoint.
430
- ###
431
- def mount(pw = nil, access = :ro)
432
- return @mountpoint if mounted?
433
- access = :ro unless access == :rw
434
-
435
- password = if pw == :prompt
436
- JSS.prompt_for_password "Enter the password for the #{access} user '#{access == :ro ? @read_only_username : @read_write_username }':"
437
- elsif pw.is_a?(Symbol) and pw.to_s.start_with?('stdin')
438
- pw.to_s =~ /^stdin(\d+)$/
439
- line = $1
440
- line ||= 2
441
- JSS.stdin line
442
- else
443
- pw
444
- end
445
-
446
- pwok = check_pw(access, password)
447
- unless pwok
448
- msg = pwok.nil? ? "No #{access} password set in the JSS" : "Incorrect password for #{access} account"
449
- raise JSS::InvalidDataError, msg
450
- end
451
-
452
- username = access == :ro ? @read_only_username : @read_write_username
453
-
454
- safe_pw = URI.escape password, /[^a-zA-Z\d]/
455
-
456
- @mount_url = "#{@connection_type.downcase}://#{username}:#{safe_pw}@#{@ip_address}/#{@share_name}"
457
- @mnt_cmd = case @connection_type.downcase
458
- when 'smb' then '/sbin/mount_smbfs'
459
- when 'afp' then '/sbin/mount_afp'
460
- else raise "Can't mount distribution point #{@name}: no known connection type."
461
- end
462
-
463
- @mountpoint.mkpath
464
-
465
- mount_out = `#{@mnt_cmd} -o '#{MOUNT_OPTIONS}' '#{@mount_url}' '#{@mountpoint}' 2>&1`
466
- if $?.exitstatus == 0 and @mountpoint.mountpoint?
467
- #if system @mnt_cmd.to_s, *['-o', MOUNT_OPTIONS, @mount_url, @mountpoint.to_s]
468
- @mounted = access
469
- else
470
- @mountpoint.rmdir if @mountpoint.directory?
471
- @mounted = nil
472
- raise JSS::FileServiceError, "Can't mount #{@ip_address}: #{mount_out}"
473
- end
474
- return @mountpoint
475
- end # mount
476
-
477
- ###
478
- ### Unmount the distribution point.
479
- ###
480
- ### Does nothing if it wasn't mounted with #mount.
481
- ###
482
- ### @return [void]
483
- ###
484
- def unmount
485
- return nil unless mounted?
486
- if system "umount '#{@mountpoint}'"
487
- @mountpoint.rmdir if @mountpoint.directory? and (not @mountpoint.mountpoint?)
488
- @mounted = false
489
- else
490
- raise JSS::FileServiceError ,"There was a problem unmounting #{@mountpoint}"
491
- end
492
- nil
493
- end # unmount
494
-
495
-
496
- ###
497
- ### Is this thing mounted right now?
498
- ###
499
- ### @return [Boolean]
500
- ###
501
- def mounted?
502
- @mountpoint.directory? and @mountpoint.mountpoint?
503
- end
504
-
505
-
506
- #### aliases
507
- alias hostname ip_address
508
- alias umount unmount
509
-
510
- ######################################
511
- ### Private Instance Methods
512
- ######################################
513
- private
514
-
515
- ###
516
- ### Unused - until I get around to making DP's updatable
517
- ###
518
- ### the XML representation of the current state of this object,
519
- ### for POSTing or PUTting back to the JSS via the API
520
- ### Will be supported for Dist Points some day, I'm sure.
521
- ###
522
- def rest_xml
523
- doc = REXML::Document.new
524
- dp = doc.add_element "distribution_point"
525
- dp.add_element(:name.to_s).text = @name
526
- dp.add_element(:ip_address.to_s).text = @ip_address
527
- dp.add_element(:local_path.to_s).text = @local_path
528
- dp.add_element(:enable_load_balancing.to_s).text = @enable_load_balancing
529
- dp.add_element(:failover_point.to_s).text = @failover_point
530
- dp.add_element(:is_master.to_s).text = @is_master
531
-
532
- dp.add_element(:connection_type.to_s).text = @connection_type
533
- dp.add_element(:share_port.to_s).text = @share_port
534
- dp.add_element(:share_name.to_s).text = @share_name
535
- dp.add_element(:read_write_username.to_s).text = @read_write_username
536
- dp.add_element(:read_write_password.to_s).text = @read_write_password
537
- dp.add_element(:read_only_username.to_s).text = @read_only_username
538
- dp.add_element(:read_only_password.to_s).text = @read_only_password
539
- dp.add_element(:workgroup_or_domain.to_s).text = @workgroup_or_domain
540
-
541
- dp.add_element(:http_downloads_enabled.to_s).text = @http_downloads_enabled
542
- dp.add_element(:protocol.to_s).text = @protocol
543
- dp.add_element(:port.to_s).text = @port
544
- dp.add_element(:context.to_s).text = @context
545
- dp.add_element(:no_authentication_required.to_s).text = @no_authentication_required
546
- dp.add_element(:certificate_required.to_s).text = @certificate_required
547
- dp.add_element(:username_password_required.to_s).text = @username_password_required
548
- dp.add_element(:http_username.to_s).text = @http_username
549
- dp.add_element(:certificate.to_s).text = @certificate
550
- dp.add_element(:http_url.to_s).text = @http_url
551
- dp.add_element(:failover_point_url.to_s).text = @failover_point_url
552
-
553
- dp.add_element(:ssh_username.to_s).text = @ssh_username
554
- dp.add_element(:ssh_password.to_s).text = @ssh_password if @ssh_password
555
-
556
- return doc.to_s
557
- end #rest_xml
558
-
559
- end # class
560
- end # module