knife-tidy 0.1.1 → 0.2.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
2
  SHA1:
3
- metadata.gz: d41634bad35e623a19ebe00e33d890aa31c6e4e9
4
- data.tar.gz: dc4576d52dc94ea7c5dce5e72d6045dc4ddbb634
3
+ metadata.gz: 2bc910eba99a7cccb3e6ca423da6c116f1fd09af
4
+ data.tar.gz: fc67a3f6dd6f653e28336f6907e409b1dc6934c3
5
5
  SHA512:
6
- metadata.gz: 309ce63b1bd9eb385a901efdc4cc185cc04a2953bf88064a5aad88a28d7beb7109eee64956f0e7f3956eac9a549e954e2b957753d0059f3f55893d48f0feca0d
7
- data.tar.gz: c7d6e786d7f4ece31e628d3dd3976cf0f723e4bb2db0815851fa68ecf448f5976461897fac525702761997d1f8b380d4e0a99d88eb490656e40d7198685063fe
6
+ metadata.gz: 133361ea06a8bc562de3d149e3b0e523627ab3bbdccbdac8d5a8e4205d0acaadfa249395403f9d2659de82b7cb34024e29affbc3d17cf63a523dc7a69027d560
7
+ data.tar.gz: a80bd192038fb73f4b375098f0958cdbd537c5d4321d0dc8f14251446788429145709016080fcb83edcc7ae2ed6363625cd975bbbe3c46e662d7094d6f172db9
@@ -1,12 +1,22 @@
1
1
  # Change Log
2
2
 
