chef-cli 5.5.4 → 5.6.1

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.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef-cli/command/generate.rb +12 -6
  3. data/lib/chef-cli/command/generator_commands/chef_exts/quieter_doc_formatter.rb +9 -0
  4. data/lib/chef-cli/command/generator_commands/cookbook.rb +1 -1
  5. data/lib/chef-cli/command/generator_commands/input.rb +37 -0
  6. data/lib/chef-cli/command/generator_commands/profile.rb +37 -0
  7. data/lib/chef-cli/command/generator_commands/waiver.rb +37 -0
  8. data/lib/chef-cli/command/push.rb +9 -0
  9. data/lib/chef-cli/configurable.rb +5 -1
  10. data/lib/chef-cli/generator.rb +15 -0
  11. data/lib/chef-cli/skeletons/code_generator/recipes/cookbook.rb +13 -14
  12. data/lib/chef-cli/skeletons/code_generator/recipes/input.rb +13 -0
  13. data/lib/chef-cli/skeletons/code_generator/recipes/profile.rb +22 -0
  14. data/lib/chef-cli/skeletons/code_generator/recipes/waiver.rb +13 -0
  15. data/lib/chef-cli/skeletons/code_generator/templates/default/compliance_dir_README.md.erb +25 -0
  16. data/lib/chef-cli/skeletons/code_generator/templates/default/compliance_profile_control.rb.erb +14 -0
  17. data/lib/chef-cli/skeletons/code_generator/templates/default/compliance_profile_inspec.yml.erb +16 -0
  18. data/lib/chef-cli/skeletons/code_generator/templates/default/input.yml.erb +8 -0
  19. data/lib/chef-cli/skeletons/code_generator/templates/default/waiver.yml.erb +10 -0
  20. data/lib/chef-cli/version.rb +1 -1
  21. data/spec/shared/custom_generator_cookbook.rb +44 -0
  22. data/spec/unit/command/generator_commands/cookbook_spec.rb +336 -5
  23. data/spec/unit/command/generator_commands/input_spec.rb +31 -0
  24. data/spec/unit/command/generator_commands/profile_spec.rb +34 -0
  25. data/spec/unit/command/generator_commands/waiver_spec.rb +31 -0
  26. metadata +19 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dfeb3741f305634bdb91164a529d57fda8ba8dd8ee1a74f942e4e38eb521e79f
4
- data.tar.gz: 5f57c0483c71fc7732ad9fec53ee0954022ac35194ba0f4a5909239c10d17e2d
3
+ metadata.gz: 308c1bbb1d1f4d2070055036818dc566c577d28cd3c6ab476054029302082676
4
+ data.tar.gz: a5cc534e4f0d0ae65347b5b438ffc968b4dc982078a37e6c89ff1a351eee4ee3
5
5
  SHA512:
6
- metadata.gz: f8dc515d741fe02197afead1faa446a632b6a71f918370df34585c66b33ef8c760b6ff2f7c14bad37cfdeaaa24f3e98a3884065336912fd8b5982039d43012d5
7
- data.tar.gz: 168e5f6b65ef26172869372c3d2af1f2bc2e0f910ae65c12303d3856d1c4e4dd715a3d1c59ef17067feeea217f03912864f30b5a90e1f6f13e0dc13005a48388
6
+ metadata.gz: 6d53620886e274948207b24d28dcb1bae9f3b784d64783ae42b9698f5359c6ef1653bb1a65417d3309a0bdef10d3254663049447c9a6cdfdcfe1321739335a7d
7
+ data.tar.gz: abc2a02f25e66edb3bd03b9c1a4903310f1029f699107b23565e3629cacb65b8254faaacb8354f2a00b1c9b6155eaa39df1f3709542eb840f5a2477310b221e4
@@ -29,6 +29,9 @@ require_relative "generator_commands/template"
29
29
  require_relative "generator_commands/repo"
30
30
  require_relative "generator_commands/policyfile"
31
31
  require_relative "generator_commands/generator_generator"
32
+ require_relative "generator_commands/input"
33
+ require_relative "generator_commands/profile"
34
+ require_relative "generator_commands/waiver"
32
35
  require_relative "../dist"
33
36
 
34
37
  module ChefCLI
@@ -45,16 +48,19 @@ module ChefCLI
45
48
  generators << GeneratorCommand.new(name, class_name, description)
46
49
  end
47
50
 
48
- generator(:cookbook, :Cookbook, "Generate a single cookbook")
49
- generator(:recipe, :Recipe, "Generate a new recipe")
50
51
  generator(:attribute, :Attribute, "Generate an attributes file")
51
- generator(:template, :Template, "Generate a file template")
52
+ generator(:cookbook, :Cookbook, "Generate a single cookbook")
52
53
  generator(:file, :CookbookFile, "Generate a cookbook file")
54
+ generator(:generator, :GeneratorGenerator, "Copy #{ChefCLI::Dist::PRODUCT}'s generator cookbook so you can customize it")
53
55
  generator(:helpers, :Helpers, "Generate a cookbook helper file in libraries")
54
- generator(:resource, :Resource, "Generate a custom resource")
55
- generator(:repo, :Repo, "Generate a #{ChefCLI::Dist::INFRA_PRODUCT} code repository")
56
+ generator(:input, :Input, "Generate a Compliance Phase #{ChefCLI::Dist::INSPEC_PRODUCT} Input file")
56
57
  generator(:policyfile, :Policyfile, "Generate a Policyfile for use with the install/push commands")
