fluent-plugin-azurestorage-gen2 0.2.10 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b42f7d710c0d096c722704a8737dc9ef17acc34c
4
- data.tar.gz: 820a5d16c3523f721fe4c9b60dcd04f4e7369a03
2
+ SHA256:
3
+ metadata.gz: eeea9ef451a8996e41202f49defb227905aeec16aab55f6f208617517365b929
4
+ data.tar.gz: 0c2027d20716c613c35ee0a325694225d138f0712fc4ca638962beef9397edea
5
5
  SHA512:
6
- metadata.gz: 9dd02068916c98e40bd0cd59524ce4a6fed211c0d4b912dd4057ff3e7012f7f423c5c00f9fdc72ce5398911ef0a9990a307b2091315adca95ef7ac28a5ae35ab
7
- data.tar.gz: a7bff81b96aea91b67d3cca7cec85fa27edc5e701dd47db993e8ae9dd6d6d1ff980f62c4b6755959935acbe0d5ea52d8908eee4ed682001e0ef65af7013f05f6
6
+ metadata.gz: 65a5ffaea781a9e74f860f489e91f2fc0f0264a8998ffd694808688e48a826a5f3af5d02c1b07091565324c70ad7d6dcfbdfcbb7278d108eacd01089964cdf6c
7
+ data.tar.gz: 40f629211e74147a59dadf047809f1b743ef01437542b9c880b0a2fe51907dd182a2db49a90ba9c80c1aa3741a30b739d59452b31a195ffb839529559b6c3c70
data/README.md CHANGED
@@ -31,6 +31,7 @@ $ gem install fluent-plugin-azurestorage-gen2
31
31
  azure_storage_account mystorageabfs
32
32
  azure_container mycontainer
33
33
  azure_instance_msi /subscriptions/mysubscriptionid
34
+ azure_client_id <msi client id>
34
35
  azure_object_key_format %{path}-%{index}.%{file_extension}
35
36
  azure_oauth_refresh_interval 3600
36
37
  time_slice_format %Y%m%d-%H
@@ -92,6 +93,14 @@ Your Azure Storage Access Key(Primary or Secondary). This also can be got from A
92
93
 
93
94
  Your Azure Managed Service Identity ID. When storage key authentication is not used, the plugin uses OAuth2 to authenticate as given MSI. This authentication method only works on Azure VM. If the VM has only one MSI assigned, this parameter becomes optional and the only MSI will be used. Otherwise this parameter is required.
94
95
 
96
+ ### azure_client_id
97
+
98
+ Azure AD client id is a specific explicit identity to use when authenticating to Azure AD. Mutually exclusive with azure_object_id and azure_instance_msi. (for now, you need to define next to `azure_instance_msi`)
99
+
100
+ ### azure_object_id
101
+
102
+ Azure AD object id is a specific explicit identity to use when authenticating to Azure AD. Mutually exclusive with azure_client_id and azure_instance_msi. (for now, you need to define next to `azure_instance_msi`)
103
+
95
104
  ### azure_oauth_tenant_id (Preview)
96
105
 
97
106
  Azure account tenant id from your Azure Directory. Required if OAuth based credential mechanism is used.
@@ -152,6 +161,7 @@ The format of Azure Storage object keys. You can use several built-in variables:
152
161
  - %{time_slice}
153
162
  - %{index}
154
163
  - %{file_extension}
164
+ - %{upload_timestamp}
155
165
 
156
166
  to decide keys dynamically.
157
167
 
@@ -159,6 +169,7 @@ to decide keys dynamically.
159
169
  %{time_slice} is the time-slice in text that are formatted with *time_slice_format*.
160
170
  %{index} is the sequential number starts from 0, increments when multiple files are uploaded to Azure Storage in the same time slice.
161
171
  %{file_extention} is always "gz" for now.
172
+ %{upload_timestamp} is an upload timestamp in text that are formatted with *upload_timestamp_format*. Difference between time_slice and upload_timestamp is that the second one is the actual system timestamp (other one is from the metadata)
162
173
 
163
174
  The default format is "%{path}%{time_slice}_%{index}.%{file_extension}".
164
175
 
@@ -283,10 +294,34 @@ Format of the time used as the file name. Default is '%Y%m%d'. Use '%Y%m%d%H' to
283
294
 
284
295
  The time to wait old logs. Default is 10 minutes.
285
296
 
297
+ ### upload_timestamp_format
298
+
299
+ Format of the upload timestamp used as the file name. Can be used instead of index in case of `write_only` option is enabled. Default value is '%H%M%S%L'.
300
+
286
301
  ### utc
287
302
 
288
303
  Use UTC instead of local time.
289
304
 
