chef-dk 0.7.0 → 0.8.0

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/lib/chef-dk/builtin_commands.rb +10 -0
  4. data/lib/chef-dk/command/base.rb +2 -2
  5. data/lib/chef-dk/command/clean_policy_cookbooks.rb +116 -0
  6. data/lib/chef-dk/command/clean_policy_revisions.rb +113 -0
  7. data/lib/chef-dk/command/delete_policy.rb +122 -0
  8. data/lib/chef-dk/command/delete_policy_group.rb +122 -0
  9. data/lib/chef-dk/command/export.rb +3 -3
  10. data/lib/chef-dk/command/generate.rb +8 -0
  11. data/lib/chef-dk/command/generator_commands/app.rb +1 -1
  12. data/lib/chef-dk/command/generator_commands/cookbook.rb +1 -1
  13. data/lib/chef-dk/command/generator_commands/policyfile.rb +1 -1
  14. data/lib/chef-dk/command/generator_commands/repo.rb +1 -1
  15. data/lib/chef-dk/command/install.rb +22 -5
  16. data/lib/chef-dk/command/provision.rb +0 -4
  17. data/lib/chef-dk/command/push.rb +1 -2
  18. data/lib/chef-dk/command/shell_init.rb +65 -6
  19. data/lib/chef-dk/command/show_policy.rb +1 -2
  20. data/lib/chef-dk/command/undelete.rb +155 -0
  21. data/lib/chef-dk/command/update.rb +5 -5
  22. data/lib/chef-dk/command/verify.rb +61 -17
  23. data/lib/chef-dk/completions/bash.sh.erb +5 -0
  24. data/lib/chef-dk/completions/chef.fish.erb +10 -0
  25. data/lib/chef-dk/completions/zsh.zsh.erb +21 -0
  26. data/lib/chef-dk/exceptions.rb +12 -0
  27. data/lib/chef-dk/helpers.rb +17 -0
  28. data/lib/chef-dk/policyfile/community_cookbook_source.rb +0 -3
  29. data/lib/chef-dk/policyfile/lister.rb +3 -1
  30. data/lib/chef-dk/policyfile/undo_record.rb +142 -0
  31. data/lib/chef-dk/policyfile/undo_stack.rb +130 -0
  32. data/lib/chef-dk/policyfile_lock.rb +30 -0
  33. data/lib/chef-dk/policyfile_services/clean_policies.rb +5 -4
  34. data/lib/chef-dk/policyfile_services/clean_policy_cookbooks.rb +125 -0
  35. data/lib/chef-dk/policyfile_services/rm_policy.rb +142 -0
  36. data/lib/chef-dk/policyfile_services/rm_policy_group.rb +86 -0
  37. data/lib/chef-dk/policyfile_services/show_policy.rb +1 -1
  38. data/lib/chef-dk/policyfile_services/undelete.rb +108 -0
  39. data/lib/chef-dk/service_exceptions.rb +11 -0
  40. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +6 -2
  41. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +1 -1
  42. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +1 -1
  43. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +1 -1
  44. data/lib/chef-dk/version.rb +1 -1
  45. data/lib/kitchen/provisioner/policyfile_zero.rb +4 -1
  46. data/spec/unit/command/base_spec.rb +26 -1
  47. data/spec/unit/command/clean_policy_cookbooks_spec.rb +181 -0
  48. data/spec/unit/command/clean_policy_revisions_spec.rb +181 -0
  49. data/spec/unit/command/delete_policy_group_spec.rb +207 -0
  50. data/spec/unit/command/delete_policy_spec.rb +207 -0
  51. data/spec/unit/command/generate_spec.rb +41 -1
  52. data/spec/unit/command/generator_commands/cookbook_spec.rb +1 -1
  53. data/spec/unit/command/generator_commands/policyfile_spec.rb +1 -1
  54. data/spec/unit/command/install_spec.rb +24 -0
  55. data/spec/unit/command/shell_init_spec.rb +176 -5
  56. data/spec/unit/command/undelete_spec.rb +246 -0
  57. data/spec/unit/helpers_spec.rb +24 -0
  58. data/spec/unit/policyfile/lister_spec.rb +16 -0
  59. data/spec/unit/policyfile/undo_record_spec.rb +260 -0
  60. data/spec/unit/policyfile/undo_stack_spec.rb +266 -0
  61. data/spec/unit/policyfile_lock_serialization_spec.rb +41 -0
  62. data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +275 -0
  63. data/spec/unit/policyfile_services/rm_policy_group_spec.rb +241 -0
  64. data/spec/unit/policyfile_services/rm_policy_spec.rb +266 -0
  65. data/spec/unit/policyfile_services/show_policy_spec.rb +52 -2
  66. data/spec/unit/policyfile_services/undelete_spec.rb +304 -0
  67. metadata +43 -91
