knife-tidy 1.0.1 → 1.1.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.
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