ruby-jss 1.2.10 → 1.3.2

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.

Potentially problematic release.


This version of ruby-jss might be problematic. Click here for more details.

Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +92 -1
  3. data/lib/jamf/api/abstract_classes/json_object.rb +1 -1
  4. data/lib/jamf/api/abstract_classes/prestage.rb +1 -1
  5. data/lib/jamf/api/connection.rb +7 -3
  6. data/lib/jamf/configuration.rb +7 -9
  7. data/lib/jamf/ruby_extensions.rb +1 -0
  8. data/lib/jamf/ruby_extensions/array.rb +1 -1
  9. data/lib/jamf/ruby_extensions/array/utils.rb +3 -3
  10. data/lib/jamf/ruby_extensions/dig.rb +52 -0
  11. data/lib/jss.rb +2 -0
  12. data/lib/jss/api_connection.rb +2 -29
  13. data/lib/jss/api_object.rb +15 -2
  14. data/lib/jss/api_object/directory_binding.rb +273 -0
  15. data/lib/jss/api_object/directory_binding_type.rb +90 -0
  16. data/lib/jss/api_object/directory_binding_type/active_directory.rb +502 -0
  17. data/lib/jss/api_object/directory_binding_type/admitmac.rb +525 -0
  18. data/lib/jss/api_object/directory_binding_type/centrify.rb +212 -0
  19. data/lib/jss/api_object/directory_binding_type/open_directory.rb +178 -0
  20. data/lib/jss/api_object/directory_binding_type/powerbroker_identity_services.rb +73 -0
  21. data/lib/jss/api_object/disk_encryption_configurations.rb +114 -0
  22. data/lib/jss/api_object/distribution_point.rb +95 -35
  23. data/lib/jss/api_object/dock_item.rb +137 -0
  24. data/lib/jss/api_object/mobile_device_application.rb +12 -0
  25. data/lib/jss/api_object/network_segment.rb +152 -58
  26. data/lib/jss/api_object/package.rb +106 -41
  27. data/lib/jss/api_object/policy.rb +379 -4
  28. data/lib/jss/api_object/printer.rb +440 -0
  29. data/lib/jss/api_object/scopable/scope.rb +24 -24
  30. data/lib/jss/composer.rb +1 -1
  31. data/lib/jss/utility.rb +8 -22
  32. data/lib/jss/version.rb +1 -1
  33. metadata +13 -2
@@ -0,0 +1,114 @@
1
+ module JSS
2
+ ### Module Constants
3
+ #####################################
4
+
5
+ ### Module Variables
6
+ #####################################
7
+
8
+ ### Module Methods
9
+ #####################################
10
+
11
+ ### Classes
12
+ #####################################
13
+
14
+ ### Disk Encryption Configuration object inside JSS
15
+ ###
16
+ ### More Detailed Description if needed
17
+ class DiskEncryptionConfiguration < JSS::APIObject
18
+ ## Mix-Ins
19
+ #####################################
20
+ include JSS::Updatable
21
+
22
+ ## Class Constants
23
+ #####################################
24
+
25
+ # @note Currently "Individual and Institutional" configuration type is unsupported through the API
26
+ KEY_TYPE = {
27
+ individual: 'Individual',
28
+ institutional: 'Institutional',
29
+ individual_and_institutional: 'Individual and Institutional'
30
+ }.freeze
31
+
32
+ # @note as of 10.13 Management Account cannot be used due to the lack of a secure token.
33
+ ENABLED_USERS_TYPE = {
34
+ management: "Management Account",
35
+ current: "Current or Next User"
36
+ }.freeze
37
+
38
+ ### The base for REST resources of this class
39
+ RSRC_BASE = 'diskencryptionconfigurations'.freeze
40
+
41
+ ### the hash key used for the JSON list output of all objects in the JSS
42
+ RSRC_LIST_KEY = :disk_encryption_configurations
43
+
44
+ ### The hash key used for the JSON object output
45
+ ### It's also used in various error messages
46
+ RSRC_OBJECT_KEY = :disk_encryption_configuration
47
+
48
+ ## Attributes
49
+ #####################################
50
+ attr_reader :key_type
51
+ attr_reader :file_vault_enabled_users
52
+ attr_reader :institutional_recovery_key
53
+
54
+ ## Constructor
55
+ #####################################
56
+
57
+ ###
58
+ def initialize(args = {})
59
+ super
60
+
61
+ if self.in_jss?
62
+ @key_type = @init_data[:key_type]
63
+ @file_vault_enabled_users = @init_data[:file_vault_enabled_users]
64
+ @institutional_recovery_key = @init_data[:institutional_recovery_key]
65
+ else
66
+ raise JSS::InvalidDataError, "Currently the ability to create a Disk Encryption Configuration is not possible through ruby-jss."
67
+ end
68
+
69
+
70
+
71
+ end
72
+
73
+ ## Class Methods
74
+ #####################################
75
+
76
+ # Sets what type of account is to be enabled using the new value
77
+ #
78
+ # @author Tyler Morgan
79
+ #
80
+ # @param newvalue[Symbol] One of ENABLED_USERS_TYPE
81
+ #
82
+ # @return [Void]
83
+ #
84
+ def file_vault_enabled_users=(newvalue)
85
+ raise JSS::InvalidDataError, "file_vault_enabled_users must be one of :#{ENABLED_USERS_TYPE.keys.join(',:')}." unless ENABLED_USERS_TYPE.keys.include? newvalue
86
+
87
+ @file_vault_enabled_users = ENABLED_USERS_TYPE[newvalue]
88
+
89
+ @need_to_update = true
90
+
91
+ end
92
+
93
+ ## Private Instance Methods
94
+ #####################################
95
+
96
+ private
97
+
98
+ def rest_xml
99
+ raise JSS::UnsupportedError, "Key type of \"Individual and Institutional\" is currently unsupported via. API. So changes are unable to be saved." if @key_type == KEY_TYPE[:individual_and_institutional]
100
+ doc = REXML::Document.new
101
+ disk_encryption_configuration = doc.add_element 'disk_encryption_configuration'
102
+
103
+ disk_encryption_configuration.add_element('id').text = @id
104
+ disk_encryption_configuration.add_element('name').text = @name
105
+ disk_encryption_configuration.add_element('key_type').text = @key_type
106
+ disk_encryption_configuration.add_element('file_vault_enabled_users').text = @file_vault_enabled_users
107
+
108
+ doc.to_s
109
+
110
+
111
+
112
+ end
113
+ end
114
+ end
@@ -27,7 +27,7 @@ module JSS
27
27
  # Module Methods
