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.

@@ -52,6 +52,10 @@ module JSS
52
52
  # Class Methods
53
53
  #####################################
54
54
 
55
+ def self.all_bundle_ids(refresh = false)
56
+ all(refresh).map { |mda| mda[:bundle_id] }
57
+ end
58
+
55
59
  # Class Constants
56
60
  #####################################
57
61
 
@@ -78,6 +82,12 @@ module JSS
78
82
  attachment: :mobiledeviceapplications
79
83
  }.freeze
80
84
 
85
+ # see JSS::APIObject
86
+ OTHER_LOOKUP_KEYS = {
87
+ bundleid: {rsrc_id: :bundleid, list: :all_bundle_ids},
88
+ bundle_id: {rsrc_id: :bundleid, list: :all_bundle_ids}
89
+ }.freeze
90
+
81
91
  # Attributes
82
92
  #####################################
83
93
 
@@ -412,7 +422,7 @@ module JSS
412
422
  #
413
423
  def refresh_ipa
414
424
  return nil unless @in_jss
415
- fresh_data = JSS::API.get_rsrc(@rest_rsrc)[self.class::RSRC_OBJECT_KEY]
425
+ fresh_data = JSS.api_connection.get_rsrc(@rest_rsrc)[self.class::RSRC_OBJECT_KEY]
416
426
  @ipa = fresh_data[:general][:ipa]
417
427
  end
418
428
 
@@ -631,7 +631,7 @@ module JSS
631
631
  # in >=9.72: jamf install -package foo.pkg -path http://mycasper.myorg.edu/CasperShare/Packages/foo.pkg
632
632
  #
633
633
  append_at_vers = JSS.parse_jss_version('9.72')[:version]
634
- our_vers = JSS.parse_jss_version(JSS::API.server.raw_version)[:version]
634
+ our_vers = JSS.parse_jss_version(JSS.api_connection.server.raw_version)[:version]
635
635
  no_filename_in_url = (our_vers < append_at_vers)
636
636
 
637
637
  # use a provided alternative url for an http download
@@ -78,7 +78,6 @@ module JSS
78
78
  include JSS::SelfServable
79
79
  include JSS::Categorizable
80
80
 
81
-
82
81
  #####################################
83
82
  ### Class Methods
84
83
  #####################################
@@ -207,8 +206,44 @@ module JSS
207
206
  custom: :trigger_other
208
207
  }.freeze
209
208
 
209
+ NO_USER_LOGGED_IN = [
210
+ 'Do not restart',
211
+ 'Restart immediately',
212
+ 'Restart if a package or update requires it'
213
+ ].freeze
214
+
215
+ USER_LOGGED_IN = [
216
+ 'Do not restart',
217
+ 'Restart',
218
+ 'Restart if a package or update requires it',
219
+ 'Restart immediately'
220
+ ].freeze
221
+
210
222
  SCOPE_TARGET_KEY = :computers
211
223
 
224
+ # Log Flushing
225
+
226
+ LOG_FLUSH_RSRC = 'logflush'.freeze
227
+
228
+ LOG_FLUSH_INTERVAL_INTEGERS = {
229
+ 0 => 'Zero',
230
+ 1 => 'One',
231
+ 2 => 'Two',
232
+ 3 => 'Three',
233
+ 6 => 'Six'
234
+ }.freeze
235
+
236
+ LOG_FLUSH_INTERVAL_PERIODS = {
237
+ day: 'Day',
238
+ days: 'Day',
239
+ week: 'Week',
240
+ weeks: 'Week',
241
+ month: 'Month',
242
+ months: 'Month',
243
+ year: 'Year',
244
+ years: 'Year'
245
+ }.freeze
246
+
212
247
  ######################
213
248
  ### Attributes
214
249
  ######################
@@ -599,7 +634,6 @@ module JSS
599
634
 
600
635
  @printers = @init_data[:printers]
601
636
 
602
-
603
637
  ### Not in jss yet
604
638
  end
605
639
 
@@ -713,6 +747,136 @@ module JSS
713
747
  @need_to_update = true
714
748
  end
715
749
 
