palo_alto 0.2.7 → 0.2.9
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.
- checksums.yaml +4 -4
- data/console.rb +0 -1
- data/examples/connecttest.rb +1 -1
- data/examples/test_config.rb +1 -1
- data/examples/test_log.rb +1 -1
- data/examples/test_op.rb +1 -1
- data/lib/palo_alto/config.rb +5095 -1
- data/lib/palo_alto/version.rb +1 -1
- data/lib/palo_alto.rb +61 -44
- metadata +2 -2
data/lib/palo_alto/version.rb
CHANGED
data/lib/palo_alto.rb
CHANGED
@@ -74,30 +74,35 @@ module PaloAlto
|
|
74
74
|
|
75
75
|
module Helpers
|
76
76
|
class Rest
|
77
|
+
@http_clients = {} # will include [http_client, lock]
|
78
|
+
@global_lock = Mutex.new
|
79
|
+
|
77
80
|
def self.make_request(opts)
|
78
81
|
options = {}
|
79
|
-
options[:verify_ssl]
|
80
|
-
options[:timeout] = 60
|
82
|
+
options[:verify_ssl] ||= OpenSSL::SSL::VERIFY_PEER
|
81
83
|
|
82
|
-
headers
|
83
|
-
|
84
|
-
|
85
|
-
|
84
|
+
headers = {
|
85
|
+
'User-Agent': 'ruby-keystone-client',
|
86
|
+
'Accept': 'application/xml',
|
87
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
88
|
+
}
|
86
89
|
|
87
90
|
# merge in settings from method caller
|
88
91
|
options = options.merge(opts)
|
89
92
|
options[:headers].merge!(headers)
|
90
93
|
|
91
|
-
|
92
|
-
unless thread[:http]
|
93
|
-
thread[:http] = Net::HTTP.new(options[:host], options[:port])
|
94
|
-
thread[:http].use_ssl = true
|
95
|
-
thread[:http].verify_mode = options[:verify_ssl]
|
96
|
-
thread[:http].read_timeout = thread[:http].open_timeout = options[:timeout]
|
97
|
-
thread[:http].set_debug_output($stdout) if options[:debug].include?(:http)
|
98
|
-
end
|
94
|
+
http_client = lock = nil
|
99
95
|
|
100
|
-
|
96
|
+
@global_lock.synchronize do
|
97
|
+
unless (http_client, lock = @http_clients[options[:host]])
|
98
|
+
http_client = Net::HTTP.new(options[:host], 443)
|
99
|
+
http_client.use_ssl = true
|
100
|
+
http_client.verify_mode = options[:verify_ssl]
|
101
|
+
http_client.read_timeout = http_client.open_timeout = (options[:timeout] || 60)
|
102
|
+
http_client.set_debug_output(options[:debug].include?(:http) ? $stdout : nil)
|
103
|
+
@http_clients[options[:host]] = [http_client, (lock = Mutex.new)]
|
104
|
+
end
|
105
|
+
end
|
101
106
|
|
102
107
|
payload = options[:payload]
|
103
108
|
post_req = Net::HTTP::Post.new('/api/', options[:headers])
|
@@ -109,7 +114,11 @@ module PaloAlto
|
|
109
114
|
post_req.set_form_data(payload)
|
110
115
|
end
|
111
116
|
|
112
|
-
response =
|
117
|
+
response = lock.synchronize do
|
118
|
+
http_client.start unless http_client.started?
|
119
|
+
|
120
|
+
http_client.request(post_req)
|
121
|
+
end
|
113
122
|
|
114
123
|
case response.code
|
115
124
|
when '200'
|
@@ -159,7 +168,7 @@ module PaloAlto
|
|
159
168
|
end
|
160
169
|
|
161
170
|
class XML
|
162
|
-
attr_accessor :host, :
|
171
|
+
attr_accessor :host, :username, :password, :auth_key, :verify_ssl, :debug, :timeout
|
163
172
|
|
164
173
|
def execute(payload)
|
165
174
|
retried = false
|
@@ -167,10 +176,10 @@ module PaloAlto
|
|
167
176
|
# configure options for the request
|
168
177
|
options = {}
|
169
178
|
options[:host] = host
|
170
|
-
options[:port] = port
|
171
179
|
options[:verify_ssl] = verify_ssl
|
172
180
|
options[:payload] = payload
|
173
181
|
options[:debug] = debug
|
182
|
+
options[:timeout] = timeout || 180
|
174
183
|
options[:headers] = if payload[:type] == 'keygen'
|
175
184
|
{}
|
176
185
|
else
|
@@ -206,27 +215,25 @@ module PaloAlto
|
|
206
215
|
'Commit lock is not currently held by',
|
207
216
|
'You already own a config lock for scope '
|
208
217
|
]
|
209
|
-
if retried || dont_retry_at.any? { |x| e.message.start_with?(x) }
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
retry
|
216
|
-
end
|
218
|
+
raise e if retried || dont_retry_at.any? { |x| e.message.start_with?(x) }
|
219
|
+
|
220
|
+
warn "Got error #{e.inspect}; retrying" if debug.include?(:warnings)
|
221
|
+
retried = true
|
222
|
+
get_auth_key if e.is_a?(SessionTimedOutException)
|
223
|
+
retry
|
217
224
|
end
|
218
225
|
end
|
219
226
|
|
220
|
-
def commit!(all: false, device_groups: nil, wait_for_completion: true)
|
221
|
-
return nil if device_groups.is_a?(Array) && device_groups.empty?
|
227
|
+
def commit!(all: false, device_groups: nil, templates: nil, wait_for_completion: true, wait: 5, timeout: 480)
|
228
|
+
return nil if device_groups.is_a?(Array) && device_groups.empty? && templates.is_a?(Array) && templates.empty?
|
222
229
|
|
223
230
|
cmd = if all
|
224
231
|
'commit'
|
225
232
|
else
|
226
233
|
{ commit: { partial: [
|
227
234
|
{ 'admin': [username] },
|
228
|
-
device_groups ? { 'device-group': device_groups } : nil,
|
229
|
-
'no-template',
|
235
|
+
device_groups ? ( device_groups.empty? ? 'no-device-group' : { 'device-group': device_groups } ) : nil,
|
236
|
+
templates ? ( templates.empty? ? 'no-template' : { 'template': templates } ) : nil,
|
230
237
|
'no-template-stack',
|
231
238
|
'no-log-collector',
|
232
239
|
'no-log-collector-group',
|
@@ -238,10 +245,11 @@ module PaloAlto
|
|
238
245
|
end
|
239
246
|
result = op.execute(cmd)
|
240
247
|
|
241
|
-
return result unless wait_for_completion
|
242
|
-
|
243
248
|
job_id = result.at_xpath('response/result/job')&.text
|
244
|
-
|
249
|
+
|
250
|
+
return result unless job_id && wait_for_completion
|
251
|
+
|
252
|
+
wait_for_job_completion(job_id, wait: wait, timeout: timeout) if job_id
|
245
253
|
end
|
246
254
|
|
247
255
|
def full_commit_required?
|
@@ -329,7 +337,7 @@ module PaloAlto
|
|
329
337
|
}
|
330
338
|
end
|
331
339
|
|
332
|
-
def wait_for_job_completion(job_id, wait: 5, timeout:
|
340
|
+
def wait_for_job_completion(job_id, wait: 5, timeout: 480)
|
333
341
|
cmd = { show: { jobs: { id: job_id } } }
|
334
342
|
start = Time.now
|
335
343
|
loop do
|
@@ -343,7 +351,8 @@ module PaloAlto
|
|
343
351
|
false
|
344
352
|
end
|
345
353
|
|
346
|
-
|
354
|
+
# wait: how long revert is retried (every 10 seconds)
|
355
|
+
def revert!(all: false, wait: 60)
|
347
356
|
cmd = if all
|
348
357
|
{ revert: 'config' }
|
349
358
|
else
|
@@ -359,16 +368,25 @@ module PaloAlto
|
|
359
368
|
{ 'shared-object': 'excluded' }
|
360
369
|
] } } }
|
361
370
|
end
|
362
|
-
|
371
|
+
|
372
|
+
waited = 0
|
373
|
+
begin
|
374
|
+
op.execute(cmd)
|
375
|
+
rescue StandardError => e
|
376
|
+
puts 'Revert failed; waiting and retrying'
|
377
|
+
sleep 10
|
378
|
+
waited += 1
|
379
|
+
retry while waited < wait
|
380
|
+
raise e
|
381
|
+
end
|
363
382
|
end
|
364
383
|
|
365
|
-
def initialize(host:,
|
366
|
-
self.host
|
367
|
-
self.
|
368
|
-
self.
|
369
|
-
self.
|
370
|
-
self.
|
371
|
-
self.debug = debug
|
384
|
+
def initialize(host:, username:, password:, verify_ssl: OpenSSL::SSL::VERIFY_NONE, debug: [])
|
385
|
+
self.host = host
|
386
|
+
self.username = username
|
387
|
+
self.password = password
|
388
|
+
self.verify_ssl = verify_ssl
|
389
|
+
self.debug = debug
|
372
390
|
|
373
391
|
@subclasses = {}
|
374
392
|
|
@@ -377,7 +395,6 @@ module PaloAlto
|
|
377
395
|
@arguments = [Expression.new(:this_node), []]
|
378
396
|
|
379
397
|
# attempt to obtain the auth_key
|
380
|
-
# raise 'Exception attempting to obtain the auth_key' if (self.class.auth_key = get_auth_key).nil?
|
381
398
|
get_auth_key
|
382
399
|
end
|
383
400
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: palo_alto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Roesner
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|