chef-umami 0.0.6 → 0.1.0

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
- SHA1:
3
- metadata.gz: 20229674bc6c78285cdb0e431520c7586128e9a5
4
- data.tar.gz: 67e17a4cd7045f7105f7ab83aecdc858e02fcfec
2
+ SHA256:
3
+ metadata.gz: c4b494656c612150234d8aadf2f2b9522ce278bf2a279d7de9c187a2afc63ec5
4
+ data.tar.gz: 790ea90397d73c0defa6c600246d66faa7c4618fd2ec337e091dd37a4779d2d1
5
5
  SHA512:
6
- metadata.gz: 93f9eaf93b7b68f378793c8745c6dda3235240a568093e0d7d82da4873d51a9e24eb08d34e8f3aaaf383c0a9f779c95c6b247c6e911319f22a462f99b91f96d2
7
- data.tar.gz: aec07f530e3fd0bbb618046315845f30927eb3cd8b37e9026202ebf62891f19128d9579f66debd12f5966331a886e07b613b80d96676640b259fe86aea9fd7bd
6
+ metadata.gz: ca092e6173b6b1d8827cf5191145b271341e159e4cb9ecff7ddaa4cf8e795f0ed3d551b49694e8f9ad7c4c4b4c5c2bde5742e571b918b6e3a75115afed39104a
7
+ data.tar.gz: aa896dd76d1e333b8e28144ad837d345228c751551d1ec0681f3f79d6ca36c65c8a1cfd2d677b9fccf74ff9fbd0ea57627c4b0bdd98b8a2a04e506a803ad37b3
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.0]
4
+
5
+ Updates to support modern Chef.
6
+
7
+ - Specifically Chef 14.x and ChefDK 3.4.x.
8
+ - Replaces the export/upload mechanism with the push mechanism as it does all that work anyhow.
9
+ - Honestly, the only thing being used by the previous export functionality was the Chef client config. The rest was waste.
10
+ - Updates `Umami::Client` to manage creating and ingesting the config we need.
11
+ - Adds `Umami::Policyfile::PolicyfileLock` as a convenience.
12
+ - Minor updates to address changes in Chef/ChefDK support and methods.
13
+ - Fixes up Rubocop support within Umami as well as that used for testing Umami itself.
14
+
3
15
  ## [0.0.6]
4
16
  - Adds tests.
5
17
  - Updates gem dependencies to use newer versions of Chef and ChefDK.
@@ -13,17 +13,96 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require 'chef'
16
+ require 'chef-umami/policyfile/policyfile_lock'
17
+ require 'tmpdir' # Extends Dir
18
+
19
+ # NOTE: Lifts some code from https://github.com/chef/chef-dk/blob/master/lib/chef-dk/policyfile_services/export_repo.rb
16
20
 
17
21
  module Umami
18
22
  class Client
19
- def initialize
20
- @client = client
23
+ attr_reader :config_path
24
+ attr_reader :policyfile
25
+ attr_reader :staging_dir # Where Umami will stage files.
26
+ def initialize(policyfile = nil)
27
+ @client = client
28
+ @policy_name = nil
29
+ @policyfile = policyfile
30
+ @staging_dir = Dir.mktmpdir('umami-')
31
+ @config_path = client_rb_staging_path
32
+ end
33
+
34
+ def policy_name
35
+ @policy_name ||= Umami::Policyfile::PolicyfileLock.new(policyfile).name
21
36
  end
22
37
 
23
38
  def client
24
39
  @client ||= Chef::Client.new
25
40
  end
26
41
 
