kitchen-inspector 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +9 -0
- data/CHANGELOG.md +24 -0
- data/Gemfile +0 -2
- data/README.md +268 -39
- data/Rakefile +41 -0
- data/kitchen-inspector.gemspec +21 -3
- data/lib/kitchen-inspector/inspector.rb +11 -4
- data/lib/kitchen-inspector/inspector/chef_inspector.rb +66 -0
- data/lib/kitchen-inspector/inspector/cli.rb +29 -3
- data/lib/kitchen-inspector/inspector/{error.rb → common.rb} +43 -1
- data/lib/kitchen-inspector/inspector/dependency.rb +26 -40
- data/lib/kitchen-inspector/inspector/health_bureau.rb +181 -0
- data/lib/kitchen-inspector/inspector/mixin/utils.rb +83 -0
- data/lib/kitchen-inspector/inspector/report/report.rb +182 -0
- data/lib/kitchen-inspector/inspector/report/status_reporter.rb +105 -0
- data/lib/kitchen-inspector/inspector/repository_inspector.rb +134 -0
- data/lib/kitchen-inspector/inspector/repository_managers/base.rb +110 -0
- data/lib/kitchen-inspector/inspector/repository_managers/github.rb +97 -0
- data/lib/kitchen-inspector/inspector/repository_managers/gitlab.rb +100 -0
- data/lib/kitchen-inspector/inspector/version.rb +1 -2
- data/spec/cli_spec.rb +46 -0
- data/spec/data/cookbook_deps/metadata.rb +10 -0
- data/spec/data/cookbook_no_deps/metadata.rb +7 -0
- data/spec/data/test_client.pem +27 -0
- data/spec/data/test_config_invalid.rb +4 -0
- data/spec/data/test_config_valid.rb +4 -0
- data/spec/dependency_inspector_spec.rb +296 -0
- data/spec/github_manager_spec.rb +79 -0
- data/spec/gitlab_manager_spec.rb +58 -0
- data/spec/report_spec.rb +237 -0
- data/spec/support/spec_helper.rb +81 -0
- data/spec/utils_spec.rb +29 -0
- metadata +129 -15
- data/INFO.md +0 -44
- data/info.css +0 -31
- data/lib/kitchen-inspector/inspector/dependency_inspector.rb +0 -153
- data/lib/kitchen-inspector/inspector/report.rb +0 -148
data/kitchen-inspector.gemspec
CHANGED
@@ -3,12 +3,24 @@ lib = File.expand_path('../lib', __FILE__)
|
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'kitchen-inspector/inspector/version'
|
5
5
|
|
6
|
+
# Generate pre-release versions for non tagged releases
|
7
|
+
git_version = begin
|
8
|
+
describe = `git describe`
|
9
|
+
if $?.success?
|
10
|
+
stripped = describe.strip
|
11
|
+
/^([^-]+)-([0-9]+)-[^-]+$/.match(stripped) ? "#{$1}.#{$2}" : stripped
|
12
|
+
else
|
13
|
+
git_raw = `git log --pretty=format:%h | head -n1`
|
14
|
+
$?.success? ? '0.0.0.%d' % git_raw.strip.to_i(16) : '0.0.0'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
6
18
|
Gem::Specification.new do |spec|
|
7
19
|
spec.name = "kitchen-inspector"
|
8
|
-
spec.version =
|
20
|
+
spec.version = git_version
|
9
21
|
spec.authors = ["Stefano Tortarolo"]
|
10
22
|
spec.email = ["stefano.tortarolo@gmail.com"]
|
11
|
-
spec.description = %q{Given
|
23
|
+
spec.description = %q{Given a Chef cookbook, verifies its dependencies against a Chef Server and a Repository Manager instance (i.e., GitHub/GitLab)}
|
12
24
|
spec.summary = %q{Kitchen integrity checker}
|
13
25
|
spec.homepage = "https://github.com/astratto/kitchen-inspector"
|
14
26
|
spec.license = "MIT"
|
@@ -21,12 +33,18 @@ Gem::Specification.new do |spec|
|
|
21
33
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
34
|
spec.add_development_dependency "rubocop", "~> 0.14"
|
23
35
|
spec.add_development_dependency "rake"
|
36
|
+
spec.add_development_dependency 'chef-zero'
|
37
|
+
spec.add_development_dependency 'rspec'
|
38
|
+
spec.add_development_dependency 'coveralls'
|
39
|
+
spec.add_development_dependency "gitlab", "~> 3.0"
|
40
|
+
spec.add_development_dependency "octokit", "~> 2.6"
|
24
41
|
|
25
42
|
spec.add_dependency "solve", "~> 0.8.0"
|
26
43
|
spec.add_dependency "berkshelf", "~> 2.0.10"
|
27
44
|
spec.add_dependency "thor", "~> 0.18.0"
|
28
45
|
spec.add_dependency "terminal-table", "~> 1.4.5"
|
29
46
|
spec.add_dependency "colorize", "~> 0.6.0"
|
30
|
-
spec.add_dependency "
|
47
|
+
spec.add_dependency "httparty", "~> 0.10.0"
|
48
|
+
spec.add_dependency "googl", "~> 0.6.3"
|
31
49
|
spec.add_dependency "chef", ">= 11.0.0"
|
32
50
|
end
|
@@ -29,11 +29,18 @@ require 'colorize'
|
|
29
29
|
require 'ridley'
|
30
30
|
require 'terminal-table'
|
31
31
|
require 'thor'
|
32
|
-
require '
|
32
|
+
require 'googl'
|
33
33
|
|
34
|
+
require 'kitchen-inspector/inspector/common'
|
35
|
+
require 'kitchen-inspector/inspector/mixin/utils'
|
34
36
|
require 'kitchen-inspector/inspector/cli'
|
35
|
-
require 'kitchen-inspector/inspector/error'
|
36
37
|
require 'kitchen-inspector/inspector/dependency'
|
37
|
-
|
38
|
-
require 'kitchen-inspector/inspector/
|
38
|
+
|
39
|
+
require 'kitchen-inspector/inspector/chef_inspector'
|
40
|
+
require 'kitchen-inspector/inspector/repository_inspector'
|
41
|
+
require 'kitchen-inspector/inspector/health_bureau'
|
42
|
+
|
43
|
+
require 'kitchen-inspector/inspector/repository_managers/base'
|
44
|
+
require 'kitchen-inspector/inspector/report/report'
|
45
|
+
require 'kitchen-inspector/inspector/report/status_reporter'
|
39
46
|
require 'kitchen-inspector/inspector/version'
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Stefano Tortarolo <stefano.tortarolo@gmail.com>
|
3
|
+
#
|
4
|
+
# MIT License
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
# a copy of this software and associated documentation files (the
|
8
|
+
# "Software"), to deal in the Software without restriction, including
|
9
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
# the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be
|
15
|
+
# included in all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
#
|
25
|
+
|
26
|
+
module KitchenInspector
|
27
|
+
module Inspector
|
28
|
+
class ChefInspector
|
29
|
+
include Utils
|
30
|
+
|
31
|
+
def initialize(config)
|
32
|
+
@chef_server_url = config[:url]
|
33
|
+
@chef_username = config[:username]
|
34
|
+
@chef_client_pem = config[:client_pem]
|
35
|
+
|
36
|
+
raise ChefAccessNotConfiguredError, config_msg("Chef Server url", ":url") unless @chef_server_url
|
37
|
+
raise ChefAccessNotConfiguredError, config_msg("Chef username", ":username") unless @chef_username
|
38
|
+
raise ChefAccessNotConfiguredError, config_msg("Chef client PEM", ":client_pem") unless @chef_client_pem
|
39
|
+
|
40
|
+
@chef_info_cache = {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def investigate(dependency)
|
44
|
+
cache_key = "#{dependency.name}, #{dependency.requirement}"
|
45
|
+
@chef_info_cache[cache_key] ||= begin
|
46
|
+
chef_info = {}
|
47
|
+
chef_info[:versions] = find_versions(dependency.name)
|
48
|
+
chef_info[:latest_version] = get_latest_version(chef_info[:versions])
|
49
|
+
chef_info[:version_used] = satisfy(dependency.requirement, chef_info[:versions])
|
50
|
+
chef_info
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Given a project return the versions on the Chef Server
|
55
|
+
def find_versions(project)
|
56
|
+
rest = Chef::REST.new(@chef_server_url, @chef_username, @chef_client_pem)
|
57
|
+
cookbook = rest.get("cookbooks/#{project}")
|
58
|
+
versions = []
|
59
|
+
versions = cookbook[project]["versions"].collect{|c| fix_version_name(c["version"])} if cookbook
|
60
|
+
versions
|
61
|
+
rescue Net::HTTPServerException
|
62
|
+
[]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -34,20 +34,46 @@ module KitchenInspector
|
|
34
34
|
default: 'table',
|
35
35
|
aliases: '-t'
|
36
36
|
|
37
|
-
|
37
|
+
method_option :recursive, type: :boolean,
|
38
|
+
desc: 'Specify whether recursive dependencies must be analyzed',
|
39
|
+
default: true,
|
40
|
+
aliases: '-r'
|
41
|
+
|
42
|
+
method_option :config, type: :string,
|
43
|
+
desc: 'The configuration to use',
|
44
|
+
default: File.join("#{Dir.home}", ".chef", "kitchen_inspector.rb"),
|
45
|
+
aliases: '-c'
|
46
|
+
|
47
|
+
method_option :remarks, type: :boolean,
|
48
|
+
desc: 'Show remarks (useful to provide more descriptive information)',
|
49
|
+
default: false,
|
50
|
+
aliases: '--remarks'
|
51
|
+
|
52
|
+
desc 'investigate (COOKBOOK_PATH)', 'Check Repository Manager/Chef Server status of dependent cookbooks'
|
38
53
|
|
39
54
|
map 'inspect' => :investigate
|
40
55
|
def investigate(path=Dir.pwd)
|
41
|
-
|
56
|
+
inspector = HealthBureau.new options[:config]
|
57
|
+
|
58
|
+
dependencies = inspector.investigate(path, options[:recursive])
|
59
|
+
|
42
60
|
if dependencies.empty?
|
43
61
|
puts 'No dependent cookbooks'.yellow
|
62
|
+
status_code = :'warning-nodependencies'
|
44
63
|
else
|
45
|
-
|
64
|
+
output, status_code = Report.generate(dependencies, options[:format], options)
|
65
|
+
puts output
|
46
66
|
end
|
67
|
+
exit STATUS_TO_RETURN_CODES[status_code]
|
68
|
+
rescue ConfigurationError => e
|
69
|
+
puts e.message.red
|
70
|
+
exit STATUS_TO_RETURN_CODES[:'error-config']
|
47
71
|
rescue NotACookbookError
|
48
72
|
puts 'The path is not a cookbook path'.red
|
73
|
+
exit STATUS_TO_RETURN_CODES[:'error-notacookbook']
|
49
74
|
rescue UnsupportedReportFormatError
|
50
75
|
puts "The report format #{options[:format]} is not supported".red
|
76
|
+
exit STATUS_TO_RETURN_CODES[:'error-reportformat']
|
51
77
|
end
|
52
78
|
end
|
53
79
|
end
|
@@ -25,10 +25,52 @@
|
|
25
25
|
|
26
26
|
module KitchenInspector
|
27
27
|
module Inspector
|
28
|
-
class
|
28
|
+
class ConfigurationError < StandardError; end
|
29
|
+
class RepositoryManagerError < ConfigurationError; end
|
30
|
+
|
29
31
|
class ChefAccessNotConfiguredError < StandardError; end
|
30
32
|
class NotACookbookError < StandardError; end
|
31
33
|
class DuplicateCookbookError < StandardError; end
|
32
34
|
class UnsupportedReportFormatError < ArgumentError; end
|
35
|
+
|
36
|
+
# Graphical marks
|
37
|
+
TICK_MARK = "\u2714"
|
38
|
+
X_MARK = "\u2716"
|
39
|
+
ESCLAMATION_MARK = "!"
|
40
|
+
INFO_MARK = "i"
|
41
|
+
INDENT_MARK = "\u203A"
|
42
|
+
QUESTION_MARK = "?"
|
43
|
+
|
44
|
+
# Dependency statuses
|
45
|
+
STATUSES = {
|
46
|
+
:up_to_date => TICK_MARK,
|
47
|
+
:err_req => X_MARK,
|
48
|
+
:err_repo => X_MARK,
|
49
|
+
:err_chef => X_MARK,
|
50
|
+
:warn_req => ESCLAMATION_MARK,
|
51
|
+
:warn_chef => INFO_MARK,
|
52
|
+
:warn_mismatch_repo => ESCLAMATION_MARK,
|
53
|
+
:warn_outofdate_repo => (ESCLAMATION_MARK * 2),
|
54
|
+
:warn_notunique_repo => QUESTION_MARK
|
55
|
+
}
|
56
|
+
STATUSES.default = ' '
|
57
|
+
|
58
|
+
# Possible return codes
|
59
|
+
#
|
60
|
+
# Note that global :err_chef is not possible since there would
|
61
|
+
# be at least one :err_req that takes precedence
|
62
|
+
STATUS_TO_RETURN_CODES = {
|
63
|
+
:up_to_date => 0,
|
64
|
+
:err_req => 100,
|
65
|
+
:err_repo => 101,
|
66
|
+
:err_config => 102,
|
67
|
+
:err_notacookbook => 103,
|
68
|
+
:err_reportformat => 104,
|
69
|
+
:warn_req => 200,
|
70
|
+
:warn_mismatch_repo => 201,
|
71
|
+
:warn_outofdate_repo => 202,
|
72
|
+
:warn_chef => 203
|
73
|
+
}
|
74
|
+
STATUS_TO_RETURN_CODES.default = 1
|
33
75
|
end
|
34
76
|
end
|
@@ -27,73 +27,59 @@ module KitchenInspector
|
|
27
27
|
module Inspector
|
28
28
|
# The class that contains information about a dependent cookbook
|
29
29
|
class Dependency
|
30
|
+
include Comparable
|
31
|
+
|
30
32
|
# The name of the dependency
|
31
33
|
attr_reader :name
|
32
34
|
|
33
35
|
# The requirement for the dependency
|
34
36
|
attr_reader :requirement
|
35
37
|
|
36
|
-
#
|
37
|
-
attr_accessor :
|
38
|
-
|
39
|
-
# The versions available on Chef Server
|
40
|
-
attr_accessor :chef_versions
|
41
|
-
|
42
|
-
# The latest version available on Chef Server
|
43
|
-
attr_accessor :latest_chef
|
38
|
+
# Info from Chef Server
|
39
|
+
attr_accessor :chef
|
44
40
|
|
45
|
-
#
|
46
|
-
attr_accessor :
|
47
|
-
|
48
|
-
# The latest version available on Gitlab
|
49
|
-
attr_accessor :latest_gitlab
|
41
|
+
# Info from the Repository Manager
|
42
|
+
attr_accessor :repomanager
|
50
43
|
|
51
44
|
# The status of the dependency
|
52
45
|
attr_accessor :status
|
53
46
|
|
54
|
-
# The
|
55
|
-
attr_accessor :
|
56
|
-
|
57
|
-
# The status of Chef Server
|
58
|
-
attr_accessor :chef_status
|
59
|
-
|
60
|
-
# The source URL for a cookbook
|
61
|
-
attr_accessor :source_url
|
62
|
-
|
63
|
-
# The changelog link for the dependency if available
|
64
|
-
attr_accessor :changelog
|
47
|
+
# The dependencies of a cookbook
|
48
|
+
attr_accessor :dependencies
|
65
49
|
|
66
50
|
# Remarks field
|
67
51
|
attr_accessor :remarks
|
68
52
|
|
53
|
+
# Dependency's parents (if transitive)
|
54
|
+
attr_accessor :parents
|
55
|
+
|
69
56
|
def initialize(name, requirement)
|
70
57
|
@name = name
|
71
58
|
@requirement = requirement
|
72
|
-
@
|
73
|
-
@
|
74
|
-
@latest_chef = nil
|
75
|
-
@gitlab_versions = []
|
76
|
-
@latest_gitlab = nil
|
59
|
+
@chef = {}
|
60
|
+
@repomanager = {}
|
77
61
|
@status = nil
|
78
|
-
@gitlab_status = nil
|
79
|
-
@chef_status = nil
|
80
|
-
@source_url = nil
|
81
62
|
@remarks = []
|
63
|
+
@dependencies = []
|
64
|
+
@parents = []
|
65
|
+
end
|
66
|
+
|
67
|
+
def ==(anOther)
|
68
|
+
name == anOther.name && requirement == anOther.requirement
|
82
69
|
end
|
83
70
|
|
84
71
|
def to_hash
|
85
72
|
{}.tap do |hash|
|
73
|
+
hash[:name] = name
|
86
74
|
hash[:requirement] = requirement
|
87
|
-
hash[:used] = version_used
|
88
|
-
hash[:chef_versions] = chef_versions
|
89
|
-
hash[:latest_chef] = latest_chef
|
90
|
-
hash[:gitlab_versions] = gitlab_versions
|
91
|
-
hash[:latest_gitlab] = latest_gitlab
|
92
75
|
hash[:status] = status
|
93
|
-
hash[:gitlab_status] = gitlab_status
|
94
|
-
hash[:chef_status] = chef_status
|
95
|
-
hash[:source_url] = source_url
|
96
76
|
hash[:remarks] = remarks
|
77
|
+
hash[:dependencies] = dependencies
|
78
|
+
hash[:chef] = chef
|
79
|
+
hash[:chef][:latest_version] = hash[:chef][:latest_version].to_s if hash[:chef][:latest_version]
|
80
|
+
hash[:repomanager] = repomanager
|
81
|
+
hash[:repomanager][:latest_tag] = hash[:repomanager][:latest_tag].to_s if hash[:repomanager][:latest_tag]
|
82
|
+
hash[:repomanager][:latest_metadata] = hash[:repomanager][:latest_metadata].to_s if hash[:repomanager][:latest_metadata]
|
97
83
|
end
|
98
84
|
end
|
99
85
|
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 Stefano Tortarolo <stefano.tortarolo@gmail.com>
|
3
|
+
#
|
4
|
+
# MIT License
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
# a copy of this software and associated documentation files (the
|
8
|
+
# "Software"), to deal in the Software without restriction, including
|
9
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
# the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be
|
15
|
+
# included in all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
#
|
25
|
+
|
26
|
+
module KitchenInspector
|
27
|
+
module Inspector
|
28
|
+
# Main class that, starting from a cookbook, analyzes its dependencies
|
29
|
+
# using its "inspectors" and returns a collection of analyzed dependencies
|
30
|
+
class HealthBureau
|
31
|
+
include Utils
|
32
|
+
|
33
|
+
attr_reader :chef_inspector, :repo_inspector
|
34
|
+
|
35
|
+
def initialize(config)
|
36
|
+
configuration = read_config(config)
|
37
|
+
|
38
|
+
begin
|
39
|
+
self.instance_eval configuration
|
40
|
+
rescue NoMethodError => e
|
41
|
+
raise ConfigurationError, "Unsupported configuration: #{e.name}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Inspect your kitchen!
|
46
|
+
#
|
47
|
+
# If recursive is specified, dependencies' metadata are downloaded and recursively analyzed
|
48
|
+
#
|
49
|
+
# @param path [String] path to the cookbook to be analyzed
|
50
|
+
# @param recursive [Boolean] whether transitive dependencies should be analyzed
|
51
|
+
# @return [Array<Dependency>] analyzed dependency and its transitive dependencies
|
52
|
+
def investigate(path, recursive=true)
|
53
|
+
raise NotACookbookError, 'Path is not a cookbook' unless File.exists?(File.join(path, 'metadata.rb'))
|
54
|
+
|
55
|
+
metadata = Ridley::Chef::Cookbook::Metadata.from_file(File.join(path, 'metadata.rb'))
|
56
|
+
metadata.dependencies.collect do |name, version|
|
57
|
+
analyze_dependency(Dependency.new(name, version), recursive)
|
58
|
+
end.flatten
|
59
|
+
end
|
60
|
+
|
61
|
+
# Analyze Chef repo and Repository manager in order to find more information
|
62
|
+
# about a given dependency
|
63
|
+
#
|
64
|
+
# @param dependency [Dependency] dependency to be analyzed
|
65
|
+
# @param recursive [Boolean] whether transitive dependencies should be analyzed
|
66
|
+
# @return [Array<Dependency>] analyzed dependency and its transitive dependencies
|
67
|
+
def analyze_dependency(dependency, recursive)
|
68
|
+
chef_info = @chef_inspector.investigate(dependency)
|
69
|
+
|
70
|
+
# Grab information from the Repository Manager
|
71
|
+
info_repo = @repo_inspector.investigate(dependency, chef_info[:version_used], recursive)
|
72
|
+
deps = info_repo.collect do |dep, repo_info|
|
73
|
+
dep_chef_info = @chef_inspector.investigate(dep)
|
74
|
+
update_dependency(dep, dep_chef_info, repo_info)
|
75
|
+
dep
|
76
|
+
end
|
77
|
+
deps
|
78
|
+
end
|
79
|
+
|
80
|
+
# Update in-place a dependency based on information retrieved from
|
81
|
+
# Chef Server and Repository Manager
|
82
|
+
#
|
83
|
+
# @param dependency [Dependency] dependency to be updated
|
84
|
+
# @param chef_info [Hash] information from Chef Server
|
85
|
+
# @param repo_info [Hash] information from Repository Manager
|
86
|
+
def update_dependency(dependency, chef_info, repo_info)
|
87
|
+
dependency.status = :up_to_date
|
88
|
+
|
89
|
+
if !chef_info[:version_used]
|
90
|
+
dependency.status = :err_req
|
91
|
+
msg = 'No versions found'
|
92
|
+
reference_version = @repo_inspector.get_reference_version(nil, repo_info)
|
93
|
+
msg << ", using #{reference_version} for recursive analysis" if reference_version
|
94
|
+
|
95
|
+
dependency.remarks << msg
|
96
|
+
else
|
97
|
+
relaxed_version = satisfy("~> #{chef_info[:version_used]}", chef_info[:versions])
|
98
|
+
if relaxed_version != chef_info[:version_used]
|
99
|
+
dependency.status = :warn_req
|
100
|
+
changelog_url = @repo_inspector.get_changelog(repo_info,
|
101
|
+
chef_info[:version_used],
|
102
|
+
relaxed_version)
|
103
|
+
dependency.remarks << "#{relaxed_version} is available. #{changelog_url}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Compare Chef and Repository Manager versions
|
108
|
+
comparison = compare_repo_chef(chef_info, repo_info)
|
109
|
+
chef_info[:status] = comparison[:chef]
|
110
|
+
repo_info[:status] = comparison[:repo]
|
111
|
+
dependency.remarks.push(*comparison[:remarks]) if comparison[:remarks]
|
112
|
+
|
113
|
+
if repo_info[:not_unique]
|
114
|
+
repo_info[:status] = :warn_notunique_repo
|
115
|
+
dependency.remarks << "Not unique on #{@repo_inspector.manager.type} (this is #{repo_info[:source_url]})"
|
116
|
+
end
|
117
|
+
|
118
|
+
# Check whether latest tag and metadata version in Repository Manager are
|
119
|
+
# consistent
|
120
|
+
unless @repo_inspector.consistent_version?(repo_info)
|
121
|
+
repo_info[:status] = :warn_mismatch_repo
|
122
|
+
dependency.remarks << "#{@repo_inspector.manager.type}'s last tag is #{repo_info[:latest_tag]} " \
|
123
|
+
"but found #{repo_info[:latest_metadata]} in metadata.rb"
|
124
|
+
end
|
125
|
+
|
126
|
+
dependency.repomanager = repo_info
|
127
|
+
dependency.chef = chef_info
|
128
|
+
end
|
129
|
+
|
130
|
+
# Compare Repository Manager and Chef Server
|
131
|
+
#
|
132
|
+
# @param chef_info [Hash] information from Chef Server
|
133
|
+
# @param repo_info [Hash] information from Repository Manager
|
134
|
+
# @return [Hash] containing servers statuses and remarks
|
135
|
+
def compare_repo_chef(chef_info, repo_info)
|
136
|
+
comparison = {:chef => :up_to_date, :repo => :up_to_date,
|
137
|
+
:remarks => []}
|
138
|
+
|
139
|
+
if chef_info[:latest_version] && repo_info[:latest_metadata]
|
140
|
+
if chef_info[:latest_version] > repo_info[:latest_metadata]
|
141
|
+
comparison[:repo] = :warn_outofdate_repo
|
142
|
+
changelog_url = @repo_inspector.get_changelog(repo_info,
|
143
|
+
repo_info[:latest_metadata].to_s,
|
144
|
+
chef_info[:latest_version].to_s)
|
145
|
+
comparison[:remarks] << "#{@repo_inspector.manager.type} out-of-date! #{changelog_url}"
|
146
|
+
return comparison
|
147
|
+
elsif chef_info[:latest_version] < repo_info[:latest_metadata]
|
148
|
+
comparison[:chef] = :warn_chef
|
149
|
+
changelog_url = @repo_inspector.get_changelog(repo_info,
|
150
|
+
chef_info[:latest_version].to_s,
|
151
|
+
repo_info[:latest_metadata].to_s)
|
152
|
+
comparison[:remarks] << "A new version might appear on Chef server. #{changelog_url}"
|
153
|
+
return comparison
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
unless repo_info[:latest_metadata]
|
158
|
+
comparison[:repo] = :err_repo
|
159
|
+
comparison[:remarks] << "#{@repo_inspector.manager.type} doesn't contain any versions."
|
160
|
+
end
|
161
|
+
|
162
|
+
unless chef_info[:latest_version]
|
163
|
+
comparison[:chef] = :err_chef
|
164
|
+
comparison[:remarks] << "Chef Server doesn't contain any versions."
|
165
|
+
end
|
166
|
+
|
167
|
+
comparison
|
168
|
+
end
|
169
|
+
|
170
|
+
# Initialize the Chef Server configuration
|
171
|
+
def chef_server(config)
|
172
|
+
@chef_inspector = ChefInspector.new config
|
173
|
+
end
|
174
|
+
|
175
|
+
# Initialize the Repository Manager
|
176
|
+
def repository_manager(config)
|
177
|
+
@repo_inspector = RepositoryInspector.new config
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|