cheffish 4.0.0 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +8 -8
  3. data/Rakefile +24 -12
  4. data/cheffish.gemspec +15 -15
  5. data/lib/chef/resource/chef_acl.rb +63 -63
  6. data/lib/chef/resource/chef_client.rb +9 -9
  7. data/lib/chef/resource/chef_container.rb +9 -9
  8. data/lib/chef/resource/chef_data_bag.rb +9 -9
  9. data/lib/chef/resource/chef_data_bag_item.rb +27 -27
  10. data/lib/chef/resource/chef_environment.rb +21 -22
  11. data/lib/chef/resource/chef_group.rb +19 -19
  12. data/lib/chef/resource/chef_mirror.rb +32 -17
  13. data/lib/chef/resource/chef_node.rb +14 -14
  14. data/lib/chef/resource/chef_organization.rb +29 -30
  15. data/lib/chef/resource/chef_resolved_cookbooks.rb +7 -7
  16. data/lib/chef/resource/chef_role.rb +25 -22
  17. data/lib/chef/resource/chef_user.rb +13 -14
  18. data/lib/chef/resource/private_key.rb +24 -25
  19. data/lib/chef/resource/public_key.rb +6 -7
  20. data/lib/cheffish.rb +17 -17
  21. data/lib/cheffish/array_property.rb +2 -2
  22. data/lib/cheffish/base_properties.rb +3 -3
  23. data/lib/cheffish/base_resource.rb +8 -8
  24. data/lib/cheffish/basic_chef_client.rb +17 -17
  25. data/lib/cheffish/chef_actor_base.rb +8 -8
  26. data/lib/cheffish/chef_run.rb +7 -2
  27. data/lib/cheffish/chef_run_data.rb +2 -2
  28. data/lib/cheffish/chef_run_listener.rb +1 -1
  29. data/lib/cheffish/key_formatter.rb +16 -18
  30. data/lib/cheffish/merged_config.rb +5 -3
  31. data/lib/cheffish/node_properties.rb +11 -7
  32. data/lib/cheffish/recipe_dsl.rb +33 -34
  33. data/lib/cheffish/rspec.rb +3 -3
  34. data/lib/cheffish/rspec/chef_run_support.rb +13 -13
  35. data/lib/cheffish/rspec/matchers.rb +4 -4
  36. data/lib/cheffish/rspec/matchers/be_idempotent.rb +3 -3
  37. data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +3 -3
  38. data/lib/cheffish/rspec/matchers/have_updated.rb +3 -3
  39. data/lib/cheffish/rspec/recipe_run_wrapper.rb +8 -7
  40. data/lib/cheffish/rspec/repository_support.rb +6 -6
  41. data/lib/cheffish/server_api.rb +11 -11
  42. data/lib/cheffish/version.rb +1 -1
  43. data/spec/functional/fingerprint_spec.rb +12 -12
  44. data/spec/functional/merged_config_spec.rb +46 -6
  45. data/spec/functional/server_api_spec.rb +3 -3
  46. data/spec/integration/chef_acl_spec.rb +489 -489
  47. data/spec/integration/chef_client_spec.rb +39 -39
  48. data/spec/integration/chef_container_spec.rb +14 -14
  49. data/spec/integration/chef_data_bag_item_spec.rb +9 -9
  50. data/spec/integration/chef_group_spec.rb +219 -219
  51. data/spec/integration/chef_mirror_spec.rb +228 -228
  52. data/spec/integration/chef_node_spec.rb +511 -511
  53. data/spec/integration/chef_organization_spec.rb +126 -126
  54. data/spec/integration/chef_role_spec.rb +33 -33
  55. data/spec/integration/chef_user_spec.rb +37 -37
  56. data/spec/integration/private_key_spec.rb +154 -154
  57. data/spec/integration/recipe_dsl_spec.rb +10 -10
  58. data/spec/integration/rspec/converge_spec.rb +49 -49
  59. data/spec/support/key_support.rb +6 -6
  60. data/spec/support/spec_support.rb +3 -3
  61. data/spec/unit/get_private_key_spec.rb +19 -19
  62. data/spec/unit/recipe_run_wrapper_spec.rb +4 -4
  63. metadata +3 -3
