knife-essentials 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. data/lib/chef/knife/diff_essentials.rb +2 -5
  2. data/lib/chef/knife/raw_essentials.rb +2 -2
  3. data/lib/chef_fs/command_line.rb +98 -79
  4. data/lib/chef_fs/data_handler/acl_data_handler.rb +22 -0
  5. data/lib/chef_fs/data_handler/container_data_handler.rb +20 -0
  6. data/lib/chef_fs/data_handler/group_data_handler.rb +33 -0
  7. data/lib/chef_fs/data_handler/user_data_handler.rb +6 -1
  8. data/lib/chef_fs/file_system/acl_dir.rb +62 -0
  9. data/lib/chef_fs/file_system/acl_entry.rb +54 -0
  10. data/lib/chef_fs/file_system/acls_dir.rb +66 -0
  11. data/lib/chef_fs/file_system/base_fs_object.rb +0 -74
  12. data/lib/chef_fs/file_system/chef_repository_file_system_root_dir.rb +9 -0
  13. data/lib/chef_fs/file_system/chef_server_root_dir.rb +21 -2
  14. data/lib/chef_fs/file_system/cookbook_dir.rb +1 -1
  15. data/lib/chef_fs/file_system/cookbooks_acl_dir.rb +39 -0
  16. data/lib/chef_fs/file_system/cookbooks_dir.rb +3 -2
  17. data/lib/chef_fs/file_system/data_bags_dir.rb +1 -5
  18. data/lib/chef_fs/file_system/nodes_dir.rb +13 -3
  19. data/lib/chef_fs/file_system/rest_list_dir.rb +5 -7
  20. data/lib/chef_fs/file_system/rest_list_entry.rb +18 -18
  21. data/lib/chef_fs/knife.rb +7 -4
  22. data/lib/chef_fs/raw_request.rb +73 -0
  23. data/lib/chef_fs/version.rb +1 -1
  24. data/spec/support/integration_helper.rb +12 -1
  25. metadata +10 -6
  26. data/spec/chef_fs/file_system/chef_server_root_dir_spec.rb +0 -252
  27. data/spec/chef_fs/file_system/cookbook_dir_spec.rb +0 -582
  28. data/spec/chef_fs/file_system/cookbooks_dir_spec.rb +0 -165
  29. data/spec/chef_fs/file_system/data_bags_dir_spec.rb +0 -235
data/lib/chef_fs/knife.rb CHANGED
@@ -27,7 +27,7 @@ module ChefFS
27
27
  def self.common_options
28
28
  option :repo_mode,
29
29
  :long => '--repo-mode MODE',
30
- :description => "Specifies the local repository layout. Values: default or everything"
30
+ :description => "Specifies the local repository layout. Values: default, everything, hosted_everything"
31
31
 
32
32
  option :chef_repo_path,
33
33
  :long => '--chef-repo-path PATH',
@@ -39,7 +39,7 @@ module ChefFS
39
39
  Chef::Config[:repo_mode] = config[:repo_mode] if config[:repo_mode]
40
40
 
41
41
  # --chef-repo-path overrides all other paths
42
- path_variables = %w(client_path cookbook_path data_bag_path environment_path node_path role_path user_path)
42
+ path_variables = %w(acl_path client_path cookbook_path container_path data_bag_path environment_path group_path node_path role_path user_path)
43
43
  if config[:chef_repo_path]
44
44
  Chef::Config[:chef_repo_path] = config[:chef_repo_path]
45
45
  path_variables.each do |variable_name|
@@ -79,7 +79,7 @@ module ChefFS
79
79
  end
80
80
 
81
81
  def chef_fs
82
- @chef_fs ||= ChefFS::FileSystem::ChefServerRootDir.new("remote", Chef::Config, Chef::Config[:repo_mode])
82
+ @chef_fs ||= ChefFS::FileSystem::ChefServerRootDir.new("remote", Chef::Config)
83
83
  end
84
84
 
85
85
  def object_paths
@@ -90,8 +90,11 @@ module ChefFS
90
90
  end
91
91
 
92
92
  result = {}
93
- if Chef::Config[:repo_mode] == 'everything'
93
+ case Chef::Config[:repo_mode]
94
+ when 'everything'
94
95
  object_names = %w(clients cookbooks data_bags environments nodes roles users)
