chef-dk 2.3.4 → 2.4.17
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/Gemfile +22 -18
- data/Gemfile.lock +184 -254
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/acceptance/Gemfile.lock +27 -32
- data/lib/chef-dk/chef_server_api_multi.rb +73 -0
- data/lib/chef-dk/command/update.rb +5 -12
- data/lib/chef-dk/configurable.rb +19 -0
- data/lib/chef-dk/cookbook_omnifetch.rb +1 -0
- data/lib/chef-dk/exceptions.rb +11 -0
- data/lib/chef-dk/generator.rb +1 -1
- data/lib/chef-dk/policyfile/attribute_merge_checker.rb +110 -0
- data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +5 -4
- data/lib/chef-dk/policyfile/chef_server_lock_fetcher.rb +164 -0
- data/lib/chef-dk/policyfile/cookbook_location_specification.rb +3 -3
- data/lib/chef-dk/policyfile/dsl.rb +16 -0
- data/lib/chef-dk/policyfile/included_policies_cookbook_source.rb +156 -0
- data/lib/chef-dk/policyfile/local_lock_fetcher.rb +122 -0
- data/lib/chef-dk/policyfile/lock_applier.rb +80 -0
- data/lib/chef-dk/policyfile/null_cookbook_source.rb +4 -0
- data/lib/chef-dk/policyfile/policyfile_location_specification.rb +122 -0
- data/lib/chef-dk/policyfile_compiler.rb +129 -16
- data/lib/chef-dk/policyfile_lock.rb +30 -0
- data/lib/chef-dk/policyfile_services/install.rb +7 -1
- data/lib/chef-dk/policyfile_services/update_attributes.rb +10 -2
- data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +14 -1
- data/lib/chef-dk/version.rb +1 -1
- data/omnibus_overrides.rb +6 -6
- data/spec/unit/chef_server_api_multi_spec.rb +120 -0
- data/spec/unit/command/update_spec.rb +3 -3
- data/spec/unit/configurable_spec.rb +27 -0
- data/spec/unit/policyfile/attribute_merge_checker_spec.rb +80 -0
- data/spec/unit/policyfile/chef_server_lock_fetcher_spec.rb +161 -0
- data/spec/unit/policyfile/cookbook_location_specification_spec.rb +48 -0
- data/spec/unit/policyfile/included_policies_cookbook_source_spec.rb +242 -0
- data/spec/unit/policyfile/local_lock_fetcher_spec.rb +161 -0
- data/spec/unit/policyfile/lock_applier_spec.rb +100 -0
- data/spec/unit/policyfile_demands_spec.rb +1 -1
- data/spec/unit/policyfile_includes_dsl_spec.rb +159 -0
- data/spec/unit/policyfile_includes_spec.rb +720 -0
- data/spec/unit/policyfile_install_with_includes_spec.rb +232 -0
- data/spec/unit/policyfile_lock_build_spec.rb +11 -2
- data/spec/unit/policyfile_services/update_attributes_spec.rb +13 -0
- metadata +28 -3
|
@@ -115,9 +115,9 @@ module ChefDK
|
|
|
115
115
|
|
|
116
116
|
def update_lock_and_install(cookbooks_to_update)
|
|
117
117
|
ui.msg "Updating #{cookbooks_to_update.join(',')} cookbooks"
|
|
118
|
-
|
|
119
118
|
to_update = policyfile_lock.solution_dependencies.transitive_deps(cookbooks_to_update)
|
|
120
119
|
prepare_constraints_for_update(to_update)
|
|
120
|
+
prepare_constraints_for_policies
|
|
121
121
|
generate_lock_and_install
|
|
122
122
|
end
|
|
123
123
|
|
|
@@ -139,6 +139,12 @@ module ChefDK
|
|
|
139
139
|
end
|
|
140
140
|
end
|
|
141
141
|
|
|
142
|
+
def prepare_constraints_for_policies
|
|
143
|
+
Policyfile::LockApplier.
|
|
144
|
+
new(policyfile_lock, policyfile_compiler).
|
|
145
|
+
apply!
|
|
146
|
+
end
|
|
147
|
+
|
|
142
148
|
def install_from_lock
|
|
143
149
|
ui.msg "Installing cookbooks from lock"
|
|
144
150
|
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
require "chef-dk/helpers"
|
|
19
19
|
require "chef-dk/policyfile/storage_config"
|
|
20
|
+
require "chef-dk/policyfile/lock_applier"
|
|
20
21
|
require "chef-dk/service_exceptions"
|
|
21
22
|
require "chef-dk/policyfile_compiler"
|
|
22
23
|
|
|
@@ -30,18 +31,21 @@ module ChefDK
|
|
|
30
31
|
|
|
31
32
|
attr_reader :ui
|
|
32
33
|
attr_reader :storage_config
|
|
34
|
+
attr_reader :chef_config
|
|
33
35
|
|
|
34
|
-
def initialize(policyfile: nil, ui: nil, root_dir: nil)
|
|
36
|
+
def initialize(policyfile: nil, ui: nil, root_dir: nil, chef_config: nil)
|
|
35
37
|
@ui = ui
|
|
36
38
|
|
|
37
39
|
policyfile_rel_path = policyfile || "Policyfile.rb"
|
|
38
40
|
policyfile_full_path = File.expand_path(policyfile_rel_path, root_dir)
|
|
39
41
|
@storage_config = Policyfile::StorageConfig.new.use_policyfile(policyfile_full_path)
|
|
40
42
|
@updated = false
|
|
43
|
+
@chef_config = chef_config
|
|
41
44
|
end
|
|
42
45
|
|
|
43
46
|
def run
|
|
44
47
|
assert_policy_and_lock_present!
|
|
48
|
+
prepare_constraints
|
|
45
49
|
|
|
46
50
|
if policyfile_compiler.default_attributes != policyfile_lock.default_attributes
|
|
47
51
|
policyfile_lock.default_attributes = policyfile_compiler.default_attributes
|
|
@@ -74,7 +78,7 @@ module ChefDK
|
|
|
74
78
|
end
|
|
75
79
|
|
|
76
80
|
def policyfile_compiler
|
|
77
|
-
@policyfile_compiler ||= ChefDK::PolicyfileCompiler.evaluate(policyfile_content, policyfile_expanded_path, ui: ui)
|
|
81
|
+
@policyfile_compiler ||= ChefDK::PolicyfileCompiler.evaluate(policyfile_content, policyfile_expanded_path, ui: ui, chef_config: chef_config)
|
|
78
82
|
end
|
|
79
83
|
|
|
80
84
|
def policyfile_lock_content
|
|
@@ -97,6 +101,10 @@ module ChefDK
|
|
|
97
101
|
end
|
|
98
102
|
end
|
|
99
103
|
|
|
104
|
+
def prepare_constraints
|
|
105
|
+
Policyfile::LockApplier.new(policyfile_lock, policyfile_compiler).
|
|
106
|
+
apply!
|
|
107
|
+
end
|
|
100
108
|
end
|
|
101
109
|
end
|
|
102
110
|
end
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
require 'spec_helper'
|
|
8
8
|
|
|
9
9
|
describe '<%= cookbook_name %>::<%= recipe_name %>' do
|
|
10
|
-
context 'When all attributes are default, on
|
|
10
|
+
context 'When all attributes are default, on Ubuntu 16.04' do
|
|
11
11
|
let(:chef_run) do
|
|
12
12
|
# for a complete list of available platforms and versions see:
|
|
13
13
|
# https://github.com/customink/fauxhai/blob/master/PLATFORMS.md
|
|
@@ -19,4 +19,17 @@ describe '<%= cookbook_name %>::<%= recipe_name %>' do
|
|
|
19
19
|
expect { chef_run }.to_not raise_error
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
+
|
|
23
|
+
context 'When all attributes are default, on CentOS 7.4.1708' do
|
|
24
|
+
let(:chef_run) do
|
|
25
|
+
# for a complete list of available platforms and versions see:
|
|
26
|
+
# https://github.com/customink/fauxhai/blob/master/PLATFORMS.md
|
|
27
|
+
runner = ChefSpec::ServerRunner.new(platform: 'centos', version: '7.4.1708')
|
|
28
|
+
runner.converge(described_recipe)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'converges successfully' do
|
|
32
|
+
expect { chef_run }.to_not raise_error
|
|
33
|
+
end
|
|
34
|
+
end
|
|
22
35
|
end
|
data/lib/chef-dk/version.rb
CHANGED
data/omnibus_overrides.rb
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# THIS IS NOW HAND MANAGED, JUST EDIT THE THING
|
|
2
2
|
# .travis.yml and appveyor.yml consume this,
|
|
3
3
|
# try to keep it machine-parsable.
|
|
4
|
-
override :rubygems, version: "2.6.
|
|
5
|
-
override :bundler, version: "1.15.
|
|
4
|
+
override :rubygems, version: "2.6.14"
|
|
5
|
+
override :bundler, version: "1.15.4"
|
|
6
6
|
override "libffi", version: "3.2.1"
|
|
7
7
|
override "libiconv", version: "1.15"
|
|
8
8
|
override "liblzma", version: "5.2.3"
|
|
9
9
|
override "libtool", version: "2.4.2"
|
|
10
|
-
override "libxml2", version: "2.9.
|
|
11
|
-
override "libxslt", version: "1.1.
|
|
12
|
-
override "libyaml", version: "0.1.
|
|
10
|
+
override "libxml2", version: "2.9.5"
|
|
11
|
+
override "libxslt", version: "1.1.30"
|
|
12
|
+
override "libyaml", version: "0.1.7"
|
|
13
13
|
override "makedepend", version: "1.0.5"
|
|
14
14
|
override "ncurses", version: "5.9"
|
|
15
15
|
override "pkg-config-lite", version: "0.28-1"
|
|
@@ -19,4 +19,4 @@ override "util-macros", version: "1.19.0"
|
|
|
19
19
|
override "xproto", version: "7.0.28"
|
|
20
20
|
override "zlib", version: "1.2.11"
|
|
21
21
|
override "libzmq", version: "4.0.7"
|
|
22
|
-
override "openssl", version: "1.0.
|
|
22
|
+
override "openssl", version: "1.0.2m"
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright:: Copyright (c) 2017 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 "spec_helper"
|
|
19
|
+
require "chef-dk/chef_server_api_multi"
|
|
20
|
+
|
|
21
|
+
describe ChefDK::ChefServerAPIMulti do
|
|
22
|
+
|
|
23
|
+
let(:url) { "https://chef.example/organizations/myorg" }
|
|
24
|
+
|
|
25
|
+
let(:opts) do
|
|
26
|
+
{
|
|
27
|
+
signing_key_filename: "/path/to/key.pem",
|
|
28
|
+
client_name: "example-user",
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
let(:expected_server_api_opts) do
|
|
33
|
+
{
|
|
34
|
+
signing_key_filename: "/path/to/key.pem",
|
|
35
|
+
client_name: "example-user",
|
|
36
|
+
keepalives: true,
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
let(:chef_server_api) { instance_double("Chef::ServerAPI") }
|
|
41
|
+
|
|
42
|
+
subject(:server_api_multi) { described_class.new(url, opts) }
|
|
43
|
+
|
|
44
|
+
before do
|
|
45
|
+
# clean out thread local storage or else `chef_server_api` instance double
|
|
46
|
+
# will get re-used across test examples and rspec will complain:
|
|
47
|
+
Thread.current[:chef_server_api_multi] = nil
|
|
48
|
+
allow(Chef::ServerAPI).to receive(:new).with(url, expected_server_api_opts).and_return(chef_server_api)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "has a url" do
|
|
52
|
+
expect(server_api_multi.url).to eq(url)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "has an options hash for Chef::ServerAPI, with `keepalives: true` added" do
|
|
56
|
+
expect(server_api_multi.opts).to eq(expected_server_api_opts)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "creates a thread-local Chef::ServerAPI object for requests" do
|
|
60
|
+
server_api_multi.client_for_thread # force `||=` to run
|
|
61
|
+
expect(server_api_multi.client_for_thread).to eq(Thread.current[:chef_server_api_multi])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe "when keepalives are disabled" do
|
|
65
|
+
|
|
66
|
+
let(:opts) do
|
|
67
|
+
{
|
|
68
|
+
signing_key_filename: "/path/to/key.pem",
|
|
69
|
+
client_name: "example-user",
|
|
70
|
+
keepalives: false,
|
|
71
|
+
}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "does not override disabling them" do
|
|
75
|
+
expect(server_api_multi.opts[:keepalives]).to be(false)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe "delegating request methods to thread-local ServerAPI object" do
|
|
81
|
+
|
|
82
|
+
it "delegates #head" do
|
|
83
|
+
expect(chef_server_api).to receive(:head).with("/foo")
|
|
84
|
+
server_api_multi.head("/foo")
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "delegates #get" do
|
|
88
|
+
expect(chef_server_api).to receive(:get).with("/foo")
|
|
89
|
+
server_api_multi.get("/foo")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "delegates #put" do
|
|
93
|
+
expect(chef_server_api).to receive(:put).with("/foo", "data")
|
|
94
|
+
server_api_multi.put("/foo", "data")
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "delegates #post" do
|
|
98
|
+
expect(chef_server_api).to receive(:post).with("/foo", "data")
|
|
99
|
+
server_api_multi.post("/foo", "data")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "delegates #delete" do
|
|
103
|
+
expect(chef_server_api).to receive(:delete).with("/foo")
|
|
104
|
+
server_api_multi.delete("/foo")
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "delegates #streaming_request" do
|
|
108
|
+
expect(chef_server_api).to receive(:streaming_request).with("/foo")
|
|
109
|
+
server_api_multi.streaming_request("/foo")
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "passes a block argument to #streaming_request" do
|
|
113
|
+
expect(chef_server_api).to receive(:streaming_request).with("/foo").and_yield
|
|
114
|
+
x = 0
|
|
115
|
+
server_api_multi.streaming_request("/foo") { x = 5 }
|
|
116
|
+
expect(x).to eq(5)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -82,7 +82,7 @@ describe ChefDK::Command::Update do
|
|
|
82
82
|
|
|
83
83
|
it "creates an attributes update service object" do
|
|
84
84
|
expect(ChefDK::PolicyfileServices::UpdateAttributes).to receive(:new).
|
|
85
|
-
with(policyfile: nil, ui: command.ui, root_dir: Dir.pwd).
|
|
85
|
+
with(policyfile: nil, ui: command.ui, root_dir: Dir.pwd, chef_config: anything).
|
|
86
86
|
and_return(update_attrs_service)
|
|
87
87
|
expect(command.attributes_updater).to eq(update_attrs_service)
|
|
88
88
|
end
|
|
@@ -133,7 +133,7 @@ describe ChefDK::Command::Update do
|
|
|
133
133
|
before do
|
|
134
134
|
expect(install_service).to receive(:run)
|
|
135
135
|
expect(ChefDK::PolicyfileServices::UpdateAttributes).to receive(:new).
|
|
136
|
-
with(policyfile: nil, ui: command.ui, root_dir: Dir.pwd).
|
|
136
|
+
with(policyfile: nil, ui: command.ui, root_dir: Dir.pwd, chef_config: anything).
|
|
137
137
|
and_return(update_attrs_service)
|
|
138
138
|
expect(update_attrs_service).to receive(:run)
|
|
139
139
|
end
|
|
@@ -160,7 +160,7 @@ describe ChefDK::Command::Update do
|
|
|
160
160
|
before do
|
|
161
161
|
expect(install_service).to receive(:run).and_raise(exception)
|
|
162
162
|
expect(ChefDK::PolicyfileServices::UpdateAttributes).to receive(:new).
|
|
163
|
-
with(policyfile: nil, ui: command.ui, root_dir: Dir.pwd).
|
|
163
|
+
with(policyfile: nil, ui: command.ui, root_dir: Dir.pwd, chef_config: anything).
|
|
164
164
|
and_return(update_attrs_service)
|
|
165
165
|
expect(update_attrs_service).to receive(:run)
|
|
166
166
|
end
|
|
@@ -23,6 +23,8 @@ describe ChefDK::Configurable do
|
|
|
23
23
|
|
|
24
24
|
let(:includer) { TestConfigurable.new }
|
|
25
25
|
|
|
26
|
+
before { includer.reset_config! }
|
|
27
|
+
|
|
26
28
|
it "provides chef_config" do
|
|
27
29
|
expect(includer.chef_config).to eq Chef::Config
|
|
28
30
|
end
|
|
@@ -38,4 +40,29 @@ describe ChefDK::Configurable do
|
|
|
38
40
|
it "provides generator_config" do
|
|
39
41
|
expect(includer.generator_config).to eq Chef::Config.chefdk.generator
|
|
40
42
|
end
|
|
43
|
+
|
|
44
|
+
describe "loading Chef Config" do
|
|
45
|
+
|
|
46
|
+
let(:url) { "https://chef.example/organizations/myorg" }
|
|
47
|
+
|
|
48
|
+
let(:key_path) { "/path/to/my/key.pem" }
|
|
49
|
+
|
|
50
|
+
let(:username) { "my-username" }
|
|
51
|
+
|
|
52
|
+
before do
|
|
53
|
+
Chef::Config.chef_server_url(url)
|
|
54
|
+
Chef::Config.client_key(key_path)
|
|
55
|
+
Chef::Config.node_name(username)
|
|
56
|
+
includer.chef_config
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "creates a default chef server HTTP client for Omnifetch" do
|
|
60
|
+
client = CookbookOmnifetch.default_chef_server_http_client
|
|
61
|
+
expect(client).to be_a_kind_of(ChefDK::ChefServerAPIMulti)
|
|
62
|
+
expect(client.url).to eq(url)
|
|
63
|
+
expect(client.opts[:signing_key_filename]).to eq(key_path)
|
|
64
|
+
expect(client.opts[:client_name]).to eq(username)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
41
68
|
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright:: Copyright (c) 2017 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 "spec_helper"
|
|
19
|
+
require "chef-dk/policyfile/attribute_merge_checker"
|
|
20
|
+
|
|
21
|
+
describe ChefDK::Policyfile::AttributeMergeChecker do
|
|
22
|
+
let(:checker) { ChefDK::Policyfile::AttributeMergeChecker.new }
|
|
23
|
+
|
|
24
|
+
describe "when the same attribute is provided multiple times with the same value" do
|
|
25
|
+
describe "at the top level" do
|
|
26
|
+
before do
|
|
27
|
+
checker.with_attributes("foo", { "a" => "b" })
|
|
28
|
+
checker.with_attributes("bar", { "a" => "b", "c" => "d" })
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "does not raise an error" do
|
|
32
|
+
expect { checker.check! }.not_to raise_error
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe "deeply nested" do
|
|
37
|
+
before do
|
|
38
|
+
checker.with_attributes("foo", { "a" => { "b" => "c" } })
|
|
39
|
+
checker.with_attributes("bar", { "a" => { "b" => "c" } })
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "does not raise an error" do
|
|
43
|
+
expect { checker.check! }.not_to raise_error
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "when conflicts are present" do
|
|
49
|
+
describe "at the top level" do
|
|
50
|
+
before do
|
|
51
|
+
checker.with_attributes("foo", { "a" => "b" })
|
|
52
|
+
checker.with_attributes("bar", { "a" => "c", "c" => "d" })
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "raises an error" do
|
|
56
|
+
expect { checker.check! }.to raise_error(
|
|
57
|
+
ChefDK::Policyfile::AttributeMergeChecker::ConflictError) do |e|
|
|
58
|
+
expect(e.attribute_path).to eq("[a]")
|
|
59
|
+
expect(e.provided_by).to include("foo", "bar")
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe "deeply nested" do
|
|
65
|
+
before do
|
|
66
|
+
checker.with_attributes("foo", { "a" => { "b" => "c" } })
|
|
67
|
+
checker.with_attributes("bar", { "a" => { "b" => "d" } })
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "raises an error" do
|
|
71
|
+
expect { checker.check! }.to raise_error(
|
|
72
|
+
ChefDK::Policyfile::AttributeMergeChecker::ConflictError) do |e|
|
|
73
|
+
expect(e.attribute_path).to eq("[a][b]")
|
|
74
|
+
expect(e.provided_by).to include("foo", "bar")
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright:: Copyright (c) 2017 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 "spec_helper"
|
|
19
|
+
require "chef-dk/policyfile/chef_server_lock_fetcher"
|
|
20
|
+
|
|
21
|
+
describe ChefDK::Policyfile::ChefServerLockFetcher do
|
|
22
|
+
|
|
23
|
+
let(:revision_id) { "6fe753184c8946052d3231bb4212116df28d89a3a5f7ae52832ad408419dd5eb" }
|
|
24
|
+
let(:identifier) { "fab501cfaf747901bd82c1bc706beae7dc3a350c" }
|
|
25
|
+
let(:minimal_lockfile_json) do
|
|
26
|
+
<<-E
|
|
27
|
+
{
|
|
28
|
+
"revision_id": "#{revision_id}",
|
|
29
|
+
"name": "install-example",
|
|
30
|
+
"run_list": [
|
|
31
|
+
"recipe[local-cookbook::default]"
|
|
32
|
+
],
|
|
33
|
+
"cookbook_locks": {
|
|
34
|
+
"local-cookbook": {
|
|
35
|
+
"version": "2.3.4",
|
|
36
|
+
"identifier": "#{identifier}",
|
|
37
|
+
"dotted_decimal_identifier": "70567763561641081.489844270461035.258281553147148",
|
|
38
|
+
"source": "cookbooks/local-cookbook",
|
|
39
|
+
"cache_key": null,
|
|
40
|
+
"scm_info": null,
|
|
41
|
+
"source_options": {
|
|
42
|
+
"path": "cookbooks/local-cookbook"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"default_attributes": {},
|
|
47
|
+
"override_attributes": {},
|
|
48
|
+
"solution_dependencies": {
|
|
49
|
+
"Policyfile": [
|
|
50
|
+
[
|
|
51
|
+
"local-cookbook",
|
|
52
|
+
">= 0.0.0"
|
|
53
|
+
]
|
|
54
|
+
],
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"local-cookbook (2.3.4)": [
|
|
57
|
+
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
E
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def minimal_lockfile
|
|
66
|
+
FFI_Yajl::Parser.parse(minimal_lockfile_json)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
let(:policy_name) { "chatserver" }
|
|
70
|
+
let(:policy_revision_id) { "somerevisionid" }
|
|
71
|
+
let(:policy_group) { "somegroup" }
|
|
72
|
+
let(:url) { "https://chef.example/organizations/monkeynews" }
|
|
73
|
+
|
|
74
|
+
let(:chef_config) do
|
|
75
|
+
double("ChefConfig").tap do |double|
|
|
76
|
+
allow(double).to receive(:client_key).and_return("key")
|
|
77
|
+
allow(double).to receive(:node_name).and_return("node_name")
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
let(:http_client) { instance_double("Chef::ServerAPI", url: url ) }
|
|
81
|
+
|
|
82
|
+
let(:minimal_lockfile_modified) do
|
|
83
|
+
minimal_lockfile.tap do |lockfile|
|
|
84
|
+
lockfile["cookbook_locks"]["local-cookbook"]["source_options"] = {
|
|
85
|
+
"chef_server_artifact" => url,
|
|
86
|
+
"identifier" => identifier,
|
|
87
|
+
}
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
subject(:fetcher) { described_class.new(policy_name, source_options, chef_config) }
|
|
92
|
+
|
|
93
|
+
before do
|
|
94
|
+
allow(Chef::ServerAPI).to receive(:new).with(url, anything).and_return(http_client)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
context "when using revision id" do
|
|
98
|
+
let(:source_options) do
|
|
99
|
+
{
|
|
100
|
+
server: url,
|
|
101
|
+
policy_name: policy_name,
|
|
102
|
+
policy_revision_id: policy_revision_id,
|
|
103
|
+
}
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "calls the chef server to get the policy" do
|
|
107
|
+
expect(http_client).to receive(:get).with("policies/#{policy_name}/revisions/#{policy_revision_id}").
|
|
108
|
+
and_return(minimal_lockfile)
|
|
109
|
+
expect(fetcher.lock_data).to eq(minimal_lockfile_modified)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context "and policy_name is not provided" do
|
|
113
|
+
let(:source_options) do
|
|
114
|
+
{
|
|
115
|
+
server: url,
|
|
116
|
+
policy_revision_id: policy_revision_id,
|
|
117
|
+
}
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "calls the chef server to get the policy with the dsl name" do
|
|
121
|
+
expect(http_client).to receive(:get).with("policies/#{policy_name}/revisions/#{policy_revision_id}").
|
|
122
|
+
and_return(minimal_lockfile)
|
|
123
|
+
expect(fetcher.lock_data).to eq(minimal_lockfile_modified)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
context "when using policy group" do
|
|
129
|
+
let(:source_options) do
|
|
130
|
+
{
|
|
131
|
+
server: url,
|
|
132
|
+
policy_name: policy_name,
|
|
133
|
+
policy_group: policy_group,
|
|
134
|
+
}
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
let(:source_options_for_lock) do
|
|
138
|
+
source_options.merge({ policy_revision_id: revision_id })
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "calls the chef server to get the policy" do
|
|
142
|
+
expect(http_client).to receive(:get).with("policy_groups/#{policy_group}/policies/#{policy_name}").
|
|
143
|
+
and_return(minimal_lockfile)
|
|
144
|
+
expect(fetcher.lock_data).to eq(minimal_lockfile_modified)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "includes the revision id in the source_options_for_lock" do
|
|
148
|
+
allow(http_client).to receive(:get).with(
|
|
149
|
+
"policy_groups/#{policy_group}/policies/#{policy_name}").and_return(minimal_lockfile)
|
|
150
|
+
|
|
151
|
+
expect(fetcher.source_options_for_lock).to eq(source_options_for_lock)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "correctly applies source_options that were included in the lock" do
|
|
155
|
+
fetcher.apply_locked_source_options(source_options_for_lock)
|
|
156
|
+
expect(http_client).to receive(:get).with(
|
|
157
|
+
"policies/#{policy_name}/revisions/#{revision_id}").and_return(minimal_lockfile)
|
|
158
|
+
fetcher.lock_data
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|