@@ -1,8 +1,10 @@
1
+ require "chef/mash"
2
+
1
3
  module Cheffish
2
4
  class MergedConfig
3
5
  def initialize(*configs)
4
- @configs = configs
5
- @merge_arrays = {}
6
+ @configs = configs.map { |config| Chef::Mash.from_hash config }
7
+ @merge_arrays = Chef::Mash.new
6
8
  end
7
9
 
8
10
  include Enumerable
@@ -60,7 +62,7 @@ module Cheffish
60
62
  alias_method :has_key?, :key?
61
63
 
62
64
  def keys
63
- configs.map { |c| c.keys }.flatten(1).uniq
65
+ configs.flat_map { |c| c.keys }.uniq
64
66
  end
65
67
 
66
68
  def values
@@ -1,4 +1,4 @@
1
- require 'cheffish/base_properties'
1
+ require "cheffish/base_properties"
2
2
 
3
3
  module Cheffish
4
4
  module NodeProperties
@@ -10,7 +10,7 @@ module Cheffish
10
10
  chef_environment run_context.cheffish.current_environment
11
11
  end
12
12
 
13
- property :name, Cheffish::NAME_REGEX, name_property: true
13
+ property :node_properties_name, Cheffish::NAME_REGEX, name_property: true
14
14
  property :chef_environment, Cheffish::NAME_REGEX
15
15
  property :run_list, Array # We should let them specify it as a series of parameters too
16
16
  property :attributes, Hash
@@ -22,7 +22,7 @@ module Cheffish
22
22
  # end
23
23
  # attribute 'ip_address', :delete
24
24
  attr_accessor :attribute_modifiers
25
- def attribute(attribute_path, value=Chef::NOT_PASSED, &block)
25
+ def attribute(attribute_path, value = Chef::NOT_PASSED, &block)
26
26
  @attribute_modifiers ||= []
27
27
  if value != Chef::NOT_PASSED
28
28
  @attribute_modifiers << [ attribute_path, value ]
@@ -36,7 +36,7 @@ module Cheffish
36
36
  # Patchy tags
37
37
  # tag 'webserver', 'apache', 'myenvironment'
38
38
  def tag(*tags)
39
- attribute 'tags' do |existing_tags|
39
+ attribute "tags" do |existing_tags|
40
40
  existing_tags ||= []
41
41
  tags.each do |tag|
42
42
  if !existing_tags.include?(tag.to_s)
@@ -46,8 +46,9 @@ module Cheffish
46
46
  existing_tags
47
47
  end
48
48
  end
49
+
49
50
  def remove_tag(*tags)
50
- attribute 'tags' do |existing_tags|
51
+ attribute "tags" do |existing_tags|
51
52
  if existing_tags
52
53
  tags.each do |tag|
53
54
  existing_tags.delete(tag.to_s)
@@ -61,10 +62,10 @@ module Cheffish
61
62
  # tags :a, :b, :c # removes all other tags
62
63
  def tags(*tags)
63
64
  if tags.size == 0
64
- attribute('tags')
65
+ attribute("tags")
65
66
  else
66
67
  tags = tags[0] if tags.size == 1 && tags[0].kind_of?(Array)
67
- attribute 'tags', tags.map { |tag| tag.to_s }
68
+ attribute "tags", tags.map { |tag| tag.to_s }
68
69
  end
69
70
  end
70
71
 
@@ -82,6 +83,7 @@ module Cheffish
82
83
  @run_list_modifiers ||= []
83
84
  @run_list_modifiers += recipes.map { |recipe| Chef::RunList::RunListItem.new("recipe[#{recipe}]") }
84
85
  end
86
+
85
87
  def role(*roles)
86
88
  if roles.size == 0
87
89
  raise ArgumentError, "At least one role must be specified"
@@ -89,6 +91,7 @@ module Cheffish
89
91
  @run_list_modifiers ||= []
90
92
  @run_list_modifiers += roles.map { |role| Chef::RunList::RunListItem.new("role[#{role}]") }
91
93
  end
94
+
92
95
  def remove_recipe(*recipes)
93
96
  if recipes.size == 0
94
97
  raise ArgumentError, "At least one recipe must be specified"