3
- ## [0.1.1](https://github.com/jeremymv2/knife-tidy/tree/0.1.1) (2017-08-11)
4
- [Full Changelog](https://github.com/jeremymv2/knife-tidy/compare/0.1.1...0.1.1)
3
+ ## [0.1.0](https://github.com/jeremymv2/knife-tidy/tree/0.1.0) (2017-08-15)
4
+ [Full Changelog](https://github.com/jeremymv2/knife-tidy/compare/0.2.0...0.1.0)
5
5
 
6
6
  **Merged pull requests:**
7
7
 
8
+ - bump version to 0.2.0 [\#6](https://github.com/jeremymv2/knife-tidy/pull/6) ([jeremymv2](https://github.com/jeremymv2))
9
+
10
+ ## [0.2.0](https://github.com/jeremymv2/knife-tidy/tree/0.2.0) (2017-08-16)
11
+ [Full Changelog](https://github.com/jeremymv2/knife-tidy/compare/0.1.1...0.2.0)
12
+
13
+ **Merged pull requests:**
14
+
15
+ - moved all common functions to tidy\_common.rb [\#5](https://github.com/jeremymv2/knife-tidy/pull/5) ([jeremymv2](https://github.com/jeremymv2))
16
+ - Jeremymv2/acl items [\#4](https://github.com/jeremymv2/knife-tidy/pull/4) ([jeremymv2](https://github.com/jeremymv2))
17
+ - updated changelog [\#3](https://github.com/jeremymv2/knife-tidy/pull/3) ([jeremymv2](https://github.com/jeremymv2))
8
18
  - bump version to 0.1.1 [\#2](https://github.com/jeremymv2/knife-tidy/pull/2) ([jeremymv2](https://github.com/jeremymv2))
9
19
 
10
20
 
11
21
 
12
- \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
22
+ \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
data/README.md CHANGED
@@ -31,7 +31,7 @@ The following options are supported across all subcommands:
31
31
  * `--orgs ORG1,ORG2`:
32
32
  Only apply to objects in the named organizations (default: all orgs)
33
33
 
34
- # knife tidy server report (options)
34
+ ## $ knife tidy server report (options)
35
35
 
36
36
  Cookbooks and nodes account for the largest objects in your Chef Server.
37
37
  If you want to keep it lean and mean and easy to port the object data, you must
@@ -51,7 +51,7 @@ org_threshold_numdays_stale_nodes.json | Nodes in that org that have not checked
51
51
  org_cookbook_count.json | Number of cookbook versions for each cookbook that that org.
52
52
  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.
53
53
 
54
- # knife tidy backup clean (options)
54
+ ## $ knife tidy backup clean (options)
55
55
 
56
56
  ## Options
57
57
 
@@ -90,9 +90,9 @@ org_unused_cookbooks.json | List of cookbooks and versions that do not appear to
90
90
  * DONE: metadata self-dependency correction
91
91
  * DONE: user email validation
92
92
  * DONE: ensure user emails do not cause primary key violation
93
- * TODO: ambiguous actors (acl actor exists as client and user)
94
- * TODO: users/clients referenced as actors in acls that do not exist in users/clients
95
- * TODO: nonexistent groups referenced in acls
93
+ * DONE: ambiguous actors (acl actor exists as client and user)
94
+ * DONE: users/clients referenced as actors in acls that do not exist in users/clients
95
+ * DONE: nonexistent groups referenced in acls
96
96
 
97
97
  ## Summary and Credits
98
98
 
data/Rakefile CHANGED
@@ -72,7 +72,7 @@ namespace :changelog do
72
72
 
73
73
  GitHubChangelogGenerator::RakeTask.new :changelog do |config|
74
74
  config.since_tag = '0.1.1'
75
- config.future_release = '0.1.1'
75
+ config.future_release = '0.1.0'
76
76
  end
77
77
  end
78
78
  end
@@ -2,12 +2,12 @@
2
2
  "chef-sugar":{
3
3
  "organizations/*/cookbooks/chef-sugar*/metadata.rb":[
4
4
  {
5
- "pattern":"require +File.expand_path('../lib/chef/sugar/version', __FILE__)",
5
+ "pattern":"^require .*/lib/chef/sugar/version",
6
6
  "replace":"# require File.expand_path('../lib/chef/sugar/version', __FILE__)"
7
7
  },
8
8
  {
9
9
  "pattern":"version *Chef::Sugar::VERSION",
10
- "replace":"# version !COOKBOOK_VERSION!"
10
+ "replace":"version !COOKBOOK_VERSION!"
11
11
  }
12
12
  ]
13
13
  }
@@ -4,15 +4,17 @@ class Chef
4
4
  class Knife
5
5
  class TidyBackupClean < Knife
6
6
 
7
- include Knife::TidyBase
8
-
9
7
  deps do
10
8
  require 'chef/cookbook_loader'
11
9
  require 'chef/cookbook/metadata'
12
10
  require 'chef/tidy_substitutions'
11
+ require 'chef/tidy_acls'
12
+ require 'chef/tidy_common'
13
13
  require 'ffi_yajl'
14
14
  end
15
15
 
16
+ include Knife::TidyBase
17
+
16
18
  option :backup_path,
17
19
  :long => '--backup-path path/to/backup',
18
20
  :description => 'The path to the knife-ec-backup backup directory'
@@ -22,75 +24,72 @@ class Chef
22
24
  :description => 'The path to the file used for substitutions. If non-existant, a boiler plate one will be created.'
23
25
 
24
26
  def run
25
- unless config[:backup_path]
26
- ui.error 'Must specify --backup-path'
27
+ unless config[:backup_path] && ::File.directory?(config[:backup_path])
28
+ ui.error 'Must specify valid --backup-path'
27
29
  exit 1
28
30
  end
29
31
 
30
- validate_user_emails!
32
+ validate_user_emails
31
33
 
32
34
  if config[:gsub_file]
33
35
  unless ::File.exist?(config[:gsub_file])
34
36
  Chef::TidySubstitutions.new(substitutions_file).boiler_plate
35
37
  exit
36
38
  else
37
- Chef::TidySubstitutions.new(substitutions_file, backup_path_expanded).run_substitutions
39
+ Chef::TidySubstitutions.new(substitutions_file, tidy).run_substitutions
38
40
  end
39
41
  end
40
42
 
41
43
  orgs.each do |org|
44
+ org_acls = Chef::TidyOrgAcls.new(tidy, org)
45
+ org_acls.validate_acls
46
+ org_acls.validate_user_acls
42
47
  fix_self_dependencies(org)
43
48
  load_cookbooks(org)
44
49
  generate_new_metadata(org)
45
50
  end
46
51
  end
47
52
 
48
- def validate_user_emails!
53
+ def tidy
54
+ @tidy ||= Chef::TidyCommon.new(config[:backup_path])
55
+ end
56
+
57
+ def validate_user_emails
49
58
  emails_seen = []
50
- global_users.each do |user|
59
+ tidy.global_user_names.each do |user|
51
60
  email = ''
52
61
  ui.info "Validating #{user}"
53
- the_user = FFI_Yajl::Parser.parse(::File.read(::File.join(global_users_path_expanded, "#{user}.json")), symbolize_names: false)
62
+ the_user = FFI_Yajl::Parser.parse(::File.read(::File.join(tidy.users_path, "#{user}.json")), symbolize_names: false)
54
63
  if the_user['email'].match(/\A[^@\s]+@[^@\s]+\z/)
55
64
  if emails_seen.include?(the_user['email'])
56
65
  ui.info "Already saw #{user}'s email, creating a unique one."
57
- email = unique_email
66
+ email = tidy.unique_email
58
67
  new_user = the_user.dup
59
68
  new_user['email'] = email
60
- save_user(new_user)
69
+ tidy.save_user(new_user)
61
70
  emails_seen.push(email)
62
71
  else
63
72
  emails_seen.push(the_user['email'])
64
73
  end
65
74
  else
66
75
  ui.info "User #{user} does not have a valid email, creating a unique one."
67
- email = unique_email
76
+ email = tidy.unique_email
68
77
  new_user = the_user.dup
69
78
  new_user['email'] = email
70
- save_user(new_user)
79
+ tidy.save_user(new_user)
71
80
  emails_seen.push(email)
72
81
  end
73
82
  end
74
83
  end
75
84
 
76
- def unique_email
77
- (0...8).map { (65 + rand(26)).chr }.join.downcase +
78
- '@' + (0...8).map { (65 + rand(26)).chr }.join.downcase + '.com'
79
- end
80
-
81
- def save_user(user)
82
- ::File.open(::File.join(global_users_path_expanded, "#{user['username']}.json"), 'w+') do |f|
83
- f.write(FFI_Yajl::Encoder.encode(user, pretty: true))
84
- end
85
- end
86
-
87
85
  def load_cookbooks(org)
88
- cl = Chef::CookbookLoader.new(cookbooks_path_expanded(org))
86
+ cl = Chef::CookbookLoader.new(tidy.cookbooks_path(org))
89
87
  for_each_cookbook_basename(org) do |cookbook|
90
88
  ui.info "Loading #{cookbook}"
91
89
  ret = cl.load_cookbook(cookbook)
92
90
  if ret.nil?
93
- ui.error "Something's wrong with the #{cookbook} cookbook - cannot load it!"
91
+ ui.warn "Something's wrong with the #{cookbook} cookbook - cannot load it! Moving to cookbooks.broken folder."
92
+ broken_cookooks_add(org, cookbook)
94
93
  end
95
94
  end
96
95
  rescue LoadError => e
@@ -99,15 +98,23 @@ class Chef
99
98
  exit 1
100
99
  end
101
100
 
101
+ def broken_cookooks_add(org, cookbook)
102
+ broken_path = ::File.join(tidy.org_path(org), 'cookbooks.broken')
103
+ FileUtils.mkdir(broken_path) unless ::File.directory?(broken_path)
104
+ Dir[::File.join(tidy.cookbooks_path(org), "#{cookbook}*")].each do |cb|
105
+ FileUtils.mv(cb, broken_path, :verbose => true, :force => true)
106
+ end
107
+ end
108
+
102
109
  def generate_new_metadata(org)
103
110
  for_each_cookbook_path(org) do |cookbook_path|
104
- generate_metadata_from_file(cookbook_name_from_path(cookbook_path), cookbook_path)
111
+ generate_metadata_from_file(tidy.cookbook_name_from_path(cookbook_path), cookbook_path)
105
112
  end
106
113
  end
107
114
 
108
115
  def fix_self_dependencies(org)
109
116
  for_each_cookbook_path(org) do |cookbook_path|
110
- name = cookbook_name_from_path(cookbook_path)
117
+ name = tidy.cookbook_name_from_path(cookbook_path)
111
118
  md_path = ::File.join(cookbook_path, 'metadata.rb')
112
119
  unless ::File.exist?(md_path)
113
120
  ui.warn "No metadata.rb in #{cookbook_path} - skipping"
@@ -142,8 +149,33 @@ class Chef
142
149
  exit 1
143
150
  end
144
151
 
145
- def validate_user(user)
146
- ui.info "Validating user #{user}"
152
+ def substitutions_file
153
+ @substitutions_file ||= ::File.expand_path(config[:gsub_file])
154
+ end
155
+
156
+ def orgs
157
+ @orgs ||= if config[:org_list]
158
+ config[:org_list].split(',')
159
+ else
160
+ Dir[::File.join(tidy.backup_path, 'organizations', '*')].map { |dir| ::File.basename(dir) }
161
+ end
162
+ end
163
+
164
+ def for_each_cookbook_basename(org)
165
+ cookbooks_seen = []
166
+ Dir[::File.join(tidy.cookbooks_path(org), '**-**')].each do |cookbook|
167
+ name = tidy.cookbook_name_from_path(cookbook)
168
+ unless cookbooks_seen.include?(name)
169
+ cookbooks_seen.push(name)
170
+ yield name
171
+ end
172
+ end
173
+ end
174
+
175
+ def for_each_cookbook_path(org)
176
+ Dir[::File.join(tidy.cookbooks_path(org), '**')].each do |cookbook|
177
+ yield cookbook
178
+ end
147
179
  end
148
180
  end
149
181
  end
@@ -47,55 +47,6 @@ class Chef
47
47
  def rest
48
48
  @rest ||= Chef::ServerAPI.new(server.root_url, {:api_version => "0"})
49
49
  end
50
-
51
- def backup_path_expanded
52
- ::File.expand_path(config[:backup_path])
53
- end
54
-
55
- def cookbook_name_from_path(path)
56
- ::File.basename(path, '-*')
57
- end
58
-
59
- def cookbooks_path_expanded(org)
60
- ::File.expand_path(::File.join(backup_path_expanded, 'organizations', org, 'cookbooks'))
61
- end
62
-
63
- def global_users_path_expanded
64
- ::File.expand_path(::File.join(backup_path_expanded, 'users'))
65
- end
66
-
67
- def substitutions_file
68
- ::File.expand_path(config[:gsub_file])
69
- end
70
-
71
- def global_users
72
- Dir[::File.join(backup_path_expanded, 'users', '*')].map { |dir| ::File.basename(dir, '.json') }
73
- end
74
-
75
- def orgs
76
- if config[:org_list]
77
- config[:org_list].split(',')
78
- else
79
- Dir[::File.join(backup_path_expanded, 'organizations', '*')].map { |dir| ::File.basename(dir) }
80
- end
81
- end
82
-
83
- def for_each_cookbook_basename(org)
84
- cookbooks_seen = []
85
- Dir[::File.join(cookbooks_path_expanded(org), '**-**')].each do |cookbook|
86
- name = cookbook_name_from_path(cookbook)
87
- unless cookbooks_seen.include?(name)
88
- cookbooks_seen.push(name)
89
- yield name
90
- end
91
- end
92
- end
93
-
94
- def for_each_cookbook_path(org)
95
- Dir[::File.join(cookbooks_path_expanded(org), '**')].each do |cookbook|
96
- yield cookbook
97
- end
98
- end
99
50
  end
100
51
  end
101
52
  end
@@ -0,0 +1,180 @@
1
+ require 'ffi_yajl'
2
+ require 'fileutils'
3
+ require 'chef/log'
4
+
5
+ class Chef
6
+ class TidyOrgAcls
7
+ attr_accessor :members, :clients, :groups, :users
8
+
9
+ def initialize(tidy, org)
10
+ @tidy = tidy
11
+ @backup_path = @tidy.backup_path
12
+ @org = org
13
+ @clients = []
14
+ @members = []
15
+ @groups = []
16
+ @users = []
17
+ load_actors
18
+ end
19
+
20
+ def load_users
21
+ Chef::Log.warn "Loading users"
22
+ Dir[::File.join(@tidy.users_path, '*.json')].each do |user|
23
+ @users.push(FFI_Yajl::Parser.parse(::File.read(user), symbolize_names: true))
24
+ end
25
+ end
26
+
27
+ def load_members
28
+ Chef::Log.info "Loading members for #{@org}"
29
+ @members = FFI_Yajl::Parser.parse(::File.read(@tidy.members_path(@org)), symbolize_names: true)
30
+ end
31
+
32
+ def load_clients
33
+ Chef::Log.info "Loading clients for #{@org}"
34
+ Dir[::File.join(@tidy.clients_path(@org), '*.json')].each do |client|
35
+ @clients.push(FFI_Yajl::Parser.parse(::File.read(client), symbolize_names: true))
36
+ end
37
+ end
38
+
39
+ def load_groups
40
+ Chef::Log.info "Loading groups for #{@org}"
41
+ Dir[::File.join(@tidy.groups_path(@org), '*.json')].each do |group|
42
+ @groups.push(FFI_Yajl::Parser.parse(::File.read(group), symbolize_names: true))
43
+ end
44
+ end
45
+
46
+ def load_actors
47
+ load_users
48
+ load_members
49
+ load_clients
50
+ load_groups
51
+ Chef::Log.info "#{@org} Actors loaded!"
52
+ end
53
+
54
+ def acl_ops
55
+ %w( create read update delete grant )
56
+ end
57
+
58
+ def acl_actors_groups(acl)
59
+ actors_seen = []
60
+ groups_seen = []
61
+ acl_ops.each do |op|
62
+ acl[op]['actors'].each do |actor|
63
+ actors_seen.push(actor) unless actors_seen.include?(actor)
64
+ end
65
+ acl[op]['groups'].each do |group|
66
+ groups_seen.push(group) unless groups_seen.include?(group)
67
+ end
68
+ end
69
+ { actors: actors_seen, groups: groups_seen }
70
+ end
71
+
72
+ def valid_org_member?(actor)
73
+ ! @members.select { |user| user[:user][:username] == actor }.empty?
74
+ end
75
+
76
+ def valid_org_client?(actor)
77
+ ! @clients.select { |client| client[:name] == actor }.empty?
78
+ end
79
+
80
+ def valid_global_user?(actor)
81
+ ! @users.select { |user| user[:username] == actor }.empty?
82
+ end
83
+
84
+ def invalid_group?(actor)
85
+ @groups.select { |group| group[:name] == actor }.empty? &&
86
+ actor != '::server-admins' &&
87
+ actor != "::#{@org}_read_access_group"
88
+ end
89
+
90
+ def ambiguous_actor?(actor)
91
+ valid_org_member?(actor) && valid_org_client?(actor)
92
+ end
93
+
94
+ def missing_from_members?(actor)
95
+ valid_global_user?(actor) && !valid_org_member?(actor) && !valid_org_client?(actor)
96
+ end
97
+
98
+ def missing_org_client?(actor)
99
+ !valid_global_user?(actor) && !valid_org_member?(actor) && !valid_org_client?(actor)
100
+ end
101
+
102
+ def org_acls
103
+ @org_acls ||= Dir[::File.join(@tidy.org_acls_path(@org), '**.json')] +
104
+ Dir[::File.join(@tidy.org_acls_path(@org), '**', '*.json')]
105
+ end
106
+
107
+ def fix_ambiguous_actor(actor)
108
+ Chef::Log.warn "Ambiguous actor! #{actor} removing from #{@tidy.members_path(@org)}"
109
+ remove_user_from_org(actor)
110
+ end
111
+
112
+ def add_client_to_org(actor)
113
+ # TODO
114
+ Chef::Log.warn "Client referenced in acl non-existant: #{actor}"
115
+ end
116
+
117
+ def add_actor_to_members(actor)
118
+ Chef::Log.warn "Invalid actor: #{actor} adding to #{@tidy.members_path(@org)}"
119
+ user = { user: { username: actor } }
120
+ @members.push(user)
121
+ write_new_file(@members, @tidy.members_path(@org))
122
+ end
123
+
124
+ def write_new_file(contents, path)
125
+ FileUtils.cp(path, "#{path}.orig") unless ::File.exist?("#{path}.orig")
126
+ ::File.open(path, 'w+') do |f|
127
+ f.write(FFI_Yajl::Encoder.encode(contents, pretty: true))
128
+ end
129
+ end
130
+
131
+ def remove_user_from_org(actor)
132
+ @members.reject! { |user| user[:user][:username] == actor }
133
+ write_new_file(@members, @tidy.members_path(@org))
134
+ end
135
+
136
+ def remove_group_from_acl(group, acl_file)
137
+ Chef::Log.warn "Removing invalid group: #{group} from #{acl_file}"
138
+ acl = FFI_Yajl::Parser.parse(::File.read(acl_file), symbolize_names: false)
139
+ acl_ops.each do |op|
140
+ acl[op]['groups'].reject! { |the_group| the_group == group }
141
+ end
142
+ write_new_file(acl, acl_file)
143
+ end
144
+
145
+ def validate_acls
146
+ org_acls.each do |acl_file|
147
+ acl = FFI_Yajl::Parser.parse(::File.read(acl_file), symbolize_names: false)
148
+ actors_groups = acl_actors_groups(acl)
149
+ actors_groups[:actors].each do |actor|
150
+ next if actor == 'pivotal'
151
+ if ambiguous_actor?(actor)
152
+ fix_ambiguous_actor(actor)
153
+ elsif missing_from_members?(actor)
154
+ add_actor_to_members(actor)
155
+ elsif missing_org_client?(actor)
156
+ add_client_to_org(actor)
157
+ end
158
+ end
159
+ actors_groups[:groups].each do |group|
160
+ if invalid_group?(group)
161
+ remove_group_from_acl(group, acl_file)
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ def validate_user_acls
168
+ @members.each do |member|
169
+ user_acl_path = ::File.join(@tidy.user_acls_path, "#{member[:user][:username]}.json")
170
+ user_acl = FFI_Yajl::Parser.parse(::File.read(user_acl_path), symbolize_names: false)
171
+ actors_groups = acl_actors_groups(user_acl)
172
+ actors_groups[:groups].each do |group|
173
+ if invalid_group?(group)
174
+ remove_group_from_acl(group, user_acl_path)
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,70 @@
1
+ require 'ffi_yajl'
2
+ require 'fileutils'
3
+
4
+ class Chef
5
+ class TidyCommon
6
+ attr_accessor :backup_path
7
+
8
+ def initialize(backup_path)
9
+ @backup_path = ::File.expand_path(backup_path)
10
+ end
11
+
12
+ def users_path
13
+ @users_path ||= File.expand_path(::File.join(@backup_path, 'users'))
14
+ end
15
+
16
+ def members_path(org)
17
+ ::File.expand_path(::File.join(@backup_path, 'organizations', org, 'members.json'))
18
+ end
19
+
20
+ def clients_path(org)
21
+ ::File.expand_path(::File.join(@backup_path, 'organizations', org, 'clients'))
22
+ end
23
+
24
+ def groups_path(org)
25
+ ::File.expand_path(::File.join(@backup_path, 'organizations', org, 'groups'))
26
+ end
27
+
28
+ def org_acls_path(org)
29
+ ::File.expand_path(::File.join(@backup_path, 'organizations', org, 'acls'))
30
+ end
31
+
32
+ def user_acls_path
33
+ @user_acls_path ||= ::File.expand_path(::File.join(@backup_path, 'user_acls'))
34
+ end
35
+
36
+ def cookbooks_path(org)
37
+ ::File.expand_path(::File.join(@backup_path, 'organizations', org, 'cookbooks'))
38
+ end
39
+
40
+ def org_path(org)
41
+ ::File.expand_path(::File.join(@backup_path, 'organizations', org))
42
+ end
43
+
44
+ def unique_email
45
+ (0...8).map { (65 + rand(26)).chr }.join.downcase +
46
+ '@' + (0...8).map { (65 + rand(26)).chr }.join.downcase + '.com'
47
+ end
48
+
49
+ def save_user(user)
50
+ ::File.open(::File.join(users_path, "#{user['username']}.json"), 'w+') do |f|
51
+ f.write(FFI_Yajl::Encoder.encode(user, pretty: true))
52
+ end
53
+ end
54
+
55
+ def write_new_file(contents, path)
56
+ FileUtils.cp(path, "#{path}.orig") unless ::File.exist?("#{path}.orig")
57
+ ::File.open(path, 'w+') do |f|
58
+ f.write(FFI_Yajl::Encoder.encode(contents, pretty: true))
59
+ end
60
+ end
61
+
62
+ def cookbook_name_from_path(path)
63
+ ::File.basename(path, '-*')
64
+ end
65
+
66
+ def global_user_names
67
+ @global_user_names ||= Dir[::File.join(@backup_path, 'users', '*')].map { |dir| ::File.basename(dir, '.json') }
68
+ end
69
+ end
70
+ end
@@ -9,15 +9,11 @@ class Chef
9
9
 
10
10
  attr_accessor :file_path, :backup_path, :data
11
11
 
12
- def initialize(file_path = nil, backup_path = nil)
12
+ def initialize(file_path = nil, tidy_common = nil)
13
13
  @file_path = file_path
14
- @backup_path = backup_path
14
+ @backup_path = tidy_common.backup_path if tidy_common
15
15
  end
16
16
 
17
- # Load the substitutions from disk
18
- #
19
- # @return [Hash]
20
- #
21
17
  def load_data
22
18
  Chef::Log.info "Loading substitutions from #{file_path}"
23
19
  @data = FFI_Yajl::Parser.parse(::File.read(@file_path), symbolize_names: false)
@@ -53,7 +49,7 @@ class Chef
53
49
  end
54
50
  end
55
51
  temp_file.close
56
- FileUtils.mv(path, "#{path}.orig") unless ::File.exist?("#{path}.orig")
52
+ FileUtils.cp(path, "#{path}.orig") unless ::File.exist?("#{path}.orig")
57
53
  FileUtils.mv(temp_file.path, path)
58
54
  ensure
59
55
  temp_file.close
@@ -66,7 +62,7 @@ class Chef
66
62
  @data.keys.each do |entry|
67
63
  @data[entry].keys.each do |glob|
68
64
  Chef::Log.info "Running substitutions for #{entry} -> #{glob}"
69
- Dir[::File.join(backup_path, glob)].each do |file|
65
+ Dir[::File.join(@backup_path, glob)].each do |file|
70
66
  @data[entry][glob].each do |substitution|
71
67
  search = Regexp.new(substitution['pattern'])
72
68
  replace = substitution['replace'].dup
@@ -1,4 +1,4 @@
1
1
  module KnifeTidy
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
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: 0.1.1
4
+ version: 0.2.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-08-12 00:00:00.000000000 Z
11
+ date: 2017-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -113,6 +113,8 @@ files:
113
113
  - lib/chef/knife/tidy_backup_clean.rb
114
114
  - lib/chef/knife/tidy_base.rb
115
115
  - lib/chef/knife/tidy_server_report.rb
116
+ - lib/chef/tidy_acls.rb
117
+ - lib/chef/tidy_common.rb
116
118
  - lib/chef/tidy_server.rb
117
119
  - lib/chef/tidy_substitutions.rb
118
120
  - lib/knife-tidy/version.rb