knife-tidy 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +19 -15
- data/conf/substitutions.json.example +2 -18
- data/lib/chef/knife/tidy_backup_clean.rb +23 -0
- data/lib/chef/knife/tidy_server_clean.rb +30 -33
- data/lib/chef/knife/tidy_server_report.rb +8 -2
- data/lib/knife-tidy/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9766f389dc78f0c5c764b04ad056d0c74278751
|
4
|
+
data.tar.gz: 6df96008461814fa24005126d3df61a117288cd3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21bf46076b9e8dee58aea293820e13ea93d724ea240cb95c9b44e43942aab098a754aea3e31affbd9f481acacfc3eda39c9f9d1787210039aed5f20691ed00b5
|
7
|
+
data.tar.gz: ec2a71913df5a0e69949e3a0a6efe59814df404db9de70d29255a77a340430ca83836cdba78ad8d8927c8a183f2516ba027a54c07be1272681f5e33521e481a9
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [0.5.0](https://github.com/chef-customers/knife-tidy/tree/0.5.0) (2017-10-06)
|
4
|
+
[Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.4.1...0.5.0)
|
5
|
+
|
6
|
+
**Closed issues:**
|
7
|
+
|
8
|
+
- Supermarket.chef.io [\#37](https://github.com/chef-customers/knife-tidy/issues/37)
|
9
|
+
|
10
|
+
**Merged pull requests:**
|
11
|
+
|
12
|
+
- enabling deletion of stale nodes [\#44](https://github.com/chef-customers/knife-tidy/pull/44) ([jeremymv2](https://github.com/jeremymv2))
|
13
|
+
- better warning message before confirmation [\#43](https://github.com/chef-customers/knife-tidy/pull/43) ([jeremymv2](https://github.com/jeremymv2))
|
14
|
+
- Jeremymv2/chef sugar fix default [\#42](https://github.com/chef-customers/knife-tidy/pull/42) ([jeremymv2](https://github.com/jeremymv2))
|
15
|
+
- deleting nodes also deletes client [\#41](https://github.com/chef-customers/knife-tidy/pull/41) ([jeremymv2](https://github.com/jeremymv2))
|
16
|
+
- Change nodes\_list method to get all nodes [\#40](https://github.com/chef-customers/knife-tidy/pull/40) ([nsdavidson](https://github.com/nsdavidson))
|
17
|
+
- bump version to 0.4.1 [\#39](https://github.com/chef-customers/knife-tidy/pull/39) ([jeremymv2](https://github.com/jeremymv2))
|
18
|
+
|
3
19
|
## [0.4.1](https://github.com/chef-customers/knife-tidy/tree/0.4.1) (2017-09-27)
|
4
20
|
[Full Changelog](https://github.com/chef-customers/knife-tidy/compare/0.4.0...0.4.1)
|
5
21
|
|
data/README.md
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
# Summary
|
4
4
|
|
5
|
-
This Chef Knife plugin
|
6
|
-
*
|
7
|
-
*
|
5
|
+
This Chef Knife plugin provides:
|
6
|
+
* Reports on the state of Chef Server objects that can be tidied up
|
7
|
+
* Removal of stale nodes (and associated clients and ACLs) identified by the above Reports
|
8
|
+
* A [knife-ec-backup](https://github.com/chef/knife-ec-backup) companion tool that will clean up data integrity issues in an object backup
|
8
9
|
|
9
10
|
# Requirements
|
10
11
|
|
@@ -56,6 +57,21 @@ org_threshold_numdays_stale_nodes.json | Nodes in that org that have not checked
|
|
56
57
|
org_cookbook_count.json | Number of cookbook versions for each cookbook that that org.
|
57
58
|
org_unused_cookbooks.json | List of cookbooks and versions that do not appear to be in-use for that org. This is determined by checking the versioned run list of each of the nodes in the org.
|
58
59
|
|
60
|
+
## $ knife tidy server clean --help
|
61
|
+
Remove stale nodes that haven't checked-in to the Chef Server as defined by the `--node-threshold NUM_DAYS` option when the reports were generated.. The associated client and ACLs are also removed.
|
62
|
+
|
63
|
+
Future: remove unused cookbooks - currently this feature is disabled.
|
64
|
+
|
65
|
+
## Options
|
66
|
+
|
67
|
+
* `--dry-run`
|
68
|
+
Do not perform any actual deletion, only report on what would have been deleted.
|
69
|
+
|
70
|
+
Example:
|
71
|
+
```bash
|
72
|
+
knife tidy server clean --orgs brewinc,acmeinc
|
73
|
+
```
|
74
|
+
|
59
75
|
## $ knife tidy backup clean --help
|
60
76
|
|
61
77
|
## Options
|
@@ -80,18 +96,6 @@ knife tidy backup clean --backup-path backups/ --gsub-file substitutions.json
|
|
80
96
|
|
81
97
|
```json
|
82
98
|
{
|
83
|
-
"chef-sugar":{
|
84
|
-
"organizations/*/cookbooks/chef-sugar*/metadata.rb":[
|
85
|
-
{
|
86
|
-
"pattern":"^require .*/lib/chef/sugar/version",
|
87
|
-
"replace":"# require File.expand_path('../lib/chef/sugar/version', *__FILE__)"
|
88
|
-
},
|
89
|
-
{
|
90
|
-
"pattern":"version *Chef::Sugar::VERSION",
|
91
|
-
"replace":"version !COOKBOOK_VERSION!"
|
92
|
-
}
|
93
|
-
]
|
94
|
-
},
|
95
99
|
"io-read-version-and-readme.md":{
|
96
100
|
"organizations/*/cookbooks/*/metadata.rb":[
|
97
101
|
{
|
@@ -1,25 +1,9 @@
|
|
1
1
|
{
|
2
|
-
"
|
3
|
-
"organizations/*/cookbooks/chef-sugar*/metadata.rb":[
|
4
|
-
{
|
5
|
-
"pattern":"^require .*/lib/chef/sugar/version",
|
6
|
-
"replace":"# require File.expand_path('../lib/chef/sugar/version', *__FILE__)"
|
7
|
-
},
|
8
|
-
{
|
9
|
-
"pattern":"version *Chef::Sugar::VERSION",
|
10
|
-
"replace":"version !COOKBOOK_VERSION!"
|
11
|
-
}
|
12
|
-
]
|
13
|
-
},
|
14
|
-
"io-read-version-and-readme.md":{
|
2
|
+
"your-problem-descriptor":{
|
15
3
|
"organizations/*/cookbooks/*/metadata.rb":[
|
16
4
|
{
|
17
|
-
"pattern":"^version
|
5
|
+
"pattern":"^version .*GO_PIPELINE_LABEL",
|
18
6
|
"replace":"version !COOKBOOK_VERSION!"
|
19
|
-
},
|
20
|
-
{
|
21
|
-
"pattern":"^long_description +IO.read.* 'README.md'.*",
|
22
|
-
"replace":"#long_description \"A Long Description..\""
|
23
7
|
}
|
24
8
|
]
|
25
9
|
}
|
@@ -45,6 +45,8 @@ class Chef
|
|
45
45
|
exit 1
|
46
46
|
end
|
47
47
|
|
48
|
+
fix_chef_sugar_metadata
|
49
|
+
|
48
50
|
Chef::TidySubstitutions.new(substitutions_file, tidy).run_substitutions if config[:gsub_file]
|
49
51
|
|
50
52
|
validate_user_emails
|
@@ -187,6 +189,27 @@ class Chef
|
|
187
189
|
end
|
188
190
|
end
|
189
191
|
|
192
|
+
def fix_chef_sugar_metadata
|
193
|
+
Dir[::File.join(tidy.backup_path, 'organizations/*/cookbooks/chef-sugar*/metadata.rb')].each do |file|
|
194
|
+
puts 'INFO: Searching for known chef-sugar problems when uploading.'
|
195
|
+
s = Chef::TidySubstitutions.new
|
196
|
+
version = s.cookbook_version_from_path(file)
|
197
|
+
patterns = [
|
198
|
+
{
|
199
|
+
search: '^require .*/lib/chef/sugar/version',
|
200
|
+
replace: "# require File.expand_path('../lib/chef/sugar/version', *__FILE__)"
|
201
|
+
},
|
202
|
+
{
|
203
|
+
search: '^version *Chef::Sugar::VERSION',
|
204
|
+
replace: "version '#{version}'"
|
205
|
+
}
|
206
|
+
]
|
207
|
+
patterns.each do |p|
|
208
|
+
s.sub_in_file(file, Regexp.new(p[:search]), p[:replace])
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
190
213
|
def fix_self_dependencies(org)
|
191
214
|
for_each_cookbook_path(org) do |cookbook_path|
|
192
215
|
name = tidy.cookbook_name_from_path(cookbook_path)
|
@@ -15,8 +15,8 @@ class Chef
|
|
15
15
|
|
16
16
|
option :concurrency,
|
17
17
|
:long => '--concurrency THREADS',
|
18
|
-
:default =>
|
19
|
-
:description => 'Maximum number of simultaneous requests to send (default:
|
18
|
+
:default => 1,
|
19
|
+
:description => 'Maximum number of simultaneous requests to send (default: 1)'
|
20
20
|
|
21
21
|
option :only_cookbooks,
|
22
22
|
:long => '--only-cookbooks',
|
@@ -24,23 +24,17 @@ class Chef
|
|
24
24
|
|
25
25
|
option :only_nodes,
|
26
26
|
:long => '--only-nodes',
|
27
|
-
:description => 'Only delete stale nodes from Chef Server.'
|
27
|
+
:description => 'Only delete stale nodes (and associated clients and ACLs) from Chef Server.'
|
28
28
|
|
29
29
|
option :dry_run,
|
30
30
|
:long => '--dry-run',
|
31
31
|
:description => 'Do not perform any actual deletion, only report on what would have been deleted.'
|
32
32
|
|
33
33
|
def run
|
34
|
-
# not enabled
|
35
|
-
ui.warn "This feature is not enabled"
|
36
|
-
exit
|
37
|
-
|
38
34
|
STDOUT.sync = true
|
39
35
|
|
40
36
|
ensure_reports_dir
|
41
|
-
puts "INFO: Reading from #{tidy.reports_dir} directory"
|
42
37
|
|
43
|
-
puts "INFO: Using thread concurrency #{config[:concurrency]}"
|
44
38
|
configure_chef
|
45
39
|
|
46
40
|
if config[:only_cookbooks] && config[:only_nodes]
|
@@ -48,7 +42,13 @@ class Chef
|
|
48
42
|
exit 1
|
49
43
|
end
|
50
44
|
|
51
|
-
|
45
|
+
deletions = if config[:only_cookbooks]
|
46
|
+
"cookbooks"
|
47
|
+
elsif config[:only_nodes]
|
48
|
+
"nodes (and associated clients and ACLs)"
|
49
|
+
else
|
50
|
+
"cookbooks and nodes (and associated clients and ACLs)"
|
51
|
+
end
|
52
52
|
|
53
53
|
orgs = if config[:org_list]
|
54
54
|
config[:org_list].split(',')
|
@@ -56,6 +56,10 @@ class Chef
|
|
56
56
|
all_orgs
|
57
57
|
end
|
58
58
|
|
59
|
+
ui.warn "This operation will affect the following Orgs on #{server.root_url}\n\n#{orgs}\n\n"
|
60
|
+
|
61
|
+
ui.confirm("About to delete #{deletions} from the Chef Server identified in the #{tidy.reports_dir} directory! Are you sure you wish to continue") unless config[:unattended]
|
62
|
+
|
59
63
|
orgs.each do |org|
|
60
64
|
clean_cookbooks(org) unless config[:only_nodes]
|
61
65
|
clean_nodes(org) unless config[:only_cookbooks]
|
@@ -65,6 +69,8 @@ class Chef
|
|
65
69
|
end
|
66
70
|
|
67
71
|
def clean_cookbooks(org)
|
72
|
+
ui.warn "Cleaning cookbooks is a feature not yet enabled."
|
73
|
+
return
|
68
74
|
queue = Chef::Util::ThreadedJobQueue.new
|
69
75
|
unused_cookbooks_file = ::File.join(tidy.reports_dir, "#{org}_unused_cookbooks.json")
|
70
76
|
return unless ::File.exist?(unused_cookbooks_file)
|
@@ -82,19 +88,12 @@ class Chef
|
|
82
88
|
def delete_cookbook_job(org, cookbook, version)
|
83
89
|
path = "/organizations/#{org}/cookbooks/#{cookbook}/#{version}"
|
84
90
|
if config[:dry_run]
|
85
|
-
printf("
|
91
|
+
printf("DRYRUN: Would have executed `rest.delete(#{path})`\n")
|
86
92
|
return
|
87
93
|
end
|
94
|
+
printf("INFO: Deleting #{path}\n")
|
88
95
|
rest.delete(path)
|
89
|
-
response = '200'
|
90
96
|
rescue Net::HTTPServerException
|
91
|
-
response = $!.response.code
|
92
|
-
ensure
|
93
|
-
return if config[:dry_run]
|
94
|
-
formatted = response == '200' ?
|
95
|
-
ui.color(' Deleting %-20s %-10s %10s', :green) :
|
96
|
-
ui.color(' Deleting %-20s %-10s %10s', :red)
|
97
|
-
printf("#{formatted}\n", cookbook, version, response)
|
98
97
|
end
|
99
98
|
|
100
99
|
def clean_nodes(org)
|
@@ -110,21 +109,19 @@ class Chef
|
|
110
109
|
end
|
111
110
|
|
112
111
|
def delete_node_job(org, node)
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
112
|
+
paths = ["/organizations/#{org}/nodes/#{node}", "/organizations/#{org}/clients/#{node}"]
|
113
|
+
paths.each do |path|
|
114
|
+
if config[:dry_run]
|
115
|
+
printf("DRYRUN: Would have executed `rest.delete(#{path})`\n")
|
116
|
+
next
|
117
|
+
else
|
118
|
+
begin
|
119
|
+
printf("INFO: Deleting #{path}\n")
|
120
|
+
rest.delete(path)
|
121
|
+
rescue Net::HTTPServerException
|
122
|
+
end
|
123
|
+
end
|
117
124
|
end
|
118
|
-
rest.delete(path)
|
119
|
-
response = '200'
|
120
|
-
rescue Net::HTTPServerException
|
121
|
-
response = $!.response.code
|
122
|
-
ensure
|
123
|
-
return if config[:dry_run]
|
124
|
-
formatted = response == '200' ?
|
125
|
-
ui.color(' Deleting %-20s %10s', :green) :
|
126
|
-
ui.color(' Deleting %-20s %10s', :red)
|
127
|
-
printf("#{formatted}\n", node, response)
|
128
125
|
end
|
129
126
|
|
130
127
|
def ensure_reports_dir
|
@@ -37,7 +37,7 @@ class Chef
|
|
37
37
|
cb_list = cookbook_list(org)
|
38
38
|
version_count = cookbook_count(cb_list).sort_by(&:last).reverse.to_h
|
39
39
|
used_cookbooks = {}
|
40
|
-
nodes = nodes_list(org)
|
40
|
+
nodes = nodes_list(org)
|
41
41
|
|
42
42
|
nodes.select{|node| !node['cookbooks'].nil?}.each do |node|
|
43
43
|
node['cookbooks'].each do |name, version_hash|
|
@@ -86,7 +86,10 @@ class Chef
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
+
# Need the block here to get the search method to invoke multiple searches and
|
90
|
+
# aggregate results for result sets over 1k.
|
89
91
|
def nodes_list(org)
|
92
|
+
node_results = []
|
90
93
|
Chef::Search::Query.new("#{server.root_url}/organizations/#{org}").search(
|
91
94
|
:node, '*:*',
|
92
95
|
:filter_result => {
|
@@ -94,7 +97,10 @@ class Chef
|
|
94
97
|
'cookbooks' => ['cookbooks'],
|
95
98
|
'ohai_time' => ['ohai_time']
|
96
99
|
}
|
97
|
-
)
|
100
|
+
) do |node|
|
101
|
+
node_results << node
|
102
|
+
end
|
103
|
+
node_results
|
98
104
|
end
|
99
105
|
|
100
106
|
def cookbook_list(org)
|
data/lib/knife-tidy/version.rb
CHANGED
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: 0.
|
4
|
+
version: 0.5.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-
|
11
|
+
date: 2017-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|