@@ -96,6 +99,7 @@ module Cheffish
96
99
  @run_list_removers ||= []
97
100
  @run_list_removers += recipes.map { |recipe| Chef::RunList::RunListItem.new("recipe[#{recipe}]") }
98
101
  end
102
+
99
103
  def remove_role(*roles)
100
104
  if roles.size == 0
101
105
  raise ArgumentError, "At least one role must be specified"
@@ -1,30 +1,29 @@
1
- require 'cheffish'
2
-
3
- require 'chef/version'
4
- require 'chef_zero/server'
5
- require 'chef/chef_fs/chef_fs_data_store'
6
- require 'chef/chef_fs/config'
7
- require 'cheffish/chef_run_data'
8
- require 'cheffish/chef_run_listener'
9
- require 'chef/client'
10
- require 'chef/config'
11
- require 'chef_zero/version'
12
- require 'cheffish/merged_config'
13
- require 'chef/resource/chef_acl'
14
- require 'chef/resource/chef_client'
15
- require 'chef/resource/chef_container'
16
- require 'chef/resource/chef_data_bag'
17
- require 'chef/resource/chef_data_bag_item'
18
- require 'chef/resource/chef_environment'
19
- require 'chef/resource/chef_group'
20
- require 'chef/resource/chef_mirror'
21
- require 'chef/resource/chef_node'
22
- require 'chef/resource/chef_organization'
23
- require 'chef/resource/chef_role'
24
- require 'chef/resource/chef_user'
25
- require 'chef/resource/private_key'
26
- require 'chef/resource/public_key'
27
-
1
+ require "cheffish"
2
+
3
+ require "chef/version"
4
+ require "chef_zero/server"
5
+ require "chef/chef_fs/chef_fs_data_store"
6
+ require "chef/chef_fs/config"
7
+ require "cheffish/chef_run_data"
8
+ require "cheffish/chef_run_listener"
9
+ require "chef/client"
10
+ require "chef/config"
11
+ require "chef_zero/version"
12
+ require "cheffish/merged_config"
13
+ require "chef/resource/chef_acl"
14
+ require "chef/resource/chef_client"
15
+ require "chef/resource/chef_container"
16
+ require "chef/resource/chef_data_bag"
17
+ require "chef/resource/chef_data_bag_item"
18
+ require "chef/resource/chef_environment"
19
+ require "chef/resource/chef_group"
20
+ require "chef/resource/chef_mirror"
21
+ require "chef/resource/chef_node"
22
+ require "chef/resource/chef_organization"
23
+ require "chef/resource/chef_role"
24
+ require "chef/resource/chef_user"
25
+ require "chef/resource/private_key"
26
+ require "chef/resource/public_key"
28
27
 
29
28
  class Chef
30
29
  module DSL
@@ -46,7 +45,7 @@ class Chef
46
45
  end
47
46
 
48
47
  def with_chef_local_server(options, &block)
49
- options[:host] ||= '127.0.0.1'
48
+ options[:host] ||= "127.0.0.1"
50
49
  options[:log_level] ||= Chef::Log.level
51
50
  options[:port] ||= ChefZero::VERSION.to_f >= 2.2 ? 8901.upto(9900) : 8901
52
51
 
@@ -57,7 +56,7 @@ class Chef
57
56
  end
58
57
 
59
58
  # Ensure all paths are given
60
- %w(acl client cookbook container data_bag environment group node role).each do |type|
59
+ %w{acl client cookbook container data_bag environment group node role}.each do |type|
61
60
  # Set the options as symbol keys and then copy to string keys
62
61
  string_key = "#{type}_path"
63
62
  symbol_key = "#{type}_path".to_sym
@@ -66,7 +65,7 @@ class Chef
66
65
  if options[:chef_repo_path].kind_of?(String)
67
66
  Chef::Util::PathHelper.join(options[:chef_repo_path], "#{type}s")
68
67
  else
69
- options[:chef_repo_path].map { |path| Chef::Util::PathHelper.join(path, "#{type}s")}
68
+ options[:chef_repo_path].map { |path| Chef::Util::PathHelper.join(path, "#{type}s") }
70
69
  end
71
70
  end