28
28
  #####################################
29
29
 
30
- # A Distribution Point in the JSS
30
+ # A FileShare Distribution Point in the JSS
31
31
  #
32
32
  # As well as the normal Class and Instance methods for {APIObject} subclasses, the
33
33
  # DistributionPoint class provides more interaction with other parts of the API.
@@ -43,6 +43,11 @@ module JSS
43
43
  # and unmount it with {#unmount}. The {JSS::Package} and possibly {JSS::Script} classes use this to upload
44
44
  # items to the master.
45
45
  #
46
+ # NOTE: This class only deals with FileShare Distribution Points.
47
+ # There is no access to the Cloud Distribution Point in the classic API.
48
+ # See the .master_distribution_point and .my_distribution_point class methods
49
+ # for how they handle things when the Cloud DP is the master.
50
+ #
46
51
  # @see JSS::APIObject
47
52
  #
48
53
  class DistributionPoint < JSS::APIObject
@@ -80,32 +85,92 @@ module JSS
80
85
  # Class Methods
81
86
  #####################################
82
87
 
83
- # Get the DistributionPoint instance for the master
84
- # distribution point in the JSS. If there's only one
85
- # in the JSS, return it even if not marked as master.
88
+ # Get the DistributionPoint instance for the master distribution point.
89
+ #
90
+ # If the Cloud Dist Point is master, then the classic API has no way to
91
+ # know that or access it. In that case you can provide the 'default:' parameter.
92
+ # Give it the name or id of any dist. point to be used instead, or give it
93
+ # :random to randomly choose one.
94
+ #
95
+ # If there are no fileshare dist points defined (the cloud is the only one)
96
+ # then this whole class can't really be used.
86
97
  #
87
98
  # @param refresh[Boolean] should the distribution point be re-queried?
88
99
  #
100
+ # @param default[String, Integer, Symbol] Name or ID of a dist point to use
101
+ # if no master is found, or :random to randomly choose one.
102
+ #
89
103
  # @param api[JSS::APIConnection] which API connection should we query?
90
104
  #
91
105
  # @return [JSS::DistributionPoint]
92
106
  #
93
- def self.master_distribution_point(refresh = false, api: JSS.api)
94
- api.master_distribution_point refresh
107
+ def self.master_distribution_point(refresh = false, default: nil, api: JSS.api)
108
+ @master_distribution_point = nil if refresh
109
+ return @master_distribution_point if @master_distribution_point
110
+
111
+ all_ids(refresh, api: api).each do |dp_id|
112
+ dp = fetch id: dp_id, api: api
113
+ if dp.master?
114
+ @master_distribution_point = dp
115
+ break
116
+ end
117
+ end
118
+
119
+ # If we're here, the Cloud DP might be master, but there's no
120
+ # access to it in the API :/
121
+ raise JSS::NoSuchItemError, 'No Master FileShare Distribtion Point. Use the default: parameter if needed.' unless @master_distribution_point || default
122
+
123
+ if @master_distribution_point
124
+ @master_distribution_point
125
+ elsif default == :random
126
+ @master_distribution_point = fetch(id: all_ids.sample, api: api)
127
+ else
128
+ @master_distribution_point = fetch(default, api: api)
129
+ end
95
130
  end
