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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +9 -0
  4. data/CHANGELOG.md +24 -0
  5. data/Gemfile +0 -2
  6. data/README.md +268 -39
  7. data/Rakefile +41 -0
  8. data/kitchen-inspector.gemspec +21 -3
  9. data/lib/kitchen-inspector/inspector.rb +11 -4
  10. data/lib/kitchen-inspector/inspector/chef_inspector.rb +66 -0
  11. data/lib/kitchen-inspector/inspector/cli.rb +29 -3
  12. data/lib/kitchen-inspector/inspector/{error.rb → common.rb} +43 -1
  13. data/lib/kitchen-inspector/inspector/dependency.rb +26 -40
  14. data/lib/kitchen-inspector/inspector/health_bureau.rb +181 -0
  15. data/lib/kitchen-inspector/inspector/mixin/utils.rb +83 -0
  16. data/lib/kitchen-inspector/inspector/report/report.rb +182 -0
  17. data/lib/kitchen-inspector/inspector/report/status_reporter.rb +105 -0
  18. data/lib/kitchen-inspector/inspector/repository_inspector.rb +134 -0
  19. data/lib/kitchen-inspector/inspector/repository_managers/base.rb +110 -0
  20. data/lib/kitchen-inspector/inspector/repository_managers/github.rb +97 -0
  21. data/lib/kitchen-inspector/inspector/repository_managers/gitlab.rb +100 -0
  22. data/lib/kitchen-inspector/inspector/version.rb +1 -2
  23. data/spec/cli_spec.rb +46 -0
  24. data/spec/data/cookbook_deps/metadata.rb +10 -0
  25. data/spec/data/cookbook_no_deps/metadata.rb +7 -0
  26. data/spec/data/test_client.pem +27 -0
  27. data/spec/data/test_config_invalid.rb +4 -0
  28. data/spec/data/test_config_valid.rb +4 -0
  29. data/spec/dependency_inspector_spec.rb +296 -0
  30. data/spec/github_manager_spec.rb +79 -0
  31. data/spec/gitlab_manager_spec.rb +58 -0
  32. data/spec/report_spec.rb +237 -0
  33. data/spec/support/spec_helper.rb +81 -0
  34. data/spec/utils_spec.rb +29 -0
  35. metadata +129 -15
  36. data/INFO.md +0 -44
  37. data/info.css +0 -31
  38. data/lib/kitchen-inspector/inspector/dependency_inspector.rb +0 -153
  39. data/lib/kitchen-inspector/inspector/report.rb +0 -148
@@ -0,0 +1,29 @@
1
+ require_relative 'support/spec_helper'
2
+
3
+ include Utils
4
+
5
+ describe Utils do
6
+ describe ".eval_metadata" do
7
+ let(:response_metadata) do
8
+ "name 'test_meta'\n" \
9
+ "maintainer 'Kitchen Inspector'\n" \
10
+ "maintainer_email 'example@fake.com'\n" \
11
+ "license 'All rights reserved'\n" \
12
+ "description 'Installs/Configures test_meta'\n" \
13
+ "long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))\n" \
14
+ "version '0.10.2'\n" \
15
+ "depends 'apache2', '= 1.8.2'\n" \
16
+ "depends 'postgresql', '= 3.0.5'"
17
+ end
18
+
19
+ it "generates a valid Metadata" do
20
+ metadata = eval_metadata response_metadata
21
+ expect(metadata.version).to eq("0.10.2")
22
+ end
23
+
24
+ it "generates a Metadata with filtered fields" do
25
+ metadata = eval_metadata response_metadata
26
+ expect(metadata.description).to eq("A fabulous new cookbook")
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-inspector
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefano Tortarolo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-18 00:00:00.000000000 Z
11
+ date: 2013-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,76 @@ dependencies:
52
52
  - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: chef-zero
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: coveralls
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: gitlab
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: octokit
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '2.6'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: '2.6'
55
125
  - !ruby/object:Gem::Dependency
56
126
  name: solve
57
127
  requirement: !ruby/object:Gem::Requirement
@@ -123,19 +193,33 @@ dependencies:
123
193
  - !ruby/object:Gem::Version
124
194
  version: 0.6.0
125
195
  - !ruby/object:Gem::Dependency
126
- name: gitlab
196
+ name: httparty
127
197
  requirement: !ruby/object:Gem::Requirement
128
198
  requirements:
129
- - - '>='
199
+ - - ~>
130
200
  - !ruby/object:Gem::Version
