buckknife 0.0.4
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.
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/HISTORY.md +8 -0
- data/README.md +65 -0
- data/Rakefile +27 -0
- data/buckknife.gemspec +31 -0
- data/lib/buckknife.rb +44 -0
- data/lib/buckknife/command.rb +33 -0
- data/lib/buckknife/commands/add_role.rb +13 -0
- data/lib/buckknife/commands/base.rb +24 -0
- data/lib/buckknife/commands/bootstrap.rb +28 -0
- data/lib/buckknife/commands/capistrano.rb +46 -0
- data/lib/buckknife/commands/create.rb +42 -0
- data/lib/buckknife/commands/euca_create.rb +60 -0
- data/lib/buckknife/commands/rackspace_create.rb +58 -0
- data/lib/buckknife/commands/run_client.rb +49 -0
- data/lib/buckknife/data_accessor.rb +29 -0
- data/lib/buckknife/environment.rb +16 -0
- data/lib/buckknife/helper.rb +39 -0
- data/lib/buckknife/knife_helper.rb +22 -0
- data/lib/buckknife/node.rb +30 -0
- data/lib/buckknife/project.rb +80 -0
- data/lib/buckknife/templates/deploy_environments.rb.erb +85 -0
- data/lib/buckknife/templates/project.json.erb +75 -0
- data/lib/buckknife/version.rb +3 -0
- data/lib/chef/knife/project_add_role.rb +24 -0
- data/lib/chef/knife/project_bootstrap.rb +24 -0
- data/lib/chef/knife/project_capistrano.rb +19 -0
- data/lib/chef/knife/project_create.rb +53 -0
- data/lib/chef/knife/project_info.rb +13 -0
- data/lib/chef/knife/project_list.rb +17 -0
- data/lib/chef/knife/project_new.rb +28 -0
- data/lib/chef/knife/project_run_client.rb +30 -0
- data/lib/chef/knife/project_show.rb +34 -0
- data/spec/buckknife/commands/add_role_spec.rb +14 -0
- data/spec/buckknife/commands/bootstrap_spec.rb +22 -0
- data/spec/buckknife/commands/capistrano_spec.rb +13 -0
- data/spec/buckknife/commands/create_spec.rb +48 -0
- data/spec/buckknife/commands/run_client_spec.rb +15 -0
- data/spec/buckknife/environment_spec.rb +14 -0
- data/spec/buckknife/helper_spec.rb +11 -0
- data/spec/buckknife/node_spec.rb +18 -0
- data/spec/buckknife/project_spec.rb +49 -0
- data/spec/data_bags/projects/myapp.json +139 -0
- data/spec/knife.rb +4 -0
- data/spec/knife/project_bootstrap_spec.rb +0 -0
- data/spec/knife/project_info_spec.rb +17 -0
- data/spec/knife/project_list_spec.rb +18 -0
- data/spec/spec_helper.rb +27 -0
- metadata +251 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'chef/knife'
|
2
|
+
|
3
|
+
module BuckKnife
|
4
|
+
class ProjectAddRole < Chef::Knife
|
5
|
+
banner "knife project add role PROJECT [NODE]"
|
6
|
+
|
7
|
+
deps do
|
8
|
+
require 'buckknife'
|
9
|
+
include BuckKnife::KnifeHelper
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
project = project_from_arg_or_ask
|
14
|
+
node_name = @name_args[1]
|
15
|
+
nodes = Array(project.node(node_name) || project.nodes)
|
16
|
+
|
17
|
+
nodes.each do |node|
|
18
|
+
ui.output "# Run these command to add roles one at a time to #{node.name}:"
|
19
|
+
ui.output BuckKnife::Commands::AddRole.new( node )
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'chef/knife'
|
2
|
+
|
3
|
+
module BuckKnife
|
4
|
+
class ProjectBootstrap < Chef::Knife
|
5
|
+
banner "knife project bootstrap PROJECT [NODE]"
|
6
|
+
|
7
|
+
deps do
|
8
|
+
require 'buckknife'
|
9
|
+
include BuckKnife::KnifeHelper
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
project = project_from_arg_or_ask
|
14
|
+
node_name = @name_args[1]
|
15
|
+
nodes = Array(project.node(node_name) || project.nodes)
|
16
|
+
|
17
|
+
nodes.each do |node|
|
18
|
+
ui.output "# Run this command to bootstrap #{node.name}:"
|
19
|
+
ui.output BuckKnife::Commands::Bootstrap.new( project, node )
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'chef/knife'
|
2
|
+
|
3
|
+
module BuckKnife
|
4
|
+
class ProjectCapistrano < Chef::Knife
|
5
|
+
banner "knife project capistrano PROJECT"
|
6
|
+
|
7
|
+
deps do
|
8
|
+
require 'buckknife'
|
9
|
+
include BuckKnife::KnifeHelper
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
project = project_from_arg_or_ask
|
14
|
+
ui.output "# Copy and commit this file to the project's repository:"
|
15
|
+
ui.output BuckKnife::Commands::Capistrano.new(project).call
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'chef/knife'
|
2
|
+
|
3
|
+
module BuckKnife
|
4
|
+
class ProjectCreate < Chef::Knife
|
5
|
+
banner "knife project create PROJECT [NODE]"
|
6
|
+
|
7
|
+
deps do
|
8
|
+
require 'buckknife'
|
9
|
+
include BuckKnife::KnifeHelper
|
10
|
+
end
|
11
|
+
|
12
|
+
option :identity_file,
|
13
|
+
:short => "-i IDENTITY_FILE",
|
14
|
+
:long => "--identity-file",
|
15
|
+
:description => "The SSH identity file used for authentication"
|
16
|
+
|
17
|
+
option :provider,
|
18
|
+
:short => "-p PROVIDER",
|
19
|
+
:long => "--provider",
|
20
|
+
:description => "The cloud provider to use (euca, rackspace, ...)"
|
21
|
+
|
22
|
+
option :ssh_username,
|
23
|
+
:short => "-x USERNAME",
|
24
|
+
:long => "--ssh-user",
|
25
|
+
:description => "The ssh username"
|
26
|
+
|
27
|
+
def run
|
28
|
+
project = project_from_arg_or_ask
|
29
|
+
node_name = @name_args[1]
|
30
|
+
nodes = Array(project.node(node_name) || project.nodes)
|
31
|
+
|
32
|
+
project.identity_file = Chef::Config[:knife][:euca_identity_file] if Chef::Config[:knife][:euca_identity_file]
|
33
|
+
project.provider = config[:provider] if config[:provider]
|
34
|
+
project.ssh_username = config[:ssh_username] if config[:ssh_username]
|
35
|
+
|
36
|
+
# TODO: Move this into project, ActiveModel validation?
|
37
|
+
unless project.valid?
|
38
|
+
ui.fatal("The #{project.name}.json file has some errors that need to be fixed:")
|
39
|
+
project.errors.each do |att, err|
|
40
|
+
ui.fatal("'#{att}' #{err}")
|
41
|
+
end
|
42
|
+
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
|
46
|
+
nodes.each do |node|
|
47
|
+
ui.output "# Run this command to create #{node.name}:"
|
48
|
+
ui.output BuckKnife::Commands::Create[project.provider].new(project, node)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'chef/knife'
|
2
|
+
|
3
|
+
module BuckKnife
|
4
|
+
class ProjectInfo < Chef::Knife
|
5
|
+
banner "knife project info"
|
6
|
+
|
7
|
+
def run
|
8
|
+
ui.output "Config file: %s" % Chef::Config[:config_file] || config[:config_file]
|
9
|
+
ui.output "Chef Server: %s" % Chef::Config[:chef_server_url]
|
10
|
+
ui.output "Project Dir: %s" % Chef::Config[:knife][:project_dir]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'chef/knife'
|
2
|
+
|
3
|
+
module BuckKnife
|
4
|
+
class ProjectList < Chef::Knife
|
5
|
+
banner "knife project list"
|
6
|
+
|
7
|
+
deps do
|
8
|
+
require 'buckknife'
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
BuckKnife::Project.all.each do |project|
|
13
|
+
ui.output " #{project.name}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'chef/knife'
|
2
|
+
|
3
|
+
module BuckKnife
|
4
|
+
class ProjectNew < Chef::Knife
|
5
|
+
banner "knife project new PROJECT"
|
6
|
+
|
7
|
+
deps do
|
8
|
+
require 'buckknife'
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
project_name = @name_args[0]
|
13
|
+
|
14
|
+
if project_name.nil?
|
15
|
+
show_usage
|
16
|
+
ui.fatal("You must specify a project name")
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
template = BuckKnife.template_root.join("project.json.erb").read
|
21
|
+
compiled = ERB.new(template, nil, '%>').result(binding)
|
22
|
+
project_path = Project.root.join("#{project_name}.json")
|
23
|
+
project_path.open("w") { |f| f.write compiled }
|
24
|
+
|
25
|
+
ui.output ui.color("#{project_name}.json written to #{project_path}", :green)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'chef/knife'
|
2
|
+
|
3
|
+
module BuckKnife
|
4
|
+
class ProjectRunClient < Chef::Knife
|
5
|
+
banner "knife project run client PROJECT [NODE] [options]"
|
6
|
+
|
7
|
+
deps do
|
8
|
+
require 'buckknife'
|
9
|
+
include BuckKnife::KnifeHelper
|
10
|
+
end
|
11
|
+
|
12
|
+
option :env,
|
13
|
+
:short => "-e ENVIRONMENT",
|
14
|
+
:long => "--env ENVIRONMENT",
|
15
|
+
:description => "Project environment to scope to (dev,staging,production)"
|
16
|
+
|
17
|
+
def run
|
18
|
+
project = project_from_arg_or_ask
|
19
|
+
node_name = @name_args[1]
|
20
|
+
|
21
|
+
ui.output "# Run this command to run client:"
|
22
|
+
ui.output BuckKnife::Commands::RunClient.new(
|
23
|
+
:project => project.name,
|
24
|
+
:node => node_name,
|
25
|
+
:environment => config[:env]
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'chef/knife'
|
2
|
+
|
3
|
+
module BuckKnife
|
4
|
+
class ProjectShow < Chef::Knife
|
5
|
+
banner "knife project show PROJECT"
|
6
|
+
|
7
|
+
deps do
|
8
|
+
require 'buckknife'
|
9
|
+
include BuckKnife::KnifeHelper
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
ui.use_presenter BuckKnife::ProjectPresenter
|
14
|
+
project = project_from_arg_or_ask
|
15
|
+
output(project)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class ProjectPresenter < Chef::Knife::Core::GenericPresenter
|
20
|
+
|
21
|
+
def summarize(project)
|
22
|
+
summarized = <<-SUMMARY
|
23
|
+
#{ui.color('Project Name:', :bold)} #{ui.color(project.name, :bold)}
|
24
|
+
#{key('Environments:')} #{project.environment_names.join(', ')}
|
25
|
+
#{key('Nodes:')} #{project.node_names.join("\n" + ' ' * 14)}
|
26
|
+
SUMMARY
|
27
|
+
end
|
28
|
+
|
29
|
+
def key(key_text)
|
30
|
+
ui.color(key_text, :cyan)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BuckKnife::Commands::AddRole do
|
4
|
+
it "should output a knife command to add roles" do
|
5
|
+
project = BuckKnife::Project.find('myapp')
|
6
|
+
node = project.node('myapp-monitor1')
|
7
|
+
cmd = BuckKnife::Commands::AddRole.new(node)
|
8
|
+
|
9
|
+
cmd.to_s.should == [
|
10
|
+
"knife node run_list add myapp-monitor1 'role[monitor_client]'",
|
11
|
+
"knife node run_list add myapp-monitor1 'role[rails_app]'"
|
12
|
+
].join("\n")
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# cli = BuckKnife::CLI.new(args, options, config)
|
2
|
+
# cli.invoke(:task, [first_arg, second_arg, third_arg], {options hash})
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe BuckKnife::Commands::Bootstrap do
|
6
|
+
it "should output a knife command to bootstrap the server on rackspace" do
|
7
|
+
project = BuckKnife::Project.find('myapp')
|
8
|
+
node = project.node('myapp-monitor1')
|
9
|
+
cmd = BuckKnife::Commands::Bootstrap.new(project, node)
|
10
|
+
|
11
|
+
cmd.to_s.should == [
|
12
|
+
"knife bootstrap 127.0.0.1",
|
13
|
+
"-N myapp-monitor1",
|
14
|
+
"-x username",
|
15
|
+
"-P password",
|
16
|
+
"-r 'role[base],recipe[base_projects::myapp],role[base_server]'",
|
17
|
+
"-d ubuntu10.04.deb",
|
18
|
+
"--sudo"
|
19
|
+
].join(' ')
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# cli = BuckKnife::CLI.new(args, options, config)
|
2
|
+
# cli.invoke(:task, [first_arg, second_arg, third_arg], {options hash})
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe BuckKnife::Commands::Capistrano do
|
6
|
+
it "should output a capistrano deploy script for a project" do
|
7
|
+
BuckKnife::Commands::Capistrano.any_instance.stub(:fetch_ip) { "127.0.0.1" }
|
8
|
+
project = BuckKnife::Project.find('myapp')
|
9
|
+
cmd = BuckKnife::Commands::Capistrano.new(project)
|
10
|
+
|
11
|
+
cmd.call.should =~ /DO NOT MODIFY THIS FILE/
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# cli = BuckKnife::CLI.new(args, options, config)
|
2
|
+
# cli.invoke(:task, [first_arg, second_arg, third_arg], {options hash})
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe BuckKnife::Commands::Create do
|
6
|
+
it "should output a knife command to create the server on rackspace" do
|
7
|
+
project = BuckKnife::Project.find('myapp')
|
8
|
+
node = project.node('myapp-monitor1')
|
9
|
+
cmd = BuckKnife::Commands::Create[project.provider].new(project, node)
|
10
|
+
|
11
|
+
cmd.to_s.should == [
|
12
|
+
"knife rackspace server create",
|
13
|
+
"-r 'role[base],recipe[base_projects::myapp],role[base_server]'",
|
14
|
+
"-f 4",
|
15
|
+
"-I 49",
|
16
|
+
"-d ubuntu10.04.deb",
|
17
|
+
"-s http://localhost:4000",
|
18
|
+
"-N myapp-monitor1",
|
19
|
+
"-S myapp-monitor1",
|
20
|
+
"-K ''",
|
21
|
+
"-A ''"
|
22
|
+
].join(' ')
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should output a knife command to create the server on eucalyptus" do
|
27
|
+
project = BuckKnife::Project.find('myapp')
|
28
|
+
project.should_receive(:provider) { "euca" }.twice
|
29
|
+
node = project.node('myapp-monitor1')
|
30
|
+
|
31
|
+
node.flavor.should be_nil
|
32
|
+
|
33
|
+
cmd = BuckKnife::Commands::Create[project.provider].new(project, node)
|
34
|
+
cmd.should_receive(:availability_zone) { "us-west-1" }.twice
|
35
|
+
|
36
|
+
cmd.to_s.should == [
|
37
|
+
"knife euca server create",
|
38
|
+
"-r 'role[base],recipe[base_projects::myapp],role[base_server]'",
|
39
|
+
"-f m1.large",
|
40
|
+
"-I emi-DFB9107F",
|
41
|
+
"-d ubuntu10.04.deb",
|
42
|
+
"-s http://localhost:4000",
|
43
|
+
"-N myapp-monitor1",
|
44
|
+
"-Z us-west-1"
|
45
|
+
].join(' ')
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BuckKnife::Commands::RunClient do
|
4
|
+
it "should output a knife command to add roles" do
|
5
|
+
cmd = BuckKnife::Commands::RunClient.new(:project => 'myapp', :node => 'myapp-monitor1')
|
6
|
+
|
7
|
+
cmd.to_s.should == [
|
8
|
+
"knife ssh 'project:myapp AND name:myapp-monitor1'",
|
9
|
+
"'sudo chef-client'",
|
10
|
+
"--attribute ipaddress",
|
11
|
+
"-x username",
|
12
|
+
"-P password"
|
13
|
+
].join(' ')
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BuckKnife::Environment do
|
4
|
+
context "initialized with a name and hash of data" do
|
5
|
+
subject { BuckKnife::Environment.new("dev", {"domain_name" => "dev.myapp.com"}, []) }
|
6
|
+
it "should have a name" do
|
7
|
+
subject.name.should == "dev"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should have a domain name" do
|
11
|
+
subject.domain_name.should == "dev.myapp.com"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BuckKnife::Helper do
|
4
|
+
it "should create a run list from roles and recipes" do
|
5
|
+
roles = ['base', 'base_server']
|
6
|
+
recipes = ["base_projects::projectname"]
|
7
|
+
sep = ','
|
8
|
+
result = BuckKnife::Helper.combine_roles_and_recipes(roles, recipes, sep)
|
9
|
+
result.should == "role[base],role[base_server],recipe[base_projects::projectname]"
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BuckKnife::Node do
|
4
|
+
context "initialized with a hash of data" do
|
5
|
+
subject { BuckKnife::Project.find("myapp").node("myapp-monitor1") }
|
6
|
+
it "should have a name" do
|
7
|
+
subject.name.should == "myapp-monitor1"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should have a size" do
|
11
|
+
subject.size.should == "2G"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have a run list" do
|
15
|
+
subject.run_list.should == "role[monitor_client] role[rails_app]"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BuckKnife::Project do
|
4
|
+
context "initialized with a hash of data" do
|
5
|
+
subject { BuckKnife::Project.find("myapp") }
|
6
|
+
it "should have a name" do
|
7
|
+
subject.name.should == "myapp"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should have node names" do
|
11
|
+
subject.node_names.should == %w[
|
12
|
+
myapp-dev-app1
|
13
|
+
myapp-dev-app2
|
14
|
+
myapp-dev-job1
|
15
|
+
myapp-monitor1
|
16
|
+
myapp-prod-app1
|
17
|
+
myapp-prod-app2
|
18
|
+
myapp-prod-job1
|
19
|
+
myapp-staging-app1
|
20
|
+
myapp-staging-app2
|
21
|
+
myapp-staging-job1
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have nodes" do
|
26
|
+
subject.nodes.first.should be_instance_of BuckKnife::Node
|
27
|
+
end
|
28
|
+
|
29
|
+
it "can look up a node based on name" do
|
30
|
+
subject.node("myapp-monitor1").should be_instance_of BuckKnife::Node
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should have a repository" do
|
34
|
+
subject.repository.should == "http://svn.domain.com/myapp/trunk"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have environment names" do
|
38
|
+
subject.environment_names.should == ["dev", "production", "staging"]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have environments" do
|
42
|
+
subject.environments.first.should be_instance_of BuckKnife::Environment
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should have a provider" do
|
46
|
+
subject.provider.should == "rackspace"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|