chef 12.19.36 → 12.20.3

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: 335aea9aecdac4a9defa58006059d87033abe677
4
- data.tar.gz: 13b5a5f45795e1510e381a895a2b9a094b816f5f
3
+ metadata.gz: b76fcc06d56bcab5fc551164c0522fdc88252c06
4
+ data.tar.gz: 734f7fda8fb0ea35b678ed60fd91aab39a7ee834
5
5
  SHA512:
6
- metadata.gz: 81560c62293354d270308a04fc712a7ef6f8dfe64f9b2ad5b07e2bb453d489cb7fc252efe88bc5d079e6b0ab23fba8b8afd6de144f980efe1dbd76e2ba1f8e78
7
- data.tar.gz: 63fc53a5763e242ea084c13bf5d469449bc8df4d058f92d6a336c0166e45b4397e51179a71575ed405bbc8fa7441f4f9ccee8e6d90d34c68cd9a4d573b9fdd2d
6
+ metadata.gz: ce495ae0e26ca2d7eeef5c7bce3e4e81a569a70149150e468cf87cbde16611fde6f7b44e3a82cbfc53d00f8aa8a67d46bbffa5bfe7c254878b3b06e3342c462a
7
+ data.tar.gz: 5aaaf3599b394c59041bcbcac810e8df7ff51afbee519bbecc7622de3c7b30650d6e1a14cf2a42b2dc7e974ca7b08205c94f5e98c1af65b41a21508725d6022f
data/VERSION CHANGED
@@ -1 +1 @@
1
- 12.19.36
1
+ 12.20.3
@@ -280,6 +280,8 @@ class Chef
280
280
 
281
281
  run_context = setup_run_context
282
282
 
283
+ load_required_recipe(@rest, run_context) unless Chef::Config[:solo_legacy_mode]
284
+
283
285
  if Chef::Config[:audit_mode] != :audit_only
284
286
  converge_error = converge_and_save(run_context)
285
287
  end
@@ -514,6 +516,49 @@ class Chef
514
516
  run_context
515
517
  end
516
518
 
519
+ #
520
+ # Adds a required recipe as specified by the Chef Server
521
+ #
522
+ # @return The modified run context
523
+ #
524
+ # @api private
525
+ #
526
+ # TODO: @rest doesn't appear to be used anywhere outside
527
+ # of client.register except for here. If it's common practice
528
+ # to create your own rest client, perhaps we should do that
529
+ # here but it seems more appropriate to reuse one that we
530
+ # know is already created. for ease of testing, we'll pass
531
+ # the existing rest client in as a parameter
532
+ #
533
+ def load_required_recipe(rest, run_context)
534
+ required_recipe_contents = rest.get("required_recipe")
535
+ Chef::Log.info("Required Recipe found, loading it")
536
+ Chef::FileCache.store("required_recipe", required_recipe_contents)
537
+ required_recipe_file = Chef::FileCache.load("required_recipe", false)
538
+
539
+ # TODO: add integration tests with resource reporting turned on
540
+ # (presumably requires changes to chef-zero)
541
+ #
542
+ # Chef::Recipe.new takes a cookbook name and a recipe name along
543
+ # with the run context. These names are eventually used in the
544
+ # resource reporter, and if the cookbook name cannot be found in the
545
+ # cookbook collection then we will fail with an exception. Cases where
546
+ # we currently also fail:
547
+ # - specific recipes
548
+ # - chef-apply would fail if resource reporting was enabled
549
+ #
550
+ recipe = Chef::Recipe.new(nil, nil, run_context)
551
+ recipe.from_file(required_recipe_file)
552
+ run_context
553
+ rescue Net::HTTPServerException => e
554
+ case e.response
555
+ when Net::HTTPNotFound
556
+ Chef::Log.debug("Required Recipe not configured on the server, skipping it")
557
+ else
558
+ raise
559
+ end
560
+ end
561
+
517
562
  #
518
563
  # The PolicyBuilder strategy for figuring out run list and cookbooks.
519
564
  #