42
+ def fake_client_key
43
+ File.join(staging_dir, 'umami.pem')
44
+ end
45
+
46
+ def cp_fake_client_key
47
+ # Create a fake client cert based on a dummy cert we have laying around.
48
+ fake_client_key_src = File.join(File.dirname(__FILE__), %w(.. .. support umami.pem))
49
+ FileUtils.cp(fake_client_key_src, fake_client_key)
50
+ end
51
+
52
+ def dot_chef_staging_dir
53
+ dot_dir = File.join(staging_dir, '.chef')
54
+ FileUtils.mkdir_p(dot_dir)
55
+ dot_dir
56
+ end
57
+
58
+ def client_rb_staging_path
59
+ File.join(dot_chef_staging_dir, 'config.rb')
60
+ end
61
+
62
+ def create_client_rb
63
+ File.open(client_rb_staging_path, 'wb+') do |f|
64
+ f.print(<<~CONFIG)
65
+ ### Chef Client Configuration ###
66
+ # The settings in this file will configure chef to apply the exported policy in
67
+ # this directory. To use it, run:
68
+ #
69
+ # chef-client -z
70
+ #
71
+ policy_name '#{policy_name}'
72
+ policy_group 'local'
73
+ use_policyfile true
74
+ policy_document_native_api true
75
+ chef_server_url 'http://127.0.0.1:8889'
76
+ node_name 'umami-node'
77
+ client_key '#{fake_client_key}'
78
+ # In order to use this repo, you need a version of Chef Client and Chef Zero
79
+ # that supports policyfile "native mode" APIs:
80
+ current_version = Gem::Version.new(Chef::VERSION)
81
+ unless Gem::Requirement.new(">= 12.7").satisfied_by?(current_version)
82
+ puts("!" * 80)
83
+ puts(<<-MESSAGE)
84
+ This Chef Repo requires features introduced in Chef 12.7, but you are using
85
+ Chef \#{Chef::VERSION}. Please upgrade to Chef 12.7 or later.
86
+ MESSAGE
87
+ puts("!" * 80)
88
+ exit!(1)
89
+ end
90
+ CONFIG
91
+ end
92
+ end
93
+
94
+ def build_config
95
+ create_client_rb
96
+ cp_fake_client_key
97
+ end
98
+
99
+ def apply_config!
100
+ build_config
101
+ Chef::Config.from_file(config_path)
102
+ # Define Chef::Config['config_file'] lest Ohai complain.
103
+ Chef::Config['config_file'] = config_path
104
+ end
105
+
27
106
  # Perform the steps required prior to compiling resources, including
28
107
  # running Ohai and building up the node object.
29
108
  def prep
@@ -32,7 +32,7 @@ module Umami
32
32
  r = RuboCop::CLI.new
33
33
  # Don't output to STDOUT.
34
34
  args = [
35
- '--only', 'Style/IndentationWidth,Style/IndentationConsistency',
35
+ '--only', 'Layout/IndentationWidth,Layout/IndentationConsistency',
36
36
  '--auto-correct',
37
37
  '--out', '/dev/null',
38
38
  path
@@ -12,35 +12,35 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'chef-dk/authenticated_http'
16
15
  require 'chef-dk/policyfile/storage_config'
17
- require 'chef-dk/policyfile/uploader'
18
16
  require 'chef-dk/policyfile_lock'
19
17
  require 'chef-dk/ui'
20
18
 
21
19
  module Umami
22
20
  class Policyfile
23
- class Uploader
24
- attr_reader :policyfile_lock_file
25
- def initialize(policyfile_lock_file = nil)
26
- @http_client = http_client
27
- @policyfile_lock_file = policyfile_lock_file
28
- @policyfile_lock = policyfile_lock
29
- @policyfile_uploader = policyfile_uploader
30
- @storage_config = storage_config
31
- @ui = ui
21
+ class PolicyfileLock
22
+ attr_reader :policyfile
23
+ def initialize(policyfile = nil)
24
+ @policyfile = policyfile
25
+ @policyfile_lock = nil
26
+ @storage_config = storage_config
27
+ @ui = ui
32
28
  end
33
29
 
34
30
  def storage_config
35
- @storage_config ||= ChefDK::Policyfile::StorageConfig.new.use_policyfile(policyfile_lock_file)
31
+ @storage_config ||= ChefDK::Policyfile::StorageConfig.new.use_policyfile(policyfile)
36
32
  end
37
33
 
38
34
  def ui
39
35
  @ui ||= ChefDK::UI.new
40
36
  end
41
37
 
38
+ def policyfile_lock_path
39
+ policyfile.gsub(/\.rb$/, '.lock.json')
40
+ end
41
+
42
42
  def policyfile_lock_content
43
- IO.read(policyfile_lock_file)
43
+ IO.read(policyfile_lock_path)
44
44
  end
45
45
 
46
46
  def lock_data
@@ -54,31 +54,8 @@ module Umami
54
54
  ).build_from_lock_data(lock_data)
