knife-tidy 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ec26fb4a7cf8f9acf3f6bdc47c74086120fa64bc
4
- data.tar.gz: d33295fc06282011d316c1d5b17a1b009da99ecb
2
+ SHA256:
3
+ metadata.gz: fefc42c2e244bb50117ab8ce5fc5b8b6c5263a6211571279b9288e7f4132cc8e
4
+ data.tar.gz: b989cd57166d61a455619598b56f950449a05fdac1181f23edf20f0045dd9e2a
5
5
  SHA512:
6
- metadata.gz: 37ec3f61124ab2e314242d268496781f41f3a4272564ce5f4f33e6f29fc07c93e1ae0e5ebfefa81e32e5e9458abade0df5f15b5e0cf7fa5cc32fbe74de29764e
7
- data.tar.gz: c5dde500fa0cb884f0fa4a5cb920f6f6a0aafabc5dffbbdd05f33cddb5c9b425dcb0bbec2d1b4421428ca1e2562ab521e751506360f9167e4fe6eaadc08de6d6
6
+ metadata.gz: 4570d1e16e3b42d1c356b27464d5de59d9dccd8700c6f0c7525da06ede382c8007ec4d8c2a8be6e4da991f3c62f302021f42cad7495d4ed6c1f6436620555bed
7
+ data.tar.gz: dce7f38a43495322dfac2cb5e9f12ebe1647a931b70bb16a08210bf975866eab94e47717224ce58763df3ee9775d77228a4e862cbf81454e9970bb44458aa920
data/CHANGELOG.md CHANGED
@@ -1,220 +1,23 @@
1
1
  # Change Log
2
2
 
3
- ## [1.0.1](https://github.com/chef-customers/knife-tidy/tree/1.0.1) (2017-12-12)
4
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/1.0.0...1.0.1)
3
+ ## [1.1.0](https://github.com/chef-customers/knife-tidy/tree/1.1.0) (2018-01-11)
4
+ [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/1.1.0...1.1.0)
5
5
 
6
6
  **Closed issues:**
7
7
 
