chef-cli 5.5.4 → 5.6.1

Sign up to get free protection for your applications and to get access to all the features.
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