72
71
 
@@ -97,9 +96,9 @@ class Chef
97
96
  end
98
97
 
99
98
  class Config
100
- default(:profile) { ENV['CHEF_PROFILE'] || 'default' }
99
+ default(:profile) { ENV["CHEF_PROFILE"] || "default" }
101
100
  configurable(:private_keys)
102
- default(:private_key_paths) { [ Chef::Util::PathHelper.join(config_dir, 'keys'), Chef::Util::PathHelper.join(user_home, '.ssh') ] }
101
+ default(:private_key_paths) { [ Chef::Util::PathHelper.join(config_dir, "keys"), Chef::Util::PathHelper.join(user_home, ".ssh") ] }
103
102
  default(:private_key_write_path) { private_key_paths.first }
104
103
  end
105
104
 
@@ -128,9 +127,9 @@ end
128
127
 
129
128
  # Chef 12 moved Chef::Config.path_join to PathHelper.join
130
129
  if Chef::VERSION.to_i >= 12
131
- require 'chef/util/path_helper'
130
+ require "chef/util/path_helper"
132
131
  else
133
- require 'chef/config'
132
+ require "chef/config"
134
133
  class Chef
135
134
  class Util
136
135
  class PathHelper
@@ -1,6 +1,6 @@
1
- require 'cheffish/rspec/chef_run_support'
2
- require 'cheffish/rspec/repository_support'
3
- require 'cheffish/rspec/matchers'
1
+ require "cheffish/rspec/chef_run_support"
2
+ require "cheffish/rspec/repository_support"
3
+ require "cheffish/rspec/matchers"
4
4
 
5
5
  module Cheffish
6
6
  module RSpec
@@ -1,10 +1,10 @@
1
- require 'chef_zero/rspec'
2
- require 'chef/server_api'
3
- require 'cheffish/rspec/repository_support'
4
- require 'uri'
5
- require 'cheffish/chef_run'
6
- require 'cheffish/rspec/recipe_run_wrapper'
7
- require 'cheffish/rspec/matchers'
1
+ require "chef_zero/rspec"
2
+ require "chef/server_api"
3
+ require "cheffish/rspec/repository_support"
4
+ require "uri"
5
+ require "cheffish/chef_run"
6
+ require "cheffish/rspec/recipe_run_wrapper"
7
+ require "cheffish/rspec/matchers"
8
8
 
9
9
  module Cheffish
10
10
  module RSpec
@@ -19,7 +19,7 @@ module Cheffish
19
19
  end
20
20
 
21
21
  def when_the_chef_12_server(*args, **options, &block)
22
- if Gem::Version.new(ChefZero::VERSION) >= Gem::Version.new('3.1')
22
+ if Gem::Version.new(ChefZero::VERSION) >= Gem::Version.new("3.1")
23
23
  when_the_chef_server(*args, :osc_compat => false, :single_org => false, **options, &block)
24
24
  end
25
25
  end
@@ -37,7 +37,7 @@ module Cheffish
37
37
  end
38
38
 
39
39
  def get(path, *args)
40
- if path[0] == '/'
40
+ if path[0] == "/"
41
41
  path = URI.join(rest.url, path)
42
42
  end
43
43
  rest.get(path, *args)
@@ -47,17 +47,17 @@ module Cheffish
47
47
  {}
48
48
  end
49
49
 
50
- def expect_recipe(str=nil, file=nil, line=nil, &recipe)
50
+ def expect_recipe(str = nil, file = nil, line = nil, &recipe)
51
51
  r = recipe(str, file, line, &recipe)
52
52
  r.converge
53
53
  expect(r)
54
54
  end
55
55
 
56
- def expect_converge(str=nil, file=nil, line=nil, &recipe)
56
+ def expect_converge(str = nil, file = nil, line = nil, &recipe)
57
57
  expect { converge(str, file, line, &recipe) }
58
58
  end
59
59
 
60
- def recipe(str=nil, file=nil, line=nil, &recipe)
60
+ def recipe(str = nil, file = nil, line = nil, &recipe)
61
61
  if !recipe
62
62
  if file && line
63
63
  recipe = proc { eval(str, nil, file, line) }