@@ -40,8 +40,7 @@ to the target machine, you can apply the policy to the machine with
40
40
  versioned_cookbooks true
41
41
  policy_document_native_api false
42
42
 
43
- The Policyfile feature is incomplete and beta quality. See our detailed README
44
- for more information.
43
+ See our detailed README for more information:
45
44
 
46
45
  https://github.com/opscode/chef-dk/blob/master/POLICYFILE_README.md
47
46
 
@@ -140,7 +139,8 @@ E
140
139
  when 2
141
140
  @policyfile_relative_path, @export_dir = remaining_args
142
141
  else
143
- ui.err(banner)
142
+ ui.err(opt_parser)
143
+ ui.err("\n")
144
144
  return false
145
145
  end
146
146
  true
@@ -86,6 +86,14 @@ E
86
86
  msg(banner)
87
87
  1
88
88
  end
89
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
90
+ # ChefDK::Command::Base also handles this error in the same way, but it
91
+ # does not have access to the correct option parser, so it cannot print
92
+ # the usage correctly. Therefore, invalid CLI usage needs to be handled
93
+ # here.
94
+ err("ERROR: #{e.message}\n")
95
+ msg(generator.opt_parser)
96
+ 1
89
97
  end
90
98
 
91
99
  def generator_for(arg)
@@ -46,7 +46,7 @@ module ChefDK
46
46
  setup_context
47
47
  chef_runner.converge
48
48
  else
49
- msg(banner)
49
+ err(opt_parser)
50
50
  1
51
51
  end
52
52
  rescue ChefDK::ChefRunnerError => e
@@ -49,7 +49,7 @@ module ChefDK
49
49
  setup_context
50
50
  chef_runner.converge
51
51
  else
52
- msg(banner)
52
+ err(opt_parser)
53
53
  1
54
54
  end
55
55
  rescue ChefDK::ChefRunnerError => e
@@ -52,7 +52,7 @@ module ChefDK
52
52
  chef_runner.converge
53
53
  0
54
54
  else
55
- msg(banner)
55
+ err(opt_parser)
56
56
  1
57
57
  end
58
58
  end
@@ -52,7 +52,7 @@ module ChefDK
52
52
  setup_context
53
53
  chef_runner.converge
54
54
  else
55
- msg(banner)
55
+ err(opt_parser)
56
56
  1
57
57
  end
58
58
  end
@@ -18,12 +18,15 @@
18
18
  require 'chef-dk/command/base'
19
19
  require 'chef-dk/ui'
20
20
  require 'chef-dk/policyfile_services/install'
21
+ require 'chef-dk/configurable'
21
22
 
22
23
  module ChefDK
23
24
  module Command
24
25
 
25
26
  class Install < Base
26
27
 
28
+ include Configurable
29
+
27
30
  banner(<<-E)
28
31
  Usage: chef install [ POLICY_FILE ] [options]
29
32
 
@@ -34,8 +37,7 @@ lockfile to install the locked cookbooks on another machine. You can also push
34
37
  the lockfile to a "policy group" on a Chef Server and apply that exact set of
35
38
  cookbooks to nodes in your infrastructure.
36
39
 
