logstash-output-swift 0.1

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.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +2 -0
  3. data/CONTRIBUTORS +22 -0
  4. data/DEVELOPER.md +15 -0
  5. data/Gemfile +11 -0
  6. data/LICENSE +201 -0
  7. data/NOTICE.TXT +2 -0
  8. data/README.md +38 -0
  9. data/lib/logstash/outputs/swift.rb +360 -0
  10. data/lib/logstash/outputs/swift/file_repository.rb +121 -0
  11. data/lib/logstash/outputs/swift/path_validator.rb +18 -0
  12. data/lib/logstash/outputs/swift/size_and_time_rotation_policy.rb +24 -0
  13. data/lib/logstash/outputs/swift/size_rotation_policy.rb +26 -0
  14. data/lib/logstash/outputs/swift/temporary_file.rb +71 -0
  15. data/lib/logstash/outputs/swift/temporary_file_factory.rb +129 -0
  16. data/lib/logstash/outputs/swift/time_rotation_policy.rb +26 -0
  17. data/lib/logstash/outputs/swift/uploader.rb +64 -0
  18. data/lib/logstash/outputs/swift/writable_directory_validator.rb +17 -0
  19. data/lib/logstash/outputs/swift/write_container_permission_validator.rb +52 -0
  20. data/logstash-output-swift.gemspec +28 -0
  21. data/spec/integration/dynamic_prefix_spec.rb +92 -0
  22. data/spec/integration/gzip_file_spec.rb +62 -0
  23. data/spec/integration/gzip_size_rotation_spec.rb +63 -0
  24. data/spec/integration/restore_from_crash_spec.rb +39 -0
  25. data/spec/integration/size_rotation_spec.rb +59 -0
  26. data/spec/integration/stress_test_spec.rb +60 -0
  27. data/spec/integration/time_based_rotation_with_constant_write_spec.rb +60 -0
  28. data/spec/integration/time_based_rotation_with_stale_write_spec.rb +64 -0
  29. data/spec/integration/upload_current_file_on_shutdown_spec.rb +51 -0
  30. data/spec/outputs/swift/file_repository_spec.rb +143 -0
  31. data/spec/outputs/swift/size_and_time_rotation_policy_spec.rb +77 -0
  32. data/spec/outputs/swift/size_rotation_policy_spec.rb +41 -0
  33. data/spec/outputs/swift/temporary_file_factory_spec.rb +89 -0
  34. data/spec/outputs/swift/temporary_file_spec.rb +47 -0
  35. data/spec/outputs/swift/time_rotation_policy_spec.rb +60 -0
  36. data/spec/outputs/swift/uploader_spec.rb +49 -0
  37. data/spec/outputs/swift/writable_directory_validator_spec.rb +40 -0
  38. data/spec/outputs/swift/write_container_permission_validator_spec.rb +38 -0
  39. data/spec/outputs/swift_spec.rb +76 -0
  40. data/spec/spec_helper.rb +48 -0
  41. data/spec/supports/helpers.rb +38 -0
  42. metadata +212 -0
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/swift/temporary_file"
4
+ require "stud/temporary"
5
+ require "fileutils"
6
+ require "securerandom"
7
+
8
+ describe LogStash::Outputs::Swift::TemporaryFile do
9
+ let(:content) { "hello world" }
10
+ let(:key) { "foo" }
11
+ let(:uuid) { SecureRandom.uuid }
12
+ let(:temporary_file) { ::File.open(::File.join(temporary_directory, uuid, key), "w+") }
13
+ let(:temporary_directory) { Stud::Temporary.directory }
14
+
15
+ before :each do
16
+ FileUtils.mkdir_p(::File.join(temporary_directory, uuid))
17
+ end
18
+
19
+ subject { described_class.new(key, temporary_file, temporary_directory) }
20
+
21
+ it "returns the key of the file" do
22
+ expect(subject.key).to eq(key)
23
+ end
24
+
25
+ it "saves content to a file" do
26
+ subject.write(content)
27
+ subject.close
28
+ expect(File.read(subject.path).strip).to eq(content)
29
+ end
30
+
31
+ it "deletes a file" do
32
+ expect(File.exist?(subject.path)).to be_truthy
33
+ subject.delete!
34
+ expect(File.exist?(subject.path)).to be_falsey
35
+ end
36
+
37
+ it "successfully delete a file already closed" do
38
+ subject.close
39
+ expect(File.exist?(subject.path)).to be_truthy
40
+ subject.delete!
41
+ expect(File.exist?(subject.path)).to be_falsey
42
+ end
43
+
44
+ it "returns the creation time" do
45
+ expect(subject.ctime).to be < Time.now + 0.5
46
+ end
47
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/swift/time_rotation_policy"
4
+ require "logstash/outputs/swift/temporary_file"
5
+
6
+ describe LogStash::Outputs::Swift::TimeRotationPolicy do
7
+ subject { described_class.new(max_time) }
8
+
9
+ let(:max_time) { 1 }
10
+ let(:temporary_directory) { Stud::Temporary.directory }
11
+ let(:temporary_file) { Stud::Temporary.file }
12
+ let(:name) { "foobar" }
13
+ let(:content) { "hello" * 1000 }
14
+ let(:file) { LogStash::Outputs::Swift::TemporaryFile.new(name, temporary_file, temporary_directory) }
15
+
16
+ it "raises an exception if the `file_time` is set to 0" do
17
+ expect { described_class.new(0) }.to raise_error(LogStash::ConfigurationError, /`time_file` need to be greather than 0/)
18
+ end
19
+
20
+ it "raises an exception if the `file_time` is < 0" do
21
+ expect { described_class.new(-100) }.to raise_error(LogStash::ConfigurationError, /`time_file` need to be greather than 0/)
22
+ end
23
+
24
+ context "when the size of the file is superior to 0" do
25
+ before :each do
26
+ file.write(content)
27
+ file.fsync
28
+ end
29
+
30
+ it "returns true if the file old enough" do
31
+ allow(file).to receive(:ctime).and_return(Time.now - (max_time * 2 * 60))
32
+ expect(subject.rotate?(file)).to be_truthy
33
+ end
34
+
35
+ it "returns false is not old enough" do
36
+ expect(subject.rotate?(file)).to be_falsey
37
+ end
38
+ end
39
+
40
+ context "When the size of the file is 0" do
41
+ it "returns false if the file old enough" do
42
+ allow(file).to receive(:ctime).and_return(Time.now - (max_time * 2 * 60))
43
+ expect(subject.rotate?(file)).to be_falsey
44
+ end
45
+
46
+ it "returns false is not old enough" do
47
+ expect(subject.rotate?(file)).to be_falsey
48
+ end
49
+ end
50
+
51
+ context "#needs_periodic?" do
52
+ it "return false" do
53
+ expect(subject.needs_periodic?).to be_truthy
54
+ end
55
+ end
56
+
57
+ it "convert minute into seconds" do
58
+ expect(subject.time_file).to eq(60)
59
+ end
60
+ end
@@ -0,0 +1,49 @@
1
+ # Encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/swift/uploader"
4
+ require "logstash/outputs/swift/temporary_file"
5
+ require "fog/openstack"
6
+ require "stud/temporary"
7
+
8
+ describe LogStash::Outputs::Swift::Uploader do
9
+ let(:logger) { spy(:logger ) }
10
+ let(:max_upload_workers) { 1 }
11
+ let(:bucket_name) { "foobar-bucket" }
12
+
13
+ let(:service) { Fog::Storage::OpenStack.new }
14
+ let(:container) { service.directories.get(bucket_name) }
15
+
16
+ let(:temporary_directory) { Stud::Temporary.pathname }
17
+ let(:temporary_file) { Stud::Temporary.file }
18
+ let(:key) { "foobar" }
19
+ let(:upload_options) { {} }
20
+ let(:threadpool) do
21
+ Concurrent::ThreadPoolExecutor.new({
22
+ :min_threads => 1,
23
+ :max_threads => 8,
24
+ :max_queue => 1,
25
+ :fallback_policy => :caller_runs
26
+ })
27
+ end
28
+
29
+ let(:file) do
30
+ f = LogStash::Outputs::Swift::TemporaryFile.new(key, temporary_file, temporary_directory)
31
+ f.write("random content")
32
+ f.fsync
33
+ f
34
+ end
35
+
36
+ subject { described_class.new(container, logger, threadpool) }
37
+
38
+ it "upload file to the swift container" do
39
+ expect { subject.upload(file) }.not_to raise_error
40
+ end
41
+
42
+ it "execute a callback when the upload is complete" do
43
+ callback = proc { |f| }
44
+
45
+ expect(callback).to receive(:call).with(file)
46
+ subject.upload(file, { :on_complete => callback })
47
+ end
48
+
49
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/swift/writable_directory_validator"
4
+ require "stud/temporary"
5
+
6
+ describe LogStash::Outputs::Swift::WritableDirectoryValidator do
7
+ let(:temporary_directory) { File.join(Stud::Temporary.directory, Time.now.to_i.to_s) }
8
+
9
+ subject { described_class }
10
+
11
+ context "when the directory doesn't exists" do
12
+ it "creates the directory" do
13
+ expect(Dir.exist?(temporary_directory)).to be_falsey
14
+ expect(subject.valid?(temporary_directory)).to be_truthy
15
+ expect(Dir.exist?(temporary_directory)).to be_truthy
16
+ end
17
+ end
18
+
19
+ context "when the directory exist" do
20
+ before do
21
+ FileUtils.mkdir_p(temporary_directory)
22
+ end
23
+
24
+ it "doesn't change the directory" do
25
+ expect(Dir.exist?(temporary_directory)).to be_truthy
26
+ expect(subject.valid?(temporary_directory)).to be_truthy
27
+ expect(Dir.exist?(temporary_directory)).to be_truthy
28
+ end
29
+ end
30
+
31
+ it "return false if the directory is not writable" do
32
+ expect(::File).to receive(:writable?).with(temporary_directory).and_return(false)
33
+ expect(subject.valid?(temporary_directory)).to be_falsey
34
+ end
35
+
36
+ it "return true if the directory is writable" do
37
+ expect(::File).to receive(:writable?).with(temporary_directory).and_return(true)
38
+ expect(subject.valid?(temporary_directory)).to be_truthy
39
+ end
40
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/swift/write_container_permission_validator"
4
+ require "fog/openstack"
5
+
6
+ describe LogStash::Outputs::Swift::WriteContainerPermissionValidator do
7
+ let(:logger) { spy(:logger ) }
8
+ let(:bucket_name) { "foobar" }
9
+ let(:obj) { double("swift_object") }
10
+
11
+ let(:service) { Fog::Storage::OpenStack.new }
12
+ let(:container) { service.directories.get(bucket_name) }
13
+
14
+ let(:upload_options) { {} }
15
+
16
+ subject { described_class.new(logger) }
17
+
18
+ context "when permissions are sufficient" do
19
+ it "returns true" do
20
+ expect(container).to receive_message_chain(:files, :create).with(any_args).and_return(obj)
21
+ expect(obj).to receive(:delete).and_return(true)
22
+ expect(subject.valid?(container)).to be_truthy
23
+ end
24
+
25
+ it "hides delete errors" do
26
+ expect(container).to receive_message_chain(:files, :create).with(any_args).and_return(obj)
27
+ expect(obj).to receive(:delete).and_raise(StandardError)
28
+ expect(subject.valid?(container)).to be_truthy
29
+ end
30
+ end
31
+
32
+ context "when permission aren't sufficient" do
33
+ it "returns false" do
34
+ expect(container).to receive_message_chain(:files, :create).with(any_args).and_raise(StandardError)
35
+ expect(subject.valid?(container)).to be_falsey
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,76 @@
1
+ # encoding: utf-8
2
+ require "logstash/outputs/swift"
3
+ require "logstash/event"
4
+ require "logstash/codecs/line"
5
+ require "stud/temporary"
6
+ require "fog/openstack"
7
+
8
+ describe LogStash::Outputs::Swift do
9
+ let(:prefix) { "super/%{server}" }
10
+ let(:bucket_name) { "mybucket" }
11
+ let(:options) { { "container" => bucket_name,
12
+ "prefix" => prefix,
13
+ "restore" => false,
14
+ "username" => "access_key_id",
15
+ "api_key" => "secret_access_key",
16
+ "auth_url" => "secret_access_key",
17
+ "project_name" => "secret_access_key",
18
+ "domain_name" => "secret_access_key"
19
+ } }
20
+ let(:service) { Fog::Storage::OpenStack.new }
21
+ let(:mock_container) { service.directories.get(bucket_name) }
22
+ let(:event) { LogStash::Event.new({ "server" => "overwatch" }) }
23
+ let(:event_encoded) { "super hype" }
24
+ let(:events_and_encoded) { { event => event_encoded } }
25
+
26
+ subject { described_class.new(options) }
27
+
28
+ before do
29
+ allow(subject).to receive(:container_resource).and_return(mock_container)
30
+ allow_any_instance_of(LogStash::Outputs::Swift::WriteContainerPermissionValidator).to receive(:valid?).with(mock_container).and_return(true)
31
+ end
32
+
33
+ context "#register configuration validation" do
34
+ describe "temporary directory" do
35
+ let(:temporary_directory) { Stud::Temporary.pathname }
36
+ let(:options) { super.merge({ "temporary_directory" => temporary_directory }) }
37
+
38
+ it "creates the directory when it doesn't exist" do
39
+ expect(Dir.exist?(temporary_directory)).to be_falsey
40
+ subject.register
41
+ expect(Dir.exist?(temporary_directory)).to be_truthy
42
+ end
43
+
44
+ it "raises an error if we cannot write to the directory" do
45
+ expect(LogStash::Outputs::Swift::WritableDirectoryValidator).to receive(:valid?).with(temporary_directory).and_return(false)
46
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError)
47
+ end
48
+ end
49
+
50
+ it "validates the prefix" do
51
+ swift = described_class.new(options.merge({ "prefix" => "`no\><^" }))
52
+ expect { swift.register }.to raise_error(LogStash::ConfigurationError)
53
+ end
54
+
55
+ it "allow to not validate credentials" do
56
+ swift = described_class.new(options.merge({"validate_credentials_on_root_bucket" => false}))
57
+ expect_any_instance_of(LogStash::Outputs::Swift::WriteContainerPermissionValidator).not_to receive(:valid?).with(any_args)
58
+ swift.register
59
+ end
60
+ end
61
+
62
+ context "receiving events" do
63
+ before do
64
+ subject.register
65
+ end
66
+
67
+ after do
68
+ subject.close
69
+ end
70
+
71
+ it "uses `Event#sprintf` for the prefix" do
72
+ expect(event).to receive(:sprintf).with(prefix).and_return("super/overwatch")
73
+ subject.multi_receive_encoded(events_and_encoded)
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require_relative "supports/helpers"
4
+ require "logstash/logging/logger"
5
+ require "fog/openstack"
6
+
7
+ LogStash::Logging::Logger::configure_logging("debug") if ENV["DEBUG"]
8
+
9
+ module Fog
10
+ module Storage
11
+ class OpenStack
12
+
13
+ class Mock
14
+
15
+ def put_object(container, object, data, options = {}, &block)
16
+ response = Excon::Response.new
17
+ response.status = 201
18
+ response.body = ""
19
+ response
20
+ end
21
+
22
+ def put_container(name, options = {})
23
+ response = Excon::Response.new
24
+ response.status = 201
25
+ response.body = ""
26
+ response
27
+ end
28
+
29
+ def get_container(container, options = {})
30
+ response = Excon::Response.new
31
+ response.status = 201
32
+ response.body = []
33
+ response
34
+ end
35
+
36
+ def get_containers(options = {})
37
+ response = Excon::Response.new
38
+ response.status = 201
39
+ response.body = []
40
+ response
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+
48
+ Fog.mock!
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ shared_context "setup plugin" do
3
+ let(:temporary_directory) { Stud::Temporary.pathname }
4
+
5
+ let(:bucket) { ENV["AWS_LOGSTASH_TEST_BUCKET"] }
6
+ let(:access_key_id) { ENV["AWS_ACCESS_KEY_ID"] }
7
+ let(:secret_access_key) { ENV["AWS_SECRET_ACCESS_KEY"] }
8
+ let(:size_file) { 100 }
9
+ let(:time_file) { 100 }
10
+ let(:tags) { [] }
11
+ let(:prefix) { "home" }
12
+ let(:region) { ENV['AWS_REGION'] }
13
+
14
+ let(:main_options) do
15
+ {
16
+ "bucket" => bucket,
17
+ "prefix" => prefix,
18
+ "temporary_directory" => temporary_directory,
19
+ "access_key_id" => access_key_id,
20
+ "secret_access_key" => secret_access_key,
21
+ "size_file" => size_file,
22
+ "time_file" => time_file,
23
+ "region" => region,
24
+ "tags" => []
25
+ }
26
+ end
27
+
28
+ let(:client_credentials) { Aws::Credentials.new(access_key_id, secret_access_key) }
29
+ let(:bucket_resource) { Aws::S3::Bucket.new(bucket, { :credentials => client_credentials, :region => region }) }
30
+
31
+ subject { LogStash::Outputs::S3.new(options) }
32
+ end
33
+
34
+ def clean_remote_files(prefix = "")
35
+ bucket_resource.objects(:prefix => prefix).each do |object|
36
+ object.delete
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,212 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-output-swift
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - kakoni
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-12-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: logstash-core-plugin-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.60'
20
+ - - "<="
21
+ - !ruby/object:Gem::Version
22
+ version: '2.99'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1.60'
30
+ - - "<="
31
+ - !ruby/object:Gem::Version
32
+ version: '2.99'
33
+ - !ruby/object:Gem::Dependency
34
+ name: fog-openstack
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: concurrent-ruby
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: stud
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.0.22
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.0.22
75
+ - !ruby/object:Gem::Dependency
76
+ name: logstash-devutils
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: logstash-input-generator
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: logstash-codec-line
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ description: This gem is a Logstash plugin required to be installed on top of the
118
+ Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This
119
+ gem is not a stand-alone program
120
+ email: kakoni@gmail.com
121
+ executables: []
122
+ extensions: []
123
+ extra_rdoc_files: []
124
+ files:
125
+ - CHANGELOG.md
126
+ - CONTRIBUTORS
127
+ - DEVELOPER.md
128
+ - Gemfile
129
+ - LICENSE
130
+ - NOTICE.TXT
131
+ - README.md
132
+ - lib/logstash/outputs/swift.rb
133
+ - lib/logstash/outputs/swift/file_repository.rb
134
+ - lib/logstash/outputs/swift/path_validator.rb
135
+ - lib/logstash/outputs/swift/size_and_time_rotation_policy.rb
136
+ - lib/logstash/outputs/swift/size_rotation_policy.rb
137
+ - lib/logstash/outputs/swift/temporary_file.rb
138
+ - lib/logstash/outputs/swift/temporary_file_factory.rb
139
+ - lib/logstash/outputs/swift/time_rotation_policy.rb
140
+ - lib/logstash/outputs/swift/uploader.rb
141
+ - lib/logstash/outputs/swift/writable_directory_validator.rb
142
+ - lib/logstash/outputs/swift/write_container_permission_validator.rb
143
+ - logstash-output-swift.gemspec
144
+ - spec/integration/dynamic_prefix_spec.rb
145
+ - spec/integration/gzip_file_spec.rb
146
+ - spec/integration/gzip_size_rotation_spec.rb
147
+ - spec/integration/restore_from_crash_spec.rb
148
+ - spec/integration/size_rotation_spec.rb
149
+ - spec/integration/stress_test_spec.rb
150
+ - spec/integration/time_based_rotation_with_constant_write_spec.rb
151
+ - spec/integration/time_based_rotation_with_stale_write_spec.rb
152
+ - spec/integration/upload_current_file_on_shutdown_spec.rb
153
+ - spec/outputs/swift/file_repository_spec.rb
154
+ - spec/outputs/swift/size_and_time_rotation_policy_spec.rb
155
+ - spec/outputs/swift/size_rotation_policy_spec.rb
156
+ - spec/outputs/swift/temporary_file_factory_spec.rb
157
+ - spec/outputs/swift/temporary_file_spec.rb
158
+ - spec/outputs/swift/time_rotation_policy_spec.rb
159
+ - spec/outputs/swift/uploader_spec.rb
160
+ - spec/outputs/swift/writable_directory_validator_spec.rb
161
+ - spec/outputs/swift/write_container_permission_validator_spec.rb
162
+ - spec/outputs/swift_spec.rb
163
+ - spec/spec_helper.rb
164
+ - spec/supports/helpers.rb
165
+ homepage:
166
+ licenses:
167
+ - Apache-2.0
168
+ metadata:
169
+ logstash_plugin: 'true'
170
+ logstash_group: output
171
+ post_install_message:
172
+ rdoc_options: []
173
+ require_paths:
174
+ - lib
175
+ required_ruby_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ required_rubygems_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ requirements: []
186
+ rubyforge_project:
187
+ rubygems_version: 2.6.13
188
+ signing_key:
189
+ specification_version: 4
190
+ summary: Sends Logstash events to the Openstack Swift Service
191
+ test_files:
192
+ - spec/integration/dynamic_prefix_spec.rb
193
+ - spec/integration/gzip_file_spec.rb
194
+ - spec/integration/gzip_size_rotation_spec.rb
195
+ - spec/integration/restore_from_crash_spec.rb
196
+ - spec/integration/size_rotation_spec.rb
197
+ - spec/integration/stress_test_spec.rb
198
+ - spec/integration/time_based_rotation_with_constant_write_spec.rb
199
+ - spec/integration/time_based_rotation_with_stale_write_spec.rb
200
+ - spec/integration/upload_current_file_on_shutdown_spec.rb
201
+ - spec/outputs/swift/file_repository_spec.rb
202
+ - spec/outputs/swift/size_and_time_rotation_policy_spec.rb
203
+ - spec/outputs/swift/size_rotation_policy_spec.rb
204
+ - spec/outputs/swift/temporary_file_factory_spec.rb
205
+ - spec/outputs/swift/temporary_file_spec.rb
206
+ - spec/outputs/swift/time_rotation_policy_spec.rb
207
+ - spec/outputs/swift/uploader_spec.rb
208
+ - spec/outputs/swift/writable_directory_validator_spec.rb
209
+ - spec/outputs/swift/write_container_permission_validator_spec.rb
210
+ - spec/outputs/swift_spec.rb
211
+ - spec/spec_helper.rb
212
+ - spec/supports/helpers.rb