chef-dk 0.3.0 → 0.3.5
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 +4 -4
- data/README.md +5 -0
- data/lib/chef-dk/cli.rb +7 -5
- data/lib/chef-dk/command/generate.rb +2 -0
- data/lib/chef-dk/command/generator_commands.rb +8 -0
- data/lib/chef-dk/command/generator_commands/base.rb +4 -1
- data/lib/chef-dk/command/generator_commands/policyfile.rb +83 -0
- data/lib/chef-dk/command/install.rb +4 -5
- data/lib/chef-dk/command/push.rb +4 -5
- data/lib/chef-dk/command/verify.rb +3 -2
- data/lib/chef-dk/component_test.rb +7 -2
- data/lib/chef-dk/exceptions.rb +3 -34
- data/lib/chef-dk/helpers.rb +20 -2
- data/lib/chef-dk/policyfile/cookbook_locks.rb +19 -1
- data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +11 -1
- data/lib/chef-dk/policyfile/storage_config.rb +23 -0
- data/lib/chef-dk/policyfile/uploader.rb +1 -1
- data/lib/chef-dk/policyfile_services/install.rb +19 -32
- data/lib/chef-dk/policyfile_services/push.rb +17 -27
- data/lib/chef-dk/service_exception_inspectors.rb +25 -0
- data/lib/chef-dk/service_exception_inspectors/base.rb +40 -0
- data/lib/chef-dk/service_exception_inspectors/http.rb +121 -0
- data/lib/chef-dk/service_exceptions.rb +77 -0
- data/lib/chef-dk/skeletons/code_generator/recipes/policyfile.rb +8 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +16 -0
- data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +1 -1
- data/lib/chef-dk/version.rb +1 -1
- data/spec/unit/cli_spec.rb +126 -65
- data/spec/unit/command/exec_spec.rb +7 -2
- data/spec/unit/command/generator_commands/cookbook_spec.rb +27 -1
- data/spec/unit/command/generator_commands/policyfile_spec.rb +125 -0
- data/spec/unit/command/install_spec.rb +3 -4
- data/spec/unit/command/push_spec.rb +6 -7
- data/spec/unit/command/shell_init_spec.rb +5 -1
- data/spec/unit/cookbook_profiler/git_spec.rb +2 -2
- data/spec/unit/policyfile/cookbook_locks_spec.rb +58 -0
- data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +8 -1
- data/spec/unit/policyfile/storage_config_spec.rb +75 -1
- data/spec/unit/policyfile/uploader_spec.rb +31 -0
- data/spec/unit/policyfile_lock_validation_spec.rb +13 -12
- data/spec/unit/policyfile_services/install_spec.rb +5 -3
- data/spec/unit/policyfile_services/push_spec.rb +7 -5
- data/spec/unit/service_exception_inspectors/base_spec.rb +43 -0
- data/spec/unit/service_exception_inspectors/http_spec.rb +140 -0
- metadata +41 -2
@@ -16,6 +16,7 @@
|
|
16
16
|
#
|
17
17
|
|
18
18
|
require 'chef-dk/cookbook_omnifetch'
|
19
|
+
require 'chef-dk/exceptions'
|
19
20
|
|
20
21
|
module ChefDK
|
21
22
|
module Policyfile
|
@@ -37,23 +38,37 @@ module ChefDK
|
|
37
38
|
end
|
38
39
|
|
39
40
|
def use_policyfile(policyfile_filename)
|
41
|
+
unless policyfile_filename.end_with?(".rb")
|
42
|
+
raise InvalidPolicyfileFilename, "Policyfile filenames must end with `.rb' extension (you gave: `#{policyfile_filename}')"
|
43
|
+
end
|
40
44
|
@policyfile_filename = policyfile_filename
|
45
|
+
@policyfile_lock_filename = policyfile_filename.sub(/\.rb\Z/, '.lock.json')
|
41
46
|
@relative_paths_root = File.dirname(policyfile_filename)
|
42
47
|
self
|
43
48
|
end
|
44
49
|
|
45
50
|
def use_policyfile_lock(policyfile_lock_filename)
|
46
51
|
@policyfile_lock_filename = policyfile_lock_filename
|
52
|
+
@policyfile_filename = policyfile_lock_filename.sub(/\.lock\.json\Z/, '.rb')
|
47
53
|
@relative_paths_root = File.dirname(policyfile_lock_filename)
|
48
54
|
self
|
49
55
|
end
|
50
56
|
|
57
|
+
def policyfile_expanded_path
|
58
|
+
File.expand_path(policyfile_filename, relative_paths_root)
|
59
|
+
end
|
60
|
+
|
61
|
+
def policyfile_lock_expanded_path
|
62
|
+
File.expand_path(policyfile_lock_filename, relative_paths_root)
|
63
|
+
end
|
64
|
+
|
51
65
|
private
|
52
66
|
|
53
67
|
def handle_options(options)
|
54
68
|
@cache_path = options[:cache_path] if options[:cache_path]
|
55
69
|
@relative_paths_root = options[:relative_paths_root] if options.key?(:relative_paths_root)
|
56
70
|
end
|
71
|
+
|
57
72
|
end
|
58
73
|
|
59
74
|
module StorageConfigDelegation
|
@@ -70,6 +85,14 @@ module ChefDK
|
|
70
85
|
storage_config.policyfile_filename
|
71
86
|
end
|
72
87
|
|
88
|
+
def policyfile_expanded_path
|
89
|
+
storage_config.policyfile_expanded_path
|
90
|
+
end
|
91
|
+
|
92
|
+
def policyfile_lock_expanded_path
|
93
|
+
storage_config.policyfile_lock_expanded_path
|
94
|
+
end
|
95
|
+
|
73
96
|
end
|
74
97
|
|
75
98
|
end
|
@@ -119,7 +119,7 @@ module ChefDK
|
|
119
119
|
def upload_cookbooks
|
120
120
|
ui.msg("WARN: Uploading cookbooks using semver compat mode")
|
121
121
|
|
122
|
-
uploader.upload_cookbooks
|
122
|
+
uploader.upload_cookbooks unless cookbook_versions_to_upload.empty?
|
123
123
|
|
124
124
|
reused_cbs, uploaded_cbs = cookbook_versions_for_policy.partition do |cb_with_lock|
|
125
125
|
remote_already_has_cookbook?(cb_with_lock.cookbook)
|
@@ -15,7 +15,9 @@
|
|
15
15
|
# limitations under the License.
|
16
16
|
#
|
17
17
|
|
18
|
-
require '
|
18
|
+
require 'ffi_yajl'
|
19
|
+
|
20
|
+
require 'chef-dk/service_exceptions'
|
19
21
|
require 'chef-dk/policyfile_compiler'
|
20
22
|
require 'chef-dk/policyfile/storage_config'
|
21
23
|
require 'chef-dk/policyfile_lock'
|
@@ -25,54 +27,43 @@ module ChefDK
|
|
25
27
|
|
26
28
|
class Install
|
27
29
|
|
28
|
-
|
30
|
+
include Policyfile::StorageConfigDelegation
|
31
|
+
include ChefDK::Helpers
|
32
|
+
|
29
33
|
attr_reader :ui
|
34
|
+
attr_reader :storage_config
|
30
35
|
|
31
36
|
def initialize(policyfile: nil, ui: nil, root_dir: nil)
|
32
|
-
@policyfile_relative_path = policyfile
|
33
37
|
@ui = ui
|
34
|
-
|
38
|
+
|
39
|
+
policyfile_rel_path = policyfile || "Policyfile.rb"
|
40
|
+
policyfile_full_path = File.expand_path(policyfile_rel_path, root_dir)
|
41
|
+
@storage_config = Policyfile::StorageConfig.new.use_policyfile(policyfile_full_path)
|
35
42
|
|
36
43
|
@policyfile_content = nil
|
37
44
|
@policyfile_compiler = nil
|
38
45
|
end
|
39
46
|
|
40
47
|
def run
|
41
|
-
unless File.exist?(
|
48
|
+
unless File.exist?(policyfile_expanded_path)
|
42
49
|
# TODO: suggest next step. Add a generator/init command? Specify path to Policyfile.rb?
|
43
50
|
# See card CC-232
|
44
|
-
raise PolicyfileNotFound, "Policyfile not found at path #{
|
51
|
+
raise PolicyfileNotFound, "Policyfile not found at path #{policyfile_expanded_path}"
|
45
52
|
end
|
46
53
|
|
47
|
-
if File.exist?(
|
54
|
+
if File.exist?(policyfile_lock_expanded_path)
|
48
55
|
install_from_lock
|
49
56
|
else
|
50
57
|
generate_lock_and_install
|
51
58
|
end
|
52
59
|
end
|
53
60
|
|
54
|
-
def policyfile_relative_path
|
55
|
-
@policyfile_relative_path || "Policyfile.rb"
|
56
|
-
end
|
57
|
-
|
58
|
-
def policyfile_path
|
59
|
-
File.expand_path(policyfile_relative_path, root_dir)
|
60
|
-
end
|
61
|
-
|
62
|
-
def lockfile_relative_path
|
63
|
-
policyfile_relative_path.gsub(/\.rb\Z/, '') + ".lock.json"
|
64
|
-
end
|
65
|
-
|
66
|
-
def lockfile_path
|
67
|
-
File.expand_path(lockfile_relative_path, root_dir)
|
68
|
-
end
|
69
|
-
|
70
61
|
def policyfile_content
|
71
|
-
@policyfile_content ||= IO.read(
|
62
|
+
@policyfile_content ||= IO.read(policyfile_expanded_path)
|
72
63
|
end
|
73
64
|
|
74
65
|
def policyfile_compiler
|
75
|
-
@policyfile_compiler ||= ChefDK::PolicyfileCompiler.evaluate(policyfile_content,
|
66
|
+
@policyfile_compiler ||= ChefDK::PolicyfileCompiler.evaluate(policyfile_content, policyfile_expanded_path, ui: ui)
|
76
67
|
end
|
77
68
|
|
78
69
|
def expanded_run_list
|
@@ -80,7 +71,7 @@ module ChefDK
|
|
80
71
|
end
|
81
72
|
|
82
73
|
def policyfile_lock_content
|
83
|
-
@policyfile_lock_content ||= IO.read(
|
74
|
+
@policyfile_lock_content ||= IO.read(policyfile_lock_expanded_path) if File.exist?(policyfile_lock_expanded_path)
|
84
75
|
end
|
85
76
|
|
86
77
|
def policyfile_lock
|
@@ -91,10 +82,6 @@ module ChefDK
|
|
91
82
|
end
|
92
83
|
end
|
93
84
|
|
94
|
-
def storage_config
|
95
|
-
@storage_config ||= Policyfile::StorageConfig.new(relative_paths_root: root_dir)
|
96
|
-
end
|
97
|
-
|
98
85
|
def generate_lock_and_install
|
99
86
|
policyfile_compiler.error!
|
100
87
|
|
@@ -107,13 +94,13 @@ module ChefDK
|
|
107
94
|
|
108
95
|
lock_data = policyfile_compiler.lock.to_lock
|
109
96
|
|
110
|
-
|
97
|
+
with_file(policyfile_lock_expanded_path) do |f|
|
111
98
|
f.print(FFI_Yajl::Encoder.encode(lock_data, pretty: true ))
|
112
99
|
end
|
113
100
|
|
114
101
|
ui.msg ""
|
115
102
|
|
116
|
-
ui.msg "Lockfile written to #{
|
103
|
+
ui.msg "Lockfile written to #{policyfile_lock_expanded_path}"
|
117
104
|
rescue => error
|
118
105
|
raise PolicyfileInstallError.new("Failed to generate Policyfile.lock", error)
|
119
106
|
end
|
@@ -15,47 +15,41 @@
|
|
15
15
|
# limitations under the License.
|
16
16
|
#
|
17
17
|
|
18
|
+
require 'ffi_yajl'
|
19
|
+
|
20
|
+
require 'chef-dk/service_exceptions'
|
18
21
|
require 'chef-dk/authenticated_http'
|
19
22
|
require 'chef-dk/policyfile_compiler'
|
20
23
|
require 'chef-dk/policyfile/uploader'
|
24
|
+
require 'chef-dk/policyfile/storage_config'
|
21
25
|
|
22
26
|
module ChefDK
|
23
27
|
module PolicyfileServices
|
24
28
|
class Push
|
25
29
|
|
30
|
+
include Policyfile::StorageConfigDelegation
|
31
|
+
include ChefDK::Helpers
|
32
|
+
|
26
33
|
attr_reader :root_dir
|
27
34
|
attr_reader :config
|
28
35
|
attr_reader :policy_group
|
29
36
|
attr_reader :ui
|
37
|
+
attr_reader :storage_config
|
30
38
|
|
31
39
|
def initialize(policyfile: nil, ui: nil, policy_group: nil, config: nil, root_dir: nil)
|
32
40
|
@root_dir = root_dir
|
33
|
-
@policyfile_relative_path = policyfile
|
34
41
|
@ui = ui
|
35
42
|
@config = config
|
36
43
|
@policy_group = policy_group
|
37
44
|
|
45
|
+
policyfile_rel_path = policyfile || "Policyfile.rb"
|
46
|
+
policyfile_full_path = File.expand_path(policyfile_rel_path, root_dir)
|
47
|
+
@storage_config = Policyfile::StorageConfig.new.use_policyfile(policyfile_full_path)
|
48
|
+
|
38
49
|
@http_client = nil
|
39
|
-
@storage_config = nil
|
40
50
|
@policy_data = nil
|
41
51
|
end
|
42
52
|
|
43
|
-
def policyfile_relative_path
|
44
|
-
@policyfile_relative_path || "Policyfile.rb"
|
45
|
-
end
|
46
|
-
|
47
|
-
def policyfile_path
|
48
|
-
File.expand_path(policyfile_relative_path, root_dir)
|
49
|
-
end
|
50
|
-
|
51
|
-
def lockfile_relative_path
|
52
|
-
policyfile_relative_path.gsub(/\.rb\Z/, '') + ".lock.json"
|
53
|
-
end
|
54
|
-
|
55
|
-
def lockfile_path
|
56
|
-
File.expand_path(lockfile_relative_path, root_dir)
|
57
|
-
end
|
58
|
-
|
59
53
|
def http_client
|
60
54
|
@http_client ||= ChefDK::AuthenticatedHTTP.new(config.chef_server_url,
|
61
55
|
signing_key_filename: config.client_key,
|
@@ -63,13 +57,9 @@ module ChefDK
|
|
63
57
|
end
|
64
58
|
|
65
59
|
def policy_data
|
66
|
-
@policy_data ||= FFI_Yajl::Parser.parse(IO.read(
|
60
|
+
@policy_data ||= FFI_Yajl::Parser.parse(IO.read(policyfile_lock_expanded_path))
|
67
61
|
rescue => error
|
68
|
-
raise PolicyfilePushError.new("Error reading lockfile #{
|
69
|
-
end
|
70
|
-
|
71
|
-
def storage_config
|
72
|
-
@storage_config ||= ChefDK::Policyfile::StorageConfig.new.use_policyfile_lock(lockfile_path)
|
62
|
+
raise PolicyfilePushError.new("Error reading lockfile #{policyfile_lock_expanded_path}", error)
|
73
63
|
end
|
74
64
|
|
75
65
|
def uploader
|
@@ -77,8 +67,8 @@ module ChefDK
|
|
77
67
|
end
|
78
68
|
|
79
69
|
def run
|
80
|
-
unless File.exist?(
|
81
|
-
raise LockfileNotFound, "No lockfile at #{
|
70
|
+
unless File.exist?(policyfile_lock_expanded_path)
|
71
|
+
raise LockfileNotFound, "No lockfile at #{policyfile_lock_expanded_path} - you need to run `install` before `push`"
|
82
72
|
end
|
83
73
|
|
84
74
|
validate_lockfile
|
@@ -100,7 +90,7 @@ module ChefDK
|
|
100
90
|
end
|
101
91
|
|
102
92
|
def write_updated_lockfile
|
103
|
-
|
93
|
+
with_file(policyfile_lock_expanded_path) do |f|
|
104
94
|
f.print(FFI_Yajl::Encoder.encode(policyfile_lock.to_lock, pretty: true ))
|
105
95
|
end
|
106
96
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2014 Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'chef-dk/service_exception_inspectors/base'
|
19
|
+
require 'chef-dk/service_exception_inspectors/http'
|
20
|
+
|
21
|
+
module ChefDK
|
22
|
+
module ServiceExceptionInspectors
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2014 Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
module ChefDK
|
19
|
+
module ServiceExceptionInspectors
|
20
|
+
|
21
|
+
class Base
|
22
|
+
|
23
|
+
attr_reader :exception
|
24
|
+
|
25
|
+
def initialize(exception)
|
26
|
+
@exception = exception
|
27
|
+
end
|
28
|
+
|
29
|
+
def message
|
30
|
+
exception.message
|
31
|
+
end
|
32
|
+
|
33
|
+
def extended_error_info
|
34
|
+
""
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2014 Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'ffi_yajl'
|
19
|
+
|
20
|
+
module ChefDK
|
21
|
+
module ServiceExceptionInspectors
|
22
|
+
class HTTP
|
23
|
+
|
24
|
+
attr_reader :exception
|
25
|
+
|
26
|
+
def initialize(exception)
|
27
|
+
@exception = exception
|
28
|
+
end
|
29
|
+
|
30
|
+
def message
|
31
|
+
"HTTP #{code} #{response_message}: " + parsed_response_body
|
32
|
+
end
|
33
|
+
|
34
|
+
def extended_error_info
|
35
|
+
<<-END
|
36
|
+
--- REQUEST DATA ----
|
37
|
+
#{http_method} #{uri}
|
38
|
+
#{request_headers}
|
39
|
+
#{req_body}
|
40
|
+
|
41
|
+
--- RESPONSE DATA ---
|
42
|
+
#{code} #{response_message}
|
43
|
+
#{response_headers}
|
44
|
+
|
45
|
+
#{response_body}
|
46
|
+
|
47
|
+
END
|
48
|
+
end
|
49
|
+
|
50
|
+
def response
|
51
|
+
exception.response
|
52
|
+
end
|
53
|
+
|
54
|
+
def code
|
55
|
+
response.code
|
56
|
+
end
|
57
|
+
|
58
|
+
def response_message
|
59
|
+
response.message
|
60
|
+
end
|
61
|
+
|
62
|
+
def response_body
|
63
|
+
response.body
|
64
|
+
end
|
65
|
+
|
66
|
+
def parsed_response_body
|
67
|
+
if response_body && !response_body.empty?
|
68
|
+
attempt_error_message_extract
|
69
|
+
else
|
70
|
+
"(No explanation provided by server)"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def attempt_error_message_extract
|
75
|
+
error_body = FFI_Yajl::Parser.parse(response_body)
|
76
|
+
if error_body.respond_to?(:key?) && error_body.key?("error")
|
77
|
+
Array(error_body["error"]).join(", ")
|
78
|
+
else
|
79
|
+
error_body.to_s
|
80
|
+
end
|
81
|
+
rescue
|
82
|
+
response_body
|
83
|
+
end
|
84
|
+
|
85
|
+
def response_headers
|
86
|
+
headers_s = ""
|
87
|
+
response.each_header do |key, value|
|
88
|
+
headers_s << key << ": " << value << "\n"
|
89
|
+
end
|
90
|
+
headers_s
|
91
|
+
end
|
92
|
+
|
93
|
+
def request
|
94
|
+
exception.chef_rest_request
|
95
|
+
end
|
96
|
+
|
97
|
+
def uri
|
98
|
+
request.uri.to_s + request.path.to_s
|
99
|
+
end
|
100
|
+
|
101
|
+
def http_method
|
102
|
+
request.method
|
103
|
+
end
|
104
|
+
|
105
|
+
def request_headers
|
106
|
+
headers_s = ""
|
107
|
+
request.each_header do |key, value|
|
108
|
+
headers_s << key << ": " << value << "\n"
|
109
|
+
end
|
110
|
+
headers_s
|
111
|
+
end
|
112
|
+
|
113
|
+
def req_body
|
114
|
+
request.body
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|