37
- The Policyfile feature is incomplete and beta quality. See our detailed README
38
- for more information.
40
+ See our detailed README for more information:
39
41
 
40
42
  https://github.com/opscode/chef-dk/blob/master/POLICYFILE_README.md
41
43
 
@@ -43,6 +45,11 @@ Options:
43
45
 
44
46
  E
45
47
 
48
+ option :config_file,
49
+ short: "-c CONFIG_FILE",
50
+ long: "--config CONFIG_FILE",
51
+ description: "Path to configuration file"
52
+
46
53
  option :debug,
47
54
  short: "-D",
48
55
  long: "--debug",
@@ -62,7 +69,12 @@ E
62
69
  end
63
70
 
64
71
  def run(params = [])
65
- apply_params!(params)
72
+ return 1 unless apply_params!(params)
73
+ # Force config file to be loaded. We don't use the configuration
74
+ # directly, but the user may have SSL configuration options that they
75
+ # need to talk to a private supermarket (e.g., trusted_certs or
76
+ # ssl_verify_mode)
77
+ chef_config
66
78
  installer.run
67
79
  0
68
80
  rescue PolicyfileServiceError => e
@@ -78,6 +90,10 @@ E
78
90
  !!config[:debug]
79
91
  end
80
92
 
93
+ def config_path
94
+ config[:config_file]
95
+ end
96
+
81
97
  def handle_error(error)
82
98
  ui.err("Error: #{error.message}")
83
99
  if error.respond_to?(:reason)
@@ -91,10 +107,11 @@ E
91
107
  def apply_params!(params)
92
108
  remaining_args = parse_options(params)
93
109
  if remaining_args.size > 1
94
- ui.err(banner)
95
- return 1
110
+ ui.err(opt_parser)
111
+ return false
96
112
  else
97
113
  @policyfile_relative_path = remaining_args.first
114
+ true
98
115
  end
99
116
  end
100
117
 
@@ -130,10 +130,6 @@ before converging the machine(s) defined in the provision cookbook.
130
130
  In the third form of the command, `chef provision` expects to create machines
131
131
  that will not operate in policyfile mode.
132
132
 
133
- Note that this command is considered beta. Behavior, the APIs that pass CLI
134
- data to chef-client, and argument names may change as more experience is gained
135
- from real-world usage.
136
-
137
133
  Chef Provisioning is documented at https://docs.chef.io/provisioning.html
138
134
 
139
135
  Options:
@@ -35,8 +35,7 @@ with all the cookbooks contained in the policy lock. The policy lock is applied
35
35
  to a specific POLICY_GROUP, which is a set of nodes that share the same
36
36
  run_list and cookbooks.
37
37
 
38
- The Policyfile feature is incomplete and beta quality. See our detailed README
39
- for more information.
38
+ See our detailed README for more information:
40
39
 
41
40
  https://github.com/opscode/chef-dk/blob/master/POLICYFILE_README.md
42
41
 
@@ -15,10 +15,29 @@
15
15
  # limitations under the License.
16
16
  #
17
17
 
18
+ require 'erb'
19
+
20
+ require 'chef-dk/commands_map'
21
+ require 'chef-dk/builtin_commands'
18
22
  require 'chef-dk/command/base'
19
23
  require 'mixlib/shellout'
20
24
 
21
25
  module ChefDK
26
+
27
+ class ShellCompletionTemplateContext
28
+
29
+ def commands
30
+ ChefDK.commands_map.command_specs.inject({}) do |cmd_info, (_key, cmd_spec)|
31
+ cmd_info[cmd_spec.name] = cmd_spec.description
32
+ cmd_info
33
+ end
34
+ end
35
+
36
+ def get_binding
37
+ binding
38
+ end
39
+ end
40
+
22
41
  module Command
23
42
  class ShellInit < ChefDK::Command::Base
24
43
 
@@ -56,6 +75,11 @@ HELP
56
75
  :long => "--omnibus-dir OMNIBUS_DIR",
57
76
  :description => "Alternate path to omnibus install (used for testing)"
58
77
 