305
+ ### write_only
306
+
307
+ If that option is enabled, HEAD calls are skipped during blob operations. (so make sure to set the chunk limit to 4MB in order to avoid HEAD operation because of the append operation needs the last position of the uploaded blobs).
308
+
309
+ ### proxy_url
310
+
311
+ Proxy URL for Azure endpoint.
312
+
313
+ ### proxy_username
314
+
315
+ Proxy username for Azure proxy endpoint (used only if `proxy_url` is filled)
316
+
317
+ ### proxy_password
318
+
319
+ Proxy password for Azure `proxy_username` (used only if `proxy_url` is filled)
320
+
321
+ ### http_timeout_seconds
322
+
323
+ The time limit for HTTP request in seconds. Default: 120
324
+
290
325
  ## TODOs
291
326
 
292
327
  - add storage key support
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.10
1
+ 0.3.3
@@ -24,6 +24,8 @@ module Fluent::Plugin
24
24
  config_param :azure_storage_account, :string, :default => nil
25
25
  config_param :azure_storage_access_key, :string, :default => nil, :secret => true
26
26
  config_param :azure_instance_msi, :string, :default => nil
27
+ config_param :azure_client_id, :string, :default => nil
28
+ config_param :azure_object_id, :string, :default => nil
27
29
  config_param :azure_oauth_app_id, :string, :default => nil, :secret => true
28
30
  config_param :azure_oauth_secret, :string, :default => nil, :secret => true
29
31
  config_param :azure_oauth_tenant_id, :string, :default => nil
@@ -44,6 +46,12 @@ module Fluent::Plugin
44
46
  config_param :time_slice_format, :string, :default => '%Y%m%d'
45
47
  config_param :hex_random_length, :integer, default: 4
46
48
  config_param :command_parameter, :string, :default => nil
49
+ config_param :proxy_url, :string, :default => nil
50
+ config_param :proxy_username, :string, :default => nil
51
+ config_param :proxy_password, :string, :default => nil, :secret => true
52
+ config_param :write_only, :bool, :default => false
53
+ config_param :upload_timestamp_format, :string, :default => '%H%M%S%L'
54
+ config_param :http_timeout_seconds, :integer, :default => 120
47
55
 
48
56
  DEFAULT_FORMAT_TYPE = "out_file"
49
57
  ACCESS_TOKEN_API_VERSION = "2018-02-01"
@@ -53,7 +61,7 @@ module Fluent::Plugin
53
61
  config_section :format do
54
62
  config_set_default :@type, DEFAULT_FORMAT_TYPE
55
63
  end
56
-
64
+
57
65
  config_section :buffer do
58
66
  config_set_default :chunk_keys, ['time']
59
67
  config_set_default :timekey, (60 * 60 * 24)
@@ -76,7 +84,7 @@ module Fluent::Plugin
76
84
  end
77
85
 
78
86
  @formatter = formatter_create
79
-
87
+
80
88
  if @azure_container.nil?
81
89
  raise Fluent::ConfigError, "azure_container is needed"
82
90
  end
@@ -102,12 +110,20 @@ module Fluent::Plugin
102
110
  if !@skip_container_check
103
111
  if @failsafe_container_check
104
112
  begin
105
- ensure_container
113
+ if @write_only && @auto_create_container
114
+ create_container
115
+ else
116
+ ensure_container
117
+ end
106
118
  rescue Exception => e
107
119
  log.warn("#{e.message}, container list/create failsafe is enabled. Continue without those operations.")
108
120
  end
109
121
  else
110
- ensure_container
122
+ if @write_only && @auto_create_container
123
+ create_container
124
+ else
125
+ ensure_container
126
+ end
111
127
  end
112
128
  end
113
129
  super
@@ -158,11 +174,16 @@ module Fluent::Plugin
158
174
  private
159
175
  def upload_blob(content, chunk)
160
176
  log.debug "azurestorage_gen2: Uploading blob: #{@azure_storage_path}"
161
- existing_content_length = get_blob_properties(@azure_storage_path)
162
- if existing_content_length == 0
177
+ if @write_only
163
178
  create_blob(@azure_storage_path)
179
+ append_blob(content, chunk, 0)
180
+ else
181
+ existing_content_length = get_blob_properties(@azure_storage_path)
182
+ if existing_content_length == 0
183
+ create_blob(@azure_storage_path)
184
+ end
185
+ append_blob(content, chunk, existing_content_length)
164
186
  end
165
- append_blob(content, chunk, existing_content_length)
166
187
  end
167
188
 
168
189
  private
@@ -175,8 +196,10 @@ module Fluent::Plugin
175
196
  end
176
197
  if @localtime
