sous-chef 0.0.3 → 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 CHANGED
@@ -2,4 +2,5 @@
2
2
  .rvmrc
3
3
  .ruby-version
4
4
  *.gem
5
+ tmp
5
6
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sous-chef (0.0.0)
4
+ sous-chef (0.0.3)
5
5
  knife-solo (~> 0.1.0)
6
6
  rake (~> 10.0.3)
7
7
 
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # SousChef
1
+ # Sous Chef
2
2
 
3
3
  Note: This gem is a work in progress.
4
4
 
5
- Manage knife-solo nodes.
5
+ Manage [knife-solo](http://matschaffer.github.com/knife-solo/) nodes.
6
6
 
7
7
  ## Install
8
8
 
@@ -12,20 +12,38 @@ Add the following to your `Rakefile`:
12
12
  require 'sous-chef'
13
13
  ```
14
14
 
15
+ You may run `rake sous_chef` to generate sample `nodes.yml` to `nodes/nodes.yml`
16
+
15
17
  ## Configure
16
18
 
17
19
  Create configuration in knife-solo nodes dir e.g. `nodes/nodes.yml`. Node
18
20
  configuration is used for sshconfig as well as nodename. Example `nodes.yml`:
19
21
 
20
22
  ```yaml
21
- SuperAwesomeNode:
22
- HostName: 12.34.56.789
23
- Port 1234
24
- IdentityFile: ~/.ssh/other_id_rsa
23
+ # Format:
24
+ #
25
+ # <node name>:
26
+ # node_config: <knife-solo node config e.g. nodes/someNode.json>
27
+ # ssh_config:
28
+ # <ssh config options>
29
+ # e.g.
30
+ # Host: <host alias. defaults to node name>
31
+ # HostName: 12.34.56.789
32
+ # Port: 1234
33
+ # IdentityFile: ~/.ssh/other_id_rsa
34
+ #
25
35
 
36
+ SuperAwesomeNode:
37
+ node_config: nodes/some_node.json
38
+ ssh_config:
39
+ HostName: 12.34.56.789
40
+ Port 1234
41
+ IdentityFile: ~/.ssh/other_id_rsa
26
42
 
27
43
  OtherAwesome:
28
- HostName: localhost
44
+ node_config: nodes/some_node.json
45
+ ssh_config:
46
+ HostName: 12.34.56.789
29
47
  ```
30
48
 
31
49
  ## Usage
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'bundler/gem_tasks'
6
+ require 'rspec/core/rake_task'
7
+
8
+ desc 'Default: run unit tests.'
9
+ task :default => :spec
10
+
11
+ desc "Run all specs"
12
+ RSpec::Core::RakeTask.new do |t|
13
+ t.pattern = 'spec/**/*_spec.rb'
14
+ t.rspec_opts = '--color'
15
+ end
16
+
@@ -0,0 +1,25 @@
1
+ module SousChef
2
+ class Manager
3
+ attr_accessor :nodes
4
+ attr_reader :parser
5
+
6
+ def initialize(config_file)
7
+ @parser = Parser.new(config_file)
8
+ @nodes = {}
9
+ initialize_nodes
10
+ end
11
+
12
+ def all
13
+ @nodes.keys
14
+ end
15
+
16
+ private
17
+
18
+ def initialize_nodes
19
+ @parser.parse.each do |node, settings|
20
+ @nodes[node] = Node.new(node, settings)
21
+ end
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,54 @@
1
+ class SousChef::Node
2
+ attr_reader :name
3
+
4
+ require 'tempfile'
5
+
6
+ def initialize(node, settings)
7
+ @settings = settings
8
+ @name = node
9
+ end
10
+
11
+ def config
12
+ @config ||= @settings['node_config'] || {}
13
+ end
14
+
15
+ def hostname
16
+ @hostname ||= ssh_hash['Host'] || @name
17
+ end
18
+
19
+ def ssh_config
20
+ @ssh_config ||= begin
21
+ config = "Host #{hostname}\n"
22
+ ssh_attrs.each do |key, value|
23
+ config << " #{key} #{value}\n"
24
+ end
25
+ config
26
+ end
27
+ end
28
+
29
+ def ssh_config_path
30
+ @ssh_config_file ||= begin
31
+ config_file = Tempfile.new('agent_ssh_config')
32
+ config_file.write(ssh_config)
33
+ config_file.close
34
+ at_exit { config_file.delete }
35
+ config_file
36
+ end
37
+ @ssh_config_file.path
38
+ end
39
+
40
+ private
41
+
42
+ def ssh_hash
43
+ @ssh_hash ||= @settings['ssh_config'] || {}
44
+ end
45
+
46
+ def ssh_attrs
47
+ @ssh_attrs ||= begin
48
+ ssh_attrs = ssh_hash.clone
49
+ ssh_attrs.delete('Host')
50
+ ssh_attrs
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,22 @@
1
+ class SousChef::Parser
2
+ attr_reader :config_file
3
+
4
+ def initialize(config_file)
5
+ @config_file = config_file
6
+ end
7
+
8
+ def parse
9
+ parse_yaml(@config_file)
10
+ end
11
+
12
+ private
13
+
14
+ def parse_yaml(config_file)
15
+ if File.exists?(config_file)
16
+ YAML.load_file(config_file)
17
+ else
18
+ {}
19
+ end
20
+ end
21
+ end
22
+
@@ -1,5 +1,4 @@
1
- require 'tempfile'
2
- require 'yaml'
1
+ require 'rake'
3
2
 
4
3
  def run(command)
5
4
  puts "Running: #{command}"
@@ -8,97 +7,30 @@ def run(command)
8
7
  end
9
8
 
10
9
  def run_knife(command, node)
11
- run "knife solo #{command} -F #{agents_ssh_config_path} #{node} -N #{node} nodes/buildAgent.json"
10
+ run "knife solo #{command} -F #{node.ssh_config_path} #{node.hostname} -N #{node.name} #{node.config}"
12
11
  end
13
12
 
14
- def agents
15
- agents_path = File.join(Dir.pwd, "nodes", "nodes.yml")
16
- unless File.exists? agents_path
17
- puts "Can't find #{agents_path}"
18
- exit 1
19
- end
20
- YAML.load_file(agents_path)
21
- end
22
-
23
- def agents_ssh_config_path
24
- @agents_ssh_config_path ||= begin
25
- ssh_config_file = Tempfile.new('agent_ssh_config')
26
- agents.each do |node, attrs|
27
- ssh_config_file.write("Host #{node}\n")
28
- attrs.each do |key, value|
29
- ssh_config_file.write(" #{key} #{value}\n")
30
- end
31
- end
32
- ssh_config_file.close
33
- at_exit { ssh_config_file.delete }
34
- ssh_config_file.path
35
- end
36
- end
37
-
38
- def agent_names
39
- agents.map { |key, value| key }
40
- end
41
-
42
- agent_names.each do |node|
43
- namespace node do
44
- desc "Run knife solo prepare for #{node}"
13
+ SousChef::Manager.new(SousChef::CONFIG_FILE).nodes.each do |name, node|
14
+ namespace name do
15
+ desc "Run knife solo prepare for #{name}"
45
16
  task :prepare do
46
17
  run_knife 'prepare', node
47
18
  end
48
19
 
49
- desc "Run knife solo cook for #{node}"
20
+ desc "Run knife solo cook for #{name}"
50
21
  task :cook do
51
22
  run_knife 'cook', node
52
23
  end
53
24
 
54
- desc "Run knife solo bootstrap for #{node}"
25
+ desc "Run knife solo bootstrap for #{name}"
55
26
  task :bootstrap do
56
27
  run_knife 'bootstrap', node
57
28
  end
58
29
  end
59
30
  end
60
31
 
61
- namespace :vagrant do
62
- def vagrant_ssh_config_path
63
- @vagrant_ssh_config_paths ||= begin
64
- ssh_config_file = Tempfile.new('vagrant-ssh-config')
65
- ssh_config_file.write(`vagrant ssh-config`)
66
- ssh_config_file.write(' LogLevel quiet')
67
- ssh_config_file.close
68
- ssh_config_file.path
69
- end
70
- end
71
-
72
- def run_knife_vagrant(command)
73
- run "knife solo #{command} -F #{vagrant_ssh_config_path} default nodes/buildAgent.json"
74
- end
75
-
76
- desc "Start the VM for the Vagrant Utility box"
77
- task :up do
78
- run "vagrant up"
79
- end
80
-
81
- desc "Prepare the Vagrant Utility box for provisioning"
82
- task :prepare => [:up] do
83
- run_knife_vagrant 'prepare'
84
- end
85
-
86
- desc "Provision the Vagrant Utility box"
87
- task :cook do
88
- run_knife_vagrant 'cook'
89
- end
90
-
91
- desc "Bootstrap (prepare & cook) the Vagrant Utility box"
92
- task :bootstrap => [:up] do
93
- run_knife_vagrant 'bootstrap'
94
- end
95
-
96
- desc "Destroy Vagrant Utility box"
97
- task :destroy do
98
- run "vagrant destroy -f"
99
- end
100
-
101
- desc "Cleans Vagrant Utility box, creating a fresh box"
102
- task :clean => [:destroy, :up]
32
+ desc "Generate nodes.yml example config"
33
+ task :sous_chef do
34
+ SousChef.create_config
103
35
  end
104
36
 
data/lib/sous-chef.rb CHANGED
@@ -1,10 +1,22 @@
1
- require 'rake'
2
-
3
- load 'sous-chef/tasks.rb'
4
1
 
5
2
  module SousChef
3
+ CONFIG_FILE = File.join(Dir.pwd, "nodes", "nodes.yml")
4
+
6
5
  class << self
7
- attr_accessor :agents
6
+ def create_config
7
+ template = File.expand_path(File.join(File.dirname(__FILE__), 'templates', 'nodes.example.yml'))
8
+ if File.exists?(CONFIG_FILE)
9
+ puts "nodes.yml already exists"
10
+ else
11
+ puts "Coping example nodes.yml and placing in #{SousChef::CONFIG_FILE}"
12
+ FileUtils.cp(template, CONFIG_FILE)
13
+ end
14
+ end
8
15
  end
9
16
  end
10
17
 
18
+ require 'sous-chef/parser.rb'
19
+ require 'sous-chef/node.rb'
20
+ require 'sous-chef/manager.rb'
21
+ require 'sous-chef/tasks.rb'
22
+
@@ -0,0 +1,2 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'sous-chef', 'tasks'))
2
+
@@ -0,0 +1,13 @@
1
+ # Format:
2
+ #
3
+ # <node name>:
4
+ # node_config: <knife-solo node config e.g. nodes/someNode.json>
5
+ # ssh_config:
6
+ # <ssh config options>
7
+ # e.g.
8
+ # Host: <host alias. defaults to node name>
9
+ # HostName: 12.34.56.789
10
+ # Port: 1234
11
+ # IdentityFile: ~/.ssh/other_id_rsa
12
+ #
13
+
data/sous-chef.gemspec CHANGED
@@ -6,13 +6,13 @@ Gem::Specification.new do |s|
6
6
  s.email = "shaun@substantail.com"
7
7
 
8
8
  s.name = 'sous-chef'
9
- s.version = "0.0.3"
9
+ s.version = "0.0.4"
10
10
  s.description = %q{Manage knife-solo nodes}
11
11
  s.summary = %q{Manage knife-solo nodes}
12
- s.homepage = %q{http://github.com/substantial/sous-chef}
13
- s.rubyforge_project = "sous-chef"
12
+ s.homepage = %q{http://github.com/substantial/sous-chef}
13
+ s.license = "MIT"
14
14
 
15
- s.license = "MIT"
15
+ s.rubyforge_project = "sous-chef"
16
16
 
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -0,0 +1,7 @@
1
+ SuperAwesomeNode:
2
+ node_config: some/path/to/node/config
3
+ ssh_config:
4
+ HostName: Some IP
5
+ Port: 1234
6
+ IdentityFile: ~/.ssh/other_id_rsa
7
+
@@ -0,0 +1,12 @@
1
+ SuperAwesomeNode:
2
+ node_config: some/path/to/node/config
3
+ ssh_config:
4
+ HostName: 12.34.56.789
5
+ Port: 1234
6
+ IdentityFile: ~/.ssh/other_id_rsa
7
+
8
+ OtherAwesome:
9
+ node_config: some/path/to/node/config
10
+ ssh_config:
11
+ HostName: localhost
12
+
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe SousChef::Manager do
4
+ let(:manager) { SousChef::Manager.new(File.join(SPEC_ROOT, "fixtures", "some_nodes.yml")) }
5
+
6
+ describe "#initialize" do
7
+ it "instantiates a parser with the config file" do
8
+ manager.parser.should be_a SousChef::Parser
9
+ end
10
+
11
+ it "instantiates nodes" do
12
+ manager.nodes.should be_a Hash
13
+ end
14
+ end
15
+
16
+ describe "#all" do
17
+ it "returns node names" do
18
+ manager.all.should =~ %w[SuperAwesomeNode OtherAwesome]
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe SousChef::Node do
4
+ let(:node_hash) { {
5
+ "node_config" => "some/path/to/node/config",
6
+ "ssh_config" => { "HostName" => "Some IP" }
7
+ }}
8
+
9
+ subject { SousChef::Node.new('SuperAwesomeNode', node_hash) }
10
+
11
+ describe "#name" do
12
+ its(:name) { should == "SuperAwesomeNode" }
13
+ end
14
+
15
+ describe "#config" do
16
+ its(:config) { should == 'some/path/to/node/config' }
17
+ end
18
+
19
+ describe "#hostname" do
20
+ its(:hostname) { should == 'SuperAwesomeNode' }
21
+
22
+ context "with host in ssh_config" do
23
+ before { node_hash["ssh_config"]["Host"] = 'Some other name'}
24
+ its(:hostname) { should == 'Some other name'}
25
+ end
26
+ end
27
+
28
+ describe "#ssh_config" do
29
+ it "returns ssh_config" do
30
+ subject.ssh_config.should include "Host SuperAwesomeNode\n"
31
+ subject.ssh_config.should include "HostName Some IP\n"
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe SousChef::Parser do
4
+ describe "#initialize" do
5
+ let(:parser) { SousChef::Parser.new('some config file') }
6
+
7
+ it 'sets config file' do
8
+ parser.config_file.should == 'some config file'
9
+ end
10
+ end
11
+
12
+ describe "#parse" do
13
+ subject { SousChef::Parser.new(File.join(SPEC_ROOT, "fixtures", "some_nodes.yml")).parse }
14
+
15
+ it "parses yaml" do
16
+ subject.keys.should =~ %w[SuperAwesomeNode OtherAwesome]
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,11 @@
1
+ require 'bundler'
2
+ Bundler.setup
3
+
4
+ SPEC_ROOT = File.dirname(__FILE__)
5
+
6
+ RSpec.configure do |config|
7
+ config.mock_with :rspec
8
+ end
9
+
10
+ require File.join(SPEC_ROOT, '/../lib/sous-chef')
11
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sous-chef
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-24 00:00:00.000000000 Z
12
+ date: 2013-01-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -101,10 +101,21 @@ files:
101
101
  - Gemfile
102
102
  - Gemfile.lock
103
103
  - README.md
104
+ - Rakefile
104
105
  - lib/sous-chef.rb
106
+ - lib/sous-chef/manager.rb
107
+ - lib/sous-chef/node.rb
108
+ - lib/sous-chef/parser.rb
105
109
  - lib/sous-chef/tasks.rb
106
- - lib/sous-chef/tasks/sous-chef.rake
110
+ - lib/tasks/sous-chef.rake
111
+ - lib/templates/nodes.example.yml
107
112
  - sous-chef.gemspec
113
+ - spec/fixtures/single_node.yml
114
+ - spec/fixtures/some_nodes.yml
115
+ - spec/sous-chef/manager_spec.rb
116
+ - spec/sous-chef/node_spec.rb
117
+ - spec/sous-chef/parser_spec.rb
118
+ - spec/spec_helper.rb
108
119
  homepage: http://github.com/substantial/sous-chef
109
120
  licenses:
110
121
  - MIT
@@ -130,4 +141,10 @@ rubygems_version: 1.8.24
130
141
  signing_key:
131
142
  specification_version: 3
132
143
  summary: Manage knife-solo nodes
133
- test_files: []
144
+ test_files:
145
+ - spec/fixtures/single_node.yml
146
+ - spec/fixtures/some_nodes.yml
147
+ - spec/sous-chef/manager_spec.rb
148
+ - spec/sous-chef/node_spec.rb
149
+ - spec/sous-chef/parser_spec.rb
150
+ - spec/spec_helper.rb
@@ -1,2 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '../sous-chef', 'tasks'))
2
-