@@ -49,13 +49,15 @@ class Chef
49
49
  exit(1)
50
50
  end
51
51
 
52
- # create the data bag
52
+ # Verify if the data bag exists
53
53
  begin
54
+ rest.get("data/#{@data_bag_name}")
55
+ ui.info("Data bag #{@data_bag_name} already exists")
56
+ rescue Net::HTTPServerException => e
57
+ raise unless e.to_s =~ /^404/
58
+ # if it doesn't exists, try to create it
54
59
  rest.post("data", { "name" => @data_bag_name })
55
60
  ui.info("Created data_bag[#{@data_bag_name}]")
56
- rescue Net::HTTPServerException => e
57
- raise unless e.to_s =~ /^409/
58
- ui.info("Data bag #{@data_bag_name} already exists")
59
61
  end
60
62
 
61
63
  # if an item is specified, create it, as well
@@ -115,7 +115,7 @@ class Chef
115
115
  so = shell_out(cmd)
116
116
  so.run_command
117
117
  so.stdout.split(/\n/).map do |t|
118
- if z = t.match(/^ +Key fingerprint = ([0-9A-F ]+)/)
118
+ if z = t.match(/^fpr:+([0-9A-F]+):/)
119
119
  z[1].split.join
120
120
  end
121
121
  end.compact
@@ -147,8 +147,10 @@ class Chef
147
147
  end
148
148
 
149
149
  def no_new_keys?(file)
150
- installed_keys = extract_fingerprints_from_cmd("apt-key finger")
151
- proposed_keys = extract_fingerprints_from_cmd("gpg --with-fingerprint #{file}")
150
+ # Now we are using the option --with-colons that works across old os versions
151
+ # as well as the latest (16.10). This for both `apt-key` and `gpg` commands
152
+ installed_keys = extract_fingerprints_from_cmd("apt-key adv --list-public-keys --with-fingerprint --with-colons")
153
+ proposed_keys = extract_fingerprints_from_cmd("gpg --with-fingerprint --with-colons #{file}")
152
154
  (installed_keys & proposed_keys).sort == proposed_keys.sort
153
155
  end
154
156
 
@@ -21,7 +21,7 @@
21
21
 
22
22
  class Chef
23
23
  CHEF_ROOT = File.expand_path("../..", __FILE__)
24
- VERSION = "12.19.36"
24
+ VERSION = "12.20.3"
25
25
  end
26
26
 
27
27
  #
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: John Keiser (<jkeiser@chef.io>)
3
- # Copyright:: Copyright 2011-2016, Chef Software Inc.
3
+ # Copyright:: Copyright 2011-2017, Chef Software Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -654,7 +654,7 @@ describe Chef::Resource::Link do
654
654
  end
655
655
  context "and the link does not yet exist" do
656
656
  it "links to the target file" do
657
- skip("OS X/FreeBSD/AIX symlink? and readlink working on hard links to symlinks") if os_x? || freebsd? || aix?
657
+ skip("OS X/FreeBSD/AIX/Solaris symlink? and readlink working on hard links to symlinks") if os_x? || freebsd? || aix? || solaris?
658
658
  resource.run_action(:create)
659
659
  expect(File.exists?(target_file)).to be_truthy
660
660
  # OS X gets angry about this sort of link. Bug in OS X, IMO.
@@ -673,7 +673,7 @@ describe Chef::Resource::Link do
673
673
  end
674
674
  context "and the link does not yet exist" do
675
675
  it "links to the target file" do
676
- skip("OS X/FreeBSD/AIX fails to create hardlinks to broken symlinks") if os_x? || freebsd? || aix?
676
+ skip("OS X/FreeBSD/AIX/Solaris fails to create hardlinks to broken symlinks") if os_x? || freebsd? || aix? || solaris?
677
677
  resource.run_action(:create)
678
678
  expect(File.exists?(target_file) || File.symlink?(target_file)).to be_truthy
679
679
  expect(symlink?(target_file)).to be_truthy
@@ -135,6 +135,12 @@ shared_context "a client run" do
135
135
  and_return({})
