Skip to content
This repository has been archived by the owner on Dec 31, 2022. It is now read-only.

Commit

Permalink
feat: eliminate RDS requirement
Browse files Browse the repository at this point in the history
The database adapter and parameters can be defined in the
node (custom json) if an RDS resource is not defined.
This is expected behaviour for Opsworks users.

BREAKING CHANGE: Sqlite3 is no longer set as the default database
adapter.

In order to use sqlite as the database adapter it must be defined
in the node.
  • Loading branch information
npflood committed Jun 2, 2016
1 parent 93015b6 commit daa4254
Show file tree
Hide file tree
Showing 17 changed files with 127 additions and 53 deletions.
24 changes: 12 additions & 12 deletions Gemfile.lock
Expand Up @@ -44,9 +44,9 @@ GEM
celluloid-io (0.16.2)
celluloid (>= 0.16.0)
nio4r (>= 1.1.0)
chef (12.9.41)
chef (12.10.24)
bundler (>= 1.10)
chef-config (= 12.9.41)
chef-config (= 12.10.24)
chef-zero (~> 4.5)
diff-lcs (~> 1.2, >= 1.2.4)
erubis (~> 2.7)
Expand All @@ -70,7 +70,7 @@ GEM
specinfra (~> 2.10)
syslog-logger (~> 1.6)
uuidtools (~> 2.1.5)
chef-config (12.9.41)
chef-config (12.10.24)
fuzzyurl (~> 0.8.0)
mixlib-config (~> 2.0)
mixlib-shellout (~> 2.0)
Expand All @@ -80,7 +80,7 @@ GEM
mixlib-log (~> 1.3)
rack
uuidtools (~> 2.1)
chefspec (4.6.1)
chefspec (4.7.0)
chef (>= 11.14)
fauxhai (~> 3.2)
rspec (~> 3.0)
Expand Down Expand Up @@ -109,7 +109,7 @@ GEM
ffi (1.9.10)
ffi-yajl (2.2.3)
libyajl2 (~> 1.2)
foodcritic (6.2.0)
foodcritic (6.3.0)
cucumber-core (>= 1.3)
erubis
nokogiri (>= 1.5, < 2.0)
Expand Down Expand Up @@ -160,7 +160,7 @@ GEM
mixlib-shellout (2.2.6)
mixlib-versioning (1.1.0)
molinillo (0.4.5)
multi_json (1.12.0)
multi_json (1.12.1)
multipart-post (2.0.0)
net-http-persistent (2.9.4)
net-http-pipeline (1.0.1)
Expand All @@ -180,7 +180,7 @@ GEM
mini_portile2 (~> 2.0.0.rc2)
octokit (4.3.0)
sawyer (~> 0.7.0, >= 0.5.3)
ohai (8.15.1)
ohai (8.16.0)
chef-config (>= 12.5.0.alpha.1, < 13)
ffi (~> 1.9)
ffi-yajl (~> 2.2)
Expand Down Expand Up @@ -208,7 +208,7 @@ GEM
rainbow (2.1.0)
rake (11.1.2)
retryable (2.0.3)
ridley (4.5.0)
ridley (4.5.1)
addressable
buff-config (~> 1.0)
buff-extensions (~> 1.0)
Expand Down Expand Up @@ -251,14 +251,14 @@ GEM
rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.8.0)
ruby-progressbar (1.8.1)
rufus-lru (1.1.0)
safe_yaml (1.0.4)
sawyer (0.7.0)
addressable (>= 2.3.5, < 2.5)
faraday (~> 0.8, < 0.10)
semverse (1.2.1)
serverspec (2.34.0)
serverspec (2.36.0)
multi_json
rspec (~> 3.0)
rspec-its
Expand All @@ -272,7 +272,7 @@ GEM
solve (2.0.3)
molinillo (~> 0.4.2)
semverse (~> 1.1)
specinfra (2.57.2)
specinfra (2.57.4)
net-scp
net-ssh (>= 2.7, < 4.0)
net-telnet
Expand Down Expand Up @@ -333,4 +333,4 @@ DEPENDENCIES
travis