750
+ ### Set Server Side Activation
751
+ ###
752
+ ### @param activation[Time] Activation date and time
753
+ ###
754
+ ### @return [void]
755
+ ###
756
+ def server_side_activation=(activation)
757
+ raise JSS::InvalidDataError, 'Activation must be a Time' unless activation.is_a? Time
758
+ @server_side_limitations[:activation] = activation
759
+ @need_to_update = true
760
+ end
761
+
762
+ ### Set Server Side Expiration
763
+ ###
764
+ ### @param expiration[Time] Expiration date and time
765
+ ###
766
+ ### @return [void]
767
+ ###
768
+ def server_side_expiration=(expiration)
769
+ raise JSS::InvalidDataError, 'Expiration must be a Time' unless expiration.is_a? Time
770
+ @server_side_limitations[:expiration] = expiration
771
+ @need_to_update = true
772
+ end
773
+
774
+ ### Reboot Options
775
+ ### Set Reboot Message
776
+ ###
777
+ ### @param reboot_message[String] Text of Reboot Message
778
+ ###
779
+ ### @return [void] description of returned object
780
+ ###
781
+ def message=(reboot_message)
782
+ raise JSS::InvalidDataError, 'Reboot message must be a String' unless reboot_message.is_a? String
783
+ @reboot_options[:message] = reboot_message
784
+ @need_to_update = true
785
+ end
786
+
787
+ ### Reboot Options
788
+ ### Set Startup Disk
789
+ ### Only Supports 'Specify Local Startup Disk' at the moment
790
+ ###
791
+ ### @param startup_disk_option[String]
792
+ ###
793
+ ### @return [void]
794
+ ###
795
+ def startup_disk=(startup_disk_option)
796
+ raise JSS::InvalidDataError, "#{startup_disk_option} is not a valid Startup Disk" unless startup_disk_option.is_a? String
797
+ @reboot_options[:startup_disk] = 'Specify Local Startup Disk'
798
+ self.specify_startup = startup_disk_option
799
+ @need_to_update = true
800
+ end
801
+
802
+ ### Reboot Options
803
+ ### Specify Startup Volume
804
+ ### Only Supports "Specify Local Startup Disk"
805
+ ###
806
+ ### @param startup_volume[String] a Volume to reboot to
807
+ ###
808
+ ### @return [void]
809
+ ###
810
+ def specify_startup=(startup_volume)
811
+ raise JSS::InvalidDataError, "#{startup_volume} is not a valid Startup Disk" unless startup_volume.is_a? String
812
+ @reboot_options[:specify_startup] = startup_volume
813
+ @need_to_update = true
814
+ end
815
+
816
+ ### Reboot Options
817
+ ### No User Logged In
818
+ ###
819
+ ### @param no_user_option[String] Any one of the Strings from NO_USER_LOGGED_IN
820
+ ###
821
+ ### @return [void]
822
+ ###
823
+ def no_user_logged_in=(no_user_option)
824
+ raise JSS::InvalidDataError, "no_user_logged_in options: #{NO_USER_LOGGED_IN.join(', ')}" unless NO_USER_LOGGED_IN.include? no_user_option
825
+ @reboot_options[:no_user_logged_in] = no_user_option
826
+ @need_to_update = true
827
+ end
828
+
829
+ ### Reboot Options
830
+ ### User Logged In
831
+ ###
832
+ ### @param logged_in_option[String] Any one of the Strings from USER_LOGGED_IN
833
+ ###
834
+ ### @return [void]
835
+ ###
836
+ def user_logged_in=(logged_in_option)
837
+ raise JSS::InvalidDataError, "user_logged_in options: #{USER_LOGGED_IN.join(', ')}" unless USER_LOGGED_IN.include? logged_in_option
838
+ @reboot_options[:user_logged_in] = logged_in_option
839
+ @need_to_update = true
840
+ end
841
+
842
+ ### Reboot Options
843
+ ### Do Not Reboot
844
+ ### Shortcut method to suppress Reboot Options
845
+ ###
846
+ ### @return [void]
847
+ ###
848
+ def do_not_reboot
849
+ @reboot_options[:user_logged_in] = 'Do not restart'
850
+ @reboot_options[:no_user_logged_in] = 'Do not restart'
851
+ @need_to_update = true
852
+ end
853
+
854
+ ### Reboot Options
855
+ ### Minutes Until Reboot
856
+ ###
857
+ ### @param minutes[String] The number of minutes to delay prior to reboot
858
+ ###
859
+ ### @return [void]
860
+ ###
861
+ def minutes_until_reboot=(minutes)
862
+ raise JSS::InvalidDataError, 'Minutes until reboot must be an Integer' unless minutes.is_a? Integer
863
+ @reboot_options[:minutes_until_reboot] = minutes
864
+ @need_to_update = true
865
+ end
866
+
867
+ ### Reboot Options
868
+ ### FileVault Authenticated Reboot
869
+ ###
870
+ ### @param fv_bool[Boolean] true or false
871
+ ###
872
+ ### @return [void]
873
+ ###
874
+ def file_vault_2_reboot=(fv_bool)
875
+ raise JSS::InvalidDataError, 'FileVault 2 Reboot must be a Boolean' unless fv_bool.jss_boolean?
876
+ @reboot_options[:file_vault_2_reboot] = fv_bool
877
+ @need_to_update = true
878
+ end
879
+
716
880
  ###### Files & Processes
