spiceweasel 1.2.0 → 2.0.0

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