55
55
  end
56
56
 
57
- def http_client
58
- @http_client ||= ChefDK::AuthenticatedHTTP.new(Chef::Config['chef_server_url'])
59
- end
60
-
61
- def policy_group
62
- Chef::Config['policy_group']
63
- end
64
-
65
- def policy_document_native_api
66
- true
67
- end
68
-
69
- def policyfile_uploader
70
- @policyfile_uploader ||= ChefDK::Policyfile::Uploader.new(
71
- policyfile_lock,
72
- policy_group,
73
- ui: ui,
74
- http_client: http_client,
75
- policy_document_native_api: policy_document_native_api
76
- )
77
- end
78
-
79
- # Push the policy, including all dependent cookbooks.
80
- def upload
81
- policyfile_uploader.upload
57
+ def name
58
+ policyfile_lock.name
82
59
  end
83
60
  end
84
61
  end
@@ -0,0 +1,46 @@
1
+ # Copyright 2017 Bloomberg Finance, L.P.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'chef-dk/policyfile_services/push'
16
+
17
+ module Umami
18
+ class PolicyfileServices
19
+ class Push < ChefDK::PolicyfileServices::Push
20
+ def initialize(policyfile: nil, ui: nil, policy_group: nil, config: nil, root_dir: nil)
21
+ super(policyfile: policyfile, ui: ui, policy_group: policy_group,
22
+ config: config, root_dir: root_dir)
23
+ end
24
+
25
+ # Keep up with the times and force use of the newer API.
26
+ def api_version
27
+ '2'
28
+ end
29
+
30
+ # We'll override the #http_client method to ensure we set the appropriate
31
+ # API version we expect to be used. Chef::Authenticator#request_version
32
+ # will use this to set the appropriate header that Chef Server (Zero)
33
+ # uses to determine how to generate cookbook manifests. Without this, we
34
+ # see issues during the Umami::Client#compile phase where Chef cannot
35
+ # locate recipes within a cookbook and `umami` fails miserably.
36
+ # I spent a week debugging this when trying to update `umami` to support
37
+ # newer Chef libraries. That, too, was miserable.
38
+ def http_client
39
+ @http_client ||= Chef::ServerAPI.new(config.chef_server_url,
40
+ signing_key_filename: config.client_key,
41
+ client_name: config.node_name,
42
+ api_version: api_version)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -18,10 +18,10 @@ require 'chef-umami/client'
18
18
  require 'chef-umami/logger'
19
19
  require 'chef-umami/options'
20
20
  require 'chef-umami/server'
21
- require 'chef-umami/policyfile/exporter'
22
- require 'chef-umami/policyfile/uploader'
21
+ require 'chef-umami/policyfile_services/push'
23
22
  require 'chef-umami/test/unit'
24
23
  require 'chef-umami/test/integration'
24
+ require 'chef-dk/ui'
25
25
 
26
26
  module Umami
27
27
  class Runner
@@ -30,24 +30,36 @@ module Umami
30
30
 
31
31
  attr_reader :cookbook_dir
32
32
  def initialize
33
- @config = config
33
+ @umami_config = umami_config
34
34
  @cookbook_dir = Dir.pwd
35
- @exporter = exporter
36
- @chef_zero_server = chef_zero_server
37
- # If we load the uploader or client now, they won't see the updated
38
- # Chef config!
39
- @uploader = nil
35
+ ## If we load the pusher or client now, they won't see the updated
36
+ ## Chef config!
37
+ @push = nil
40
38
  @chef_client = nil
39
+ @ui = ui
41
40
  end
42
41
 
43
- # A hash of values describing the config. Comprised of command line
42
+ # A hash of values describing the Umami config. Comprised of command line
44
43
  # options. May (in the future) contain options read from a config file.
45
- def config
46
- @config ||= parse_options
44
+ def umami_config
45
+ @umami_config ||= parse_options
46
+ end
47
+
48
+ # Convenience to return the Chef::Config singleton.
49
+ def chef_config
50
+ Chef::Config
51
+ end
52
+
53
+ def ui
54
+ @ui ||= ChefDK::UI.new
47
55
  end