717
881
 
718
882
  ### @return [String] The unix shell command to run on ths client.
@@ -1103,6 +1267,33 @@ module JSS
1103
1267
  $CHILD_STATUS.exitstatus.zero? ? true : false
1104
1268
  end
1105
1269
 
1270
+ # Flush all policy logs for this policy older than
1271
+ # some number of days, weeks, months or years.
1272
+ #
1273
+ # With no parameters, flushes all logs
1274
+ #
1275
+ # NOTE: Currently the API doesn't have a way to
1276
+ # flush only failed policies.
1277
+ #
1278
+ # @param older_than[Integer] 0, 1, 2, 3, or 6
1279
+ #
1280
+ # @param period[Symbol] :days, :weeks, :months, or :years
1281
+ #
1282
+ # @return [void]
1283
+ #
1284
+ def flush_logs(older_than: 0, period: :days)
1285
+ raise JSS::NoSuchItemError, "Policy doesn't exist in the JSS. Use #create first." \
1286
+ unless @in_jss
1287
+ raise JSS::InvalidDataError, "older_than must be one of: #{LOG_FLUSH_INTERVAL_INTEGERS.keys.join ', '}" \
1288
+ unless LOG_FLUSH_INTERVAL_INTEGERS.keys.include? older_than
1289
+ raise JSS::InvalidDataError, "period must be one of: :#{LOG_FLUSH_INTERVAL_PERIODS.keys.join ', :'}" \
1290
+ unless LOG_FLUSH_INTERVAL_PERIODS.keys.include? period
1291
+
1292
+ interval = "#{LOG_FLUSH_INTERVAL_INTEGERS[older_than]}+#{LOG_FLUSH_INTERVAL_PERIODS[period]}"
1293
+
1294
+ JSS.api_connection.delete_rsrc "#{LOG_FLUSH_RSRC}/policy/id/#{@id}/interval/#{interval}"
1295
+ end
1296
+
1106
1297
  ###### Aliases
1107
1298
 
1108
1299
  alias enabled? enabled
@@ -1130,8 +1321,21 @@ module JSS
1130
1321
 
1131
1322
  JSS.hash_to_rexml_array(@trigger_events).each { |t| general << t }
1132
1323
 
1324
+ date_time_limitations = general.add_element 'date_time_limitations'
1325
+ date_time_limitations.add_element('expiration_date_epoch').text = @server_side_limitations[:expiration].to_jss_epoch if @server_side_limitations[:expiration]
1326
+ date_time_limitations.add_element('activation_date_epoch').text = @server_side_limitations[:activation].to_jss_epoch if @server_side_limitations[:activation]
1327
+
1133
1328
  obj << @scope.scope_xml
1134
1329
 
1330
+ reboot = obj.add_element 'reboot'
1331
+ reboot.add_element('message').text = @reboot_options[:message] if @reboot_options[:message]
1332
+ reboot.add_element('startup_disk').text = @reboot_options[:startup_disk] if @reboot_options[:startup_disk]
1333
+ reboot.add_element('specify_startup').text = @reboot_options[:specify_startup] if @reboot_options[:specify_startup]
1334
+ reboot.add_element('no_user_logged_in').text = @reboot_options[:no_user_logged_in] if @reboot_options[:no_user_logged_in]
1335
+ reboot.add_element('user_logged_in').text = @reboot_options[:user_logged_in] if @reboot_options[:user_logged_in]
1336
+ reboot.add_element('minutes_until_reboot').text = @reboot_options[:minutes_until_reboot] if @reboot_options[:minutes_until_reboot]
1337
+ reboot.add_element('file_vault_2_reboot').text = @reboot_options[:file_vault_2_reboot] if @reboot_options[:file_vault_2_reboot]
1338
+
1135
1339
  files_processes = obj.add_element 'files_processes'