96
+ when 'hosted_everything'
97
+ object_names = %w(acls clients cookbooks containers data_bags environments groups nodes roles)
95
98
  else
96
99
  object_names = %w(cookbooks data_bags environments roles)
97
100
  end
@@ -0,0 +1,73 @@
1
+ module ChefFS
2
+ module RawRequest
3
+ def self.raw_json(chef_rest, api_path)
4
+ JSON.parse(raw_request(chef_rest, api_path), :create_additions => false)
5
+ end
6
+
7
+ def self.raw_request(chef_rest, api_path)
8
+ api_request(chef_rest, :GET, chef_rest.create_url(api_path), {}, false)
9
+ end
10
+
11
+ def self.api_request(chef_rest, method, url, headers={}, data=false)
12
+ json_body = data
13
+ # json_body = data ? Chef::JSONCompat.to_json(data) : nil
14
+ # Force encoding to binary to fix SSL related EOFErrors
15
+ # cf. http://tickets.opscode.com/browse/CHEF-2363
16
+ # http://redmine.ruby-lang.org/issues/5233
17
+ # json_body.force_encoding(Encoding::BINARY) if json_body.respond_to?(:force_encoding)
18
+ headers = build_headers(chef_rest, method, url, headers, json_body)
19
+
20
+ chef_rest.retriable_rest_request(method, url, json_body, headers) do |rest_request|
21
+ response = rest_request.call {|r| r.read_body}
22
+
23
+ response_body = chef_rest.decompress_body(response)
24
+
25
+ if response.kind_of?(Net::HTTPSuccess)
26
+ response_body
27
+ elsif redirect_location = redirected_to(response)
28
+ raise "Redirected to #{create_url(redirect_location)}"
29
+ follow_redirect {api_request(:GET, create_url(redirect_location))}
30
+ else
31
+ # have to decompress the body before making an exception for it. But the body could be nil.
32
+ response.body.replace(chef_rest.decompress_body(response)) if response.body.respond_to?(:replace)
33
+
34
+ if response['content-type'] =~ /json/
35
+ exception = response_body
36
+ msg = "HTTP Request Returned #{response.code} #{response.message}: "
37
+ msg << (exception["error"].respond_to?(:join) ? exception["error"].join(", ") : exception["error"].to_s)
38
+ Chef::Log.info(msg)
39
+ end
40
+ response.error!
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ # Copied so that it does not automatically inflate an object
48
+ # This is also used by knife raw_essentials
49
+
50
+ ACCEPT_ENCODING = "Accept-Encoding".freeze
51
+ ENCODING_GZIP_DEFLATE = "gzip;q=1.0,deflate;q=0.6,identity;q=0.3".freeze
52
+
53
+ def self.redirected_to(response)
54
+ return nil unless response.kind_of?(Net::HTTPRedirection)
55
+ # Net::HTTPNotModified is undesired subclass of Net::HTTPRedirection so test for this
56
+ return nil if response.kind_of?(Net::HTTPNotModified)
57
+ response['location']
58
+ end
59
+
60
+
61
+ def self.build_headers(chef_rest, method, url, headers={}, json_body=false, raw=false)
62
+ # headers = @default_headers.merge(headers)
63
+ #headers['Accept'] = "application/json" unless raw
64
+ headers['Accept'] = "application/json" unless raw
65
+ headers["Content-Type"] = 'application/json' if json_body
66
+ headers['Content-Length'] = json_body.bytesize.to_s if json_body
67
+ headers[Chef::REST::RESTRequest::ACCEPT_ENCODING] = Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE
68
+ headers.merge!(chef_rest.authentication_headers(method, url, json_body)) if chef_rest.sign_requests?
69
+ headers.merge!(Chef::Config[:custom_http_headers]) if Chef::Config[:custom_http_headers]
70
+ headers
71
+ end
72
+ end
73
+ end
@@ -1,3 +1,3 @@
1
1
  module ChefFS
2
- VERSION = "0.9.4"
2
+ VERSION = "0.9.5"
3
3
  end
@@ -28,7 +28,18 @@ require 'support/spec_helper'
28
28
  module IntegrationSupport
29
29
  include ChefZero::RSpec
30
30
 
