spiceweasel 1.2.0 → 2.0.0
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/LICENSE +201 -0
- data/README.md +141 -241
- data/bin/spiceweasel +2 -104
- data/lib/spiceweasel.rb +5 -11
- data/lib/spiceweasel/cli.rb +249 -83
- data/lib/spiceweasel/clusters.rb +53 -0
- data/lib/spiceweasel/config.rb +46 -0
- data/lib/spiceweasel/cookbooks.rb +105 -0
- data/lib/spiceweasel/data_bags.rb +89 -0
- data/lib/spiceweasel/environments.rb +103 -0
- data/lib/spiceweasel/execute.rb +42 -0
- data/lib/spiceweasel/extract_local.rb +130 -0
- data/lib/spiceweasel/log.rb +30 -0
- data/lib/spiceweasel/nodes.rb +126 -0
- data/lib/spiceweasel/roles.rb +131 -0
- data/lib/spiceweasel/version.rb +1 -1
- data/spec/bin/spiceweasel_spec.rb +44 -12
- metadata +106 -25
- data/lib/spiceweasel/cookbook_data.rb +0 -66
- data/lib/spiceweasel/cookbook_list.rb +0 -96
- data/lib/spiceweasel/data_bag_list.rb +0 -81
- data/lib/spiceweasel/directory_extractor.rb +0 -121
- data/lib/spiceweasel/environment_list.rb +0 -96
- data/lib/spiceweasel/node_list.rb +0 -98
- data/lib/spiceweasel/role_list.rb +0 -124
@@ -1,66 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Geoff Meakin
|
3
|
-
# Author:: Matt Ray (<matt@opscode.com>)
|
4
|
-
#
|
5
|
-
# Copyright:: 2012, Opscode, Inc <legal@opscode.com>
|
6
|
-
#
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
-
# you may not use this file except in compliance with the License.
|
9
|
-
# You may obtain a copy of the License at
|
10
|
-
#
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
-
#
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
-
# See the License for the specific language governing permissions and
|
17
|
-
# limitations under the License.
|
18
|
-
#
|
19
|
-
|
20
|
-
class Spiceweasel::CookbookData
|
21
|
-
|
22
|
-
attr_accessor :_name, :_dependencies, :_version
|
23
|
-
|
24
|
-
def initialize(file_name)
|
25
|
-
@_name = file_name.split('/').last
|
26
|
-
@_dependencies = []
|
27
|
-
@_version = ""
|
28
|
-
@file_name = file_name
|
29
|
-
end
|
30
|
-
|
31
|
-
def is_readable?
|
32
|
-
return false unless File.directory?("cookbooks/#{@_name}")
|
33
|
-
return false unless File.exists?("cookbooks/#{@_name}/metadata.rb")
|
34
|
-
true
|
35
|
-
end
|
36
|
-
|
37
|
-
def read
|
38
|
-
if File.exists?("cookbooks/#{@_name}/metadata.rb") && File.readable?("cookbooks/#{@_name}/metadata.rb")
|
39
|
-
self.instance_eval(IO.read("cookbooks/#{@_name}/metadata.rb"), "cookbooks/#{@_name}/metadata.rb", 1)
|
40
|
-
else
|
41
|
-
raise IOError, "Cannot open or read cookbooks/#{@_name}/metadata.rb!"
|
42
|
-
end
|
43
|
-
{'name' => @_name, 'version' => @_version, 'dependencies' => @_dependencies }
|
44
|
-
end
|
45
|
-
|
46
|
-
def name(*args) # Override metadata.rb DSL
|
47
|
-
@_name = args.shift
|
48
|
-
end
|
49
|
-
|
50
|
-
def version(*args) # Override metadata.rb DSL
|
51
|
-
@_version = args.shift
|
52
|
-
end
|
53
|
-
|
54
|
-
def depends(*args) # Override metadata.rb DSL
|
55
|
-
cookbook = args.shift
|
56
|
-
if args.length > 0
|
57
|
-
cookbook_version = args.shift
|
58
|
-
end
|
59
|
-
@_dependencies << {'cookbook' => cookbook, 'version' => cookbook_version}
|
60
|
-
end
|
61
|
-
|
62
|
-
def method_missing(m, *args, &block)
|
63
|
-
true
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Matt Ray (<matt@opscode.com>)
|
3
|
-
#
|
4
|
-
# Copyright:: 2011-2012, Opscode, Inc <legal@opscode.com>
|
5
|
-
#
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
-
# you may not use this file except in compliance with the License.
|
8
|
-
# You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
# See the License for the specific language governing permissions and
|
16
|
-
# limitations under the License.
|
17
|
-
#
|
18
|
-
|
19
|
-
class Spiceweasel::CookbookList
|
20
|
-
def initialize(cookbooks = [], options = {})
|
21
|
-
@create = @delete = ''
|
22
|
-
@cookbook_list = {}
|
23
|
-
@dependencies = []
|
24
|
-
#validate each of the cookbooks specified in the manifest
|
25
|
-
if cookbooks
|
26
|
-
cookbooks.each do |cookbook|
|
27
|
-
cb = cookbook.keys.first
|
28
|
-
if cookbook[cb] and cookbook[cb].length > 0
|
29
|
-
version = cookbook[cb][0].to_s || ""
|
30
|
-
args = cookbook[cb][1] || ""
|
31
|
-
end
|
32
|
-
STDOUT.puts "DEBUG: cookbook: #{cb} #{version}" if Spiceweasel::DEBUG
|
33
|
-
if File.directory?("cookbooks")
|
34
|
-
if File.directory?("cookbooks/#{cb}")
|
35
|
-
validateMetadata(cb,version) unless Spiceweasel::NOVALIDATION
|
36
|
-
else
|
37
|
-
if Spiceweasel::SITEINSTALL #use knife cookbook site install
|
38
|
-
@create += "knife cookbook#{options['knife_options']} site install #{cb} #{version} #{args}\n"
|
39
|
-
else #use knife cookbook site download, untar and then remove the tarball
|
40
|
-
@create += "knife cookbook#{options['knife_options']} site download #{cb} #{version} --file cookbooks/#{cb}.tgz #{args}\n"
|
41
|
-
@create += "tar -C cookbooks/ -xf cookbooks/#{cb}.tgz\n"
|
42
|
-
@create += "rm -f cookbooks/#{cb}.tgz\n"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
else
|
46
|
-
STDERR.puts "'cookbooks' directory not found, unable to validate, download and load cookbooks" unless Spiceweasel::NOVALIDATION
|
47
|
-
end
|
48
|
-
@create += "knife cookbook#{options['knife_options']} upload #{cb}\n"
|
49
|
-
@delete += "knife cookbook#{options['knife_options']} delete #{cb} #{version} -a -y\n"
|
50
|
-
|
51
|
-
@cookbook_list[cb] = version
|
52
|
-
end
|
53
|
-
validateDependencies() unless Spiceweasel::NOVALIDATION
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
#check the metadata for versions and gather deps
|
58
|
-
def validateMetadata(cookbook,version)
|
59
|
-
#check metadata.rb for requested version
|
60
|
-
metadata = File.open("cookbooks/#{cookbook}/metadata.rb").grep(/^version/)[0].split()[1].gsub(/"/,'').to_s
|
61
|
-
STDOUT.puts "DEBUG: cookbook metadata version: #{metadata}" if Spiceweasel::DEBUG
|
62
|
-
if version and (metadata != version)
|
63
|
-
STDERR.puts "ERROR: Invalid version '#{version}' of '#{cookbook}' requested, '#{metadata}' is already in the cookbooks directory."
|
64
|
-
exit(-1)
|
65
|
-
end
|
66
|
-
deps = File.open("cookbooks/#{cookbook}/metadata.rb").grep(/^depends/)
|
67
|
-
deps.each do |dependency|
|
68
|
-
STDOUT.puts "DEBUG: cookbook #{cookbook} metadata dependency: #{dependency}" if Spiceweasel::DEBUG
|
69
|
-
line = dependency.split()
|
70
|
-
if line[1] =~ /^["']/ #ignore variables and versions
|
71
|
-
cbdep = line[1].gsub(/["']/,'')
|
72
|
-
cbdep.gsub!(/\,/,'') if cbdep.end_with?(',')
|
73
|
-
STDOUT.puts "DEBUG: cookbook #{cookbook} metadata depends: #{cbdep}" if Spiceweasel::DEBUG
|
74
|
-
@dependencies << cbdep
|
75
|
-
end
|
76
|
-
end
|
77
|
-
return @cookbook
|
78
|
-
end
|
79
|
-
|
80
|
-
#compare the list of cookbook deps with those specified
|
81
|
-
def validateDependencies()
|
82
|
-
STDOUT.puts "DEBUG: cookbook validateDependencies: '#{@dependencies}'" if Spiceweasel::DEBUG
|
83
|
-
@dependencies.each do |dep|
|
84
|
-
if !member?(dep)
|
85
|
-
STDERR.puts "ERROR: Cookbook dependency '#{dep}' is missing from the list of cookbooks in the manifest."
|
86
|
-
exit(-1)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
attr_reader :cookbook_list, :create, :delete
|
92
|
-
|
93
|
-
def member?(cookbook)
|
94
|
-
cookbook_list.keys.include?(cookbook)
|
95
|
-
end
|
96
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Matt Ray (<matt@opscode.com>)
|
3
|
-
#
|
4
|
-
# Copyright:: 2011, Opscode, Inc <legal@opscode.com>
|
5
|
-
#
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
-
# you may not use this file except in compliance with the License.
|
8
|
-
# You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
# See the License for the specific language governing permissions and
|
16
|
-
# limitations under the License.
|
17
|
-
#
|
18
|
-
|
19
|
-
require 'json'
|
20
|
-
|
21
|
-
class Spiceweasel::DataBagList
|
22
|
-
def initialize(data_bags = [], options = {})
|
23
|
-
@create = @delete = ''
|
24
|
-
if data_bags
|
25
|
-
if !File.directory?("data_bags")
|
26
|
-
STDERR.puts "ERROR: 'data_bags' directory not found, unable to validate or load data bag items" unless Spiceweasel::NOVALIDATION
|
27
|
-
end
|
28
|
-
data_bags.each do |data_bag|
|
29
|
-
db = data_bag.keys[0]
|
30
|
-
STDOUT.puts "DEBUG: data bag: #{db}" if Spiceweasel::DEBUG
|
31
|
-
if !File.directory?("data_bags/#{db}")
|
32
|
-
STDERR.puts "ERROR: 'data_bags/#{db}' directory not found, unable to validate or load data bag items" unless Spiceweasel::NOVALIDATION
|
33
|
-
end
|
34
|
-
@create += "knife data bag#{options['knife_options']} create #{db}\n"
|
35
|
-
@delete += "knife data bag#{options['knife_options']} delete #{db} -y\n"
|
36
|
-
items = data_bag[db] || []
|
37
|
-
secret = nil
|
38
|
-
while item = items.shift
|
39
|
-
STDOUT.puts "DEBUG: data bag #{db} item: #{item}" if Spiceweasel::DEBUG
|
40
|
-
if item.start_with?("secret")
|
41
|
-
secret = item.split()[1]
|
42
|
-
if !File.exists?(secret) and !Spiceweasel::NOVALIDATION
|
43
|
-
STDERR.puts "ERROR: secret key #{secret} not found, unable to load encrypted data bags for data bag #{db}."
|
44
|
-
exit(-1)
|
45
|
-
end
|
46
|
-
next
|
47
|
-
end
|
48
|
-
if item =~ /\*/ #wildcard support, will fail if directory not present
|
49
|
-
files = Dir.glob("data_bags/#{db}/#{item}.json")
|
50
|
-
items += files.collect {|x| x[x.rindex('/')+1..-6]}
|
51
|
-
STDOUT.puts "DEBUG: found items '#{items}' for data bag: #{db}" if Spiceweasel::DEBUG
|
52
|
-
next
|
53
|
-
end
|
54
|
-
validateItem(db, item) unless Spiceweasel::NOVALIDATION
|
55
|
-
if secret
|
56
|
-
@create += "knife data bag#{options['knife_options']} from file #{db} #{item}.json --secret-file #{secret}\n"
|
57
|
-
else
|
58
|
-
@create += "knife data bag#{options['knife_options']} from file #{db} #{item}.json\n"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
#validate the item to be loaded
|
66
|
-
def validateItem(db, item)
|
67
|
-
if !File.exists?("data_bags/#{db}/#{item}.json")
|
68
|
-
STDERR.puts "ERROR: data bag '#{db}' item '#{item}' file 'data_bags/#{db}/#{item}.json' does not exist"
|
69
|
-
exit(-1)
|
70
|
-
end
|
71
|
-
f = File.read("data_bags/#{db}/#{item}.json")
|
72
|
-
itemfile = JSON.parse(f) #invalid JSON will throw a trace
|
73
|
-
#validate the id matches the file name
|
74
|
-
if !item.eql?(itemfile['id'])
|
75
|
-
STDERR.puts "ERROR: data bag '#{db}' item '#{item}' listed in the manifest does not match the id '#{itemfile['id']}' within the 'data_bags/#{db}/#{item}.json' file."
|
76
|
-
exit(-1)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
attr_reader :create, :delete
|
81
|
-
end
|
@@ -1,121 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Geoff Meakin
|
3
|
-
# Author:: Matt Ray (<matt@opscode.com>)
|
4
|
-
#
|
5
|
-
# Copyright:: 2012, Opscode, Inc <legal@opscode.com>
|
6
|
-
#
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
-
# you may not use this file except in compliance with the License.
|
9
|
-
# You may obtain a copy of the License at
|
10
|
-
#
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
-
#
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
-
# See the License for the specific language governing permissions and
|
17
|
-
# limitations under the License.
|
18
|
-
#
|
19
|
-
|
20
|
-
class Spiceweasel::DirectoryExtractor
|
21
|
-
|
22
|
-
def self.parse_objects
|
23
|
-
objects = {"cookbooks" => nil, "roles" => nil, "environments" => nil, "data bags" => nil, "nodes" => nil}
|
24
|
-
# COOKBOOKS
|
25
|
-
cookbooks = []
|
26
|
-
Dir.glob("cookbooks/*").each do |cookbook_full_path|
|
27
|
-
cookbook = cookbook_full_path.split('/').last
|
28
|
-
STDOUT.puts "DEBUG: dir_ext: cookbook: '#{cookbook}'" if Spiceweasel::DEBUG
|
29
|
-
cookbook_data = Spiceweasel::CookbookData.new(cookbook)
|
30
|
-
if cookbook_data.is_readable?
|
31
|
-
cookbooks << cookbook_data.read
|
32
|
-
end
|
33
|
-
end
|
34
|
-
STDOUT.puts "DEBUG: dir_ext: cookbooks: '#{cookbooks}'" if Spiceweasel::DEBUG
|
35
|
-
cookbooks = self.order_cookbooks_by_dependency(cookbooks)
|
36
|
-
objects["cookbooks"] = cookbooks unless cookbooks.empty?
|
37
|
-
|
38
|
-
# ROLES
|
39
|
-
roles = []
|
40
|
-
Dir.glob("roles/*.{rb,json}").each do |role_full_path|
|
41
|
-
role = self.grab_name_from_path(role_full_path)
|
42
|
-
STDOUT.puts "DEBUG: dir_ext: role: '#{role}'" if Spiceweasel::DEBUG
|
43
|
-
roles << {role => nil}
|
44
|
-
end
|
45
|
-
objects["roles"] = roles unless roles.nil?
|
46
|
-
# ENVIRONMENTS
|
47
|
-
environments = []
|
48
|
-
Dir.glob("environments/*.{rb,json}").each do |environment_full_path|
|
49
|
-
environment = self.grab_name_from_path(environment_full_path)
|
50
|
-
STDOUT.puts "DEBUG: dir_ext: environment: '#{environment}'" if Spiceweasel::DEBUG
|
51
|
-
environments << {environment => nil}
|
52
|
-
end
|
53
|
-
objects["environments"] = environments unless environments.empty?
|
54
|
-
# DATA BAGS
|
55
|
-
data_bags = []
|
56
|
-
Dir.glob("data_bags/*").each do |data_bag_full_path|
|
57
|
-
data_bag = data_bag_full_path.split('/').last
|
58
|
-
STDOUT.puts "DEBUG: dir_ext: data_bag: '#{data_bag}'" if Spiceweasel::DEBUG
|
59
|
-
data_bag_items = []
|
60
|
-
Dir.glob("#{data_bag_full_path}/*.{rb,json}").each do |data_bag_item_full_path|
|
61
|
-
STDOUT.puts "DEBUG: dir_ext: data_bag: '#{data_bag}':'#{data_bag_item_full_path}'" if Spiceweasel::DEBUG
|
62
|
-
data_bag_items << self.grab_name_from_path(data_bag_item_full_path)
|
63
|
-
end if File.directory?(data_bag_full_path)
|
64
|
-
data_bags << {data_bag => data_bag_items} unless data_bag_items.empty?
|
65
|
-
end
|
66
|
-
objects["data bags"] = data_bags unless data_bags.empty?
|
67
|
-
# NODES
|
68
|
-
# TODO: Cant use this yet as node_list.rb doesnt support node from file syntax but expects the node info to be part of the objects passed in
|
69
|
-
# nodes = []
|
70
|
-
# Dir.glob("nodes/*.{rb,json}").each do |node_full_path|
|
71
|
-
# node = self.grab_name_from_path(node_full_path)
|
72
|
-
# nodes << {node => nil}
|
73
|
-
# end
|
74
|
-
# objects["nodes"] = nodes unless nodes.empty?
|
75
|
-
|
76
|
-
objects
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.grab_name_from_path(path)
|
80
|
-
name = path.split('/').last.split('.')
|
81
|
-
if name.length>1
|
82
|
-
name.pop
|
83
|
-
end
|
84
|
-
name.join('.')
|
85
|
-
end
|
86
|
-
|
87
|
-
def self.order_cookbooks_by_dependency(cookbooks)
|
88
|
-
# Weak algorithm, not particularly elegant, ignores version info as unlikely to have two versions of a cookbook anyway
|
89
|
-
# We're going to find the cookbooks with their dependencies matched and keep going until all we have is unmatched deps
|
90
|
-
|
91
|
-
sorted_cookbooks = []
|
92
|
-
unsorted_cookbooks = cookbooks
|
93
|
-
scount = 0
|
94
|
-
#keep looping until no more cookbooks are left or can't remove remainders
|
95
|
-
while unsorted_cookbooks.any? and scount < cookbooks.length
|
96
|
-
cookbook = unsorted_cookbooks.shift
|
97
|
-
#if all the cookbook dependencies are in sorted_cookbooks
|
98
|
-
if sorted_cookbooks.eql?(sorted_cookbooks | cookbook['dependencies'].collect {|x| x['cookbook']})
|
99
|
-
sorted_cookbooks.push(cookbook['name'])
|
100
|
-
scount = 0
|
101
|
-
else #put it back in the list
|
102
|
-
unsorted_cookbooks.push(cookbook)
|
103
|
-
scount = scount + 1
|
104
|
-
end
|
105
|
-
STDOUT.puts "DEBUG: dir_ext: sorted_cookbooks: '#{sorted_cookbooks}' #{scount}" if Spiceweasel::DEBUG
|
106
|
-
end
|
107
|
-
if scount > 0
|
108
|
-
remainders = unsorted_cookbooks.collect {|x| x['name']}
|
109
|
-
STDOUT.puts "DEBUG: dir_ext: remainders: '#{remainders}'" if Spiceweasel::DEBUG
|
110
|
-
if Spiceweasel::NOVALIDATION #stuff is missing, oh well
|
111
|
-
sorted_cookbooks.push(remainders).flatten!
|
112
|
-
else
|
113
|
-
deps = unsorted_cookbooks.collect {|x| x['dependencies'].collect {|x| x['cookbook']} - sorted_cookbooks}
|
114
|
-
STDERR.puts "ERROR: Dependencies not satisfied or circular dependencies in cookbook(s): #{remainders} depend(s) on #{deps}"
|
115
|
-
exit(-1)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
#hack to get the format same as yaml/json parse
|
119
|
-
return sorted_cookbooks.collect {|x| {x => nil} }
|
120
|
-
end
|
121
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Matt Ray (<matt@opscode.com>)
|
3
|
-
#
|
4
|
-
# Copyright:: 2011-2012, Opscode, Inc <legal@opscode.com>
|
5
|
-
#
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
-
# you may not use this file except in compliance with the License.
|
8
|
-
# You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
# See the License for the specific language governing permissions and
|
16
|
-
# limitations under the License.
|
17
|
-
#
|
18
|
-
|
19
|
-
require 'json'
|
20
|
-
|
21
|
-
class Spiceweasel::EnvironmentList
|
22
|
-
def initialize(environments = [], cookbooks = {}, options = {})
|
23
|
-
@create = @delete = ''
|
24
|
-
@environment_list = []
|
25
|
-
if environments
|
26
|
-
environments.each do |env|
|
27
|
-
environment = env.keys[0]
|
28
|
-
STDOUT.puts "DEBUG: environment: #{environment}" if Spiceweasel::DEBUG
|
29
|
-
if File.directory?("environments")
|
30
|
-
validate(environment, cookbooks) unless Spiceweasel::NOVALIDATION
|
31
|
-
else
|
32
|
-
STDERR.puts "'environments' directory not found, unable to validate or load environments" unless Spiceweasel::NOVALIDATION
|
33
|
-
end
|
34
|
-
if File.exists?("environments/#{environment}.json")
|
35
|
-
@create += "knife environment#{options['knife_options']} from file #{environment}.json\n"
|
36
|
-
else #assume no .json means they want .rb and catchall for misssing dir
|
37
|
-
@create += "knife environment#{options['knife_options']} from file #{environment}.rb\n"
|
38
|
-
end
|
39
|
-
@delete += "knife environment#{options['knife_options']} delete #{environment} -y\n"
|
40
|
-
@environment_list << environment
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
#validate the content of the environment file
|
46
|
-
def validate(environment, cookbooks)
|
47
|
-
#validate the environments passed in match the name of either the .rb or .json
|
48
|
-
if File.exists?("environments/#{environment}.rb")
|
49
|
-
#validate that the name inside the file matches
|
50
|
-
name = File.open("environments/#{environment}.rb").grep(/^name/)[0].split()[1].gsub(/"/,'').to_s
|
51
|
-
if !environment.eql?(name)
|
52
|
-
STDERR.puts "ERROR: Environment '#{environment}' listed in the manifest does not match the name '#{name}' within the environments/#{environment}.rb file."
|
53
|
-
exit(-1)
|
54
|
-
end
|
55
|
-
#validate the cookbooks exist if they're mentioned
|
56
|
-
envcookbooks = File.open("environments/#{environment}.rb").grep(/^cookbook /)
|
57
|
-
envcookbooks.each do |cb|
|
58
|
-
dep = cb.split()[1].gsub(/"/,'').gsub(/,/,'')
|
59
|
-
STDOUT.puts "DEBUG: environment: '#{environment}' cookbook: '#{dep}'" if Spiceweasel::DEBUG
|
60
|
-
if !cookbooks.member?(dep)
|
61
|
-
STDERR.puts "ERROR: Cookbook dependency '#{dep}' from environment '#{environment}' is missing from the list of cookbooks in the manifest."
|
62
|
-
exit(-1)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
elsif File.exists?("environments/#{environment}.json")
|
66
|
-
#load the json, don't symbolize since we don't need json_class
|
67
|
-
f = File.read("environments/#{environment}.json")
|
68
|
-
JSON.create_id = nil
|
69
|
-
envfile = JSON.parse(f, {:symbolize_names => false})
|
70
|
-
STDOUT.puts "DEBUG: environment: '#{environment}' file: '#{envfile}'" if Spiceweasel::DEBUG
|
71
|
-
#validate that the name inside the file matches
|
72
|
-
STDOUT.puts "DEBUG: environment: '#{environment}' name: '#{envfile['name']}'" if Spiceweasel::DEBUG
|
73
|
-
if !environment.eql?(envfile['name'])
|
74
|
-
STDERR.puts "ERROR: Environment '#{environment}' listed in the manifest does not match the name '#{envfile['name']}' within the 'environments/#{environment}.json' file."
|
75
|
-
exit(-1)
|
76
|
-
end
|
77
|
-
#validate the cookbooks exist if they're mentioned
|
78
|
-
envfile['cookbook_versions'].keys.each do |cb|
|
79
|
-
STDOUT.puts "DEBUG: environment: '#{environment}' cookbook: '#{cb}'" if Spiceweasel::DEBUG
|
80
|
-
if !cookbooks.member?(cb.to_s)
|
81
|
-
STDERR.puts "ERROR: Cookbook dependency '#{cb}' from environment '#{environment}' is missing from the list of cookbooks in the manifest."
|
82
|
-
exit(-1)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
else #environment is not here
|
86
|
-
STDERR.puts "ERROR: Invalid Environment '#{environment}' listed in the manifest but not found in the environments directory."
|
87
|
-
exit(-1)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
attr_reader :environment_list, :create, :delete
|
92
|
-
|
93
|
-
def member?(environment)
|
94
|
-
environment_list.include?(environment)
|
95
|
-
end
|
96
|
-
end
|