1136
1340
  JSS.hash_to_rexml_array(@files_processes).each { |f| files_processes << f }
1137
1341
 
@@ -1,79 +1,67 @@
1
1
  module JSS
2
- #####################################
3
- ### Classes
4
- #####################################
5
-
6
- ###
7
- ### Restricted Software in the JSS.
8
- ###
9
- ### This class only supports showing of object data.
10
- ###
11
- ### @see JSS::APIObject
12
- ###
2
+
3
+ # Restricted Software items in the JSS.
4
+ #
5
+ # @see JSS::APIObject
6
+ #
13
7
  class RestrictedSoftware < JSS::APIObject
14
8
 
9
+ # Mix-Ins
15
10
  #####################################
16
- ### Mix-Ins
17
- #####################################
18
-
11
+ include JSS::Updatable
12
+ include JSS::Creatable
19
13
  include JSS::Scopable
20
14
 
21
- #####################################
22
- ### Class Constants
15
+ # Class Constants
23
16
  #####################################
24
17
 
25
- ### The base for REST resources of this class
26
- RSRC_BASE = "restrictedsoftware"
18
+ # The base for REST resources of this class
19
+ RSRC_BASE = 'restrictedsoftware'.freeze
27
20
 
28
- ### the hash key used for the JSON list output of all objects in the JSS
21
+ # the hash key used for the JSON list output of all objects in the JSS
29
22
  RSRC_LIST_KEY = :restricted_software
30
23
 
31
- ### The hash key used for the JSON object output.
32
- ### It's also used in various error messages
24
+ # The hash key used for the JSON object output.
25
+ # It's also used in various error messages
33
26
  RSRC_OBJECT_KEY = :restricted_software
34
27
 
35
- ### these keys, as well as :id and :name, are present in valid API JSON data for this class
36
- VALID_DATA_KEYS = [:scope]
28
+ # these keys, as well as :id and :name, are present in valid API JSON data for this class
29
+ VALID_DATA_KEYS = [:scope].freeze
37
30
 
38
- ### Our scopes deal with computers
31
+ # Our scopes deal with computers
39
32
  SCOPE_TARGET_KEY = :computers
40
33
 
41
- #####################################
42
- ### Attributes
34
+ # Attributes
43
35
  #####################################
44
36
 
45
- ### The values returned in the General, Location, and Purchasing subsets are stored as direct attributes
46
- ### Location and Purchasing are defined in the Locatable and Purchasable mixin modules.
47
- ### Here's General, in alphabetical order
48
-
49
- ### @return [String] the process name
37
+ # @return [String] the process name
50
38
  attr_reader :process_name
51
39
 
52
- ### @return [Boolean] whether to return match exact process name
40
+ # @return [Boolean] whether to return match exact process name
53
41
  attr_reader :match_exact_process_name
54
42
 
55
- ### @return [Boolean] whether to send a notification
43
+ # @return [Boolean] whether to send a notification
56
44
  attr_reader :send_notification
57
45
 
58
- ### @return [Boolean] whether to kill the running process
46
+ # @return [Boolean] whether to kill the running process
59
47
  attr_reader :kill_process
60
48
 
61
- ### @return [Boolean] whether to delete the executable
49
+ # @return [Boolean] whether to delete the executable
62
50
  attr_reader :delete_executable
63
51
 
64
- ### @return [String] message displayed to the user
52
+ # @return [String] message displayed to the user
65
53
  attr_reader :display_message
66
54
 
67
- ### @return [Hash] the :name and :id of the site for this machine
55
+ # @return [Hash] the :name and :id of the site for this machine
68
56
  attr_reader :site
69
57
 
70
- #####################################
71
- ### Instance Methods
58
+ # Instance Methods
72
59
  #####################################
73
60
 
74
61
  def initialize(args = {})
75
- super args, []
62
+ super args
76
63
 