31
- # Integration DSL
31
+ def self.extended(base)
32
+ base.before :each do
33
+ @old_repo_mode = nil
34
+ @old_versioned_cookbooks = nil
35
+ Chef::Config.repo_mode = nil
36
+ Chef::Config.versioned_cookbooks = nil
37
+ end
38
+ base.after :each do
39
+ Chef::Config.repo_mode = @old_repo_mode
40
+ Chef::Config.versioned_cookbooks = @old_versioned_cookbooks
41
+ end
42
+ end
32
43
 
33
44
  def when_the_repository(description, *args, &block)
34
45
  context "When the local repository #{description}", *args do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-essentials
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-13 00:00:00.000000000 Z
12
+ date: 2013-03-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: chef-zero
@@ -63,15 +63,21 @@ files:
63
63
  - lib/chef/knife/show_essentials.rb
64
64
  - lib/chef/knife/upload_essentials.rb
65
65
  - lib/chef_fs/command_line.rb
66
+ - lib/chef_fs/data_handler/acl_data_handler.rb
66
67
  - lib/chef_fs/data_handler/client_data_handler.rb
68
+ - lib/chef_fs/data_handler/container_data_handler.rb
67
69
  - lib/chef_fs/data_handler/cookbook_data_handler.rb
68
70
  - lib/chef_fs/data_handler/data_bag_item_data_handler.rb
69
71
  - lib/chef_fs/data_handler/data_handler_base.rb
70
72
  - lib/chef_fs/data_handler/environment_data_handler.rb
73
+ - lib/chef_fs/data_handler/group_data_handler.rb
71
74
  - lib/chef_fs/data_handler/node_data_handler.rb
72
75
  - lib/chef_fs/data_handler/role_data_handler.rb
73
76
  - lib/chef_fs/data_handler/user_data_handler.rb
74
77
  - lib/chef_fs/file_pattern.rb
78
+ - lib/chef_fs/file_system/acl_dir.rb
79
+ - lib/chef_fs/file_system/acl_entry.rb
80
+ - lib/chef_fs/file_system/acls_dir.rb
75
81
  - lib/chef_fs/file_system/base_fs_dir.rb
76
82
  - lib/chef_fs/file_system/base_fs_object.rb
77
83
  - lib/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb
@@ -82,6 +88,7 @@ files:
82
88
  - lib/chef_fs/file_system/cookbook_dir.rb
83
89
  - lib/chef_fs/file_system/cookbook_file.rb
84
90
  - lib/chef_fs/file_system/cookbook_subdir.rb
91
+ - lib/chef_fs/file_system/cookbooks_acl_dir.rb
85
92
  - lib/chef_fs/file_system/cookbooks_dir.rb
86
93
  - lib/chef_fs/file_system/data_bag_dir.rb
87
94
  - lib/chef_fs/file_system/data_bag_item.rb
@@ -103,14 +110,11 @@ files:
103
110
  - lib/chef_fs/file_system.rb
104
111
  - lib/chef_fs/knife.rb
105
112
  - lib/chef_fs/path_utils.rb
113
+ - lib/chef_fs/raw_request.rb
106
114
  - lib/chef_fs/version.rb
107
115
  - lib/chef_fs.rb
108
116
  - spec/chef_fs/diff_spec.rb
109
117
  - spec/chef_fs/file_pattern_spec.rb
110
- - spec/chef_fs/file_system/chef_server_root_dir_spec.rb
111
- - spec/chef_fs/file_system/cookbook_dir_spec.rb
112
- - spec/chef_fs/file_system/cookbooks_dir_spec.rb
113
- - spec/chef_fs/file_system/data_bags_dir_spec.rb
114
118
  - spec/chef_fs/file_system_spec.rb
115
119
  - spec/integration/chef_repo_path_spec.rb
116
120
  - spec/integration/chef_repository_file_system_spec.rb