@@ -68,7 +68,7 @@ module Cheffish
68
68
  RecipeRunWrapper.new(chef_config, &recipe)
69
69
  end
70
70
 
71
- def converge(str=nil, file=nil, line=nil, &recipe)
71
+ def converge(str = nil, file = nil, line = nil, &recipe)
72
72
  r = recipe(str, file, line, &recipe)
73
73
  r.converge
74
74
  r
@@ -1,4 +1,4 @@
1
- require 'cheffish/rspec/matchers/have_updated'
2
- require 'cheffish/rspec/matchers/be_idempotent'
3
- require 'cheffish/rspec/matchers/partially_match'
4
- require 'cheffish/rspec/matchers/emit_no_warnings_or_errors'
1
+ require "cheffish/rspec/matchers/have_updated"
2
+ require "cheffish/rspec/matchers/be_idempotent"
3
+ require "cheffish/rspec/matchers/partially_match"
4
+ require "cheffish/rspec/matchers/emit_no_warnings_or_errors"
@@ -1,4 +1,4 @@
1
- require 'rspec/matchers'
1
+ require "rspec/matchers"
2
2
 
3
3
  RSpec::Matchers.define :be_idempotent do
4
4
  match do |recipe|
@@ -8,9 +8,9 @@ RSpec::Matchers.define :be_idempotent do
8
8
  recipe.up_to_date?
9
9
  end
10
10
 
11
- failure_message {
11
+ failure_message do
12
12
  "#{@recipe} is not idempotent! Converging it a second time caused updates.\n#{@recipe.output_for_failure_message}"
13
- }
13
+ end
14
14
 
15
15
  supports_block_expectations
16
16
  end
@@ -1,4 +1,4 @@
1
- require 'rspec/matchers'
1
+ require "rspec/matchers"
2
2
 
3
3
  RSpec::Matchers.define :emit_no_warnings_or_errors do
4
4
  match do |recipe|
@@ -7,9 +7,9 @@ RSpec::Matchers.define :emit_no_warnings_or_errors do
7
7
  @warn_err.empty?
8
8
  end
9
9
 
10
- failure_message {
10
+ failure_message do
11
11
  "#{@recipe} emitted warnings and errors!\n#{@warn_err}"
12
- }
12
+ end
13
13
 
14
14
  supports_block_expectations
15
15
  end
@@ -1,4 +1,4 @@
1
- require 'rspec/matchers'
1
+ require "rspec/matchers"
2
2
 
3
3
  RSpec::Matchers.define :have_updated do |resource_name, *expected_actions|
4
4
  match do |recipe|
@@ -14,7 +14,7 @@ RSpec::Matchers.define :have_updated do |resource_name, *expected_actions|
14
14
  updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
15
15
  result = "expected that the chef_run would #{expected_actions.join(',')} #{resource_name}."
16
16
  if updates.size > 0
17
- result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
17
+ result << " Actual updates were #{updates.map { |event, resource, action| "#{resource} => #{action.inspect}" }.join(', ')}"
18
18
  else
19
19
  result << " Nothing was updated."
20
20
  end
@@ -26,7 +26,7 @@ RSpec::Matchers.define :have_updated do |resource_name, *expected_actions|
26
26
  updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
27
27
  result = "expected that the chef_run would not #{expected_actions.join(',')} #{resource_name}."
28
28
  if updates.size > 0
29
- result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
29
+ result << " Actual updates were #{updates.map { |event, resource, action| "#{resource} => #{action.inspect}" }.join(', ')}"
30
30
  else
31
31
  result << " Nothing was updated."
32
32
  end
@@ -1,5 +1,5 @@
1
- require 'cheffish/chef_run'
2
- require 'forwardable'
1
+ require "cheffish/chef_run"
2
+ require "forwardable"
3
3
 
4
4
  module Cheffish
5
5
  module RSpec
@@ -7,7 +7,7 @@ module Cheffish
7
7
  def initialize(chef_config, example: nil, &recipe)
8
8
  super(chef_config)
9
9
  @recipe = recipe
10
- @example = example || recipe.binding.eval('self')
10
+ @example = example || recipe.binding.eval("self")
11
11
  end
12
12
 