57
- generator(:generator, :GeneratorGenerator, "Copy #{ChefCLI::Dist::PRODUCT}'s generator cookbook so you can customize it")
58
+ generator(:profile, :Profile, "Generate a Compliance Phase #{ChefCLI::Dist::INSPEC_PRODUCT} profile")
59
+ generator(:recipe, :Recipe, "Generate a new recipe")
60
+ generator(:repo, :Repo, "Generate a #{ChefCLI::Dist::INFRA_PRODUCT} code repository")
61
+ generator(:resource, :Resource, "Generate a custom resource")
62
+ generator(:template, :Template, "Generate a file template")
63
+ generator(:waiver, :Waiver, "Generate a Compliance Phase #{ChefCLI::Dist::INSPEC_PRODUCT} Waiver file")
58
64
 
59
65
  def self.banner_headline
60
66
  <<~E
@@ -32,5 +32,14 @@ module ChefCLI
32
32
 
33
33
  # Called when cookbook loading starts.
34
34
  def library_load_start(file_count); end
35
+
36
+ # Called when cookbook loading starts.
37
+ def profiles_load_start; end
38
+
39
+ # Called when cookbook loading starts.
40
+ def inputs_load_start; end
41
+
42
+ # Called when cookbook loading starts.
43
+ def waivers_load_start; end
35
44
  end
36
45
  end
@@ -86,7 +86,7 @@ module ChefCLI
86
86
  option :pipeline,
87
87
  long: "--pipeline PIPELINE",
88
88
  description: "REMOVED: #{ChefCLI::Dist::WORKFLOW} is EOL. This option has been removed.",
89
- default: "master"
89
+ default: nil
90
90
 
91
91
  options.merge!(SharedGeneratorOptions.options)
92
92
 
@@ -0,0 +1,37 @@
1
+ #
2
+ # Copyright:: 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_relative "cookbook_code_file"
19
+ require_relative "../../dist"
20
+
21
+ module ChefCLI
22
+ module Command
23
+ module GeneratorCommands
24
+ # chef generate input [path/to/cookbook_root] NAME
25
+ class Input < CookbookCodeFile
26
+
27
+ banner "Usage: #{ChefCLI::Dist::EXEC} generate input [path/to/cookbook] NAME [options]"
28
+
29
+ options.merge!(SharedGeneratorOptions.options)
30
+
31
+ def recipe
32
+ "input"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ #
2
+ # Copyright:: 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_relative "cookbook_code_file"
19
+ require_relative "../../dist"
20
+
21
+ module ChefCLI
22
+ module Command
23
+ module GeneratorCommands
24
+ # chef generate profile [path/to/cookbook_root] NAME
25
+ class Profile < CookbookCodeFile
26
+
27
+ banner "Usage: #{ChefCLI::Dist::EXEC} generate profile [path/to/cookbook] NAME [options]"
28
+
29
+ options.merge!(SharedGeneratorOptions.options)
30
+
31
+ def recipe
32
+ "profile"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ #
2
+ # Copyright:: 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_relative "cookbook_code_file"
19
+ require_relative "../../dist"
20
+
21
+ module ChefCLI
22
+ module Command
23
+ module GeneratorCommands
24
+ # chef generate waiver [path/to/cookbook_root] NAME
25
+ class Waiver < CookbookCodeFile
26
+
27
+ banner "Usage: #{ChefCLI::Dist::EXEC} generate waiver [path/to/cookbook] NAME [options]"
28
+
29
+ options.merge!(SharedGeneratorOptions.options)
30
+
31
+ def recipe
32
+ "waiver"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -44,6 +44,15 @@ module ChefCLI
44
44
 
45
45
  E
46
46
 
47
+ option :credential,
48
+ long: "--credentials string",
49
+ description: "The credentials file to load for user profiles (default $HOME/.chef/credentials)"
50
+
51
+ option :profile,
52
+ short: "-p",
53
+ long: "--profile PROFILE",
54
+ description: "The credentials profile to select."
55
+
47
56
  attr_reader :policyfile_relative_path
48
57
  attr_reader :policy_group
49
58
 
@@ -61,7 +61,11 @@ module ChefCLI
61
61
  end
62
62
 
63
63
  def config_loader
64
- @config_loader ||= Chef::WorkstationConfigLoader.new(config[:config_file])
64
+ if !config[:profile].nil?
65
+ @config_loader ||= Chef::WorkstationConfigLoader.new(config[:config_file], profile: config[:profile])
66
+ else
67
+ @config_loader ||= Chef::WorkstationConfigLoader.new(config[:config_file])
68
+ end
65
69
  end
66
70
 
67
71
  def generator_config
@@ -68,6 +68,21 @@ module ChefCLI
68
68
  Time.now.year
69
69
  end
70
70
 
71
+ def self.license_long(license = nil)
72
+ case license
73
+ when "apachev2"
74
+ "Apache-2.0"
75
+ when "mit"
76
+ "MIT"
77
+ when "gplv2"
78
+ "GPL-2.0"
79
+ when "gplv3"
80
+ "GPL-3.0"
81
+ else
82
+ "All Rights Reserved"
83
+ end
84
+ end
85
+
71
86
  # Prints the short description of the license, suitable for use in a
