ruby-jss 0.9.2 → 0.10.0a1
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.
- checksums.yaml +4 -4
- data/CHANGES.md +13 -1
- data/README.md +7 -7
- data/bin/cgrouper +6 -6
- data/bin/netseg-update +1 -1
- data/lib/jss.rb +1 -0
- data/lib/jss/api_connection.rb +428 -44
- data/lib/jss/api_object.rb +119 -68
- data/lib/jss/api_object/account.rb +12 -12
- data/lib/jss/api_object/advanced_search.rb +12 -12
- data/lib/jss/api_object/categorizable.rb +4 -4
- data/lib/jss/api_object/category.rb +2 -2
- data/lib/jss/api_object/computer.rb +111 -58
- data/lib/jss/api_object/computer_invitation.rb +2 -2
- data/lib/jss/api_object/creatable.rb +19 -8
- data/lib/jss/api_object/criteriable/criteria.rb +8 -8
- data/lib/jss/api_object/distribution_point.rb +14 -48
- data/lib/jss/api_object/extension_attribute.rb +14 -11
- data/lib/jss/api_object/extension_attribute/computer_extension_attribute.rb +18 -18
- data/lib/jss/api_object/group.rb +7 -7
- data/lib/jss/api_object/ldap_server.rb +51 -60
- data/lib/jss/api_object/locatable.rb +2 -2
- data/lib/jss/api_object/matchable.rb +8 -9
- data/lib/jss/api_object/mobile_device.rb +61 -59
- data/lib/jss/api_object/mobile_device_application.rb +3 -3
- data/lib/jss/api_object/network_segment.rb +24 -19
- data/lib/jss/api_object/package.rb +6 -6
- data/lib/jss/api_object/peripheral.rb +5 -5
- data/lib/jss/api_object/policy.rb +5 -5
- data/lib/jss/api_object/restricted_software.rb +4 -4
- data/lib/jss/api_object/scopable/scope.rb +3 -3
- data/lib/jss/api_object/script.rb +1 -1
- data/lib/jss/api_object/self_servable.rb +3 -3
- data/lib/jss/api_object/self_servable/icon.rb +7 -2
- data/lib/jss/api_object/updatable.rb +2 -2
- data/lib/jss/api_object/uploadable.rb +1 -1
- data/lib/jss/api_object/user.rb +2 -2
- data/lib/jss/composer.rb +37 -10
- data/lib/jss/ruby_extensions/string.rb +51 -42
- data/lib/jss/server.rb +27 -6
- data/lib/jss/utility.rb +44 -0
- data/lib/jss/validate.rb +85 -0
- data/lib/jss/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3796577e296c595860954645bc0a2596f14245ff
|
4
|
+
data.tar.gz: 1ef961ef3629054e53f04415999bb02525c6973a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 449baa374a0229a15335eb9d96e5815fac87537176d7d9abad9cc9e3be39538b11cc575ff2a6651ba5e820e6f9724339fb2e32720f4fa48b431440cc3e32c873
|
7
|
+
data.tar.gz: 9c1f058392f666a6bc812beadb9d36891ab6e49df7f4c47e3ecce7faa896e35108ed2a97c32bfdffa5da367f88ff7832f94c01f4ca59bfc4152f0e6b5345f3d0
|
data/CHANGES.md
CHANGED
@@ -1,6 +1,18 @@
|
|
1
1
|
# Change History
|
2
2
|
|
3
|
-
## v0.9.
|
3
|
+
## v0.9.3 2017-08-08
|
4
|
+
|
5
|
+
- Add: JSS::Computer instance now allow you to modify mac_address, alt_mac_address, udid, and serial_number.
|
6
|
+
Note: even tho the WebUI doesn't allow editing of the serial_number, the API does and doing so can be useful
|
7
|
+
for dealing with duplicate SN's when a new logic board with a new udid creates a new computer entry.
|
8
|
+
- Add: JSS::Validate module, to consoliday generic data-validation methods. Methods will be moved to it from
|
9
|
+
other places over time.
|
10
|
+
|
11
|
+
## v0.9.2 2017-07-25
|
12
|
+
|
13
|
+
- Fix: parsing of JSS versions > 9.99
|
14
|
+
|
15
|
+
## v0.9.0 2017-07-17
|
4
16
|
|
5
17
|
- Add: JSS::MobileDevice.all_apple_tvs class method
|
6
18
|
- Add: JSS::MobileDevice.management_history method, and related methods in instances
|
data/README.md
CHANGED
@@ -99,11 +99,11 @@ ns.save
|
|
99
99
|
Before you can work with JSS Objects via the API, you have to connect to it.
|
100
100
|
|
101
101
|
The constant {JSS::API} contains the connection to the API (a singleton instance of {JSS::APIConnection}). When the JSS Module is first loaded, it isn't
|
102
|
-
connected. To remedy that, use JSS.
|
102
|
+
connected. To remedy that, use JSS.api.connect, passing it values for the connection. In this example, those values are stored
|
103
103
|
in the local variables jss_user, jss_user_pw, and jss_server_hostname, and others are left as default.
|
104
104
|
|
105
105
|
```ruby
|
106
|
-
JSS.
|
106
|
+
JSS.api.connect user: jss_user, pw: jss_user_pw, server: jss_server_hostname
|
107
107
|
```
|
108
108
|
|
109
109
|
Make sure the user has privileges in the JSS to do things with desired Objects.
|
@@ -301,7 +301,7 @@ Other useful classes:
|
|
301
301
|
|
302
302
|
The {JSS::Configuration} singleton class is used to read, write, and use site-specific defaults for the JSS module. When the Module is required, the single instance of {JSS::Configuration} is created and stored in the constant {JSS::CONFIG}. At that time the system-wide file /etc/jss_gem.conf is examined if it exists, and the items in it are loaded into the attributes of {JSS::CONFIG}. The user-specific file ~/.jss_gem.conf then is examined if it exists, and any items defined there will override those values from the system-wide file.
|
303
303
|
|
304
|
-
The values defined in those files are used as defaults throughout the module. Currently, those values are only related to establishing the API connection. For example, if a server name is defined, then a :server does not have to be specified when calling {JSS::API#connect}. Values provided explicitly when calling JSS.
|
304
|
+
The values defined in those files are used as defaults throughout the module. Currently, those values are only related to establishing the API connection. For example, if a server name is defined, then a :server does not have to be specified when calling {JSS::API#connect}. Values provided explicitly when calling JSS.api.connect will override the config values.
|
305
305
|
|
306
306
|
While the {JSS::Configuration} class provides methods for changing the values, saving the files, and re-reading them, or reading an arbitrary file, the files are text files with a simple format, and can be created by any means desired. The file format is one attribute per line, thus:
|
307
307
|
|
@@ -326,11 +326,11 @@ api_username: readonly-api-user
|
|
326
326
|
api_verify_cert: false
|
327
327
|
```
|
328
328
|
|
329
|
-
and then any calls to JSS.
|
329
|
+
and then any calls to JSS.api.connect will assume that server and username, and won't complain about the self-signed certificate.
|
330
330
|
|
331
331
|
### Passwords
|
332
332
|
|
333
|
-
The config files don't store passwords and the {JSS::Configuration} instance doesn't work with them. You'll have to use your own methods for acquiring the password for the JSS.
|
333
|
+
The config files don't store passwords and the {JSS::Configuration} instance doesn't work with them. You'll have to use your own methods for acquiring the password for the JSS.api.connect call.
|
334
334
|
|
335
335
|
The {JSS::API#connect} method also accepts the symbols :stdin# and :prompt as values for the :pw argument, which will cause it to read the password from a line of stdin, or prompt for it in the shell.
|
336
336
|
|
@@ -340,7 +340,7 @@ Here's an example of how to use a password stored in a file:
|
|
340
340
|
|
341
341
|
```ruby
|
342
342
|
password = File.read "/path/to/secure/password/file" # read the password from a file
|
343
|
-
JSS.
|
343
|
+
JSS.api.connect pw: password # other arguments used from the config settings
|
344
344
|
```
|
345
345
|
|
346
346
|
And here's an example of how to read a password from a web server and use it.
|
@@ -348,7 +348,7 @@ And here's an example of how to read a password from a web server and use it.
|
|
348
348
|
```ruby
|
349
349
|
require 'open-uri'
|
350
350
|
password = open('https://server.org.org/path/to/password').read
|
351
|
-
JSS.
|
351
|
+
JSS.api.connect pw: password # other arguments used from the config settings
|
352
352
|
```
|
353
353
|
|
354
354
|
## BEYOND THE API
|
data/bin/cgrouper
CHANGED
@@ -2,21 +2,21 @@
|
|
2
2
|
|
3
3
|
### Copyright 2017 Pixar
|
4
4
|
|
5
|
-
###
|
5
|
+
###
|
6
6
|
### Licensed under the Apache License, Version 2.0 (the "Apache License")
|
7
7
|
### with the following modification; you may not use this file except in
|
8
8
|
### compliance with the Apache License and the following modification to it:
|
9
9
|
### Section 6. Trademarks. is deleted and replaced with:
|
10
|
-
###
|
10
|
+
###
|
11
11
|
### 6. Trademarks. This License does not grant permission to use the trade
|
12
12
|
### names, trademarks, service marks, or product names of the Licensor
|
13
13
|
### and its affiliates, except as required to comply with Section 4(c) of
|
14
14
|
### the License and to reproduce the content of the NOTICE file.
|
15
|
-
###
|
15
|
+
###
|
16
16
|
### You may obtain a copy of the Apache License at
|
17
|
-
###
|
17
|
+
###
|
18
18
|
### http://www.apache.org/licenses/LICENSE-2.0
|
19
|
-
###
|
19
|
+
###
|
20
20
|
### Unless required by applicable law or agreed to in writing, software
|
21
21
|
### distributed under the Apache License with the above modification is
|
22
22
|
### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
@@ -191,7 +191,7 @@ class App
|
|
191
191
|
raise JSS::MissingDataError, "No JSS Username provided or found in the JSS gem config." unless @options.user
|
192
192
|
raise JSS::MissingDataError, "No JSS Server provided or found in the JSS gem config." unless @options.server
|
193
193
|
|
194
|
-
JSS.
|
194
|
+
JSS.api.connect( :server => @options.server,
|
195
195
|
:port => @options.port,
|
196
196
|
:verify_cert => @options.verify_cert,
|
197
197
|
:user => @options.user,
|
data/bin/netseg-update
CHANGED
data/lib/jss.rb
CHANGED
data/lib/jss/api_connection.rb
CHANGED
@@ -37,49 +37,93 @@ module JSS
|
|
37
37
|
# Classes
|
38
38
|
#####################################
|
39
39
|
|
40
|
-
# Instances of this class represent
|
40
|
+
# Instances of this class represent a REST connection to a JSS API.
|
41
41
|
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
# that API, including login credentials, URLs, and so on.
|
42
|
+
# For most cases, a single connection to a single JSS is all you need, and
|
43
|
+
# this is ruby-jss's default behavior.
|
45
44
|
#
|
46
|
-
#
|
45
|
+
# If needed, multiple connections can be made and used sequentially or
|
46
|
+
# simultaneously.
|
47
|
+
#
|
48
|
+
# == Using the default connection
|
47
49
|
#
|
48
50
|
# When ruby-jss is loaded, a not-yet-connected default instance of
|
49
|
-
# JSS::APIConnection is created
|
51
|
+
# JSS::APIConnection is created and stored in the constant JSS::API.
|
52
|
+
# This connection is used as the initial 'active connection' (see below)
|
53
|
+
# so all methods that make API calls will use it by default. For most uses,
|
54
|
+
# where you're only going to be working with one connection to one JSS, the
|
55
|
+
# default connection is all you need.
|
56
|
+
#
|
50
57
|
# Before using it you must call its {#connect} method, passing in appropriate
|
51
58
|
# connection details and credentials.
|
52
59
|
#
|
53
|
-
#
|
60
|
+
# Example:
|
54
61
|
#
|
55
|
-
#
|
56
|
-
#
|
62
|
+
# require 'ruby-jss'
|
63
|
+
# JSS.api.connect server: 'server.address.edu', user: 'jss-api-user', pw: :prompt
|
64
|
+
# # (see {JSS::APIConnection#connect} for all the connection options)
|
57
65
|
#
|
58
|
-
#
|
66
|
+
# a_phone = JSS::MobileDevice.fetch id: 8743
|
59
67
|
#
|
60
|
-
#
|
61
|
-
# using the default connection is preferred. You can call its {#connect}
|
62
|
-
# method at any time to change servers or connection credentials.
|
68
|
+
# # the mobile device was fetched through the default connection
|
63
69
|
#
|
64
|
-
# == Multiple
|
70
|
+
# == Using Multiple Simultaneous Connections
|
65
71
|
#
|
66
72
|
# Sometimes you need to connect simultaneously to more than one JSS.
|
67
|
-
# or to the same JSS with different credentials.
|
73
|
+
# or to the same JSS with different credentials. ruby-jss allows you to
|
74
|
+
# create as many connections as needed, and gives you three ways to use them:
|
68
75
|
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
# (See below for how to switch between different connections)
|
76
|
+
# 1. Making a connection 'active', after which API calls go thru it
|
77
|
+
# automatically
|
72
78
|
#
|
73
|
-
#
|
74
|
-
#
|
79
|
+
# Example:
|
80
|
+
#
|
81
|
+
# a_computer = JSS::Computer.fetch id: 1234
|
82
|
+
#
|
83
|
+
# # the JSS::Computer with id 1234 is fetched from the active connection
|
84
|
+
# # and stored in the variable 'a_computer'
|
85
|
+
#
|
86
|
+
# NOTE: When ruby-jss is first loaded, the default connection (see above)
|
87
|
+
# is the active connection.
|
88
|
+
#
|
89
|
+
# 2. Passing an APIConnection instance to methods that use the API
|
90
|
+
#
|
91
|
+
# Example:
|
92
|
+
#
|
93
|
+
# a_computer = JSS::Computer.fetch id: 1234, api: production_api
|
94
|
+
#
|
95
|
+
# # the JSS::Computer with id 1234 is fetched from the connection
|
96
|
+
# # stored in the variable 'production_api'. The computer is
|
97
|
+
# # then stored in the variable 'a_computer'
|
98
|
+
#
|
99
|
+
# 3. Using the APIConnection instance itself to make API calls.
|
100
|
+
#
|
101
|
+
# Example:
|
102
|
+
#
|
103
|
+
# a_computer = production_api.fetch :Computer, id: 1234
|
104
|
+
#
|
105
|
+
# # the JSS::Computer with id 1234 is fetched from the connection
|
106
|
+
# # stored in the variable 'production_api'. The computer is
|
107
|
+
# # then stored in the variable 'a_computer'
|
108
|
+
#
|
109
|
+
# See below for more details about the ways to use multiple connections.
|
110
|
+
#
|
111
|
+
# NOTE:
|
112
|
+
# Objects retrieved or created through an APIConnection store an internal
|
113
|
+
# reference to that APIConnection and use that when they make other API
|
114
|
+
# calls, thus ensuring data consistency when using multiple connections.
|
115
|
+
#
|
116
|
+
# Similiarly, the data caches used by APIObject list methods (e.g.
|
117
|
+
# JSS::Computer.all, .all_names, and so on) are stored in the APIConnection
|
118
|
+
# instance through which they were read, so they won't be incorrect when
|
119
|
+
# you use multiple connections.
|
75
120
|
#
|
76
|
-
# == Making new
|
121
|
+
# == Making new APIConnection instances
|
77
122
|
#
|
78
|
-
# New connections can be created
|
79
|
-
# the standard ruby 'new' method.
|
123
|
+
# New connections can be created using the standard ruby 'new' method.
|
80
124
|
#
|
81
125
|
# If you provide connection details when calling 'new', they will be passed
|
82
|
-
# to the #connect method immediately.
|
126
|
+
# to the {#connect} method immediately. Otherwise you can call {#connect} later.
|
83
127
|
#
|
84
128
|
# production_api = JSS::APIConnection.new(
|
85
129
|
# name: 'prod',
|
@@ -90,28 +134,46 @@ module JSS
|
|
90
134
|
#
|
91
135
|
# # the new connection is now stored in the variable 'production_api'.
|
92
136
|
#
|
93
|
-
# ==
|
137
|
+
# == Using the 'Active' Connection
|
94
138
|
#
|
95
|
-
#
|
96
|
-
#
|
97
|
-
#
|
139
|
+
# While multiple connection instances can be created, only one at a time is
|
140
|
+
# 'the active connection' and all APIObject-based access methods in ruby-jss
|
141
|
+
# will use it automatically. When ruby-jss is loaded, the default connection
|
142
|
+
# (see above) is the active connection.
|
143
|
+
#
|
144
|
+
# To use the active connection, just call a method on an APIObject subclass
|
145
|
+
# that uses the API.
|
146
|
+
#
|
147
|
+
# For example, the various list methods:
|
148
|
+
#
|
149
|
+
# all_computer_sns = JSS::Computer.all_serial_numbers
|
150
|
+
#
|
151
|
+
# # the list of all computer serial numbers is read from the active
|
152
|
+
# # connection and stored in all_computer_sns
|
153
|
+
#
|
154
|
+
# Fetching an object from the API:
|
155
|
+
#
|
156
|
+
# victim_md = JSS::MobileDevice.fetch id: 832
|
157
|
+
#
|
158
|
+
# # the variable 'victim_md' now contains a JSS::MobileDevice queried
|
159
|
+
# # through the active connection.
|
160
|
+
#
|
161
|
+
# The currently-active connection instance is available from the
|
162
|
+
# `JSS.api` method.
|
163
|
+
#
|
164
|
+
# === Making a Connection Active
|
165
|
+
#
|
166
|
+
# Only one connection is 'active' at a time and the currently active one is
|
167
|
+
# returned when you call `JSS.api` or its alias `JSS.active_connection`
|
98
168
|
#
|
99
169
|
# To activate another connection just pass it to the JSS.use_api method like so:
|
170
|
+
#
|
100
171
|
# JSS.use_api production_api
|
101
172
|
# # the connection we stored in 'production_api' is now active
|
102
173
|
#
|
103
174
|
# To re-activate to the default connection, just call
|
104
175
|
# JSS.use_default_connection
|
105
176
|
#
|
106
|
-
# NOTE:
|
107
|
-
# The APIObject list methods (e.g. JSS::Computer.all) cache the list
|
108
|
-
# data from the API the first time they are used, and after that when
|
109
|
-
# their 'refresh' option is true.
|
110
|
-
#
|
111
|
-
# Those caches are stored in the APIConnection instance through-
|
112
|
-
# which they were read, so they won't be incorrect when you switch
|
113
|
-
# connections.
|
114
|
-
#
|
115
177
|
# == Connection Names:
|
116
178
|
#
|
117
179
|
# As seen in the example above, you can provide a 'name:' parameter
|
@@ -147,9 +209,61 @@ module JSS
|
|
147
209
|
#
|
148
210
|
# JSS.api.name # => 'prod2'
|
149
211
|
#
|
212
|
+
# == Passing an APIConnection object to API-related methods
|
213
|
+
#
|
214
|
+
# All methods that use the API can take an 'api:' parameter which
|
215
|
+
# contains an APIConnection object. When provided, that APIconnection is
|
216
|
+
# used rather than the active connection.
|
217
|
+
#
|
218
|
+
# For example:
|
219
|
+
#
|
220
|
+
# prod2_computer_sns = JSS::Computer.all_serial_numbers, api: production_api2
|
221
|
+
#
|
222
|
+
# # the list of all computer serial numbers is read from the connection in
|
223
|
+
# # the variable 'production_api2' and stored in 'prod2_computer_sns'
|
224
|
+
#
|
225
|
+
# prod2_victim_md = JSS::MobileDevice.fetch id: 832, api: production_api2
|
226
|
+
#
|
227
|
+
# # the variable 'prod2_victim_md' now contains a JSS::MobileDevice queried
|
228
|
+
# # through the connection 'production_api2'.
|
229
|
+
#
|
230
|
+
# == Using the APIConnection itself to make API calls.
|
231
|
+
#
|
232
|
+
# Rather than passing an APIConnection into another method, you can call
|
233
|
+
# similar methods on the connection itself. For example, these two calls
|
234
|
+
# have the same result as the two examples above:
|
235
|
+
#
|
236
|
+
# prod2_computer_sns = production_api2.all :Computer, only: :serial_numbers
|
237
|
+
# prod2_victim_md = production_api2.fetch :MobileDevice, id: 832
|
238
|
+
#
|
239
|
+
# Here are the API calls you can make directly from an APIConnection object.
|
240
|
+
# Most of them behave identically to the same methods in the APIObject classes
|
241
|
+
#
|
242
|
+
# - {#all} The 'list' methods of the various APIObject classes. Use the 'only:'
|
243
|
+
# parameter to specify one of the sub-list-methods, like #all_ids or
|
244
|
+
# #all_laptops
|
245
|
+
# - {#map_all_ids} the equivalent of #map_all_ids_to in the APIObject classes
|
246
|
+
# - {#valid_id} given a class and an identifier (like macaddress or udid)
|
247
|
+
# return a valid id or nil
|
248
|
+
# - {#exist?} given a class and an identifier (like macaddress or udid) does
|
249
|
+
# the identifier exist for the class in the JSS
|
250
|
+
# - {#match} list items in the JSS matching a query
|
251
|
+
# (if the object is {Matchable})
|
252
|
+
# - {#fetch} retrieve an object from the JSS
|
253
|
+
# - {#make} instantiate an object to be created in the JSS
|
254
|
+
# - {#send_computer_mdm_command} same as {Computer.send_mdm_command}
|
255
|
+
# - {#computer_checkin_settings} same as {Computer.checkin_settings}
|
256
|
+
# - {#computer_inventory_collection_settings} same as {Computer.inventory_collection_settings}
|
257
|
+
# - {#send_mobiledevice_mdm_command} same as {MobileDevice.send_mdm_command}
|
258
|
+
# - {#master_distribution_point} same as {DistributionPoint.master_distribution_point}
|
259
|
+
# - {#my_distribution_point} same as {DistributionPoint.my_distribution_point}
|
260
|
+
# - {#network_ranges} same as {NetworkSegment.network_ranges}
|
261
|
+
# - {#network_segments_for_ip} same as {NetworkSegment.segments_for_ip}
|
262
|
+
# - {#my_network_segments} same as {NetworkSegment.my_network_segments}
|
263
|
+
#
|
150
264
|
# == Low-level use of APIConnection instances.
|
151
265
|
#
|
152
|
-
# For most
|
266
|
+
# For most cases, using APIConnection instances as mentioned above
|
153
267
|
# is all you'll need. However to access API resources that aren't yet
|
154
268
|
# implemented in other parts of ruby-jss, you can use the methods
|
155
269
|
# {#get_rsrc}, {#put_rsrc}, {#post_rsrc}, & {#delete_rsrc}
|
@@ -378,7 +492,7 @@ module JSS
|
|
378
492
|
#
|
379
493
|
def get_rsrc(rsrc, format = :json)
|
380
494
|
# puts object_id
|
381
|
-
raise JSS::InvalidConnectionError, 'Not Connected. Use
|
495
|
+
raise JSS::InvalidConnectionError, 'Not Connected. Use .connect first.' unless @connected
|
382
496
|
rsrc = URI.encode rsrc
|
383
497
|
@last_http_response = @cnx[rsrc].get(accept: format)
|
384
498
|
return JSON.parse(@last_http_response, symbolize_names: true) if format == :json
|
@@ -393,7 +507,7 @@ module JSS
|
|
393
507
|
# @return [String] the xml response from the server.
|
394
508
|
#
|
395
509
|
def put_rsrc(rsrc, xml)
|
396
|
-
raise JSS::InvalidConnectionError, 'Not Connected. Use
|
510
|
+
raise JSS::InvalidConnectionError, 'Not Connected. Use .connect first.' unless @connected
|
397
511
|
|
398
512
|
# convert CRs & to
|
399
513
|
xml.gsub!(/\r/, ' ')
|
@@ -413,7 +527,7 @@ module JSS
|
|
413
527
|
# @return [String] the xml response from the server.
|
414
528
|
#
|
415
529
|
def post_rsrc(rsrc, xml = '')
|
416
|
-
raise JSS::InvalidConnectionError, 'Not Connected. Use
|
530
|
+
raise JSS::InvalidConnectionError, 'Not Connected. Use .connect first.' unless @connected
|
417
531
|
|
418
532
|
# convert CRs & to
|
419
533
|
xml.gsub!(/\r/, ' ') if xml
|
@@ -431,7 +545,7 @@ module JSS
|
|
431
545
|
# @return [String] the xml response from the server.
|
432
546
|
#
|
433
547
|
def delete_rsrc(rsrc, xml = nil)
|
434
|
-
raise JSS::InvalidConnectionError, 'Not Connected. Use
|
548
|
+
raise JSS::InvalidConnectionError, 'Not Connected. Use .connect first.' unless @connected
|
435
549
|
raise MissingDataError, 'Missing :rsrc' if rsrc.nil?
|
436
550
|
|
437
551
|
# payload?
|
@@ -492,6 +606,274 @@ module JSS
|
|
492
606
|
alias connected? connected
|
493
607
|
alias host hostname
|
494
608
|
|
609
|
+
|
610
|
+
#################
|
611
|
+
|
612
|
+
# Call one of the 'all*' methods on a JSS::APIObject subclass
|
613
|
+
# using this APIConnection.
|
614
|
+
#
|
615
|
+
# @param class_name[String,Symbol] The name of a JSS::APIObject subclass
|
616
|
+
# see {JSS.api_object_class}
|
617
|
+
#
|
618
|
+
# @param refresh[Boolean] Should the data be re-read from the API?
|
619
|
+
#
|
620
|
+
# @param only[String,Symbol] Limit the output to subset or data. All
|
621
|
+
# APIObject subclasses can take :ids or :names, which calls the .all_ids
|
622
|
+
# and .all_names methods. Some subclasses can take other options, e.g.
|
623
|
+
# MobileDevice can take :udids
|
624
|
+
#
|
625
|
+
# @return [Array] The list of items for the class
|
626
|
+
#
|
627
|
+
def all(class_name, refresh = false, only: nil )
|
628
|
+
the_class = JSS.api_object_class(class_name)
|
629
|
+
list_method = only ? :"all_#{only}" : :all
|
630
|
+
|
631
|
+
raise ArgumentError, "Unknown identifier: #{only} for #{the_class}" unless
|
632
|
+
the_class.respond_to? list_method
|
633
|
+
|
634
|
+
the_class.send list_method, refresh, api: self
|
635
|
+
end
|
636
|
+
|
637
|
+
# Call the 'map_all_ids_to' method on a JSS::APIObject subclass
|
638
|
+
# using this APIConnection.
|
639
|
+
#
|
640
|
+
# @param class_name[String,Symbol] The name of a JSS::APIObject subclass
|
641
|
+
# see {JSS.api_object_class}
|
642
|
+
#
|
643
|
+
# @param refresh[Boolean] Should the data be re-read from the API?
|
644
|
+
#
|
645
|
+
# @param to[String,Symbol] the value to which the ids should be mapped
|
646
|
+
#
|
647
|
+
# @return [Hash] The ids for the class keyed to the requested identifier
|
648
|
+
#
|
649
|
+
def map_all_ids(class_name, refresh = false, to: nil)
|
650
|
+
raise "'to:' value must be provided for mapping ids." unless to
|
651
|
+
the_class = JSS.api_object_class(class_name)
|
652
|
+
the_class.map_all_ids_to to, api: self
|
653
|
+
end
|
654
|
+
|
655
|
+
# Call the 'valid_id' method on a JSS::APIObject subclass
|
656
|
+
# using this APIConnection. See {JSS::APIObject.valid_id}
|
657
|
+
#
|
658
|
+
# @param class_name[String,Symbol] The name of a JSS::APIObject subclass,
|
659
|
+
# see {JSS.api_object_class}
|
660
|
+
#
|
661
|
+
# @param identifier[String,Symbol] the value to which the ids should be mapped
|
662
|
+
#
|
663
|
+
# @param refresh[Boolean] Should the data be re-read from the API?
|
664
|
+
#
|
665
|
+
# @return [Integer, nil] the id of the matching object of the class,
|
666
|
+
# or nil if there isn't one
|
667
|
+
#
|
668
|
+
def valid_id(class_name, identifier, refresh = true)
|
669
|
+
the_class = JSS.api_object_class(class_name)
|
670
|
+
the_class.valid_id identifier, refresh, api: self
|
671
|
+
end
|
672
|
+
|
673
|
+
# Call the 'exist?' method on a JSS::APIObject subclass
|
674
|
+
# using this APIConnection. See {JSS::APIObject.exist?}
|
675
|
+
#
|
676
|
+
# @param class_name[String,Symbol] The name of a JSS::APIObject subclass
|
677
|
+
# see {JSS.api_object_class}
|
678
|
+
#
|
679
|
+
# @param identifier[String,Symbol] the value to which the ids should be mapped
|
680
|
+
#
|
681
|
+
# @param refresh[Boolean] Should the data be re-read from the API?
|
682
|
+
#
|
683
|
+
# @return [Boolean] Is there an object of this class in the JSS matching
|
684
|
+
# this indentifier?
|
685
|
+
#
|
686
|
+
def exist?(class_name, identifier, refresh = false)
|
687
|
+
!valid_id(class_name, identifier, refresh).nil?
|
688
|
+
end
|
689
|
+
|
690
|
+
# Call {Matchable.match} for the given class.
|
691
|
+
#
|
692
|
+
# See {Matchable.match}
|
693
|
+
#
|
694
|
+
# @param class_name[String,Symbol] The name of a JSS::APIObject subclass
|
695
|
+
# see {JSS.api_object_class}
|
696
|
+
#
|
697
|
+
# @return (see Matchable.match)
|
698
|
+
#
|
699
|
+
def match(class_name, term)
|
700
|
+
the_class = JSS.api_object_class(class_name)
|
701
|
+
raise JSS::UnsupportedError, "Class #{the_class} is not matchable" unless the_class.respond_to? :match
|
702
|
+
the_class.match term, api: self
|
703
|
+
end
|
704
|
+
|
705
|
+
# Retrieve an object of a given class from the API
|
706
|
+
# See {APIObject.fetch}
|
707
|
+
#
|
708
|
+
# @param class_name[String,Symbol] The name of a JSS::APIObject subclass
|
709
|
+
# see {JSS.api_object_class}
|
710
|
+
#
|
711
|
+
# @return [APIObject] The ruby-instance of the object.
|
712
|
+
#
|
713
|
+
def fetch(class_name, arg)
|
714
|
+
the_class = JSS.api_object_class(class_name)
|
715
|
+
the_class.fetch arg, api: self
|
716
|
+
end
|
717
|
+
|
718
|
+
# Make a ruby instance of a not-yet-existing APIObject
|
719
|
+
# of the given class
|
720
|
+
# See {APIObject.make}
|
721
|
+
#
|
722
|
+
# @param class_name[String,Symbol] The name of a JSS::APIObject subclass
|
723
|
+
# see {JSS.api_object_class}
|
724
|
+
#
|
725
|
+
# @return [APIObject] The un-created ruby-instance of the object.
|
726
|
+
#
|
727
|
+
def make(class_name, **args)
|
728
|
+
the_class = JSS.api_object_class(class_name)
|
729
|
+
args[:api] = self
|
730
|
+
the_class.make args
|
731
|
+
end
|
732
|
+
|
733
|
+
# Call {JSS::Computer.checkin_settings} passing this API
|
734
|
+
# connection
|
735
|
+
#
|
736
|
+
# @return (see JSS::Computer.checkin_settings)
|
737
|
+
#
|
738
|
+
def computer_checkin_settings
|
739
|
+
JSS::Computer.checkin_settings api: self
|
740
|
+
end
|
741
|
+
|
742
|
+
|
743
|
+
# Call {JSS::Computer.inventory_collection_settings} passing this API
|
744
|
+
# connection
|
745
|
+
#
|
746
|
+
# @return (see JSS::Computer.checkin_settings)
|
747
|
+
#
|
748
|
+
def computer_inventory_collection_settings
|
749
|
+
JSS::Computer.inventory_collection_settings api: self
|
750
|
+
end
|
751
|
+
|
752
|
+
# Get the DistributionPoint instance for the master
|
753
|
+
# distribution point in the JSS. If there's only one
|
754
|
+
# in the JSS, return it even if not marked as master.
|
755
|
+
#
|
756
|
+
# @param refresh[Boolean] re-read from the API?
|
757
|
+
#
|
758
|
+
# @return [JSS::DistributionPoint]
|
759
|
+
#
|
760
|
+
def master_distribution_point(refresh = false)
|
761
|
+
@master_distribution_point = nil if refresh
|
762
|
+
return @master_distribution_point if @master_distribution_point
|
763
|
+
|
764
|
+
all_dps = JSS::DistributionPoint.all refresh, api: self
|
765
|
+
|
766
|
+
@master_distribution_point =
|
767
|
+
case all_dps.size
|
768
|
+
when 0
|
769
|
+
raise JSS::NoSuchItemError, "No distribution points defined"
|
770
|
+
when 1
|
771
|
+
JSS::DistributionPoint.fetch id: all_dps.first[:id], api: self
|
772
|
+
else
|
773
|
+
JSS::DistributionPoint.fetch id: :master, api: self
|
774
|
+
end
|
775
|
+
end
|
776
|
+
|
777
|
+
# Get the DistributionPoint instance for the machine running
|
778
|
+
# this code, based on its IP address. If none is defined for this IP address,
|
779
|
+
# use the result of master_distribution_point
|
780
|
+
#
|
781
|
+
# @param refresh[Boolean] should the distribution point be re-queried?
|
782
|
+
#
|
783
|
+
# @return [JSS::DistributionPoint]
|
784
|
+
#
|
785
|
+
def my_distribution_point(refresh = false)
|
786
|
+
@my_distribution_point = nil if refresh
|
787
|
+
return @my_distribution_point if @my_distribution_point
|
788
|
+
|
789
|
+
my_net_seg = my_network_segments[0]
|
790
|
+
@my_distribution_point = JSS::NetworkSegment.fetch(id: my_net_seg, api: self).distribution_point if my_net_seg
|
791
|
+
@my_distribution_point ||= master_distribution_point refresh
|
792
|
+
@my_distribution_point
|
793
|
+
end
|
794
|
+
|
795
|
+
# All NetworkSegments in this jss as IPAddr object Ranges representing the
|
796
|
+
# Segment, e.g. with starting = 10.24.9.1 and ending = 10.24.15.254
|
797
|
+
# the range looks like:
|
798
|
+
# <IPAddr: IPv4:10.24.9.1/255.255.255.255>..#<IPAddr: IPv4:10.24.15.254/255.255.255.255>
|
799
|
+
#
|
800
|
+
# Using the #include? method on those Ranges is very useful.
|
801
|
+
#
|
802
|
+
# @param refresh[Boolean] should the data be re-queried?
|
803
|
+
#
|
804
|
+
# @return [Hash{Integer => Range}] the network segments as IPv4 address Ranges
|
805
|
+
#
|
806
|
+
def network_ranges(refresh = false)
|
807
|
+
@network_ranges = nil if refresh
|
808
|
+
return @network_ranges if @network_ranges
|
809
|
+
@network_ranges = {}
|
810
|
+
JSS::NetworkSegment.all(refresh, api: self).each do |ns|
|
811
|
+
@network_ranges[ns[:id]] = IPAddr.new(ns[:starting_address])..IPAddr.new(ns[:ending_address])
|
812
|
+
end
|
813
|
+
@network_ranges
|
814
|
+
end # def network_segments
|
815
|
+
|
816
|
+
# Find the ids of the network segments that contain a given IP address.
|
817
|
+
#
|
818
|
+
# Even tho IPAddr.include? will take a String or an IPAddr
|
819
|
+
# I convert the ip to an IPAddr so that an exception will be raised if
|
820
|
+
# the ip isn't a valid ip.
|
821
|
+
#
|
822
|
+
# @param ip[String, IPAddr] the IP address to locate
|
823
|
+
#
|
824
|
+
# @param refresh[Boolean] should the data be re-queried?
|
825
|
+
#
|
826
|
+
# @return [Array<Integer>] the ids of the NetworkSegments containing the given ip
|
827
|
+
#
|
828
|
+
def network_segments_for_ip(ip, refresh = false)
|
829
|
+
ok_ip = IPAddr.new(ip)
|
830
|
+
matches = []
|
831
|
+
network_ranges.each { |id, subnet| matches << id if subnet.include?(ok_ip) }
|
832
|
+
matches
|
833
|
+
end
|
834
|
+
|
835
|
+
# Find the current network segment ids for the machine running this code
|
836
|
+
#
|
837
|
+
# @return [Array<Integer>] the NetworkSegment ids for this machine right now.
|
838
|
+
#
|
839
|
+
def my_network_segments
|
840
|
+
network_segments_for_ip JSS::Client.my_ip_address
|
841
|
+
end
|
842
|
+
|
843
|
+
# Send an MDM command to one or more computers managed by
|
844
|
+
# this JSS
|
845
|
+
#
|
846
|
+
# see {JSS::Computer.send_mdm_command}
|
847
|
+
#
|
848
|
+
def send_computer_mdm_command(targets, command, passcode = nil)
|
849
|
+
JSS::Computer.send_mdm_command(targets, command, passcode, api: self)
|
850
|
+
end
|
851
|
+
|
852
|
+
# Send an MDM command to one or more mobile devices managed by
|
853
|
+
# this JSS
|
854
|
+
#
|
855
|
+
# see {JSS::MobileDevice.send_mdm_command}
|
856
|
+
#
|
857
|
+
def send_mobiledevice_mdm_command(targets, command, data = nil)
|
858
|
+
JSS::MobileDevice.send_mdm_command(targets, command, data, api: self)
|
859
|
+
end
|
860
|
+
|
861
|
+
# Remove the various cached data
|
862
|
+
# from the instance_variables used to create
|
863
|
+
# pretty-print (pp) output.
|
864
|
+
#
|
865
|
+
# @return [Array] the desired instance_variables
|
866
|
+
#
|
867
|
+
def pretty_print_instance_variables
|
868
|
+
vars = instance_variables.sort
|
869
|
+
vars.delete :@object_list_cache
|
870
|
+
vars.delete :@last_http_response
|
871
|
+
vars.delete :@network_ranges
|
872
|
+
vars.delete :@my_distribution_point
|
873
|
+
vars.delete :@master_distribution_point
|
874
|
+
vars
|
875
|
+
end
|
876
|
+
|
495
877
|
# Private Insance Methods
|
496
878
|
####################################
|
497
879
|
private
|
@@ -596,9 +978,9 @@ module JSS
|
|
596
978
|
# keep this basic level of info available for basic authentication
|
597
979
|
# and JSS version checking.
|
598
980
|
begin
|
599
|
-
@server = JSS::Server.new get_rsrc('jssuser')[:user]
|
981
|
+
@server = JSS::Server.new get_rsrc('jssuser')[:user], self
|
600
982
|
rescue RestClient::Unauthorized, RestClient::Request::Unauthorized
|
601
|
-
raise JSS::AuthenticationError, "Incorrect JSS username or password for '#{
|
983
|
+
raise JSS::AuthenticationError, "Incorrect JSS username or password for '#{@jss_user}@#{@server_host}:#{@port}'."
|
602
984
|
end
|
603
985
|
|
604
986
|
min_vers = JSS.parse_jss_version(JSS::MINIMUM_SERVER_VERSION)[:version]
|
@@ -757,12 +1139,14 @@ module JSS
|
|
757
1139
|
class << self
|
758
1140
|
alias api_connection api
|
759
1141
|
alias connection api
|
1142
|
+
alias active_connection api
|
760
1143
|
|
761
1144
|
alias new_connection new_api_connection
|
762
1145
|
alias new_api new_api_connection
|
763
1146
|
|
764
1147
|
alias use_api use_api_connection
|
765
1148
|
alias use_connection use_api_connection
|
1149
|
+
alias activate_connection use_api_connection
|
766
1150
|
end
|
767
1151
|
|
768
1152
|
# create the default connection
|