jss-api 0.5.8 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES.md +55 -7
- data/README.md +2 -1
- data/bin/cgrouper +1 -1
- data/bin/subnet-update +1 -1
- data/lib/jss-api.rb +2 -363
- data/lib/jss-api/api_connection.rb +78 -15
- data/lib/jss-api/api_object.rb +1 -1
- data/lib/jss-api/api_object/advanced_search.rb +1 -1
- data/lib/jss-api/api_object/advanced_search/advanced_computer_search.rb +1 -1
- data/lib/jss-api/api_object/advanced_search/advanced_mobile_device_search.rb +1 -1
- data/lib/jss-api/api_object/advanced_search/advanced_user_search.rb +1 -1
- data/lib/jss-api/api_object/building.rb +1 -1
- data/lib/jss-api/api_object/category.rb +1 -1
- data/lib/jss-api/api_object/computer.rb +1 -1
- data/lib/jss-api/api_object/creatable.rb +1 -1
- data/lib/jss-api/api_object/criteriable.rb +1 -1
- data/lib/jss-api/api_object/criteriable/criteria.rb +1 -1
- data/lib/jss-api/api_object/criteriable/criterion.rb +1 -1
- data/lib/jss-api/api_object/department.rb +1 -1
- data/lib/jss-api/api_object/distribution_point.rb +92 -22
- data/lib/jss-api/api_object/extendable.rb +1 -1
- data/lib/jss-api/api_object/extension_attribute.rb +1 -1
- data/lib/jss-api/api_object/extension_attribute/computer_extension_attribute.rb +1 -1
- data/lib/jss-api/api_object/extension_attribute/mobile_device_extension_attribute.rb +1 -1
- data/lib/jss-api/api_object/extension_attribute/user_extension_attribute.rb +1 -1
- data/lib/jss-api/api_object/group.rb +1 -1
- data/lib/jss-api/api_object/group/computer_group.rb +1 -1
- data/lib/jss-api/api_object/group/mobile_device_group.rb +1 -1
- data/lib/jss-api/api_object/group/user_group.rb +1 -1
- data/lib/jss-api/api_object/ldap_server.rb +1 -1
- data/lib/jss-api/api_object/locatable.rb +1 -1
- data/lib/jss-api/api_object/matchable.rb +1 -1
- data/lib/jss-api/api_object/mobile_device.rb +1 -1
- data/lib/jss-api/api_object/netboot_server.rb +1 -1
- data/lib/jss-api/api_object/network_segment.rb +1 -1
- data/lib/jss-api/api_object/osx_configuration_profile.rb +1 -1
- data/lib/jss-api/api_object/package.rb +117 -64
- data/lib/jss-api/api_object/peripheral.rb +1 -1
- data/lib/jss-api/api_object/peripheral_type.rb +1 -1
- data/lib/jss-api/api_object/policy.rb +1 -1
- data/lib/jss-api/api_object/purchasable.rb +1 -1
- data/lib/jss-api/api_object/removable_macaddr.rb +1 -1
- data/lib/jss-api/api_object/scopable.rb +1 -1
- data/lib/jss-api/api_object/scopable/scope.rb +1 -1
- data/lib/jss-api/api_object/script.rb +1 -1
- data/lib/jss-api/api_object/self_servable.rb +1 -1
- data/lib/jss-api/api_object/site.rb +1 -1
- data/lib/jss-api/api_object/software_update_server.rb +1 -1
- data/lib/jss-api/api_object/updatable.rb +1 -1
- data/lib/jss-api/api_object/uploadable.rb +1 -1
- data/lib/jss-api/api_object/user.rb +1 -1
- data/lib/jss-api/client.rb +22 -21
- data/lib/jss-api/compatibility.rb +1 -1
- data/lib/jss-api/composer.rb +2 -2
- data/lib/jss-api/configuration.rb +1 -1
- data/lib/jss-api/db_connection.rb +63 -12
- data/lib/jss-api/exceptions.rb +1 -1
- data/lib/jss-api/ruby_extensions.rb +1 -1
- data/lib/jss-api/ruby_extensions/filetest.rb +1 -1
- data/lib/jss-api/ruby_extensions/hash.rb +1 -1
- data/lib/jss-api/ruby_extensions/ipaddr.rb +1 -1
- data/lib/jss-api/ruby_extensions/pathname.rb +1 -1
- data/lib/jss-api/ruby_extensions/string.rb +17 -1
- data/lib/jss-api/ruby_extensions/time.rb +1 -1
- data/lib/jss-api/server.rb +1 -1
- data/lib/jss-api/utility.rb +416 -0
- data/lib/jss-api/version.rb +8 -8
- metadata +3 -2
@@ -1,25 +1,25 @@
|
|
1
|
-
### Copyright
|
2
|
-
###
|
1
|
+
### Copyright 2016 Pixar
|
2
|
+
###
|
3
3
|
### Licensed under the Apache License, Version 2.0 (the "Apache License")
|
4
4
|
### with the following modification; you may not use this file except in
|
5
5
|
### compliance with the Apache License and the following modification to it:
|
6
6
|
### Section 6. Trademarks. is deleted and replaced with:
|
7
|
-
###
|
7
|
+
###
|
8
8
|
### 6. Trademarks. This License does not grant permission to use the trade
|
9
9
|
### names, trademarks, service marks, or product names of the Licensor
|
10
10
|
### and its affiliates, except as required to comply with Section 4(c) of
|
11
11
|
### the License and to reproduce the content of the NOTICE file.
|
12
|
-
###
|
12
|
+
###
|
13
13
|
### You may obtain a copy of the Apache License at
|
14
|
-
###
|
14
|
+
###
|
15
15
|
### http://www.apache.org/licenses/LICENSE-2.0
|
16
|
-
###
|
16
|
+
###
|
17
17
|
### Unless required by applicable law or agreed to in writing, software
|
18
18
|
### distributed under the Apache License with the above modification is
|
19
19
|
### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
20
20
|
### KIND, either express or implied. See the Apache License for the specific
|
21
21
|
### language governing permissions and limitations under the Apache License.
|
22
|
-
###
|
22
|
+
###
|
23
23
|
###
|
24
24
|
|
25
25
|
###
|
@@ -86,6 +86,8 @@ module JSS
|
|
86
86
|
### The possible values for cpu_type (required_processor) in a JSS package
|
87
87
|
CPU_TYPES = ["None", "x86", "ppc"]
|
88
88
|
|
89
|
+
# TO DO - this is redundant with DEFAULT_PROCESSOR, but both are in use
|
90
|
+
# clean them up!
|
89
91
|
### which is default? there must be one to make a new pkg
|
90
92
|
DEFAULT_CPU_TYPE = "None"
|
91
93
|
|
@@ -115,10 +117,10 @@ module JSS
|
|
115
117
|
|
116
118
|
### @return [String] the filename of the .pkg, .mpkg, or .dmg on the Casper server
|
117
119
|
attr_reader :filename
|
118
|
-
|
119
|
-
### @return [Pathname] the local receipt when this pkg is installed
|
120
|
+
|
121
|
+
### @return [Pathname] the local receipt when this pkg is installed
|
120
122
|
attr_reader :receipt
|
121
|
-
|
123
|
+
|
122
124
|
### @return [Boolean] does this item 'Fill Existing Users' when jamf installs it?
|
123
125
|
attr_reader :fill_existing_users
|
124
126
|
|
@@ -130,16 +132,16 @@ module JSS
|
|
130
132
|
|
131
133
|
### @return [Array<String>] the OS versions this can be installed onto. For all minor versions, the format is 10.5.x
|
132
134
|
attr_reader :os_requirements
|
133
|
-
|
135
|
+
|
134
136
|
### @return [String] limit installation to these architectures: 'x86', 'ppc', 'None'
|
135
137
|
attr_reader :required_processor
|
136
|
-
|
138
|
+
|
137
139
|
### @return [String] the name of a pkg to install (or "Do Not Install") when this pkg can't be installed
|
138
140
|
attr_reader :switch_with_package
|
139
141
|
|
140
142
|
### @return [Boolean] can this item be uninstalled? Some, e.g. OS Updates, can't
|
141
143
|
attr_reader :allow_uninstalled
|
142
|
-
|
144
|
+
|
143
145
|
### @return [String] the category of this pkg, stored in the JSS as the id number from the categories table
|
144
146
|
attr_reader :category
|
145
147
|
|
@@ -151,16 +153,16 @@ module JSS
|
|
151
153
|
|
152
154
|
### @return [Boolean] only install this pkg if it's available in the commandline softwareupdate.
|
153
155
|
attr_reader :install_if_reported_available
|
154
|
-
|
156
|
+
|
155
157
|
### @return [Boolean] should this pkg be installed on the boot volume during imaging
|
156
158
|
attr_reader :boot_volume_required
|
157
|
-
|
159
|
+
|
158
160
|
### @return [Integer] Priority to use for deploying or uninstalling the package
|
159
161
|
attr_reader :priority
|
160
162
|
|
161
163
|
### @return [Boolean] does this pkg cause a notification to be sent on self-heal?
|
162
164
|
attr_reader :send_notification
|
163
|
-
|
165
|
+
|
164
166
|
|
165
167
|
###
|
166
168
|
### @see JSS::APIObject#initialize
|
@@ -173,6 +175,7 @@ module JSS
|
|
173
175
|
@allow_uninstalled = @init_data[:allow_uninstalled]
|
174
176
|
@boot_volume_required = @init_data[:boot_volume_required]
|
175
177
|
@category = JSS::APIObject.get_name(@init_data[:category])
|
178
|
+
@category = nil if @category.to_s.casecmp("No category assigned") == 0
|
176
179
|
@filename = @init_data[:filename] || @init_data[:name]
|
177
180
|
@fill_existing_users = @init_data[:fill_existing_users]
|
178
181
|
@fill_user_template = @init_data[:fill_user_template]
|
@@ -185,12 +188,12 @@ module JSS
|
|
185
188
|
@priority = @init_data[:priority] || DEFAULT_PRIORITY
|
186
189
|
@reboot_required = @init_data[:reboot_required]
|
187
190
|
@required_processor = @init_data[:required_processor] || DEFAULT_CPU_TYPE
|
191
|
+
@required_processor = nil if @required_processor.to_s.casecmp('none') == 0
|
188
192
|
@send_notification = @init_data[:send_notification]
|
189
193
|
@switch_with_package = @init_data[:switch_with_package] || DO_NOT_INSTALL
|
190
|
-
|
194
|
+
|
191
195
|
# the receipt is the filename with any .zip extension removed.
|
192
|
-
@receipt = @
|
193
|
-
|
196
|
+
@receipt = @filename ? (JSS::Client::RECEIPTS_FOLDER + @filename.to_s.sub(/.zip$/, '')) : nil
|
194
197
|
end # init
|
195
198
|
|
196
199
|
|
@@ -478,7 +481,7 @@ module JSS
|
|
478
481
|
def installed?
|
479
482
|
@receipt.file?
|
480
483
|
end
|
481
|
-
|
484
|
+
|
482
485
|
###
|
483
486
|
### Upload a locally-readable file to the master distribution point.
|
484
487
|
### If the file is a directory (like a bundle .pk/.mpkg) it will be zipped before
|
@@ -489,7 +492,7 @@ module JSS
|
|
489
492
|
###
|
490
493
|
### @param local_file_path[String,Pathname] the local path to the file to be uploaded
|
491
494
|
###
|
492
|
-
### @param rw_pw[String,Symbol] the password for the read/write account on the master Distribution Point,
|
495
|
+
### @param rw_pw[String,Symbol] the password for the read/write account on the master Distribution Point,
|
493
496
|
### or :prompt, or :stdin# where # is the line of stdin containing the password See {JSS::DistributionPoint#mount}
|
494
497
|
###
|
495
498
|
### @param unmount[Boolean] whether or not ot unount the distribution point when finished.
|
@@ -499,7 +502,7 @@ module JSS
|
|
499
502
|
def upload_master_file (local_file_path, rw_pw, unmount = true)
|
500
503
|
|
501
504
|
raise JSS::NoSuchItemError, "Please create this package in the JSS before uploading it." unless @in_jss
|
502
|
-
|
505
|
+
|
503
506
|
mdp = JSS::DistributionPoint.master_distribution_point
|
504
507
|
destination = mdp.mount(rw_pw, :rw) +"#{DIST_POINT_PKGS_FOLDER}/#{@filename}"
|
505
508
|
|
@@ -534,11 +537,11 @@ module JSS
|
|
534
537
|
local_path = zipfile
|
535
538
|
|
536
539
|
self.filename = zipfile.basename.to_s
|
537
|
-
|
540
|
+
|
538
541
|
end # if directory
|
539
542
|
self.update
|
540
543
|
FileUtils.copy_entry local_path, destination
|
541
|
-
|
544
|
+
|
542
545
|
mdp.unmount if unmount
|
543
546
|
end # upload
|
544
547
|
|
@@ -569,21 +572,23 @@ module JSS
|
|
569
572
|
end # delete master file
|
570
573
|
|
571
574
|
|
575
|
+
### Install this package via the jamf binary 'install' command from the
|
576
|
+
### distribution point for this machine.
|
577
|
+
### See {JSS::DistributionPoint.my_distribution_point}
|
572
578
|
###
|
573
579
|
### @note This code must be run as root to install packages
|
574
580
|
###
|
575
|
-
###
|
576
|
-
###
|
577
|
-
###
|
578
|
-
### The read-only or http passwd for the dist. point must be provided, except for
|
579
|
-
### non-authenticated http downloads)
|
581
|
+
### The read-only or http passwd for the dist. point must be provided,
|
582
|
+
### except for non-authenticated http downloads)
|
580
583
|
###
|
581
584
|
### @param args[Hash] the arguments for installation
|
582
585
|
###
|
583
|
-
### @option args :ro_pw[String] the read-only or http password for the
|
584
|
-
###
|
586
|
+
### @option args :ro_pw[String] the read-only or http password for the
|
587
|
+
### distribution point for the local machine
|
588
|
+
### (http will be used if available, and may not need a pw)
|
585
589
|
###
|
586
|
-
### @option args :target[String,Pathname] The drive on which to install
|
590
|
+
### @option args :target[String,Pathname] The drive on which to install
|
591
|
+
### the package, defaults to '/'
|
587
592
|
###
|
588
593
|
### @option args :verbose [Boolean] be verbose to stdout, defaults to false
|
589
594
|
###
|
@@ -591,14 +596,21 @@ module JSS
|
|
591
596
|
###
|
592
597
|
### @option args :fut[Boolean] fill user template, defaults to false
|
593
598
|
###
|
594
|
-
### @option args :unmount[Boolean] unmount the distribution point when
|
595
|
-
### defaults to false
|
599
|
+
### @option args :unmount[Boolean] unmount the distribution point when
|
600
|
+
### finished?(if we mounted it), defaults to false
|
601
|
+
###
|
602
|
+
### @option args :no_http[Boolean] don't use http downloads even if they
|
603
|
+
### are enabled for the dist. point.
|
596
604
|
###
|
597
|
-
### @option args :
|
605
|
+
### @option args :alt_download_url [String] Use this url for an http
|
606
|
+
### download, regardless of distribution point settings. This can be used
|
607
|
+
### to access Cloud Distribution Points if the fileshare isn't available.
|
608
|
+
### The URL should already be ur
|
609
|
+
### The package filename will be removed or appended as needed.
|
598
610
|
###
|
599
|
-
### @return [
|
611
|
+
### @return [Boolean] did the jamf install succeed?
|
600
612
|
###
|
601
|
-
### @todo deal with cert-based https authentication
|
613
|
+
### @todo deal with cert-based https authentication in dist points
|
602
614
|
###
|
603
615
|
def install (args = {})
|
604
616
|
|
@@ -608,46 +620,73 @@ module JSS
|
|
608
620
|
|
609
621
|
ro_pw = args[:ro_pw]
|
610
622
|
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
+
# as of Casper 9.72, with http downloads, the jamf binary requires
|
624
|
+
# the filename must be at the end of the -path url, but before 9.72
|
625
|
+
# it can't be.
|
626
|
+
# e.g.
|
627
|
+
# in <9.72: jamf install -package foo.pkg -path http://mycasper.myorg.edu/CasperShare/Packages
|
628
|
+
# but
|
629
|
+
# in >=9.72: jamf install -package foo.pkg -path http://mycasper.myorg.edu/CasperShare/Packages/foo.pkg
|
630
|
+
#
|
631
|
+
append_at_vers = JSS.parse_jss_version("9.72")[:version]
|
632
|
+
our_vers = JSS.parse_jss_version(JSS::API.server.raw_version)[:version]
|
633
|
+
no_filename_in_url = (our_vers < append_at_vers)
|
634
|
+
|
635
|
+
# use a provided alternative url for an http download
|
636
|
+
if args[:alt_download_url]
|
637
|
+
|
638
|
+
# we'll re-add the filename below if needed.
|
639
|
+
src_path = args[:alt_download_url].chomp "/#{@filename}"
|
640
|
+
|
641
|
+
# use our appropriate dist. point for download
|
642
|
+
else
|
643
|
+
mdp = JSS::DistributionPoint.my_distribution_point
|
644
|
+
|
645
|
+
### how do we access our dist. point? with http?
|
646
|
+
if mdp.http_downloads_enabled and (not args[:no_http])
|
647
|
+
using_http = true
|
648
|
+
src_path = mdp.http_url
|
649
|
+
if mdp.username_password_required
|
650
|
+
raise JSS::MissingDataError, "No password provided for http download" unless ro_pw
|
651
|
+
raise JSS::InvaldDatatError, "Incorrect password for http access to distribution point." unless mdp.check_pw(:http, ro_pw)
|
652
|
+
# insert the name and pw into the uri
|
653
|
+
reserved_chars = Regexp.new("[^#{URI::REGEXP::PATTERN::UNRESERVED}]") # we'll escape all the chars that aren't unreserved
|
654
|
+
src_path = src_path.sub(%r{(https?://)(\S)}, "#{$1}#{URI.escape mdp.http_username,reserved_chars}:#{URI.escape ro_pw, reserved_chars}@#{$2}")
|
655
|
+
end
|
656
|
+
|
657
|
+
# or with filesharing?
|
658
|
+
else
|
659
|
+
using_http = false
|
660
|
+
src_path = mdp.mount(ro_pw)
|
623
661
|
end
|
624
662
|
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
663
|
+
# look at the pkgs folder
|
664
|
+
src_path += "#{DIST_POINT_PKGS_FOLDER}"
|
665
|
+
end # if args[:alt_download_url]
|
666
|
+
|
667
|
+
src_path += "/#{@filename}" unless no_filename_in_url
|
630
668
|
|
631
|
-
# look at the pkgs folder
|
632
|
-
src_path += "/#{DIST_POINT_PKGS_FOLDER}"
|
633
669
|
|
634
670
|
### are we doing "fill existing users" or "fill user template"?
|
635
671
|
do_feu = args[:feu] ? "-feu" : ""
|
636
672
|
do_fut = args[:fut] ? "-fut" : ""
|
637
673
|
|
638
674
|
### the install args for jamf
|
639
|
-
command_args = "-package '#{@filename}' -path '#{src_path}' -target '#{args[:target]}' #{do_feu} #{do_fut} -showProgress -verbose
|
675
|
+
command_args = "-package '#{@filename}' -path '#{src_path}' -target '#{args[:target]}' #{do_feu} #{do_fut} -showProgress -verbose"
|
640
676
|
|
641
|
-
### run it via a client
|
677
|
+
### run it via a client cmd
|
642
678
|
install_out = JSS::Client.run_jamf :install, command_args, args[:verbose]
|
643
679
|
|
644
|
-
|
680
|
+
install_out =~ %r{<exitCode>(\d+)</exitCode>}
|
681
|
+
install_exit = $1 ? $1.to_i : nil
|
682
|
+
install_exit ||= $?.exitstatus
|
683
|
+
|
645
684
|
|
646
685
|
if (args.include? :unmount)
|
647
686
|
mdp.unmount unless using_http
|
648
687
|
end
|
649
688
|
|
650
|
-
return install_exit
|
689
|
+
return install_exit == 0 ? true : false
|
651
690
|
end
|
652
691
|
|
653
692
|
###
|
@@ -668,7 +707,7 @@ module JSS
|
|
668
707
|
### @return [Process::Status] the result of the 'jamf uninstall' command
|
669
708
|
###
|
670
709
|
def uninstall (args = {})
|
671
|
-
|
710
|
+
|
672
711
|
raise JSS::UnsupportedError, \
|
673
712
|
"This package cannot be uninstalled. Please use CasperAdmin to index it and allow uninstalls" unless removable?
|
674
713
|
raise JSS::UnsupportedError, "You must have root privileges to uninstall packages" unless JSS.superuser?
|
@@ -689,6 +728,18 @@ module JSS
|
|
689
728
|
|
690
729
|
|
691
730
|
|
731
|
+
### What type of package is this?
|
732
|
+
###
|
733
|
+
### @return [Symbol] :pkg or :dmg or:unknown
|
734
|
+
###
|
735
|
+
def type
|
736
|
+
case @filename
|
737
|
+
when /\.m?pkg(\.zip)?$/ then :pkg
|
738
|
+
when /\.dmg$/ then :dmg
|
739
|
+
else :unknown
|
740
|
+
end
|
741
|
+
end
|
742
|
+
|
692
743
|
|
693
744
|
################################
|
694
745
|
### Private Instance Methods
|
@@ -706,7 +757,7 @@ module JSS
|
|
706
757
|
pkg = doc.add_element "package"
|
707
758
|
pkg.add_element('allow_uninstalled').text = @allow_uninstalled
|
708
759
|
pkg.add_element('boot_volume_required').text = @boot_volume_required
|
709
|
-
pkg.add_element('category').text = @category
|
760
|
+
pkg.add_element('category').text = @category.to_s.casecmp("No category assigned") == 0 ? "" : @category
|
710
761
|
pkg.add_element('filename').text = @filename
|
711
762
|
pkg.add_element('fill_existing_users').text = @fill_existing_users
|
712
763
|
pkg.add_element('fill_user_template').text = @fill_user_template
|
@@ -717,7 +768,7 @@ module JSS
|
|
717
768
|
pkg.add_element('os_requirements').text = JSS.to_s_and_a(@os_requirements)[:stringform]
|
718
769
|
pkg.add_element('priority').text = @priority
|
719
770
|
pkg.add_element('reboot_required').text = @reboot_required
|
720
|
-
pkg.add_element('required_processor').text = @required_processor
|
771
|
+
pkg.add_element('required_processor').text = @required_processor.to_s.empty? ? "None" : @required_processor
|
721
772
|
pkg.add_element('send_notification').text = @send_notification
|
722
773
|
pkg.add_element('switch_with_package').text = @switch_with_package
|
723
774
|
return doc.to_s
|
@@ -741,7 +792,7 @@ module JSS
|
|
741
792
|
alias boot boot_volume_required
|
742
793
|
alias boot? boot_volume_required
|
743
794
|
alias notify send_notification
|
744
|
-
|
795
|
+
|
745
796
|
alias removable= allow_uninstalled=
|
746
797
|
alias boot= boot_volume_required=
|
747
798
|
alias feu= fill_existing_users=
|
@@ -754,6 +805,8 @@ module JSS
|
|
754
805
|
|
755
806
|
|
756
807
|
|
808
|
+
|
809
|
+
|
757
810
|
end # class Package
|
758
811
|
|
759
812
|
end # module jss
|