136
136
  end
137
137
 
138
+ def stub_for_required_recipe
139
+ response = Net::HTTPNotFound.new("1.1", "404", "Not Found")
140
+ exception = Net::HTTPServerException.new('404 "Not Found"', response)
141
+ expect(http_node_load).to receive(:get).with("required_recipe").and_raise(exception)
142
+ end
143
+
138
144
  def stub_for_converge
139
145
  # define me
140
146
  end
@@ -165,6 +171,7 @@ shared_context "a client run" do
165
171
  stub_for_data_collector_init
166
172
  stub_for_node_load
167
173
  stub_for_sync_cookbooks
174
+ stub_for_required_recipe
168
175
  stub_for_converge
169
176
  stub_for_audit
170
177
  stub_for_node_save
@@ -402,6 +402,55 @@ describe Chef::Client do
402
402
  end
403
403
  end
404
404
 
405
+ describe "load_required_recipe" do
406
+ let(:rest) { double("Chef::ServerAPI (required recipe)") }
407
+ let(:run_context) { double("Chef::RunContext") }
408
+ let(:recipe) { double("Chef::Recipe (required recipe)") }
409
+ let(:required_recipe) do
410
+ <<EOM
411
+ fake_recipe_variable = "for reals"
412
+ EOM
413
+ end
414
+
415
+ context "when required_recipe is configured" do
416
+
417
+ before(:each) do
418
+ expect(rest).to receive(:get).with("required_recipe").and_return(required_recipe)
419
+ expect(Chef::Recipe).to receive(:new).with(nil, nil, run_context).and_return(recipe)
420
+ expect(recipe).to receive(:from_file)
421
+ end
422
+
423
+ it "fetches the recipe and adds it to the run context" do
424
+ client.load_required_recipe(rest, run_context)
425
+ end
426
+
427
+ context "when the required_recipe has bad contents" do
428
+ let(:required_recipe) do
429
+ <<EOM
430
+ this is not a recipe
431
+ EOM
432
+ end
433
+ it "should not raise an error" do
434
+ expect { client.load_required_recipe(rest, run_context) }.not_to raise_error()
435
+ end
436
+ end
437
+ end
438
+
439
+ context "when required_recipe returns 404" do
440
+ let(:http_response) { Net::HTTPNotFound.new("1.1", "404", "Not Found") }
441
+ let(:http_exception) { Net::HTTPServerException.new('404 "Not Found"', http_response) }
442
+
443
+ before(:each) do
444
+ expect(rest).to receive(:get).with("required_recipe").and_raise(http_exception)
445
+ end
446
+
447
+ it "should log and continue on" do
448
+ expect(Chef::Log).to receive(:debug)
449
+ client.load_required_recipe(rest, run_context)
450
+ end
451
+ end
452
+ end
453
+
405
454
  describe "windows_admin_check" do
406
455
  context "platform is not windows" do
407
456
  before do
@@ -46,64 +46,84 @@ describe Chef::Knife::DataBagCreate do
46
46
  allow(knife).to receive(:config).and_return(config)
47
47
  end
48
48
 
49
- it "tries to create a data bag with an invalid name when given one argument" do
50
- knife.name_args = ["invalid&char"]
51
- expect(Chef::DataBag).to receive(:validate_name!).with(knife.name_args[0]).and_raise(Chef::Exceptions::InvalidDataBagName)
52
- expect { knife.run }.to exit_with_code(1)
53
- end
54
-
55
- context "when given one argument" do
56
- before do
57
- knife.name_args = [bag_name]
58
- end
59
-
60
- it "creates a data bag" do
61
- expect(rest).to receive(:post).with("data", { "name" => bag_name })
62
- expect(knife.ui).to receive(:info).with("Created data_bag[#{bag_name}]")
49
+ context "when data_bag already exist" do
50
+ it "doesn't creates a data bag" do
51
+ expect(knife).to receive(:create_object).and_yield(raw_hash)
52
+ expect(rest).to receive(:get).with("data/#{bag_name}")
53
+ expect(rest).to_not receive(:post).with("data", { "name" => bag_name })
54
+ expect(knife.ui).to receive(:info).with("Data bag #{bag_name} already exists")
63
55
 
