clusterfsck 0.1.5.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.
Files changed (38) hide show
  1. data/.gitignore +19 -0
  2. data/.rspec +2 -0
  3. data/.rvmrc +1 -0
  4. data/Gemfile +12 -0
  5. data/Guardfile +24 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +121 -0
  8. data/Rakefile +10 -0
  9. data/bin/clusterfsck +60 -0
  10. data/clusterfsck.gemspec +34 -0
  11. data/lib/clusterfsck.rb +48 -0
  12. data/lib/clusterfsck/cli.rb +8 -0
  13. data/lib/clusterfsck/commands/cluster_fsck_env_argument_parser.rb +21 -0
  14. data/lib/clusterfsck/commands/create.rb +20 -0
  15. data/lib/clusterfsck/commands/edit.rb +30 -0
  16. data/lib/clusterfsck/commands/environments.rb +14 -0
  17. data/lib/clusterfsck/commands/list.rb +20 -0
  18. data/lib/clusterfsck/commands/override.rb +27 -0
  19. data/lib/clusterfsck/commands/setup.rb +11 -0
  20. data/lib/clusterfsck/configuration.rb +13 -0
  21. data/lib/clusterfsck/credential_grabber.rb +53 -0
  22. data/lib/clusterfsck/reader.rb +56 -0
  23. data/lib/clusterfsck/s3_methods.rb +52 -0
  24. data/lib/clusterfsck/setup.rb +51 -0
  25. data/lib/clusterfsck/version.rb +3 -0
  26. data/lib/clusterfsck/writer.rb +30 -0
  27. data/spec/lib/clusterfsck/commands/amicus_env_argument_parser_spec.rb +26 -0
  28. data/spec/lib/clusterfsck/commands/create_spec.rb +41 -0
  29. data/spec/lib/clusterfsck/commands/edit_spec.rb +49 -0
  30. data/spec/lib/clusterfsck/commands/override_spec.rb +26 -0
  31. data/spec/lib/clusterfsck/configuration_spec.rb +25 -0
  32. data/spec/lib/clusterfsck/credential_grabber_spec.rb +100 -0
  33. data/spec/lib/clusterfsck/reader_spec.rb +60 -0
  34. data/spec/lib/clusterfsck/s3_methods_spec.rb +39 -0
  35. data/spec/lib/clusterfsck/writer_spec.rb +84 -0
  36. data/spec/spec_helper.rb +24 -0
  37. data/spec/support/cluster_fsck_env_setter.rb +11 -0
  38. metadata +177 -0
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'commander'
3
+ require 'clusterfsck/cli'
4
+
5
+ module ClusterFsck::Commands
6
+ describe Override do
7
+ let(:mock_reader) do
8
+ mock("reader",
9
+ read: "contents",
10
+ local_override_path: "/path/to/nowhere",
11
+ full_s3_path: "test/test-key"
12
+ )
13
+ end
14
+ let(:args) { ["test-key"] }
15
+
16
+ before do
17
+ ClusterFsck::Reader.should_receive(:new).with(args.first, cluster_fsck_env: 'test').and_return(mock_reader)
18
+ end
19
+
20
+ it "should read the remote contents and write the local contents" do
21
+ FileUtils.should_receive(:mkdir_p).with(File.dirname(mock_reader.local_override_path))
22
+ File.should_receive(:open).with(mock_reader.local_override_path, "w")
23
+ subject.run_command(args)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ module ClusterFsck
4
+ describe Configuration do
5
+
6
+ it "should be a mash" do
7
+ Configuration.new.should be_a(Hashie::Mash)
8
+ end
9
+
10
+ it "should load from yaml" do
11
+ yaml = YAML.dump({foo: 'bar'})
12
+ Configuration.from_yaml(yaml)[:foo].should == 'bar'
13
+ end
14
+
15
+ # TODO (topper): this isn't explicitly testing the right thing
16
+ # but it does *actually* test the right thing
17
+ it "should dump to yaml" do
18
+ hsh = {'foo' => 'bar'}
19
+ Configuration.new(hsh).to_yaml.should == YAML.dump(hsh)
20
+ end
21
+
22
+ end
23
+
24
+
25
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ module ClusterFsck
4
+
5
+ describe CredentialGrabber do
6
+ let(:credential_grabber) { CredentialGrabber.new }
7
+
8
+ before do
9
+ credential_grabber.stub(:exists?).and_return(false)
10
+ end
11
+
12
+ it "should have a singleton find" do
13
+ fake_credential_grabber = mock(:credential_grabber)
14
+ fake_credential_grabber.should_receive(:find).and_return nil
15
+ CredentialGrabber.should_receive(:new).and_return(fake_credential_grabber)
16
+ CredentialGrabber.find
17
+ end
18
+
19
+ let(:cf_credentials) do
20
+ {
21
+ access_key_id: 'cf_access_key',
22
+ secret_access_key: 'cf_secret_key'
23
+ }
24
+ end
25
+
26
+ let(:env_credentials) do
27
+ {
28
+ access_key_id: 'env_access_key',
29
+ secret_access_key: 'env_secret_key'
30
+ }
31
+ end
32
+
33
+ let(:fog_credentials) do
34
+ {
35
+ default: {
36
+ aws_access_key_id: 'fog_access_key',
37
+ aws_secret_access_key: 'fog_secret_key'
38
+ }
39
+ }
40
+ end
41
+
42
+ describe "when there is a ~/.fog file but no ~/.clusterfsck" do
43
+ before do
44
+ File.stub(:expand_path).with(CredentialGrabber::FOG_PATH).and_return(CredentialGrabber::FOG_PATH)
45
+ credential_grabber.should_receive(:exists?).with(CredentialGrabber::FOG_PATH).and_return(true)
46
+ YAML.should_receive(:load_file).with(CredentialGrabber::FOG_PATH).and_return(fog_credentials)
47
+ end
48
+
49
+ it "should return the credentials" do
50
+ credential_grabber.find.should == {
51
+ access_key_id: 'fog_access_key',
52
+ secret_access_key: 'fog_secret_key',
53
+ }
54
+ end
55
+ end
56
+
57
+ describe "when there is a ~/.clusterfsck config and with or without a ~/.fog file" do
58
+ before do
59
+ credential_grabber.stub(:exists?).with(true)
60
+ ClusterFsck::CLUSTER_FSCK_CONFIG.should_receive(:[]).at_least(:once)
61
+ .with('aws_access_key_id').and_return(cf_credentials[:access_key_id])
62
+ ClusterFsck::CLUSTER_FSCK_CONFIG.should_receive(:[]).at_least(:once)
63
+ .with('aws_secret_access_key').and_return(cf_credentials[:secret_access_key])
64
+ end
65
+
66
+ it "should return the clusterfsck credentials" do
67
+ credential_grabber.find.should == cf_credentials
68
+ end
69
+ it "should return the credentials" do
70
+ credential_grabber.find.should == cf_credentials
71
+ end
72
+ end
73
+
74
+ describe "when there is both ENV vars and a ~/.fog file" do
75
+ before :each do
76
+ ENV.stub(:[]).with("AWS_ACCESS_KEY_ID").and_return(env_credentials[:access_key_id])
77
+ ENV.stub(:[]).with("AWS_SECRET_ACCESS_KEY").and_return(env_credentials[:secret_access_key])
78
+ File.stub(:expand_path).with(CredentialGrabber::FOG_PATH).and_return(CredentialGrabber::FOG_PATH)
79
+ end
80
+
81
+ it "should return the clusterfsck credentials" do
82
+ credential_grabber.find.should == env_credentials
83
+ end
84
+
85
+ it "should not look at expand_path because it short circuits first" do
86
+ credential_grabber.find
87
+ YAML.should_not_receive(:load_file)
88
+ end
89
+ end
90
+
91
+ describe "when there are no credential files" do
92
+
93
+ it "should return nil" do
94
+ credential_grabber.find.should be_nil
95
+ end
96
+
97
+ end
98
+
99
+ end
100
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ module ClusterFsck
4
+
5
+ describe Reader do
6
+ let(:cluster_fsck_env) { 'test' }
7
+ let(:key) { "test-key" }
8
+ let(:reader) { Reader.new(key) }
9
+ let(:mock_s3_obj) { mock(:s3_object, read: nil, :exists? => true) }
10
+
11
+
12
+ it "should set cluster_fsck_env" do
13
+ reader.cluster_fsck_env.should == cluster_fsck_env
14
+ end
15
+
16
+ describe "when there is a local override" do
17
+ let(:local_yaml) { YAML.dump(foo: true) }
18
+ let(:local_path) { "clusterfsck/#{cluster_fsck_env}/#{key}" }
19
+
20
+ before do
21
+ reader.send(:stored_object).should_not_receive(:exists?) #shouldn't even check for existence on the network
22
+ File.should_receive(:exists?).at_least(1).times.with(local_path).and_return(true)
23
+ File.stub(:read).with(local_path).and_return(local_yaml)
24
+ end
25
+
26
+ it "should #has_local_override?" do
27
+ reader.has_local_override?.should be_true
28
+ end
29
+
30
+ it "should use the local override when it exists" do
31
+ reader.read.should == Configuration.from_yaml(local_yaml)
32
+ end
33
+ end
34
+
35
+ describe "#read" do
36
+ let(:version_count) { 3 }
37
+
38
+ before do
39
+ mock_s3_obj.stub({
40
+ read: YAML.dump({
41
+ foo: 'bar'
42
+ }),
43
+ versions: mock('versions', count: version_count)
44
+ })
45
+ reader.stub(:s3_object).with(key).and_return(mock_s3_obj)
46
+ reader.stub(:s3_object).with(key.to_sym).and_return(mock_s3_obj)
47
+ end
48
+
49
+ it "should load the remote file and yaml parse it" do
50
+ reader.read['foo'].should == 'bar'
51
+ end
52
+
53
+ it "should set the version count" do
54
+ reader.read
55
+ reader.version_count.should == version_count
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ module ClusterFsck
4
+ class DummyClass
5
+ include S3Methods
6
+
7
+ def cluster_fsck_env
8
+ "test"
9
+ end
10
+ end
11
+
12
+ describe S3Methods do
13
+ let(:cluster_fsck_env) { 'test' }
14
+ let(:config_bucket) { ClusterFsck.config_bucket }
15
+ let(:key) { 'test_key' }
16
+ let(:dummy_instance) { DummyClass.new }
17
+
18
+ let(:mock_listing) { mock('obj', key: "#{cluster_fsck_env}/#{key}") }
19
+ let(:bucket_objects) { mock('bucket_objects', with_prefix: [mock_listing]) }
20
+ let(:mock_bucket) { mock(:bucket, objects: bucket_objects) }
21
+
22
+ before do
23
+ DummyClass.any_instance.stub(:bucket).and_return(mock_bucket)
24
+ end
25
+
26
+ it "should qualify the keys it gets with the namespace" do
27
+ mock_bucket.stub(:objects) { { key => 'fail',
28
+ "#{cluster_fsck_env}/#{key}" => 'pass'} }
29
+ dummy_instance.stub(:bucket) { mock_bucket }
30
+ dummy_instance.s3_object(key).should == 'pass'
31
+ end
32
+
33
+ it "should enumerate all files with the prefix" do
34
+ bucket_objects.should_receive(:with_prefix).with(cluster_fsck_env).and_return([mock_listing])
35
+ dummy_instance.all_files.should == [mock_listing.key]
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ module ClusterFsck
4
+
5
+ describe Writer do
6
+ let(:cluster_fsck_env) { 'development' }
7
+ let(:key) { 'tester' }
8
+ let(:reader) { Reader.new(key) }
9
+ let(:mock_s3_obj) { mock(:s3_object, read: nil) }
10
+ let(:writer) { Writer.new(key) }
11
+ let(:initial_version_count) { 3 }
12
+
13
+ before do
14
+ mock_s3_obj.stub(
15
+ read: YAML.dump({
16
+ foo: 'bar',
17
+ deep: {
18
+ works: 'too',
19
+ even: 'here'
20
+ }
21
+ }),
22
+ versions: mock('versions', count: initial_version_count),
23
+ :exists? => true
24
+ )
25
+ Reader.any_instance.stub(:s3_object).with("#{key}").and_return(mock_s3_obj)
26
+ writer.stub(:s3_object).and_return(mock_s3_obj)
27
+ end
28
+
29
+ describe "#set" do
30
+ it "should write the configuration to the file" do
31
+ writer.should_receive(:s3_object).with(key).and_return(mock_s3_obj)
32
+
33
+ mock_s3_obj.should_receive(:write).with(YAML.dump({
34
+ 'deep' => {
35
+ 'even' => 'changed'
36
+ }
37
+ }))
38
+
39
+ do_write
40
+ end
41
+
42
+ describe "with version counts" do
43
+
44
+ it "should work normally when nothing has changed underneath" do
45
+ mock_write
46
+ mock_s3_obj.versions.stub(:count).and_return(initial_version_count, (initial_version_count + 1))
47
+
48
+ do_write
49
+ end
50
+
51
+ it "should raise an error and not write when it has changed before the set" do
52
+ mock_s3_obj.should_not_receive(:write)
53
+ mock_s3_obj.versions.stub(:count).and_return(initial_version_count + 1)
54
+
55
+ ->() { do_write }.should raise_error(ClusterFsck::S3Methods::ConflictError)
56
+ end
57
+
58
+ it "should raise an error if the version count has hopped AFTER our write" do
59
+ mock_write
60
+ mock_s3_obj.versions.stub(:count).and_return(initial_version_count, (initial_version_count + 2))
61
+
62
+ ->() { do_write }.should raise_error(ClusterFsck::S3Methods::ConflictError)
63
+ end
64
+
65
+ def mock_write
66
+ mock_s3_obj.should_receive(:write).with(YAML.dump({
67
+ 'deep' => {
68
+ 'even' => 'changed'
69
+ }
70
+ }))
71
+ end
72
+ end
73
+
74
+ def do_write
75
+ writer.set(Configuration.new({
76
+ deep: {
77
+ even: 'changed'
78
+ }
79
+ }), initial_version_count)
80
+ end
81
+
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ Dir["spec/support/**/*.rb"].each {|f| require File.expand_path(f)}
3
+
4
+ require 'pry'
5
+ require 'clusterfsck'
6
+
7
+
8
+ # This file was generated by the `rspec --init` command. Conventionally, all
9
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
10
+ # Require this file using `require "spec_helper"` to ensure that it is only
11
+ # loaded once.
12
+ #
13
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
14
+ RSpec.configure do |config|
15
+ config.treat_symbols_as_metadata_keys_with_true_values = true
16
+ config.run_all_when_everything_filtered = true
17
+ config.filter_run :focus
18
+
19
+ # Run specs in random order to surface order dependencies. If you find an
20
+ # order dependency and want to debug it, you can fix the order by providing
21
+ # the seed, which is printed after each run.
22
+ # --seed 1234
23
+ config.order = 'random'
24
+ end
@@ -0,0 +1,11 @@
1
+ RSpec.configure do |config|
2
+ config.before(:suite) do
3
+ ENV['CLUSTER_FSCK_ENV'] = 'test'
4
+ #redefine constant warning when setting ClusterFsck::CLUSTER_FSCK_ENV constant here
5
+ def ClusterFsck.cluster_fsck_env
6
+ 'test'
7
+ end
8
+ ENV['CLUSTER_FSCK_BUCKET'] = 'test'
9
+ ClusterFsck::CLUSTER_FSCK_BUCKET = 'test'
10
+ end
11
+ end
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: clusterfsck
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Topper Bowers, Brian Glusman
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: aws-sdk
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.8.1.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.8.1.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: hashie
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: random-word
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
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
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: commander
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 4.1.0
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 4.1.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: cluster-aware S3 based config getter/setter
95
+ email:
96
+ - topper@amicushq.com, brian@amicushq.com
97
+ executables:
98
+ - clusterfsck
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - .gitignore
103
+ - .rspec
104
+ - .rvmrc
105
+ - Gemfile
106
+ - Guardfile
107
+ - LICENSE.txt
108
+ - README.md
109
+ - Rakefile
110
+ - bin/clusterfsck
111
+ - clusterfsck.gemspec
112
+ - lib/clusterfsck.rb
113
+ - lib/clusterfsck/cli.rb
114
+ - lib/clusterfsck/commands/cluster_fsck_env_argument_parser.rb
115
+ - lib/clusterfsck/commands/create.rb
116
+ - lib/clusterfsck/commands/edit.rb
117
+ - lib/clusterfsck/commands/environments.rb
118
+ - lib/clusterfsck/commands/list.rb
119
+ - lib/clusterfsck/commands/override.rb
120
+ - lib/clusterfsck/commands/setup.rb
121
+ - lib/clusterfsck/configuration.rb
122
+ - lib/clusterfsck/credential_grabber.rb
123
+ - lib/clusterfsck/reader.rb
124
+ - lib/clusterfsck/s3_methods.rb
125
+ - lib/clusterfsck/setup.rb
126
+ - lib/clusterfsck/version.rb
127
+ - lib/clusterfsck/writer.rb
128
+ - spec/lib/clusterfsck/commands/amicus_env_argument_parser_spec.rb
129
+ - spec/lib/clusterfsck/commands/create_spec.rb
130
+ - spec/lib/clusterfsck/commands/edit_spec.rb
131
+ - spec/lib/clusterfsck/commands/override_spec.rb
132
+ - spec/lib/clusterfsck/configuration_spec.rb
133
+ - spec/lib/clusterfsck/credential_grabber_spec.rb
134
+ - spec/lib/clusterfsck/reader_spec.rb
135
+ - spec/lib/clusterfsck/s3_methods_spec.rb
136
+ - spec/lib/clusterfsck/writer_spec.rb
137
+ - spec/spec_helper.rb
138
+ - spec/support/cluster_fsck_env_setter.rb
139
+ homepage: http://github.com/amicus/clusterfsck
140
+ licenses: []
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ! '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - ! '>='
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubyforge_project:
159
+ rubygems_version: 1.8.24
160
+ signing_key:
161
+ specification_version: 3
162
+ summary: ClusterFsck manages configurable settings and sensitive login information
163
+ across any number of separate or related projects by reading writing simple values
164
+ or arrays/hashes of data to and from YAML files stored on Amazon S3. It also allows
165
+ centrally overriding or changing these on a per environment basis.
166
+ test_files:
167
+ - spec/lib/clusterfsck/commands/amicus_env_argument_parser_spec.rb
168
+ - spec/lib/clusterfsck/commands/create_spec.rb
169
+ - spec/lib/clusterfsck/commands/edit_spec.rb
170
+ - spec/lib/clusterfsck/commands/override_spec.rb
171
+ - spec/lib/clusterfsck/configuration_spec.rb
172
+ - spec/lib/clusterfsck/credential_grabber_spec.rb
173
+ - spec/lib/clusterfsck/reader_spec.rb
174
+ - spec/lib/clusterfsck/s3_methods_spec.rb
175
+ - spec/lib/clusterfsck/writer_spec.rb
176
+ - spec/spec_helper.rb
177
+ - spec/support/cluster_fsck_env_setter.rb