177
198
  hms_slicer = Time.now.strftime("%H%M%S")
199
+ upload_timestamp = Time.now.strftime(@upload_timestamp_format)
178
200
  else
179
201
  hms_slicer = Time.now.utc.strftime("%H%M%S")
202
+ upload_timestamp = Time.now.utc.strftime(@upload_timestamp_format)
180
203
  end
181
204
 
182
205
  @values_for_object_chunk[chunk.unique_id] ||= {
@@ -186,7 +209,8 @@ module Fluent::Plugin
186
209
  "%{path}" => @path,
187
210
  "%{index}" => index,
188
211
  "%{uuid_flush}" => uuid_random,
189
- "%{file_extension}" => @final_file_extension
212
+ "%{file_extension}" => @final_file_extension,
213
+ "%{upload_timestamp}" => upload_timestamp,
190
214
  }
191
215
  values_for_object_key_post = {
192
216
  "%{date_slice}" => time_slice,
@@ -255,7 +279,19 @@ module Fluent::Plugin
255
279
  unless @azure_instance_msi.nil?
256
280
  params[:msi_res_id] = @azure_instance_msi
257
281
  end
258
- request = Typhoeus::Request.new("http://169.254.169.254/metadata/identity/oauth2/token", params: params, headers: { Metadata: "true"})
282
+ unless @azure_client_id.nil?
283
+ params[:client_id] = @azure_client_id
284
+ end
285
+ unless @azure_object_id.nil?
286
+ params[:object_id] = @azure_object_id
287
+ end
288
+ req_opts = {
289
+ :params => params,
290
+ :headers => { Metadata: "true" },
291
+ :timeout => @http_timeout_seconds
292
+ }
293
+ add_proxy_options(req_opts)
294
+ request = Typhoeus::Request.new("http://169.254.169.254/metadata/identity/oauth2/token", req_opts)
259
295
  request.on_complete do |response|
260
296
  if response.success?
261
297
  data = JSON.parse(response.body)
@@ -273,7 +309,14 @@ module Fluent::Plugin
273
309
  params = { :"api-version" => ACCESS_TOKEN_API_VERSION, :resource => "#{@url_storage_resource}"}
274
310
  headers = {:"Content-Type" => "application/x-www-form-urlencoded"}
275
311
  content = "grant_type=client_credentials&client_id=#{@azure_oauth_app_id}&client_secret=#{@azure_oauth_secret}&resource=#{@url_storage_resource}"
276
- request = Typhoeus::Request.new("https://login.microsoftonline.com/#{@azure_oauth_tenant_id}/oauth2/token", :body => content, :headers => headers)
312
+ req_opts = {
313
+ :params => params,
314
+ :body => content,
315
+ :headers => headers,
316
+ :timeout => @http_timeout_seconds
317
+ }
318
+ add_proxy_options(req_opts)
319
+ request = Typhoeus::Request.new("https://login.microsoftonline.com/#{@azure_oauth_tenant_id}/oauth2/token", req_opts)
277
320
  request.on_complete do |response|
278
321
  if response.success?
279
322
  data = JSON.parse(response.body)
@@ -300,7 +343,14 @@ module Fluent::Plugin
300
343
  params = {:resource => "filesystem" }
301
344
  auth_header = create_auth_header("head", datestamp, "#{@azure_container}", headers, params)
302
345
  headers[:Authorization] = auth_header
303
- request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}", :method => :head, :params => params, :headers=> headers)
346
+ req_opts = {
347
+ :method => :head,
348
+ :params => params,
349
+ :headers => headers,
350
+ :timeout => @http_timeout_seconds
351
+ }
352
+ add_proxy_options(req_opts)
353
+ request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}", req_opts)
304
354
  request.on_complete do |response|
305
355
  if response.success?
306
356
  log.info "azurestorage_gen2: Container '#{@azure_container}' exists."
@@ -327,7 +377,14 @@ module Fluent::Plugin
327
377
  params = {:resource => "filesystem" }
328
378
  auth_header = create_auth_header("put", datestamp, "#{@azure_container}", headers, params)
329
379
  headers[:Authorization] = auth_header
330
- request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}", :method => :put, :params => params, :headers=> headers)
380
+ req_opts = {
381
+ :method => :put,
382
+ :params => params,
383
+ :headers => headers,
384
+ :timeout => @http_timeout_seconds
385
+ }
386
+ add_proxy_options(req_opts)
387
+ request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}", req_opts)
331
388
  request.on_complete do |response|
332
389
  if response.success?
333
390
  log.debug "azurestorage_gen2: Container '#{@azure_container}' created, response code: #{response.code}"