72
87
  # preamble to a file. Optionally specify a comment to prepend to each line.
73
88
  def license_description(comment = nil)
@@ -9,23 +9,10 @@ generator_desc('Ensuring correct cookbook content')
9
9
  directory cookbook_dir
10
10
 
11
11
  # metadata.rb
12
- spdx_license = case context.license
13
- when 'apachev2'
14
- 'Apache-2.0'
15
- when 'mit'
16
- 'MIT'
17
- when 'gplv2'
18
- 'GPL-2.0'
19
- when 'gplv3'
20
- 'GPL-3.0'
21
- else
22
- 'All Rights Reserved'
23
- end
24
-
25
12
  template "#{cookbook_dir}/metadata.rb" do
26
13
  helpers(ChefCLI::Generator::TemplateHelper)
27
14
  variables(
28
- spdx_license: spdx_license
15
+ spdx_license: ChefCLI::Generator::TemplateHelper.license_long(context.license)
29
16
  )
30
17
  action :create_if_missing
31
18
  end
@@ -131,6 +118,18 @@ else
131
118
  end
132
119
  end
133
120
 
121
+ # compliance phase
122
+ %w(inputs profiles waivers).each do |dir|
123
+ directory "#{cookbook_dir}/compliance/#{dir}" do
124
+ recursive true
125
+ end
126
+ end
127
+
128
+ template "#{cookbook_dir}/compliance/README.md" do
129
+ source 'compliance_dir_README.md.erb'
130
+ action :create_if_missing
131
+ end
132
+
134
133
  # git
135
134
  if context.have_git
136
135
  unless context.skip_git_init