48
56
 
49
57
  def policyfile
50
- config[:policyfile]
58
+ umami_config[:policyfile]
59
+ end
60
+
61
+ def policy_group
62
+ chef_config['policy_group']
51
63
  end
52
64
 
53
65
  # Return the computed policyfile lock name.
@@ -65,12 +77,14 @@ module Umami
65
77
  end
66
78
  end
67
79
 
68
- def exporter
69
- @exporter ||= Umami::Policyfile::Exporter.new(policyfile_lock_file, cookbook_dir, policyfile)
70
- end
71
-
72
- def uploader
73
- @uploader ||= Umami::Policyfile::Uploader.new(policyfile_lock_file)
80
+ def push
81
+ # rubocop:disable Layout/AlignHash
82
+ @push ||= Umami::PolicyfileServices::Push.new(policyfile: policyfile,
83
+ ui: ui,
84
+ policy_group: policy_group,
85
+ config: chef_config,
86
+ root_dir: cookbook_dir)
87
+ # rubocop:enable Layout/AlignHash
74
88
  end
75
89
 
76
90
  def chef_zero_server
@@ -78,31 +92,27 @@ module Umami
78
92
  end
79
93
 
80
94
  def chef_client
81
- @chef_client ||= Umami::Client.new
95
+ @chef_client ||= Umami::Client.new(policyfile)
82
96
  end
83
97
 
84
98
  def run
85
99
  validate_lock_file!
86
- puts "\nExporting the policy, related cookbooks, and a valid client configuration..."
87
- exporter.export
88
- Chef::Config.from_file(exporter.chef_config_file)
100
+ chef_client.apply_config!
89
101
  chef_zero_server.start
90
102
  puts "\nUploading the policy and related cookbooks..."
91
- uploader.upload
103
+ push.run
92
104
  puts "\nExecuting chef-client compile phase..."
93
- # Define Chef::Config['config_file'] lest Ohai complain.
94
- Chef::Config['config_file'] = exporter.chef_config_file
95
105
  chef_client.compile
96
106
  # Build a hash of all the recipes' resources, keyed by the canonical
97
107
  # name of the recipe (i.e. ohai::default).
98
108
  recipe_resources = {}
99
109
  chef_client.resource_collection.each do |resource|
100
110
  canonical_recipe = "#{resource.cookbook_name}::#{resource.recipe_name}"
101
- unless config[:recipes].empty?
111
+ unless umami_config[:recipes].nil? || umami_config[:recipes].empty?
102
112
  # The user has explicitly requested that one or more recipes have
103
113
  # tests written, to the exclusion of others.
104
114
  # ONLY include the recipe if it matches the list.
105
- next unless config[:recipes].include?(canonical_recipe)
115
+ next unless umami_config[:recipes].include?(canonical_recipe)
106
116
  end
107
117
  if recipe_resources.key?(canonical_recipe)
108
118
  recipe_resources[canonical_recipe] << resource
@@ -114,17 +124,17 @@ module Umami
114
124
  # Remove the temporary directory using a naive guard to ensure we're
115
125
  # deleting what we expect.
116
126
  re_export_path = Regexp.new('/tmp/umami')
117
- FileUtils.rm_rf(exporter.export_root) if exporter.export_root.match(re_export_path)
127
+ FileUtils.rm_rf(chef_client.staging_dir) if chef_client.staging_dir.match(re_export_path)
118
128
 
119
- if config[:unit_tests]
129
+ if umami_config[:unit_tests]
120
130
  puts "\nGenerating a set of unit tests..."
121
- unit_tester = Umami::Test::Unit.new(config[:test_root])
131
+ unit_tester = Umami::Test::Unit.new(umami_config[:test_root])
122
132
  unit_tester.generate(recipe_resources)
123
133
  end
124
134
 
125
- if config[:integration_tests]
135
+ if umami_config[:integration_tests]
126
136
  puts "\nGenerating a set of integration tests..."
