summaryrefslogtreecommitdiff
path: root/lib/chef
diff options
context:
space:
mode:
authortylercloke <tylercloke@gmail.com>2015-04-23 13:35:58 -0700
committertylercloke <tylercloke@gmail.com>2015-04-28 14:24:57 -0700
commit2c07a07d816937c5228b67836782a19fb7e7a30b (patch)
tree7c5febef7c1b63a3cd720e3562aa3000e84a8f4e /lib/chef
parentafa4b9e4034628bf5a4f337cf57cfa657df6ec3d (diff)
downloadchef-2c07a07d816937c5228b67836782a19fb7e7a30b.tar.gz
Implemented `knife user key create` and `knife client key create`.
Implemented using a common service class that contains most of the actual functionality outside of parsing and inheriting Chef::Knife.
Diffstat (limited to 'lib/chef')
-rw-r--r--lib/chef/config.rb4
-rw-r--r--lib/chef/exceptions.rb1
-rw-r--r--lib/chef/knife/client_key_create.rb67
-rw-r--r--lib/chef/knife/key_create.rb108
-rw-r--r--lib/chef/knife/key_create_base.rb50
-rw-r--r--lib/chef/knife/user_key_create.rb69
6 files changed, 298 insertions, 1 deletions
diff --git a/lib/chef/config.rb b/lib/chef/config.rb
index d73bcf8e6e..d2d3c736c2 100644
--- a/lib/chef/config.rb
+++ b/lib/chef/config.rb
@@ -326,8 +326,10 @@ class Chef
# 'some_url.../organizations/*' then remove the '/organization/*' by default
if self.configuration[:chef_server_url] =~ /\/organizations\/\S*$/
self.configuration[:chef_server_url].split('/')[0..-3].join('/')
- else # default to whatever chef_server_url is
+ elsif self.configuration[:chef_server_url] # default to whatever chef_server_url is
self.configuration[:chef_server_url]
+ else
+ "https://localhost:443"
end
end
diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb
index cfedbfd0d9..da562e70f4 100644
--- a/lib/chef/exceptions.rb
+++ b/lib/chef/exceptions.rb
@@ -70,6 +70,7 @@ class Chef
class InvalidPrivateKey < ArgumentError; end
class ConfigurationError < ArgumentError; end
class MissingKeyAttribute < ArgumentError; end
+ class KeyCommandInputError < ArgumentError; end
class InvalidKeyArgument < ArgumentError; end
class InvalidKeyAttribute < ArgumentError; end
class RedirectLimitExceeded < RuntimeError; end
diff --git a/lib/chef/knife/client_key_create.rb b/lib/chef/knife/client_key_create.rb
new file mode 100644
index 0000000000..3b7e97eb24
--- /dev/null
+++ b/lib/chef/knife/client_key_create.rb
@@ -0,0 +1,67 @@
+#
+# Author:: Tyler Cloke (tyler@chef.io)
+# Copyright:: Copyright (c) 2015 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.
+#
+
+require 'chef/knife'
+require 'chef/knife/key_create_base'
+
+class Chef
+ class Knife
+ # Implements knife user key create using Chef::Knife::KeyCreate
+ # as a service class.
+ #
+ # @author Tyler Cloke
+ #
+ # @attr_reader [String] actor the name of the client that this key is for
+ class ClientKeyCreate < Knife
+ include Chef::Knife::KeyCreateBase
+
+ attr_reader :actor
+
+ def initialize(argv=[])
+ super(argv)
+ @service_object = nil
+ end
+
+ def run
+ apply_params!(@name_args)
+ service_object.run
+ end
+
+ def actor_field_name
+ 'client'
+ end
+
+ def service_object
+ @service_object ||= Chef::Knife::KeyCreate.new(@actor, actor_field_name, ui, config)
+ end
+
+ def actor_missing_error
+ 'You must specify a client name'
+ end
+
+ def apply_params!(params)
+ @actor = params[0]
+ if @actor.nil?
+ show_usage
+ ui.fatal(actor_missing_error)
+ exit 1
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/knife/key_create.rb b/lib/chef/knife/key_create.rb
new file mode 100644
index 0000000000..5ee36e9793
--- /dev/null
+++ b/lib/chef/knife/key_create.rb
@@ -0,0 +1,108 @@
+#
+# Author:: Tyler Cloke (<tyler@chef.io>)
+# Copyright:: Copyright (c) 2015 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.
+#
+
+require 'chef/key'
+require 'chef/json_compat'
+require 'chef/exceptions'
+
+class Chef
+ class Knife
+ # Service class for UserKeyCreate and ClientKeyCreate,
+ # Implements common functionality of knife [user | org client] key create.
+ #
+ # @author Tyler Cloke
+ #
+ # @attr_accessor [Hash] cli input, see UserKeyCreate and ClientKeyCreate for what could populate it
+ class KeyCreate
+
+ attr_accessor :config
+
+ def initialize(actor, actor_field_name, ui, config)
+ @actor = actor
+ @actor_field_name = actor_field_name
+ @ui = ui
+ @config = config
+ end
+
+ def public_key_or_key_name_error_msg
+<<EOS
+You must pass either --public-key or --key-name, or both.
+If you only pass --public-key, a key name will be generated from the fingerprint of your key.
+If you only pass --key-name, a key pair will be generated by the server.
+EOS
+ end
+
+ def edit_data(key)
+ @ui.edit_data(key)
+ end
+
+ def display_info(input)
+ @ui.info(input)
+ end
+
+ def display_private_key(private_key)
+ @ui.msg(private_key)
+ end
+
+ def output_private_key_to_file(private_key)
+ File.open(@config[:file], "w") do |f|
+ f.print(private_key)
+ end
+ end
+
+ def create_key_from_hash(output)
+ Chef::Key.from_hash(output).create
+ end
+
+ def run
+ key = Chef::Key.new(@actor, @actor_field_name)
+ if !@config[:public_key] && !@config[:key_name]
+ raise Chef::Exceptions::KeyCommandInputError, public_key_or_key_name_error_msg
+ elsif !@config[:public_key]
+ key.create_key(true)
+ end
+
+ if @config[:public_key]
+ key.public_key(File.read(File.expand_path(@config[:public_key])))
+ end
+
+ if @config[:key_name]
+ key.name(@config[:key_name])
+ end
+
+ if @config[:expiration_date]
+ key.expiration_date(@config[:expiration_date])
+ else
+ key.expiration_date("infinity")
+ end
+
+ output = edit_data(key)
+ key = create_key_from_hash(output)
+
+ display_info("Created key: #{key.name}")
+ if key.private_key
+ if @config[:file]
+ output_private_key_to_file(key.private_key)
+ else
+ display_private_key(key.private_key)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/knife/key_create_base.rb b/lib/chef/knife/key_create_base.rb
new file mode 100644
index 0000000000..da31f70d1d
--- /dev/null
+++ b/lib/chef/knife/key_create_base.rb
@@ -0,0 +1,50 @@
+#
+# Author:: Tyler Cloke (<tyler@chef.io>)
+# Copyright:: Copyright (c) 2015 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.
+#
+
+class Chef
+ class Knife
+ # Extendable module that class_eval's common options into UserKeyCreate and ClientKeyCreate
+ #
+ # @author Tyler Cloke
+ module KeyCreateBase
+ def self.included(includer)
+ includer.class_eval do
+ option :public_key,
+ :short => "-p FILENAME",
+ :long => "--public-key FILENAME",
+ :description => "Public key for newly created key. If not passed, the server will create a key pair for you, but you must pass --key-name NAME in that case."
+
+ option :file,
+ :short => "-f FILE",
+ :long => "--file FILE",
+ :description => "Write the private key to a file, if you requested the server to create one."
+
+ option :key_name,
+ :short => "-k NAME",
+ :long => "--key-name NAME",
+ :description => "The name for your key. If you do not pass a name, you must pass --public-key, and the name will default to the fingerprint of the public key passed."
+
+ option :expiration_date,
+ :short => "-e DATE",
+ :long => "--expiration-date DATE",
+ :description => "Optionally pass the expiration date for the key in ISO 8601 fomatted string: YYYY-MM-DDTHH:MM:SSZ e.g. 2013-12-24T21:00:00Z. Defaults to infinity if not passed. UTC timezone assumed."
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/knife/user_key_create.rb b/lib/chef/knife/user_key_create.rb
new file mode 100644
index 0000000000..5ed699ff5b
--- /dev/null
+++ b/lib/chef/knife/user_key_create.rb
@@ -0,0 +1,69 @@
+#
+# Author:: Tyler Cloke (tyler@chef.io)
+# Copyright:: Copyright (c) 2015 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.
+#
+
+require 'chef/knife'
+require 'chef/knife/key_create_base'
+
+class Chef
+ class Knife
+ # Implements knife user key create using Chef::Knife::KeyCreate
+ # as a service class.
+ #
+ # @author Tyler Cloke
+ #
+ # @attr_reader [String] actor the name of the user that this key is for
+ class UserKeyCreate < Knife
+ include Chef::Knife::KeyCreateBase
+
+ banner 'knife user key create USER (options)'
+
+ attr_reader :actor
+
+ def initialize(argv=[])
+ super(argv)
+ @service_object = nil
+ end
+
+ def run
+ apply_params!(@name_args)
+ service_object.run
+ end
+
+ def actor_field_name
+ 'user'
+ end
+
+ def service_object
+ @service_object ||= Chef::Knife::KeyCreate.new(@actor, actor_field_name, ui, config)
+ end
+
+ def actor_missing_error
+ 'You must specify a user name'
+ end
+
+ def apply_params!(params)
+ @actor = params[0]
+ if @actor.nil?
+ show_usage
+ ui.fatal(actor_missing_error)
+ exit 1
+ end
+ end
+ end
+ end
+end