96
131
 
97
132
  # Get the DistributionPoint instance for the machine running
98
133
  # this code, based on its IP address. If none is defined for this IP address,
99
- # use the result of master_distribution_point
134
+ # use the name or id provided as default. If no default: is provided,
135
+ # the master dp is used. If no master dp available (meaning its the
136
+ # cloud dp) then use a randomly chosen dp.
100
137
  #
101
138
  # @param refresh[Boolean] should the distribution point be re-queried?
102
139
  #
140
+ # @param default[String, Integer, Symbol] the name or id of a Dist Point
141
+ # to use if none is specified for this IP addr. Or :master, to use the
142
+ # master DP, or :random to use a randomly chosen one. If :master is
143
+ # specified and there is no master (master is cloud) then a random one is used.
144
+ #
103
145
  # @param api[JSS::APIConnection] which API connection should we query?
104
146
  #
105
147
  # @return [JSS::DistributionPoint]
106
148
  #
107
- def self.my_distribution_point(refresh = false, api: JSS.api)
108
- api.my_distribution_point refresh
149
+ def self.my_distribution_point(refresh = false, default: :master, api: JSS.api)
150
+ @my_distribution_point = nil if refresh
151
+ return @my_distribution_point if @my_distribution_point
152
+
153
+ my_net_seg_id = JSS::NetworkSegment.my_network_segment refresh, api: api
154
+
155
+ if my_net_seg_id
156
+ my_net_seg = JSS::NetworkSegment.fetch id: my_net_seg_id, api: api
157
+ my_dp_name = my_net_seg.distribution_point
158
+ @my_distribution_point = fetch name: my_dp_name, api: api if my_dp_name
159
+ end # if my_net_seg_id
160
+
161
+ return @my_distribution_point if @my_distribution_point
162
+
163
+ @my_distribution_point =
164
+ case default
165
+ when String
166
+ fetch name: default, api: api
167
+ when Integer
168
+ fetch id: default, api: api
169
+ when :master
170
+ master_distribution_point refresh, default: :random, api: api
171
+ when :random
172
+ fetch id: all_ids(refresh).sample, api: api
173
+ end
109
174
  end
110
175
 
111
176
  # Class Attributes
@@ -274,7 +339,7 @@ module JSS
274
339
  # Seemms the read-only pw isn't available in the API
275
340
 
276
341
  # if we mount for fileservice, where's the mountpoint?
277
- @mountpoint = Pathname.new "/#{DEFAULT_MOUNTPOINT_DIR}/#{DEFAULT_MOUNTPOINT_PREFIX}#{@id}"
342
+ @mountpoint = DEFAULT_MOUNTPOINT_DIR + "#{DEFAULT_MOUNTPOINT_PREFIX}#{@id}"
278
343
  end # init
279
344
 
280
345
  # Check the validity of a password.
@@ -315,37 +380,15 @@ module JSS
315
380
  # @return [FalseClass, Symbol] false if not reachable, otherwise :http or :mountable
316
381
  #
317
382
  def reachable_for_download?(pw = '', check_http = true)
318
- pw ||= ''
319
- http_checked = ''
320
- if check_http && http_downloads_enabled
321
- if @username_password_required
322
- # we don't check the pw here, because if the connection fails, we'll
323
- # drop down below to try the password for mounting.
324
- # we'll escape all the chars that aren't unreserved
325
- # reserved_chars = Regexp.new("[^#{URI::REGEXP::PATTERN::UNRESERVED}]")
326
- user_pass = "#{CGI.escape @http_username.to_s}:#{CGI.escape ro_pw.to_s}@"
327
- url = @http_url.sub "://#{@ip_address}", "://#{user_pass}#{@ip_address}"
328
- else
329
- url = @http_url
330
- end
331
-
332
- begin
333
- open(url).read
334
- return :http
335
- rescue
336
- http_checked = 'http and '
337
- end
338
- end # if check_http && http_downloads_enabled
339
-
383
+ return :http if check_http && http_reachable?(pw)
340
384
  return :mountable if mounted?
341
-
342
385
  return false unless check_pw :ro, pw
343
386
 
344
387
  begin
345
388
  mount pw, :ro
346
- return :mountable
389
+ :mountable
347
390
  rescue
348
- return false
391
+ false
349
392
  ensure
350
393
  unmount
351
394
  end
@@ -469,6 +512,23 @@ module JSS
469
512
  ######################################
470
513
  private
471
514
 