13
13
  attr_reader :recipe
@@ -29,14 +29,14 @@ module Cheffish
29
29
  # 12.3-ish resource or we want to call a `let` variable.
30
30
  #
31
31
  @client.instance_eval { @rspec_example = example }
32
- def @client.method_missing(name, *args, &block)
32
+ def @client.method_missing(name, *args, &block) # rubocop:disable Lint/NestedMethodDefinition
33
33
  # If there is a let variable, call it. This is because in 12.4,
34
34
  # the parent class is going to call respond_to?(name) to find out
35
35
  # if someone was doing weird things, and then call send(). This
36
36
  # would result in an infinite loop, coming right. Back. Here.
37
37
  # A fix to chef is incoming, but we still need this if we want to
38
38
  # work with Chef 12.4.
39
- if Gem::Version.new(Chef::VERSION) >= Gem::Version.new('12.4')
39
+ if Gem::Version.new(Chef::VERSION) >= Gem::Version.new("12.4")
40
40
  if @rspec_example.respond_to?(name)
41
41
  return @rspec_example.public_send(name, *args, &block)
42
42
  end
@@ -55,9 +55,10 @@ module Cheffish
55
55
  end
56
56
  end
57
57
  end
58
+
58
59
  # This is called by respond_to?, and is required to make sure the
59
60
  # resource knows that we will in fact call the given method.
60
- def @client.respond_to_missing?(name, include_private = false)
61
+ def @client.respond_to_missing?(name, include_private = false) # rubocop:disable Lint/NestedMethodDefinition
61
62
  @rspec_example.respond_to?(name, include_private) || super
62
63
  end
63
64
 
@@ -65,7 +66,7 @@ module Cheffish
65
66
  # will hook resources up to the example let variables as well (via
66
67
  # enclosing_provider).
67
68
  # Please don't hurt me
68
- def @client.is_a?(klass)
69
+ def @client.is_a?(klass) # rubocop:disable Lint/NestedMethodDefinition
69
70
  klass == Chef::Provider || super(klass)
70
71
  end
71
72
 
@@ -12,9 +12,9 @@ module Cheffish
12
12
  ::RSpec.shared_context "with a chef repo" do
13
13
  before :each do
14
14
  raise "Can only create one directory per test" if @repository_dir
15
- @repository_dir = Dir.mktmpdir('chef_repo')
15
+ @repository_dir = Dir.mktmpdir("chef_repo")
16
16
  Chef::Config.chef_repo_path = @repository_dir
17
- %w(client cookbook data_bag environment node role user).each do |object_name|
17
+ %w{client cookbook data_bag environment node role user}.each do |object_name|
18
18
  Chef::Config.delete("#{object_name}_path".to_sym)
19
19
  end
20
20
  end
@@ -22,7 +22,7 @@ module Cheffish
22
22
  after :each do
23
23
  if @repository_dir
24
24
  begin
25
- %w(client cookbook data_bag environment node role user).each do |object_name|
25
+ %w{client cookbook data_bag environment node role user}.each do |object_name|
26
26
  Chef::Config.delete("#{object_name}_path".to_sym)
27
27
  end
28
28
  Chef::Config.delete(:chef_repo_path)
@@ -45,8 +45,8 @@ module Cheffish
45
45
  def file(relative_path, contents)
46
46
  filename = path_to(relative_path)
47
47
  dir = File.dirname(filename)
48
- FileUtils.mkdir_p(dir) unless dir == '.'
49
- File.open(filename, 'w') do |file|
48
+ FileUtils.mkdir_p(dir) unless dir == "."
49
+ File.open(filename, "w") do |file|
50
50
  raw = case contents
51
51
  when Hash, Array
52
52
  JSON.pretty_generate(contents)
@@ -60,7 +60,7 @@ module Cheffish
60
60
  def symlink(relative_path, relative_dest)
61
61
  filename = path_to(relative_path)
62
62
  dir = File.dirname(filename)
63
- FileUtils.mkdir_p(dir) unless dir == '.'
63
+ FileUtils.mkdir_p(dir) unless dir == "."
64
64
  dest_filename = path_to(relative_dest)
65
65
  File.symlink(dest_filename, filename)
66
66
  end