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

Commit

Permalink
Added webserver setup (nginx)
Browse files Browse the repository at this point in the history
  • Loading branch information
Igor Rzegocki committed Apr 16, 2016
1 parent ff85e4f commit 1581def
Show file tree
Hide file tree
Showing 16 changed files with 316 additions and 6 deletions.
17 changes: 17 additions & 0 deletions attributes/default.rb
Expand Up @@ -21,6 +21,23 @@
default['defaults']['appserver']['tries'] = 5
default['defaults']['appserver']['timeout'] = 60

# webserver
## common

default['defaults']['webserver']['adapter'] = 'nginx'

## nginx

default['defaults']['webserver']['build_type'] = 'default'
default['defaults']['webserver']['client_body_timeout'] = '12'
default['defaults']['webserver']['client_header_timeout'] = '12'
default['defaults']['webserver']['client_max_body_size'] = '10m'
default['defaults']['webserver']['keepalive_timeout'] = '15'
default['defaults']['webserver']['log_dir'] = '/var/log/nginx'
default['defaults']['webserver']['proxy_read_timeout'] = '60'
default['defaults']['webserver']['proxy_send_timeout'] = '60'
default['defaults']['webserver']['send_timeout'] = '10'

# framework
## common

Expand Down
21 changes: 21 additions & 0 deletions libraries/drivers_webserver_base.rb
@@ -0,0 +1,21 @@
# frozen_string_literal: true
module Drivers
module Webserver
class Base < Drivers::Base
include Drivers::Dsl::Output

def out
handle_output(raw_out)
end

def raw_out
node['defaults']['webserver'].merge(
node['deploy'][app['shortname']]['webserver'] || {}
).symbolize_keys
end

def validate_app_engine
end
end
end
end
21 changes: 21 additions & 0 deletions libraries/drivers_webserver_factory.rb
@@ -0,0 +1,21 @@
# frozen_string_literal: true
module Drivers
module Webserver
class Factory
def self.build(app, node, options = {})
engine = detect_engine(app, node, options)
raise StandardError, 'There is no supported Webserver driver for given configuration.' if engine.blank?
engine.new(app, node, options)
end

def self.detect_engine(app, node, _options)
Drivers::Webserver::Base.descendants.detect do |webserver_driver|
webserver_driver.allowed_engines.include?(
node['deploy'][app['shortname']]['webserver'].try(:[], 'adapter') ||
node['defaults']['webserver']['adapter']
)
end
end
end
end
end
75 changes: 75 additions & 0 deletions libraries/drivers_webserver_nginx.rb
@@ -0,0 +1,75 @@
# frozen_string_literal: true
module Drivers
module Webserver
class Nginx < Drivers::Webserver::Base
adapter :nginx
allowed_engines :nginx
output filter: [
:build_type, :client_body_timeout, :client_header_timeout, :client_max_body_size, :keepalive_timeout,
:log_dir, :proxy_read_timeout, :proxy_send_timeout, :send_timeout
]
# notifies action: :restart,
# resource: proc { |app| "service[nginx_#{app['shortname']}]" },
# timer: :immediately

def setup(context)
context.include_recipe("nginx::#{out[:build_type]}")
end

def configure(context)
add_ssl_directory(context)
add_ssl_item(context, :private_key)
add_ssl_item(context, :certificate)
add_ssl_item(context, :chain)

add_unicorn_config(context) if Drivers::Appserver::Factory.build(app, node).adapter == 'unicorn'
enable_appserver_config(context)
end

private

def add_ssl_directory(context)
context.directory '/etc/nginx/ssl' do
owner 'root'
group 'root'
mode '0700'
end
end

def add_ssl_item(context, name)
key_data = app[:ssl_configuration].try(:[], name)
return if key_data.blank?
extensions = { private_key: 'key', certificate: 'crt', chain: 'ca' }