64
56
  knife.run
65
57
  end
66
58
  end
67
59
 
68
- context "no secret is specified for encryption" do
69
- let(:item) do
70
- item = Chef::DataBagItem.from_hash(raw_hash)
71
- item.data_bag(bag_name)
72
- item
60
+ context "when data_bag doesn't exist" do
61
+ before do
62
+ # Data bag doesn't exist by default so we mock the GET request to return 404
63
+ exception = double("404 error", :code => "404")
64
+ allow(rest).to receive(:get)
65
+ .with("data/#{bag_name}")
66
+ .and_raise(Net::HTTPServerException.new("404", exception))
73
67
  end
74
68
 
75
- it "creates a data bag item" do
76
- expect(knife).to receive(:create_object).and_yield(raw_hash)
77
- expect(knife).to receive(:encryption_secret_provided?).and_return(false)
78
- expect(rest).to receive(:post).with("data", { "name" => bag_name }).ordered
79
- expect(rest).to receive(:post).with("data/#{bag_name}", item).ordered
80
-
81
- knife.run
69
+ it "tries to create a data bag with an invalid name when given one argument" do
70
+ knife.name_args = ["invalid&char"]
71
+ expect(Chef::DataBag).to receive(:validate_name!).with(knife.name_args[0]).and_raise(Chef::Exceptions::InvalidDataBagName)
72
+ expect { knife.run }.to exit_with_code(1)
82
73
  end
83
- end
84
74
 
85
- context "a secret is specified for encryption" do
86
- let(:encoded_data) { Chef::EncryptedDataBagItem.encrypt_data_bag_item(raw_hash, secret) }
75
+ context "when given one argument" do
76
+ before do
77
+ knife.name_args = [bag_name]
78
+ end
79
+
80
+ it "creates a data bag" do
81
+ expect(rest).to receive(:post).with("data", { "name" => bag_name })
82
+ expect(knife.ui).to receive(:info).with("Created data_bag[#{bag_name}]")
87
83
 
88
- let(:item) do
89
- item = Chef::DataBagItem.from_hash(encoded_data)
90
- item.data_bag(bag_name)
91
- item
84
+ knife.run
85
+ end
92
86
  end
93
87
 
94
- it "creates an encrypted data bag item" do
95
- expect(knife).to receive(:create_object).and_yield(raw_hash)
96
- expect(knife).to receive(:encryption_secret_provided?).and_return(true)
97
- expect(knife).to receive(:read_secret).and_return(secret)
98
- expect(Chef::EncryptedDataBagItem)
99
- .to receive(:encrypt_data_bag_item)
100
- .with(raw_hash, secret)
101
- .and_return(encoded_data)
102
- expect(rest).to receive(:post).with("data", { "name" => bag_name }).ordered
103
- expect(rest).to receive(:post).with("data/#{bag_name}", item).ordered
88
+ context "no secret is specified for encryption" do
89
+ let(:item) do
90
+ item = Chef::DataBagItem.from_hash(raw_hash)
91
+ item.data_bag(bag_name)
92
+ item
93
+ end
94
+
95
+ it "creates a data bag item" do
96
+ expect(knife).to receive(:create_object).and_yield(raw_hash)
97
+ expect(knife).to receive(:encryption_secret_provided?).and_return(false)
98
+ expect(rest).to receive(:post).with("data", { "name" => bag_name }).ordered
99
+ expect(rest).to receive(:post).with("data/#{bag_name}", item).ordered
100
+
101
+ knife.run
102
+ end
103
+ end
104
104
 
