ruby-jss 1.0.0b2 → 1.0.0b6
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 +5 -5
- data/.yardopts +1 -1
- data/CHANGES.md +46 -8
- data/README.md +26 -27
- data/bin/cgrouper +2 -2
- data/bin/jamfHelperBackgrounder +0 -2
- data/bin/netseg-update +3 -4
- data/data/ruby-jss.conf.example +2 -8
- data/lib/jss/api_connection.rb +6 -3
- data/lib/jss/api_object/advanced_search.rb +1 -1
- data/lib/jss/api_object/computer_invitation.rb +1 -1
- data/lib/jss/api_object/criteriable.rb +1 -1
- data/lib/jss/api_object/ebook.rb +25 -0
- data/lib/jss/api_object/group.rb +1 -1
- data/lib/jss/api_object/mobile_device_application.rb +1 -1
- data/lib/jss/api_object/patch_title.rb +98 -46
- data/lib/jss/api_object/peripheral.rb +2 -2
- data/lib/jss/api_object/sitable.rb +1 -1
- data/lib/jss/api_object.rb +2 -2
- data/lib/jss/client/management_action.rb +2 -2
- data/lib/jss/utility.rb +1 -1
- data/lib/jss/validate.rb +32 -29
- data/lib/jss/version.rb +1 -1
- data/test/README.md +149 -0
- data/test/bin/runtests +290 -0
- data/test/lib/testhelper/auth.rb +275 -0
- data/test/lib/testhelper/patch_mgmt.rb +123 -0
- data/test/lib/testhelper.rb +69 -0
- data/test/specs/api_connection_spec.rb +57 -0
- data/test/specs/patch01_source_spec.rb +54 -0
- data/test/specs/patch02_internal_source_spec.rb +88 -0
- data/test/specs/patch03_external_source_spec.rb +120 -0
- data/test/specs/patch04_titles_spec.rb +207 -0
- data/test/specs/patch05_policies_spec.rb +119 -0
- data/test/specs/patch06_cleanup_spec.rb +52 -0
- data/test/specs/policy_spec.rb +112 -0
- metadata +16 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b7a56f45bbacab2bbc21539605b30f7bedbaef3672a639d2f32b80d766352090
|
4
|
+
data.tar.gz: d9ade8517e722087ae3fc6fe4ed79c01b938a01a1e5b556c3df6ca2b294282d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81be4beedc05189fb45f8978895458c1ee9ee70eaee7755c90bd3b7f9af01084f39593b5caaea77973ad20d41e317e40235a5307d4279ebc84dcd9e780120095
|
7
|
+
data.tar.gz: 0afc5a122964e84d1869a5c4f9914d0b790d91f641a1b76aa1673640bea0a501449e6d59c653fcec3adc0b3f14e00d6ae18350b2a988be32d4dc415b0f92fd30
|
data/.yardopts
CHANGED
data/CHANGES.md
CHANGED
@@ -1,35 +1,73 @@
|
|
1
1
|
# Change History
|
2
2
|
|
3
|
-
## v 1.0.
|
3
|
+
## v 1.0.0, 2018-08-10
|
4
|
+
|
5
|
+
Finally we're going to version 1.0, which we should have done when we went opensource. Future releases will try to adhere to [Semantic Versioning](https://semver.org/) as described in the [rubygems.org guidelines](https://guides.rubygems.org/patterns/#semantic-versioning)
|
6
|
+
|
7
|
+
**IMPORTANT** This version is not backward compatible with 0.x version. Please read the details below and test your code before deploying widely.
|
8
|
+
|
4
9
|
|
5
|
-
Finally we're going to version 1.0, which we should have done when we went opensource.
|
6
10
|
|
7
11
|
- requirement: Jamf Pro API version must be 10.4 or higher
|
8
12
|
|
13
|
+
- change: defaults to using TLSv1.2 for API connections.
|
14
|
+
|
15
|
+
As of Jamf Pro 10.5. the server requires TLSv1.2 and will not accept connections using TLSv1.
|
16
|
+
|
17
|
+
**COMPATIBILITY:**
|
18
|
+
|
19
|
+
MacOS 10.12 and lower have an old version of the openssl library which used by the built-in ruby (/usr/bin/ruby), which does not support TLSv1.2.
|
20
|
+
|
21
|
+
If you are using macOS 10.12 or lower to connect to Jamf Pro 10.4 (the lowest Jamf server supported by this version of ruby-jss), you must specify the older TLS when using APIConnection#connect, e.g.
|
22
|
+
|
23
|
+
`JSS.api.connect server: 'myjss.myschool.edu', user: 'username', pw: :prompt, ssl_version: :TLSv1`
|
24
|
+
|
25
|
+
Machines running macOS 10.12 or lower will not be able to connect to Jamf Pro > v10.4 with the built-in ruby openssl library. If you specify `ssl_version: :TLSv1` you will get an error because the server won't accept it. If you leave the default :TLSv1_2, ruby's openssl library will complain that it doesn't know about that.
|
26
|
+
|
27
|
+
If you have 10.12 or older machines that must connect to newer Jamf Pro servers with ruby-jss, there are a few options.
|
28
|
+
|
29
|
+
- upgade the machines to 10.13 or higher
|
30
|
+
- install a newer openssl, then install a your own ruby using that openssl (both can be done with homebrew)
|
31
|
+
- do the above, then extract the openssl library and modify it to work with the built-in ruby.
|
32
|
+
|
33
|
+
If you have questions about this, feel free to reach out to ruby-jss@pixar.com, or in the #ruby or #jss-api channels in MacAdmins slack space, for some advice.
|
34
|
+
|
9
35
|
- add: JSS::PatchSource metaclass and the subclassses JSS::PatchInternalSource, and JSS::PatchExternalSource. These provide acecss to the patchavailabletitles enpoint, which is needed to acquire name_id's for creating/activating JSS::PatchTitles
|
10
36
|
|
11
|
-
- add: JSS::PatchTitle, which also gives access to the patchreports endpoint. Also uses the JSS::PatchTitle::Version class to handle patch versions within a title, and assign packages to them.
|
37
|
+
- add: JSS::PatchTitle, which also gives access to the patchreports endpoint. Also uses the JSS::PatchTitle::Version class to handle patch versions within a title, and assign packages to them. **WARNING**: ruby-jss will now allow duplicate 'display names' (the #name of the JSS::PatchTitle instance) - but the Jamf Web UI will allow duplicates. If you have duplicates, and retrieve PatchTitles by name, which one gets returned to you is undefined.
|
38
|
+
|
39
|
+
- The 'source_id' and 'name_id' of a patch title are, when combined, a unique identifier in the JSS (i.e. name_id's are unique within sources) As such, the PatchTitle.all list provides a :source_name_id key, which is a String made by joining the two values with a '-', e.g. '1-GoogleChrome'. This value can be used as a lookup for .fetch, e.g. `JSS::PatchTitle.fetch source_name_id: '1-GoogleChrome'`. There is also a matching .all_source_name_ids method, and the .map_all_ids_to() method takes :source_name_id as a mapping parameter. You can also use .fetch and .make with both source: (id or name) and name_id: specified.
|
40
|
+
|
12
41
|
|
13
|
-
- add: JSS::PatchPolicy. PatchPolicies are creatable when providing an active PatchTitle and an
|
42
|
+
- add: JSS::PatchPolicy. PatchPolicies are creatable when providing an active PatchTitle and an appropriate PatchTitle::Version that has a package assigned to it.
|
14
43
|
|
15
44
|
- add: the Group metaclass now has a calculate_members option (bool) to the #create method. When true, the membership of the group will be updated in the existing ruby instance immediately after the group is created in the JSS. Doesn't do much for static groups, but is useful for smart groups. Defaults to true. If you don't care about the membership immediately, or don't want to wait for the membership to be calculated on the server, set this to false.
|
16
45
|
|
17
46
|
- improvement: better handling of http error responses
|
18
47
|
|
48
|
+
- improvement: JSS::Policy objects now have setters for the 'Maintenence' subset, e.g. recons ('update inventory'), reset_name, fix_byhost, etc.
|
49
|
+
|
19
50
|
- add: more generic data validation methods in JSS::Validate module, and more use of them throughout the code.
|
20
51
|
|
21
52
|
- add: 'support' in SelfServable for notifications - note that there are API bugs limiting the usefulness of this.
|
22
53
|
|
23
54
|
- add: regex options to JSS::Criteriable::Criterion objects
|
24
55
|
|
25
|
-
- remove: the .new class method on APIObject subclasses no longer works. Even
|
56
|
+
- remove: the .new class method on APIObject subclasses no longer works. Even though it's the standard ruby way to create instances of a class, it was confusing, since it implied creating new objects in the JSS. Instead you must now use the .fetch class method to instantiate existing objects and the .make class method to instantiate local instances of objects to be created in the JSS.
|
57
|
+
|
58
|
+
**COMPATIBILITY:**
|
59
|
+
|
60
|
+
`existingcomp = JSS::Computer.new id: 1234` and `new_pol = JSS::Policy.new id: :new, name: 'mypolicy'` will now raise an error.
|
61
|
+
|
62
|
+
Instead you must use `existingcomp = JSS::Computer.fetch id: 1234` and `new_pol = JSS::Policy.make name: 'mypolicy'`
|
26
63
|
|
27
|
-
|
64
|
+
Note that the instance methods #create (create the current instance as a new object in the JSS) and #update (send changes in the current instance to the JSS) remain unchanged, and both continue handled by #save
|
28
65
|
|
29
|
-
- add: there is now a, sort-of, spec/testing framework. While based on ruby's minitest specifications,
|
66
|
+
- add: there is now a, sort-of, spec/testing framework. While based on ruby's minitest specifications, it's wrapped in a very custom executable with a helper module. See the README in the test directory for details. Specs will be added slowly over time.
|
30
67
|
|
31
|
-
-
|
68
|
+
- add: JSS::Client now has a .management_action class method, which wraps around the 'Management Action.app' tool that comes with Jamf Pro and creates Notification Center notifications. At the moment support is minimal, and the notification type (alert vs. banner) is up to the User.
|
32
69
|
|
70
|
+
- misc: as Apple says: various bugfixes and improvements.
|
33
71
|
|
34
72
|
## v 0.14.0, 2018-05-30
|
35
73
|
|
data/README.md
CHANGED
@@ -27,13 +27,13 @@
|
|
27
27
|
|
28
28
|
## DESCRIPTION
|
29
29
|
|
30
|
-
|
30
|
+
ruby-jss defines a Ruby module called JSS, which is used for accessing the 'classic' REST API of
|
31
31
|
the JAMF Software Server (JSS), the core of Jamf Pro, an enterprise-level management tool for Apple
|
32
32
|
devices from [Jamf.com](http://www.jamf.com/). It is available as a
|
33
33
|
[rubygem](https://rubygems.org/gems/ruby-jss), and the
|
34
34
|
[source is on github](https://github.com/PixarAnimationStudios/ruby-jss).
|
35
35
|
|
36
|
-
The module abstracts API resources as Ruby objects, and provides methods for interacting with those
|
36
|
+
The module abstracts many API resources as Ruby objects, and provides methods for interacting with those
|
37
37
|
resources. It also provides some features that aren't a part of the API itself, but come with other
|
38
38
|
Jamf-related tools, such as uploading .pkg and .dmg {JSS::Package} data to the master distribution
|
39
39
|
point, and the installation of {JSS::Package} objects on client machines. (See [BEYOND THE API](#beyond-the-api))
|
@@ -47,7 +47,6 @@ Hopefully others will find it useful, and add more to it as well.
|
|
47
47
|
|
48
48
|
[Full technical documentation can be found here.](http://www.rubydoc.info/gems/ruby-jss/)
|
49
49
|
|
50
|
-
|
51
50
|
## SYNOPSIS
|
52
51
|
|
53
52
|
Here are some simple examples of using ruby-jss
|
@@ -157,8 +156,8 @@ Some classes can use more than just the :id and :name keys for lookups, e.g. com
|
|
157
156
|
|
158
157
|
You can even fetch objects without specifying the kind of identifier, e.g. `JSS::Computer.fetch 3241`, but this will be slower, since ruby-jss searches by matching the given value with all available identifiers, returning the first match.
|
159
158
|
|
160
|
-
*NOTE*:
|
161
|
-
The '.new' method
|
159
|
+
*NOTE*: For APIObject subclasses, the '.fetch' class method is now the required method to use for retrieving existing objects
|
160
|
+
from the API. The '.new' method no longer works. See below for using .make to create new objects in the JSS.
|
162
161
|
|
163
162
|
--------
|
164
163
|
|
@@ -185,7 +184,9 @@ Then use the #create method to create it in the JSS. The #save method is an alia
|
|
185
184
|
new_pkg.create # returns 453, the id number of the object just created
|
186
185
|
```
|
187
186
|
|
188
|
-
*NOTE*:
|
187
|
+
*NOTE*: For APIObject subclasses, the '.make' class method is now the required method to use for making ruby instances to be
|
188
|
+
created in the JSS. The '.new' method no longer works.
|
189
|
+
|
189
190
|
|
190
191
|
--------
|
191
192
|
|
@@ -240,6 +241,7 @@ Here's what we've implemented so far. See each Class's [documentation(http://www
|
|
240
241
|
* {JSS::ComputerExtensionAttribute}
|
241
242
|
* {JSS::ComputerGroup}
|
242
243
|
* {JSS::Department}
|
244
|
+
* {JSS::DistributionPoint}
|
243
245
|
* {JSS::MobileDeviceApplication}
|
244
246
|
* {JSS::MobileDeviceExtensionAttribute}
|
245
247
|
* {JSS::MobileDeviceGroup}
|
@@ -258,6 +260,10 @@ Here's what we've implemented so far. See each Class's [documentation(http://www
|
|
258
260
|
* {JSS::Computer}
|
259
261
|
* {JSS::MobileDevice}
|
260
262
|
* {JSS::Policy} (still not fully implemented)
|
263
|
+
* {JSS::PatchInternalSource}
|
264
|
+
* {JSS::PatchExternalSource}
|
265
|
+
* {JSS::PatchTitle}
|
266
|
+
* {JSS::PatchPolicy}
|
261
267
|
|
262
268
|
**NOTE** Computer and Mobile Device data gathered by an Inventory Upate (a.k.a. 'recon') is not editable.
|
263
269
|
|
@@ -368,26 +374,6 @@ While the Jamf Pro API provides access to object data in the JSS, this gem tries
|
|
368
374
|
* Extension Attributes
|
369
375
|
* {JSS::ExtensionAttribute} work with {JSS::AdvancedSearch} subclasses to provide extra reporting about Ext. Attrib. values.
|
370
376
|
|
371
|
-
## REQUIREMENTS
|
372
|
-
|
373
|
-
ruby-jss was written for:
|
374
|
-
|
375
|
-
* Mac OS X 10.9 or higher
|
376
|
-
* Ruby 2.0 or higher
|
377
|
-
* Casper Suite version 9.4 or higher
|
378
|
-
|
379
|
-
It also requires these gems, which will be installed automatically if you install JSS with `gem install jss`
|
380
|
-
|
381
|
-
* rest-client >=1.6.7 ( >= 1.7.0 with Casper >= 9.6.1) http://rubygems.org/gems/rest-client
|
382
|
-
* json or json\_pure >= 1.6.5 http://rubygems.org/gems/json or http://rubygems.org/gems/json_pure
|
383
|
-
* (only in ruby 1.8.7. Ruby >= 1.9 has json in its standard library)
|
384
|
-
* ruby-mysql >= 2.9.12 http://rubygems.org/gems/ruby-mysql
|
385
|
-
* (only for a few things that still require direct SQL access to the JSS database)
|
386
|
-
* plist =3.1.0 http://rubygems.org/gems/plist
|
387
|
-
* for the {JSS::Composer} module and {JSS::Client} class
|
388
|
-
* net-ldap >= 0.3.1 http://rubygems.org/gems/net-ldap
|
389
|
-
* for accessing the LDAP servers defined in the JSS, to check for user and group info.
|
390
|
-
|
391
377
|
## INSTALL
|
392
378
|
|
393
379
|
NOTE: You may need to install XCode, and it's CLI tools, in order to install the required gems.
|
@@ -396,10 +382,23 @@ In general, you can install ruby-jss with this command:
|
|
396
382
|
|
397
383
|
`gem install ruby-jss`
|
398
384
|
|
385
|
+
## REQUIREMENTS
|
386
|
+
|
387
|
+
ruby-jss was written for:
|
388
|
+
|
389
|
+
* Mac OS X 10.9 or higher
|
390
|
+
* Ruby 2.0 or higher
|
391
|
+
* Casper Suite version 10.4 or higher
|
392
|
+
|
393
|
+
It also requires other ruby gems, which will be installed automatically if you install with `gem install ruby-jss`
|
394
|
+
See the .gemspec file for details
|
395
|
+
|
399
396
|
|
400
397
|
## HELP
|
401
398
|
|
402
|
-
Full documentation is available at [rubydoc.info](http://www.rubydoc.info/gems/ruby-jss/)
|
399
|
+
Full documentation is available at [rubydoc.info](http://www.rubydoc.info/gems/ruby-jss/).
|
400
|
+
|
401
|
+
There's a [wiki on the github page](https://github.com/PixarAnimationStudios/ruby-jss/wiki), feel free to contribute examples and tidbits.
|
403
402
|
|
404
403
|
[Email the developers](mailto:ruby-jss@pixar.com)
|
405
404
|
|
data/bin/cgrouper
CHANGED
@@ -207,9 +207,9 @@ class App
|
|
207
207
|
|
208
208
|
# get the group from the API
|
209
209
|
if @options.action == :create_group
|
210
|
-
@group = JSS::ComputerGroup.
|
210
|
+
@group = JSS::ComputerGroup.make :name => @options.group, :type => :static
|
211
211
|
else
|
212
|
-
@group = JSS::ComputerGroup.
|
212
|
+
@group = JSS::ComputerGroup.fetch :name => @options.group
|
213
213
|
end
|
214
214
|
|
215
215
|
end # if ACTIONS_NEEDING_GROUP
|
data/bin/jamfHelperBackgrounder
CHANGED
data/bin/netseg-update
CHANGED
@@ -322,8 +322,7 @@ Notes:
|
|
322
322
|
end # if noop
|
323
323
|
|
324
324
|
ender = @use_cidr ? :cidr : :ending_address
|
325
|
-
new_seg = JSS::NetworkSegment.
|
326
|
-
:id => :new,
|
325
|
+
new_seg = JSS::NetworkSegment.make(
|
327
326
|
:name => seg,
|
328
327
|
:starting_address => seg_data[:starting],
|
329
328
|
ender => seg_data[:ending]
|
@@ -339,7 +338,7 @@ Notes:
|
|
339
338
|
puts "Without --no-op this would: Delete segment named '#{seg}',"
|
340
339
|
next
|
341
340
|
end # if noop
|
342
|
-
JSS::NetworkSegment.
|
341
|
+
JSS::NetworkSegment.fetch(name: seg).delete
|
343
342
|
puts "Deleted Network Segment '#{seg}' from the JSS"
|
344
343
|
end # @segments_to_delete.each do |seg|
|
345
344
|
end # delete_segments
|
@@ -354,7 +353,7 @@ Notes:
|
|
354
353
|
IPAddr.new(seg_data[:ending])
|
355
354
|
end
|
356
355
|
|
357
|
-
this_seg = JSS::NetworkSegment.
|
356
|
+
this_seg = JSS::NetworkSegment.fetch name: seg
|
358
357
|
data_range = data_start..data_end
|
359
358
|
next if this_seg.range == data_range
|
360
359
|
|
data/data/ruby-jss.conf.example
CHANGED
@@ -57,7 +57,7 @@ api_server_port:
|
|
57
57
|
### The SSL version to use for the API connection
|
58
58
|
###
|
59
59
|
### If you leave this blank:
|
60
|
-
### Defaults to '
|
60
|
+
### Defaults to 'TLSv1_2'
|
61
61
|
###
|
62
62
|
api_ssl_version:
|
63
63
|
|
@@ -75,14 +75,8 @@ api_verify_cert:
|
|
75
75
|
### - api_username
|
76
76
|
### The username to use when making an API connection.
|
77
77
|
###
|
78
|
-
### *** REQUIRED ***
|
79
|
-
###
|
80
78
|
### Note that the passwords are not storeable here!!
|
81
|
-
### see https://github.com/PixarAnimationStudios/ruby-jss/blob/master/README.md#
|
82
|
-
###
|
83
|
-
### If you leave this blank:
|
84
|
-
### d3 may break, as well as any other code that
|
85
|
-
### expects a configured api user name
|
79
|
+
### see https://github.com/PixarAnimationStudios/ruby-jss/blob/master/README.md#password
|
86
80
|
###
|
87
81
|
api_username:
|
88
82
|
|
data/lib/jss/api_connection.rb
CHANGED
@@ -336,6 +336,7 @@ module JSS
|
|
336
336
|
|
337
337
|
# @return [Boolean] are we connected right now?
|
338
338
|
attr_reader :connected
|
339
|
+
alias connected? connected
|
339
340
|
|
340
341
|
# @return [JSS::Server] the details of the JSS to which we're connected.
|
341
342
|
attr_reader :server
|
@@ -509,14 +510,19 @@ module JSS
|
|
509
510
|
def get_rsrc(rsrc, format = :json)
|
510
511
|
# puts object_id
|
511
512
|
validate_connected
|
513
|
+
|
512
514
|
raise JSS::InvalidDataError, 'format must be :json or :xml' unless %i[json xml].include? format
|
513
515
|
|
516
|
+
# TODO: fix what rubocop is complaining about in the line below.
|
517
|
+
# (I doubt we want to CGI.escape the whole resource)
|
514
518
|
rsrc = URI.encode rsrc
|
515
519
|
begin
|
516
520
|
@last_http_response = @cnx[rsrc].get(accept: format)
|
517
521
|
rescue RestClient::ExceptionWithResponse => e
|
518
522
|
handle_http_error e
|
519
523
|
end
|
524
|
+
# TODO: make sure we're returning the String version of the
|
525
|
+
# response (i.e. its body) here and in POST, PUT, DELETE.
|
520
526
|
format == :json ? JSON.parse(@last_http_response, symbolize_names: true) : @last_http_response
|
521
527
|
end
|
522
528
|
|
@@ -625,9 +631,6 @@ module JSS
|
|
625
631
|
srvr ||= JSS::Client.jss_server
|
626
632
|
srvr
|
627
633
|
end
|
628
|
-
|
629
|
-
# aliases
|
630
|
-
alias connected? connected
|
631
634
|
alias host hostname
|
632
635
|
|
633
636
|
#################
|
@@ -210,7 +210,7 @@ module JSS
|
|
210
210
|
@api.timeout = 1800
|
211
211
|
@api.open_timeout = 1800
|
212
212
|
begin
|
213
|
-
requery = self.class.
|
213
|
+
requery = self.class.fetch(id: @id)
|
214
214
|
@search_results = requery.search_results
|
215
215
|
@result_display_keys = requery.result_display_keys
|
216
216
|
ensure
|
@@ -172,7 +172,7 @@ module JSS
|
|
172
172
|
def create
|
173
173
|
new_invitation_id = super
|
174
174
|
|
175
|
-
jss_me = ComputerInvitation.
|
175
|
+
jss_me = ComputerInvitation.fetch(id: new_invitation_id, name: 'set_by_request')
|
176
176
|
@name = jss_me.name
|
177
177
|
@invitation_type = jss_me.invitation_type
|
178
178
|
@create_account_if_does_not_exist = jss_me.create_account_if_does_not_exist
|
@@ -81,7 +81,7 @@ module JSS
|
|
81
81
|
### crta = JSS::Criteriable::Criteria.new [crtn_0, crtn_1]
|
82
82
|
###
|
83
83
|
### # create a new Advanced Search
|
84
|
-
### srch = JSS::AdvancedComputerSearch.
|
84
|
+
### srch = JSS::AdvancedComputerSearch.make, :name => "my computer search"
|
85
85
|
### srch.display_fields = ["Computer Name"]
|
86
86
|
###
|
87
87
|
### # add our Criteria to it
|
data/lib/jss/api_object/ebook.rb
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
### Copyright 2018 Pixar
|
2
|
+
|
3
|
+
###
|
4
|
+
### Licensed under the Apache License, Version 2.0 (the "Apache License")
|
5
|
+
### with the following modification; you may not use this file except in
|
6
|
+
### compliance with the Apache License and the following modification to it:
|
7
|
+
### Section 6. Trademarks. is deleted and replaced with:
|
8
|
+
###
|
9
|
+
### 6. Trademarks. This License does not grant permission to use the trade
|
10
|
+
### names, trademarks, service marks, or product names of the Licensor
|
11
|
+
### and its affiliates, except as required to comply with Section 4(c) of
|
12
|
+
### the License and to reproduce the content of the NOTICE file.
|
13
|
+
###
|
14
|
+
### You may obtain a copy of the Apache License at
|
15
|
+
###
|
16
|
+
### http://www.apache.org/licenses/LICENSE-2.0
|
17
|
+
###
|
18
|
+
### Unless required by applicable law or agreed to in writing, software
|
19
|
+
### distributed under the Apache License with the above modification is
|
20
|
+
### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
21
|
+
### KIND, either express or implied. See the Apache License for the specific
|
22
|
+
### language governing permissions and limitations under the Apache License.
|
23
|
+
###
|
24
|
+
###
|
25
|
+
|
1
26
|
# This is just a stub for now.
|
2
27
|
|
3
28
|
#
|
data/lib/jss/api_object/group.rb
CHANGED
@@ -106,7 +106,7 @@ module JSS
|
|
106
106
|
# Constructor
|
107
107
|
#####################################
|
108
108
|
|
109
|
-
# When creating a new group in the JSS, you must call .
|
109
|
+
# When creating a new group in the JSS, you must call .make with a :type key
|
110
110
|
# and a value of :smart or :static, as well as a :name and the :id => :new
|
111
111
|
#
|
112
112
|
# @see JSS::APIObject
|
@@ -36,8 +36,20 @@ module JSS
|
|
36
36
|
# attribute, a Hash of versions keyed by the version string. The values are
|
37
37
|
# JSS::PatchTitle::Version objects.
|
38
38
|
#
|
39
|
-
#
|
40
|
-
# a
|
39
|
+
# When creating/activating new Patch Titles, with .make, a unique name:, a
|
40
|
+
# source: and a name_id: must be provided - the source must be the name or id
|
41
|
+
# of an existing PatchSource, and the name_id must be offered by that source.
|
42
|
+
# Once created, the source_id and name_id cannot be changed.
|
43
|
+
#
|
44
|
+
# When fetching titles, they can be fetched by id:, source_name_id:, or both
|
45
|
+
# source: and name_id:
|
46
|
+
#
|
47
|
+
# WARNING: While they can be fetched by name, beware: the JSS does not enforce
|
48
|
+
# unique names of titles even thought ruby-jss does. If there are duplicates
|
49
|
+
# of the name you fetch, which one you get is undefined.
|
50
|
+
#
|
51
|
+
# Use the patch_report class or instance method, or
|
52
|
+
# PatchTitle::Version.patch_report, to retrieve a report of computers with a
|
41
53
|
# specific version of the title installed, or :all, :latest, or :unknown
|
42
54
|
# versions. Reports called on the class or an instance default to :all
|
43
55
|
# versions, and are slower to retrieve than a specific version,
|
@@ -152,7 +164,10 @@ module JSS
|
|
152
164
|
# source_id: parameter, which limites the results to
|
153
165
|
# patch titles with the specified source_id.
|
154
166
|
#
|
155
|
-
#
|
167
|
+
# Also - since the combined source_id and name_id are unique, create an
|
168
|
+
# identifier key ':source_name_id' by joining them with '-'
|
169
|
+
#
|
170
|
+
# JAMF BUG: More broken json - the id is coming as a string.
|
156
171
|
# so here we turn it into an integer manually :-(
|
157
172
|
# Ditto for source_id
|
158
173
|
#
|
@@ -160,6 +175,7 @@ module JSS
|
|
160
175
|
data = super refresh, api: api
|
161
176
|
data.each do |info|
|
162
177
|
info[:id] = info[:id].to_i
|
178
|
+
info[:source_name_id] = "#{info[:source_id]}-#{info[:name_id]}"
|
163
179
|
info[:source_id] = info[:source_id].to_i
|
164
180
|
end
|
165
181
|
return data unless source_id
|
@@ -182,12 +198,6 @@ module JSS
|
|
182
198
|
all(refresh, source_id: source_id, api: api).map { |i| i[:id] }
|
183
199
|
end
|
184
200
|
|
185
|
-
# @return [Array<String>] all 'name_id' values for active patches
|
186
|
-
#
|
187
|
-
def self.all_name_ids(refresh = false, source_id: nil, api: JSS.api)
|
188
|
-
all(refresh, source_id: source_id, api: api).map { |i| i[:name_id] }
|
189
|
-
end
|
190
|
-
|
191
201
|
# Returns an Array of unique source_ids used by active Patches
|
192
202
|
#
|
193
203
|
# e.g. if there are patches that come from one internal source
|
@@ -207,6 +217,12 @@ module JSS
|
|
207
217
|
all(refresh, api: api).map { |i| i[:source_id] }.sort.uniq
|
208
218
|
end
|
209
219
|
|
220
|
+
# @return [Array<String>] all 'source_name_id' values for active patches
|
221
|
+
#
|
222
|
+
def self.all_source_name_ids(refresh = false, api: JSS.api)
|
223
|
+
all(refresh, api: api).map { |i| i[:source_name_id] }
|
224
|
+
end
|
225
|
+
|
210
226
|
# Get a patch report for a softwaretitle, withouth fetching an instance.
|
211
227
|
# Defaults to reporting all versions. Specifiying a version will be faster.
|
212
228
|
#
|
@@ -280,18 +296,50 @@ module JSS
|
|
280
296
|
end
|
281
297
|
private_class_method :patch_report_rsrc
|
282
298
|
|
283
|
-
#
|
284
|
-
#
|
299
|
+
# Patch titles only have an id-based GET resource in the API.
|
300
|
+
# so all other lookup values have to be converted to ID before
|
301
|
+
# the call to super
|
285
302
|
#
|
286
|
-
def self.fetch(
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
303
|
+
def self.fetch(identifier = nil, **params)
|
304
|
+
# default api
|
305
|
+
api = params[:api] ? params[:api] : JSS.api
|
306
|
+
|
307
|
+
# source: and source_id: are considered the same, source_id: wins
|
308
|
+
params[:source_id] ||= params[:source]
|
309
|
+
|
310
|
+
# if given a source name, this converts it to an id
|
311
|
+
params[:source_id] = JSS::PatchSource.valid_id params[:source_id]
|
312
|
+
|
313
|
+
# build a possible source_name_id
|
314
|
+
params[:source_name_id] ||= "#{params[:source_id]}-#{params[:name_id]}"
|
315
|
+
|
316
|
+
id =
|
317
|
+
if identifier
|
318
|
+
valid_id identifier
|
319
|
+
elsif params[:id]
|
320
|
+
all_ids.include?(params[:id]) ? params[:id] : nil
|
321
|
+
elsif params[:source_name_id]
|
322
|
+
map_all_ids_to(:source_name_id).invert[params[:source_name_id]]
|
323
|
+
elsif params[:name]
|
324
|
+
map_all_ids_to(:name).invert[params[:name]]
|
325
|
+
end
|
326
|
+
|
327
|
+
raise JSS::NoSuchItemError, "No matching #{name} found" unless id
|
291
328
|
|
292
329
|
super id: id, api: api
|
293
330
|
end
|
294
331
|
|
332
|
+
# Override the {APIObject.valid_id}, since patch sources are so non-standard
|
333
|
+
# Accept id, source_name_id, or name.
|
334
|
+
# Note name may not be unique, and if not, ymmv
|
335
|
+
#
|
336
|
+
def self.valid_id(ident, refresh = false, api: JSS.api)
|
337
|
+
id = all_ids(refresh, api: api).include?(ident) ? ident : nil
|
338
|
+
id ||= map_all_ids_to(:source_name_id).invert[ident]
|
339
|
+
id ||= map_all_ids_to(:name).invert[ident]
|
340
|
+
id
|
341
|
+
end
|
342
|
+
|
295
343
|
# Attributes
|
296
344
|
#####################################
|
297
345
|
|
@@ -303,6 +351,9 @@ module JSS
|
|
303
351
|
# for this title
|
304
352
|
attr_reader :source_id
|
305
353
|
|
354
|
+
# @return [String] the source_id and name_id joined by '-', a unique identifier
|
355
|
+
attr_reader :source_name_id
|
356
|
+
|
306
357
|
# @return [Boolean] Are new patches announced in the JSS web ui?
|
307
358
|
attr_reader :web_notification
|
308
359
|
alias web_notification? web_notification
|
@@ -311,17 +362,31 @@ module JSS
|
|
311
362
|
attr_reader :email_notification
|
312
363
|
alias email_notification? email_notification
|
313
364
|
|
314
|
-
# @return [Hash{String => JSS::PatchTitle::Version}] The JSS::PatchVersions fetched for
|
315
|
-
# this title, keyed by version string
|
316
|
-
attr_reader :versions
|
317
|
-
|
318
|
-
# PatchTitles may be fetched by name: or id:
|
319
365
|
#
|
320
366
|
def initialize(**args)
|
321
367
|
super
|
322
368
|
|
323
|
-
|
324
|
-
|
369
|
+
if in_jss
|
370
|
+
@name_id = @init_data[:name_id]
|
371
|
+
@source_id = @init_data[:source_id]
|
372
|
+
else
|
373
|
+
# source: and source_id: are considered the same, source_id: wins
|
374
|
+
@init_data[:source_id] ||= @init_data[:source]
|
375
|
+
|
376
|
+
raise JSS::MissingDataError, 'source: and name_id: must be provided' unless @init_data[:name_id] && @init_data[:source_id]
|
377
|
+
|
378
|
+
@source_id = JSS::PatchSource.valid_id(@init_data[:source_id])
|
379
|
+
|
380
|
+
raise JSS::NoSuchItemError, "No Patch Sources match '#{@init_data[:source]}'" unless source_id
|
381
|
+
|
382
|
+
@name_id = @init_data[:name_id]
|
383
|
+
|
384
|
+
valid_name_id = JSS::PatchSource.available_name_ids(@source_id).include? @name_id
|
385
|
+
|
386
|
+
raise JSS::NoSuchItemError, "source #{@init_data[:source]} doesn't offer name_id '#{@init_data[:name_id]}'" unless valid_name_id
|
387
|
+
end
|
388
|
+
|
389
|
+
@source_name_id = "#{@source_id}-#{@name_id}"
|
325
390
|
|
326
391
|
@init_data[:notifications] ||= {}
|
327
392
|
notifs = @init_data[:notifications]
|
@@ -337,6 +402,16 @@ module JSS
|
|
337
402
|
@changed_pkgs = []
|
338
403
|
end
|
339
404
|
|
405
|
+
# @return [Hash{String => JSS::PatchTitle::Version}] The JSS::PatchVersions fetched for
|
406
|
+
# this title, keyed by version string
|
407
|
+
def versions
|
408
|
+
return @versions unless in_jss
|
409
|
+
return @versions unless @versions.empty?
|
410
|
+
# if we are in jss, and versions is empty, re-fetch them
|
411
|
+
@versions = self.class.fetch(id: id).versions
|
412
|
+
end
|
413
|
+
|
414
|
+
|
340
415
|
# @return [Hash] Subset of @versions, containing those which have packages
|
341
416
|
# assigned
|
342
417
|
#
|
@@ -376,33 +451,14 @@ module JSS
|
|
376
451
|
@need_to_update = true
|
377
452
|
end
|
378
453
|
|
379
|
-
def source_id=(new_id)
|
380
|
-
sid = JSS::PatchSource.valid_patch_source_id new_id
|
381
|
-
raise JSS::NoSuchItemError, "No active Patch Sources matche '#{new_id}'" unless sid
|
382
|
-
return if sid == source_id
|
383
|
-
@source_id = sid
|
384
|
-
@need_to_update = true
|
385
|
-
end
|
386
|
-
|
387
|
-
def name_id=(new_id)
|
388
|
-
return if new_id == name_id
|
389
|
-
raise JSS::MissingDataError, 'source_id must be set before setting name_id' if source_id.to_s.empty?
|
390
|
-
raise JSS::NoSuchItemError, "source_id #{source_id} doesn't offer name_id '#{new_id}'" unless JSS::PatchSource.available_name_ids(source_id).include? new_id
|
391
|
-
@name_id = new_id
|
392
|
-
@need_to_update = true
|
393
|
-
end
|
394
|
-
|
395
454
|
# wrapper to fetch versions after creating
|
396
455
|
def create
|
397
|
-
validate_for_saving
|
398
456
|
response = super
|
399
|
-
@versions = self.class.fetch(id: id).versions
|
400
457
|
response
|
401
458
|
end
|
402
459
|
|
403
460
|
# wrapper to clear @changed_pkgs after updating
|
404
461
|
def update
|
405
|
-
validate_for_saving
|
406
462
|
response = super
|
407
463
|
@changed_pkgs.clear
|
408
464
|
response
|
@@ -433,10 +489,6 @@ module JSS
|
|
433
489
|
#################################
|
434
490
|
private
|
435
491
|
|
436
|
-
def validate_for_saving
|
437
|
-
raise JSS::MissingDataError, 'PatchTitles must have valid source_id and name_id' if source_id.to_s.empty? || name_id.to_s.empty?
|
438
|
-
end
|
439
|
-
|
440
492
|
# Return the REST XML for this title, with the current values,
|
441
493
|
# for saving or updating.
|
442
494
|
#
|