131
- version: '0'
201
+ version: 0.10.0
132
202
  type: :runtime
133
203
  prerelease: false
134
204
  version_requirements: !ruby/object:Gem::Requirement
135
205
  requirements:
136
- - - '>='
206
+ - - ~>
137
207
  - !ruby/object:Gem::Version
138
- version: '0'
208
+ version: 0.10.0
209
+ - !ruby/object:Gem::Dependency
210
+ name: googl
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ~>
214
+ - !ruby/object:Gem::Version
215
+ version: 0.6.3
216
+ type: :runtime
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ~>
221
+ - !ruby/object:Gem::Version
222
+ version: 0.6.3
139
223
  - !ruby/object:Gem::Dependency
140
224
  name: chef
141
225
  requirement: !ruby/object:Gem::Requirement
@@ -150,8 +234,8 @@ dependencies:
150
234
  - - '>='
151
235
  - !ruby/object:Gem::Version
152
236
  version: 11.0.0
153
- description: Given an Opscode Chef cookbook, verifies its dependencies against a Chef
154
- Server and a Gitlab instance
237
+ description: Given a Chef cookbook, verifies its dependencies against a Chef Server
238
+ and a Repository Manager instance (i.e., GitHub/GitLab)
155
239
  email:
156
240
  - stefano.tortarolo@gmail.com
157
241
  executables:
@@ -160,22 +244,40 @@ extensions: []
160
244
  extra_rdoc_files: []
161
245
  files:
162
246
  - .gitignore
247
+ - .travis.yml
163
248
  - CHANGELOG.md
164
249
  - Gemfile
165
- - INFO.md
166
250
  - LICENSE
167
251
  - README.md
168
252
  - Rakefile
169
253
  - bin/kitchen-inspector
170
- - info.css
171
254
  - kitchen-inspector.gemspec
172
255
  - lib/kitchen-inspector/inspector.rb
256
+ - lib/kitchen-inspector/inspector/chef_inspector.rb
173
257
  - lib/kitchen-inspector/inspector/cli.rb
258
+ - lib/kitchen-inspector/inspector/common.rb
174
259
  - lib/kitchen-inspector/inspector/dependency.rb
175
- - lib/kitchen-inspector/inspector/dependency_inspector.rb
176
- - lib/kitchen-inspector/inspector/error.rb
177
- - lib/kitchen-inspector/inspector/report.rb
260
+ - lib/kitchen-inspector/inspector/health_bureau.rb
261
+ - lib/kitchen-inspector/inspector/mixin/utils.rb
262
+ - lib/kitchen-inspector/inspector/report/report.rb
263
+ - lib/kitchen-inspector/inspector/report/status_reporter.rb
264
+ - lib/kitchen-inspector/inspector/repository_inspector.rb
265
+ - lib/kitchen-inspector/inspector/repository_managers/base.rb
266
+ - lib/kitchen-inspector/inspector/repository_managers/github.rb
267
+ - lib/kitchen-inspector/inspector/repository_managers/gitlab.rb
178
268
  - lib/kitchen-inspector/inspector/version.rb
269
+ - spec/cli_spec.rb
270
+ - spec/data/cookbook_deps/metadata.rb
271
+ - spec/data/cookbook_no_deps/metadata.rb
272
+ - spec/data/test_client.pem
273
+ - spec/data/test_config_invalid.rb
274
+ - spec/data/test_config_valid.rb
275
+ - spec/dependency_inspector_spec.rb
276
+ - spec/github_manager_spec.rb
277
+ - spec/gitlab_manager_spec.rb
278
+ - spec/report_spec.rb
279
+ - spec/support/spec_helper.rb
280
+ - spec/utils_spec.rb
179
281
  homepage: https://github.com/astratto/kitchen-inspector
180
282
  licenses:
181
283
  - MIT
@@ -200,4 +302,16 @@ rubygems_version: 2.1.11
200
302
  signing_key:
201
303
  specification_version: 4
202
304
  summary: Kitchen integrity checker