105
- knife.run
105
+ context "a secret is specified for encryption" do
106
+ let(:encoded_data) { Chef::EncryptedDataBagItem.encrypt_data_bag_item(raw_hash, secret) }
107
+
108
+ let(:item) do
109
+ item = Chef::DataBagItem.from_hash(encoded_data)
110
+ item.data_bag(bag_name)
111
+ item
112
+ end
113
+
114
+ it "creates an encrypted data bag item" do
115
+ expect(knife).to receive(:create_object).and_yield(raw_hash)
116
+ expect(knife).to receive(:encryption_secret_provided?).and_return(true)
117
+ expect(knife).to receive(:read_secret).and_return(secret)
118
+ expect(Chef::EncryptedDataBagItem)
119
+ .to receive(:encrypt_data_bag_item)
120
+ .with(raw_hash, secret)
121
+ .and_return(encoded_data)
122
+ expect(rest).to receive(:post).with("data", { "name" => bag_name }).ordered
123
+ expect(rest).to receive(:post).with("data/#{bag_name}", item).ordered
124
+
125
+ knife.run
126
+ end
106
127
  end
107
128
  end
108
-
109
129
  end
@@ -18,32 +18,30 @@
18
18
 
19
19
  require "spec_helper"
20
20
 
21
+ # Now we are using the option --with-colons that works across old os versions
22
+ # as well as the latest (16.10). This for both `apt-key` and `gpg` commands
23
+ #
24
+ # Output of the command:
25
+ # => apt-key adv --list-public-keys --with-fingerprint --with-colons
21
26
  APT_KEY_FINGER = <<-EOF
22
- /etc/apt/trusted.gpg
23
- --------------------
24
- pub 1024D/437D05B5 2004-09-12
25
- Key fingerprint = 6302 39CC 130E 1A7F D81A 27B1 4097 6EAF 437D 05B5
26
- uid Ubuntu Archive Automatic Signing Key <ftpmaster@ubuntu.com>
27
- sub 2048g/79164387 2004-09-12
28
-
29
- pub 1024D/FBB75451 2004-12-30
30
- Key fingerprint = C598 6B4F 1257 FFA8 6632 CBA7 4618 1433 FBB7 5451
31
- uid Ubuntu CD Image Automatic Signing Key <cdimage@ubuntu.com>
32
-
33
- pub 4096R/C0B21F32 2012-05-11
34
- Key fingerprint = 790B C727 7767 219C 42C8 6F93 3B4F E6AC C0B2 1F32
35
- uid Ubuntu Archive Automatic Signing Key (2012) <ftpmaster@ubuntu.com>
36
-
37
- pub 4096R/EFE21092 2012-05-11
38
- Key fingerprint = 8439 38DF 228D 22F7 B374 2BC0 D94A A3F0 EFE2 1092
39
- uid Ubuntu CD Image Automatic Signing Key (2012) <cdimage@ubuntu.com>
40
-
27
+ tru:t:1:1488924856:0:3:1:5
28
+ pub:-:1024:17:40976EAF437D05B5:2004-09-12:::-:Ubuntu Archive Automatic Signing Key <ftpmaster@ubuntu.com>::scESC:
29
+ fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:
30
+ sub:-:2048:16:251BEFF479164387:2004-09-12::::::e:
31
+ pub:-:1024:17:46181433FBB75451:2004-12-30:::-:Ubuntu CD Image Automatic Signing Key <cdimage@ubuntu.com>::scSC:
32
+ fpr:::::::::C5986B4F1257FFA86632CBA746181433FBB75451:
33
+ pub:-:4096:1:3B4FE6ACC0B21F32:2012-05-11:::-:Ubuntu Archive Automatic Signing Key (2012) <ftpmaster@ubuntu.com>::scSC:
34
+ fpr:::::::::790BC7277767219C42C86F933B4FE6ACC0B21F32:
35
+ pub:-:4096:1:D94AA3F0EFE21092:2012-05-11:::-:Ubuntu CD Image Automatic Signing Key (2012) <cdimage@ubuntu.com>::scSC:
36
+ fpr:::::::::843938DF228D22F7B3742BC0D94AA3F0EFE21092:
41
37
  EOF
42
38
 
39
+ # Output of the command:
40
+ # => gpg --with-fingerprint --with-colons [FILE]
43
41
  GPG_FINGER = <<-EOF