515
+ # can the dp be reached for http downloads?
516
+ def http_reachable?(pw)
517
+ return false unless http_downloads_enabled
518
+
519
+ url =
520
+ if @username_password_required
521
+ user_pass = "#{CGI.escape @http_username.to_s}:#{CGI.escape pw.to_s}@"
522
+ @http_url.sub "://#{@ip_address}", "://#{user_pass}#{@ip_address}"
523
+ else
524
+ @http_url
525
+ end
526
+ URI.parse(url).read
527
+ true
528
+ rescue
529
+ false
530
+ end
531
+
472
532
  # Unused - until I get around to making DP's updatable
473
533
  #
474
534
  # the XML representation of the current state of this object,
@@ -0,0 +1,137 @@
1
+ ### Copyright 2019 Rixar
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
+
26
+ module JSS
27
+
28
+ # Module Variables
29
+ #####################################
30
+
31
+ # Module Methods
32
+ #####################################
33
+
34
+ # Classes
35
+ #####################################
36
+
37
+ # A Dock Item in the JSS.
38
+ # These are rather simple. They have an ID, name, path, type, and contents which is read-only
39
+ #
40
+ # @see JSS::APIObject
41
+ #
42
+ class DockItem < JSS::APIObject
43
+
44
+ # Mix-Ins
45
+ #####################################
46
+ include JSS::Creatable
47
+ include JSS::Updatable
48
+
49
+ # Class Methods
50
+ #####################################
51
+
52
+ # Class Constants
53
+ #####################################
54
+
55
+ # The Dock Item type
56
+ DOCK_ITEM_TYPE = [
57
+ "App",
58
+ "File",
59
+ "Folder"
60
+ ].freeze
61
+
62
+ # The base for REST resources of this class
63
+ RSRC_BASE = 'dockitems'.freeze
64
+
65
+ # the hash key used for the JSON list output of all objects in the JSS
66
+ RSRC_LIST_KEY = :dock_items
67
+
68
+ # The hash key used for the JSON object output.
69
+ # It's also used in various error messages
70
+ RSRC_OBJECT_KEY = :dock_item
71
+
72
+ # the object type for this object in
73
+ # the object history table.
74
+ # See {APIObject#add_object_history_entry}
75
+ #OBJECT_HISTORY_OBJECT_TYPE = 41
76
+
77
+ # Attributes
78
+ #####################################
79
+ attr_reader :id
80
+ attr_reader :name
81
+ attr_reader :type
82
+ attr_reader :path
83
+
84
+ # Constructor
85
+ # @see JSS::APIObject.initialize
86
+ #####################################
87
+ def initialize(args = {})
88
+ super args
89
+
90
+ @type = "App" unless !@init_data[:type].nil?
91
+ @type = @init_data[:type]
92
+ @path = @init_data[:path]
93
+ end
94
+
95
+ # Public Instance Methods
96
+ #####################################
97
+
98
+ # set the type
99
+ #
100
+ # @param newval[String] the new app type
101
+ #
102
+ # @return [void]
103
+ #
104
+ def type=(newval)
105
+ raise JSS::InvalidDataError, 'Type must be a string' unless message.is_a? String
106
+ raise JSS::InvalidDataError, "Type must be one of the following: #{DOCK_ITEM_TYPE.to_s}; not #{newval.to_s}" unless DOCK_ITEM_TYPE.include? newval.to_s
107
+ @type = newval
108
+ @need_to_update = true
109
+ end
110
+
111
+ # set the path
112
+ #
113
+ # @param newval[String] the new app path
114
+ def path=(newval)
115
+ raise JSS::InvalidDataError, 'Path must be a String' unless newval.is_a? String
116
+ @path = newval
117
+ @need_to_update = true
118
+ end
119
+
120
+ # private instance methods
121
+ ######################
122
+ private
123
+
124
+ # the xml formated data for adding or updating this in the JSS
125
+ #
126
+ def rest_xml
127
+ doc = REXML::Document.new APIConnection::XML_HEADER
128
+ ns = doc.add_element RSRC_OBJECT_KEY.to_s
129
+ ns.add_element('name').text = @name
130
+ ns.add_element('type').text = @type.to_s
131
+ ns.add_element('path').text = @path.to_s
132
+ doc.to_s
133
+ end # rest_xml
134
+ end
135
+
136
+
137
+ end
@@ -444,6 +444,18 @@ module JSS
444
444
  refresh_ipa
445
445
  end
446
446
 
447
+ # Remove the various cached data
448
+ # from the instance_variables used to create
449
+ # pretty-print (pp) output.
450
+ #
451
+ # @return [Array] the desired instance_variables
452
+ #
453
+ def pretty_print_instance_variables
454
+ vars = super
455
+ vars.delete :@ipa
456
+ vars
457
+ end
458
+
447
459
  # Private Instance Methods
448
460
  ###########################################
449
461
  private