203
- test_files: []
305
+ test_files:
306
+ - spec/cli_spec.rb
307
+ - spec/data/cookbook_deps/metadata.rb
308
+ - spec/data/cookbook_no_deps/metadata.rb
309
+ - spec/data/test_client.pem
310
+ - spec/data/test_config_invalid.rb
311
+ - spec/data/test_config_valid.rb
312
+ - spec/dependency_inspector_spec.rb
313
+ - spec/github_manager_spec.rb
314
+ - spec/gitlab_manager_spec.rb
315
+ - spec/report_spec.rb
316
+ - spec/support/spec_helper.rb
317
+ - spec/utils_spec.rb
data/INFO.md DELETED
@@ -1,44 +0,0 @@
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
data/info.css DELETED
@@ -1,31 +0,0 @@
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
- }
@@ -1,153 +0,0 @@
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
-
53
- require 'pry-byebug'
54
- binding.pry
55
- ridley = Ridley::Chef::Cookbook::Metadata.from_file(File.join(path, 'metadata.rb'))
56
- dependencies =
57
- ridley.dependencies.map do |name, version|
58
- Dependency.new(name, version)
59
- end
60
- populate_fields(dependencies)
61
- end
62
-
63
- def self.populate_fields(dependencies)
64
- projects = Gitlab.projects(:per_page => REPO_PER_PAGE)
65
-
66
- dependencies.each do |dependency|
67
- # Skip cookbooks that are not available on Gitlab.
68
- project = projects.select do |pr|
69
- pr.instance_variable_get("@data")["path"] == "#{dependency.name}"
70
- end
71
-
72
- next unless project
73
-
74
- raise DuplicateCookbookError, "Found two versions for #{dependency.name} on Gitlab." if project.size > 1
75
- project = project.first
76
-
77
- dependency.gitlab_versions = find_gitlab_versions(project)
78
- dependency.chef_versions = find_chef_server_versions(project.path)
79
- dependency.version_used = satisfy(dependency.requirement, dependency.chef_versions)
80
- dependency.source_url = "#{GITLAB_BASE_URL}/#{project.path_with_namespace}"
81
-
82
- update_status(dependency)
83
- end
84
- end
85
-
86
- def self.satisfy(constraint, versions)
87
- Solve::Solver.satisfy_best(constraint, versions).to_s
88
- rescue Solve::Errors::NoSolutionError
89
- nil
90
- end
91
-
92
- # Updates the status of the dependency based on the version used and the latest version available on Gitlab
93
- def self.update_status(dependency)
94
- dependency.latest_chef = get_latest_version(dependency.chef_versions)
95
- dependency.latest_gitlab = get_latest_version(dependency.gitlab_versions)
96
-
97
- dependency.status = 'up-to-date'
98
- dependency.chef_status = 'up-to-date'
99
- dependency.gitlab_status = 'up-to-date'
100
-
101
- if !dependency.version_used
102
- dependency.status = 'error'
103
- dependency.remarks << 'No versions found'
104
- else
105
- relaxed_version = satisfy("~> #{dependency.version_used}", dependency.chef_versions)
106
- if relaxed_version != dependency.version_used
107
- dependency.status = 'warning-req'
108
- dependency.remarks << "#{relaxed_version} is available"
109
- end
110
- end
111
-
112
- if dependency.latest_chef && dependency.latest_gitlab
113
- if dependency.latest_chef > dependency.latest_gitlab
114
- dependency.chef_status = 'up-to-date'
115
- dependency.gitlab_status = 'warning-gitlab'
116
- dependency.remarks << "Gitlab out-of-date!"
117
- elsif dependency.latest_chef < dependency.latest_gitlab
118
- dependency.chef_status = 'warning-chef'
119
- dependency.gitlab_status = 'up-to-date'
120
- dependency.remarks << "A new version might appear on Chef server"
121
- end
122
- else
123
- dependency.gitlab_status = 'warning-gitlab' unless dependency.latest_gitlab
124
- dependency.chef_status = 'warning-chef' unless dependency.latest_chef
125
- end
126
- end
127
-
128
- def self.find_chef_server_versions(project)
129
- rest = Chef::REST.new(CHEF_SERVER_URL, CHEF_USERNAME, CHEF_CLIENT_PEM)
130
- cookbook = rest.get("cookbooks/#{project}")
131
- versions = []
132
- versions = cookbook[project]["versions"].collect{|c| fix_version_name(c["version"])} if cookbook
133
- versions
134
- rescue Net::HTTPServerException
135
- []
136
- end
137
-
138
- def self.find_gitlab_versions(project)
139
- Gitlab.tags(project.id).collect do |t|
140
- fix_version_name(t.instance_variable_get("@data")["name"])
141
- end
142
- end
143
-
144
- def self.fix_version_name(version)
145
- version.gsub(/[v][\.]*/i, "")
146
- end
147
-
148
- def self.get_latest_version(versions)
149
- versions.collect{|v| Solve::Version.new(v)}.max
150
- end
151
- end
152
- end
153
- end