44
- pub 1024D/02A818DD 2009-04-22 Cloudera Apt Repository
45
- Key fingerprint = F36A 89E3 3CC1 BD0F 7107 9007 3275 74EE 02A8 18DD
46
- sub 2048g/D1CA74A1 2009-04-22
42
+ pub:-:1024:17:327574EE02A818DD:2009-04-22:::-:Cloudera Apt Repository:
43
+ fpr:::::::::F36A89E33CC1BD0F71079007327574EE02A818DD:
44
+ sub:-:2048:16:84080586D1CA74A1:2009-04-22::::
47
45
  EOF
48
46
 
49
47
  describe Chef::Provider::AptRepository do
@@ -57,6 +55,10 @@ describe Chef::Provider::AptRepository do
57
55
  Chef::Provider::AptRepository.new(new_resource, run_context)
58
56
  end
59
57
 
58
+ let(:apt_key_finger_cmd) do
59
+ "apt-key adv --list-public-keys --with-fingerprint --with-colons"
60
+ end
61
+
60
62
  let(:apt_key_finger) do
61
63
  r = double("Mixlib::ShellOut", stdout: APT_KEY_FINGER, exitstatus: 0, live_stream: true)
62
64
  allow(r).to receive(:run_command)
@@ -102,28 +104,32 @@ C5986B4F1257FFA86632CBA746181433FBB75451
102
104
 
103
105
  it "should run the desired command" do
104
106
  expect(apt_key_finger).to receive(:run_command)
105
- provider.extract_fingerprints_from_cmd("apt-key finger")
107
+ provider.extract_fingerprints_from_cmd(apt_key_finger_cmd)
106
108
  end
107
109
 
108
110
  it "should return a list of key fingerprints" do
109
- expect(provider.extract_fingerprints_from_cmd("apt-key finger")).to eql(apt_fingerprints)
111
+ expect(provider.extract_fingerprints_from_cmd(apt_key_finger_cmd)).to eql(apt_fingerprints)
110
112
  end
111
113
  end
112
114
 
113
115
  describe "#no_new_keys?" do
114
116
  before do
115
- allow(provider).to receive(:extract_fingerprints_from_cmd).with("apt-key finger").and_return(apt_fingerprints)
117
+ allow(provider).to receive(:extract_fingerprints_from_cmd).with(apt_key_finger_cmd).and_return(apt_fingerprints)
116
118
  end
117
119
 
118
120
  let(:file) { "/tmp/remote-gpg-keyfile" }
119
121
 
120
122
  it "should match a set of keys" do
121
- allow(provider).to receive(:extract_fingerprints_from_cmd).with("gpg --with-fingerprint #{file}").and_return(Array(apt_fingerprints.first))
123
+ allow(provider).to receive(:extract_fingerprints_from_cmd)
124
+ .with("gpg --with-fingerprint --with-colons #{file}")
125
+ .and_return(Array(apt_fingerprints.first))
122
126
  expect(provider.no_new_keys?(file)).to be_truthy
123
127
  end
124
128
 
125
129
  it "should notice missing keys" do
126
- allow(provider).to receive(:extract_fingerprints_from_cmd).with("gpg --with-fingerprint #{file}").and_return(%w{ F36A89E33CC1BD0F71079007327574EE02A818DD })
130
+ allow(provider).to receive(:extract_fingerprints_from_cmd)
131
+ .with("gpg --with-fingerprint --with-colons #{file}")
132
+ .and_return(%w{ F36A89E33CC1BD0F71079007327574EE02A818DD })
127
133
  expect(provider.no_new_keys?(file)).to be_falsey
128
134
  end
129
135
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.19.36
4
+ version: 12.20.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Jacob
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-23 00:00:00.000000000 Z
11
+ date: 2017-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-config
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 12.19.36
19
+ version: 12.20.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 12.19.36
26
+ version: 12.20.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: mixlib-cli
29
29
  requirement: !ruby/object:Gem::Requirement