webhdfs 0.7.3 → 0.10.0
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 +5 -5
- data/README.md +15 -0
- data/VERSION +1 -1
- data/lib/webhdfs/client_v1.rb +86 -12
- data/webhdfs.gemspec +5 -6
- metadata +12 -12
- data/.gitignore +0 -4
- data/Rakefile +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 769cd8dca5e3e329a882028bdcd06a3251e997148a7e85fdb68b14b21d37d989
|
4
|
+
data.tar.gz: f57beca7f1528b812e4bc99328120c673d93eb7eb48dc97aa5197ec976f7a5b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b0ddef524644a473dd37f9bd13d63eb09cd50d6b709444a93d577dfbe8e080f1bde7426c142e20eae992c578674957b53e77d8eacd4aa644d754cd6602d05de
|
7
|
+
data.tar.gz: 00a583e338e6f4e3bcd15ebba1437503b4f17f3ee1ef253fec211a05b7959ce7cfa9f97a55cc0f9fc92277e5c7a828a9a63e1d7f56a15160361087f25e4dc3ab
|
data/README.md
CHANGED
@@ -95,15 +95,30 @@ Note that net/https and openssl libraries must be available:
|
|
95
95
|
client.ssl = true
|
96
96
|
client.ssl_ca_file = "/path/to/ca_file.pem" # if needed
|
97
97
|
client.ssl_varify_mode = :peer # if needed (:none or :peer)
|
98
|
+
client.ssl_version = :TLSv1 # if needed
|
98
99
|
|
99
100
|
### For Kerberos Authentication
|
100
101
|
|
101
102
|
Note that [gssapi](https://github.com/zenchild/gssapi) library must be available:
|
102
103
|
|
103
104
|
client = WebHDFS::Client.new('hostname', 14000)
|
105
|
+
# or if you want to use client delegation token with renewing per 8 hours
|
106
|
+
client = WebHDFS::Client.new('hostname', 14000, username, nil, nil, nil, {}, 8)
|
107
|
+
|
104
108
|
client.kerberos = true
|
105
109
|
client.kerberos_keytab = "/path/to/project.keytab"
|
106
110
|
|
111
|
+
### For SSL Client Authentication
|
112
|
+
|
113
|
+
Note that openssl libraries must be available:
|
114
|
+
|
115
|
+
require 'openssl'
|
116
|
+
|
117
|
+
client = WebHDFS::Client.new(host, port)
|
118
|
+
client.ssl = true
|
119
|
+
client.ssl_key = OpenSSL::PKey::RSA.new(open('/path/to/key.pem'))
|
120
|
+
client.ssl_cert = OpenSSL::X509::Certificate.new(open('/path/to/cert.pem'))
|
121
|
+
|
107
122
|
## AUTHORS
|
108
123
|
|
109
124
|
* Kazuki Ohta <kazuki.ohta@gmail.com>
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.10.0
|
data/lib/webhdfs/client_v1.rb
CHANGED
@@ -23,8 +23,12 @@ module WebHDFS
|
|
23
23
|
attr_accessor :ssl
|
24
24
|
attr_accessor :ssl_ca_file
|
25
25
|
attr_reader :ssl_verify_mode
|
26
|
+
attr_accessor :ssl_cert
|
27
|
+
attr_accessor :ssl_key
|
28
|
+
attr_accessor :ssl_version
|
26
29
|
attr_accessor :kerberos, :kerberos_keytab
|
27
30
|
attr_accessor :http_headers
|
31
|
+
attr_accessor :kerberos_delegation_token
|
28
32
|
|
29
33
|
SSL_VERIFY_MODES = [:none, :peer]
|
30
34
|
def ssl_verify_mode=(mode)
|
@@ -34,7 +38,7 @@ module WebHDFS
|
|
34
38
|
@ssl_verify_mode = mode
|
35
39
|
end
|
36
40
|
|
37
|
-
def initialize(host='localhost', port=50070, username=nil, doas=nil, proxy_address=nil, proxy_port=nil, http_headers={})
|
41
|
+
def initialize(host='localhost', port=50070, username=nil, doas=nil, proxy_address=nil, proxy_port=nil, http_headers={}, renew_kerberos_delegation_token_time_hour=nil)
|
38
42
|
@host = host
|
39
43
|
@port = port
|
40
44
|
@username = username
|
@@ -50,35 +54,69 @@ module WebHDFS
|
|
50
54
|
@ssl = false
|
51
55
|
@ssl_ca_file = nil
|
52
56
|
@ssl_verify_mode = nil
|
57
|
+
@ssl_cert = nil
|
58
|
+
@ssl_key = nil
|
59
|
+
@ssl_version = nil
|
53
60
|
|
54
61
|
@kerberos = false
|
55
62
|
@kerberos_keytab = nil
|
63
|
+
@renew_kerberos_delegation_token_time_hour = renew_kerberos_delegation_token_time_hour
|
64
|
+
@kerberos_delegation_token = nil
|
65
|
+
@kerberos_token_updated_at = Time.now
|
56
66
|
@http_headers = http_headers
|
57
67
|
end
|
58
68
|
|
69
|
+
def should_kerberos_token_updated?
|
70
|
+
@kerberos_token_updated_at + (@renew_kerberos_delegation_token_time_hour * 60 * 60) <= Time.now
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def get_cached_kerberos_delegation_token(force_renew=nil)
|
75
|
+
return @kerberos_delegation_token if @kerberos_delegation_token && !should_kerberos_token_updated? && !force_renew
|
76
|
+
|
77
|
+
if !@kerberos_delegation_token || force_renew
|
78
|
+
@kerberos_delegation_token = get_kerberos_delegation_token(@username)
|
79
|
+
@kerberos_token_updated_at = Time.now
|
80
|
+
else
|
81
|
+
renew_kerberos_delegation_token(@kerberos_delegation_token)
|
82
|
+
@kerberos_token_updated_at = Time.now
|
83
|
+
end
|
84
|
+
@kerberos_delegation_token
|
85
|
+
rescue => e
|
86
|
+
raise WebHDFS::RequestFailedError, e.message
|
87
|
+
end
|
88
|
+
|
59
89
|
# curl -i -X PUT "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?op=CREATE
|
60
90
|
# [&overwrite=<true|false>][&blocksize=<LONG>][&replication=<SHORT>]
|
61
|
-
# [&permission=<OCTAL>][&buffersize=<INT>]
|
91
|
+
# [&permission=<OCTAL>][&buffersize=<INT>]
|
92
|
+
# [&delegation=<DELEGATION_TOKEN>]"
|
62
93
|
def create(path, body, options={})
|
63
94
|
if @httpfs_mode
|
64
95
|
options = options.merge({'data' => 'true'})
|
65
96
|
end
|
97
|
+
if @renew_kerberos_delegation_token_time_hour
|
98
|
+
options = options.merge('delegation' => get_cached_kerberos_delegation_token)
|
99
|
+
end
|
66
100
|
check_options(options, OPT_TABLE['CREATE'])
|
67
101
|
res = operate_requests('PUT', path, 'CREATE', options, body)
|
68
102
|
res.code == '201'
|
69
103
|
end
|
70
|
-
OPT_TABLE['CREATE'] = ['overwrite', 'blocksize', 'replication', 'permission', 'buffersize', 'data']
|
104
|
+
OPT_TABLE['CREATE'] = ['overwrite', 'blocksize', 'replication', 'permission', 'buffersize', 'data', 'delegation']
|
71
105
|
|
72
|
-
# curl -i -X POST "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?op=APPEND
|
106
|
+
# curl -i -X POST "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?op=APPEND
|
107
|
+
# [&buffersize=<INT>][&delegation=<DELEGATION_TOKEN>]"
|
73
108
|
def append(path, body, options={})
|
74
109
|
if @httpfs_mode
|
75
110
|
options = options.merge({'data' => 'true'})
|
76
111
|
end
|
112
|
+
if @renew_kerberos_delegation_token_time_hour
|
113
|
+
options = options.merge('delegation' => get_cached_kerberos_delegation_token)
|
114
|
+
end
|
77
115
|
check_options(options, OPT_TABLE['APPEND'])
|
78
116
|
res = operate_requests('POST', path, 'APPEND', options, body)
|
79
117
|
res.code == '200'
|
80
118
|
end
|
81
|
-
OPT_TABLE['APPEND'] = ['buffersize', 'data']
|
119
|
+
OPT_TABLE['APPEND'] = ['buffersize', 'data', 'delegation']
|
82
120
|
|
83
121
|
# curl -i -L "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?op=OPEN
|
84
122
|
# [&offset=<LONG>][&length=<LONG>][&buffersize=<INT>]"
|
@@ -158,6 +196,13 @@ module WebHDFS
|
|
158
196
|
end
|
159
197
|
alias :gethomedirectory :homedir
|
160
198
|
|
199
|
+
# curl -i "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?op=GETTRASHROOT"
|
200
|
+
def gettrashroot(options={})
|
201
|
+
check_options(options, OPT_TABLE['GETTRASHROOT'])
|
202
|
+
res = operate_requests('GET', '/', 'GETTRASHROOT', options)
|
203
|
+
check_success_json(res, 'Path')
|
204
|
+
end
|
205
|
+
|
161
206
|
# curl -i -X PUT "http://<HOST>:<PORT>/webhdfs/v1/<PATH>?op=SETPERMISSION
|
162
207
|
# [&permission=<OCTAL>]"
|
163
208
|
def chmod(path, mode, options={})
|
@@ -206,12 +251,25 @@ module WebHDFS
|
|
206
251
|
OPT_TABLE['SETTIMES'] = ['modificationtime', 'accesstime']
|
207
252
|
alias :settimes :touch
|
208
253
|
|
209
|
-
#
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
254
|
+
# curl -i "http://<HOST>:<PORT>/webhdfs/v1/?op=GETDELEGATIONTOKEN&renewer=<USER>"
|
255
|
+
def get_kerberos_delegation_token(user, options={})
|
256
|
+
options = options.merge({ 'renewer' => user })
|
257
|
+
check_options(options, OPT_TABLE['GETDELEGATIONTOKEN'])
|
258
|
+
res = operate_requests('GET', '/', 'GETDELEGATIONTOKEN', options)
|
259
|
+
check_success_json(res, 'Token')
|
260
|
+
JSON.parse(res.body)['Token']['urlString']
|
261
|
+
end
|
262
|
+
OPT_TABLE['GETDELEGATIONTOKEN'] = ['renewer']
|
263
|
+
|
264
|
+
# curl -i -X PUT "http://<HOST>:<PORT>/webhdfs/v1/?op=RENEWDELEGATIONTOKEN&token=<DELEGATION_TOKEN>"
|
265
|
+
def renew_kerberos_delegation_token(token, options={})
|
266
|
+
options = options.merge({ 'token' => token })
|
267
|
+
check_options(options, OPT_TABLE['RENEWDELEGATIONTOKEN'])
|
268
|
+
res = operate_requests('PUT', '/', 'RENEWDELEGATIONTOKEN', options)
|
269
|
+
check_success_json(res, 'long')
|
270
|
+
end
|
271
|
+
OPT_TABLE['RENEWDELEGATIONTOKEN'] = ['token']
|
272
|
+
|
215
273
|
# def cancel_delegation_token(token, options={}) # CANCELDELEGATIONTOKEN
|
216
274
|
# raise NotImplementedError
|
217
275
|
# end
|
@@ -300,6 +358,9 @@ module WebHDFS
|
|
300
358
|
when :peer then OpenSSL::SSL::VERIFY_PEER
|
301
359
|
end
|
302
360
|
end
|
361
|
+
conn.cert = @ssl_cert if @ssl_cert
|
362
|
+
conn.key = @ssl_key if @ssl_key
|
363
|
+
conn.ssl_version = @ssl_version if @ssl_version
|
303
364
|
end
|
304
365
|
|
305
366
|
gsscli = nil
|
@@ -343,7 +404,8 @@ module WebHDFS
|
|
343
404
|
end
|
344
405
|
end
|
345
406
|
|
346
|
-
if
|
407
|
+
# if delegation token param settled, namenode do not response WWW-Authenticate header
|
408
|
+
if @kerberos and res.code == '307' and not params.key?('delegation')
|
347
409
|
itok = (res.header.get_fields('WWW-Authenticate') || ['']).pop.split(/\s+/).last
|
348
410
|
unless itok
|
349
411
|
raise WebHDFS::KerberosError, 'Server does not return WWW-Authenticate header'
|
@@ -368,6 +430,18 @@ module WebHDFS
|
|
368
430
|
'Response body is empty...'
|
369
431
|
end
|
370
432
|
|
433
|
+
# when delegation token is expired
|
434
|
+
if res.code == '403' and @renew_kerberos_delegation_token_time_hour
|
435
|
+
if message.include?('{"RemoteException":{')
|
436
|
+
detail = JSON.parse(message) rescue nil
|
437
|
+
if detail&.dig('RemoteException', 'exception') == 'InvalidToken' and detail&.dig('RemoteException', 'message')&.include?('HDFS_DELEGATION_TOKEN')
|
438
|
+
params = params.merge('token' => get_cached_kerberos_delegation_token(true))
|
439
|
+
sleep @retry_interval if @retry_interval > 0
|
440
|
+
return request(host, port, method, path, op, params, payload, header, retries+1)
|
441
|
+
end
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
371
445
|
if @retry_known_errors && retries < @retry_times
|
372
446
|
detail = nil
|
373
447
|
if message =~ /^\{"RemoteException":\{/
|
data/webhdfs.gemspec
CHANGED
@@ -7,14 +7,13 @@ Gem::Specification.new do |gem|
|
|
7
7
|
gem.homepage = "https://github.com/kzk/webhdfs/"
|
8
8
|
gem.summary = gem.description
|
9
9
|
gem.version = File.read("VERSION").strip
|
10
|
-
gem.authors = ["Kazuki Ohta"]
|
11
|
-
gem.email = "kazuki.ohta@gmail.com"
|
10
|
+
gem.authors = ["Kazuki Ohta", "Satoshi Tagomori"]
|
11
|
+
gem.email = ["kazuki.ohta@gmail.com", "tagomoris@gmail.com"]
|
12
12
|
gem.has_rdoc = false
|
13
|
-
|
14
|
-
gem.
|
15
|
-
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
-
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
13
|
+
gem.files = Dir['lib/**/*','test/**/*','*.gemspec','*.md','AUTHORS','COPYING','Gemfile','VERSION']
|
14
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
15
|
gem.require_paths = ['lib']
|
16
|
+
gem.licenses = ["Apache-2.0"]
|
18
17
|
|
19
18
|
gem.add_development_dependency "rake"
|
20
19
|
gem.add_development_dependency "rdoc"
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webhdfs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kazuki Ohta
|
8
|
-
|
8
|
+
- Satoshi Tagomori
|
9
|
+
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2021-08-01 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rake
|
@@ -81,17 +82,17 @@ dependencies:
|
|
81
82
|
- !ruby/object:Gem::Version
|
82
83
|
version: '0'
|
83
84
|
description: Ruby WebHDFS/HttpFs client
|
84
|
-
email:
|
85
|
+
email:
|
86
|
+
- kazuki.ohta@gmail.com
|
87
|
+
- tagomoris@gmail.com
|
85
88
|
executables: []
|
86
89
|
extensions: []
|
87
90
|
extra_rdoc_files: []
|
88
91
|
files:
|
89
|
-
- ".gitignore"
|
90
92
|
- AUTHORS
|
91
93
|
- COPYING
|
92
94
|
- Gemfile
|
93
95
|
- README.md
|
94
|
-
- Rakefile
|
95
96
|
- VERSION
|
96
97
|
- lib/webhdfs.rb
|
97
98
|
- lib/webhdfs/backport.rb
|
@@ -103,9 +104,10 @@ files:
|
|
103
104
|
- test/webhdfs/fileutils.rb
|
104
105
|
- webhdfs.gemspec
|
105
106
|
homepage: https://github.com/kzk/webhdfs/
|
106
|
-
licenses:
|
107
|
+
licenses:
|
108
|
+
- Apache-2.0
|
107
109
|
metadata: {}
|
108
|
-
post_install_message:
|
110
|
+
post_install_message:
|
109
111
|
rdoc_options: []
|
110
112
|
require_paths:
|
111
113
|
- lib
|
@@ -120,12 +122,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
122
|
- !ruby/object:Gem::Version
|
121
123
|
version: '0'
|
122
124
|
requirements: []
|
123
|
-
|
124
|
-
|
125
|
-
signing_key:
|
125
|
+
rubygems_version: 3.2.3
|
126
|
+
signing_key:
|
126
127
|
specification_version: 4
|
127
128
|
summary: Ruby WebHDFS/HttpFs client
|
128
129
|
test_files:
|
129
130
|
- test/test_helper.rb
|
130
131
|
- test/webhdfs/fileutils.rb
|
131
|
-
has_rdoc: false
|
data/.gitignore
DELETED
data/Rakefile
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
Bundler::GemHelper.install_tasks
|
3
|
-
|
4
|
-
require 'rake/testtask'
|
5
|
-
|
6
|
-
Rake::TestTask.new(:test) do |test|
|
7
|
-
test.libs << 'lib' << 'test'
|
8
|
-
test.test_files = FileList['test/webhdfs/*.rb']
|
9
|
-
test.verbose = true
|
10
|
-
end
|
11
|
-
|
12
|
-
task :doc do |t|
|
13
|
-
`bundle exec rdoc --markup=tomdoc --visibility=public --include=lib --exclude=test`
|
14
|
-
end
|
15
|
-
|
16
|
-
task :coverage do |t|
|
17
|
-
ENV['SIMPLE_COV'] = '1'
|
18
|
-
Rake::Task["test"].invoke
|
19
|
-
end
|
20
|
-
|
21
|
-
task :default => [:build]
|