@@ -1,252 +0,0 @@
1
- #
2
- # Author:: John Keiser (<jkeiser@opscode.com>)
3
- # Copyright:: Copyright (c) 2012 Opscode, Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require 'support/spec_helper'
20
- require 'chef_fs/file_system/chef_server_root_dir'
21
-
22
- describe ChefFS::FileSystem::ChefServerRootDir do
23
-
24
- let(:should_receive_children) { endpoint.should_receive(:chef_collection).once.and_return(chef_collection) }
25
- let(:should_receive_read) { endpoint_leaf.should_receive(:chef_hash).once.and_return(chef_hash) }
26
- let(:should_throw_404) do
27
- nonexistent_child.should_receive(:raw_request).
28
- with("#{endpoint_name}/blah").
29
- once.and_raise(Net::HTTPServerException.new(nil,Net::HTTPResponse.new(nil,'404',nil)))
30
- end
31
-
32
- let(:chef_collection) do
33
- {
34
- "achild" => "http://opscode.com/achild",
35
- "bchild" => "http://opscode.com/bchild"
36
- }
37
- end
38
-
39
- let(:chef_hash) { { 'a' => 'b' } }
40
-
41
- shared_examples 'a json endpoint dir leaf' do
42
- it 'parent is endpoint' do
43
- endpoint_leaf.parent.should == endpoint
44
- end
45
- it 'name is correct' do
46
- endpoint_leaf.name.should == "#{endpoint_leaf_name}.json"
47
- end
48
- it 'path is correct' do
49
- endpoint_leaf.path.should == "/#{endpoint_name}/#{endpoint_leaf_name}.json"
50
- end
51
- it 'path_for_printing is correct' do
52
- endpoint_leaf.path_for_printing.should == "remote/#{endpoint_name}/#{endpoint_leaf_name}.json"
53
- end
54
- it 'is not a directory' do
55
- endpoint_leaf.dir?.should be_false
56
- end
57
- it 'exists' do
58
- should_receive_children
59
- endpoint_leaf.exists?.should be_true
60
- end
61
- it 'read returns content' do
62
- should_receive_read
63
- endpoint_leaf.read.should == '{
64
- "name": "achild",
65
- "a": "b"
66
- }'
67
- end
68
- end
69
-
70
-
71
- shared_examples 'a json rest endpoint dir' do
72
- it 'parent is root' do
73
- endpoint.parent.should == root_dir
74
- end
75
- it 'has correct name' do
76
- endpoint.name.should == endpoint_name
77
- end
78
- it 'has correct path' do
79
- endpoint.path.should == "/#{endpoint_name}"
80
- end
81
- it 'has correct path_for_printing' do
82
- endpoint.path_for_printing.should == "remote/#{endpoint_name}"
83
- end
84
- it 'is a directory' do
85
- endpoint.dir?.should be_true
86
- end
87
- it 'exists' do
88
- endpoint.exists?.should be_true
89
- end
90
- it 'can have json files as children' do
91
- endpoint.can_have_child?('blah.json', false).should be_true
92
- end
93
- it 'cannot have non-json files as children' do
94
- endpoint.can_have_child?('blah', false).should be_false
95
- end
96
- it 'cannot have directories as children' do
97
- endpoint.can_have_child?('blah', true).should be_false
98
- endpoint.can_have_child?('blah.json', true).should be_false
99
- end
100
-
101
-
102
- it 'has correct children' do
103
- should_receive_children
104
- endpoint.children.map { |child| child.name }.should =~ %w(achild.json bchild.json)
105
- end
106
-
107
- context 'achild in endpoint.children' do
108
- let(:endpoint_leaf_name) { 'achild' }
109
- let(:endpoint_leaf) do
110
- should_receive_children
111
- endpoint.children.select { |child| child.name == 'achild.json' }.first
112
- end
113
- it_behaves_like 'a json endpoint dir leaf'
114
- end
115
- context 'endpoint.child(achild)' do
116
- let(:endpoint_leaf_name) { 'achild' }
117
- let(:endpoint_leaf) { endpoint.child('achild.json') }
118
- it_behaves_like 'a json endpoint dir leaf'
119
- end
120
- context 'nonexistent child()' do
121
- let(:nonexistent_child) { endpoint.child('blah.json') }
122
- it 'has correct parent, name, path and path_for_printing' do
123
- nonexistent_child.parent.should == endpoint
124
- nonexistent_child.name.should == "blah.json"
125
- nonexistent_child.path.should == "#{endpoint.path}/blah.json"
126
- nonexistent_child.path_for_printing.should == "#{endpoint.path_for_printing}/blah.json"
127
- end
128
- it 'does not exist' do
129
- should_receive_children
130
- nonexistent_child.exists?.should be_false
131
- end
132
- it 'is not a directory' do
133
- nonexistent_child.dir?.should be_false
134
- end
135
- it 'read returns NotFoundError' do
136
- should_throw_404
137
- expect { nonexistent_child.read }.to raise_error(ChefFS::FileSystem::NotFoundError)
138
- end
139
- end
140
- end
141
-
142
- let(:root_dir) {
143
- ChefFS::FileSystem::ChefServerRootDir.new('remote',
144
- {
145
- :chef_server_url => 'url',
146
- :node_name => 'username',
147
- :client_key => 'key'
148
- }, 'everything')
149
- }
150
-
151
- before(:each) do
152
- @rest = double("rest")
153
- Chef::REST.stub(:new).with('url','username','key') { @rest }
154
- end
155
-
156
- context 'the root directory' do
157
- it 'has no parent' do
158
- root_dir.parent.should == nil
159
- end
160
- it 'is a directory' do
161
- root_dir.dir?.should be_true
162
- end
163
- it 'exists' do
164
- root_dir.exists?.should be_true
165
- end
166
- it 'has name ""' do
167
- root_dir.name.should == ""
168
- end
169
- it 'has path /' do
170
- root_dir.path.should == '/'
171
- end
172
- it 'has path_for_printing remote/' do
173
- root_dir.path_for_printing.should == 'remote/'
174
- end
175
- it 'has correct children' do
176
- root_dir.children.map { |child| child.name }.should =~ %w(clients cookbooks data_bags environments nodes roles users)
177
- end
178
- it 'can have children with the known names' do
179
- %w(clients cookbooks data_bags environments nodes roles users).each { |child| root_dir.can_have_child?(child, true).should be_true }
180
- end
181
- it 'cannot have files as children' do
182
- %w(clients cookbooks data_bags environments nodes roles users).each { |child| root_dir.can_have_child?(child, false).should be_false }
183
- root_dir.can_have_child?('blah', false).should be_false
184
- end
185
- it 'cannot have other child directories than the known names' do
186
- root_dir.can_have_child?('blah', true).should be_false
187
- end
188
- it 'child() responds to children' do
189
- %w(clients cookbooks data_bags environments nodes roles users).each { |child| root_dir.child(child).exists?.should be_true }
190
- end
191
- context 'nonexistent child()' do
192
- let(:nonexistent_child) { root_dir.child('blah') }
193
- it 'has correct parent, name, path and path_for_printing' do
194
- nonexistent_child.parent.should == root_dir
195
- nonexistent_child.name.should == "blah"
196
- nonexistent_child.path.should == "/blah"
197
- nonexistent_child.path_for_printing.should == "remote/blah"
198
- end
199
- it 'does not exist' do
200
- nonexistent_child.exists?.should be_false
201
- end
202
- it 'is not a directory' do
203
- nonexistent_child.dir?.should be_false
204
- end
205
- it 'read returns NotFoundError' do
206
- expect { nonexistent_child.read }.to raise_error(ChefFS::FileSystem::NotFoundError)
207
- end
208
- end
209
- end
210
-
211
- context 'clients in children' do
212
- let(:endpoint_name) { 'clients' }
213
- let(:endpoint) { root_dir.children.select { |child| child.name == 'clients' }.first }
214
-
215
- it_behaves_like 'a json rest endpoint dir'
216
- end
217
-
218
- context 'root.child(clients)' do
219
- let(:endpoint_name) { 'clients' }
220
- let(:endpoint) { root_dir.child('clients') }
221
-
222
- it_behaves_like 'a json rest endpoint dir'
223
- end
224
-
225
- context 'root.child(environments)' do
226
- let(:endpoint_name) { 'environments' }
227
- let(:endpoint) { root_dir.child('environments') }
228
-
229
- it_behaves_like 'a json rest endpoint dir'
230
- end
231
-
232
- context 'root.child(nodes)' do
233
- let(:endpoint_name) { 'nodes' }
234
- let(:endpoint) { root_dir.child('nodes') }
235
-
236
- it_behaves_like 'a json rest endpoint dir'
237
- end
238
-
239
- context 'root.child(roles)' do
240
- let(:endpoint_name) { 'roles' }
241
- let(:endpoint) { root_dir.child('roles') }
242
-
243
- it_behaves_like 'a json rest endpoint dir'
244
- end
245
-
246
- context 'root.child(users)' do
247
- let(:endpoint_name) { 'users' }
248
- let(:endpoint) { root_dir.child('users') }
249
-
250
- it_behaves_like 'a json rest endpoint dir'
251
- end
252
- end