@@ -347,7 +404,14 @@ module Fluent::Plugin
347
404
  params = {:resource => "file", :recursive => "false"}
348
405
  auth_header = create_auth_header("put", datestamp, "#{@azure_container}#{blob_path}", headers, params)
349
406
  headers[:Authorization] = auth_header
350
- request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}#{blob_path}", :method => :put, :params => params, :headers=> headers)
407
+ req_opts = {
408
+ :method => :put,
409
+ :params => params,
410
+ :headers => headers,
411
+ :timeout => @http_timeout_seconds
412
+ }
413
+ add_proxy_options(req_opts)
414
+ request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}#{blob_path}", req_opts)
351
415
  request.on_complete do |response|
352
416
  if response.success?
353
417
  log.debug "azurestorage_gen2: Blob '#{blob_path}' has been created, response code: #{response.code}"
@@ -370,7 +434,15 @@ module Fluent::Plugin
370
434
  params = {:action => "append", :position => "#{position}"}
371
435
  auth_header = create_auth_header("patch", datestamp, "#{@azure_container}#{blob_path}", headers, params)
372
436
  headers[:Authorization] = auth_header
373
- request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}#{blob_path}", :method => :patch, :headers=> headers, :params => params, :body => content)
437
+ req_opts = {
438
+ :method => :patch,
439
+ :params => params,
440
+ :headers => headers,
441
+ :body => content,
442
+ :timeout => @http_timeout_seconds
443
+ }
444
+ add_proxy_options(req_opts)
445
+ request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}#{blob_path}", req_opts)
374
446
  request.on_complete do |response|
375
447
  if response.success?
376
448
  log.debug "azurestorage_gen2: Blob '#{blob_path}' has been appended, response code: #{response.code}"
@@ -395,7 +467,14 @@ module Fluent::Plugin
395
467
  params = {:action => "flush", :position => "#{position}"}
396
468
  auth_header = create_auth_header("patch", datestamp, "#{@azure_container}#{blob_path}",headers, params)
397
469
  headers[:Authorization] = auth_header
398
- request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}#{blob_path}", :method => :patch, :params => params, :headers=> headers)
470
+ req_opts = {
471
+ :method => :patch,
472
+ :params => params,
473
+ :headers => headers,
474
+ :timeout => @http_timeout_seconds
475
+ }
476
+ add_proxy_options(req_opts)
477
+ request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}#{blob_path}", req_opts)
399
478
  request.on_complete do |response|
400
479
  if response.success?
401
480
  log.debug "azurestorage_gen2: Blob '#{blob_path}' flush was successful, response code: #{response.code}"
@@ -416,7 +495,14 @@ module Fluent::Plugin
416
495
  content_length = -1
417
496
  auth_header = create_auth_header("head", datestamp, "#{@azure_container}#{blob_path}", headers, params)
418
497
  headers[:Authorization] = auth_header
419
- request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}#{blob_path}", :method => :head, :params => params, :headers=> headers)
498
+ req_opts = {
499
+ :method => :head,
500
+ :params => params,
501
+ :headers => headers,
502
+ :timeout => @http_timeout_seconds
503
+ }
504
+ add_proxy_options(req_opts)
505
+ request = Typhoeus::Request.new("https://#{azure_storage_account}#{@url_domain_suffix}/#{@azure_container}#{blob_path}", req_opts)
420
506
  request.on_complete do |response|
421
507
  if response.success?
422
508
  log.debug "azurestorage_gen2: Get blob properties for '#{blob_path}', response headers: #{response.headers}"
@@ -484,6 +570,16 @@ module Fluent::Plugin
484
570
  "SharedKey #{@azure_storage_account}:#{signed(method, datestamp, resource, headers, params)}"
485
571
  end
486
572
  end
573
+
574
+ private
575
+ def add_proxy_options(req_opts = {})
576
+ unless @proxy_url.nil?
577
+ req_opts[:proxy] = @proxy_url
578
+ unless @proxy_username.nil? || @proxy_password.nil?
579
+ req_opts[:proxyuserpwd] = "#{@proxy_username}:#{@proxy_password}"
580
+ end
581
+ end
582
+ end
487
583
 
488
584
  private
489
585
  def signed(method, datestamp, resource, headers, params)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-azurestorage-gen2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.10
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oliver Szabo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-28 00:00:00.000000000 Z
11
+ date: 2021-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -225,8 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
225
  - !ruby/object:Gem::Version
226
226
  version: '0'
227
227
  requirements: []
228
- rubyforge_project:
229
- rubygems_version: 2.5.1
228
+ rubygems_version: 3.1.2
230
229
  signing_key:
231
230
  specification_version: 4
232
231
  summary: Azure Storage output plugin for Fluentd event collector