8
- - Clean up references to tidy methods [\#68](https://github.com/chef-customers/knife-tidy/issues/68)
9
- - A stale search index can generate inaccurate tidy reports [\#62](https://github.com/chef-customers/knife-tidy/issues/62)
8
+ - notifications fail for chef orgs containing an underscore [\#77](https://github.com/chef-customers/knife-tidy/issues/77)
9
+ - Add option to attach raw JSON report files to the email notification [\#75](https://github.com/chef-customers/knife-tidy/issues/75)
10
10
 
11
- **Merged pull requests:**
12
-
13
- - Fix validate\_user\_acls and default\_user\_acl methods [\#73](https://github.com/chef-customers/knife-tidy/pull/73) ([itmustbejj](https://github.com/itmustbejj))
14
-
15
- ## [1.0.0](https://github.com/chef-customers/knife-tidy/tree/1.0.0) (2017-12-04)
16
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.7.0...1.0.0)
17
-
18
- **Merged pull requests:**
19
-
20
- - Enabled cookbook deletion [\#71](https://github.com/chef-customers/knife-tidy/pull/71) ([itmustbejj](https://github.com/itmustbejj))
21
- - Add option for backup path to server clean [\#70](https://github.com/chef-customers/knife-tidy/pull/70) ([TheLunaticScripter](https://github.com/TheLunaticScripter))
22
- - Warn the user if there are nodes created in the last hour that haven'… [\#67](https://github.com/chef-customers/knife-tidy/pull/67) ([itmustbejj](https://github.com/itmustbejj))
23
- - Add guard to skip generating org reports if the search index is not u… [\#66](https://github.com/chef-customers/knife-tidy/pull/66) ([itmustbejj](https://github.com/itmustbejj))
24
- - Enable server clean command and clarify confirmation dialogue [\#31](https://github.com/chef-customers/knife-tidy/pull/31) ([jonlives](https://github.com/jonlives))
25
-
26
- ## [0.7.0](https://github.com/chef-customers/knife-tidy/tree/0.7.0) (2017-11-29)
27
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.6.1...0.7.0)
28
-
29
- **Closed issues:**
30
-
31
- - Users/clients from backups older than CS 12.5 may be missing read acls on clients [\#63](https://github.com/chef-customers/knife-tidy/issues/63)
32
- - notify subcommand ignores --orgs option [\#59](https://github.com/chef-customers/knife-tidy/issues/59)
33
-
34
- **Merged pull requests:**
35
-
36
- - release 0.7.0 [\#65](https://github.com/chef-customers/knife-tidy/pull/65) ([jeremymv2](https://github.com/jeremymv2))
37
- - Add admins/users groups to the read acl for clients from \< CS 12.5 [\#64](https://github.com/chef-customers/knife-tidy/pull/64) ([itmustbejj](https://github.com/itmustbejj))
38
- - Restore acls for ::server-admins and org read access groups if they a… [\#61](https://github.com/chef-customers/knife-tidy/pull/61) ([itmustbejj](https://github.com/itmustbejj))
39
- - Filter email notifications on org\_list config option. [\#60](https://github.com/chef-customers/knife-tidy/pull/60) ([itmustbejj](https://github.com/itmustbejj))
40
- - Set default encoding to utf-8 to properly handle non-ascii in backups. [\#58](https://github.com/chef-customers/knife-tidy/pull/58) ([itmustbejj](https://github.com/itmustbejj))
41
- - Add check for pre-12.3 nodes to report generation… [\#57](https://github.com/chef-customers/knife-tidy/pull/57) ([jonlives](https://github.com/jonlives))
42
- - bump path to 0.6.1 [\#55](https://github.com/chef-customers/knife-tidy/pull/55) ([jeremymv2](https://github.com/jeremymv2))
43
-
44
- ## [0.6.1](https://github.com/chef-customers/knife-tidy/tree/0.6.1) (2017-10-26)
45
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.6.0...0.6.1)
46
-
47
- **Closed issues:**
48
-
49
- - knife tidy server clean - org names with \_ [\#53](https://github.com/chef-customers/knife-tidy/issues/53)
50
-
51
- **Merged pull requests:**
52
-
53
- - fixing orgs with underscores [\#54](https://github.com/chef-customers/knife-tidy/pull/54) ([jeremymv2](https://github.com/jeremymv2))
54
- - Jeremymv2/release 0 6 0 [\#52](https://github.com/chef-customers/knife-tidy/pull/52) ([jeremymv2](https://github.com/jeremymv2))
55
-
56
- ## [0.6.0](https://github.com/chef-customers/knife-tidy/tree/0.6.0) (2017-10-23)
57
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.5.2...0.6.0)
58
-
59
- **Merged pull requests:**
60
-
61
- - fix travis [\#51](https://github.com/chef-customers/knife-tidy/pull/51) ([jeremymv2](https://github.com/jeremymv2))
62
- - Add knife tidy notify command [\#50](https://github.com/chef-customers/knife-tidy/pull/50) ([jonlives](https://github.com/jonlives))
63
- - bump to 0.5.2 [\#49](https://github.com/chef-customers/knife-tidy/pull/49) ([jeremymv2](https://github.com/jeremymv2))
64
-
65
- ## [0.5.2](https://github.com/chef-customers/knife-tidy/tree/0.5.2) (2017-10-20)
66
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.5.1...0.5.2)
67
-
68
- **Merged pull requests:**
69
-
70
- - fixing regex for whitespace [\#48](https://github.com/chef-customers/knife-tidy/pull/48) ([jeremymv2](https://github.com/jeremymv2))
71
- - bump patch to 0.5.1 [\#47](https://github.com/chef-customers/knife-tidy/pull/47) ([jeremymv2](https://github.com/jeremymv2))
72
-
73
- ## [0.5.1](https://github.com/chef-customers/knife-tidy/tree/0.5.1) (2017-10-19)
74
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.5.0...0.5.1)
75
-
76
- **Merged pull requests:**
77
-
78
- - Add node\_count to stale node json output. [\#46](https://github.com/chef-customers/knife-tidy/pull/46) ([MarkGibbons](https://github.com/MarkGibbons))
79
- - bump to 0.5.0 [\#45](https://github.com/chef-customers/knife-tidy/pull/45) ([jeremymv2](https://github.com/jeremymv2))
80
-
81
- ## [0.5.0](https://github.com/chef-customers/knife-tidy/tree/0.5.0) (2017-10-06)
82
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.4.1...0.5.0)
83
-
84
- **Closed issues:**
85
-
86
- - Supermarket.chef.io [\#37](https://github.com/chef-customers/knife-tidy/issues/37)
87
-
88
- **Merged pull requests:**
89
-
90
- - enabling deletion of stale nodes [\#44](https://github.com/chef-customers/knife-tidy/pull/44) ([jeremymv2](https://github.com/jeremymv2))
91
- - better warning message before confirmation [\#43](https://github.com/chef-customers/knife-tidy/pull/43) ([jeremymv2](https://github.com/jeremymv2))
92
- - Jeremymv2/chef sugar fix default [\#42](https://github.com/chef-customers/knife-tidy/pull/42) ([jeremymv2](https://github.com/jeremymv2))
93
- - deleting nodes also deletes client [\#41](https://github.com/chef-customers/knife-tidy/pull/41) ([jeremymv2](https://github.com/jeremymv2))
94
- - Change nodes\_list method to get all nodes [\#40](https://github.com/chef-customers/knife-tidy/pull/40) ([nsdavidson](https://github.com/nsdavidson))
95
- - bump version to 0.4.1 [\#39](https://github.com/chef-customers/knife-tidy/pull/39) ([jeremymv2](https://github.com/jeremymv2))
96
-
97
- ## [0.4.1](https://github.com/chef-customers/knife-tidy/tree/0.4.1) (2017-09-27)
98
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.4.0...0.4.1)
99
-
100
- **Merged pull requests:**
101
-
102
- - fixing corrupt invitations and invalid platform names with commas in … [\#38](https://github.com/chef-customers/knife-tidy/pull/38) ([jeremymv2](https://github.com/jeremymv2))
103
- - bump to 0.4.0 [\#36](https://github.com/chef-customers/knife-tidy/pull/36) ([jeremymv2](https://github.com/jeremymv2))
104
-
105
- ## [0.4.0](https://github.com/chef-customers/knife-tidy/tree/0.4.0) (2017-09-26)
106
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.3.6...0.4.0)
107
-
108
- **Merged pull requests:**
109
-
110
- - fix NilClass on env\_run\_lists [\#35](https://github.com/chef-customers/knife-tidy/pull/35) ([jeremymv2](https://github.com/jeremymv2))
111
- - fix merge conflict from rebase [\#34](https://github.com/chef-customers/knife-tidy/pull/34) ([jeremymv2](https://github.com/jeremymv2))
112
- - Simple feature to clean up EC11 org objects which don't load into CS12 [\#33](https://github.com/chef-customers/knife-tidy/pull/33) ([irvingpop](https://github.com/irvingpop))
113
- - role run\_list clean up and metadata name regex simplification [\#32](https://github.com/chef-customers/knife-tidy/pull/32) ([jeremymv2](https://github.com/jeremymv2))
114
- - bump to 0.3.6 [\#30](https://github.com/chef-customers/knife-tidy/pull/30) ([jeremymv2](https://github.com/jeremymv2))
115
-
116
- ## [0.3.6](https://github.com/chef-customers/knife-tidy/tree/0.3.6) (2017-09-25)
117
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.3.5...0.3.6)
118
-
119
- **Merged pull requests:**
120
-
121
- - first check if the\_user.has\_key?\('email'\) [\#29](https://github.com/chef-customers/knife-tidy/pull/29) ([jeremymv2](https://github.com/jeremymv2))
122
- - bump to 0.3.5 [\#28](https://github.com/chef-customers/knife-tidy/pull/28) ([jeremymv2](https://github.com/jeremymv2))
123
-
124
- ## [0.3.5](https://github.com/chef-customers/knife-tidy/tree/0.3.5) (2017-09-20)
125
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.3.4...0.3.5)
126
-
127
- **Merged pull requests:**
128
-
129
- - Catch pins with no cookbooks [\#27](https://github.com/chef-customers/knife-tidy/pull/27) ([nsdavidson](https://github.com/nsdavidson))
130
-
131
- ## [0.3.4](https://github.com/chef-customers/knife-tidy/tree/0.3.4) (2017-09-16)
132
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.3.3...0.3.4)
133
-
134
- **Merged pull requests:**
135
-
136
- - check if metadata.has\_key?\('platforms'\) [\#26](https://github.com/chef-customers/knife-tidy/pull/26) ([jeremymv2](https://github.com/jeremymv2))
137
-
138
- ## [0.3.3](https://github.com/chef-customers/knife-tidy/tree/0.3.3) (2017-09-15)
139
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.3.2...0.3.3)
140
-
141
- **Merged pull requests:**
142
-
143
- - boiler plate gsub file now works [\#25](https://github.com/chef-customers/knife-tidy/pull/25) ([jeremymv2](https://github.com/jeremymv2))
144
- - fixing null values and emtpy arrays in metadata.json [\#24](https://github.com/chef-customers/knife-tidy/pull/24) ([jeremymv2](https://github.com/jeremymv2))
145
- - Jeremyv2/action needed notification [\#23](https://github.com/chef-customers/knife-tidy/pull/23) ([jeremymv2](https://github.com/jeremymv2))
146
-
147
- ## [0.3.2](https://github.com/chef-customers/knife-tidy/tree/0.3.2) (2017-09-14)
148
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.3.1...0.3.2)
149
-
150
- **Merged pull requests:**
151
-
152
- - fixed name mismatch in metadata.json [\#22](https://github.com/chef-customers/knife-tidy/pull/22) ([jeremymv2](https://github.com/jeremymv2))
153
-
154
- ## [0.3.1](https://github.com/chef-customers/knife-tidy/tree/0.3.1) (2017-09-14)
155
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.3.0...0.3.1)
156
-
157
- **Merged pull requests:**
158
-
159
- - generate a metadata.rb if needed [\#21](https://github.com/chef-customers/knife-tidy/pull/21) ([jeremymv2](https://github.com/jeremymv2))
160
- - newline for action needed messages [\#20](https://github.com/chef-customers/knife-tidy/pull/20) ([jeremymv2](https://github.com/jeremymv2))
161
-
162
- ## [0.3.0](https://github.com/chef-customers/knife-tidy/tree/0.3.0) (2017-09-14)
163
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.2.4...0.3.0)
11
+ ## [1.1.0](https://github.com/chef-customers/knife-tidy/tree/1.1.0) (2018-01-11)
12
+ [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/1.0.1...1.1.0)
164
13
 
165
14
  **Closed issues:**
166
15
 
167
- - FATAL: Cannot find subcommand for: 'tidy backup clean' [\#12](https://github.com/chef-customers/knife-tidy/issues/12)
168
-
169
- **Merged pull requests:**
170
-
171
- - bump to 0.3.0 [\#19](https://github.com/chef-customers/knife-tidy/pull/19) ([jeremymv2](https://github.com/jeremymv2))
172
- - added dry-run to server clean [\#18](https://github.com/chef-customers/knife-tidy/pull/18) ([jeremymv2](https://github.com/jeremymv2))
173
-
174
- ## [0.2.4](https://github.com/chef-customers/knife-tidy/tree/0.2.4) (2017-09-12)
175
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.2.3...0.2.4)
176
-
177
- **Merged pull requests:**
178
-
179
- - disable server clean [\#17](https://github.com/chef-customers/knife-tidy/pull/17) ([jeremymv2](https://github.com/jeremymv2))
180
- - bump patch to 0.2.4 [\#16](https://github.com/chef-customers/knife-tidy/pull/16) ([jeremymv2](https://github.com/jeremymv2))
181
- - correct any cookbook metadata name issues [\#15](https://github.com/chef-customers/knife-tidy/pull/15) ([jeremymv2](https://github.com/jeremymv2))
182
-
183
- ## [0.2.3](https://github.com/chef-customers/knife-tidy/tree/0.2.3) (2017-09-11)
184
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.2.2...0.2.3)
185
-
186
- **Merged pull requests:**
187
-
188
- - setting required ruby to \>= 2.0.0 [\#14](https://github.com/chef-customers/knife-tidy/pull/14) ([jeremymv2](https://github.com/jeremymv2))
189
-
190
- ## [0.2.2](https://github.com/chef-customers/knife-tidy/tree/0.2.2) (2017-09-11)
191
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.2.1...0.2.2)
192
-
193
- **Merged pull requests:**
194
-
195
- - Jeremymv2/fix to i [\#13](https://github.com/chef-customers/knife-tidy/pull/13) ([jeremymv2](https://github.com/jeremymv2))
196
- - release 0.2.1 [\#11](https://github.com/chef-customers/knife-tidy/pull/11) ([jeremymv2](https://github.com/jeremymv2))
197
-
198
- ## [0.2.1](https://github.com/chef-customers/knife-tidy/tree/0.2.1) (2017-09-01)
199
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.2.0...0.2.1)
200
-
201
- **Merged pull requests:**
202
-
203
- - first round of tests [\#10](https://github.com/chef-customers/knife-tidy/pull/10) ([jeremymv2](https://github.com/jeremymv2))
204
- - Add environment checking for unused cookbook list [\#9](https://github.com/chef-customers/knife-tidy/pull/9) ([nsdavidson](https://github.com/nsdavidson))
205
- - disable [\#8](https://github.com/chef-customers/knife-tidy/pull/8) ([jeremymv2](https://github.com/jeremymv2))
206
- - server object deletion [\#7](https://github.com/chef-customers/knife-tidy/pull/7) ([jeremymv2](https://github.com/jeremymv2))
207
- - bump version to 0.2.0 [\#6](https://github.com/chef-customers/knife-tidy/pull/6) ([jeremymv2](https://github.com/jeremymv2))
208
-
209
- ## [0.2.0](https://github.com/chef-customers/knife-tidy/tree/0.2.0) (2017-08-16)
210
- [Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.1.1...0.2.0)
16
+ - the backup-path should default to current working directory [\#79](https://github.com/chef-customers/knife-tidy/issues/79)
211
17
 
212
18
  **Merged pull requests:**
213
19
 
214
- - moved all common functions to tidy\_common.rb [\#5](https://github.com/chef-customers/knife-tidy/pull/5) ([jeremymv2](https://github.com/jeremymv2))
215
- - Jeremymv2/acl items [\#4](https://github.com/chef-customers/knife-tidy/pull/4) ([jeremymv2](https://github.com/jeremymv2))
216
- - updated changelog [\#3](https://github.com/chef-customers/knife-tidy/pull/3) ([jeremymv2](https://github.com/jeremymv2))
217
- - bump version to 0.1.1 [\#2](https://github.com/chef-customers/knife-tidy/pull/2) ([jeremymv2](https://github.com/jeremymv2))
20
+ - Jjh/fix notification reports [\#80](https://github.com/chef-customers/knife-tidy/pull/80) ([itmustbejj](https://github.com/itmustbejj))
218
21
 
219
22
 
220
23
 
data/Rakefile CHANGED
@@ -48,8 +48,8 @@ namespace :changelog do
48
48
  require 'github_changelog_generator/task'
49
49
 
50
50
  GitHubChangelogGenerator::RakeTask.new :changelog do |config|
51
- config.since_tag = '0.1.1'
52
- config.future_release = '0.1.0'
51
+ config.since_tag = '1.0.1'
52
+ config.future_release = '1.1.0'
53
53
  end
54
54
  end
55
55
  end
@@ -3,7 +3,6 @@ require 'chef/knife/tidy_base'
3
3
  class Chef
4
4
  class Knife
5
5
  class TidyBackupClean < Knife
6
-
7
6
  deps do
8
7
  require 'chef/cookbook_loader'
9
8
  require 'chef/cookbook/metadata'
@@ -16,21 +15,21 @@ class Chef
16
15
  require 'securerandom'
17
16
  end
18
17
 
19
- banner "knife tidy backup clean (options)"
18
+ banner 'knife tidy backup clean (options)'
20
19
 
21
20
  include Knife::TidyBase
22
21
 
23
22
  option :backup_path,
24
- :long => '--backup-path path/to/backup',
25
- :description => 'The path to the knife-ec-backup backup directory'
23
+ long: '--backup-path path/to/backup',
24
+ description: 'The path to the knife-ec-backup backup directory'
26
25
 
27
26
  option :gsub_file,
28
- :long => '--gsub-file path/to/gsub/file',
29
- :description => 'The path to the file used for substitutions. If non-existant, a boiler plate one will be created.'
27
+ long: '--gsub-file path/to/gsub/file',
28
+ description: 'The path to the file used for substitutions. If non-existant, a boiler plate one will be created.'
30
29
 
31
30
  option :gen_gsub,
32
- :long => '--gen-gsub',
33
- :description => 'Generate a new boiler plate global substitutions file: \'substitutions.json\'.'
31
+ long: '--gen-gsub',
32
+ description: 'Generate a new boiler plate global substitutions file: \'substitutions.json\'.'
34
33
 
35
34
  def run
36
35
  FileUtils.rm_f(action_needed_file_path)
@@ -76,7 +75,7 @@ class Chef
76
75
  email = ''
77
76
  ui.stdout.puts "INFO: Validating #{user}"
78
77
  the_user = FFI_Yajl::Parser.parse(::File.read(::File.join(tidy.users_path, "#{user}.json")), symbolize_names: false)
79
- if the_user.has_key?('email') && the_user['email'].match(/\A[^@\s]+@[^@\s]+\z/)
78
+ if the_user.key?('email') && the_user['email'].match(/\A[^@\s]+@[^@\s]+\z/)
80
79
  if emails_seen.include?(the_user['email'])
81
80
  ui.stdout.puts "REPAIRING: Already saw #{user}'s email, creating a unique one."
82
81
  email = tidy.unique_email
@@ -105,12 +104,12 @@ class Chef
105
104
  ui.stdout.puts "INFO: Validating org object for #{org}"
106
105
  org_object = load_org_object(org)
107
106
 
108
- unless org_object.keys.count == 3 # cheapo, maybe expect the exact names?
107
+ unless org_object.keys.count == 3 # cheapo, maybe expect the exact names?
109
108
  ui.stdout.puts "REPAIRING: org object for #{org} contains extra/missing fields. Fixing that for you"
110
109
  # quick/dirty attempt at fixing any of the required fields in case they're nil
111
110
  good_name = org_object['name'] || org
112
111
  good_full_name = org_object['full_name'] || org
113
- good_guid = org_object['guid'] || SecureRandom.uuid.gsub('-','')
112
+ good_guid = org_object['guid'] || SecureRandom.uuid.delete('-')
114
113
  fixed_org_object = { name: good_name, full_name: good_full_name, guid: good_guid }
115
114
 
116
115
  write_org_object(org, fixed_org_object)
@@ -121,11 +120,11 @@ class Chef
121
120
  JSON.parse(File.read(File.join(tidy.org_path(org), 'org.json')))
122
121
  rescue Errno::ENOENT, JSON::ParserError
123
122
  ui.stdout.puts "REPAIRING: org object for organization #{org} is missing or corrupt. Generating a new one"
124
- return { name: org, full_name: org, guid: SecureRandom.uuid.gsub('-','') }
123
+ return { name: org, full_name: org, guid: SecureRandom.uuid.delete('-') }
125
124
  end
126
125
 
127
126
  def write_org_object(org, org_object)
128
- File.write(File.join(tidy.org_path(org), 'org.json') , JSON.pretty_generate(org_object))
127
+ File.write(File.join(tidy.org_path(org), 'org.json'), JSON.pretty_generate(org_object))
129
128
  end
130
129
 
131
130
  def add_cookbook_name_to_metadata(cookbook_name, rb_path)
@@ -179,7 +178,7 @@ class Chef
179
178
  broken_path = ::File.join(tidy.org_path(org), 'cookbooks.broken')
180
179
  FileUtils.mkdir(broken_path) unless ::File.directory?(broken_path)
181
180
  Dir[::File.join(tidy.cookbooks_path(org), "#{cookbook}*")].each do |cb|
182
- FileUtils.mv(cb, broken_path, :verbose => true, :force => true)
181
+ FileUtils.mv(cb, broken_path, verbose: true, force: true)
183
182
  end
184
183
  end
185
184
 
@@ -198,12 +197,12 @@ class Chef
198
197
  patterns = [
199
198
  {
200
199
  search: '^require .*/lib/chef/sugar/version',
201
- replace: "# require File.expand_path('../lib/chef/sugar/version', *__FILE__)"
200
+ replace: "# require File.expand_path('../lib/chef/sugar/version', *__FILE__)",
202
201
  },
203
202
  {
204
203
  search: '^version *Chef::Sugar::VERSION',
205
- replace: "version '#{version}'"
206
- }
204
+ replace: "version '#{version}'",
205
+ },
207
206
  ]
208
207
  patterns.each do |p|
209
208
  s.sub_in_file(file, Regexp.new(p[:search]), p[:replace])
@@ -236,11 +235,11 @@ class Chef
236
235
  md[key] = 'default value'
237
236
  end
238
237
  end
239
- if metadata.has_key?('platforms')
238
+ if metadata.key?('platforms')
240
239
  metadata['platforms'].each_pair do |key, value|
241
240
  # platform key cannot contain comma delimited values
242
241
  md['platforms'].delete(key) if key =~ /,/
243
- if value.kind_of?(Array) && value.empty?
242
+ if value.is_a?(Array) && value.empty?
244
243
  ui.stdout.puts "REPAIRING: Fixing empty platform key for for key #{key} in #{json_path}"
245
244
  md['platforms'][key] = '>= 0.0.0'
246
245
  end
@@ -280,7 +279,7 @@ class Chef
280
279
  def create_minimal_metadata(cookbook_path)
281
280
  name = tidy.cookbook_name_from_path(cookbook_path)
282
281
  components = cookbook_path.split(File::SEPARATOR)
283
- name_version = components[components.index('cookbooks')+1]
282
+ name_version = components[components.index('cookbooks') + 1]
284
283
  version = name_version.match(/\d+\.\d+\.\d+/).to_s
285
284
  metadata = {}
286
285
  metadata['name'] = name
@@ -352,7 +351,6 @@ class Chef
352
351
  end
353
352
 
354
353
  def repair_role_run_lists(role_path)
355
- # rubocop:disable MethodLength
356
354
  the_role = FFI_Yajl::Parser.parse(::File.read(role_path), symbolize_names: false)
357
355
  new_role = the_role.clone
358
356
  rl = Chef::RunList.new
@@ -365,7 +363,7 @@ class Chef
365
363
  ui.stdout.puts "REPAIRING: Invalid Recipe Item: #{item} in run_list from #{role_path}"
366
364
  end
367
365
  end
368
- if the_role.has_key?('env_run_lists')
366
+ if the_role.key?('env_run_lists')
369
367
  the_role['env_run_lists'].each_pair do |key, value|
370
368
  new_role['env_run_lists'][key] = []
371
369
  value.each do |item|
@@ -21,24 +21,22 @@ require 'chef/server_api'
21
21
  class Chef
22
22
  class Knife
23
23
  module TidyBase
24
-
25
24
  def self.included(includer)
26
25
  includer.class_eval do
27
-
28
26
  deps do
29
27
  require 'chef/tidy_server'
30
28
  require 'chef/tidy_common'
31
29
  end
32
30
 
33
31
  option :org_list,
34
- :long => "--orgs ORG1,ORG2",
35
- :description => "Only apply to objects in the named organizations"
36
- end
32
+ long: '--orgs ORG1,ORG2',
33
+ description: 'Only apply to objects in the named organizations'
34
+ end
37
35
  end
38
36
 
39
37
  def server
40
38
  @server ||= if Chef::Config.chef_server_root.nil?
41
- ui.warn("chef_server_root not found in knife configuration; using chef_server_url")
39
+ ui.warn('chef_server_root not found in knife configuration; using chef_server_url')
42
40
  Chef::TidyServer.from_chef_server_url(Chef::Config.chef_server_url)
43
41
  else
44
42
  Chef::TidyServer.new(Chef::Config.chef_server_root)
@@ -58,7 +56,7 @@ class Chef
58
56
  end
59
57
 
60
58
  def completion_message
61
- ui.stdout.puts "#{ui.color("** Finished **", :magenta)}"
59
+ ui.stdout.puts ui.color('** Finished **', :magenta).to_s
62
60
  end
63
61
 
64
62
  def action_needed_file_path
@@ -69,7 +67,7 @@ class Chef
69
67
  ::File.expand_path('reports/knife-tidy-server-warnings.txt')
70
68
  end
71
69
 
72
- def action_needed(msg, file_path=action_needed_file_path)
70
+ def action_needed(msg, file_path = action_needed_file_path)
73
71
  ::File.open(file_path, 'a') do |f|
74
72
  f.write(msg + "\n")
75
73
  end
@@ -3,68 +3,68 @@ require 'chef/knife/tidy_base'
3
3
  class Chef
4
4
  class Knife
5
5
  class TidyNotify < Knife
6
-
7
6
  deps do
8
7
  require 'ffi_yajl'
9
8
  require 'net/smtp'
10
9
  end
11
10
 
12
- banner "knife tidy notify (options)"
11
+ banner 'knife tidy notify (options)'
13
12
 
14
13
  option :smtp_server,
15
- :short => '-s SERVER_NAME',
16
- :long => '--smtp_server SERVER_NAME',
17
- :default => 'localhost',
18
- :description => 'SMTP Server to be used for emailling reports to organisation admins (defaults to localhost)'
14
+ short: '-s SERVER_NAME',
15
+ long: '--smtp_server SERVER_NAME',
16
+ default: 'localhost',
17
+ description: 'SMTP Server to be used for emailling reports to organization admins (defaults to localhost)'
19
18
 
20
19
  option :smtp_port,
21
- :short => '-p SMTP_PORT',
22
- :long => '--smtp_port SMTP_PORT',
23
- :default => 25,
24
- :description => 'SMTP port to be used for emailling reports to organisation admins (defaults to 25)'
20
+ short: '-p SMTP_PORT',
21
+ long: '--smtp_port SMTP_PORT',
22
+ default: 25,
23
+ description: 'SMTP port to be used for emailling reports to organization admins (defaults to 25)'
25
24
 
26
25
  option :smtp_helo,
27
- :short => '-h SMTP_HELO',
28
- :long => '--smtp_helo SMTP_HELO',
29
- :default => 'localhost',
30
- :description => 'SMTP HELO to be used for emailling reports to organisation admins (defaults to localhost)'
26
+ short: '-h SMTP_HELO',
27
+ long: '--smtp_helo SMTP_HELO',
28
+ default: 'localhost',
29
+ description: 'SMTP HELO to be used for emailling reports to organization admins (defaults to localhost)'
31
30
 
32
31
  option :smtp_username,
33
- :short => '-u SMTP_USERNAME',
34
- :long => '--smtp_username SMTP_USERNAME',
35
- :description => 'SMTP Username to be used for emailling reports to organisation admins'
32
+ short: '-u SMTP_USERNAME',
33
+ long: '--smtp_username SMTP_USERNAME',
34
+ description: 'SMTP Username to be used for emailling reports to organization admins'
36
35
 
37
36
  option :smtp_password,
38
- :long => '--smtp_password SMTP_PASSWORD',
39
- :description => 'SMTP Password to be used for emailling reports to organisation admins'
37
+ long: '--smtp_password SMTP_PASSWORD',
38
+ description: 'SMTP Password to be used for emailling reports to organization admins'
40
39
 
41
40
  option :smtp_from,
42
- :long => '--smtp_from SMTP_FROM',
43
- :description => 'SMTP From address to be used for emailling reports to organisation admins'
41
+ long: '--smtp_from SMTP_FROM',
42
+ description: 'SMTP From address to be used for emailling reports to organization admins'
44
43
 
45
44
  option :smtp_use_tls,
46
- :long => '--smtp_use_tls',
47
- :short => '-t',
48
- :default => false,
49
- :boolean => true | false,
50
- :description => 'Whether TLS should be used for emailling reports to organisation admins (defaults to false if omitted)'
51
-
45
+ long: '--smtp_use_tls',
46
+ short: '-t',
47
+ default: false,
48
+ boolean: true | false,
49
+ description: 'Whether TLS should be used for emailling reports to organization admins (defaults to false if omitted)'
52
50
 
53
51
  include Knife::TidyBase
54
52
 
55
53
  def run
56
-
57
54
  reports_dir = tidy.reports_dir
58
-
59
- reports_files = Dir["#{reports_dir}/*"]
60
-
55
+ report_file_suffixes = ['_unused_cookbooks.json', '_cookbook_count.json', '_stale_nodes.json']
56
+ # Only grab the files matching the report_file_suffixes
57
+ report_files = Dir["#{reports_dir}/*{#{report_file_suffixes.join(',')}}"]
61
58
 
62
59
  ui.info "Reading from #{tidy.reports_dir} directory"
63
60
 
64
- report_file_suffixes = ["_unused_cookbooks.json", "_cookbook_count.json", "_stale_nodes.json"]
65
-
66
- # Fetch list of organisation names from reports directory
67
- org_names = reports_files.map{|r_file|r_file.split("/").last.split("_").first}.sort.uniq
61
+ # Fetch list of organization names from reports directory
62
+ begin
63
+ org_names = report_files.map { |r_file| r_file.match("#{reports_dir}\/(.*)(#{report_file_suffixes.join('|')})").captures.first }.uniq
64
+ rescue NoMethodError
65
+ ui.stderr.puts 'Failed to parse json reports files. Please ensure your reports are valid.'
66
+ return
67
+ end
68
68
  if config[:org_list]
69
69
  filter_orgs = config[:org_list].split(',')
70
70
  # Take the intersection of org_names and filter_orgs
@@ -73,102 +73,139 @@ class Chef
73
73
 
74
74
  reports = {}
75
75
 
76
- # Iterate through list of collected organisations and parse any report files into JSON objects
76
+ # Iterate through list of collected organizations and parse any report files into JSON objects
77
+
78
+ unless org_names
79
+ ui.std.puts 'No valid org reports found to send notifications. Exiting.'
80
+ return
81
+ end
77
82
 
78
83
  org_names.each do |org|
79
- ui.info("Fetching report data for organisation #{org}")
84
+ ui.info("Fetching report data for organization #{org}")
80
85
  reports[org] = {}
81
86
  report_file_suffixes.each do |report|
82
87
  begin
83
88
  file_name = "#{reports_dir}/#{org}#{report}"
84
89
  ui.info(" Parsing file #{file_name}")
85
90
  json_string = File.read(file_name)
86
- reports[org][report] = FFI_Yajl::Parser.parse( json_string)
91
+ reports[org][report] = FFI_Yajl::Parser.parse(json_string)
87
92
  rescue Errno::ENOENT
88
- ui.info(" Skipping file #{file_name} - not found for organisation #{org}")
93
+ ui.info(" Skipping file #{file_name} - not found for organization #{org}")
89
94
  reports[org][report] = {}
90
95
  end
91
96
  end
92
97
 
93
- # Fetch a list of admin users for the current organisation
94
- ui.info("Fetching admins users for organisation #{org}")
98
+ # Fetch a list of admin users for the current organization
99
+ ui.info("Fetching admins users for organization #{org}")
95
100
  begin
96
101
  admins = org_admins(org)
97
- reports[org]['admins'] = admins.map{|name,data| org_user(org,name) unless name == "pivotal"}
102
+ reports[org]['admins'] = admins.map { |name, _data| org_user(org, name) unless name == 'pivotal' }
98
103
  rescue Net::HTTPServerException
99
- ui.info(" Cannot fetch admin users for organisation #{org} as it does not exist on the server")
104
+ ui.info(" Cannot fetch admin users for organization #{org} as it does not exist on the server")
100
105
  end
101
106
 
102
107
  # Build list of email recipients from the collected admin users (display name and email address of each)
103
- email_recipients = reports[org]['admins'].map{|admin|{name: admin['display_name'], email: admin['email']} unless admin.nil?}.compact
108
+ email_recipients = reports[org]['admins'].map { |admin| { name: admin['display_name'], email: admin['email'] } unless admin.nil? }.compact
104
109
 
105
- # Send a report email to all admin users of the organisation
106
- ui.info "Sending email reports for organisation #{org}"
107
- email_content = generate_email(reports,org, email_recipients)
108
- send_email(email_content,email_recipients)
110
+ # Send a report email to all admin users of the organization
111
+ ui.info "Sending email reports for organization #{org}"
112
+ email_content = generate_email(reports, org, email_recipients, report_file_suffixes)
113
+ send_email(email_content, email_recipients)
109
114
  end
110
-
111
-
112
-
113
115
  end
114
116
 
115
117
  private
116
118
 
117
- def generate_email(report_data,organisation, recipients)
119
+ def generate_email(report_data, organization, recipients, report_file_suffixes)
120
+ mime_boundary = "==Multipart_Boundary_x#{srand}x"
118
121
  message = <<MESSAGE_END
119
122
  From: Knife Tidy <#{config[:smtp_from]}>
120
- To: #{recipients.map{|recipient|"#{recipient[:name]} <#{recipient[:email]}>"}.join(", ")}
123
+ To: #{recipients.map { |recipient| "#{recipient[:name]} <#{recipient[:email]}>" }.join(', ')}
124
+ MIME-Version: 1.0
125
+ Subject: Knife Tidy Cleanup Report for Organization "#{organization}"
126
+ Content-Type: multipart/mixed; boundary="#{mime_boundary}";
127
+ --#{mime_boundary}
121
128
  Content-type: text/html
122
- Subject: Knife Tidy Cleanup Report for Organisation "#{organisation}"
129
+ Content-Transfer-Encoding: 7bit
130
+
131
+ The following reports were generated by <a href="https://github.com/chef-customers/knife-tidy">knife-tidy</a>, and contain a list of unused cookbooks and stale nodes for the Chef server organization "#{organization}"
132
+ #{generate_total_cookbooks_table(report_data, organization)}
133
+ #{generate_unused_cookbooks_table(report_data, organization)}
134
+ #{generate_node_table(report_data, organization)}
135
+ MESSAGE_END
136
+
137
+ report_file_suffixes.each do |suffix|
138
+ message += <<MESSAGE_END
139
+ --#{mime_boundary}
140
+ Content-Transfer-Encoding:7bit
141
+ Content-Type: plain/text;name="#{organization}#{suffix}";charset="UTF-8"
142
+ Content-Disposition: attachment;filename="#{organization}#{suffix}"
143
+
144
+ #{report_data[organization][suffix].to_json}
123
145
 
124
- The following report was generated by <a href="https://github.com/chef-customers/knife-tidy">knife-tidy</a>, and contains a list of unused cookbooks and stale nodes for the Chef server organisation "#{organisation}"
125
- #{generate_cookbook_table(report_data,organisation)}
126
- <br>
127
- #{generate_node_table(report_data,organisation)}
128
146
  MESSAGE_END
147
+ end
129
148
 
149
+ message += <<MESSAGE_END
150
+ --#{mime_boundary}--
151
+ MESSAGE_END
152
+ puts message
130
153
  message
131
154
  end
132
155
 
133
- def generate_cookbook_table(report_data, organisation)
156
+ def generate_total_cookbooks_table(report_data, organization)
157
+ table_start = "<h2>Total Versions by Cookbook</h2><p>This table contains the count of versions of each cookbook stored on the Chef Server.<p><table border='1' cellpadding='1' cellspacing='0'>"
158
+ table_end = '</table><br/>'
159
+ header_string = '<tr><th>Cookbook Name</th><th>Total Version Count</th></tr>'
160
+ table_body = if report_data[organization]['_cookbook_count.json'].empty?
161
+ "<tr><td colspan='2'>No cookbook versions</td></tr>"
162
+ else
163
+ report_data[organization]['_cookbook_count.json'].map { |cookbook_name, cookbook_count| "<tr><td>#{cookbook_name}</td><td>#{cookbook_count}</td></tr>" }.join("\n")
164
+ end
165
+ table_start + header_string + table_body + table_end
166
+ end
134
167
 
135
- table_start = "<h2>Unused Cookbooks</h2><p>This table contains cookbook names and versions that are not currently in the runlists of any nodes.<p><table border='1' cellpadding='1' cellspacing='0'>"
136
- table_end = "</table>"
137
- if !report_data[organisation]['_unused_cookbooks.json'].empty?
138
- header_string = "<tr><th>Cookbook Name</th><th>Unused Versions</th></tr>"
139
- table_body = report_data[organisation]['_unused_cookbooks.json'].map{|cookbook_name,cookbook_versions|"<tr><td>#{cookbook_name}</td><td>#{cookbook_versions.join("<br>")}</td></tr>"}.join("\n")
140
- else
141
- header_string = "<tr><th>Cookbook Name</th><th>Unused Version Count</th></tr>"
142
- table_body = report_data[organisation]['_cookbook_count.json'].map{|cookbook_name,cookbook_count|"<tr><td>#{cookbook_name}</td><td>#{cookbook_count}</td></tr>"}.join("\n")
143
- end
168
+ def generate_unused_cookbooks_table(report_data, organization)
169
+ table_start = "<h2>Unused Cookbooks</h2><p>This table contains cookbook names and the count of their versions that are not currently in the runlists of any nodes.<p><table border='1' cellpadding='1' cellspacing='0'>"
170
+ table_end = '</table><br/>'
171
+ header_string = '<tr><th>Cookbook Name</th><th>Unused Versions</th></tr>'
172
+ table_body = if report_data[organization]['_unused_cookbooks.json'].empty?
173
+ "<tr><td colspan='2'>No unused cookbook versions</td></tr>"
174
+ else
175
+ report_data[organization]['_unused_cookbooks.json'].map { |cookbook_name, cookbook_versions| "<tr><td>#{cookbook_name}</td><td>#{cookbook_versions.join('<br>')}</td></tr>" }.join("\n")
176
+ end
144
177
  table_start + header_string + table_body + table_end
145
178
  end
146
179
 
147
- def generate_node_table(report_data,organisation)
148
- table_start = "<h2>Stale Nodes</h2><p>This table contains nodes that have not checked in to the Chef Server in #{report_data[organisation]['_stale_nodes.json']['threshold_days']} days.<p><table border='1' cellpadding='1' cellspacing='0'>"
149
- table_end = "</table>"
150
- header_string = "<tr><th>Node Name</th></tr>"
151
- table_body = report_data[organisation]['_stale_nodes.json']['list'].map{|node_name|"<tr><td>#{node_name}</td></tr>"}.join("\n")
180
+ def generate_node_table(report_data, organization)
181
+ table_start = "<h2>Stale Nodes</h2><p>This table contains nodes that have not checked in to the Chef Server in #{report_data[organization]['_stale_nodes.json']['threshold_days']} days.<p><table border='1' cellpadding='1' cellspacing='0'>"
182
+ table_end = '</table>'
183
+ header_string = '<tr><th>Node Name</th></tr>'
184
+ table_body = if report_data[organization]['_stale_nodes.json'].empty? || report_data[organization]['_stale_nodes.json']['count'] == 0
185
+ "<tr><td colspan='2'>No stale nodes</td></tr>"
186
+ else
187
+ report_data[organization]['_stale_nodes.json']['list'].map { |node_name| "<tr><td>#{node_name}</td></tr>" }.join("\n")
188
+ end
152
189
  table_start + header_string + table_body + table_end
153
190
  end
154
191
 
155
- def send_email(mail_content,recipients)
156
- smtp = Net::SMTP.new(config[:smtp_server],config[:smtp_port])
192
+ def send_email(mail_content, recipients)
193
+ smtp = Net::SMTP.new(config[:smtp_server], config[:smtp_port])
157
194
  smtp.enable_starttls if config[:smtp_use_tls]
158
- smtp.start(config[:smtp_helo],config[:smtp_username],config[:smtp_password],:login) do |server|
159
- server.send_message(mail_content, config[:smtp_from], recipients.map{|recipient|recipient[:email]})
195
+ smtp.start(config[:smtp_helo], config[:smtp_username], config[:smtp_password], :login) do |server|
196
+ server.send_message(mail_content, config[:smtp_from], recipients.map { |recipient| recipient[:email] })
160
197
  end
161
198
  end
162
199
 
163
200
  def org_admins(org)
164
201
  admins = {}
165
- rest.get("/organizations/#{org}/groups/admins")["users"].each do |name|
202
+ rest.get("/organizations/#{org}/groups/admins")['users'].each do |name|
166
203
  admins[name] = {}
167
204
  end
168
205
  admins
169
206
  end
170
207
 
171
- def org_user(org,username)
208
+ def org_user(org, username)
172
209
  rest.get("/organizations/#{org}/users/#{username}")
173
210
  end
174
211
  end
@@ -10,28 +10,28 @@ class Chef
10
10
  require 'chef/util/threaded_job_queue'
11
11
  end
12
12
 
13
- banner "knife tidy server clean (options)"
13
+ banner 'knife tidy server clean (options)'
14
14
 
15
15
  option :backup_path,
16
- :long => '--backup-path path/to/backup',
17
- :description => 'The path to the knife-ec-backup backup directory'
16
+ long: '--backup-path path/to/backup',
17
+ description: 'The path to the knife-ec-backup backup directory'
18
18
 
19
19
  option :concurrency,
20
- :long => '--concurrency THREADS',
21
- :default => 1,
22
- :description => 'Maximum number of simultaneous requests to send (default: 1)'
20
+ long: '--concurrency THREADS',
21
+ default: 1,
22
+ description: 'Maximum number of simultaneous requests to send (default: 1)'
23
23
 
24
24
  option :only_cookbooks,
25
- :long => '--only-cookbooks',
26
- :description => 'Only delete unused cookbooks from Chef Server.'
25
+ long: '--only-cookbooks',
26
+ description: 'Only delete unused cookbooks from Chef Server.'
27
27
 
28
28
  option :only_nodes,
29
- :long => '--only-nodes',
30
- :description => 'Only delete stale nodes (and associated clients and ACLs) from Chef Server.'
29
+ long: '--only-nodes',
30
+ description: 'Only delete stale nodes (and associated clients and ACLs) from Chef Server.'
31
31
 
32
32
  option :dry_run,
33
- :long => '--dry-run',
34
- :description => 'Do not perform any actual deletion, only report on what would have been deleted.'
33
+ long: '--dry-run',
34
+ description: 'Do not perform any actual deletion, only report on what would have been deleted.'
35
35
 
36
36
  def run
37
37
  STDOUT.sync = true
@@ -56,11 +56,11 @@ class Chef
56
56
  end
57
57
 
58
58
  deletions = if config[:only_cookbooks]
59
- "cookbooks"
59
+ 'cookbooks'
60
60
  elsif config[:only_nodes]
61
- "nodes (and associated clients and ACLs)"
61
+ 'nodes (and associated clients and ACLs)'
62
62
  else
63
- "cookbooks and nodes (and associated clients and ACLs)"
63
+ 'cookbooks and nodes (and associated clients and ACLs)'
64
64
  end
65
65
 
66
66
  orgs = if config[:org_list]
@@ -94,7 +94,7 @@ class Chef
94
94
  unused_cookbooks.keys.each do |cookbook|
95
95
  versions = unused_cookbooks[cookbook]
96
96
  versions.each do |version|
97
- queue << lambda { delete_cookbook_job(org, cookbook, version) }
97
+ queue << -> { delete_cookbook_job(org, cookbook, version) }
98
98
  end
99
99
  end
100
100
  queue.process(config[:concurrency].to_i)
@@ -118,7 +118,7 @@ class Chef
118
118
  ui.stdout.puts "INFO: Cleaning stale nodes for Org: #{org}, using #{stale_nodes_file}"
119
119
  stale_nodes = FFI_Yajl::Parser.parse(::File.read(stale_nodes_file), symbolize_names: true)
120
120
  stale_nodes[:list].each do |node|
121
- queue << lambda { delete_node_job(org, node) }
121
+ queue << -> { delete_node_job(org, node) }
122
122
  end
123
123
  queue.process(config[:concurrency].to_i)
124
124
  end
@@ -68,8 +68,8 @@ class Chef
68
68
  nodes.select{|node| !node['cookbooks'].nil?}.each do |node|
69
69
  node['cookbooks'].each do |name, version_hash|
70
70
  version = Gem::Version.new(version_hash['version']).to_s
71
- if used_cookbooks[name] && !used_cookbooks[name].include?(version)
72
- used_cookbooks[name].push(version)
71
+ if used_cookbooks[name]
72
+ used_cookbooks[name].push(version) unless used_cookbooks[name].include?(version)
73
73
  else
74
74
  used_cookbooks[name] = [version]
75
75
  end
@@ -168,7 +168,8 @@ class Chef
168
168
  if used_list[name].nil? # Not in the used list at all (Remove all versions)
169
169
  unused_list[name] = versions
170
170
  elsif used_list[name].sort != versions # Is in the used cookbook list, but version arrays do not match (Find unused versions)
171
- unused_list[name] = versions - used_list[name] - [versions.last] # Don't delete the most recent version as it might not be in a run_list yet.
171
+ unused = versions - used_list[name] - [versions.last] # Don't delete the most recent version as it might not be in a run_list yet.
172
+ unused_list[name] = unused unless unused.empty?
172
173
  end
173
174
  end
174
175
  unused_list
@@ -18,7 +18,7 @@ class Chef
18
18
  end
19
19
 
20
20
  def load_users
21
- @tidy.ui.stdout.puts "INFO: Loading users"
21
+ @tidy.ui.stdout.puts 'INFO: Loading users'
22
22
  Dir[::File.join(@tidy.users_path, '*.json')].each do |user|
23
23
  @users.push(FFI_Yajl::Parser.parse(::File.read(user), symbolize_names: true))
24
24
  end
@@ -70,15 +70,15 @@ class Chef
70
70
  end
71
71
 
72
72
  def valid_org_member?(actor)
73
- ! @members.select { |user| user[:user][:username] == actor }.empty?
73
+ !@members.select { |user| user[:user][:username] == actor }.empty?
74
74
  end
75
75
 
76
76
  def valid_org_client?(actor)
77
- ! @clients.select { |client| client[:name] == actor }.empty?
77
+ !@clients.select { |client| client[:name] == actor }.empty?
78
78
  end
79
79
 
80
80
  def valid_global_user?(actor)
81
- ! @users.select { |user| user[:username] == actor }.empty?
81
+ !@users.select { |user| user[:username] == actor }.empty?
82
82
  end
83
83
 
84
84
  def invalid_group?(actor)
@@ -101,7 +101,7 @@ class Chef
101
101
 
102
102
  def org_acls
103
103
  @org_acls ||= Dir[::File.join(@tidy.org_acls_path(@org), '**.json')] +
104
- Dir[::File.join(@tidy.org_acls_path(@org), '**', '*.json')]
104
+ Dir[::File.join(@tidy.org_acls_path(@org), '**', '*.json')]
105
105
  end
106
106
 
107
107
  def fix_ambiguous_actor(actor)
@@ -153,7 +153,7 @@ class Chef
153
153
 
154
154
  def ensure_client_read_acls(acl_file)
155
155
  acl = FFI_Yajl::Parser.parse(::File.read(acl_file), symbolize_names: false)
156
- %w(users admins).each do | group |
156
+ %w(users admins).each do |group|
157
157
  unless acl['read']['groups'].include? group
158
158
  @tidy.ui.stdout.puts "REPAIRING: Adding read acl for #{group} in #{acl_file}"
159
159
  acl['read']['groups'].push(group)
@@ -177,27 +177,25 @@ class Chef
177
177
  end
178
178
  end
179
179
  actors_groups[:groups].each do |group|
180
- if invalid_group?(group)
181
- remove_group_from_acl(group, acl_file)
182
- end
180
+ remove_group_from_acl(group, acl_file) if invalid_group?(group)
183
181
  end
184
182
  end
185
183
  end
186
184
 
187
185
  def default_user_acl(client)
188
- return {:create=>{:actors=>["pivotal", client], :groups=>["::server-admins"]},
189
- :read=>{:actors=>["pivotal", client], :groups=>["::server-admins", "::#{@org}_read_access_group"]},
190
- :update=>{:actors=>["pivotal", client], :groups=>["::server-admins"]},
191
- :delete=>{:actors=>["pivotal", client], :groups=>["::server-admins"]},
192
- :grant=>{:actors=>["pivotal", client], :groups=>["::server-admins"]}}
186
+ { create: { actors: ['pivotal', client], groups: ['::server-admins'] },
187
+ read: { actors: ['pivotal', client], groups: ['::server-admins', "::#{@org}_read_access_group"] },
188
+ update: { actors: ['pivotal', client], groups: ['::server-admins'] },
189
+ delete: { actors: ['pivotal', client], groups: ['::server-admins'] },
190
+ grant: { actors: ['pivotal', client], groups: ['::server-admins'] } }
193
191
  end
194
192
 
195
193
  def default_client_acl(client_name)
196
- return {:create=>{:actors=>["pivotal", "#{@org}-validator", client_name], :groups=>["admins"]},
197
- :read=>{:actors=>["pivotal", "#{@org}-validator", client_name], :groups=>["admins", "users"]},
198
- :update=>{:actors=>["pivotal", client_name], :groups=>["admins"]},
199
- :delete=>{:actors=>["pivotal", client_name], :groups=>["admins", "users"]},
200
- :grant=>{:actors=>["pivotal", client_name], :groups=>["admins"]}}
194
+ { create: { actors: ['pivotal', "#{@org}-validator", client_name], groups: ['admins'] },
195
+ read: { actors: ['pivotal', "#{@org}-validator", client_name], groups: %w(admins users) },
196
+ update: { actors: ['pivotal', client_name], groups: ['admins'] },
197
+ delete: { actors: ['pivotal', client_name], groups: %w(admins users) },
198
+ grant: { actors: ['pivotal', client_name], groups: ['admins'] } }
201
199
  end
202
200
 
203
201
  def validate_user_acls
@@ -207,15 +205,13 @@ class Chef
207
205
  user_acl = FFI_Yajl::Parser.parse(::File.read(user_acl_path), symbolize_names: false)
208
206
  rescue Errno::ENOENT
209
207
  @tidy.ui.stdout.puts "REPAIRING: Replacing missing user acl for #{member[:user][:username]}."
210
- @tidy.write_new_file(default_user_acl(member), user_acl_path, backup=false)
208
+ @tidy.write_new_file(default_user_acl(member), user_acl_path, backup = false)
211
209
  user_acl = FFI_Yajl::Parser.parse(::File.read(user_acl_path), symbolize_names: false)
212
210
  end
213
211
  ensure_global_group_acls(user_acl_path)
214
212
  actors_groups = acl_actors_groups(user_acl)
215
213
  actors_groups[:groups].each do |group|
216
- if invalid_group?(group)
217
- remove_group_from_acl(group, user_acl_path)
218
- end
214
+ remove_group_from_acl(group, user_acl_path) if invalid_group?(group)
219
215
  end
220
216
  end
221
217
  end
@@ -227,7 +223,7 @@ class Chef
227
223
  client_acl = FFI_Yajl::Parser.parse(::File.read(client_acl_path), symbolize_names: false)
228
224
  rescue Errno::ENOENT
229
225
  @tidy.ui.stdout.puts "REPAIRING: Replacing missing client acl for #{client[:name]} in #{client_acl_path}."
230
- @tidy.write_new_file(default_client_acl(client[:name]), client_acl_path, backup=false)
226
+ @tidy.write_new_file(default_client_acl(client[:name]), client_acl_path, backup = false)
231
227
  client_acl = FFI_Yajl::Parser.parse(::File.read(client_acl_path), symbolize_names: false)
232
228
  end
233
229
  ensure_client_read_acls(client_acl_path)
@@ -1,6 +1,6 @@
1
1
  require 'ffi_yajl'
2
2
  require 'fileutils'
3
- require "chef/knife/core/ui"
3
+ require 'chef/knife/core/ui'
4
4
 
5
5
  class Chef
6
6
  class TidyCommon
@@ -67,12 +67,12 @@ class Chef
67
67
  end
68
68
  end
69
69
 
70
- def write_new_file(contents, path, backup=true)
70
+ def write_new_file(contents, path, backup = true)
71
71
  if ::File.exist?(path) && backup
72
72
  FileUtils.cp(path, "#{path}.orig") unless ::File.exist?("#{path}.orig")
73
73
  end
74
74
  ::File.open(path, 'w+') do |f|
75
- f.write(FFI_Yajl::Encoder.encode(contents, pretty: true))
75
+ f.write(FFI_Yajl::Encoder.encode(contents, pretty: true))
76
76
  end
77
77
  end
78
78
 
@@ -30,12 +30,11 @@ class Chef
30
30
 
31
31
  def cookbook_version_from_path(path)
32
32
  components = path.split(File::SEPARATOR)
33
- name_version = components[components.index('cookbooks')+1]
33
+ name_version = components[components.index('cookbooks') + 1]
34
34
  name_version.match(/\d+\.\d+\.\d+/).to_s
35
35
  end
36
36
 
37
37
  def revert
38
-
39
38
  end
40
39
 
41
40
  def sub_in_file(path, search, replace)
@@ -69,7 +68,7 @@ class Chef
69
68
  @data[entry][glob].each do |substitution|
70
69
  search = Regexp.new(substitution['pattern'])
71
70
  replace = substitution['replace'].dup
72
- replace.gsub!(/\!COOKBOOK_VERSION\!/) { |m| "'" + cookbook_version_from_path(file) + "'" }
71
+ replace.gsub!(/\!COOKBOOK_VERSION\!/) { |_m| "'" + cookbook_version_from_path(file) + "'" }
73
72
  sub_in_file(file, search, replace)
74
73
  end
75
74
  end
@@ -1,4 +1,4 @@
1
1
  module KnifeTidy
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'.freeze
3
3
  MAJOR, MINOR, TINY = VERSION.split('.')
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-tidy
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
  - Jeremy Miller
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-12 00:00:00.000000000 Z
11
+ date: 2018-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -145,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
145
  version: '0'
146
146
  requirements: []
147
147
  rubyforge_project:
148
- rubygems_version: 2.6.11
148
+ rubygems_version: 2.7.3
149
149
  signing_key:
150
150
  specification_version: 4
151
151
  summary: Report on stale Chef Server nodes and cookbooks and clean up data integrity