conan 0.1.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.
@@ -0,0 +1,9 @@
1
+ Conan The Deployer
2
+ ==================
3
+
4
+ Conan will set up a project to enable you to configure servers using Chef via Capistrano.
5
+
6
+ cd /path/to/rails/app
7
+ conan init
8
+
9
+ Follow the instructions to complete configuration.
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ require "conan/initializer"
3
+
4
+ case ARGV.first
5
+ when "init"
6
+ Conan::Initializer.run
7
+ puts File.read("CONAN_TODO")
8
+ else
9
+ raise "Unrecognised command: #{ARGV.first}"
10
+ end
@@ -0,0 +1,6 @@
1
+ require "bundler/capistrano"
2
+ require "conan/deployment"
3
+
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ Conan::Deployment.define_tasks(self)
6
+ end
@@ -0,0 +1,65 @@
1
+ module Conan
2
+ class Deployment
3
+ module Helpers
4
+ def with_user(new_user, &blk)
5
+ old_user = user
6
+ return if old_user == new_user
7
+ set :user, new_user
8
+ close_sessions
9
+ yield
10
+ set :user, old_user
11
+ close_sessions
12
+ end
13
+
14
+ def close_sessions
15
+ sessions.values.each { |session| session.close }
16
+ sessions.clear
17
+ end
18
+
19
+ def rake(command, options={})
20
+ path = options[:path] || current_path
21
+ run "cd #{path}; rake #{command} RAILS_ENV=#{rails_env}"
22
+ end
23
+
24
+ def git_tag(source, dest)
25
+ system "git fetch origin --tags"
26
+ sha1 = `git rev-parse "#{source}"`
27
+ system %{git update-ref "refs/tags/#{dest}" #{sha1}}
28
+ system %{git push -f origin tag #{dest}}
29
+ end
30
+
31
+ def add_role(*roles)
32
+ roles = Hash.new{ |h,k| h[k] = [] }
33
+
34
+ server_config.each do |s, c|
35
+ c["roles"].each do |r|
36
+ roles[r.to_sym] << s
37
+ end
38
+ end
39
+
40
+ roles.each do |r, ss|
41
+ next unless roles.include?(r)
42
+ ss.each_with_index do |s, i|
43
+ role r, s, :primary => (i == 0)
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ class <<self
50
+ def define_tasks(context)
51
+ load_script(context, "deploy")
52
+ load_script(context, "chef")
53
+ load_script(context, "git")
54
+ end
55
+
56
+ def load_script(context, fragment)
57
+ path = File.expand_path("../deployment/#{fragment}.rb", __FILE__)
58
+ code = File.read(path)
59
+ context.instance_eval(code, path)
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ include Conan::Deployment::Helpers
@@ -0,0 +1,79 @@
1
+ require "fileutils"
2
+
3
+ namespace :chef do
4
+ task :update_aliases do
5
+ require "json"
6
+
7
+ cache_path = "tmp/cache/server_internal_addresses.json"
8
+
9
+ cache =
10
+ if File.exist?(cache_path)
11
+ JSON.parse(File.read(cache_path))
12
+ else
13
+ {}
14
+ end
15
+
16
+ aliases = {}
17
+ server_config.each do |host, config|
18
+ cache[host] ||= `ssh #{host} ifconfig`[/inet addr:(10\.\d+\.\d+\.\d+)/, 1]
19
+ aliases[config["alias"]] = cache[host]
20
+ end
21
+
22
+ FileUtils.mkdir_p File.dirname(cache_path)
23
+ File.open(cache_path, "w") do |io|
24
+ io << JSON.dump(cache)
25
+ end
26
+
27
+ File.open("deploy/chef/dna/aliases.json", "w") do |io|
28
+ io << JSON.dump({"hosts" => aliases})
29
+ end
30
+ end
31
+
32
+ before "chef:rsync", "chef:update_aliases"
33
+ task :rsync do
34
+ require "json"
35
+ require "conan/smart_hash_merge"
36
+
37
+ ssh_options = {
38
+ 'BatchMode' => 'yes',
39
+ 'CheckHostIP' => 'no',
40
+ 'ForwardAgent' => 'yes',
41
+ 'StrictHostKeyChecking' => 'no',
42
+ 'UserKnownHostsFile' => '/dev/null'
43
+ }.map{|k, v| "-o #{k}=#{v}"}.join(' ')
44
+
45
+ server_config.each do |host, config|
46
+ dna = {}
47
+ (["base", "aliases"] + config["roles"]).each do |role|
48
+ path = "deploy/chef/dna/#{role}.json"
49
+ next unless File.exist?(path)
50
+ dna = Conan::SmartHashMerge.merge(dna, JSON.parse(File.read(path)))
51
+ end
52
+
53
+ File.open("deploy/chef/dna/generated.json", "w") do |io|
54
+ io << JSON.dump(dna)
55
+ end
56
+
57
+ system "rsync -Caz --rsync-path='sudo rsync' --delete --exclude .git --exclude '.*.swp' --rsh='ssh -l ubuntu #{ssh_options}' deploy/chef/ #{host}:/etc/chef"
58
+ end
59
+ end
60
+
61
+ before "chef:bootstrap", "chef:rsync"
62
+ task :bootstrap do
63
+ with_user "ubuntu" do
64
+ run "sudo /etc/chef/bootstrap.sh"
65
+ end
66
+ end
67
+
68
+ before "chef:update", "chef:bootstrap"
69
+ task "update" do
70
+ with_user "ubuntu" do
71
+ run "sudo chef-solo -j /etc/chef/dna/generated.json"
72
+ end
73
+ end
74
+ end
75
+
76
+ desc "Install and configure server(s)"
77
+ task "configure" do
78
+ chef.update
79
+ end
@@ -0,0 +1,53 @@
1
+ require "json"
2
+ set :server_config, JSON.parse(File.read("config/servers.json"))[stage] || {}
3
+
4
+ add_role :app, :db
5
+
6
+ namespace :deploy do
7
+ task :start, :roles => :app do; end
8
+ task :stop, :roles => :app do; end
9
+
10
+ task :restart, :roles => :app do
11
+ run "touch #{current_path}/tmp/restart.txt"
12
+ end
13
+ after "deploy:restart", "deploy:cleanup"
14
+
15
+ namespace :maintenance do
16
+ task :start, :roles => :app do
17
+ run "cp #{current_path}/public/maintenance.html #{current_path}/public/system/maintenance.html || echo"
18
+ end
19
+
20
+ task :stop, :roles => :app do
21
+ run "rm -f #{current_path}/public/system/maintenance.html"
22
+ end
23
+ end
24
+
25
+ task :link_shared, :roles => :app do
26
+ shared_paths.each do |s|
27
+ run "rm -f #{release_path}/#{s}"
28
+ run "ln -nfs #{shared_path}/#{s} #{release_path}/#{s}"
29
+ end
30
+ end
31
+ after "deploy:update_code", "deploy:link_shared"
32
+
33
+ desc "Deploy and run migrations"
34
+ task :default do
35
+ maintenance.start
36
+ update_code
37
+ migrate
38
+ symlink
39
+ restart
40
+ maintenance.stop
41
+ end
42
+
43
+ task :smoke_test do
44
+ if File.exist?("test/deploy/smoke_test.rb")
45
+ system "ruby test/deploy/smoke_test.rb #{stage}"
46
+ unless $? == 0
47
+ deploy.maintenance.start
48
+ raise CommandError, "Smoke tests failed"
49
+ end
50
+ end
51
+ end
52
+ after "deploy", "deploy:smoke_test"
53
+ end
@@ -0,0 +1,11 @@
1
+ namespace :git do
2
+ before "deploy:update_code", "git:tag_attempted_deploy"
3
+ task :tag_attempted_deploy do
4
+ git_tag branch, "#{stage}.last-deploy"
5
+ end
6
+
7
+ task :tag_successful_deploy do
8
+ git_tag branch, "#{stage}.last-successful-deploy"
9
+ end
10
+ after "deploy:smoke_test", "git:tag_successful_deploy"
11
+ end
@@ -0,0 +1,55 @@
1
+ require "fileutils"
2
+
3
+ module Conan
4
+ class Initializer
5
+ TEMPLATE_PATH = File.expand_path("../template", __FILE__)
6
+ ShellCommandError = Class.new(RuntimeError)
7
+
8
+ def self.run(where=Dir.pwd)
9
+ new(where).run
10
+ end
11
+
12
+ def initialize(where)
13
+ @destination = File.expand_path(where)
14
+ end
15
+
16
+ def run
17
+ copy_template
18
+ add_gitignore
19
+ add_git_submodule
20
+ end
21
+
22
+ private
23
+ def add_gitignore
24
+ gitignore = ".gitignore"
25
+ add_newline = File.exist?(gitignore) && File.read(gitignore).match(/[^\n]\Z/)
26
+ File.open(".gitignore", "a") do |f|
27
+ f.puts if add_newline
28
+ f.puts "/deploy/chef/dna/generated.json"
29
+ f.puts "/deploy/chef/dna/aliases.json"
30
+ end
31
+ end
32
+
33
+ def add_git_submodule
34
+ return unless File.directory?(".git")
35
+ sh "git submodule add git://github.com/madebymany/cookbooks.git deploy/chef/recipes/cookbooks >/dev/null 2>&1"
36
+ end
37
+
38
+ def copy_template
39
+ Dir.chdir(TEMPLATE_PATH) do
40
+ Dir["**/*"].each do |source|
41
+ target = File.join(@destination, source)
42
+ if File.directory?(source)
43
+ FileUtils.mkdir_p target
44
+ else
45
+ FileUtils.cp source, target
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def sh(command)
52
+ system command or raise ShellCommandError, command
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,34 @@
1
+ module Conan
2
+ class SmartHashMerge
3
+ def self.merge(lhash, rhash)
4
+ new(lhash, rhash).merge
5
+ end
6
+
7
+ def initialize(lhash, rhash)
8
+ @lhash, @rhash = lhash, rhash
9
+ end
10
+
11
+ def merge
12
+ lhash = @lhash.dup
13
+ deep_merge(lhash, @rhash)
14
+ end
15
+
16
+ private
17
+ def deep_merge(lhash, rhash)
18
+ merged = lhash.dup
19
+ rhash.each do |key, rvalue|
20
+ lvalue = lhash[key]
21
+ if lvalue.is_a?(Hash) and rvalue.is_a?(Hash)
22
+ merged[key] = deep_merge(lhash[key], rhash[key])
23
+ elsif lvalue.is_a?(Array) and rvalue.is_a?(Array)
24
+ merged[key] = lvalue + rvalue
25
+ elsif rvalue.is_a?(Array) && !lvalue.nil?
26
+ merged[key] = [lvalue] + rvalue
27
+ else
28
+ merged[key] = rvalue
29
+ end
30
+ end
31
+ merged
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ Conan the Deployer has set up your project.
2
+
3
+ Next, set up your deployment:
4
+
5
+ * Edit config/servers.json to specify your stages, servers, and roles
6
+
7
+ * Edit the TODOs in deploy/chef/dna/*.json
8
+
9
+ * Add stage-/role-/server-specific files in deploy/chef/dna/*.json
10
+
11
+ * Add some post-deployment tests in test/deploy/smoke_test.rb that test the
12
+ deployed app.
13
+
14
+ * Add your own recipes to deploy/chef/recipes/site-cookbooks
15
+
16
+ Finally, use Capistrano to configure your servers and deploy your application
17
+ to the desired stage:
18
+
19
+ * cap staging configure deploy
20
+
21
+ This list has been left in CONAN_TODO for you to peruse at your leisure.
@@ -0,0 +1,3 @@
1
+ load 'deploy' if respond_to?(:namespace) # cap2 differentiator
2
+ Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
3
+ load 'config/deploy'
@@ -0,0 +1,45 @@
1
+ # Configuration
2
+
3
+ # Assume that we are deploying from the "origin" remote.
4
+ set :repository, `git remote -v | grep 'origin.*fetch' | awk '{print $2}'`.chomp
5
+
6
+ # Hopefully, your application name matches the repository name.
7
+ set :application, File.basename(repository, ".git")
8
+
9
+ # Files and directories to persist between deployments:
10
+ set :shared_paths, %w[
11
+ config/database.yml
12
+ log
13
+ ]
14
+
15
+ # Your stages. The default assumes:
16
+ #
17
+ # * There is a staging and a production environment.
18
+ # * Staging is deployed from the master branch
19
+ # * Deployment to production is always made from the last branch successfully
20
+ # deployed to staging.
21
+ #
22
+
23
+ task :staging do; end
24
+ task :production do; end
25
+
26
+ case ARGV.first.to_sym
27
+ when :staging
28
+ set :stage, "staging"
29
+ set :branch, "master"
30
+ when :production
31
+ set :stage, "production"
32
+ set :branch, "staging.last-successful-deploy"
33
+ end
34
+
35
+ # You probably don't need to edit these
36
+ default_run_options[:pty] = true
37
+ set :use_sudo, false
38
+ set :deploy_via, :remote_cache
39
+ set :keep_releases, 5
40
+ set :scm, "git"
41
+ set :user, "rails"
42
+ set :deploy_to, "/mnt/#{application}"
43
+
44
+ # Let Conan take over
45
+ require "conan/capistrano"
@@ -0,0 +1,14 @@
1
+ {
2
+ "staging": {
3
+ "TODO e.g. something.amazonaws.com": {
4
+ "roles": ["app", "db", "staging"],
5
+ "alias": "staging"
6
+ }
7
+ },
8
+ "production": {
9
+ "TODO e.g. something-else.amazonaws.com": {
10
+ "roles": ["app", "db", "production"],
11
+ "alias": "app1"
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,52 @@
1
+ #!/bin/bash
2
+ # Bootstrap chef on Ubuntu 10.04
3
+
4
+ function inform {
5
+ status=$1
6
+ echo
7
+ echo -e "\e[33m• ${1}\e[0m"
8
+ echo
9
+ }
10
+
11
+ function happy_ending {
12
+ echo
13
+ echo -e "\e[32m✓ ${1}\e[0m"
14
+ exit 0
15
+ }
16
+
17
+ function croak {
18
+ echo
19
+ echo -e "\e[31m✗ $status failed. Aborting.\e[0m"
20
+ exit 1
21
+ }
22
+
23
+ command -v chef-solo >/dev/null && \
24
+ happy_ending "Chef is already bootstrapped. Nothing more to do."
25
+
26
+ inform "Updating package index"
27
+ apt-get update || croak
28
+
29
+ inform "Setting up build environment"
30
+ apt-get install -y build-essential || croak
31
+
32
+ inform "Installing Ruby Enterprise Edition"
33
+ case `uname -m` in
34
+ x86_64)
35
+ REE="http://rubyforge.org/frs/download.php/71098/ruby-enterprise_1.8.7-2010.02_amd64_ubuntu10.04.deb"
36
+ ;;
37
+ *)
38
+ REE="http://rubyforge.org/frs/download.php/71100/ruby-enterprise_1.8.7-2010.02_i386_ubuntu10.04.deb"
39
+ ;;
40
+ esac
41
+ echo "Fetching ${REE}"
42
+ curl -s -L -o ree.deb "${REE}" || croak
43
+ dpkg -i ree.deb || croak
44
+ rm ree.deb
45
+
46
+ inform "Installing Chef"
47
+ gem install -v 0.5.8 ohai --no-rdoc --no-ri || croak
48
+ gem install -v 0.9.12 chef --no-rdoc --no-ri || croak
49
+
50
+ mkdir -p /etc/chef
51
+
52
+ happy_ending "Chef has been bootstrapped!"
@@ -0,0 +1,6 @@
1
+ {
2
+ "recipes": [
3
+ "mysql::client",
4
+ "rails_app"
5
+ ]
6
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "rails_app": {
3
+ "user": "rails",
4
+ "name": "TODO",
5
+ "home": "/mnt/TODO",
6
+ "packages": [
7
+ "git-core",
8
+ "libxml2-dev",
9
+ "libxslt1-dev"
10
+ ],
11
+ "canonical_domain": "TODO e.g. www.example.com",
12
+ "domain_aliases": [
13
+ "TODO e.g. example.com"
14
+ ],
15
+ "redirections": [
16
+ "TODO e.g. ^example.com$"
17
+ ],
18
+ "database": {
19
+ "adapter": "mysql2",
20
+ "encoding": "utf8",
21
+ "collation": "utf8_general_ci"
22
+ },
23
+ "s3": {
24
+ "access_key_id": "TODO",
25
+ "secret_access_key": "TODO"
26
+ }
27
+ },
28
+ "apache": {
29
+ "listen_ports": ["80"]
30
+ },
31
+ "passenger": {
32
+ "version": "2.2.14"
33
+ },
34
+ "recipes": [
35
+ "hosts"
36
+ ]
37
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "rails_app": {
3
+ "domain_aliases": [],
4
+ "database": {
5
+ "host": "TODO",
6
+ "username": "TODO",
7
+ "password": "TODO",
8
+ "database": "TODO"
9
+ },
10
+ "s3": {
11
+ "bucket_name": "TODO"
12
+ }
13
+ }
14
+ }
15
+
@@ -0,0 +1,14 @@
1
+ {
2
+ "rails_app": {
3
+ "domain_aliases": [],
4
+ "database": {
5
+ "host": "TODO",
6
+ "username": "TODO",
7
+ "password": "TODO",
8
+ "database": "TODO"
9
+ },
10
+ "s3": {
11
+ "bucket_name": "TODO"
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,181 @@
1
+ #
2
+ # Rakefile for Chef Server Repository
3
+ #
4
+ # Author:: Adam Jacob (<adam@opscode.com>)
5
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
6
+ # License:: Apache License, Version 2.0
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+
21
+ require File.join(File.dirname(__FILE__), 'config', 'rake')
22
+
23
+ require 'tempfile'
24
+
25
+ if File.directory?(File.join(TOPDIR, ".svn"))
26
+ $vcs = :svn
27
+ elsif File.directory?(File.join(TOPDIR, ".git"))
28
+ $vcs = :git
29
+ end
30
+
31
+ desc "Update your repository from source control"
32
+ task :update do
33
+ puts "** Updating your repository"
34
+
35
+ case $vcs
36
+ when :svn
37
+ sh %{svn up}
38
+ when :git
39
+ pull = false
40
+ pull = true if File.join(TOPDIR, ".git", "remotes", "origin")
41
+ IO.foreach(File.join(TOPDIR, ".git", "config")) do |line|
42
+ pull = true if line =~ /\[remote "origin"\]/
43
+ end
44
+ if pull
45
+ sh %{git pull}
46
+ else
47
+ puts "* Skipping git pull, no origin specified"
48
+ end
49
+ else
50
+ puts "* No SCM configured, skipping update"
51
+ end
52
+ end
53
+
54
+ desc "Test your cookbooks for syntax errors"
55
+ task :test do
56
+ puts "** Testing your cookbooks for syntax errors"
57
+
58
+ recipes = ["*cookbooks"].map { |folder|
59
+ Dir[File.join(TOPDIR, folder, "**", "*.rb")]
60
+ }.flatten
61
+
62
+ recipes.each do |recipe|
63
+ print "Testing recipe #{recipe}: "
64
+ sh %{ruby -c #{recipe}} do |ok, res|
65
+ if ! ok
66
+ raise "Syntax error in #{recipe}"
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ desc "Install the latest copy of the repository on this Chef Server"
73
+ task :install => [ :update, :test ] do
74
+ puts "** Installing your cookbooks"
75
+ directories = [
76
+ COOKBOOK_PATH,
77
+ SITE_COOKBOOK_PATH,
78
+ CHEF_CONFIG_PATH
79
+ ]
80
+ puts "* Creating Directories"
81
+ directories.each do |dir|
82
+ sh "sudo mkdir -p #{dir}"
83
+ sh "sudo chown root #{dir}"
84
+ end
85
+ puts "* Installing new Cookbooks"
86
+ sh "sudo rsync -rlP --delete --exclude '.svn' cookbooks/ #{COOKBOOK_PATH}"
87
+ puts "* Installing new Site Cookbooks"
88
+ sh "sudo rsync -rlP --delete --exclude '.svn' site-cookbooks/ #{SITE_COOKBOOK_PATH}"
89
+ # puts "* Installing new Chef Server Config"
90
+ # sh "sudo cp config/server.rb #{CHEF_SERVER_CONFIG}"
91
+ # puts "* Installing new Chef Client Config"
92
+ # sh "sudo cp config/client.rb #{CHEF_CLIENT_CONFIG}"
93
+ end
94
+
95
+ desc "By default, run rake test"
96
+ task :default => [ :test ]
97
+
98
+ desc "Create a new cookbook (with COOKBOOK=name, optional CB_PREFIX=site-)"
99
+ task :new_cookbook do
100
+ create_cookbook(File.join(TOPDIR, "#{ENV["CB_PREFIX"]}cookbooks"))
101
+ end
102
+
103
+ def create_cookbook(dir)
104
+ raise "Must provide a COOKBOOK=" unless ENV["COOKBOOK"]
105
+ puts "** Creating cookbook #{ENV["COOKBOOK"]}"
106
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "attributes")}"
107
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "recipes")}"
108
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "definitions")}"
109
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "libraries")}"
110
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "files", "default")}"
111
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "templates", "default")}"
112
+ unless File.exists?(File.join(dir, ENV["COOKBOOK"], "recipes", "default.rb"))
113
+ open(File.join(dir, ENV["COOKBOOK"], "recipes", "default.rb"), "w") do |file|
114
+ file.puts <<-EOH
115
+ #
116
+ # Cookbook Name:: #{ENV["COOKBOOK"]}
117
+ # Recipe:: default
118
+ #
119
+ # Copyright #{Time.now.year}, #{COMPANY_NAME}
120
+ #
121
+ EOH
122
+ case NEW_COOKBOOK_LICENSE
123
+ when :apachev2
124
+ file.puts <<-EOH
125
+ # Licensed under the Apache License, Version 2.0 (the "License");
126
+ # you may not use this file except in compliance with the License.
127
+ # You may obtain a copy of the License at
128
+ #
129
+ # http://www.apache.org/licenses/LICENSE-2.0
130
+ #
131
+ # Unless required by applicable law or agreed to in writing, software
132
+ # distributed under the License is distributed on an "AS IS" BASIS,
133
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134
+ # See the License for the specific language governing permissions and
135
+ # limitations under the License.
136
+ #
137
+ EOH
138
+ when :none
139
+ file.puts <<-EOH
140
+ # All rights reserved - Do Not Redistribute
141
+ #
142
+ EOH
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ desc "Create a new self-signed SSL certificate for FQDN=foo.example.com"
149
+ task :ssl_cert do
150
+ $expect_verbose = true
151
+ fqdn = ENV["FQDN"]
152
+ fqdn =~ /^(.+?)\.(.+)$/
153
+ hostname = $1
154
+ domain = $2
155
+ raise "Must provide FQDN!" unless fqdn && hostname && domain
156
+ puts "** Creating self signed SSL Certificate for #{fqdn}"
157
+ sh("(cd #{CADIR} && openssl genrsa 2048 > #{fqdn}.key)")
158
+ sh("(cd #{CADIR} && chmod 644 #{fqdn}.key)")
159
+ puts "* Generating Self Signed Certificate Request"
160
+ tf = Tempfile.new("#{fqdn}.ssl-conf")
161
+ ssl_config = <<EOH
162
+ [ req ]
163
+ distinguished_name = req_distinguished_name
164
+ prompt = no
165
+
166
+ [ req_distinguished_name ]
167
+ C = #{SSL_COUNTRY_NAME}
168
+ ST = #{SSL_STATE_NAME}
169
+ L = #{SSL_LOCALITY_NAME}
170
+ O = #{COMPANY_NAME}
171
+ OU = #{SSL_ORGANIZATIONAL_UNIT_NAME}
172
+ CN = #{fqdn}
173
+ emailAddress = #{SSL_EMAIL_ADDRESS}
174
+ EOH
175
+ tf.puts(ssl_config)
176
+ tf.close
177
+ sh("(cd #{CADIR} && openssl req -config '#{tf.path}' -new -x509 -nodes -sha1 -days 3650 -key #{fqdn}.key > #{fqdn}.crt)")
178
+ sh("(cd #{CADIR} && openssl x509 -noout -fingerprint -text < #{fqdn}.crt > #{fqdn}.info)")
179
+ sh("(cd #{CADIR} && cat #{fqdn}.crt #{fqdn}.key > #{fqdn}.pem)")
180
+ sh("(cd #{CADIR} && chmod 644 #{fqdn}.pem)")
181
+ end
@@ -0,0 +1 @@
1
+ This directory contains certificates created by the Rakefile.
@@ -0,0 +1,13 @@
1
+ #
2
+ # Chef Client Config File
3
+ #
4
+
5
+ log_level :info
6
+ log_location STDOUT
7
+ ssl_verify_mode :verify_none
8
+ registration_url "http://chef:4000"
9
+ openid_url "http://chef:4001"
10
+ template_url "http://chef:4000"
11
+ remotefile_url "http://chef:4000"
12
+ search_url "http://chef:4000"
13
+
@@ -0,0 +1,54 @@
1
+ ###
2
+ # Company and SSL Details
3
+ ###
4
+
5
+ # The company name - used for SSL certificates, and in srvious other places
6
+ COMPANY_NAME = "Example Com"
7
+
8
+ # The Country Name to use for SSL Certificates
9
+ SSL_COUNTRY_NAME = "US"
10
+
11
+ # The State Name to use for SSL Certificates
12
+ SSL_STATE_NAME = "Washington"
13
+
14
+ # The Locality Name for SSL - typically, the city
15
+ SSL_LOCALITY_NAME = "Seattle"
16
+
17
+ # What department?
18
+ SSL_ORGANIZATIONAL_UNIT_NAME = "Operations"
19
+
20
+ # The SSL contact email address
21
+ SSL_EMAIL_ADDRESS = "operations@example.com"
22
+
23
+ # License for new Cookbooks
24
+ # Can be :apachev2 or :none
25
+ NEW_COOKBOOK_LICENSE = :apachev2
26
+
27
+ ##########################
28
+ # Chef Repository Layout #
29
+ ##########################
30
+
31
+ # Where to find upstream cookbooks
32
+ COOKBOOK_PATH = "/var/chef/cookbooks"
33
+
34
+ # Where to find site-local modifications to upstream cookbooks
35
+ SITE_COOKBOOK_PATH = "/var/chef/site-cookbooks"
36
+
37
+ # Chef Config Path
38
+ CHEF_CONFIG_PATH = "/etc/chef"
39
+
40
+ # The location of the Chef Server Config file (on the server)
41
+ CHEF_SERVER_CONFIG = File.join(CHEF_CONFIG_PATH, "server.rb")
42
+
43
+ # The location of the Chef Client Config file (on the client)
44
+ CHEF_CLIENT_CONFIG = File.join(CHEF_CONFIG_PATH, "client.rb")
45
+
46
+ ###
47
+ # Useful Extras (which you probably don't need to change)
48
+ ###
49
+
50
+ # The top of the repository checkout
51
+ TOPDIR = File.expand_path(File.join(File.dirname(__FILE__), ".."))
52
+
53
+ # Where to store certificates generated with ssl_cert
54
+ CADIR = File.expand_path(File.join(TOPDIR, "certificates"))
@@ -0,0 +1,16 @@
1
+ #
2
+ # Chef Server Config File
3
+ #
4
+
5
+ log_level :info
6
+ log_location STDOUT
7
+ ssl_verify_mode :verify_none
8
+ registration_url "http://chef:4000"
9
+ openid_url "http://chef:4001"
10
+ template_url "http://chef:4000"
11
+ remotefile_url "http://chef:4000"
12
+ search_url "http://chef:4000"
13
+ cookbook_path [ "/var/chef/site-cookbooks", "/var/chef/cookbooks" ]
14
+ merb_log_path "/var/log/chef-server-merb.log"
15
+
16
+ Chef::Log::Formatter.show_time = false
@@ -0,0 +1,9 @@
1
+ #
2
+ # Chef Solo Config File
3
+ #
4
+
5
+ log_level :info
6
+ log_location STDOUT
7
+ file_cache_path "/var/chef/cookbooks"
8
+ ssl_verify_mode :verify_none
9
+ Chef::Log::Formatter.show_time = false
@@ -0,0 +1 @@
1
+ This directory contains cookbooks that modify upstream ones, or that are specific to your site.
@@ -0,0 +1,6 @@
1
+ log_level :info
2
+ log_location STDOUT
3
+ ssl_verify_mode :verify_none
4
+ cookbook_path ["/etc/chef/recipes/site-cookbooks", "/etc/chef/recipes/cookbooks"]
5
+ file_store_path "/etc/chef/recipes/"
6
+ file_cache_path "/etc/chef/recipes/"
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: conan
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - Paul Battley
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-09 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: json
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: Set up a project to enable the configuration of servers using Chef via Capistrano.
36
+ email:
37
+ - pbattley@gmail.com
38
+ executables:
39
+ - conan
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - bin/conan
46
+ - lib/conan/capistrano.rb
47
+ - lib/conan/smart_hash_merge.rb
48
+ - lib/conan/deployment/git.rb
49
+ - lib/conan/deployment/chef.rb
50
+ - lib/conan/deployment/deploy.rb
51
+ - lib/conan/deployment.rb
52
+ - lib/conan/template/config/servers.json
53
+ - lib/conan/template/config/deploy.rb
54
+ - lib/conan/template/deploy/chef/dna/base.json
55
+ - lib/conan/template/deploy/chef/dna/staging.json
56
+ - lib/conan/template/deploy/chef/dna/app.json
57
+ - lib/conan/template/deploy/chef/dna/production.json
58
+ - lib/conan/template/deploy/chef/solo.rb
59
+ - lib/conan/template/deploy/chef/recipes/config/server.rb
60
+ - lib/conan/template/deploy/chef/recipes/config/rake.rb
61
+ - lib/conan/template/deploy/chef/recipes/config/client.rb
62
+ - lib/conan/template/deploy/chef/recipes/config/solo.rb
63
+ - lib/conan/template/deploy/chef/recipes/Rakefile
64
+ - lib/conan/template/deploy/chef/recipes/certificates/README
65
+ - lib/conan/template/deploy/chef/recipes/site-cookbooks/README
66
+ - lib/conan/template/deploy/chef/bootstrap.sh
67
+ - lib/conan/template/CONAN_TODO
68
+ - lib/conan/template/Capfile
69
+ - lib/conan/initializer.rb
70
+ - README.md
71
+ has_rdoc: true
72
+ homepage: http://github.com/madebymany/conan
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.3.7
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Conan The Deployer
105
+ test_files: []
106
+