context.template "/etc/nginx/ssl/#{app[:domains].first}.#{extensions[name]}" do
owner 'root'
group 'root'
mode '0644'
source 'ssl_key.erb'
variables key_data: key_data
end
end

def add_unicorn_config(context)
deploy_to = deploy_dir(app)
application = app
output = out

context.template "/etc/nginx/sites-available/#{app['shortname']}" do
owner 'root'
group 'root'
mode '0644'
source 'unicorn.nginx.conf.erb'
variables application: application, deploy_dir: deploy_to, out: output
end
end

def enable_appserver_config(context)
application = app
context.link "/etc/nginx/sites-enabled/#{application['shortname']}" do
to "/etc/nginx/sites-available/#{application['shortname']}"
end
end
end
end
end
5 changes: 3 additions & 2 deletions metadata.rb
@@ -1,14 +1,15 @@
# frozen_string_literal: true
name 'opsworks_ruby'
maintainer 'The Authors'
maintainer_email 'you@example.com'
maintainer 'Igor Rzegocki'
maintainer_email 'igor@rzegocki.pl'
license 'MIT'
description 'Installs/Configures opsworks_ruby'
long_description 'Installs/Configures opsworks_ruby'
version '0.1.0'

depends 'deployer'
depends 'ruby-ng'
depends 'nginx'
depends 'application_ruby'

source_url 'https://github.com/ajgon/opsworks_ruby'
Expand Down
2 changes: 2 additions & 0 deletions recipes/configure.rb
Expand Up @@ -19,4 +19,6 @@

appserver = Drivers::Appserver::Factory.build(application, node)
appserver.configure(self)
webserver = Drivers::Webserver::Factory.build(application, node)
webserver.configure(self)
end
2 changes: 2 additions & 0 deletions recipes/setup.rb
Expand Up @@ -16,6 +16,8 @@
every_enabled_application do |application|
scm = Drivers::Scm::Factory.build(application, node)
scm.setup(self)
webserver = Drivers::Webserver::Factory.build(application, node)
webserver.setup(self)

