kitchen-inspector 1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9b52453ef08f59048fe9d23eba2dd17f270cab33
4
+ data.tar.gz: 7806ba21b1e19419f5d6356ea49078718871a44a
5
+ SHA512:
6
+ metadata.gz: cf646ff7130df24e3406c26269ae2eff1524e4a9ae6e726efe146b6d7ef0d4c690bbfe5584b647e4225cfb47acd935a909e81b5d0f72cc1a847f12d496596860
7
+ data.tar.gz: 6f399d5232c70cfe2106ba867c6ef61f9af77e4185666ba8908e91fd3c2c4ceba4357766c91a35cf917550a932460bc2d021a4a12b1d8c6638df02e922b6ed11
@@ -0,0 +1,14 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ doc/
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ tmp
14
+ examples
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+ gem 'byebug'
data/INFO.md ADDED
@@ -0,0 +1,44 @@
1
+ # Dependency Matrix
2
+
3
+ Note: _Used_ refers to the version that would be retrieved from the Chef Server.
4
+
5
+ ## Aligned Servers
6
+ Gitlab | Chef Server
7
+ ------ | -----------
8
+ 1.10 | 1.10
9
+ 1.9.7 | 1.9.7
10
+ 1.9.6 | 1.9.6
11
+
12
+ Scenario | Req | Used | Status Req | Status servers | Remarks
13
+ :- | :- | :- | :- | :- | :-
14
+ Behind req. | = 1.9.6 | 1.9.6 | ! warning-req | √ | You could relax requirements
15
+ Last match | ~> 1.9.6 or = 1.9.7 | 1.9.7 | √ | √ |
16
+ Forward req. | > 1.10 or > 1.9.7 | | X error | √ | Version not found
17
+
18
+ ## Gitlab out-of-date
19
+ Gitlab | Chef Server
20
+ ------ | -----------
21
+ | 1.10
22
+ 1.9.7 | 1.9.7
23
+ 1.9.6 | 1.9.6
24
+
25
+ Scenario | Req | Used | Status Req | Status servers | Remarks
26
+ :- | :- | :- | :- | :- | :-
27
+ Behind req. | = 1.9.6 | 1.9.6 | ! warning-req | ! warning-gitlab | You could relax requirements. Gitlab not aligned
28
+ Last match gitlab | ~> 1.9.6 or = 1.9.7 | 1.9.7 | √ | ! warning-gitlab | Gitlab not aligned
29
+ Last match Chef | ~> 1.10 | 1.10 | √ | ! warning-gitlab | Gitlab not aligned
30
+ Forward req. | > 1.10 or > 1.9.7 | | X error | ! warning-gitlab | Version not found
31
+
32
+ ## Chef server out-of-date
33
+ Gitlab | Chef Server
34
+ ------ | -----------
35
+ 1.10 |
36
+ 1.9.7 | 1.9.7
37
+ 1.9.6 | 1.9.6
38
+
39
+ Scenario | Req | Used | Status Req | Status servers | Remarks
40
+ :- | :- | :- | :- | :- | :-
41
+ Behind req. | = 1.9.6 | 1.9.6 | ! warning-req | ! warning-chef | You could relax requirements. Chef Server not aligned
42
+ Last match gitlab | ~> 1.10 | | X error | ! warning-chef | Chef Server not aligned
43
+ Last match Chef | ~> 1.9.6 | 1.9.7 | √ | ! warning-chef | Chef Server not aligned
44
+ Forward req. | > 1.10 | | X error | ! warning-chef | Version not found
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Stefano Tortarolo <stefano.tortarolo@gmail.com>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,80 @@
1
+ # Kitchen Inspector
2
+
3
+ Kitchen Ispector is a CLI utility inspired by chef-taste to check a cookbook's dependency status against a Chef server and a Gitlab instance.
4
+
5
+ It assumes that your kitchen is composed by:
6
+
7
+ * a Chef server containing the cookbooks to be used
8
+ * a Gitlab instance hosting cookbook's development
9
+
10
+ This tool checks whether the dependencies specified are up to date or not.
11
+ It also shows whether one of the servers must be aligned.
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ gem 'kitchen-inspector'
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it with:
24
+
25
+ $ gem install kitchen-inspector
26
+
27
+ ## Usage
28
+
29
+ The following variables must be exported in order to configure the Chef and Gitlab servers:
30
+
31
+ * GITLAB_URL: Url of the Gitlab server
32
+ * GITLAB_TOKEN: Gitlab private token (Profile > Account)
33
+ * CHEF_SERVER_URL: Url of the Chef server
34
+ * CHEF_USERNAME: Client username
35
+ * CHEF_CLIENT_PEM: Location of the client pem
36
+
37
+ From inside the cookbook's directory, type `kitchen-inspector` to inspect your kitchen.
38
+ It's also possible to specify a target directory with `kitchen-inspector investigate PATH`.
39
+
40
+ The `metadata.rb` of the cookbook is parsed to obtain the dependencies, then the configured Chef server and Gitlab server are queried to define which versions are available.
41
+ The Chef server's version is the one that will define the used version.
42
+
43
+ It will display a table that contains the following rows:
44
+
45
+ * `Name` - The name of the cookbook
46
+ * `Requirement` - The version requirement specified in the metadata
47
+ * `Used` - The final version used based on the requirement constraint
48
+ * `Latest Chef` - The latest version available on the Chef server
49
+ * `Latest Gitlab` - The latest version available on the Gitlab server
50
+ * `Requirement Status` - The status of the cookbook: up-to-date (a green tick mark), warning-req (a yellow esclamation point) or out-of-date (a red x mark)
51
+ * `Chef Server Status` - The status of the chef server: up-to-date (a green tick mark), warning-req (a yellow esclamation point) or out-of-date (a red x mark)
52
+ * `Gitlab Status` - The status of the Gitlab server: up-to-date (a green tick mark), warning-req (a yellow esclamation point) or out-of-date (a red x mark)
53
+
54
+ The overall status will also be displayed in the bottom of the table.
55
+
56
+ ### Display Format
57
+
58
+ Two display formats are supported: table and json
59
+
60
+ 1. The table format will display the dependency status as an ASCII table
61
+ 2. The json format will display the dependency status as a JSON object
62
+
63
+ ### Examples
64
+
65
+ +-----------+-------------+-------+--------+--------+-------------+-------------+--------+--------------------+
66
+ | Name | Requirement | Used | Latest | Latest | Requirement | Chef Server | Gitlab | Remarks |
67
+ | | | | Chef | Gitlab | Status | Status | Status | |
68
+ +-----------+-------------+-------+--------+--------+-------------+-------------+--------+--------------------+
69
+ | apt | = 2.3.4 | 2.3.4 | 2.3.4 | 2.3.8 | ✔ | ! | ✔ | A new version might appear on Chef server|
70
+ | jbosseap6 | ~> 0.9.3 | 0.9.8 | 0.10.0 | 0.10.0 | ✔ | ✔ | ✔ | |
71
+ | database | = 1.5.2 | 1.5.2 | 1.5.3 | 1.5.2 | ! | ✔ | !! | 1.5.3 is available, Gitlab out-of-date! |
72
+ | yum | = 2.3.4 | 2.3.4 | 2.3.4 | 2.3.4 | ✔ | ✔ | ✔ | |
73
+ | git | = 1.8.1 | 1.8.1 | 1.8.4 | 1.8.4 | ! | ✔ | ✔ | 1.8.4 is available |
74
+ | hadoop | ~> 1.1.0 | | | 1.0.0 | ✖ | ! | ✔ | No versions found |
75
+ | zookeeper | = 1.0.0 | | | 1.0.0 | ✖ | ! | ✔ | No versions found |
76
+ +-----------+-------------+-------+--------+--------+-------------+-------------+--------+--------------------+
77
+ Status: error (✖)
78
+
79
+ ## Credits
80
+ This code was heavily inspired by Kannan Manickam's [chef-taste](https://github.com/arangamani/chef-taste)
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.push File.expand_path('../../lib', __FILE__)
3
+ require 'kitchen-inspector/inspector'
4
+
5
+ KitchenInspector::Inspector::Cli.start
@@ -0,0 +1,31 @@
1
+ table {
2
+ margin-bottom: 10px !important;
3
+ margin:0px;padding:0px;
4
+ border:1px solid #000;
5
+ border-collapse: collapse;
6
+ border-spacing: 0;
7
+ width:90%;
8
+ height:100%;
9
+ }
10
+ table tr:nth-child(odd){ background-color:#f5f5f5; }
11
+ table tr:nth-child(even){ background-color:#ffffff; }
12
+
13
+ table td{
14
+ vertical-align:middle;
15
+ border:1px solid #000;
16
+ text-align:left;
17
+ padding:8px;
18
+ font-size:11px;
19
+ font-family:Arial;
20
+ font-weight:normal;
21
+ color:#000;
22
+ }
23
+ table th{
24
+ background-color:#b2b2b2;
25
+ border:1px solid #000;
26
+ text-align:center;
27
+ font-size:14px;
28
+ font-family:Arial;
29
+ font-weight:bold;
30
+ color:#333;
31
+ }
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kitchen-inspector/inspector/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "kitchen-inspector"
8
+ spec.version = KitchenInspector::Inspector::VERSION
9
+ spec.authors = ["Stefano Tortarolo"]
10
+ spec.email = ["stefano.tortarolo@gmail.com"]
11
+ spec.description = %q{This gem verifies that dependencies are updated in regard with a Chef Server and Gitlab}
12
+ spec.summary = %q{Chef server and Gitlab dependency checker}
13
+ spec.homepage = "https://github.com/astratto/kitchen-inspector"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rubocop", "~> 0.14"
23
+ spec.add_development_dependency "rake"
24
+
25
+ spec.add_dependency "solve", "~> 0.8.0"
26
+ spec.add_dependency "berkshelf", "~> 2.0.10"
27
+ spec.add_dependency "thor", "~> 0.18.0"
28
+ spec.add_dependency "terminal-table", "~> 1.4.5"
29
+ spec.add_dependency "colorize", "~> 0.6.0"
30
+ spec.add_dependency "gitlab"
31
+ spec.add_dependency "chef", ">= 11.0.0"
32
+ end
@@ -0,0 +1,39 @@
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
+ require 'chef/rest'
27
+ require 'berkshelf'
28
+ require 'colorize'
29
+ require 'ridley'
30
+ require 'terminal-table'
31
+ require 'thor'
32
+ require 'gitlab'
33
+
34
+ require 'kitchen-inspector/inspector/cli'
35
+ require 'kitchen-inspector/inspector/error'
36
+ require 'kitchen-inspector/inspector/dependency'
37
+ require 'kitchen-inspector/inspector/dependency_inspector'
38
+ require 'kitchen-inspector/inspector/report'
39
+ require 'kitchen-inspector/inspector/version'
@@ -0,0 +1,53 @@
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 Cli < Thor
29
+ default_task :investigate
30
+
31
+ method_option :format, type: :string,
32
+ desc: 'The format to use for display',
33
+ enum: %w(table json),
34
+ default: 'table',
35
+ aliases: '-t'
36
+
37
+ desc 'investigate (COOKBOOK_PATH)', 'Check Gitlab/Chef status of dependent cookbooks'
38
+
39
+ def investigate(path=Dir.pwd)
40
+ dependencies = DependencyInspector.investigate path
41
+ if dependencies.empty?
42
+ puts 'No dependent cookbooks'.yellow
43
+ else
44
+ puts Report.generate(dependencies, options[:format])
45
+ end
46
+ rescue NotACookbookError
47
+ puts 'The path is not a cookbook path'.red
48
+ rescue UnsupportedReportFormatError
49
+ puts "The report format #{options[:format]} is not supported".red
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,101 @@
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
+ # The class that contains information about a dependent cookbook
29
+ class Dependency
30
+ # The name of the dependency
31
+ attr_reader :name
32
+
33
+ # The requirement for the dependency
34
+ attr_reader :requirement
35
+
36
+ # The version of cookbook used after applying the version constraint
37
+ attr_accessor :version_used
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
44
+
45
+ # The versions available on Gitlab
46
+ attr_accessor :gitlab_versions
47
+
48
+ # The latest version available on Gitlab
49
+ attr_accessor :latest_gitlab
50
+
51
+ # The status of the dependency
52
+ attr_accessor :status
53
+
54
+ # The status of Gitlab
55
+ attr_accessor :gitlab_status
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
65
+
66
+ # Remarks field
67
+ attr_accessor :remarks
68
+
69
+ def initialize(name, requirement)
70
+ @name = name
71
+ @requirement = requirement
72
+ @version_used = nil
73
+ @chef_versions = []
74
+ @latest_chef = nil
75
+ @gitlab_versions = []
76
+ @latest_gitlab = nil
77
+ @status = nil
78
+ @gitlab_status = nil
79
+ @chef_status = nil
80
+ @source_url = nil
81
+ @remarks = []
82
+ end
83
+
84
+ def to_hash
85
+ {}.tap do |hash|
86
+ 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
+ hash[:status] = status
93
+ hash[:gitlab_status] = gitlab_status
94
+ hash[:chef_status] = chef_status
95
+ hash[:source_url] = source_url
96
+ hash[:remarks] = remarks
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,150 @@
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 DependencyInspector
29
+ REPO_PER_PAGE = 1000
30
+ GITLAB_BASE_URL = ENV['GITLAB_URL']
31
+ GITLAB_API_URL = "#{GITLAB_BASE_URL}/api/v3"
32
+ CHEF_SERVER_URL = ENV['CHEF_SERVER_URL']
33
+ CHEF_USERNAME = ENV['CHEF_USERNAME']
34
+ CHEF_CLIENT_PEM = ENV['CHEF_CLIENT_PEM']
35
+ GITLAB_TOKEN = ENV['GITLAB_TOKEN']
36
+
37
+ raise GitlabAccessNotConfiguredError, "Gitlab URL not configured. Please set it in ENV['GITLAB_URL']" unless GITLAB_BASE_URL
38
+ raise GitlabAccessNotConfiguredError, "Private Token not configured. Please set it in ENV['GITLAB_TOKEN']" unless GITLAB_TOKEN
39
+
40
+ raise ChefAccessNotConfiguredError, "Please set ENV['CHEF_SERVER_URL']" unless CHEF_SERVER_URL
41
+ raise ChefAccessNotConfiguredError, "Please set ENV['CHEF_USERNAME']" unless CHEF_USERNAME
42
+ raise ChefAccessNotConfiguredError, "Please set ENV['CHEF_CLIENT_PEM']" unless CHEF_CLIENT_PEM
43
+
44
+ Gitlab.configure do |config|
45
+ config.endpoint = GITLAB_API_URL
46
+ config.private_token = GITLAB_TOKEN
47
+ config.user_agent = 'Kitchen Inspector'
48
+ end
49
+
50
+ def self.investigate(path)
51
+ raise NotACookbookError, 'Path is not a cookbook' unless File.exists?(File.join(path, 'metadata.rb'))
52
+ ridley = Ridley::Chef::Cookbook::Metadata.from_file(File.join(path, 'metadata.rb'))
53
+ dependencies =
54
+ ridley.dependencies.map do |name, version|
55
+ Dependency.new(name, version)
56
+ end
57
+ populate_fields(dependencies)
58
+ end
59
+
60
+ def self.populate_fields(dependencies)
61
+ projects = Gitlab.projects(:per_page => REPO_PER_PAGE)
62
+
63
+ dependencies.each do |dependency|
64
+ # Skip cookbooks that are not available on Gitlab.
65
+ project = projects.select do |pr|
66
+ pr.instance_variable_get("@data")["path"] == "#{dependency.name}"
67
+ end
68
+
69
+ next unless project
70
+
71
+ raise DuplicateCookbookError, "Found two versions for #{dependency.name} on Gitlab." if project.size > 1
72
+ project = project.first
73
+
74
+ dependency.gitlab_versions = find_gitlab_versions(project)
75
+ dependency.chef_versions = find_chef_server_versions(project.path)
76
+ dependency.version_used = satisfy(dependency.requirement, dependency.chef_versions)
77
+ dependency.source_url = "#{GITLAB_BASE_URL}/#{project.path_with_namespace}"
78
+
79
+ update_status(dependency)
80
+ end
81
+ end
82
+
83
+ def self.satisfy(constraint, versions)
84
+ Solve::Solver.satisfy_best(constraint, versions).to_s
85
+ rescue Solve::Errors::NoSolutionError
86
+ nil
87
+ end
88
+
89
+ # Updates the status of the dependency based on the version used and the latest version available on Gitlab
90
+ def self.update_status(dependency)
91
+ dependency.latest_chef = get_latest_version(dependency.chef_versions)
92
+ dependency.latest_gitlab = get_latest_version(dependency.gitlab_versions)
93
+
94
+ dependency.status = 'up-to-date'
95
+ dependency.chef_status = 'up-to-date'
96
+ dependency.gitlab_status = 'up-to-date'
97
+
98
+ if !dependency.version_used
99
+ dependency.status = 'error'
100
+ dependency.remarks << 'No versions found'
101
+ else
102
+ relaxed_version = satisfy("~> #{dependency.version_used}", dependency.chef_versions)
103
+ if relaxed_version != dependency.version_used
104
+ dependency.status = 'warning-req'
105
+ dependency.remarks << "#{relaxed_version} is available"
106
+ end
107
+ end
108
+
109
+ if dependency.latest_chef && dependency.latest_gitlab
110
+ if dependency.latest_chef > dependency.latest_gitlab
111
+ dependency.chef_status = 'up-to-date'
112
+ dependency.gitlab_status = 'warning-gitlab'
113
+ dependency.remarks << "Gitlab out-of-date!"
114
+ elsif dependency.latest_chef < dependency.latest_gitlab
115
+ dependency.chef_status = 'warning-chef'
116
+ dependency.gitlab_status = 'up-to-date'
117
+ dependency.remarks << "A new version might appear on Chef server"
118
+ end
119
+ else
120
+ dependency.gitlab_status = 'warning-gitlab' unless dependency.latest_gitlab
121
+ dependency.chef_status = 'warning-chef' unless dependency.latest_chef
122
+ end
123
+ end
124
+
125
+ def self.find_chef_server_versions(project)
126
+ rest = Chef::REST.new(CHEF_SERVER_URL, CHEF_USERNAME, CHEF_CLIENT_PEM)
127
+ cookbook = rest.get("cookbooks/#{project}")
128
+ versions = []
129
+ versions = cookbook[project]["versions"].collect{|c| fix_version_name(c["version"])} if cookbook
130
+ versions
131
+ rescue Net::HTTPServerException
132
+ []
133
+ end
134
+
135
+ def self.find_gitlab_versions(project)
136
+ Gitlab.tags(project.id).collect do |t|
137
+ fix_version_name(t.instance_variable_get("@data")["name"])
138
+ end
139
+ end
140
+
141
+ def self.fix_version_name(version)
142
+ version.gsub(/[v][\.]*/i, "")
143
+ end
144
+
145
+ def self.get_latest_version(versions)
146
+ versions.collect{|v| Solve::Version.new(v)}.max
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,34 @@
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 GitlabAccessNotConfiguredError < StandardError; end
29
+ class ChefAccessNotConfiguredError < StandardError; end
30
+ class NotACookbookError < StandardError; end
31
+ class DuplicateCookbookError < StandardError; end
32
+ class UnsupportedReportFormatError < ArgumentError; end
33
+ end
34
+ end
@@ -0,0 +1,148 @@
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
+ # The ASCII code for tick mark symbol
29
+ TICK_MARK = "\u2714"
30
+ # The ASCII code for X mark symbol
31
+ X_MARK = "\u2716"
32
+ # The ! symbol
33
+ ESCLAMATION_MARK = "!"
34
+
35
+ class Report
36
+ class << self
37
+ # Generates the status of dependent cookbooks in specified format
38
+ #
39
+ # @param dependencies [Array<Dependency>] list of cookbook dependency objects
40
+ # @param format [String] the format used for Report
41
+ #
42
+ def generate(dependencies, format)
43
+ case format
44
+ when 'table'
45
+ TableReport.generate(dependencies)
46
+ when'json'
47
+ JSONReport.generate(dependencies)
48
+ else
49
+ raise UnsupportedReportFormatError, "Report format '#{format}' is not supported"
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ # Reports the cookbook dependency status in a table format
56
+ #
57
+ class TableReport
58
+ class << self
59
+ # Generates the status of dependent cookbooks as a table
60
+ #
61
+ # @param dependencies [Array<Dependency>] list of cookbook dependency objects
62
+ #
63
+ def generate(dependencies)
64
+ rows = []
65
+ headings = ["Name", "Requirement", "Used", "Latest\nChef", "Latest\nGitlab", "Requirement\nStatus",
66
+ "Chef Server\nStatus", "Gitlab\nStatus", "Remarks"]
67
+ dependencies.each do |dependency|
68
+ status = status_to_mark(dependency.status)
69
+ chef_status = status_to_mark(dependency.chef_status)
70
+ gitlab_status = status_to_mark(dependency.gitlab_status)
71
+
72
+ name = dependency.name.dup
73
+ name = name.red if dependency.status == 'error'
74
+
75
+ rows << [
76
+ name,
77
+ dependency.requirement,
78
+ dependency.version_used,
79
+ dependency.latest_chef,
80
+ dependency.latest_gitlab,
81
+ { value: status, alignment: :center },
82
+ { value: chef_status, alignment: :center },
83
+ { value: gitlab_status, alignment: :center },
84
+ dependency.remarks.join(', ')
85
+ ]
86
+ end
87
+
88
+ # Show Table
89
+ table = Terminal::Table.new headings: headings, rows: rows
90
+
91
+ # Show Status
92
+ if dependencies.any? { |dep| dep.status == 'error' }
93
+ status = "Status: error (#{X_MARK})".red
94
+ elsif dependencies.any? { |dep| dep.status == 'warning-req' }
95
+ status = "Status: warning-req (#{ESCLAMATION_MARK})".yellow
96
+ elsif dependencies.any? { |dep| dep.status == 'warning-gitlab' }
97
+ status = "Status: warning-gitlab (#{ESCLAMATION_MARK})".yellow
98
+ elsif dependencies.any? { |dep| dep.status == 'warning-chef' }
99
+ status = "Status: warning-chef (#{ESCLAMATION_MARK})".yellow
100
+ else
101
+ status = "Status: up-to-date (#{TICK_MARK})".green
102
+ end
103
+
104
+ "#{table}\n#{status}"
105
+ end
106
+
107
+ # Given a status return a mark
108
+ def status_to_mark(status)
109
+ case status
110
+ when 'up-to-date'
111
+ return TICK_MARK.green
112
+ when 'error'
113
+ return X_MARK.red
114
+ when /warning-req/
115
+ return ESCLAMATION_MARK.bold.yellow
116
+ when /warning-chef/
117
+ return "i".bold.blue
118
+ when /warning-gitlab/
119
+ return (ESCLAMATION_MARK * 2).bold.light_red
120
+ else
121
+ return ''.white
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ # Return Kitchen's status in JSON format
128
+ class JSONReport
129
+ class << self
130
+ def generate(dependencies)
131
+ JSON.pretty_generate(dependencies_hash(dependencies))
132
+ end
133
+
134
+ # Converts the dependency objects to JSON object
135
+ #
136
+ # @param dependencies [Array<Dependency>] list of cookbook dependency objects
137
+ #
138
+ def dependencies_hash(dependencies)
139
+ {}.tap do |hash|
140
+ dependencies.each do |dependency|
141
+ hash[dependency.name] = dependency.to_hash
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,30 @@
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
+ module KitchenInspector
26
+ module Inspector
27
+ # The version string
28
+ VERSION = '1.0.0'
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,202 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kitchen-inspector
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Stefano Tortarolo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '0.14'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '0.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: solve
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.8.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 0.8.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: berkshelf
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 2.0.10
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 2.0.10
83
+ - !ruby/object:Gem::Dependency
84
+ name: thor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 0.18.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 0.18.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: terminal-table
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 1.4.5
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 1.4.5
111
+ - !ruby/object:Gem::Dependency
112
+ name: colorize
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 0.6.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: 0.6.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: gitlab
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: chef
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: 11.0.0
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: 11.0.0
153
+ description: This gem verifies that dependencies are updated in regard with a Chef
154
+ Server and Gitlab
155
+ email:
156
+ - stefano.tortarolo@gmail.com
157
+ executables:
158
+ - kitchen-inspector
159
+ extensions: []
160
+ extra_rdoc_files: []
161
+ files:
162
+ - .gitignore
163
+ - Gemfile
164
+ - INFO.md
165
+ - LICENSE.txt
166
+ - README.md
167
+ - Rakefile
168
+ - bin/kitchen-inspector
169
+ - info.css
170
+ - kitchen-inspector.gemspec
171
+ - lib/kitchen-inspector/inspector.rb
172
+ - lib/kitchen-inspector/inspector/cli.rb
173
+ - lib/kitchen-inspector/inspector/dependency.rb
174
+ - lib/kitchen-inspector/inspector/dependency_inspector.rb
175
+ - lib/kitchen-inspector/inspector/error.rb
176
+ - lib/kitchen-inspector/inspector/report.rb
177
+ - lib/kitchen-inspector/inspector/version.rb
178
+ homepage: https://github.com/astratto/kitchen-inspector
179
+ licenses:
180
+ - MIT
181
+ metadata: {}
182
+ post_install_message:
183
+ rdoc_options: []
184
+ require_paths:
185
+ - lib
186
+ required_ruby_version: !ruby/object:Gem::Requirement
187
+ requirements:
188
+ - - '>='
189
+ - !ruby/object:Gem::Version
190
+ version: '0'
191
+ required_rubygems_version: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - '>='
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ requirements: []
197
+ rubyforge_project:
198
+ rubygems_version: 2.1.11
199
+ signing_key:
200
+ specification_version: 4
201
+ summary: Chef server and Gitlab dependency checker
202
+ test_files: []