summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc A. Paradise <marc.paradise@gmail.com>2019-02-26 12:21:00 -0500
committerMarc A. Paradise <marc.paradise@gmail.com>2019-03-19 14:25:11 -0400
commitc6f356718f56257aea5b145d600cfb1e79e35877 (patch)
tree2cda8f28028d30a0c1ba27853757dde424d0df78
parentfcd968388af3ae5f1f271b6939f49928fa5a59ea (diff)
downloadchef-c6f356718f56257aea5b145d600cfb1e79e35877.tar.gz
Move bootstrap options into their own module
With 18 command line flags and counting, it keeps `bootstrap.rb` a little more readable if we push the flags out into their own module and mix it in. Signed-off-by: Marc A. Paradise <marc.paradise@gmail.com>
-rw-r--r--lib/chef/knife/bootstrap.rb248
-rw-r--r--lib/chef/knife/bootstrap/options.rb267
2 files changed, 273 insertions, 242 deletions
diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb
index 572cb7c46e..105bd42e08 100644
--- a/lib/chef/knife/bootstrap.rb
+++ b/lib/chef/knife/bootstrap.rb
@@ -38,6 +38,12 @@ class Chef
require "tempfile"
require "chef_core/text" # i18n and standardized error structures
require "chef_core/target_host"
+
+ # Command line flags and options for bootstrap - there's a large number of them
+ # so we'll keep this file a little smaller by splitting them out.
+ require "chef/knife/bootstrap/options"
+ self.include Chef::Knife::Bootstrap::Options
+
# Because nothing else is using i18n out of Chef::Text yet, we're treating it
# as a dependency to avoid loading localization files before we need them.
ChefCore::Text.add_gem_localization("chef")
@@ -45,248 +51,6 @@ class Chef
banner "knife bootstrap [SSH_USER@]FQDN (options)"
-
-
- # SSH - :host
- option :ssh_user,
- short: "-x USERNAME",
- long: "--ssh-user USERNAME",
- description: "The ssh username",
- default: "root"
-
- # SSH - :password
- option :ssh_password,
- short: "-P PASSWORD",
- long: "--ssh-password PASSWORD",
- description: "The ssh password"
-
- # SSH :port
- option :ssh_port,
- short: "-p PORT",
- long: "--ssh-port PORT",
- description: "The ssh port",
- proc: Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
-
- # TODO SSH train gives bastion_host which seeems to map to getway/gateway_identity -
- # though not exactly.
- option :ssh_gateway,
- short: "-G GATEWAY",
- long: "--ssh-gateway GATEWAY",
- description: "The ssh gateway",
- proc: Proc.new { |key| Chef::Config[:knife][:ssh_gateway] = key }
-
- # TODO - missing in train: ssh_gateway_identity. But could just append to
- # keyfiles - train accepts multiple?
- # TODO - train supports bastion_user and bastion_port
- # SSH - this just maps to key_files - under knife-ssh we would use either this,
- # _or_ ssh_identity_file
- # either this or 'ssh_identity_file' but not both.
- option :ssh_gateway_identity,
- long: "--ssh-gateway-identity SSH_GATEWAY_IDENTITY",
- description: "The SSH identity file used for gateway authentication",
- proc: Proc.new { |key| Chef::Config[:knife][:ssh_gateway_identity] = key }
-
- # SSH train ssh: options[:forward_agent]
- option :forward_agent,
- short: "-A",
- long: "--forward-agent",
- description: "Enable SSH agent forwarding",
- boolean: true
-
- # SSH train: options[key_files]
- option :ssh_identity_file,
- short: "-i IDENTITY_FILE",
- long: "--ssh-identity-file IDENTITY_FILE",
- description: "The SSH identity file used for authentication"
-
- option :chef_node_name,
- short: "-N NAME",
- long: "--node-name NAME",
- description: "The Chef node name for your new node"
-
- option :prerelease,
- long: "--prerelease",
- description: "Install the pre-release chef gems"
-
- # client.rb
- option :bootstrap_version,
- long: "--bootstrap-version VERSION",
- description: "The version of Chef to install",
- proc: lambda { |v| Chef::Config[:knife][:bootstrap_version] = v }
-
- # client.rb
- option :bootstrap_proxy,
- long: "--bootstrap-proxy PROXY_URL",
- description: "The proxy server for the node being bootstrapped",
- proc: Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
-
- # client.rb
- option :bootstrap_proxy_user,
- long: "--bootstrap-proxy-user PROXY_USER",
- description: "The proxy authentication username for the node being bootstrapped"
-
- # client.rb
- option :bootstrap_proxy_pass,
- long: "--bootstrap-proxy-pass PROXY_PASS",
- description: "The proxy authentication password for the node being bootstrapped"
-
- # client.rb
- option :bootstrap_no_proxy,
- long: "--bootstrap-no-proxy [NO_PROXY_URL|NO_PROXY_IP]",
- description: "Do not proxy locations for the node being bootstrapped; this option is used internally by Opscode",
- proc: Proc.new { |np| Chef::Config[:knife][:bootstrap_no_proxy] = np }
-
- # client.rb
- option :bootstrap_template,
- short: "-t TEMPLATE",
- long: "--bootstrap-template TEMPLATE",
- description: "Bootstrap Chef using a built-in or custom template. Set to the full path of an erb template or use one of the built-in templates."
-
-
- # bootstrap_context - client.rb
- option :node_ssl_verify_mode,
- long: "--node-ssl-verify-mode [peer|none]",
- description: "Whether or not to verify the SSL cert for all HTTPS requests.",
- proc: Proc.new { |v|
- valid_values = %w{none peer}
- unless valid_values.include?(v)
- raise "Invalid value '#{v}' for --node-ssl-verify-mode. Valid values are: #{valid_values.join(", ")}"
- end
- v
- }
-
- # bootstrap_context - client.rb
- option :node_verify_api_cert,
- long: "--[no-]node-verify-api-cert",
- description: "Verify the SSL cert for HTTPS requests to the Chef server API.",
- boolean: true
-
- # runtime, prefixes to ssh command. train: [:sudo] - auto prefixes everything
- option :use_sudo,
- long: "--sudo",
- description: "Execute the bootstrap via sudo",
- boolean: true
-
- # runtime - prefixes to ssh command string
- option :preserve_home,
- long: "--sudo-preserve-home",
- description: "Preserve non-root user HOME environment variable with sudo",
- boolean: true
-
- # runtime - prefixes to ssh command string
- option :use_sudo_password,
- long: "--use-sudo-password",
- description: "Execute the bootstrap via sudo with password",
- boolean: false
-
- # runtime - client_builder - set runlist when creating node
- option :run_list,
- short: "-r RUN_LIST",
- long: "--run-list RUN_LIST",
- description: "Comma separated list of roles/recipes to apply",
- proc: lambda { |o| o.split(/[\s,]+/) },
- default: []
-
- # runtime - client_builder - set policy name when creating node
- option :policy_name,
- long: "--policy-name POLICY_NAME",
- description: "Policyfile name to use (--policy-group must also be given)",
- default: nil
-
- # runtime - client_builder - set policy group when creating node
- option :policy_group,
- long: "--policy-group POLICY_GROUP",
- description: "Policy group name to use (--policy-name must also be given)",
- default: nil
-
- # runtime - client_builder - node tags
- option :tags,
- long: "--tags TAGS",
- description: "Comma separated list of tags to apply to the node",
- proc: lambda { |o| o.split(/[\s,]+/) },
- default: []
-
- # runtime - bootstrap template
- option :first_boot_attributes,
- short: "-j JSON_ATTRIBS",
- long: "--json-attributes",
- description: "A JSON string to be added to the first run of chef-client",
- proc: lambda { |o| Chef::JSONCompat.parse(o) },
- default: nil
-
- # runtime - bootstrap template
- option :first_boot_attributes_from_file,
- long: "--json-attribute-file FILE",
- description: "A JSON file to be used to the first run of chef-client",
- proc: lambda { |o| Chef::JSONCompat.parse(File.read(o)) },
- default: nil
-
- # ssh options - train options[:verify_host_key]
- option :host_key_verify,
- long: "--[no-]host-key-verify",
- description: "Verify host key, enabled by default.",
- boolean: true,
- default: true
-
-
- # bootstrap template
- # Create ohai hints in /etc/hef/ohai/hints, fname=hintname, content=value
- option :hint,
- long: "--hint HINT_NAME[=HINT_FILE]",
- description: "Specify Ohai Hint to be set on the bootstrap target. Use multiple --hint options to specify multiple hints.",
- proc: Proc.new { |h|
- Chef::Config[:knife][:hints] ||= Hash.new
- name, path = h.split("=")
- Chef::Config[:knife][:hints][name] = path ? Chef::JSONCompat.parse(::File.read(path)) : Hash.new
- }
-
- # bootstrap overrides that change bootstrap behavior - runs on target
- option :bootstrap_url,
- long: "--bootstrap-url URL",
- description: "URL to a custom installation script",
- proc: Proc.new { |u| Chef::Config[:knife][:bootstrap_url] = u }
-
- option :bootstrap_install_command,
- long: "--bootstrap-install-command COMMANDS",
- description: "Custom command to install chef-client",
- proc: Proc.new { |ic| Chef::Config[:knife][:bootstrap_install_command] = ic }
-
- option :bootstrap_preinstall_command,
- long: "--bootstrap-preinstall-command COMMANDS",
- description: "Custom commands to run before installing chef-client",
- proc: Proc.new { |preic| Chef::Config[:knife][:bootstrap_preinstall_command] = preic }
-
- # runtime on target - can this go away with switch to train + actions - uses mixlib-install.
- option :bootstrap_wget_options,
- long: "--bootstrap-wget-options OPTIONS",
- description: "Add options to wget when installing chef-client",
- proc: Proc.new { |wo| Chef::Config[:knife][:bootstrap_wget_options] = wo }
-
- # runtime - can this go away with switch to train + actions - uses mixlib-install.
- option :bootstrap_curl_options,
- long: "--bootstrap-curl-options OPTIONS",
- description: "Add options to curl when install chef-client",
- proc: Proc.new { |co| Chef::Config[:knife][:bootstrap_curl_options] = co }
-
- option :bootstrap_vault_file,
- long: "--bootstrap-vault-file VAULT_FILE",
- description: "A JSON file with a list of vault(s) and item(s) to be updated"
-
- option :bootstrap_vault_json,
- long: "--bootstrap-vault-json VAULT_JSON",
- description: "A JSON string with the vault(s) and item(s) to be updated"
-
- option :bootstrap_vault_item,
- long: "--bootstrap-vault-item VAULT_ITEM",
- description: 'A single vault and item to update as "vault:item"',
- proc: Proc.new { |i|
- (vault, item) = i.split(/:/)
- Chef::Config[:knife][:bootstrap_vault_item] ||= {}
- Chef::Config[:knife][:bootstrap_vault_item][vault] ||= []
- Chef::Config[:knife][:bootstrap_vault_item][vault].push(item)
- Chef::Config[:knife][:bootstrap_vault_item]
- }
-
def initialize(argv = [])
super
# TODO - these map cleanly to action support classes
diff --git a/lib/chef/knife/bootstrap/options.rb b/lib/chef/knife/bootstrap/options.rb
new file mode 100644
index 0000000000..d4ad714afa
--- /dev/null
+++ b/lib/chef/knife/bootstrap/options.rb
@@ -0,0 +1,267 @@
+# Author:: Marc Paradise (<marc@chef.io>)
+# Copyright:: Copyright 2019, Chef Software Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+module Chef
+ module Knife
+ class Bootstrap
+ module Options
+ def self.included(klass)
+ # SSH - :host
+ klass.option :ssh_user,
+ short: "-x USERNAME",
+ long: "--ssh-user USERNAME",
+ description: "The ssh username",
+ default: "root"
+
+ # SSH - :password
+ klass.option :ssh_password,
+ short: "-P PASSWORD",
+ long: "--ssh-password PASSWORD",
+ description: "The ssh password"
+
+ # SSH :port
+ klass.option :ssh_port,
+ short: "-p PORT",
+ long: "--ssh-port PORT",
+ description: "The ssh port",
+ proc: Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
+
+ # TODO SSH train gives bastion_host which seeems to map to getway/gateway_identity -
+ # though not exactly.
+ klass.option :ssh_gateway,
+ short: "-G GATEWAY",
+ long: "--ssh-gateway GATEWAY",
+ description: "The ssh gateway",
+ proc: Proc.new { |key| Chef::Config[:knife][:ssh_gateway] = key }
+
+ # TODO - missing in train: ssh_gateway_identity. But could just append to
+ # keyfiles - train accepts multiple?
+ # TODO - train supports bastion_user and bastion_port
+ # SSH - this just maps to key_files - under knife-ssh we would use either this,
+ # _or_ ssh_identity_file
+ # either this or 'ssh_identity_file' but not both.
+ klass.option :ssh_gateway_identity,
+ long: "--ssh-gateway-identity SSH_GATEWAY_IDENTITY",
+ description: "The SSH identity file used for gateway authentication",
+ proc: Proc.new { |key| Chef::Config[:knife][:ssh_gateway_identity] = key }
+
+ # SSH train ssh: options[:forward_agent]
+ klass.option :forward_agent,
+ short: "-A",
+ long: "--forward-agent",
+ description: "Enable SSH agent forwarding",
+ boolean: true
+
+ # SSH train: options[key_files]
+ klass.option :ssh_identity_file,
+ short: "-i IDENTITY_FILE",
+ long: "--ssh-identity-file IDENTITY_FILE",
+ description: "The SSH identity file used for authentication"
+
+ klass.option :chef_node_name,
+ short: "-N NAME",
+ long: "--node-name NAME",
+ description: "The Chef node name for your new node"
+
+ klass.option :prerelease,
+ long: "--prerelease",
+ description: "Install the pre-release chef gems"
+
+ # client.rb
+ klass.option :bootstrap_version,
+ long: "--bootstrap-version VERSION",
+ description: "The version of Chef to install",
+ proc: lambda { |v| Chef::Config[:knife][:bootstrap_version] = v }
+
+ # client.rb
+ klass.option :bootstrap_proxy,
+ long: "--bootstrap-proxy PROXY_URL",
+ description: "The proxy server for the node being bootstrapped",
+ proc: Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
+
+ # client.rb
+ klass.option :bootstrap_proxy_user,
+ long: "--bootstrap-proxy-user PROXY_USER",
+ description: "The proxy authentication username for the node being bootstrapped"
+
+ # client.rb
+ klass.option :bootstrap_proxy_pass,
+ long: "--bootstrap-proxy-pass PROXY_PASS",
+ description: "The proxy authentication password for the node being bootstrapped"
+
+ # client.rb
+ klass.option :bootstrap_no_proxy,
+ long: "--bootstrap-no-proxy [NO_PROXY_URL|NO_PROXY_IP]",
+ description: "Do not proxy locations for the node being bootstrapped; this klass.option is used internally by Opscode",
+ proc: Proc.new { |np| Chef::Config[:knife][:bootstrap_no_proxy] = np }
+
+ # client.rb
+ klass.option :bootstrap_template,
+ short: "-t TEMPLATE",
+ long: "--bootstrap-template TEMPLATE",
+ description: "Bootstrap Chef using a built-in or custom template. Set to the full path of an erb template or use one of the built-in templates."
+
+
+ # bootstrap_context - client.rb
+ klass.option :node_ssl_verify_mode,
+ long: "--node-ssl-verify-mode [peer|none]",
+ description: "Whether or not to verify the SSL cert for all HTTPS requests.",
+ proc: Proc.new { |v|
+ valid_values = %w{none peer}
+ unless valid_values.include?(v)
+ raise "Invalid value '#{v}' for --node-ssl-verify-mode. Valid values are: #{valid_values.join(", ")}"
+ end
+ v
+ }
+
+ # bootstrap_context - client.rb
+ klass.option :node_verify_api_cert,
+ long: "--[no-]node-verify-api-cert",
+ description: "Verify the SSL cert for HTTPS requests to the Chef server API.",
+ boolean: true
+
+ # runtime, prefixes to ssh command. train: [:sudo] - auto prefixes everything
+ klass.option :use_sudo,
+ long: "--sudo",
+ description: "Execute the bootstrap via sudo",
+ boolean: true
+
+ # runtime - prefixes to ssh command string
+ klass.option :preserve_home,
+ long: "--sudo-preserve-home",
+ description: "Preserve non-root user HOME environment variable with sudo",
+ boolean: true
+
+ # runtime - prefixes to ssh command string
+ klass.option :use_sudo_password,
+ long: "--use-sudo-password",
+ description: "Execute the bootstrap via sudo with password",
+ boolean: false
+
+ # runtime - client_builder - set runlist when creating node
+ klass.option :run_list,
+ short: "-r RUN_LIST",
+ long: "--run-list RUN_LIST",
+ description: "Comma separated list of roles/recipes to apply",
+ proc: lambda { |o| o.split(/[\s,]+/) },
+ default: []
+
+ # runtime - client_builder - set policy name when creating node
+ klass.option :policy_name,
+ long: "--policy-name POLICY_NAME",
+ description: "Policyfile name to use (--policy-group must also be given)",
+ default: nil
+
+ # runtime - client_builder - set policy group when creating node
+ klass.option :policy_group,
+ long: "--policy-group POLICY_GROUP",
+ description: "Policy group name to use (--policy-name must also be given)",
+ default: nil
+
+ # runtime - client_builder - node tags
+ klass.option :tags,
+ long: "--tags TAGS",
+ description: "Comma separated list of tags to apply to the node",
+ proc: lambda { |o| o.split(/[\s,]+/) },
+ default: []
+
+ # runtime - bootstrap template
+ klass.option :first_boot_attributes,
+ short: "-j JSON_ATTRIBS",
+ long: "--json-attributes",
+ description: "A JSON string to be added to the first run of chef-client",
+ proc: lambda { |o| Chef::JSONCompat.parse(o) },
+ default: nil
+
+ # runtime - bootstrap template
+ klass.option :first_boot_attributes_from_file,
+ long: "--json-attribute-file FILE",
+ description: "A JSON file to be used to the first run of chef-client",
+ proc: lambda { |o| Chef::JSONCompat.parse(File.read(o)) },
+ default: nil
+
+ # ssh options - train options[:verify_host_key]
+ klass.option :host_key_verify,
+ long: "--[no-]host-key-verify",
+ description: "Verify host key, enabled by default.",
+ boolean: true,
+ default: true
+
+
+ # bootstrap template
+ # Create ohai hints in /etc/hef/ohai/hints, fname=hintname, content=value
+ klass.option :hint,
+ long: "--hint HINT_NAME[=HINT_FILE]",
+ description: "Specify Ohai Hint to be set on the bootstrap target. Use multiple --hint options to specify multiple hints.",
+ proc: Proc.new { |h|
+ Chef::Config[:knife][:hints] ||= Hash.new
+ name, path = h.split("=")
+ Chef::Config[:knife][:hints][name] = path ? Chef::JSONCompat.parse(::File.read(path)) : Hash.new
+ }
+
+ # bootstrap overrides that change bootstrap behavior - runs on target
+ klass.option :bootstrap_url,
+ long: "--bootstrap-url URL",
+ description: "URL to a custom installation script",
+ proc: Proc.new { |u| Chef::Config[:knife][:bootstrap_url] = u }
+
+ klass.option :bootstrap_install_command,
+ long: "--bootstrap-install-command COMMANDS",
+ description: "Custom command to install chef-client",
+ proc: Proc.new { |ic| Chef::Config[:knife][:bootstrap_install_command] = ic }
+
+ klass.option :bootstrap_preinstall_command,
+ long: "--bootstrap-preinstall-command COMMANDS",
+ description: "Custom commands to run before installing chef-client",
+ proc: Proc.new { |preic| Chef::Config[:knife][:bootstrap_preinstall_command] = preic }
+
+ # runtime on target - can this go away with switch to train + actions - uses mixlib-install.
+ klass.option :bootstrap_wget_options,
+ long: "--bootstrap-wget-options OPTIONS",
+ description: "Add options to wget when installing chef-client",
+ proc: Proc.new { |wo| Chef::Config[:knife][:bootstrap_wget_options] = wo }
+
+ # runtime - can this go away with switch to train + actions - uses mixlib-install.
+ klass.option :bootstrap_curl_options,
+ long: "--bootstrap-curl-options OPTIONS",
+ description: "Add options to curl when install chef-client",
+ proc: Proc.new { |co| Chef::Config[:knife][:bootstrap_curl_options] = co }
+
+ klass.option :bootstrap_vault_file,
+ long: "--bootstrap-vault-file VAULT_FILE",
+ description: "A JSON file with a list of vault(s) and item(s) to be updated"
+
+ klass.option :bootstrap_vault_json,
+ long: "--bootstrap-vault-json VAULT_JSON",
+ description: "A JSON string with the vault(s) and item(s) to be updated"
+
+ klass.option :bootstrap_vault_item,
+ long: "--bootstrap-vault-item VAULT_ITEM",
+ description: 'A single vault and item to update as "vault:item"',
+ proc: Proc.new { |i|
+ (vault, item) = i.split(/:/)
+ Chef::Config[:knife][:bootstrap_vault_item] ||= {}
+ Chef::Config[:knife][:bootstrap_vault_item][vault] ||= []
+ Chef::Config[:knife][:bootstrap_vault_item][vault].push(item)
+ Chef::Config[:knife][:bootstrap_vault_item]
+ }
+
+ end
+ end
+ end
+ end
+end