BUNDLED WITH
1.12.3
1.12.4
7 changes: 4 additions & 3 deletions README.md
Expand Up @@ -10,8 +10,8 @@ A [chef](https://www.chef.io/) cookbook to deploy Ruby applications to Amazon Op
## Quick Start

This cookbook is designed to "just work". So in base case scenario, all you have
to do is create a layer and application with assigned RDS data source, then
[add recipes to the corresponding OpsWorks actions](#recipes).
to do is create a layer and application with an optional assigned RDS data source,
then [add recipes to the corresponding OpsWorks actions](#recipes).

## Support

Expand Down Expand Up @@ -78,7 +78,8 @@ for you.

* `app['database']['adapter']`
* **Supported values:** `mariadb`, `mysql`, `postgresql`, `sqlite3`
* **Default:** `sqlite3` (if no RDBMS is detected)
* **Note:** There is no default database adapter if a RDS resource is not
defined in your stack.
* ActiveRecord adapter which will be used for database connection.
* `app['database']['username']`
* Username used to authenticate to the DB
Expand Down
7 changes: 3 additions & 4 deletions libraries/drivers_db_base.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true

module Drivers
module Db
class Base < Drivers::Base
Expand All @@ -9,7 +10,6 @@ class Base < Drivers::Base
defaults encoding: 'utf8', host: 'localhost', reconnect: true

def initialize(app, node, options = {})
raise ArgumentError, ':rds option is not set.' unless options[:rds]
super
end

Expand All @@ -20,7 +20,6 @@ def setup(context)
def configure(context)
database = out
rails_env = app['attributes']['rails_env']

context.template File.join(deploy_dir(app), 'shared', 'config', 'database.yml') do
source 'database.yml.erb'
mode '0660'
Expand All @@ -34,7 +33,7 @@ def configure(context)
def out
if configuration_data_source == :node_engine
return out_defaults.merge(
database: out_defaults[:database] || app['data_sources'].first['database_name']
database: out_defaults[:database] || app['data_sources'].first.try(:[], 'database_name')
)
end

Expand All @@ -53,7 +52,7 @@ def out_defaults
protected

def app_engine
options[:rds]['engine']
options.try(:[], :rds).try(:[], 'engine')
end

def node_engine
Expand Down
6 changes: 3 additions & 3 deletions libraries/drivers_db_factory.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: true

module Drivers
module Db
class Factory
def self.build(app, node, options = {})
raise ArgumentError, ':rds option is not set.' unless options[:rds]

engine = detect_engine(app, node, options)
raise StandardError, 'There is no supported Db driver for given configuration.' if engine.blank?
engine.new(app, node, options)
Expand All @@ -13,7 +12,8 @@ def self.build(app, node, options = {})
def self.detect_engine(app, node, options)
Drivers::Db::Base.descendants.detect do |db_driver|
db_driver.allowed_engines.include?(
options[:rds]['engine'] || node['deploy'][app['shortname']]['database']['adapter']
options.try(:[], :rds).try(:[], 'engine') ||
node.try(:[], 'deploy').try(:[], app['shortname']).try(:[], 'database').try(:[], 'adapter')
)
end
end
Expand Down
9 changes: 3 additions & 6 deletions libraries/helpers.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true

def applications
if Chef::Config[:solo]
Chef::Log.warn('This recipe uses search. Chef Solo does not support search.')
Expand Down Expand Up @@ -44,12 +45,8 @@ def every_enabled_application
end

def every_enabled_rds
if rdses.blank?
yield('engine' => 'sqlite')
else
rdses.each do |rds|
yield rds
end
rdses.each do |rds|
yield rds
end
end

Expand Down
2 changes: 1 addition & 1 deletion metadata.rb
Expand Up @@ -5,7 +5,7 @@
license 'MIT'
description 'Set of chef recipes for OpsWorks based Ruby projects'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '0.2.1'
version '0.3.0'

depends 'build-essential', '~> 2.0'
depends 'deployer'
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "opsworks_ruby",
"version": "0.2.1",
"version": "0.3.0",
"description": "Set of chef recipes for OpsWorks based Ruby projects.",
"dependencies": {},
"devDependencies": {
Expand Down
5 changes: 5 additions & 0 deletions recipes/configure.rb
Expand Up @@ -19,6 +19,11 @@
database.configure(self)
end

if rdses.blank?
database = Drivers::Db::Factory.build(application, node)
database.configure(self)
end

scm = Drivers::Scm::Factory.build(application, node)
scm.configure(self)
framework = Drivers::Framework::Factory.build(application, node)
Expand Down
10 changes: 10 additions & 0 deletions recipes/deploy.rb
Expand Up @@ -10,6 +10,11 @@
database.before_deploy(self)
end

if rdses.blank?
database = Drivers::Db::Factory.build(application, node)
database.before_deploy(self)
end

scm = Drivers::Scm::Factory.build(application, node)
framework = Drivers::Framework::Factory.build(application, node)
appserver = Drivers::Appserver::Factory.build(application, node)
Expand Down Expand Up @@ -85,4 +90,9 @@
database = Drivers::Db::Factory.build(application, node, rds: rds)
database.after_deploy(self)
end

if rdses.blank?
database = Drivers::Db::Factory.build(application, node)
database.after_deploy(self)
end
end
5 changes: 5 additions & 0 deletions recipes/setup.rb
Expand Up @@ -33,6 +33,11 @@
database.setup(self)
end

if rdses.blank?
database = Drivers::Db::Factory.build(application, node)
database.setup(self)
end

scm = Drivers::Scm::Factory.build(application, node)
scm.setup(self)
framework = Drivers::Framework::Factory.build(application, node)
Expand Down
5 changes: 5 additions & 0 deletions recipes/shutdown.rb
Expand Up @@ -12,6 +12,11 @@
database.shutdown(self)
end

if rdses.blank?
database = Drivers::Db::Factory.build(application, node)
database.shutdown(self)
end

scm = Drivers::Scm::Factory.build(application, node)
scm.shutdown(self)
framework = Drivers::Framework::Factory.build(application, node)
Expand Down
10 changes: 10 additions & 0 deletions recipes/undeploy.rb
Expand Up @@ -8,6 +8,11 @@
database.before_undeploy(self)
end

if rdses.blank?
database = Drivers::Db::Factory.build(application, node)
database.before_undeploy(self)
end

scm = Drivers::Scm::Factory.build(application, node)
framework = Drivers::Framework::Factory.build(application, node)
appserver = Drivers::Appserver::Factory.build(application, node)
Expand Down Expand Up @@ -46,4 +51,9 @@
database = Drivers::Db::Factory.build(application, node, rds: rds)
database.after_undeploy(self)
end

if rdses.blank?
database = Drivers::Db::Factory.build(application, node)
database.after_undeploy(self)
end
end
16 changes: 8 additions & 8 deletions spec/fixtures/node.rb
Expand Up @@ -11,14 +11,14 @@ def node(override = {})
},
deploy: {
dummy_project: {
database: {
adapter: 'postgresql',
username: 'dbuser',
password: '03c1bc98cdd5eb2f9c75',
host: 'dummy-project.c298jfowejf.us-west-2.rds.amazon.com',
database: 'dummydb',
reaping_frequency: 10
},
# database: {
# adapter: 'postgresql',
# username: 'dbuser',
# password: '03c1bc98cdd5eb2f9c75',
# host: 'dummy-project.c298jfowejf.us-west-2.rds.amazon.com',
# database: 'dummydb',
# reaping_frequency: 10
# },
scm: {
adapter: 'git',
user: 'dummy',
Expand Down
6 changes: 0 additions & 6 deletions spec/unit/examples/db_parameters_and_connection.rb
Expand Up @@ -8,12 +8,6 @@
expect(driver.options[:rds]).to eq aws_opsworks_rds_db_instance(engine: rdbms)
end

it 'raises error when no rds is present' do
expect do
described_class.new(aws_opsworks_app, node, dummy_option: true).out
end.to raise_error ArgumentError, ':rds option is not set.'
end

context 'connection data' do
it 'taken from engine' do
item = described_class.new(
Expand Down
6 changes: 0 additions & 6 deletions spec/unit/libraries/drivers_db_factory_spec.rb
Expand Up @@ -2,12 +2,6 @@
require 'spec_helper'

describe Drivers::Db::Factory do
it 'raises error when no rds is present' do
expect do
described_class.build(aws_opsworks_app, node, dummy_option: true)
end.to raise_error ArgumentError, ':rds option is not set.'
end

it 'raises error when unknown engine is present' do
expect do
described_class.build(aws_opsworks_app, node, rds: { 'engine' => 'unknown' })
Expand Down

0 comments on commit daa4254

Please sign in to comment.