openbanana 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Lookout, Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # Open Banana
2
+
3
+ [![Build Status](https://buildhive.cloudbees.com/job/lookout/job/openbanana/badge/icon)](https://buildhive.cloudbees.com/job/lookout/job/openbanana/)
4
+
5
+ Openbanana is a gem that, currently, provides a `db:grant` rake task for Rails
6
+ projects.
7
+
8
+ What this `db:grant` task does is creates the database and sets up the initial grants for the database
9
+ configured in the `config/database.yml` file
10
+
11
+ To use Openbanana, include it in your `Rakefile`:
12
+
13
+ require 'openbanana/tasks'
14
+
15
+ And in your `Gemfile`:
16
+
17
+ gem "openbanana", "~> 0.2"
18
+
19
+
20
+ Make sure you have a source for either `maestro` or `dogwood` in your Gemfile.```
21
+
22
+ ### Environment variables
23
+
24
+ * `DB_USER` overrides the default user (root) to grant privileges
25
+ * `DB_PASSWORD` overrides the default password (*empty*) to grant privileges
26
+ * `DB_HOST` overrides the hostname for the database server (defaults to
27
+ *localhost*)
28
+
29
+
30
+ For sharded configurations using a shards.yml file (such as using the octopus gem,
31
+ see https://github.com/tchandy/octopus) or with extra sharded entries in database.yml
32
+ (named *production* or *development*, etc.; such as using the data_fabric gem,
33
+ see https://github.com/bpot/data_fabric), adds a `db:grant_shards` task to create
34
+ and grant for a set of shard databases.
35
+
36
+ An example shard.yml looks like:
37
+
38
+ octopus:
39
+ ...
40
+ production:
41
+ ungrouped_shard:
42
+ adapter: mysql2
43
+ database: foo
44
+ .... also specify username, password, host, etc.
45
+ shard_group:
46
+ shard1:
47
+ database: bar_1
48
+ ....
49
+ shard2:
50
+ database: bar_2
51
+ ....
52
+ ...
53
+
54
+ or entries in database.yml that look like:
55
+
56
+ ...
57
+ shard_1_production:
58
+ adapter: mysql2
59
+ database: foo_prod_s1
60
+ .. etc.
61
+ shard_2_production:
62
+ ...
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:test)
6
+
7
+
8
+ task :default => [:test, :build]
data/lib/openbanana.rb ADDED
@@ -0,0 +1,101 @@
1
+ require "openbanana/version"
2
+ require 'rake'
3
+
4
+ module Openbanana
5
+ extend Rake::DSL
6
+
7
+ # Defining this just to make stubbing in rspec easier
8
+ def self.env
9
+ ENV
10
+ end
11
+
12
+ # load config YML file
13
+ def self.load_yml(filename = 'database.yml')
14
+ YAML.load_file(File.join(Rails.root, 'config', filename))
15
+ end
16
+
17
+ # read config YML for environment
18
+ def self.config
19
+ config = Openbanana.load_yml
20
+ return config[Rails.env]
21
+ end
22
+
23
+ # read config for sharded case using octopus shards.yml
24
+ def self.shard_config
25
+ config = Openbanana.load_yml('shards.yml')
26
+ config = config['octopus'] if config.keys == ['octopus']
27
+ config = config[Rails.env]
28
+ config = config['shards'] if config.keys == ['shards']
29
+ return config
30
+ rescue Errno::ENOENT => e
31
+ puts 'No shards.yml, using shards in database.yml'
32
+ config = Openbanana.load_yml
33
+ return Hash[config.select {|k,v| k.include?(Rails.env) && k != Rails.env}]
34
+ end
35
+
36
+ # generate SQL statements for DB creation, permission grant
37
+ def self.grant_for(config)
38
+ grants = []
39
+
40
+ unless config['database']
41
+ return nil
42
+ end
43
+
44
+ grants << "CREATE DATABASE #{config['database']};"
45
+
46
+ if config['username']
47
+ identify_by = ''
48
+ if config['password']
49
+ identify_by = "IDENTIFIED BY '#{config['password']}'"
50
+ end
51
+
52
+ unless config['networks']
53
+ grants << "GRANT ALL PRIVILEGES ON #{config['database']}.* TO '#{config['username']}'@'%' #{identify_by};"
54
+ else
55
+ config['networks'].each do |network|
56
+ grants << "GRANT ALL PRIVILEGES ON #{config['database']}.* TO '#{config['username']}'@'#{network}' #{identify_by};"
57
+ end
58
+ end
59
+ end
60
+
61
+ return grants
62
+ end
63
+
64
+ # run block on all contained hashes which have the key 'database'
65
+ def self.traverse(obj, &block)
66
+ case obj
67
+ when Hash
68
+ if obj['database']
69
+ block.call(obj)
70
+ else
71
+ obj.each {|k,v| traverse(v, &block)}
72
+ end
73
+ when Array
74
+ obj.each {|v| traverse(v, &block)}
75
+ end
76
+ end
77
+
78
+ # generate grants
79
+ def self.grants(args = {})
80
+ config = args[:sharded] ? Openbanana.shard_config : Openbanana.config
81
+ grants = []
82
+ Openbanana.traverse(config) do |leaf_config|
83
+ grants += Openbanana.grant_for(leaf_config)
84
+ end
85
+ return grants
86
+ end
87
+
88
+ # run task (here for DRY-ness)
89
+ def self.grants_task(args = {})
90
+ username = ENV['DB_USER'] || 'root'
91
+ password = ENV['DB_PASSWORD'] || ''
92
+ host = nil
93
+ if ENV['DB_HOST']
94
+ host = "--host=#{ENV['DB_HOST']}"
95
+ end
96
+
97
+ Openbanana.grants(args).each do |grant|
98
+ sh "mysql #{host} --user=#{username} --password=\"#{password}\" -e \"#{grant}\" || true"
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ require 'openbanan'
5
+
6
+ namespace :db do
7
+ desc "Set up the appropriate user grants for this project based on config/database.yml"
8
+ task :grant do
9
+ Openbanana.grants_task
10
+ end
11
+
12
+ desc "Set up the appropriate user grants for this project based on config/shards.yml and shards in config/database.yml"
13
+ task :grant_shards do
14
+ Openbanana.grants_task(:sharded => true)
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ module Openbanana
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/openbanana/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["R. Tyler Croy"]
6
+ gem.email = ["tyler@monkeypox.org"]
7
+ gem.description = %q{Simple gem to handle creating DB grans}
8
+ gem.summary = %q{Simple gem to handle creating DB grans}
9
+ gem.homepage = "https://github.com/lookout/openbanana"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "openbanana"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Openbanana::VERSION
17
+
18
+ gem.add_development_dependency 'rake'
19
+ gem.add_development_dependency 'rspec'
20
+ end
@@ -0,0 +1,17 @@
1
+ require "rake"
2
+
3
+ shared_context "rake" do
4
+ let(:rake) { Rake::Application.new }
5
+ let(:task_name) { self.class.top_level_description }
6
+ let(:task_path) { File.expand_path("./lib/openbanana/tasks/#{task_name.split(":").first}.rake") }
7
+ subject { rake[task_name] }
8
+
9
+ before do
10
+ Rake.application = rake
11
+ Rake.application.rake_require(File.expand_path('./lib/openbanana/tasks'))
12
+ Rake::Task.define_task(:environment)
13
+ end
14
+ end
15
+
16
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
17
+ require 'openbanana'
@@ -0,0 +1,131 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe 'db:grant' do
5
+ end
6
+
7
+ describe Openbanana do
8
+ before :each do
9
+ Rails = double('rails')
10
+ Rails.stub(:root).and_return('dummy_root')
11
+ end
12
+
13
+ describe '#load_yml' do
14
+ it 'should load the database.yml file on Rails.root/config' do
15
+ YAML.should_receive(:load_file).with(Rails.root + '/config/database.yml').and_return({})
16
+ Openbanana.load_yml
17
+ end
18
+
19
+ it 'should load the shards.yml file on Rails.root/config' do
20
+ YAML.should_receive(:load_file).with(Rails.root + '/config/shards.yml').and_return({})
21
+ Openbanana.load_yml('shards.yml')
22
+ end
23
+ end
24
+
25
+ describe '#config' do
26
+ let(:config) do
27
+ { 'database' => 'test_db',
28
+ 'username' => 'test_user',
29
+ 'password' => 'test_password'}
30
+ end
31
+
32
+ context 'with development configuration' do
33
+ before :each do
34
+ Openbanana.should_receive(:load_yml).and_return({'development' => config})
35
+ Rails.stub(:env).and_return('development')
36
+ end
37
+
38
+ it 'should return the proper configuration for this environment' do
39
+ result = Openbanana.config
40
+ result.should == config
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#shard_config' do
46
+ let(:config) do
47
+ { 'database' => 'test_db',
48
+ 'username' => 'test_user',
49
+ 'password' => 'test_password'}
50
+ end
51
+
52
+ context 'with development configuration' do
53
+ before :each do
54
+ Openbanana.should_receive(:load_yml).and_return({'octopus' => {'development' => {'shards' => config}}})
55
+ Rails.stub(:env).and_return('development')
56
+ end
57
+
58
+ it 'should return the proper configuration for this environment' do
59
+ result = Openbanana.shard_config
60
+ result.should == config
61
+ end
62
+ end
63
+ end
64
+
65
+ describe '#grants' do
66
+ before :each do
67
+ Openbanana.should_receive(:config).and_return(config)
68
+ end
69
+
70
+ context 'in production' do
71
+ describe 'with networks' do
72
+ let(:config) do
73
+ { 'database' => 'test_db',
74
+ 'username' => 'test_user',
75
+ 'password' => 'test_password',
76
+ 'networks' => ['127.0.0.0/24']}
77
+ end
78
+
79
+ it 'should have networks' do
80
+ result = Openbanana.grants
81
+ result.should include("GRANT ALL PRIVILEGES ON test_db.* TO 'test_user'@'127.0.0.0/24' IDENTIFIED BY 'test_password';")
82
+ end
83
+ end
84
+ end
85
+
86
+ context 'on shards' do
87
+ describe 'with multiple shards' do
88
+ let(:config) do
89
+ {
90
+ 'shard1' => {
91
+ 'database' => 'test_db1',
92
+ 'username' => 'test_user',
93
+ 'password' => 'test_password'
94
+ },
95
+ 'shard2' => {
96
+ 'database' => 'test_db2',
97
+ 'username' => 'test_user',
98
+ 'password' => 'test_password'
99
+ }
100
+ }
101
+ end
102
+
103
+ it 'should have both shards' do
104
+ result = Openbanana.grants
105
+ result.should include("GRANT ALL PRIVILEGES ON test_db1.* TO 'test_user'@'%' IDENTIFIED BY 'test_password';")
106
+ result.should include("GRANT ALL PRIVILEGES ON test_db2.* TO 'test_user'@'%' IDENTIFIED BY 'test_password';")
107
+ end
108
+ end
109
+ end
110
+
111
+ context 'grants should' do
112
+ let(:config) do
113
+ { 'database' => 'test_db',
114
+ 'username' => 'test_user',
115
+ 'password' => 'test_password'}
116
+ end
117
+
118
+ it 'generate a create database call' do
119
+ result = Openbanana.grants
120
+ result.should include('CREATE DATABASE test_db;')
121
+ end
122
+
123
+ it 'generate a grant for the user on that database' do
124
+ result = Openbanana.grants
125
+ result.should include("GRANT ALL PRIVILEGES ON test_db.* TO 'test_user'@'%' IDENTIFIED BY 'test_password';")
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: openbanana
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - R. Tyler Croy
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &11245520 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *11245520
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &11245080 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *11245080
36
+ description: Simple gem to handle creating DB grans
37
+ email:
38
+ - tyler@monkeypox.org
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - Gemfile
45
+ - LICENSE
46
+ - README.md
47
+ - Rakefile
48
+ - lib/openbanana.rb
49
+ - lib/openbanana/tasks.rb
50
+ - lib/openbanana/version.rb
51
+ - openbanana.gemspec
52
+ - spec/spec_helper.rb
53
+ - spec/tasks_spec.rb
54
+ homepage: https://github.com/lookout/openbanana
55
+ licenses: []
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 1.8.10
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Simple gem to handle creating DB grans
78
+ test_files:
79
+ - spec/spec_helper.rb
80
+ - spec/tasks_spec.rb