78
+ def initialize
79
+ super
80
+ @shell_completion_template_context = nil
81
+ end
82
+
59
83
  def omnibus_root
60
84
  config[:omnibus_dir] || super
61
85
  end
@@ -81,9 +105,46 @@ HELP
81
105
  env.each do |var_name, value|
82
106
  export(shell_name, var_name, value)
83
107
  end
108
+
109
+ emit_shell_cmd(completion_for(shell_name))
84
110
  0
85
111
  end
86
112
 
113
+ def emit_shell_cmd(cmd)
114
+ msg(cmd) unless cmd.empty?
115
+ end
116
+
117
+ def completion_for(shell)
118
+ return "" unless (completion_template_basename = completion_template_for(shell))
119
+ completion_template_path = expand_completion_template_path(completion_template_basename)
120
+ erb = ERB.new(File.read(completion_template_path), nil, '-')
121
+ context_binding = shell_completion_template_context.get_binding
122
+ erb.result(context_binding)
123
+ end
124
+
125
+ def completion_template_for(shell)
126
+ case shell
127
+ when "bash"
128
+ "bash.sh.erb"
129
+ when "fish"
130
+ "chef.fish.erb"
131
+ when "zsh"
132
+ "zsh.zsh.erb"
133
+ else
134
+ # Pull requests accepted!
135
+ nil
136
+ end
137
+
138
+ end
139
+
140
+ def expand_completion_template_path(basename)
141
+ File.join(File.expand_path("../../completions", __FILE__), basename)
142
+ end
143
+
144
+ def shell_completion_template_context
145
+ @shell_completion_template_context ||= ShellCompletionTemplateContext.new
146
+ end
147
+
87
148
  def export(shell, var, val)
88
149
  case shell
89
150
  when 'sh', 'bash', 'zsh'
@@ -96,7 +157,7 @@ HELP
96
157
  end
97
158
 
98
159
  def posix_shell_export(var, val)