64
+ @init_data[:general] ||= {}
77
65
  @process_name = @init_data[:general][:process_name]
78
66
  @match_exact_process_name = @init_data[:general][:match_exact_process_name]
79
67
  @send_notification = @init_data[:general][:send_notification]
@@ -81,6 +69,102 @@ module JSS
81
69
  @delete_executable = @init_data[:general][:delete_executable]
82
70
  @display_message = @init_data[:general][:display_message]
83
71
  @site = JSS::APIObject.get_name(@init_data[:general][:site])
72
+ @site ||= 'None'
73
+ @scope ||= JSS::Scopable::Scope.new SCOPE_TARGET_KEY, nil
74
+ end # init
75
+
76
+ def process_name=(new_val)
77
+ @process_name = new_val.to_s
78
+ @need_to_update = true
79
+ end
80
+
81
+ def match_exact_process_name=(new_val)
82
+ confirm_boolean(new_val)
83
+ @match_exact_process_name = new_val
84
+ @need_to_update = true
85
+ end
86
+
87
+ def send_notification=(new_val)
88
+ confirm_boolean(new_val)
89
+ @send_notification = new_val
90
+ @need_to_update = true
91
+ end
92
+
93
+ def kill_process=(new_val)
94
+ confirm_boolean(new_val)
95
+ @kill_process = new_val
96
+ @need_to_update = true
97
+ end
98
+
99
+ def delete_executable=(new_val)
100
+ confirm_boolean(new_val)
101
+ @delete_executable = new_val
102
+ @need_to_update = true
103
+ end
104
+
105
+ def display_message=(new_val)
106
+ @display_message = new_val.to_s
107
+ @need_to_update = true
84
108
  end
85
- end
86
- end
109
+
110
+ def site=(new_val)
111
+ if new_val.is_a? Integer
112
+ raise JSS::NoSuchItemError, "No site found with id #{new_val}" unless JSS::Site.all_ids.include? new_val
113
+ new_val = JSS::Site.map_all_ids_to(:name)[new_val]
114
+ else
115
+ new_val = new_val.to_s
116
+ raise JSS::NoSuchItemError, "No site found with name #{new_val}" unless JSS::Site.all_names.include? new_val
117
+ end
118
+ @site = new_val
119
+ @need_to_update = true
120
+ end
121
+
122
+ def create
123
+ raise JSS::MissingDataError, 'process_name must be set before creating' if @process_name.to_s.empty?
124
+ raise JSS::AlreadyExistsError, "A #{RSRC_OBJECT_KEY} named #{@name} already exists in the JSS" if self.class.all_names(:refresh).include? @name
125
+ super
126
+ end
127
+
128
+ def update
129
+ raise JSS::MissingDataError, 'process_name must be set before updating' if @process_name.to_s.empty?
130
+ super
131
+ end
132
+
133
+ ##### Aliases
134
+
135
+ alias match_exact_process_name? match_exact_process_name
136
+ alias send_notification? send_notification
137
+ alias kill_process? kill_process
138
+ alias delete_executable? delete_executable
139
+
140
+ ##### Private Instance Methods
141
+ private
142
+
143
+ def rest_xml
144
+ doc = REXML::Document.new APIConnection::XML_HEADER
145
+ obj = doc.add_element RSRC_OBJECT_KEY.to_s
146
+
147
+ general = obj.add_element 'general'
148
+ general.add_element('name').text = @name
149
+ general.add_element('process_name').text = @process_name
150
+ general.add_element('match_exact_process_name').text = @match_exact_process_name.to_s
151
+ general.add_element('send_notification').text = @send_notification.to_s
152
+ general.add_element('kill_process').text = @kill_process.to_s
153
+ general.add_element('delete_executable').text = @delete_executable.to_s
154
+ general.add_element('display_message').text = @display_message.to_s
155
+
156
+ site = general.add_element 'site'
157
+ site.add_element('name').text = @site
158
+
159
+ obj << @scope.scope_xml
160
+ doc.to_s
161
+ end # rest_xml
162
+
163
+ # TODO: Move this into a Validators module
164
+ def confirm_boolean(val)
165
+ raise JSS::InvalidDataError, 'Value must be boolean true or false' unless JSS::TRUE_FALSE.include? val
166
+ end
167
+
168
+ end # class
169
+
170
+ end # module JSS