ruby-jss 0.8.2 → 0.9.0.b1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ruby-jss might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGES.md +37 -1
- data/README.md +15 -15
- data/bin/cgrouper +1 -1
- data/bin/netseg-update +1 -1
- data/lib/jss/api_connection.rb +307 -25
- data/lib/jss/api_object.rb +123 -54
- data/lib/jss/api_object/account.rb +6 -1
- data/lib/jss/api_object/advanced_search.rb +12 -12
- data/lib/jss/api_object/computer.rb +570 -141
- data/lib/jss/api_object/computer_invitation.rb +9 -0
- data/lib/jss/api_object/creatable.rb +1 -1
- data/lib/jss/api_object/distribution_point.rb +1 -1
- data/lib/jss/api_object/extension_attribute.rb +6 -6
- data/lib/jss/api_object/group.rb +1 -1
- data/lib/jss/api_object/matchable.rb +1 -1
- data/lib/jss/api_object/mobile_device.rb +690 -304
- data/lib/jss/api_object/mobile_device_application.rb +11 -1
- data/lib/jss/api_object/package.rb +1 -1
- data/lib/jss/api_object/policy.rb +206 -2
- data/lib/jss/api_object/restricted_software.rb +126 -42
- data/lib/jss/api_object/scopable/scope.rb +20 -21
- data/lib/jss/api_object/self_servable.rb +9 -6
- data/lib/jss/api_object/updatable.rb +1 -1
- data/lib/jss/api_object/uploadable.rb +1 -1
- data/lib/jss/server.rb +57 -56
- data/lib/jss/utility.rb +4 -0
- data/lib/jss/version.rb +1 -1
- metadata +4 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 770c1a47f03a6f98144c8ad351559817416166fb
|
4
|
+
data.tar.gz: 8271b37e6692aef2f4005f3bbf043964c3d9b5c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c642a052e9e1a5aa68e4ffcf9a22cb53a367ebe7be09a3c67dc15681605ccc7eb66a85813ca7c3bbf0b8b25ed4840931f48e18954ead42946c1409e0b3c4b21f
|
7
|
+
data.tar.gz: a07ceac28ddb3fd6f4c241940e0ee93ce6ba77f9ec750b0dcbe588f7417f5602bff76deb2676913743e6497e9e62ccd8cc748a193721a4e6c68ce2c9e5c839ae
|
data/CHANGES.md
CHANGED
@@ -1,6 +1,42 @@
|
|
1
1
|
# Change History
|
2
2
|
|
3
|
-
## v0.
|
3
|
+
## v0.9.0
|
4
|
+
|
5
|
+
- Add: JSS::MobileDevice.all_apple_tvs class method
|
6
|
+
- Add: JSS::MobileDevice.management_history method, and related methods in instances
|
7
|
+
- Add: JSS::MobileDevice.send_mdm_command has been expanded to handle all MDM commands supported by the API *except* Wallpaper and PasscodeLockGracePeriod (some day soon hopefully)
|
8
|
+
- Improvement: JSS::RestrictedSoftware class is now Creatable and Updatable.
|
9
|
+
- Add: JSS::Server instances (as found in the JSS::APIConnection.server attribute) now have methods #activation_code and
|
10
|
+
#organization
|
11
|
+
- Add: JSS::Computer now can send MDM commands to instances via #blank_push #device_lock #erase_device and #remove_mdm_profile, or to
|
12
|
+
arrays of computer identifiers using the JSS::Computer.send_mdm_command method.
|
13
|
+
- Add: JSS::Computer now has class methods to retrieve the server-wide .inventory_collection_settings and
|
14
|
+
.checkin_settings
|
15
|
+
- Add: JSS::Computer instances now have access to the data in the History tab of the computer details page in
|
16
|
+
the WebUI. Subset-specific methods are #usage_logs, #audits, #policy_logs, #completed_policies, #failed_policies, #casper_remote_logs, #screen_sharing_logs, #casper_imaging_logs, #user_location_history, and #app_store_history
|
17
|
+
- Add: JSS::Computer instances now have an #application_usage method which takes a date range and returns an
|
18
|
+
array of usage data.
|
19
|
+
- Add: JSS::Computer instances now have access to their 'management data' (the stuff in the Management tab of
|
20
|
+
the Computer details in the WebUI). As well as the #management_data method, there are shortcut methods for the subsets: #smart_groups, #static_groups, & #patch_titles and in-scope items like: #policies, #configuration_profiles, #ebooks, #app_store_apps, #restricted_software
|
21
|
+
- Fix: issue with handling of params to APIObject.make
|
22
|
+
- Improvement: APIObject.fetch can be given a single value, which will be compared to the subclass's .all_ids,
|
23
|
+
.all_names, and other list methods for the various lookup keys, and if a match is found, the object is returned. E.g. instead of
|
24
|
+
JSS::Computer.fetch name: 'foo' you can just use JSS::Computer.fetch 'foo'.
|
25
|
+
Note that specifying the lookup key is always faster.
|
26
|
+
- Improvement: the OTHER_LOOKUP_KEYS constants of APIObject subclasses can now reconize variations on a key, e.g. :serialnumber and
|
27
|
+
:serial_number, or :macaddress and :mac_address
|
28
|
+
- Improvement: Support for multiple APIConnection instances - you can connect to more than one server at a time and switch between them.
|
29
|
+
- Improvement: APIConnection connection settings come first from the #connect params, then from Configuration,
|
30
|
+
then from the Client setting (if the machine is a client), then from the module defaults
|
31
|
+
- Improvement: APIConnection can now take an xml payload with #delete_rsrc
|
32
|
+
- Improvement: JSS::Policy instances can now flush their logs
|
33
|
+
- Improvement: JSS::Policy now has setters for server_side_activation and server_side_expriation.
|
34
|
+
|
35
|
+
## v0.8.3 2017-06-07
|
36
|
+
|
37
|
+
- Fix: Version parsing: empty version parts default to 0, e.g. 10.2 parses as 10.2.0
|
38
|
+
|
39
|
+
## v0.8.2 2017-06-07
|
4
40
|
|
5
41
|
- Fix: Some objects failed to locate their 'main subset' (the chunk of API data that contains the object name and id) correctly.
|
6
42
|
- Fix: Some versions of Gem::Version don't like dashes (which are part of SemVers).
|
data/README.md
CHANGED
@@ -51,10 +51,10 @@ Hopefully others will find it useful, and add more to it as well.
|
|
51
51
|
## SYNOPSIS
|
52
52
|
|
53
53
|
```ruby
|
54
|
-
require 'jss'
|
54
|
+
require 'ruby-jss'
|
55
55
|
|
56
56
|
# Connect to the API
|
57
|
-
JSS
|
57
|
+
JSS.api.connect user: jss_user, pw: jss_user_pw, server: jss_server_hostname
|
58
58
|
|
59
59
|
# get an array of basic data about all JSS::Package objects in the JSS:
|
60
60
|
pkgs = JSS::Package.all
|
@@ -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_connection.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_connection.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.
|
@@ -111,7 +111,7 @@ Make sure the user has privileges in the JSS to do things with desired Objects.
|
|
111
111
|
The {JSS::API#connect} method also accepts the symbols :stdin and :prompt as values for :pw, which will cause it to read the
|
112
112
|
password from stdin, or prompt for it in the shell. See the {JSS::APIConnection} class for more connection options and details about its methods.
|
113
113
|
|
114
|
-
Also see
|
114
|
+
Also see JSS::Configuration, and the [CONFIGURATION](#configuration) section below, for how to store
|
115
115
|
server connection parameters in a simple config file.
|
116
116
|
|
117
117
|
### Working with JSS Objects (a.k.a REST Resources)
|
@@ -164,7 +164,7 @@ Some Objects can be created anew in the JSS via ruby. To do so, first make a Rub
|
|
164
164
|
```ruby
|
165
165
|
new_pkg = JSS::Package.make name: "transmogrifier-2.3-1.pkg"
|
166
166
|
```
|
167
|
-
*NOTE*: some classes require more data than just a :name when created with .
|
167
|
+
*NOTE*: some classes require more data than just a :name when created with .make.
|
168
168
|
|
169
169
|
Then set the attributes of the new object as needed
|
170
170
|
|
@@ -236,6 +236,7 @@ See each Class's documentation for details.
|
|
236
236
|
* {JSS::Peripheral}
|
237
237
|
* {JSS::PeripheralType}
|
238
238
|
* {JSS::RemovableMacAddress}
|
239
|
+
* {JSS::RestrictedSoftware}
|
239
240
|
* {JSS::Script}
|
240
241
|
* {JSS::Site}
|
241
242
|
* {JSS::User}
|
@@ -282,7 +283,6 @@ These must be created and edited via the JSS WebApp
|
|
282
283
|
* {JSS::DistributionPoint}
|
283
284
|
* {JSS::LDAPServer}
|
284
285
|
* {JSS::NetBootServer}
|
285
|
-
* {JSS::RestrictedSoftware}
|
286
286
|
* {JSS::SoftwareUpdateServer}
|
287
287
|
|
288
288
|
### Deletable
|
@@ -291,7 +291,7 @@ All supported API Objects can be deleted
|
|
291
291
|
|
292
292
|
Other useful classes:
|
293
293
|
|
294
|
-
* {JSS::
|
294
|
+
* {JSS::APIConnection} - An object representing the connection to the REST API
|
295
295
|
* {JSS::DBConnection} - An object representing the connection to MySQL database, if used
|
296
296
|
* {JSS::Server} - An encapsulation of some info about the JamfPro server, such as the version and license. An instance is available as an attribute of the {JSS::APIConnection} singleton.
|
297
297
|
* {JSS::Client} - An object representing the local machine as a Casper-managed client, and JAMF-related info and methods
|
@@ -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_connection.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_connection.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_connection.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_connection.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,12 +348,12 @@ 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_connection.connect pw: password # other arguments used from the config settings
|
352
352
|
```
|
353
353
|
|
354
354
|
## BEYOND THE API
|
355
355
|
|
356
|
-
While the
|
356
|
+
While the Jamf Pro API provides access to object data in the JSS, this gem tries to use that data to provide more than just information exchange. Here are some examples of how we use the API data to provide functionality found in various Casper tools:
|
357
357
|
|
358
358
|
* Client Machine Access
|
359
359
|
* The {JSS::Client} module provides the ability to run jamf binary commands, and access the local cache of package receipts
|
@@ -375,7 +375,7 @@ While the Casper API provides access to object data in the JSS, this gem tries t
|
|
375
375
|
|
376
376
|
## REQUIREMENTS
|
377
377
|
|
378
|
-
|
378
|
+
ruby-jss was written for:
|
379
379
|
|
380
380
|
* Mac OS X 10.9 or higher
|
381
381
|
* Ruby 2.0 or higher
|
data/bin/cgrouper
CHANGED
@@ -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_connection.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/api_connection.rb
CHANGED
@@ -37,18 +37,129 @@ module JSS
|
|
37
37
|
# Classes
|
38
38
|
#####################################
|
39
39
|
|
40
|
-
#
|
40
|
+
# Instances of this class represent an API connection to the JSS.
|
41
41
|
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
42
|
+
# JSS::APIConnection objects are REST connections to JSS APIs and contain
|
43
|
+
# (once connected) all the data needed for communication with
|
44
|
+
# that API, including login credentials, URLs, and so on.
|
45
45
|
#
|
46
|
-
#
|
47
|
-
# method, and the {#get_rsrc}, {#put_rsrc}, {#post_rsrc}, & {#delete_rsrc}
|
48
|
-
# methods, q.v. below.
|
46
|
+
# == The default connection
|
49
47
|
#
|
50
|
-
#
|
51
|
-
#
|
48
|
+
# When ruby-jss is loaded, a not-yet-connected default instance of
|
49
|
+
# JSS::APIConnection is created, activated, and stored internally.
|
50
|
+
# Before using it you must call its {#connect} method, passing in appropriate
|
51
|
+
# connection details and credentials.
|
52
|
+
#
|
53
|
+
# Here's how to use the default connection:
|
54
|
+
#
|
55
|
+
# require 'ruby-jss'
|
56
|
+
# JSS.api.connect server: 'server.address.edu', user: 'jss-api-user', pw: :prompt
|
57
|
+
#
|
58
|
+
# (see {JSS::APIConnection#connect} for all the connection options)
|
59
|
+
#
|
60
|
+
# If you're only going to be connecting to one server, or one at a time,
|
61
|
+
# using the default connection is preferred. You can call its {#connect}
|
62
|
+
# method at any time to change servers or connection credentials.
|
63
|
+
#
|
64
|
+
# == Multiple connections & the currently active connection
|
65
|
+
#
|
66
|
+
# Sometimes you need to connect simultaneously to more than one JSS.
|
67
|
+
# or to the same JSS with different credentials.
|
68
|
+
#
|
69
|
+
# While multiple connection instances can be created, only one is active at
|
70
|
+
# a time and all API access happens through the currently active connection.
|
71
|
+
# (See below for how to switch between different connections)
|
72
|
+
#
|
73
|
+
# The currently-active connection instance is available from the
|
74
|
+
# `JSS.api` method.
|
75
|
+
#
|
76
|
+
# == Making new connection instances
|
77
|
+
#
|
78
|
+
# New connections can be created and stored in a variable using
|
79
|
+
# the standard ruby 'new' method.
|
80
|
+
#
|
81
|
+
# If you provide connection details when calling 'new', they will be passed
|
82
|
+
# to the #connect method immediately.
|
83
|
+
#
|
84
|
+
# production_api = JSS::APIConnection.new(
|
85
|
+
# name: 'prod',
|
86
|
+
# server: 'prodserver.address.org',
|
87
|
+
# user: 'produser',
|
88
|
+
# pw: :prompt
|
89
|
+
# )
|
90
|
+
#
|
91
|
+
# # the new connection is now stored in the variable 'production_api'.
|
92
|
+
#
|
93
|
+
# == Switching between multiple connections
|
94
|
+
#
|
95
|
+
# Only one connection is active at a time and the currently active one is
|
96
|
+
# returned when you call `JSS.api` or its aliases `JSS.api_connection` or
|
97
|
+
# `JSS.connection`
|
98
|
+
#
|
99
|
+
# To activate another connection just pass it to the JSS.use_api method like so:
|
100
|
+
# JSS.use_api production_api
|
101
|
+
# # the connection we stored in 'production_api' is now active
|
102
|
+
#
|
103
|
+
# To re-activate to the default connection, just call
|
104
|
+
# JSS.use_default_connection
|
105
|
+
#
|
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
|
+
# == Connection Names:
|
116
|
+
#
|
117
|
+
# As seen in the example above, you can provide a 'name:' parameter
|
118
|
+
# (a String or a Symbol) when creating a new connection. The name can be
|
119
|
+
# used later to identify connection objects.
|
120
|
+
#
|
121
|
+
# If you don't provide one, the name is ':disconnected' until you
|
122
|
+
# connect, and then 'user@server:port' after connecting.
|
123
|
+
#
|
124
|
+
# The name of the default connection is always :default
|
125
|
+
#
|
126
|
+
# To see the name of the currently active connection, just use `JSS.api.name`
|
127
|
+
#
|
128
|
+
# JSS.use_api production_api
|
129
|
+
# JSS.api.name # => 'prod'
|
130
|
+
#
|
131
|
+
# JSS.use_default_connection
|
132
|
+
# JSS.api.name # => :default
|
133
|
+
#
|
134
|
+
# == Creating, Storing and Activating a connection in one step
|
135
|
+
#
|
136
|
+
# Both of the above steps (creating/storing a connection, and making it
|
137
|
+
# active) can be performed in one step using the
|
138
|
+
# `JSS.new_api_connection` method, which creates a new APIConnection, makes it
|
139
|
+
# the active connection, and returns it.
|
140
|
+
#
|
141
|
+
# production_api2 = JSS.new_api_connection(
|
142
|
+
# name: 'prod2',
|
143
|
+
# server: 'prodserver.address.org',
|
144
|
+
# user: 'produser',
|
145
|
+
# pw: :prompt
|
146
|
+
# )
|
147
|
+
#
|
148
|
+
# JSS.api.name # => 'prod2'
|
149
|
+
#
|
150
|
+
# == Low-level use of APIConnection instances.
|
151
|
+
#
|
152
|
+
# For most uses, creating, activating, and connecting APIConnection instances
|
153
|
+
# is all you'll need. However to access API resources that aren't yet
|
154
|
+
# implemented in other parts of ruby-jss, you can use the methods
|
155
|
+
# {#get_rsrc}, {#put_rsrc}, {#post_rsrc}, & {#delete_rsrc}
|
156
|
+
# documented below.
|
157
|
+
#
|
158
|
+
# For even lower-level work, you can access the underlying RestClient::Resource
|
159
|
+
# inside the APIConnection via the connection's {#cnx} attribute.
|
160
|
+
#
|
161
|
+
# APIConnection instances also have a {#server} attribute which contains an
|
162
|
+
# instance of {JSS::Server} q.v., representing the JSS to which it's connected.
|
52
163
|
#
|
53
164
|
class APIConnection
|
54
165
|
|
@@ -117,13 +228,41 @@ module JSS
|
|
117
228
|
# @return [String] The base URL to to the current REST API
|
118
229
|
attr_reader :rest_url
|
119
230
|
|
231
|
+
# @return [String,Symbol] an arbitrary name that can be given to this
|
232
|
+
# connection during initialization, using the name: parameter.
|
233
|
+
# defaults to user@hostname:port
|
234
|
+
attr_reader :name
|
235
|
+
|
236
|
+
# @return [Hash]
|
237
|
+
# This Hash holds the most recent API query for a list of all items in any
|
238
|
+
# APIObject subclass, keyed by the subclass's RSRC_LIST_KEY.
|
239
|
+
# See the APIObject.all class method.
|
240
|
+
#
|
241
|
+
# When the APIObject.all method is called without an argument,
|
242
|
+
# and this hash has a matching value, the value is returned, rather than
|
243
|
+
# requerying the API. The first time a class calls .all, or whnever refresh
|
244
|
+
# is not false, the API is queried and the value in this hash is updated.
|
245
|
+
attr_reader :object_list_cache
|
246
|
+
|
120
247
|
# Constructor
|
121
248
|
#####################################
|
122
249
|
|
123
|
-
#
|
250
|
+
# If name: is provided (as a String or Symbol) that will be
|
251
|
+
# stored as the APIConnection's name attribute.
|
252
|
+
#
|
253
|
+
# For other available parameters, see {#connect}.
|
254
|
+
#
|
255
|
+
# If they are provided, they will be used to establish the
|
256
|
+
# connection immediately.
|
257
|
+
#
|
258
|
+
# If not, you must call {#connect} before accessing the API.
|
124
259
|
#
|
125
|
-
def initialize
|
260
|
+
def initialize(args = {})
|
261
|
+
@name = args.delete :name
|
262
|
+
@name ||= :disconnected
|
126
263
|
@connected = false
|
264
|
+
@object_list_cache = {}
|
265
|
+
connect args unless args.empty?
|
127
266
|
end # init
|
128
267
|
|
129
268
|
# Instance Methods
|
@@ -175,6 +314,7 @@ module JSS
|
|
175
314
|
|
176
315
|
verify_server_version
|
177
316
|
|
317
|
+
@name = "#{@jss_user}@#{@server_host}:#{@port}" if @name.nil? || @name == :disconnected
|
178
318
|
@connected ? hostname : nil
|
179
319
|
end # connect
|
180
320
|
|
@@ -237,7 +377,8 @@ module JSS
|
|
237
377
|
# @return [Hash,String] the result of the get
|
238
378
|
#
|
239
379
|
def get_rsrc(rsrc, format = :json)
|
240
|
-
|
380
|
+
# puts object_id
|
381
|
+
raise JSS::InvalidConnectionError, 'Not Connected. Use JSS.api.connect first.' unless @connected
|
241
382
|
rsrc = URI.encode rsrc
|
242
383
|
@last_http_response = @cnx[rsrc].get(accept: format)
|
243
384
|
return JSON.parse(@last_http_response, symbolize_names: true) if format == :json
|
@@ -252,7 +393,7 @@ module JSS
|
|
252
393
|
# @return [String] the xml response from the server.
|
253
394
|
#
|
254
395
|
def put_rsrc(rsrc, xml)
|
255
|
-
raise JSS::InvalidConnectionError, 'Not Connected. Use JSS
|
396
|
+
raise JSS::InvalidConnectionError, 'Not Connected. Use JSS.api_connection.connect first.' unless @connected
|
256
397
|
|
257
398
|
# convert CRs & to
|
258
399
|
xml.gsub!(/\r/, ' ')
|
@@ -271,11 +412,11 @@ module JSS
|
|
271
412
|
#
|
272
413
|
# @return [String] the xml response from the server.
|
273
414
|
#
|
274
|
-
def post_rsrc(rsrc, xml)
|
275
|
-
raise JSS::InvalidConnectionError, 'Not Connected. Use JSS
|
415
|
+
def post_rsrc(rsrc, xml = '')
|
416
|
+
raise JSS::InvalidConnectionError, 'Not Connected. Use JSS.api_connection.connect first.' unless @connected
|
276
417
|
|
277
418
|
# convert CRs & to
|
278
|
-
xml.gsub!(/\r/, ' ')
|
419
|
+
xml.gsub!(/\r/, ' ') if xml
|
279
420
|
|
280
421
|
# send the data
|
281
422
|
@last_http_response = @cnx[rsrc].post xml, content_type: 'text/xml', accept: :json
|
@@ -289,10 +430,13 @@ module JSS
|
|
289
430
|
#
|
290
431
|
# @return [String] the xml response from the server.
|
291
432
|
#
|
292
|
-
def delete_rsrc(rsrc)
|
293
|
-
raise JSS::InvalidConnectionError, 'Not Connected. Use JSS
|
433
|
+
def delete_rsrc(rsrc, xml = nil)
|
434
|
+
raise JSS::InvalidConnectionError, 'Not Connected. Use JSS.api_connection.connect first.' unless @connected
|
294
435
|
raise MissingDataError, 'Missing :rsrc' if rsrc.nil?
|
295
436
|
|
437
|
+
# payload?
|
438
|
+
return delete_with_payload rsrc, xml if xml
|
439
|
+
|
296
440
|
# delete the resource
|
297
441
|
@last_http_response = @cnx[rsrc].delete
|
298
442
|
end # delete_rsrc
|
@@ -352,14 +496,29 @@ module JSS
|
|
352
496
|
####################################
|
353
497
|
private
|
354
498
|
|
355
|
-
# Apply defaults from the JSS::CONFIG,
|
356
|
-
#
|
499
|
+
# Apply defaults from the JSS::CONFIG,
|
500
|
+
# then from the JSS::Client,
|
501
|
+
# then from the module defaults
|
502
|
+
# to the args for the #connect method
|
357
503
|
#
|
358
504
|
# @param args[Hash] The args for #connect
|
359
505
|
#
|
360
506
|
# @return [Hash] The args with defaults applied
|
361
507
|
#
|
362
508
|
def apply_connection_defaults(args)
|
509
|
+
apply_defaults_from_config(args)
|
510
|
+
apply_defaults_from_client(args)
|
511
|
+
apply_module_defaults(args)
|
512
|
+
end
|
513
|
+
|
514
|
+
# Apply defaults from the JSS::CONFIG
|
515
|
+
# to the args for the #connect method
|
516
|
+
#
|
517
|
+
# @param args[Hash] The args for #connect
|
518
|
+
#
|
519
|
+
# @return [Hash] The args with defaults applied
|
520
|
+
#
|
521
|
+
def apply_defaults_from_config(args)
|
363
522
|
# settings from config if they aren't in the args
|
364
523
|
args[:server] ||= JSS::CONFIG.api_server_name
|
365
524
|
args[:port] ||= JSS::CONFIG.api_server_port
|
@@ -371,12 +530,32 @@ module JSS
|
|
371
530
|
# if verify cert was not in the args, get it from the prefs.
|
372
531
|
# We can't use ||= because the desired value might be 'false'
|
373
532
|
args[:verify_cert] = JSS::CONFIG.api_verify_cert if args[:verify_cert].nil?
|
533
|
+
args
|
534
|
+
end # apply_defaults_from_config
|
374
535
|
|
536
|
+
# Apply defaults from the JSS::Client
|
537
|
+
# to the args for the #connect method
|
538
|
+
#
|
539
|
+
# @param args[Hash] The args for #connect
|
540
|
+
#
|
541
|
+
# @return [Hash] The args with defaults applied
|
542
|
+
#
|
543
|
+
def apply_defaults_from_client(args)
|
544
|
+
return unless JSS::Client.installed?
|
375
545
|
# these settings can come from the jamf binary config, if this machine is a JSS client.
|
376
546
|
args[:server] ||= JSS::Client.jss_server
|
377
547
|
args[:port] ||= JSS::Client.jss_port
|
378
|
-
args[:use_ssl] ||= JSS::Client.jss_protocol.end_with? 's'
|
548
|
+
args[:use_ssl] ||= JSS::Client.jss_protocol.to_s.end_with? 's'
|
549
|
+
args
|
550
|
+
end
|
379
551
|
|
552
|
+
# Apply the module defaults to the args for the #connect method
|
553
|
+
#
|
554
|
+
# @param args[Hash] The args for #connect
|
555
|
+
#
|
556
|
+
# @return [Hash] The args with defaults applied
|
557
|
+
#
|
558
|
+
def apply_module_defaults(args)
|
380
559
|
# defaults from the module if needed
|
381
560
|
args[:port] ||= args[:use_ssl] ? SSL_PORT : HTTP_PORT
|
382
561
|
args[:timeout] ||= DFT_TIMEOUT
|
@@ -410,7 +589,18 @@ module JSS
|
|
410
589
|
#
|
411
590
|
def verify_server_version
|
412
591
|
@connected = true
|
413
|
-
|
592
|
+
|
593
|
+
# the jssuser resource is readable by anyone with a JSS acct
|
594
|
+
# regardless of their permissions.
|
595
|
+
# However, it's marked as 'deprecated'. Hopefully jamf will
|
596
|
+
# keep this basic level of info available for basic authentication
|
597
|
+
# and JSS version checking.
|
598
|
+
begin
|
599
|
+
@server = JSS::Server.new get_rsrc('jssuser')[:user]
|
600
|
+
rescue RestClient::Unauthorized, RestClient::Request::Unauthorized
|
601
|
+
raise JSS::AuthenticationError, "Incorrect JSS username or password for '#{JSS.api_connection.jss_user}@#{JSS.api_connection.server_host}'."
|
602
|
+
end
|
603
|
+
|
414
604
|
min_vers = JSS.parse_jss_version(JSS::MINIMUM_SERVER_VERSION)[:version]
|
415
605
|
return unless @server.version < min_vers
|
416
606
|
err_msg = "JSS version #{@server.raw_version} to low. Must be >= #{min_vers}"
|
@@ -485,9 +675,101 @@ module JSS
|
|
485
675
|
raise JSS::ConflictError, conflict_reason
|
486
676
|
end
|
487
677
|
|
488
|
-
|
678
|
+
# RestClient::Resource#delete doesn't take an HTTP payload,
|
679
|
+
# but some JSS API resources require it (notably, logflush).
|
680
|
+
#
|
681
|
+
# This method uses RestClient::Request#execute
|
682
|
+
# to do the same thing that RestClient::Resource#delete does, but
|
683
|
+
# adding the payload.
|
684
|
+
#
|
685
|
+
# @param rsrc[String] the sub-resource we're DELETEing
|
686
|
+
#
|
687
|
+
# @param payload[String] The XML to be passed with the DELETE
|
688
|
+
#
|
689
|
+
# @param additional_headers[Type] See RestClient::Request#execute
|
690
|
+
#
|
691
|
+
# @param &block[Type] See RestClient::Request#execute
|
692
|
+
#
|
693
|
+
# @return [String] the XML response from the server.
|
694
|
+
#
|
695
|
+
def delete_with_payload(rsrc, payload, additional_headers = {}, &block)
|
696
|
+
headers = (@cnx.options[:headers] || {}).merge(additional_headers)
|
697
|
+
@last_http_response = RestClient::Request.execute(
|
698
|
+
@cnx.options.merge(
|
699
|
+
method: :delete,
|
700
|
+
url: @cnx[rsrc].url,
|
701
|
+
payload: payload,
|
702
|
+
headers: headers
|
703
|
+
),
|
704
|
+
&(block || @block)
|
705
|
+
)
|
706
|
+
end # delete_with_payload
|
707
|
+
|
708
|
+
end # class APIConnection
|
709
|
+
|
710
|
+
# Create a new APIConnection object and use it for all
|
711
|
+
# future API calls. If connection options are provided,
|
712
|
+
# they are passed to the connect method immediately, otherwise
|
713
|
+
# JSS.api.connect must be called before attemting to use the
|
714
|
+
# connection.
|
715
|
+
#
|
716
|
+
# @param (See JSS::APIConnection#connect)
|
717
|
+
#
|
718
|
+
# @return [APIConnection] the new, active connection
|
719
|
+
#
|
720
|
+
def self.new_api_connection(args = {})
|
721
|
+
@api = APIConnection.new args
|
722
|
+
@api
|
723
|
+
end
|
724
|
+
|
725
|
+
# Switch the connection used for all API interactions to the
|
726
|
+
# one provided. See {JSS::APIConnection} for details and examples
|
727
|
+
# of using multiple connections
|
728
|
+
#
|
729
|
+
# @param connection [APIConnection] The APIConnection to use for future
|
730
|
+
# API calls. If omitted, use the default connection created when ruby-jss
|
731
|
+
# was loaded (which may or may not yet be connected)
|
732
|
+
#
|
733
|
+
# @return [APIConnection] The connection now being used.
|
734
|
+
#
|
735
|
+
def self.use_api_connection(connection)
|
736
|
+
raise 'API connections must be instances of JSS::APIConnection' unless connection.is_a? JSS::APIConnection
|
737
|
+
@api = connection
|
738
|
+
end
|
739
|
+
|
740
|
+
# Make the default connection (Stored in JSS::API) active
|
741
|
+
#
|
742
|
+
# @return [void]
|
743
|
+
#
|
744
|
+
def self.use_default_connection
|
745
|
+
use_api_connection API
|
746
|
+
end
|
747
|
+
|
748
|
+
# The currently active JSS::APIConnection instance.
|
749
|
+
#
|
750
|
+
# @return [JSS::APIConnection]
|
751
|
+
#
|
752
|
+
def self.api
|
753
|
+
@api
|
754
|
+
end
|
755
|
+
|
756
|
+
# aliases of module methods
|
757
|
+
class << self
|
758
|
+
alias api_connection api
|
759
|
+
alias connection api
|
760
|
+
|
761
|
+
alias new_connection new_api_connection
|
762
|
+
alias new_api new_api_connection
|
763
|
+
|
764
|
+
alias use_api use_api_connection
|
765
|
+
alias use_connection use_api_connection
|
766
|
+
end
|
767
|
+
|
768
|
+
# create the default connection
|
769
|
+
new_api_connection(name: :default) unless @api
|
489
770
|
|
490
|
-
#
|
491
|
-
|
771
|
+
# Save the default connection in the API constant,
|
772
|
+
# mostly for backward compatibility.
|
773
|
+
API = @api unless defined? API
|
492
774
|
|
493
775
|
end # module
|