99
- msg(%Q(export #{var}="#{val}"))
160
+ emit_shell_cmd(%Q(export #{var}="#{val}"))
100
161
  end
101
162
 
102
163
  def fish_shell_export(var, val)
@@ -105,17 +166,15 @@ HELP
105
166
  # /dev/null to avoid Fish's helpful warnings about nonexistent
106
167
  # PATH elements.
107
168
  if var == 'PATH'
108
- msg(%Q(set -gx #{var} "#{val.split(':').join('" "')}" 2>/dev/null;))
169
+ emit_shell_cmd(%Q(set -gx #{var} "#{val.split(':').join('" "')}" 2>/dev/null;))
109
170
  else
110
- msg(%Q(set -gx #{var} "#{val}";))
171
+ emit_shell_cmd(%Q(set -gx #{var} "#{val}";))
111
172
  end
112
173
  end
113
174
 
114
175
  def powershell_export(var, val)
115
- msg(%Q($env:#{var}="#{val}"))
176
+ emit_shell_cmd(%Q($env:#{var}="#{val}"))
116
177
  end
117
178
  end
118
179
  end
119
180
  end
120
-
121
-
@@ -38,8 +38,7 @@ When both POLICY_NAME and POLICY_GROUP are given, the command shows the content
38
38
  of a the active policyfile lock for the given POLICY_GROUP. See also the `diff`
39
39
  command.
40
40
 
41
- The Policyfile feature is incomplete and beta quality. See our detailed README
42
- for more information.
41
+ See our detailed README for more information:
43
42
 
44
43
  https://github.com/opscode/chef-dk/blob/master/POLICYFILE_README.md
45
44
 
@@ -0,0 +1,155 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2015 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 'chef-dk/command/base'
19
+ require 'chef-dk/ui'
20
+ require 'chef-dk/configurable'
21
+ require 'chef-dk/policyfile_services/undelete'
22
+
23
+ module ChefDK
24
+ module Command
25
+
26
+ class Undelete < Base
27
+
28
+ banner(<<-BANNER)
29
+ Usage: chef undelete [--list | --id ID] [options]
30
+
31
+ `chef undelete` helps you recover quickly if you've deleted a policy or policy
32
+ group in error. When run with no arguements, it lists the available undo
33
+ operations. To undo the last delete operation, use `chef undelete --last`.
34
+
35
+ CAVEATS:
36
+ `chef undelete` doesn't detect conflicts. If a deleted item has been recreated,
37
+ running `chef undelete` will overwrite it.
38
+
39
+ Undo information does not include cookbooks that might be referenced by
40
+ policies. If you have cleaned the policy cookbooks after the delete operation
41
+ you want to reverse, `chef undelete` may not be able to fully restore the
42
+ previous state.
43
+
44
+ The delete commands also do not store access control data, so you may have to
45
+ manually reapply any ACL customizations you have made.
46
+
47
+ See our detailed README for more information:
48
+
49
+ https://github.com/opscode/chef-dk/blob/master/POLICYFILE_README.md
50
+
51
+ Options:
52
+
53
+ BANNER
54
+
55
+ option :undo_last,
56
+ short: "-l",
57
+ long: "--last",
58
+ description: "Undo the most recent delete operation"
59
+
60
+ option :undo_record_id,
61
+ short: "-i ID",
62
+ long: "--id ID",
63
+ description: "Undo the delete operation with the given ID"
64
+
65
+ option :config_file,
66
+ short: "-c CONFIG_FILE",
67
+ long: "--config CONFIG_FILE",
68
+ description: "Path to configuration file"
69
+
70
+ option :debug,
71
+ short: "-D",
72
+ long: "--debug",
73
+ description: "Enable stacktraces and other debug output",
74
+ default: false
75
+
76
+ include Configurable
77
+
78
+ attr_accessor :ui
79
+
80
+ attr_reader :undo_record_id
81
+
82
+ def initialize(*args)
83
+ super
84
+ @list_undo_records = false
85
+ @undo_record_id = nil
86
+ @ui = UI.new
87
+ end
88
+
89
+ def run(params)
90
+ return 1 unless apply_params!(params)
91
+ if list_undo_records?
92
+ undelete_service.list
93
+ else
94
+ undelete_service.run
95
+ end
96
+ 0
97
+ rescue PolicyfileServiceError => e
98
+ handle_error(e)
99
+ 1
100
+ end
101
+
102
+ def undelete_service
103
+ @undelete_service ||=
104
+ PolicyfileServices::Undelete.new(config: chef_config,
105
+ ui: ui,
106
+ undo_record_id: undo_record_id)
107
+ end
108
+
109
+ def debug?
110
+ !!config[:debug]
111
+ end
112
+
113
+ def list_undo_records?
114
+ @list_undo_records
115
+ end
116
+
117
+ def handle_error(error)
118
+ ui.err("Error: #{error.message}")
119
+ if error.respond_to?(:reason)
120
+ ui.err("Reason: #{error.reason}")
121
+ ui.err("")
122
+ ui.err(error.extended_error_info) if debug?
123
+ ui.err(error.cause.backtrace.join("\n")) if debug?
124
+ end
125
+ end
126
+
127
+ def apply_params!(params)
128
+ remaining_args = parse_options(params)
129
+
130
+ if !remaining_args.empty?
131
+ ui.err("Too many arguments")
132
+ ui.err("")
133
+ ui.err(opt_parser)
134
+ false
135
+ elsif config[:undo_record_id].nil? && config[:undo_last].nil?
136
+ @list_undo_records = true
137
+ true
138
+ elsif config[:undo_record_id] && config[:undo_last]
139
+ ui.err("Error: options --last and --id cannot both be given.")
140
+ ui.err("")
141
+ ui.err(opt_parser)
142
+ false
143
+ elsif config[:undo_record_id]
144
+ @undo_record_id = config[:undo_record_id]
145
+ true
146
+ elsif config[:undo_last]
147
+ @undo_record_id = nil
148
+ true
149
+ end
150
+ end
151
+
152
+ end
153
+ end
154
+ end
155
+