@@ -0,0 +1,13 @@
1
+ context = ChefCLI::Generator.context
2
+ cookbook_dir = File.join(context.cookbook_root, context.cookbook_name)
3
+ input_dir = File.join(cookbook_dir, 'compliance', 'inputs')
4
+ input_path = File.join(input_dir, "#{context.new_file_basename}.yml")
5
+
6
+ directory input_dir do
7
+ recursive true
8
+ end
9
+
10
+ template input_path do
11
+ source 'input.yml.erb'
12
+ helpers(ChefCLI::Generator::TemplateHelper)
13
+ end
@@ -0,0 +1,22 @@
1
+ context = ChefCLI::Generator.context
2
+ cookbook_dir = File.join(context.cookbook_root, context.cookbook_name)
3
+ profile_dir = File.join(cookbook_dir, 'compliance', 'profiles', "#{context.new_file_basename}")
4
+ control_dir = File.join(profile_dir, 'controls')
5
+
6
+ directory control_dir do
7
+ recursive true
8
+ end
9
+
10
+ template "#{profile_dir}/inspec.yml" do
11
+ source 'compliance_profile_inspec.yml.erb'
12
+ helpers(ChefCLI::Generator::TemplateHelper)
13
+ variables(
14
+ spdx_license: ChefCLI::Generator::TemplateHelper.license_long(context.license),
15
+ profile_name: context.new_file_basename
16
+ )
17
+ end
18
+
19
+ template "#{control_dir}/example.rb" do
20
+ source 'compliance_profile_control.rb.erb'
21
+ helpers(ChefCLI::Generator::TemplateHelper)
22
+ end
@@ -0,0 +1,13 @@
1
+ context = ChefCLI::Generator.context
2
+ cookbook_dir = File.join(context.cookbook_root, context.cookbook_name)
3
+ waiver_dir = File.join(cookbook_dir, 'compliance', 'waivers')
4
+ waiver_path = File.join(waiver_dir, "#{context.new_file_basename}.yml")
5
+
6
+ directory waiver_dir do
7
+ recursive true
8
+ end
9
+
10
+ template waiver_path do
11
+ source 'waiver.yml.erb'
12
+ helpers(ChefCLI::Generator::TemplateHelper)
13
+ end
@@ -0,0 +1,25 @@
1
+ # compliance
2
+
3
+ This directory contains <%= ChefCLI::Dist::INSPEC_PRODUCT %> profile, waiver and input objects which are used with the <%= ChefCLI::Dist::INFRA_PRODUCT %> Compliance Phase.
4
+
5
+ Detailed information on the <%= ChefCLI::Dist::INFRA_PRODUCT %> Compliance Phase can be found in the [Chef Documentation](https://docs.chef.io/chef_compliance_phase/).
6
+
7
+ ```plain
8
+ ./compliance
9
+ ├── inputs
10
+ ├── profiles
11
+ └── waivers
12
+ ```
13
+
14
+ Use the `<%= ChefCLI::Dist::EXEC %> generate` command from <%= ChefCLI::Dist::PRODUCT %> to create content for these directories:
15
+
16
+ ```sh
17
+ # Generate a <%= ChefCLI::Dist::INSPEC_PRODUCT %> profile
18
+ <%= ChefCLI::Dist::EXEC %> generate profile PROFILE_NAME
19
+
20
+ # Generate a <%= ChefCLI::Dist::INSPEC_PRODUCT %> waiver file
21
+ <%= ChefCLI::Dist::EXEC %> generate waiver WAIVER_NAME
22
+
23
+ # Generate a <%= ChefCLI::Dist::INSPEC_PRODUCT %> input file
24
+ <%= ChefCLI::Dist::EXEC %> generate input INPUT_NAME
25
+ ```
@@ -0,0 +1,14 @@
1
+ # Cookbook:: <%= cookbook_name %>
2
+
3
+ # The <%= ChefCLI::Dist::INSPEC_PRODUCT %> reference, with examples and extensive documentation, can be
4
+ # found at https://docs.chef.io/inspec/resources/
5
+
6
+ control 'example_control' do
7
+ impact 0.7
8
+ title 'Example Control'
9
+ desc 'This is an example control. Replace with real test content.'
10
+
11
+ describe user('root'), :skip do
12
+ it { should exist }
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ ---
2
+ # Cookbook:: <%= cookbook_name %>
3
+
4
+ # The <%= ChefCLI::Dist::INSPEC_PRODUCT %> reference, with examples and extensive documentation, can be
5
+ # found at https://docs.chef.io/inspec/profiles/
6
+
7
+ name: <%= @profile_name %>
8
+ title: <%= @profile_name %>
9
+ maintainer: <%= copyright_holder %>
10
+ copyright: <%= copyright_holder %>
11
+ copyright_email: <%= email %>
12
+ license: <%= @spdx_license %>
13
+ summary: A <%= ChefCLI::Dist::INSPEC_PRODUCT %> Compliance Profile
14
+ version: 0.1.0
15
+ supports:
16
+ platform: os
@@ -0,0 +1,8 @@
1
+ ---
2
+ # Cookbook:: <%= cookbook_name %>
3
+
4
+ # Additional information can be found on the <%= ChefCLI::Dist::INSPEC_PRODUCT %> Documentation site https://docs.chef.io/inspec/inputs/
5
+
6
+ # Example Syntax:
7
+ input_a_name: input_a_value
8
+ input_b_name: input_b_value
@@ -0,0 +1,10 @@
1
+ ---
2
+ # Cookbook:: <%= cookbook_name %>
3
+
4
+ # Additional information can be found on the <%= ChefCLI::Dist::INSPEC_PRODUCT %> Documentation site https://docs.chef.io/inspec/waivers/
5
+
6
+ # Example Syntax:
7
+ control_id_to_waive:
8
+ expiration_date: 2050-12-31
9
+ run: false
10
+ justification: "This is the text that will be included with the InSpec report supplying the reason this control is waived."
@@ -16,5 +16,5 @@
16
16
  #
17
17
 
18
18
  module ChefCLI
19
- VERSION = "5.5.4".freeze
19
+ VERSION = "5.6.1".freeze
20
20
  end
@@ -66,6 +66,23 @@ shared_examples_for "custom generator cookbook" do
66
66
  end
67
67
  end
68
68
 
69
+ context "with an invalid generator-cookbook path" do
70
+
71
+ it "fails with an informative error" do
72
+ Dir.chdir(tempdir) do
73
+ allow(code_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
74
+ allow(code_generator).to receive(:stderr).and_return(stderr_io)
75
+ expect(code_generator.run).to eq(1)
76
+ end
77
+
78
+ cookbook_path = File.dirname(generator_cookbook_path)
79
+ expected_msg = %Q{ERROR: Could not find cookbook(s) to satisfy run list ["recipe[a_generator_cookbook::#{generator_name}]"] in #{cookbook_path}}
80
+
81
+ expect(stderr_io.string).to include(expected_msg)
82
+ end
83
+
84
+ end
85
+
69
86
  context "with a generator-cookbook path to a specific cookbook" do
70
87
 
71
88
  let(:metadata_file) { File.join(generator_cookbook_path, "metadata.rb") }
@@ -88,5 +105,32 @@ shared_examples_for "custom generator cookbook" do
88
105
  end
89
106
 
90
107
  end
108
+
109
+ context "with a generator-cookbook path to a directory containing a 'code_generator' cookbook" do
110
+
111
+ before do
112
+ FileUtils.mkdir_p(generator_cookbook_path)
113
+ FileUtils.cp_r(default_generator_cookbook_path, generator_cookbook_path)
114
+
115
+ allow(code_generator).to receive(:stderr).and_return(stderr_io)
116
+ end
117
+
118
+ it "creates the new_files (and warns about deprecated usage)" do
119
+ allow(code_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
120
+
121
+ Dir.chdir(tempdir) do
122
+ code_generator.run
123
+ end
124
+ generated_files = Dir.glob("#{tempdir}/#{generator_arg}/**/*", File::FNM_DOTMATCH)
125
+ expected_cookbook_files.each do |expected_file|
126
+ expect(generated_files).to include(expected_file)
127
+ end
128
+
129
+ code_generator_path = File.join(generator_cookbook_path, "code_generator")
130
+ warning_message = "WARN: Please configure the generator cookbook by giving the full path to the desired cookbook (like '#{code_generator_path}')"
131
+
132
+ expect(stderr_io.string).to include(warning_message)
133
+ end
134
+ end
91
135
  end
92
136
  end
@@ -44,6 +44,7 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
44
44
  CHANGELOG.md
45
45
  recipes
46
46
  recipes/default.rb
47
+ compliance/README.md
47
48
  }
48
49
  end
49
50
 
@@ -67,6 +68,7 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
67
68
  spec/unit
68
69
  spec/unit/recipes
69
70
  spec/unit/recipes/default_spec.rb
71
+ compliance/README.md
70
72
  }
71
73
  end
72
74
 
@@ -151,7 +153,7 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
151
153
  end
152
154
 
153
155
  it "warns if a hyphenated cookbook name is passed" do
154
- expect(with_argv(%w{my-cookbook}).run).to eq(1)
156
+ expect(with_argv(%w{my-cookbook}).run).to eq(0)
155
157
  message = "Hyphens are discouraged in cookbook names as they may cause problems with custom resources. See https://docs.chef.io/workstation/ctl_chef/#chef-generate-cookbook for more information."
156
158
  expect(stdout_io.string).to include(message)
157
159
  end
@@ -176,6 +178,18 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
176
178
  expect(generator_context.specs).to be(false)
177
179
  end
178
180
 
181
+ it "creates a new cookbook" do
182
+
183
+ Dir.chdir(tempdir) do
184
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
185
+ expect(cookbook_generator.run).to eq(0)
186
+ end
187
+ generated_files = Dir.glob("#{tempdir}/new_cookbook/**/*", File::FNM_DOTMATCH)
188
+ expected_cookbook_files.each do |expected_file|
189
+ expect(generated_files).to include(expected_file)
190
+ end
191
+ end
192
+
179
193
  context "when given the specs flag" do
180
194
 
181
195
  let(:argv) { %w{ new_cookbook --specs } }
@@ -185,6 +199,17 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
185
199
  cookbook_generator.setup_context
186
200
  expect(generator_context.specs).to be(true)
187
201
  end
202
+
203
+ it "creates a new cookbook" do
204
+ Dir.chdir(tempdir) do
205
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
206
+ expect(cookbook_generator.run).to eq(0)
207
+ end
208
+ generated_files = Dir.glob("#{tempdir}/new_cookbook/**/*", File::FNM_DOTMATCH)
209
+ expected_cookbook_files_specs.each do |expected_file|
210
+ expect(generated_files).to include(expected_file)
211
+ end
212
+ end
188
213
  end
189
214
 
190
215
  context "when given the verbose flag" do
@@ -196,19 +221,34 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
196
221
  cookbook_generator.setup_context
197
222
  expect(generator_context.verbose).to be(true)
198
223
  end
224
+
225
+ it "emits verbose output" do
226
+ Dir.chdir(tempdir) do
227
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
228
+ expect(cookbook_generator.run).to eq(0)
229
+ end
230
+
231
+ # The normal chef formatter puts a heading for each recipe like this.
232
+ # Full output is large and subject to change with minor changes in the
233
+ # generator cookbook, so we just look for this line
234
+ expected_line = "Recipe: code_generator::cookbook"
235
+
236
+ actual = stdout_io.string
237
+
238
+ expect(actual).to include(expected_line)
239
+ end
199
240
  end
200
241
 
201
242
  shared_examples_for "a generated file" do |context_var|
202
243
  before do
203
244
  Dir.chdir(tempdir) do
204
245
  allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
205
- expect(cookbook_generator.run).to eq(1)
246
+ expect(cookbook_generator.run).to eq(0)
206
247
  end
207
248
  end
208
249
 
209
- it "should not generate a file" do
210
- expect(File.directory?(file)).to be false
211
- expect(File).not_to exist(file)
250
+ it "should contain #{context_var} from the generator context" do
251
+ expect(File.read(file)).to match line
212
252
  end
213
253
  end
214
254
 
@@ -228,6 +268,297 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
228
268
  end
229
269
  end
230
270
 
271
+ # This shared example group requires a let binding for
272
+ # `expected_kitchen_yml_content`
273
+ shared_examples_for "kitchen_yml_and_integration_tests" do
274
+
275
+ describe "Generating Test Kitchen and integration testing files" do
276
+
277
+ describe "generating kitchen config" do
278
+
279
+ before do
280
+ Dir.chdir(tempdir) do
281
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
282
+ expect(cookbook_generator.run).to eq(0)
283
+ end
284
+ end
285
+
286
+ let(:file) { File.join(tempdir, "new_cookbook", "kitchen.yml") }
287
+
288
+ it "creates a kitchen.yml with the expected content" do
289
+ expect(IO.read(file)).to eq(expected_kitchen_yml_content)
290
+ end
291
+
292
+ end
293
+
294
+ describe "test/integration/default/default_test.rb" do
295
+ let(:file) { File.join(tempdir, "new_cookbook", "test", "integration", "default", "default_test.rb") }
296
+
297
+ include_examples "a generated file", :cookbook_name do
298
+ let(:line) { "describe port" }
299
+ end
300
+ end
301
+ end
302
+ end
303
+
304
+ # This shared example group requires you to define a let binding for
305
+ # `expected_chefspec_spec_helper_content`
306
+ shared_examples_for "chefspec_spec_helper_file" do
307
+
308
+ describe "Generating ChefSpec files" do
309
+
310
+ before do
311
+ Dir.chdir(tempdir) do
312
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
313
+ expect(cookbook_generator.run).to eq(0)
314
+ end
315
+ end
316
+
317
+ let(:file) { File.join(tempdir, "new_cookbook", "spec", "spec_helper.rb") }
318
+
319
+ it "creates a spec/spec_helper.rb for ChefSpec with the expected content" do
320
+ expect(IO.read(file)).to eq(expected_chefspec_spec_helper_content)
321
+ end
322
+
323
+ end
324
+
325
+ end
326
+
327
+ context "when configured for Policyfiles" do
328
+
329
+ let(:argv) { %w{new_cookbook --policy} }
330
+
331
+ describe "Policyfile.rb" do
332
+
333
+ let(:file) { File.join(tempdir, "new_cookbook", "Policyfile.rb") }
334
+
335
+ let(:expected_content) do
336
+ <<~POLICYFILE_RB
337
+ # Policyfile.rb - Describe how you want Chef Infra Client to build your system.
338
+ #
339
+ # For more information on the Policyfile feature, visit
340
+ # https://docs.chef.io/policyfile/
341
+
342
+ # A name that describes what the system you're building with Chef does.
343
+ name 'new_cookbook'
344
+
345
+ # Where to find external cookbooks:
346
+ default_source :supermarket
347
+
348
+ # run_list: chef-client will run these recipes in the order specified.
349
+ run_list 'new_cookbook::default'
350
+
351
+ # Specify a custom source for a single cookbook:
352
+ cookbook 'new_cookbook', path: '.'
353
+ POLICYFILE_RB
354
+ end
355
+
356
+ before do
357
+ Dir.chdir(tempdir) do
358
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
359
+ expect(cookbook_generator.run).to eq(0)
360
+ end
361
+ end
362
+
363
+ it "has a run_list and cookbook path that will work out of the box" do
364
+ expect(IO.read(file)).to eq(expected_content)
365
+ end
366
+
367
+ end
368
+
369
+ include_examples "kitchen_yml_and_integration_tests" do
370
+
371
+ let(:expected_kitchen_yml_content) do
372
+ <<~KITCHEN_YML
373
+ ---
374
+ driver:
375
+ name: vagrant
376
+
377
+ ## The forwarded_port port feature lets you connect to ports on the VM guest
378
+ ## via localhost on the host.
379
+ ## see also: https://www.vagrantup.com/docs/networking/forwarded_ports
380
+
381
+ # network:
382
+ # - ["forwarded_port", {guest: 80, host: 8080}]
383
+
384
+ provisioner:
385
+ name: chef_zero
386
+
387
+ ## product_name and product_version specifies a specific Chef product and version to install.
388
+ ## see the Chef documentation for more details: https://docs.chef.io/workstation/config_yml_kitchen/
389
+ # product_name: chef
390
+ # product_version: 17
391
+
392
+ verifier:
393
+ name: inspec
394
+
395
+ platforms:
396
+ - name: ubuntu-20.04
397
+ - name: centos-8
398
+
399
+ suites:
400
+ - name: default
401
+ verifier:
402
+ inspec_tests:
403
+ - test/integration/default
404
+ KITCHEN_YML
405
+ end
406
+
407
+ end
408
+
409
+ include_examples "chefspec_spec_helper_file" do
410
+ let(:argv) { %w{ new_cookbook --policy --specs } }
411
+
412
+ let(:expected_chefspec_spec_helper_content) do
413
+ <<~SPEC_HELPER
414
+ require 'chefspec'
415
+ require 'chefspec/policyfile'
416
+ SPEC_HELPER
417
+ end
418
+
419
+ end
420
+
421
+ end
422
+
423
+ context "when YAML recipe flag is passed" do
424
+
425
+ let(:argv) { %w{new_cookbook --yaml} }
426
+
427
+ describe "recipes/default.yml" do
428
+ let(:file) { File.join(tempdir, "new_cookbook", "recipes", "default.yml") }
429
+
430
+ let(:expected_content_header) do
431
+ <<~DEFAULT_YML_HEADER
432
+ #
433
+ # Cookbook:: new_cookbook
434
+ # Recipe:: default
435
+ #
436
+ DEFAULT_YML_HEADER
437
+ end
438
+
439
+ let(:expected_content) do
440
+ <<~DEFAULT_YML_CONTENT
441
+ ---
442
+ resources:
443
+ # Example Syntax
444
+ # Additional snippets are available using the Chef Infra Extension for Visual Studio Code
445
+ # - type: file
446
+ # name: '/path/to/file'
447
+ # content: 'content'
448
+ # owner: 'root'
449
+ # group: 'root'
450
+ # mode: '0755'
451
+ # action:
452
+ # - create
453
+ DEFAULT_YML_CONTENT
454
+ end
455
+
456
+ before do
457
+ Dir.chdir(tempdir) do
458
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
459
+ expect(cookbook_generator.run).to eq(0)
460
+ end
461
+ end
462
+
463
+ it "has a default.yml file with template contents" do
464
+ expect(IO.read(file)).to match(expected_content_header)
465
+ expect(IO.read(file)).to match(expected_content)
466
+ end
467
+
468
+ end
469
+
470
+ end
471
+
472
+ context "when configured for Berkshelf" do
473
+
474
+ let(:argv) { %w{new_cookbook --berks} }
475
+
476
+ describe "Berksfile" do
477
+
478
+ let(:file) { File.join(tempdir, "new_cookbook", "Berksfile") }
479
+
480
+ let(:expected_content) do
481
+ <<~POLICYFILE_RB
482
+ source 'https://supermarket.chef.io'
483
+
484
+ metadata
485
+ POLICYFILE_RB
486
+ end
487
+
488
+ before do
489
+ Dir.chdir(tempdir) do
490
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
491
+ expect(cookbook_generator.run).to eq(0)
492
+ end
493
+ end
494
+
495
+ it "pulls deps from metadata" do
496
+ expect(IO.read(file)).to eq(expected_content)
497
+ end
498
+
499
+ end
500
+
501
+ include_examples "kitchen_yml_and_integration_tests" do
502
+
503
+ let(:expected_kitchen_yml_content) do
504
+ <<~KITCHEN_YML
505
+ ---
506
+ driver:
507
+ name: vagrant
508
+
509
+ ## The forwarded_port port feature lets you connect to ports on the VM guest via
510
+ ## localhost on the host.
511
+ ## see also: https://www.vagrantup.com/docs/networking/forwarded_ports
512
+
513
+ # network:
514
+ # - ["forwarded_port", {guest: 80, host: 8080}]
515
+
516
+ provisioner:
517
+ name: chef_zero
518
+ # You may wish to disable always updating cookbooks in CI or other testing environments.
519
+ # For example:
520
+ # always_update_cookbooks: <%= !ENV['CI'] %>
521
+ always_update_cookbooks: true
522
+
523
+ ## product_name and product_version specifies a specific Chef product and version to install.
524
+ ## see the Chef documentation for more details: https://docs.chef.io/workstation/config_yml_kitchen/
525
+ # product_name: chef
526
+ # product_version: 17
527
+
528
+ verifier:
529
+ name: inspec
530
+
531
+ platforms:
532
+ - name: ubuntu-20.04
533
+ - name: centos-8
534
+
535
+ suites:
536
+ - name: default
537
+ run_list:
538
+ - recipe[new_cookbook::default]
539
+ verifier:
540
+ inspec_tests:
541
+ - test/integration/default
542
+ attributes:
543
+ KITCHEN_YML
544
+ end
545
+
546
+ end
547
+
548
+ include_examples "chefspec_spec_helper_file" do
549
+ let(:argv) { %w{ new_cookbook --berks --specs } }
550
+
551
+ let(:expected_chefspec_spec_helper_content) do
552
+ <<~SPEC_HELPER
553
+ require 'chefspec'
554
+ require 'chefspec/berkshelf'
555
+ SPEC_HELPER
556
+ end
557
+
558
+ end
559
+
560
+ end
561
+
231
562
  describe "metadata.rb" do
232
563
  let(:file) { File.join(tempdir, "new_cookbook", "metadata.rb") }
233
564
 
@@ -0,0 +1,31 @@
1
+ #
2
+ # Copyright:: 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 "shared/a_file_generator"
20
+ require "chef-cli/command/generator_commands/input"
21
+
22
+ describe ChefCLI::Command::GeneratorCommands::Input do
23
+
24
+ include_examples "a file generator" do
25
+
26
+ let(:generator_name) { "input" }
27
+ let(:generated_files) { [ "compliance/inputs/new_input.yml" ] }
28
+ let(:new_file_name) { "new_input" }
29
+
30
+ end
31
+ end
@@ -0,0 +1,34 @@
1
+ #
2
+ # Copyright:: 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 "shared/a_file_generator"
20
+ require "chef-cli/command/generator_commands/profile"
21
+
22
+ describe ChefCLI::Command::GeneratorCommands::Profile do
23
+
24
+ include_examples "a file generator" do
25
+
26
+ let(:generator_name) { "profile" }
27
+ let(:generated_files) {
28
+ [ "compliance/profiles/new_profile/inspec.yml",
29
+ "compliance/profiles/new_profile/controls/example.rb" ]
30
+ }
31
+ let(:new_file_name) { "new_profile" }
32
+
33
+ end
34
+ end
@@ -0,0 +1,31 @@
1
+ #
2
+ # Copyright:: 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 "shared/a_file_generator"
20
+ require "chef-cli/command/generator_commands/waiver"
21
+
22
+ describe ChefCLI::Command::GeneratorCommands::Waiver do
23
+
24
+ include_examples "a file generator" do
25
+
26
+ let(:generator_name) { "waiver" }
27
+ let(:generated_files) { [ "compliance/waivers/new_waiver.yml" ] }
28
+ let(:new_file_name) { "new_waiver" }
29
+
30
+ end
31
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.5.4
4
+ version: 5.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chef Software, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-18 00:00:00.000000000 Z
11
+ date: 2022-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mixlib-cli
@@ -248,11 +248,14 @@ files:
248
248
  - lib/chef-cli/command/generator_commands/cookbook_file.rb
249
249
  - lib/chef-cli/command/generator_commands/generator_generator.rb
250
250
  - lib/chef-cli/command/generator_commands/helpers.rb
251
+ - lib/chef-cli/command/generator_commands/input.rb
251
252
  - lib/chef-cli/command/generator_commands/policyfile.rb
253
+ - lib/chef-cli/command/generator_commands/profile.rb
252
254
  - lib/chef-cli/command/generator_commands/recipe.rb
253
255
  - lib/chef-cli/command/generator_commands/repo.rb
254
256
  - lib/chef-cli/command/generator_commands/resource.rb
255
257
  - lib/chef-cli/command/generator_commands/template.rb
258
+ - lib/chef-cli/command/generator_commands/waiver.rb
256
259
  - lib/chef-cli/command/install.rb
257
260
  - lib/chef-cli/command/push.rb
258
261
  - lib/chef-cli/command/push_archive.rb
@@ -350,11 +353,14 @@ files:
350
353
  - lib/chef-cli/skeletons/code_generator/recipes/cookbook.rb
351
354
  - lib/chef-cli/skeletons/code_generator/recipes/cookbook_file.rb
352
355
  - lib/chef-cli/skeletons/code_generator/recipes/helpers.rb
356
+ - lib/chef-cli/skeletons/code_generator/recipes/input.rb
353
357
  - lib/chef-cli/skeletons/code_generator/recipes/policyfile.rb
358
+ - lib/chef-cli/skeletons/code_generator/recipes/profile.rb
354
359
  - lib/chef-cli/skeletons/code_generator/recipes/recipe.rb
355
360
  - lib/chef-cli/skeletons/code_generator/recipes/repo.rb
356
361
  - lib/chef-cli/skeletons/code_generator/recipes/resource.rb
357
362
  - lib/chef-cli/skeletons/code_generator/recipes/template.rb
363
+ - lib/chef-cli/skeletons/code_generator/recipes/waiver.rb
358
364
  - lib/chef-cli/skeletons/code_generator/templates/default/CHANGELOG.md.erb
359
365
  - lib/chef-cli/skeletons/code_generator/templates/default/LICENSE.all_rights.erb
360
366
  - lib/chef-cli/skeletons/code_generator/templates/default/LICENSE.apachev2.erb
@@ -364,8 +370,12 @@ files:
364
370
  - lib/chef-cli/skeletons/code_generator/templates/default/Policyfile.rb.erb
365
371
  - lib/chef-cli/skeletons/code_generator/templates/default/README.md.erb
366
372
  - lib/chef-cli/skeletons/code_generator/templates/default/attribute.rb.erb
373
+ - lib/chef-cli/skeletons/code_generator/templates/default/compliance_dir_README.md.erb
374
+ - lib/chef-cli/skeletons/code_generator/templates/default/compliance_profile_control.rb.erb
375
+ - lib/chef-cli/skeletons/code_generator/templates/default/compliance_profile_inspec.yml.erb
367
376
  - lib/chef-cli/skeletons/code_generator/templates/default/cookbook_file.erb
368
377
  - lib/chef-cli/skeletons/code_generator/templates/default/helpers.rb.erb
378
+ - lib/chef-cli/skeletons/code_generator/templates/default/input.yml.erb
369
379
  - lib/chef-cli/skeletons/code_generator/templates/default/inspec_default_test.rb.erb
370
380
  - lib/chef-cli/skeletons/code_generator/templates/default/kitchen.yml.erb
371
381
  - lib/chef-cli/skeletons/code_generator/templates/default/kitchen_dokken.yml.erb
@@ -377,6 +387,7 @@ files:
377
387
  - lib/chef-cli/skeletons/code_generator/templates/default/repo/gitignore.erb
378
388
  - lib/chef-cli/skeletons/code_generator/templates/default/resource.rb.erb
379
389
  - lib/chef-cli/skeletons/code_generator/templates/default/template.erb
390
+ - lib/chef-cli/skeletons/code_generator/templates/default/waiver.yml.erb
380
391
  - lib/chef-cli/ui.rb
381
392
  - lib/chef-cli/version.rb
382
393
  - lib/kitchen/provisioner/chef_zero_capture.rb
@@ -411,11 +422,14 @@ files:
411
422
  - spec/unit/command/generator_commands/cookbook_spec.rb
412
423
  - spec/unit/command/generator_commands/generator_generator_spec.rb
413
424
  - spec/unit/command/generator_commands/helpers_spec.rb
425
+ - spec/unit/command/generator_commands/input_spec.rb
414
426
  - spec/unit/command/generator_commands/policyfile_spec.rb
427
+ - spec/unit/command/generator_commands/profile_spec.rb
415
428
  - spec/unit/command/generator_commands/recipe_spec.rb
416
429
  - spec/unit/command/generator_commands/repo_spec.rb
417
430
  - spec/unit/command/generator_commands/resource_spec.rb
418
431
  - spec/unit/command/generator_commands/template_spec.rb
432
+ - spec/unit/command/generator_commands/waiver_spec.rb
419
433
  - spec/unit/command/install_spec.rb
420
434
  - spec/unit/command/push_archive_spec.rb
421
435
  - spec/unit/command/push_spec.rb
@@ -634,11 +648,14 @@ test_files:
634
648
  - spec/unit/command/generator_commands/cookbook_spec.rb
635
649
  - spec/unit/command/generator_commands/generator_generator_spec.rb
636
650
  - spec/unit/command/generator_commands/helpers_spec.rb
651
+ - spec/unit/command/generator_commands/input_spec.rb
637
652
  - spec/unit/command/generator_commands/policyfile_spec.rb
653
+ - spec/unit/command/generator_commands/profile_spec.rb
638
654
  - spec/unit/command/generator_commands/recipe_spec.rb
639
655
  - spec/unit/command/generator_commands/repo_spec.rb
640
656
  - spec/unit/command/generator_commands/resource_spec.rb
641
657
  - spec/unit/command/generator_commands/template_spec.rb
658
+ - spec/unit/command/generator_commands/waiver_spec.rb
642
659
  - spec/unit/command/install_spec.rb
643
660
  - spec/unit/command/push_archive_spec.rb
644
661
  - spec/unit/command/push_spec.rb