127
- integration_tester = Umami::Test::Integration.new(config[:test_root])
137
+ integration_tester = Umami::Test::Integration.new(umami_config[:test_root])
128
138
  integration_tester.generate(recipe_resources)
129
139
  end
130
140
  end
@@ -49,6 +49,7 @@ module Umami
49
49
  return if resource.action.include?(:delete)
50
50
  end
51
51
  return if resource.action == :delete
52
+
52
53
  "\n" + send("test_#{resource.declared_type}", resource)
53
54
  end
54
55
 
@@ -60,8 +60,9 @@ module Umami
60
60
 
61
61
  def write_test(resource = nil)
62
62
  state_attrs = [] # Attribute hash to be used with #with()
63
- resource.state.each do |attr, value|
63
+ resource.state_for_resource_reporter.each do |attr, value|
64
64
  next if value.nil? || (value.respond_to?(:empty) && value.empty?)
65
+
65
66
  if value.is_a? String
66
67
  value = value.gsub("'", "\\\\'") # Escape any single quotes in the value.
67
68
  end
@@ -90,6 +91,7 @@ module Umami
90
91
  (cookbook, recipe) = canonical_recipe.split('::')
91
92
  # Only write unit tests for the cookbook we're in.
92
93
  next unless cookbook == tested_cookbook
94
+
93
95
  content = [preamble(cookbook, recipe)]
94
96
  resources.each do |resource|
95
97
  content << write_test(resource)
@@ -13,5 +13,5 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module Umami
16
- VERSION = '0.0.6'.freeze
16
+ VERSION = '0.1.0'.freeze
17
17
  end
@@ -18,17 +18,16 @@ RSpec.describe Umami::Runner do
18
18
  it 'initiates a Umami::Runner object' do
19
19
  runner = Umami::Runner.new
20
20
  expect(runner).to be_an_instance_of(Umami::Runner)
21
- expect(runner.exporter).to be_an_instance_of(Umami::Policyfile::Exporter)
22
21
  expect(runner.chef_zero_server).to be_an_instance_of(Umami::Server)
23
22
  end
24
23
 
25
24
  context 'with no options provided' do
26
25
  it 'sets proper defaults' do
27
26
  runner = Umami::Runner.new
28
- expect(runner.config[:integration_tests]).to be true
27
+ expect(runner.umami_config[:integration_tests]).to be true
29
28
  expect(runner.policyfile).to eq("Policyfile.rb")
30
- expect(runner.config[:test_root]).to eq("spec")
31
- expect(runner.config[:unit_tests]).to be true
29
+ expect(runner.umami_config[:test_root]).to eq("spec")
30
+ expect(runner.umami_config[:unit_tests]).to be true
32
31
  end
33
32
  end
34
33
 
@@ -41,10 +40,10 @@ RSpec.describe Umami::Runner do
41
40
  my_argv.flatten!
42
41
  stub_const("ARGV", my_argv)
43
42
  runner = Umami::Runner.new
44
- expect(runner.config[:integration_tests]).to be false
43
+ expect(runner.umami_config[:integration_tests]).to be false
45
44
  expect(runner.policyfile).to eq("test_policy.rb")
46
- expect(runner.config[:test_root]).to eq("dust_spec")
47
- expect(runner.config[:unit_tests]).to be false
45
+ expect(runner.umami_config[:test_root]).to eq("dust_spec")
46
+ expect(runner.umami_config[:unit_tests]).to be false
48
47
  end
49
48
  end
50
49
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-umami
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Frantz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-26 00:00:00.000000000 Z
11
+ date: 2019-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '13.0'
19
+ version: '14'
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: '13.0'
26
+ version: '14'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: chef-dk
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.5'
33
+ version: '3'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.5'
40
+ version: '3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rubocop
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.47'
47
+ version: '0.69'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.47'
54
+ version: '0.69'
55
55
  description: A tool to generate unit/integration tests for Chef cookbooks and policy
56
56
  files.
57
57
  email:
@@ -76,8 +76,8 @@ files:
76
76
  - lib/chef-umami/logger.rb
77
77
  - lib/chef-umami/options.rb
78
78
  - lib/chef-umami/policyfile.rb
