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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 683a33677fdfcccdf3bcd483c761e419b569e666
4
- data.tar.gz: c759040209eb4ad21af23516737f5844140abed7
2
+ SHA256:
3
+ metadata.gz: 769cd8dca5e3e329a882028bdcd06a3251e997148a7e85fdb68b14b21d37d989
4
+ data.tar.gz: f57beca7f1528b812e4bc99328120c673d93eb7eb48dc97aa5197ec976f7a5b3
5
5
  SHA512:
6
- metadata.gz: 25d7628a72dac4ab37ada639fd63930f094e3b672367f4db3c8f2fb669f97a642a0f1cbfea2de9fcd88c752d502d2287f312632125982d5cf8d7497e19d2d10d
7
- data.tar.gz: 4879bd5fa710df17d53ab80c99703c57df6863b15cabafdc704368a47146345abf6ad66ae54fd9dbf6a50d07f3e7a25cbc4ee9ce8a2d1c026a52120645bc0654
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.7.3
1
+ 0.10.0
@@ -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[&buffersize=<INT>]"
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
- # def delegation_token(user, options={}) # GETDELEGATIONTOKEN
210
- # raise NotImplementedError
211
- # end
212
- # def renew_delegation_token(token, options={}) # RENEWDELEGATIONTOKEN
213
- # raise NotImplementedError
214
- # end
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 @kerberos and res.code == '307'
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
- #gem.platform = Gem::Platform::RUBY
14
- gem.files = `git ls-files`.split("\n")
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.7.3
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazuki Ohta
8
- autorequire:
8
+ - Satoshi Tagomori
9
+ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2015-11-17 00:00:00.000000000 Z
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: kazuki.ohta@gmail.com
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
- rubyforge_project:
124
- rubygems_version: 2.4.5
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
@@ -1,4 +0,0 @@
1
- /pkg/
2
- /coverage/
3
- /vendor/
4
- Gemfile.lock
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]