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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba0289a3600d2d044211e9b13ee210fb6c10b7a2
4
- data.tar.gz: 647f502e548e3f86345ce9992e20ec26fbe1a273
3
+ metadata.gz: 770c1a47f03a6f98144c8ad351559817416166fb
4
+ data.tar.gz: 8271b37e6692aef2f4005f3bbf043964c3d9b5c9
5
5
  SHA512:
6
- metadata.gz: dfebb20f13d49cd7677bc9e5fbb47ab668d5a98640cfdd3a4e97852c2cd22189c563cad9759972c5932e047ab31fdeb3cad9dce84c80c67f7e9c7e33f1f8d0f8
7
- data.tar.gz: fb8761e60f48733df1f6047a4b1b324a1ece25d6c7dad6693b2a162cdd08d981921df20efb475716996f887b43f10b4c17c5029146387ca528199da9c3583950
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.8.1 2017-06-07
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::API.connect user: jss_user, pw: jss_user_pw, server: jss_server_hostname
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::API.connect, passing it values for the connection. In this example, those values are stored
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::API.connect user: jss_user, pw: jss_user_pw, server: jss_server_hostname
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 {JSS::Configuration}, and the [CONFIGURATION](#configuration) section below, for how to store
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 .create.
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::APIConnect} - An object representing the connection to the REST API
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::API.connect will override the config values.
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::API.connect} will assume that server and username, and won't complain about the self-signed certificate.
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::API.connect call.
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::API.connect pw: password # other arguments used from the config settings
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::API.connect pw: password # other arguments used from the config settings
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 Casper 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:
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
- the JSS gem was written for:
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::API.connect( :server => @options.server,
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
@@ -148,7 +148,7 @@ class App
148
148
  end # run
149
149
 
150
150
  def connect_to_jss
151
- JSS::API.connect(
151
+ JSS.api_connection.connect(
152
152
  server: @server,
153
153
  port: @port,
154
154
  verify_cert: @verify_cert,
@@ -37,18 +37,129 @@ module JSS
37
37
  # Classes
38
38
  #####################################
39
39
 
40
- # An API connection to the JSS.
40
+ # Instances of this class represent an API connection to the JSS.
41
41
  #
42
- # This is a singleton class, only one can exist at a time.
43
- # Its one instance is created automatically when the module loads, but it
44
- # isn't connected to anything at that time.
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
- # Use it via the {JSS::API} constant to call the #connect
47
- # method, and the {#get_rsrc}, {#put_rsrc}, {#post_rsrc}, & {#delete_rsrc}
48
- # methods, q.v. below.
46
+ # == The default connection
49
47
  #
50
- # To access the underlying RestClient::Resource instance,
51
- # use JSS::API.cnx
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
- # To connect, use JSS::API.connect
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
- raise JSS::InvalidConnectionError, 'Not Connected. Use JSS::API.connect first.' unless @connected
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::API.connect first.' unless @connected
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::API.connect first.' unless @connected
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::API.connect first.' unless @connected
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, the JSS::Client
356
- # or the module defaults to the args for the #connect method
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
- @server = JSS::Server.new
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
- end # class JSSAPIConnection
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
- # The default APIConnection
491
- API = APIConnection.new
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