knife_sous 0.0.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.
Files changed (48) hide show
  1. data/.gitignore +1 -0
  2. data/.ruby-version +1 -0
  3. data/Gemfile +9 -0
  4. data/Gemfile.lock +106 -0
  5. data/Guardfile +6 -0
  6. data/README.md +51 -0
  7. data/Rakefile +16 -0
  8. data/knife_sous.gemspec +28 -0
  9. data/lib/chef/knife/sous_bootstrap.rb +31 -0
  10. data/lib/chef/knife/sous_clean.rb +30 -0
  11. data/lib/chef/knife/sous_cook.rb +31 -0
  12. data/lib/chef/knife/sous_init.rb +39 -0
  13. data/lib/chef/knife/sous_list.rb +22 -0
  14. data/lib/chef/knife/sous_prepare.rb +31 -0
  15. data/lib/knife_sous/configure_command.rb +12 -0
  16. data/lib/knife_sous/dsl_definitions.rb +29 -0
  17. data/lib/knife_sous/dsl_wrapper.rb +8 -0
  18. data/lib/knife_sous/mixins/hash_mixins.rb +14 -0
  19. data/lib/knife_sous/namespace.rb +19 -0
  20. data/lib/knife_sous/namespace_presenter.rb +27 -0
  21. data/lib/knife_sous/node.rb +47 -0
  22. data/lib/knife_sous/node_command.rb +36 -0
  23. data/lib/knife_sous/node_presenter.rb +13 -0
  24. data/lib/knife_sous/processor_command.rb +52 -0
  25. data/lib/knife_sous.rb +3 -0
  26. data/lib/templates/nodes.example.rb +32 -0
  27. data/spec/lib/chef/knife/sous_bootstrap_spec.rb +42 -0
  28. data/spec/lib/chef/knife/sous_clean_spec.rb +41 -0
  29. data/spec/lib/chef/knife/sous_cook_spec.rb +52 -0
  30. data/spec/lib/chef/knife/sous_init_spec.rb +56 -0
  31. data/spec/lib/chef/knife/sous_list_spec.rb +33 -0
  32. data/spec/lib/chef/knife/sous_prepare_spec.rb +42 -0
  33. data/spec/lib/knife_sous/configure_command_spec.rb +27 -0
  34. data/spec/lib/knife_sous/dsl_definitions_spec.rb +52 -0
  35. data/spec/lib/knife_sous/dsl_wrapper_spec.rb +12 -0
  36. data/spec/lib/knife_sous/mixins/hash_mixins_spec.rb +23 -0
  37. data/spec/lib/knife_sous/namespace_presenter_spec.rb +57 -0
  38. data/spec/lib/knife_sous/namespace_spec.rb +59 -0
  39. data/spec/lib/knife_sous/node_presenter_spec.rb +18 -0
  40. data/spec/lib/knife_sous/node_spec.rb +63 -0
  41. data/spec/lib/knife_sous/processor_command_spec.rb +135 -0
  42. data/spec/spec_helper.rb +14 -0
  43. data/spec/support/fixtures/nodes.rb +20 -0
  44. data/spec/support/knife_command_helpers.rb +11 -0
  45. data/spec/support/shared_examples/collection.rb +24 -0
  46. data/spec/support/shared_examples/dsl_wrapper.rb +11 -0
  47. data/spec/support/shared_examples/node_command.rb +66 -0
  48. metadata +178 -0
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ tmp
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-1.9.3-p362@knife_sous
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'guard'
6
+ gem 'guard-rspec'
7
+ gem 'pry'
8
+ gem 'rb-fsevent'
9
+
data/Gemfile.lock ADDED
@@ -0,0 +1,106 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ knife_sous (0.0.1)
5
+ knife-solo (~> 0.2.0)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ archive-tar-minitar (0.5.2)
11
+ chef (11.4.0)
12
+ erubis
13
+ highline (>= 1.6.9)
14
+ json (>= 1.4.4, <= 1.7.7)
15
+ mixlib-authentication (>= 1.3.0)
16
+ mixlib-cli (~> 1.3.0)
17
+ mixlib-config (>= 1.1.2)
18
+ mixlib-log (>= 1.3.0)
19
+ mixlib-shellout
20
+ net-ssh (~> 2.6)
21
+ net-ssh-multi (~> 1.1.0)
22
+ ohai (>= 0.6.0)
23
+ rest-client (>= 1.0.4, < 1.7.0)
24
+ yajl-ruby (~> 1.1)
25
+ coderay (1.0.8)
26
+ diff-lcs (1.1.3)
27
+ erubis (2.7.0)
28
+ guard (1.6.2)
29
+ listen (>= 0.6.0)
30
+ lumberjack (>= 1.0.2)
31
+ pry (>= 0.9.10)
32
+ terminal-table (>= 1.4.3)
33
+ thor (>= 0.14.6)
34
+ guard-rspec (2.4.0)
35
+ guard (>= 1.1)
36
+ rspec (~> 2.11)
37
+ highline (1.6.15)
38
+ ipaddress (0.8.0)
39
+ json (1.7.7)
40
+ knife-solo (0.2.0)
41
+ chef (>= 10.12)
42
+ librarian (~> 0.0.20)
43
+ net-ssh (>= 2.2.2, < 3.0)
44
+ librarian (0.0.26)
45
+ archive-tar-minitar (>= 0.5.2)
46
+ chef (>= 0.10)
47
+ highline
48
+ thor (~> 0.15)
49
+ listen (0.7.2)
50
+ lumberjack (1.0.2)
51
+ method_source (0.8.1)
52
+ mime-types (1.21)
53
+ mixlib-authentication (1.3.0)
54
+ mixlib-log
55
+ mixlib-cli (1.3.0)
56
+ mixlib-config (1.1.2)
57
+ mixlib-log (1.4.1)
58
+ mixlib-shellout (1.1.0)
59
+ net-ssh (2.6.5)
60
+ net-ssh-gateway (1.2.0)
61
+ net-ssh (>= 2.6.5)
62
+ net-ssh-multi (1.1)
63
+ net-ssh (>= 2.1.4)
64
+ net-ssh-gateway (>= 0.99.0)
65
+ ohai (6.16.0)
66
+ ipaddress
67
+ mixlib-cli
68
+ mixlib-config
69
+ mixlib-log
70
+ mixlib-shellout
71
+ systemu
72
+ yajl-ruby
73
+ pry (0.9.11.4)
74
+ coderay (~> 1.0.5)
75
+ method_source (~> 0.8)
76
+ slop (~> 3.4)
77
+ rake (10.0.3)
78
+ rb-fsevent (0.9.3)
79
+ rest-client (1.6.7)
80
+ mime-types (>= 1.16)
81
+ rspec (2.12.0)
82
+ rspec-core (~> 2.12.0)
83
+ rspec-expectations (~> 2.12.0)
84
+ rspec-mocks (~> 2.12.0)
85
+ rspec-core (2.12.2)
86
+ rspec-expectations (2.12.1)
87
+ diff-lcs (~> 1.1.3)
88
+ rspec-mocks (2.12.1)
89
+ slop (3.4.3)
90
+ systemu (2.5.2)
91
+ terminal-table (1.4.5)
92
+ thor (0.17.0)
93
+ yajl-ruby (1.1.0)
94
+
95
+ PLATFORMS
96
+ ruby
97
+
98
+ DEPENDENCIES
99
+ bundler (~> 1.1)
100
+ guard
101
+ guard-rspec
102
+ knife_sous!
103
+ pry
104
+ rake (~> 10.0.0)
105
+ rb-fsevent
106
+ rspec (~> 2.12.0)
data/Guardfile ADDED
@@ -0,0 +1,6 @@
1
+
2
+ guard 'rspec', cli: '--color' do
3
+ watch(%r{^spec/.+_spec\.rb$})
4
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
5
+ watch('spec/spec_helper.rb') { "spec" }
6
+ end
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # Knife Sous
2
+
3
+ A Chef Knife plugin which uses a DSL to configure and manage
4
+ [knife-solo](http://matschaffer.github.com/knife-solo/) nodes.
5
+
6
+ ## Usage
7
+
8
+ Simply ensure the gem is installed using:
9
+
10
+ gem install knife_sous
11
+
12
+ Or add this to your Gemfile if you use bundler:
13
+
14
+ gem 'knife_sous'
15
+
16
+ Having the gem installed will add Knife subcommands. Run `knife sous` with no
17
+ arguments to see a list of available commands.
18
+
19
+
20
+ ## Configure
21
+
22
+ Node configuration is done in `nodes/nodes.rb`. It uses a DSL similar to Rake.
23
+ You can namespace your nodes however you want. Example `nodes.rb`:
24
+
25
+ ```rb
26
+ namespace :production do |prod|
27
+ prod.namespace :web do |web|
28
+ web.node :nodetastic,
29
+ node_config: 'nodes/some_node.json',
30
+ hostname: 12.34.56.78,
31
+ user: 'deploy',
32
+ ssh_port: 1234
33
+ end
34
+ end
35
+ prod.namespace :db do |db|
36
+ db.node :database_node, node_config: 'nodes/database.json', hostname: 123.456.78
37
+ end
38
+ end
39
+
40
+ node :vagrant, node_config:'nodes/some_node.json'
41
+
42
+ ```
43
+
44
+ ## Contributing
45
+
46
+ 1. Fork it
47
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
48
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
49
+ 4. Push to the branch (`git push origin my-new-feature`)
50
+ 5. Create new Pull Request
51
+
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,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.authors = "Shaun Dern"
6
+ s.email = "shaun@substantail.com"
7
+
8
+ s.name = 'knife_sous'
9
+ s.version = "0.0.1"
10
+ s.description = %q{Knife plugin for managing knife-solo nodes}
11
+ s.summary = %q{A Chef Knife plugin which uses a DSL to configure and
12
+ manage knife solo nodes. Run knife solo commands on one or multiple nodes.}
13
+ s.homepage = %q{http://github.com/substantial/knife_sous}
14
+ s.license = "MIT"
15
+
16
+ s.rubyforge_project = "knife_sous"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ s.add_development_dependency "rspec", "~> 2.12.0"
24
+ s.add_development_dependency "rake", "~> 10.0.0"
25
+ s.add_development_dependency "bundler", "~> 1.1"
26
+ s.add_dependency "knife-solo", "~> 0.2.0"
27
+ end
28
+
@@ -0,0 +1,31 @@
1
+ require 'chef/knife'
2
+ require 'knife_sous/processor_command'
3
+ require 'knife_sous/configure_command'
4
+ require 'knife_sous/node_command'
5
+
6
+ class Chef
7
+ class Knife
8
+ class SousBootstrap < Knife
9
+ include KnifeSous::ProcessorCommand
10
+ include KnifeSous::ConfigureCommand
11
+ include KnifeSous::NodeCommand
12
+
13
+ deps do
14
+ require 'chef/knife/solo_bootstrap'
15
+ end
16
+
17
+ banner "knife sous bootstrap [NAMESPACE] NODE"
18
+
19
+ def solo_bootstrap_node(node)
20
+ solo_bootstrap_command = configure_command(Chef::Knife::SoloBootstrap.new, node)
21
+ Chef::Knife::SoloBootstrap.load_deps
22
+ solo_bootstrap_command.name_args << node.hostname
23
+ solo_bootstrap_command.name_args << node.node_config
24
+ solo_bootstrap_command.run
25
+ end
26
+
27
+ alias_method :solo_command, :solo_bootstrap_node
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,30 @@
1
+ require 'chef/knife'
2
+ require 'knife_sous/processor_command'
3
+ require 'knife_sous/configure_command'
4
+ require 'knife_sous/node_command'
5
+
6
+ class Chef
7
+ class Knife
8
+ class SousClean < Knife
9
+ include KnifeSous::ProcessorCommand
10
+ include KnifeSous::ConfigureCommand
11
+ include KnifeSous::NodeCommand
12
+
13
+ deps do
14
+ require 'chef/knife/solo_clean'
15
+ end
16
+
17
+ banner "knife sous clean [NAMESPACE] NODE"
18
+
19
+ def solo_clean_node(node)
20
+ solo_cook_command = configure_command(Chef::Knife::SoloClean.new, node)
21
+ Chef::Knife::SoloClean.load_deps
22
+ solo_cook_command.name_args << node.hostname
23
+ solo_cook_command.run
24
+ end
25
+
26
+ alias_method :solo_command, :solo_clean_node
27
+ end
28
+ end
29
+ end
30
+
@@ -0,0 +1,31 @@
1
+ require 'chef/knife'
2
+ require 'knife_sous/processor_command'
3
+ require 'knife_sous/configure_command'
4
+ require 'knife_sous/node_command'
5
+
6
+ class Chef
7
+ class Knife
8
+ class SousCook < Knife
9
+ include KnifeSous::ProcessorCommand
10
+ include KnifeSous::ConfigureCommand
11
+ include KnifeSous::NodeCommand
12
+
13
+ deps do
14
+ require 'chef/knife/solo_cook'
15
+ end
16
+
17
+ banner "knife sous cook [NAMESPACE] NODE"
18
+
19
+ def solo_cook_node(node)
20
+ solo_cook_command = configure_command(Chef::Knife::SoloCook.new, node)
21
+ Chef::Knife::SoloCook.load_deps
22
+ solo_cook_command.name_args << node.hostname
23
+ solo_cook_command.name_args << node.node_config
24
+ solo_cook_command.run
25
+ end
26
+
27
+ alias_method :solo_command, :solo_cook_node
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,39 @@
1
+ require 'chef/knife'
2
+ require 'knife_sous/processor_command'
3
+
4
+ class Chef
5
+ class Knife
6
+ class SousInit < Knife
7
+ include KnifeSous::ProcessorCommand
8
+
9
+ banner "knife sous init [DIRECTORY]"
10
+
11
+ def node_manifest_example_path
12
+ File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'templates', 'nodes.example.rb'))
13
+ end
14
+
15
+ def run
16
+ unless name_args.empty?
17
+ target = File.expand_path(name_args.first)
18
+ else
19
+ target = File.expand_path(Dir.pwd, File.join('nodes'))
20
+ end
21
+ copy_template(target)
22
+ end
23
+
24
+ def copy_template(location)
25
+ FileUtils.mkdir_p(location)
26
+
27
+ target_file = File.join(location, 'nodes.example.rb' )
28
+
29
+ unless File.exists?(target_file)
30
+ FileUtils.cp(node_manifest_example_path, target_file)
31
+ ui.msg "Example nodes.rb copied to #{target_file}"
32
+ else
33
+ ui.error "File already exists: #{target_file}"
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
@@ -0,0 +1,22 @@
1
+ require 'chef/knife'
2
+ require 'knife_sous/processor_command'
3
+ require 'knife_sous/namespace_presenter'
4
+
5
+ class Chef
6
+ class Knife
7
+ class SousList < Knife
8
+ include KnifeSous::ProcessorCommand
9
+
10
+ banner "knife sous list"
11
+
12
+ def run
13
+ present_nodes
14
+ end
15
+
16
+ def present_nodes
17
+ ui.output(KnifeSous::NamespacePresenter.new(root_namespace).present)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,31 @@
1
+ require 'chef/knife'
2
+ require 'knife_sous/processor_command'
3
+ require 'knife_sous/configure_command'
4
+ require 'knife_sous/node_command'
5
+
6
+ class Chef
7
+ class Knife
8
+ class SousPrepare < Knife
9
+ include KnifeSous::ProcessorCommand
10
+ include KnifeSous::ConfigureCommand
11
+ include KnifeSous::NodeCommand
12
+
13
+ deps do
14
+ require 'chef/knife/solo_prepare'
15
+ end
16
+
17
+ banner "knife sous prepare [NAMESPACE] NODE"
18
+
19
+ def solo_prepare_node(node)
20
+ solo_cook_command = configure_command(Chef::Knife::SoloPrepare.new, node)
21
+ Chef::Knife::SoloPrepare.load_deps
22
+ solo_cook_command.name_args << node.hostname
23
+ solo_cook_command.name_args << node.node_config
24
+ solo_cook_command.run
25
+ end
26
+
27
+ alias_method :solo_command, :solo_prepare_node
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,12 @@
1
+ module KnifeSous
2
+ module ConfigureCommand
3
+
4
+ module_function
5
+
6
+ def configure_command(command, node)
7
+ command.config.merge!(node.config)
8
+ command
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,29 @@
1
+ require 'knife_sous/namespace'
2
+ require 'knife_sous/node'
3
+
4
+ module KnifeSous
5
+ module DSL
6
+ def self.included(base)
7
+ base.class_eval do
8
+ base.extend Forwardable
9
+ def_delegators :children, :<<, :first, :last, :[], :map, :each, :to_a, :keep_if, :empty?
10
+ end
11
+ end
12
+
13
+ def children
14
+ @children ||= []
15
+ end
16
+
17
+ def namespace(name, &block)
18
+ namespace = Namespace.new(name)
19
+ namespace.evaluate_block(&block)
20
+ children << namespace
21
+ end
22
+
23
+ def node(name, args={})
24
+ node = Node.new(name, args)
25
+ children << node
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,8 @@
1
+ module KnifeSous
2
+ module DSLWrapper
3
+ def evaluate_block(&block)
4
+ yield self if block_given?
5
+ end
6
+ end
7
+ end
8
+
@@ -0,0 +1,14 @@
1
+ module KnifeSous
2
+ module HashMixins
3
+
4
+ module_function
5
+
6
+ def normalize_hash(hash)
7
+ Hash[hash.map{ |k, v| [sanitize_key(k), v.to_s] }]
8
+ end
9
+
10
+ def sanitize_key(key)
11
+ key.to_s.downcase.gsub(/-/, '_').to_sym
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ require 'knife_sous/node'
2
+
3
+ require 'knife_sous/dsl_definitions'
4
+ require 'knife_sous/dsl_wrapper'
5
+
6
+
7
+ module KnifeSous
8
+ class Namespace
9
+ include DSL
10
+ include DSLWrapper
11
+
12
+ attr_reader :name
13
+
14
+ def initialize(name)
15
+ @name = name.to_s
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,27 @@
1
+ require 'knife_sous/node_presenter'
2
+
3
+ module KnifeSous
4
+ class NamespacePresenter
5
+ attr_reader :namespace
6
+
7
+ def initialize(namespace)
8
+ @namespace = namespace
9
+ end
10
+
11
+ def present
12
+ return @namespace.name if @namespace.empty?
13
+
14
+ nodes = ""
15
+ @namespace.each do |child|
16
+ nodes << "#{@namespace.name} #{presenter(child).present}".lstrip
17
+ end
18
+ nodes
19
+ end
20
+
21
+ def presenter(item)
22
+ klass = item.is_a?(Node) ? NodePresenter : NamespacePresenter
23
+ klass.new(item)
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,47 @@
1
+ require 'knife_sous/dsl_wrapper'
2
+ require 'knife_sous/mixins/hash_mixins'
3
+
4
+ module KnifeSous
5
+ class Node
6
+ include KnifeSous::HashMixins
7
+
8
+ attr_reader :name, :config
9
+
10
+ def initialize(name, config_args={})
11
+ @name = name.to_s
12
+ @config = {}
13
+ update_config(config_args)
14
+ end
15
+
16
+ def update_config(other_config={})
17
+ config = convert_aliases(normalize_hash(other_config))
18
+ @config.merge!(config)
19
+ end
20
+
21
+ def convert_aliases(config_hash = {})
22
+ config_aliases.each do |key, value|
23
+ if config_hash.has_key?(key)
24
+ config_hash[value] = config_hash[key]
25
+ config_hash.delete(key)
26
+ end
27
+ end
28
+ config_hash
29
+ end
30
+
31
+ def node_name
32
+ @config[:node_name] || @name
33
+ end
34
+
35
+ def method_missing(method_name, *args, &block)
36
+ @config[method_name.to_sym]
37
+ end
38
+
39
+ def config_aliases
40
+ {
41
+ ssh_config_file: :ssh_config,
42
+ ip: :hostname
43
+ }
44
+ end
45
+ end
46
+ end
47
+
@@ -0,0 +1,36 @@
1
+ module KnifeSous
2
+ module NodeCommand
3
+
4
+ def search_for_target
5
+ result = search(name_args)
6
+ if result.nil?
7
+ ui.error "Can't find node. Run `knife sous list` to see nodes"
8
+ exit 1
9
+ end
10
+ result
11
+ end
12
+
13
+ def run
14
+ check_args
15
+ search_result = search_for_target
16
+ process_result(search_result)
17
+ end
18
+
19
+ def process_result(result)
20
+ if result.is_a? KnifeSous::Namespace
21
+ result.each { |child| process_result(child) }
22
+ else
23
+ solo_command(result)
24
+ end
25
+ end
26
+
27
+ def check_args
28
+ unless name_args.size > 0
29
+ ui.fatal "You need to specificy a node or namespace"
30
+ show_usage
31
+ exit 1
32
+ end
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,13 @@
1
+ module KnifeSous
2
+ class NodePresenter
3
+ attr_reader :node
4
+
5
+ def initialize(node)
6
+ @node = node
7
+ end
8
+
9
+ def present
10
+ "#{@node.name}\n"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,52 @@
1
+ require 'knife_sous/namespace'
2
+
3
+ module KnifeSous
4
+ module ProcessorCommand
5
+ def self.included(other)
6
+ other.class_eval do
7
+ option :node_manifest_file,
8
+ :long => '--node-manifest-file NODE_MANIFEST_FILE',
9
+ :description => 'Alternate location for node manifest config file',
10
+ :default => File.join("nodes", "nodes.rb")
11
+ end
12
+ end
13
+
14
+ def validate_config!
15
+ unless File.exists?(manifest_file_path)
16
+ ui.fatal("Couldn't find #{manifest_file_path}")
17
+ exit 1
18
+ end
19
+ unless File.readable?(manifest_file_path)
20
+ ui.fatal("Can't read #{manifest_file_path}")
21
+ exit 1
22
+ end
23
+ true
24
+ end
25
+
26
+ def search(target_qualifiers = [])
27
+ namespace = root_namespace
28
+ target_qualifiers.each do |target_qualifier|
29
+ return nil if namespace.nil?
30
+ namespace = namespace.keep_if { |item| item.name == target_qualifier }.first
31
+ end
32
+ namespace
33
+ end
34
+
35
+ def root_namespace
36
+ @root_namespace ||= process_config
37
+ end
38
+
39
+ def manifest_file_path
40
+ config[:node_manifest_file] ||= default_config[:node_manifest_file]
41
+ @manifest_file_path ||= File.expand_path(File.join(Dir.pwd, config[:node_manifest_file]))
42
+ end
43
+
44
+ def process_config
45
+ validate_config!
46
+ root_namespace = Namespace.new('')
47
+ root_namespace.instance_eval(File.read(manifest_file_path), manifest_file_path)
48
+ root_namespace
49
+ end
50
+ end
51
+ end
52
+
data/lib/knife_sous.rb ADDED
@@ -0,0 +1,3 @@
1
+
2
+ require 'chef/knife/sous_list'
3
+