every_enabled_rds do |rds|
database = Drivers::Db::Factory.build(application, node, rds: rds)
Expand Down
2 changes: 1 addition & 1 deletion spec/fixtures/aws_opsworks_app.rb
Expand Up @@ -30,7 +30,7 @@ def aws_opsworks_app(override = {})
shortname: 'dummy_project',
ssl_configuration: {
certificate: '--- SSL CERTIFICATE ---',
private_key: '--- SSL PRICATE KEY ---',
private_key: '--- SSL PRIVATE KEY ---',
chain: '--- SSL CERTIFICATE CHAIN ---'
},
type: 'other',
Expand Down
8 changes: 8 additions & 0 deletions spec/fixtures/node.rb
Expand Up @@ -31,6 +31,10 @@ def node(override = {})
adapter: 'unicorn',
delay: 3
},
webserver: {
adapter: 'nginx',
client_max_body_size: '125m'
},
framework: {
adapter: 'rails',
migrate: false
Expand All @@ -42,6 +46,10 @@ def node(override = {})
adapter: 'unicorn',
worker_processes: 8
},
webserver: {
adapter: 'nginx',
keepalive_timeout: '15'
},
framework: {
adapter: 'rails',
migration_command: 'rake db:migrate'
Expand Down
18 changes: 18 additions & 0 deletions spec/unit/libraries/drivers_webserver_factory_spec.rb
@@ -0,0 +1,18 @@
# frozen_string_literal: true
require 'spec_helper'

describe Drivers::Webserver::Factory do
it 'raises error when unknown adapter is present' do
expect do
described_class.build(
aws_opsworks_app,
'deploy' => { aws_opsworks_app['shortname'] => { 'webserver' => { 'adapter' => 'haproxy' } } }
)
end.to raise_error StandardError, 'There is no supported Webserver driver for given configuration.'
end

it 'returns a Nginx class' do
webserver = described_class.build(aws_opsworks_app, node)
expect(webserver).to be_instance_of(Drivers::Webserver::Nginx)
end
end
19 changes: 19 additions & 0 deletions spec/unit/libraries/drivers_webserver_nginx_spec.rb
@@ -0,0 +1,19 @@
# frozen_string_literal: true
require 'spec_helper'

describe Drivers::Webserver::Nginx do
it 'receives and exposes app and node' do
driver = described_class.new(aws_opsworks_app, node)

expect(driver.app).to eq aws_opsworks_app
expect(driver.node).to eq node
expect(driver.options).to eq({})
end

it 'returns proper out data' do
expect(described_class.new(aws_opsworks_app, node).out).to eq(
client_max_body_size: '125m',
keepalive_timeout: '15'
)
end
end
28 changes: 27 additions & 1 deletion spec/unit/recipes/configure_spec.rb
Expand Up @@ -44,7 +44,7 @@
end
end

context 'Postgresql + Git + Unicorn' do
context 'Postgresql + Git + Unicorn + Nginx' do
it 'creates proper database.yml template' do
db_config = Drivers::Db::Postgresql.new(aws_opsworks_app, node, rds: aws_opsworks_rds_db_instance).out
expect(chef_run)
Expand Down Expand Up @@ -89,5 +89,31 @@
expect(service.status_command)
.to eq "/srv/www/#{aws_opsworks_app['shortname']}/shared/scripts/unicorn.service status"
end

it 'creates nginx unicorn proxy handler config' do
expect(chef_run)
.to render_file("/etc/nginx/sites-available/#{aws_opsworks_app['shortname']}")
.with_content('client_max_body_size 125m;')
expect(chef_run)
.to render_file("/etc/nginx/sites-available/#{aws_opsworks_app['shortname']}")
.with_content('keepalive_timeout 15;')
expect(chef_run)
.to render_file("/etc/nginx/sites-available/#{aws_opsworks_app['shortname']}")
.with_content('ssl_certificate_key /etc/nginx/ssl/dummy-project.example.com.key;')
expect(chef_run).to create_link("/etc/nginx/sites-enabled/#{aws_opsworks_app['shortname']}")
end

it 'creates SSL keys for nginx' do
expect(chef_run).to create_directory('/etc/nginx/ssl')
expect(chef_run)
.to render_file("/etc/nginx/ssl/#{aws_opsworks_app['domains'].first}.key")
.with_content('--- SSL PRIVATE KEY ---')
expect(chef_run)
.to render_file("/etc/nginx/ssl/#{aws_opsworks_app['domains'].first}.crt")
.with_content('--- SSL CERTIFICATE ---')
expect(chef_run)
.to render_file("/etc/nginx/ssl/#{aws_opsworks_app['domains'].first}.ca")
.with_content('--- SSL CERTIFICATE CHAIN ---')
end
end
end
2 changes: 1 addition & 1 deletion spec/unit/recipes/deploy_spec.rb
Expand Up @@ -24,7 +24,7 @@
expect(chef_run).to include_recipe('opsworks_ruby::configure')
end

context 'Postgresql + Git + Unicorn' do
context 'Postgresql + Git + Unicorn + Nginx' do
it 'creates git wrapper script' do
expect(chef_run).to create_template('/tmp/ssh-git-wrapper.sh')
end
Expand Down
3 changes: 2 additions & 1 deletion spec/unit/recipes/setup_spec.rb
Expand Up @@ -72,8 +72,9 @@
end
end

context 'Postgresql + git' do
context 'Postgresql + git + nginx' do
it 'installs required packages' do
expect(chef_run).to install_package('nginx')
expect(chef_run).to install_package('git')
expect(chef_run).to install_package('libpq-dev')
end
Expand Down
1 change: 1 addition & 0 deletions templates/default/ssl_key.erb
@@ -0,0 +1 @@
<%= @key_data.to_s %>

0 comments on commit 1581def

Please sign in to comment.