79
- - lib/chef-umami/policyfile/exporter.rb
80
- - lib/chef-umami/policyfile/uploader.rb
79
+ - lib/chef-umami/policyfile/policyfile_lock.rb
80
+ - lib/chef-umami/policyfile_services/push.rb
81
81
  - lib/chef-umami/runner.rb
82
82
  - lib/chef-umami/server.rb
83
83
  - lib/chef-umami/test.rb
@@ -107,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
107
  version: '0'
108
108
  requirements: []
109
109
  rubyforge_project:
110
- rubygems_version: 2.6.11
110
+ rubygems_version: 2.7.9
111
111
  signing_key:
112
112
  specification_version: 4
113
113
  summary: A tool to generate unit/integration tests for Chef cookbooks and policy files.
@@ -1,101 +0,0 @@
1
- # Copyright 2017 Bloomberg Finance, L.P.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- require 'chef-dk/policyfile_services/install'
16
- require 'chef-dk/policyfile_services/export_repo'
17
- require 'chef-dk/ui'
18
- require 'tmpdir' # Extends Dir
19
-
20
- module Umami
21
- class Policyfile
22
- class Exporter
23
- attr_reader :chef_config_file
24
- attr_reader :cookbook_dir
25
- attr_reader :export_root
26
- attr_reader :export_path
27
- attr_reader :policyfile
28
- attr_accessor :policyfile_lock_file
29
-
30
- def initialize(policyfile_lock_file = nil, cookbook_dir = nil, policyfile = nil)
31
- @policyfile = policyfile
32
- @export_root = Dir.mktmpdir('umami-')
33
- # We need the target dir named the same as the source dir so that `chef` commands
34
- # work as happily programatically as they would via the command line.
35
- # This is because the commands assume they're being run from within a cookbook
36
- # directory.
37
- @export_path = File.join(export_root, cookbook_dir)
38
- @chef_config_file = "#{export_path}/.chef/config.rb"
39
- end
40
-
41
- def ui
42
- @ui ||= ChefDK::UI.new
43
- end
44
-
45
- # Execute `chef install` to ensure we get a fresh, clean Policyfile lock
46
- # file on each run.
47
- def install_policy
48
- puts "Generating a new Policyfile from '#{policyfile}'..."
49
- install_service = ChefDK::PolicyfileServices::Install.new(
50
- policyfile: policyfile,
51
- ui: ui
52
- )
53
- @policyfile_lock_file = install_service.storage_config.policyfile_lock_filename
54
- install_service.run
55
- end
56
-
57
- def fake_client_key
58
- "#{export_path}/umami.pem"
59
- end
60
-
61
- def cp_fake_client_key
62
- # Create a fake client cert based on a dummy cert we have laying around.
63
- fake_client_key_src = File.join(File.dirname(__FILE__), %w(.. .. .. support umami.pem))
64
- FileUtils.cp(fake_client_key_src, fake_client_key)
65
- end
66
-
67
- def update_chef_config
68
- File.open(chef_config_file, 'a') do |f|
69
- f.puts "chef_server_url 'http://127.0.0.1:8889'"
70
- f.puts "cookbook_path ['#{export_path}/cookbook_artifacts']"
71
- f.puts "client_key '#{fake_client_key}'"
72
- f.puts "node_name 'umami-node'"
73
- end
74
- end
75
-
76
- # Export the cookbook and prepare a chef-zero-compatible directory.
77
- # We'll use this as a temporary launch pad for things, as needed, akin
78
- # to test-kitchen's sandbox.
79
- def export
80
- install_policy
81
- export_service = ChefDK::PolicyfileServices::ExportRepo.new(
82
- policyfile: policyfile_lock_file,
83
- export_dir: export_path
84
- )
85
- begin
86
- export_service.run
87
- rescue ChefDK::PolicyfileExportRepoError => e
88
- puts "\nFAILED TO EXPORT POLICYFILE: #{e.message} (#{e.class})"
89
- puts "CAUSE: #{e.cause}"
90
- puts 'BACKTRACE:'
91
- e.backtrace.each do |line|
92
- puts "\t#{line}"
93
- end
94
- exit(1)
95
- end
96
- cp_fake_client_key
97
- update_chef_config
98
- end
99
- end
100
- end
101
- end