spiceweasel 1.2.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|