summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/chef/knife/osc_user_create.rb6
-rw-r--r--lib/chef/knife/osc_user_delete.rb4
-rw-r--r--lib/chef/knife/osc_user_edit.rb6
-rw-r--r--lib/chef/knife/osc_user_list.rb4
-rw-r--r--lib/chef/knife/osc_user_reregister.rb4
-rw-r--r--lib/chef/knife/osc_user_show.rb4
-rw-r--r--lib/chef/knife/user_create.rb6
-rw-r--r--lib/chef/knife/user_delete.rb8
-rw-r--r--lib/chef/knife/user_edit.rb6
-rw-r--r--lib/chef/knife/user_list.rb4
-rw-r--r--lib/chef/knife/user_reregister.rb4
-rw-r--r--lib/chef/knife/user_show.rb4
-rw-r--r--lib/chef/osc_user.rb194
-rw-r--r--lib/chef/user.rb241
-rw-r--r--lib/chef/user_v1.rb335
15 files changed, 417 insertions, 413 deletions
diff --git a/lib/chef/knife/osc_user_create.rb b/lib/chef/knife/osc_user_create.rb
index c368296040..6c3415473f 100644
--- a/lib/chef/knife/osc_user_create.rb
+++ b/lib/chef/knife/osc_user_create.rb
@@ -27,7 +27,7 @@ class Chef
class OscUserCreate < Knife
deps do
- require 'chef/osc_user'
+ require 'chef/user'
require 'chef/json_compat'
end
@@ -69,7 +69,7 @@ class Chef
exit 1
end
- user = Chef::OscUser.new
+ user = Chef::User.new
user.name(@user_name)
user.admin(config[:admin])
user.password config[:user_password]
@@ -79,7 +79,7 @@ class Chef
end
output = edit_data(user)
- user = Chef::OscUser.from_hash(output).create
+ user = Chef::User.from_hash(output).create
ui.info("Created #{user}")
if user.private_key
diff --git a/lib/chef/knife/osc_user_delete.rb b/lib/chef/knife/osc_user_delete.rb
index d6fbd4a6a9..5cd4f10413 100644
--- a/lib/chef/knife/osc_user_delete.rb
+++ b/lib/chef/knife/osc_user_delete.rb
@@ -28,7 +28,7 @@ class Chef
class OscUserDelete < Knife
deps do
- require 'chef/osc_user'
+ require 'chef/user'
require 'chef/json_compat'
end
@@ -43,7 +43,7 @@ class Chef
exit 1
end
- delete_object(Chef::OscUser, @user_name)
+ delete_object(Chef::User, @user_name)
end
end
diff --git a/lib/chef/knife/osc_user_edit.rb b/lib/chef/knife/osc_user_edit.rb
index 4c38674d08..526475db05 100644
--- a/lib/chef/knife/osc_user_edit.rb
+++ b/lib/chef/knife/osc_user_edit.rb
@@ -28,7 +28,7 @@ class Chef
class OscUserEdit < Knife
deps do
- require 'chef/osc_user'
+ require 'chef/user'
require 'chef/json_compat'
end
@@ -43,10 +43,10 @@ class Chef
exit 1
end
- original_user = Chef::OscUser.load(@user_name).to_hash
+ original_user = Chef::User.load(@user_name).to_hash
edited_user = edit_data(original_user)
if original_user != edited_user
- user = Chef::OscUser.from_hash(edited_user)
+ user = Chef::User.from_hash(edited_user)
user.update
ui.msg("Saved #{user}.")
else
diff --git a/lib/chef/knife/osc_user_list.rb b/lib/chef/knife/osc_user_list.rb
index 92f049cd19..84fca31899 100644
--- a/lib/chef/knife/osc_user_list.rb
+++ b/lib/chef/knife/osc_user_list.rb
@@ -28,7 +28,7 @@ class Chef
class OscUserList < Knife
deps do
- require 'chef/osc_user'
+ require 'chef/user'
require 'chef/json_compat'
end
@@ -40,7 +40,7 @@ class Chef
:description => "Show corresponding URIs"
def run
- output(format_list_for_display(Chef::OscUser.list))
+ output(format_list_for_display(Chef::User.list))
end
end
end
diff --git a/lib/chef/knife/osc_user_reregister.rb b/lib/chef/knife/osc_user_reregister.rb
index a71e0aa677..163b286fe0 100644
--- a/lib/chef/knife/osc_user_reregister.rb
+++ b/lib/chef/knife/osc_user_reregister.rb
@@ -28,7 +28,7 @@ class Chef
class OscUserReregister < Knife
deps do
- require 'chef/osc_user'
+ require 'chef/user'
require 'chef/json_compat'
end
@@ -48,7 +48,7 @@ class Chef
exit 1
end
- user = Chef::OscUser.load(@user_name).reregister
+ user = Chef::User.load(@user_name).reregister
Chef::Log.debug("Updated user data: #{user.inspect}")
key = user.private_key
if config[:file]
diff --git a/lib/chef/knife/osc_user_show.rb b/lib/chef/knife/osc_user_show.rb
index 6a41ddae88..cb3a77585a 100644
--- a/lib/chef/knife/osc_user_show.rb
+++ b/lib/chef/knife/osc_user_show.rb
@@ -30,7 +30,7 @@ class Chef
include Knife::Core::MultiAttributeReturnOption
deps do
- require 'chef/osc_user'
+ require 'chef/user'
require 'chef/json_compat'
end
@@ -45,7 +45,7 @@ class Chef
exit 1
end
- user = Chef::OscUser.load(@user_name)
+ user = Chef::User.load(@user_name)
output(format_for_display(user))
end
diff --git a/lib/chef/knife/user_create.rb b/lib/chef/knife/user_create.rb
index e73f6be8b6..995573cd03 100644
--- a/lib/chef/knife/user_create.rb
+++ b/lib/chef/knife/user_create.rb
@@ -27,7 +27,7 @@ class Chef
attr_accessor :user_field
deps do
- require 'chef/user'
+ require 'chef/user_v1'
require 'chef/json_compat'
end
@@ -61,11 +61,11 @@ class Chef
banner "knife user create USERNAME DISPLAY_NAME FIRST_NAME LAST_NAME EMAIL PASSWORD (options)"
def user
- @user_field ||= Chef::User.new
+ @user_field ||= Chef::UserV1.new
end
def create_user_from_hash(hash)
- Chef::User.from_hash(hash).create
+ Chef::UserV1.from_hash(hash).create
end
def osc_11_warning
diff --git a/lib/chef/knife/user_delete.rb b/lib/chef/knife/user_delete.rb
index 803be6b90c..828cd51588 100644
--- a/lib/chef/knife/user_delete.rb
+++ b/lib/chef/knife/user_delete.rb
@@ -23,7 +23,7 @@ class Chef
class UserDelete < Knife
deps do
- require 'chef/user'
+ require 'chef/user_v1'
require 'chef/json_compat'
end
@@ -55,7 +55,7 @@ EOF
if Kernel.block_given?
object = block.call
else
- object = Chef::User.load(user_name)
+ object = Chef::UserV1.load(user_name)
object.destroy
end
@@ -77,10 +77,10 @@ EOF
# Below is modification of Chef::Knife.delete_object to detect OSC 11 server.
# When OSC 11 is deprecated, simply delete all this and go back to:
#
- # delete_object(Chef::User, @user_name)
+ # delete_object(Chef::UserV1, @user_name)
#
# Also delete our override of delete_object above
- object = Chef::User.load(@user_name)
+ object = Chef::UserV1.load(@user_name)
# OSC 11 case
if object.username.nil?
diff --git a/lib/chef/knife/user_edit.rb b/lib/chef/knife/user_edit.rb
index d194f6697b..c3a4326ee8 100644
--- a/lib/chef/knife/user_edit.rb
+++ b/lib/chef/knife/user_edit.rb
@@ -23,7 +23,7 @@ class Chef
class UserEdit < Knife
deps do
- require 'chef/user'
+ require 'chef/user_v1'
require 'chef/json_compat'
end
@@ -56,7 +56,7 @@ EOF
exit 1
end
- original_user = Chef::User.load(@user_name).to_hash
+ original_user = Chef::UserV1.load(@user_name).to_hash
# DEPRECATION NOTE
# Remove this if statement and corrosponding code post OSC 11 support.
#
@@ -68,7 +68,7 @@ EOF
else # EC / CS 12 user create
edited_user = edit_data(original_user)
if original_user != edited_user
- user = Chef::User.from_hash(edited_user)
+ user = Chef::UserV1.from_hash(edited_user)
user.update
ui.msg("Saved #{user}.")
else
diff --git a/lib/chef/knife/user_list.rb b/lib/chef/knife/user_list.rb
index 7ae43dadc9..6a130392b9 100644
--- a/lib/chef/knife/user_list.rb
+++ b/lib/chef/knife/user_list.rb
@@ -25,7 +25,7 @@ class Chef
class UserList < Knife
deps do
- require 'chef/user'
+ require 'chef/user_v1'
require 'chef/json_compat'
end
@@ -37,7 +37,7 @@ class Chef
:description => "Show corresponding URIs"
def run
- output(format_list_for_display(Chef::User.list))
+ output(format_list_for_display(Chef::UserV1.list))
end
end
diff --git a/lib/chef/knife/user_reregister.rb b/lib/chef/knife/user_reregister.rb
index eab2245025..09fd1cd2d6 100644
--- a/lib/chef/knife/user_reregister.rb
+++ b/lib/chef/knife/user_reregister.rb
@@ -23,7 +23,7 @@ class Chef
class UserReregister < Knife
deps do
- require 'chef/user'
+ require 'chef/user_v1'
require 'chef/json_compat'
end
@@ -61,7 +61,7 @@ EOF
exit 1
end
- user = Chef::User.load(@user_name)
+ user = Chef::UserV1.load(@user_name)
# DEPRECATION NOTE
# Remove this if statement and corrosponding code post OSC 11 support.
diff --git a/lib/chef/knife/user_show.rb b/lib/chef/knife/user_show.rb
index f5e81e9972..3a2443471a 100644
--- a/lib/chef/knife/user_show.rb
+++ b/lib/chef/knife/user_show.rb
@@ -25,7 +25,7 @@ class Chef
include Knife::Core::MultiAttributeReturnOption
deps do
- require 'chef/user'
+ require 'chef/user_v1'
require 'chef/json_compat'
end
@@ -58,7 +58,7 @@ EOF
exit 1
end
- user = Chef::User.load(@user_name)
+ user = Chef::UserV1.load(@user_name)
# DEPRECATION NOTE
# Remove this if statement and corrosponding code post OSC 11 support.
diff --git a/lib/chef/osc_user.rb b/lib/chef/osc_user.rb
deleted file mode 100644
index 52bfd11108..0000000000
--- a/lib/chef/osc_user.rb
+++ /dev/null
@@ -1,194 +0,0 @@
-#
-# Author:: Steven Danna (steve@opscode.com)
-# Copyright:: Copyright 2012 Opscode, 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/config'
-require 'chef/mixin/params_validate'
-require 'chef/mixin/from_file'
-require 'chef/mash'
-require 'chef/json_compat'
-require 'chef/search/query'
-
-# TODO
-# DEPRECATION NOTE
-# This class was previously Chef::User. It is the code to support the User object
-# corrosponding to the Open Source Chef Server 11 and only still exists to support
-# users still on OSC 11.
-#
-# Chef::User now supports Chef Server 12.
-#
-# New development should occur in Chef::User.
-# This file and corrosponding osc_user knife files
-# should be removed once client support for Open Source Chef Server 11 expires.
-class Chef
- class OscUser
-
- include Chef::Mixin::FromFile
- include Chef::Mixin::ParamsValidate
-
- def initialize
- @name = ''
- @public_key = nil
- @private_key = nil
- @password = nil
- @admin = false
- end
-
- def name(arg=nil)
- set_or_return(:name, arg,
- :regex => /^[a-z0-9\-_]+$/)
- end
-
- def admin(arg=nil)
- set_or_return(:admin,
- arg, :kind_of => [TrueClass, FalseClass])
- end
-
- def public_key(arg=nil)
- set_or_return(:public_key,
- arg, :kind_of => String)
- end
-
- def private_key(arg=nil)
- set_or_return(:private_key,
- arg, :kind_of => String)
- end
-
- def password(arg=nil)
- set_or_return(:password,
- arg, :kind_of => String)
- end
-
- def to_hash
- result = {
- "name" => @name,
- "public_key" => @public_key,
- "admin" => @admin
- }
- result["private_key"] = @private_key if @private_key
- result["password"] = @password if @password
- result
- end
-
- def to_json(*a)
- Chef::JSONCompat.to_json(to_hash, *a)
- end
-
- def destroy
- Chef::REST.new(Chef::Config[:chef_server_url]).delete_rest("users/#{@name}")
- end
-
- def create
- payload = {:name => self.name, :admin => self.admin, :password => self.password }
- payload[:public_key] = public_key if public_key
- new_user =Chef::REST.new(Chef::Config[:chef_server_url]).post_rest("users", payload)
- Chef::OscUser.from_hash(self.to_hash.merge(new_user))
- end
-
- def update(new_key=false)
- payload = {:name => name, :admin => admin}
- payload[:private_key] = new_key if new_key
- payload[:password] = password if password
- updated_user = Chef::REST.new(Chef::Config[:chef_server_url]).put_rest("users/#{name}", payload)
- Chef::OscUser.from_hash(self.to_hash.merge(updated_user))
- end
-
- def save(new_key=false)
- begin
- create
- rescue Net::HTTPServerException => e
- if e.response.code == "409"
- update(new_key)
- else
- raise e
- end
- end
- end
-
- def reregister
- r = Chef::REST.new(Chef::Config[:chef_server_url])
- reregistered_self = r.put_rest("users/#{name}", { :name => name, :admin => admin, :private_key => true })
- private_key(reregistered_self["private_key"])
- self
- end
-
- def to_s
- "user[#{@name}]"
- end
-
- def inspect
- "Chef::OscUser name:'#{name}' admin:'#{admin.inspect}'" +
- "public_key:'#{public_key}' private_key:#{private_key}"
- end
-
- # Class Methods
-
- def self.from_hash(user_hash)
- user = Chef::OscUser.new
- user.name user_hash['name']
- user.private_key user_hash['private_key'] if user_hash.key?('private_key')
- user.password user_hash['password'] if user_hash.key?('password')
- user.public_key user_hash['public_key']
- user.admin user_hash['admin']
- user
- end
-
- def self.from_json(json)
- Chef::OscUser.from_hash(Chef::JSONCompat.from_json(json))
- end
-
- class << self
- alias_method :json_create, :from_json
- end
-
- def self.list(inflate=false)
- response = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest('users')
- users = if response.is_a?(Array)
- transform_ohc_list_response(response) # OHC/OPC
- else
- response # OSC
- end
- if inflate
- users.inject({}) do |user_map, (name, _url)|
- user_map[name] = Chef::OscUser.load(name)
- user_map
- end
- else
- users
- end
- end
-
- def self.load(name)
- response = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("users/#{name}")
- Chef::OscUser.from_hash(response)
- end
-
- # Gross. Transforms an API response in the form of:
- # [ { "user" => { "username" => USERNAME }}, ...]
- # into the form
- # { "USERNAME" => "URI" }
- def self.transform_ohc_list_response(response)
- new_response = Hash.new
- response.each do |u|
- name = u['user']['username']
- new_response[name] = Chef::Config[:chef_server_url] + "/users/#{name}"
- end
- new_response
- end
-
- private_class_method :transform_ohc_list_response
- end
-end
diff --git a/lib/chef/user.rb b/lib/chef/user.rb
index 717deb63c3..bc9705c092 100644
--- a/lib/chef/user.rb
+++ b/lib/chef/user.rb
@@ -21,85 +21,44 @@ require 'chef/mixin/from_file'
require 'chef/mash'
require 'chef/json_compat'
require 'chef/search/query'
-require 'chef/mixin/api_version_request_handling'
-require 'chef/exceptions'
-require 'chef/server_api'
-# OSC 11 BACKWARDS COMPATIBILITY NOTE (remove after OSC 11 support ends)
+# TODO
+# DEPRECATION NOTE
+# This class will be replaced by Chef::UserV1 in Chef 13. It is the code to support the User object
+# corrosponding to the Open Source Chef Server 11 and only still exists to support
+# users still on OSC 11.
#
-# In general, Chef::User is no longer expected to support Open Source Chef 11 Server requests.
-# The object that handles those requests has been moved to the Chef::OscUser namespace.
+# Chef::UserV1 now supports Chef Server 12 and will be moved to this namespace in Chef 13.
#
-# Exception: self.list is backwards compatible with OSC 11
+# New development should occur in Chef::UserV1.
+# This file and corrosponding osc_user knife files
+# should be removed once client support for Open Source Chef Server 11 expires.
class Chef
class User
include Chef::Mixin::FromFile
include Chef::Mixin::ParamsValidate
- include Chef::Mixin::ApiVersionRequestHandling
-
- SUPPORTED_API_VERSIONS = [0,1]
def initialize
- @username = nil
- @display_name = nil
- @first_name = nil
- @middle_name = nil
- @last_name = nil
- @email = nil
- @password = nil
+ @name = ''
@public_key = nil
@private_key = nil
- @create_key = nil
@password = nil
+ @admin = false
end
- def chef_root_rest_v0
- @chef_root_rest_v0 ||= Chef::ServerAPI.new(Chef::Config[:chef_server_root], {:api_version => "0"})
- end
-
- def chef_root_rest_v1
- @chef_root_rest_v1 ||= Chef::ServerAPI.new(Chef::Config[:chef_server_root], {:api_version => "1"})
+ def chef_rest_v0
+ @chef_rest_v0 ||= Chef::ServerAPI.new(Chef::Config[:chef_server_url], {:api_version => "0"})
end
- def username(arg=nil)
- set_or_return(:username, arg,
+ def name(arg=nil)
+ set_or_return(:name, arg,
:regex => /^[a-z0-9\-_]+$/)
end
- def display_name(arg=nil)
- set_or_return(:display_name,
- arg, :kind_of => String)
- end
-
- def first_name(arg=nil)
- set_or_return(:first_name,
- arg, :kind_of => String)
- end
-
- def middle_name(arg=nil)
- set_or_return(:middle_name,
- arg, :kind_of => String)
- end
-
- def last_name(arg=nil)
- set_or_return(:last_name,
- arg, :kind_of => String)
- end
-
- def email(arg=nil)
- set_or_return(:email,
- arg, :kind_of => String)
- end
-
- def password(arg=nil)
- set_or_return(:password,
- arg, :kind_of => String)
- end
-
- def create_key(arg=nil)
- set_or_return(:create_key, arg,
- :kind_of => [TrueClass, FalseClass])
+ def admin(arg=nil)
+ set_or_return(:admin,
+ arg, :kind_of => [TrueClass, FalseClass])
end
def public_key(arg=nil)
@@ -119,17 +78,12 @@ class Chef
def to_hash
result = {
- "username" => @username
+ "name" => @name,
+ "public_key" => @public_key,
+ "admin" => @admin
}
- result["display_name"] = @display_name unless @display_name.nil?
- result["first_name"] = @first_name unless @first_name.nil?
- result["middle_name"] = @middle_name unless @middle_name.nil?
- result["last_name"] = @last_name unless @last_name.nil?
- result["email"] = @email unless @email.nil?
- result["password"] = @password unless @password.nil?
- result["public_key"] = @public_key unless @public_key.nil?
- result["private_key"] = @private_key unless @private_key.nil?
- result["create_key"] = @create_key unless @create_key.nil?
+ result["private_key"] = @private_key if @private_key
+ result["password"] = @password if @password
result
end
@@ -138,86 +92,21 @@ class Chef
end
def destroy
- # will default to the current API version (Chef::Authenticator::DEFAULT_SERVER_API_VERSION)
- Chef::REST.new(Chef::Config[:chef_server_url]).delete("users/#{@username}")
+ chef_rest_v0.delete_rest("users/#{@name}")
end
def create
- # try v1, fail back to v0 if v1 not supported
- begin
- payload = {
- :username => @username,
- :display_name => @display_name,
- :first_name => @first_name,
- :last_name => @last_name,
- :email => @email,
- :password => @password
- }
- payload[:public_key] = @public_key unless @public_key.nil?
- payload[:create_key] = @create_key unless @create_key.nil?
- payload[:middle_name] = @middle_name unless @middle_name.nil?
- raise Chef::Exceptions::InvalidUserAttribute, "You cannot set both public_key and create_key for create." if !@create_key.nil? && !@public_key.nil?
- new_user = chef_root_rest_v1.post("users", payload)
-
- # get the private_key out of the chef_key hash if it exists
- if new_user['chef_key']
- if new_user['chef_key']['private_key']
- new_user['private_key'] = new_user['chef_key']['private_key']
- end
- new_user['public_key'] = new_user['chef_key']['public_key']
- new_user.delete('chef_key')
- end
- rescue Net::HTTPServerException => e
- # rescue API V0 if 406 and the server supports V0
- supported_versions = server_client_api_version_intersection(e, SUPPORTED_API_VERSIONS)
- raise e unless supported_versions && supported_versions.include?(0)
- payload = {
- :username => @username,
- :display_name => @display_name,
- :first_name => @first_name,
- :last_name => @last_name,
- :email => @email,
- :password => @password
- }
- payload[:middle_name] = @middle_name unless @middle_name.nil?
- payload[:public_key] = @public_key unless @public_key.nil?
- # under API V0, the server will create a key pair if public_key isn't passed
- new_user = chef_root_rest_v0.post("users", payload)
- end
-
+ payload = {:name => self.name, :admin => self.admin, :password => self.password }
+ payload[:public_key] = public_key if public_key
+ new_user = chef_rest_v0.post_rest("users", payload)
Chef::User.from_hash(self.to_hash.merge(new_user))
end
def update(new_key=false)
- begin
- payload = {:username => username}
- payload[:display_name] = display_name unless display_name.nil?
- payload[:first_name] = first_name unless first_name.nil?
- payload[:middle_name] = middle_name unless middle_name.nil?
- payload[:last_name] = last_name unless last_name.nil?
- payload[:email] = email unless email.nil?
- payload[:password] = password unless password.nil?
-
- # API V1 will fail if these key fields are defined, and try V0 below if relevant 400 is returned
- payload[:public_key] = public_key unless public_key.nil?
- payload[:private_key] = new_key if new_key
-
- updated_user = chef_root_rest_v1.put("users/#{username}", payload)
- rescue Net::HTTPServerException => e
- if e.response.code == "400"
- # if a 400 is returned but the error message matches the error related to private / public key fields, try V0
- # else, raise the 400
- error = Chef::JSONCompat.from_json(e.response.body)["error"].first
- error_match = /Since Server API v1, all keys must be updated via the keys endpoint/.match(error)
- if error_match.nil?
- raise e
- end
- else # for other types of errors, test for API versioning errors right away
- supported_versions = server_client_api_version_intersection(e, SUPPORTED_API_VERSIONS)
- raise e unless supported_versions && supported_versions.include?(0)
- end
- updated_user = chef_root_rest_v0.put("users/#{username}", payload)
- end
+ payload = {:name => name, :admin => admin}
+ payload[:private_key] = new_key if new_key
+ payload[:password] = password if password
+ updated_user = chef_rest_v0.put_rest("users/#{name}", payload)
Chef::User.from_hash(self.to_hash.merge(updated_user))
end
@@ -233,47 +122,30 @@ class Chef
end
end
- # Note: remove after API v0 no longer supported by client (and knife command).
def reregister
- begin
- payload = self.to_hash.merge({"private_key" => true})
- reregistered_self = chef_root_rest_v0.put("users/#{username}", payload)
- private_key(reregistered_self["private_key"])
- # only V0 supported for reregister
- rescue Net::HTTPServerException => e
- # if there was a 406 related to versioning, give error explaining that
- # only API version 0 is supported for reregister command
- if e.response.code == "406" && e.response["x-ops-server-api-version"]
- version_header = Chef::JSONCompat.from_json(e.response["x-ops-server-api-version"])
- min_version = version_header["min_version"]
- max_version = version_header["max_version"]
- error_msg = reregister_only_v0_supported_error_msg(max_version, min_version)
- raise Chef::Exceptions::OnlyApiVersion0SupportedForAction.new(error_msg)
- else
- raise e
- end
- end
+ reregistered_self = chef_rest_v0.put_rest("users/#{name}", { :name => name, :admin => admin, :private_key => true })
+ private_key(reregistered_self["private_key"])
self
end
def to_s
- "user[#{@username}]"
+ "user[#{@name}]"
+ end
+
+ def inspect
+ "Chef::User name:'#{name}' admin:'#{admin.inspect}'" +
+ "public_key:'#{public_key}' private_key:#{private_key}"
end
# Class Methods
def self.from_hash(user_hash)
user = Chef::User.new
- user.username user_hash['username']
- user.display_name user_hash['display_name'] if user_hash.key?('display_name')
- user.first_name user_hash['first_name'] if user_hash.key?('first_name')
- user.middle_name user_hash['middle_name'] if user_hash.key?('middle_name')
- user.last_name user_hash['last_name'] if user_hash.key?('last_name')
- user.email user_hash['email'] if user_hash.key?('email')
- user.password user_hash['password'] if user_hash.key?('password')
- user.public_key user_hash['public_key'] if user_hash.key?('public_key')
+ user.name user_hash['name']
user.private_key user_hash['private_key'] if user_hash.key?('private_key')
- user.create_key user_hash['create_key'] if user_hash.key?('create_key')
+ user.password user_hash['password'] if user_hash.key?('password')
+ user.public_key user_hash['public_key']
+ user.admin user_hash['admin']
user
end
@@ -286,19 +158,12 @@ class Chef
end
def self.list(inflate=false)
- response = Chef::REST.new(Chef::Config[:chef_server_url]).get('users')
+ response = Chef::ServerAPI.new(Chef::Config[:chef_server_url], {:api_version => "0"}).get_rest('users')
users = if response.is_a?(Array)
- # EC 11 / CS 12 V0, V1
- # GET /organizations/<org>/users
- transform_list_response(response)
- else
- # OSC 11
- # GET /users
- # EC 11 / CS 12 V0, V1
- # GET /users
- response # OSC
- end
-
+ transform_ohc_list_response(response) # OHC/OPC
+ else
+ response # OSC
+ end
if inflate
users.inject({}) do |user_map, (name, _url)|
user_map[name] = Chef::User.load(name)
@@ -309,9 +174,8 @@ class Chef
end
end
- def self.load(username)
- # will default to the current API version (Chef::Authenticator::DEFAULT_SERVER_API_VERSION)
- response = Chef::REST.new(Chef::Config[:chef_server_url]).get("users/#{username}")
+ def self.load(name)
+ response = Chef::ServerAPI.new(Chef::Config[:chef_server_url], {:api_version => "0"}).get_rest("users/#{name}")
Chef::User.from_hash(response)
end
@@ -319,7 +183,7 @@ class Chef
# [ { "user" => { "username" => USERNAME }}, ...]
# into the form
# { "USERNAME" => "URI" }
- def self.transform_list_response(response)
+ def self.transform_ohc_list_response(response)
new_response = Hash.new
response.each do |u|
name = u['user']['username']
@@ -328,7 +192,6 @@ class Chef
new_response
end
- private_class_method :transform_list_response
-
+ private_class_method :transform_ohc_list_response
end
end
diff --git a/lib/chef/user_v1.rb b/lib/chef/user_v1.rb
new file mode 100644
index 0000000000..31cb0576a2
--- /dev/null
+++ b/lib/chef/user_v1.rb
@@ -0,0 +1,335 @@
+#
+# Author:: Steven Danna (steve@opscode.com)
+# Copyright:: Copyright 2012 Opscode, 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/config'
+require 'chef/mixin/params_validate'
+require 'chef/mixin/from_file'
+require 'chef/mash'
+require 'chef/json_compat'
+require 'chef/search/query'
+require 'chef/mixin/api_version_request_handling'
+require 'chef/exceptions'
+require 'chef/server_api'
+
+# OSC 11 BACKWARDS COMPATIBILITY NOTE (remove after OSC 11 support ends)
+#
+# In general, Chef::UserV1 is no longer expected to support Open Source Chef 11 Server requests.
+# The object that handles those requests remain in the Chef::User namespace.
+# This code will be moved to the Chef::User namespace as of Chef 13.
+#
+# Exception: self.list is backwards compatible with OSC 11
+class Chef
+ class UserV1
+
+ include Chef::Mixin::FromFile
+ include Chef::Mixin::ParamsValidate
+ include Chef::Mixin::ApiVersionRequestHandling
+
+ SUPPORTED_API_VERSIONS = [0,1]
+
+ def initialize
+ @username = nil
+ @display_name = nil
+ @first_name = nil
+ @middle_name = nil
+ @last_name = nil
+ @email = nil
+ @password = nil
+ @public_key = nil
+ @private_key = nil
+ @create_key = nil
+ @password = nil
+ end
+
+ def chef_root_rest_v0
+ @chef_root_rest_v0 ||= Chef::ServerAPI.new(Chef::Config[:chef_server_root], {:api_version => "0"})
+ end
+
+ def chef_root_rest_v1
+ @chef_root_rest_v1 ||= Chef::ServerAPI.new(Chef::Config[:chef_server_root], {:api_version => "1"})
+ end
+
+ def username(arg=nil)
+ set_or_return(:username, arg,
+ :regex => /^[a-z0-9\-_]+$/)
+ end
+
+ def display_name(arg=nil)
+ set_or_return(:display_name,
+ arg, :kind_of => String)
+ end
+
+ def first_name(arg=nil)
+ set_or_return(:first_name,
+ arg, :kind_of => String)
+ end
+
+ def middle_name(arg=nil)
+ set_or_return(:middle_name,
+ arg, :kind_of => String)
+ end
+
+ def last_name(arg=nil)
+ set_or_return(:last_name,
+ arg, :kind_of => String)
+ end
+
+ def email(arg=nil)
+ set_or_return(:email,
+ arg, :kind_of => String)
+ end
+
+ def password(arg=nil)
+ set_or_return(:password,
+ arg, :kind_of => String)
+ end
+
+ def create_key(arg=nil)
+ set_or_return(:create_key, arg,
+ :kind_of => [TrueClass, FalseClass])
+ end
+
+ def public_key(arg=nil)
+ set_or_return(:public_key,
+ arg, :kind_of => String)
+ end
+
+ def private_key(arg=nil)
+ set_or_return(:private_key,
+ arg, :kind_of => String)
+ end
+
+ def password(arg=nil)
+ set_or_return(:password,
+ arg, :kind_of => String)
+ end
+
+ def to_hash
+ result = {
+ "username" => @username
+ }
+ result["display_name"] = @display_name unless @display_name.nil?
+ result["first_name"] = @first_name unless @first_name.nil?
+ result["middle_name"] = @middle_name unless @middle_name.nil?
+ result["last_name"] = @last_name unless @last_name.nil?
+ result["email"] = @email unless @email.nil?
+ result["password"] = @password unless @password.nil?
+ result["public_key"] = @public_key unless @public_key.nil?
+ result["private_key"] = @private_key unless @private_key.nil?
+ result["create_key"] = @create_key unless @create_key.nil?
+ result
+ end
+
+ def to_json(*a)
+ Chef::JSONCompat.to_json(to_hash, *a)
+ end
+
+ def destroy
+ # will default to the current API version (Chef::Authenticator::DEFAULT_SERVER_API_VERSION)
+ Chef::REST.new(Chef::Config[:chef_server_url]).delete("users/#{@username}")
+ end
+
+ def create
+ # try v1, fail back to v0 if v1 not supported
+ begin
+ payload = {
+ :username => @username,
+ :display_name => @display_name,
+ :first_name => @first_name,
+ :last_name => @last_name,
+ :email => @email,
+ :password => @password
+ }
+ payload[:public_key] = @public_key unless @public_key.nil?
+ payload[:create_key] = @create_key unless @create_key.nil?
+ payload[:middle_name] = @middle_name unless @middle_name.nil?
+ raise Chef::Exceptions::InvalidUserAttribute, "You cannot set both public_key and create_key for create." if !@create_key.nil? && !@public_key.nil?
+ new_user = chef_root_rest_v1.post("users", payload)
+
+ # get the private_key out of the chef_key hash if it exists
+ if new_user['chef_key']
+ if new_user['chef_key']['private_key']
+ new_user['private_key'] = new_user['chef_key']['private_key']
+ end
+ new_user['public_key'] = new_user['chef_key']['public_key']
+ new_user.delete('chef_key')
+ end
+ rescue Net::HTTPServerException => e
+ # rescue API V0 if 406 and the server supports V0
+ supported_versions = server_client_api_version_intersection(e, SUPPORTED_API_VERSIONS)
+ raise e unless supported_versions && supported_versions.include?(0)
+ payload = {
+ :username => @username,
+ :display_name => @display_name,
+ :first_name => @first_name,
+ :last_name => @last_name,
+ :email => @email,
+ :password => @password
+ }
+ payload[:middle_name] = @middle_name unless @middle_name.nil?
+ payload[:public_key] = @public_key unless @public_key.nil?
+ # under API V0, the server will create a key pair if public_key isn't passed
+ new_user = chef_root_rest_v0.post("users", payload)
+ end
+
+ Chef::UserV1.from_hash(self.to_hash.merge(new_user))
+ end
+
+ def update(new_key=false)
+ begin
+ payload = {:username => username}
+ payload[:display_name] = display_name unless display_name.nil?
+ payload[:first_name] = first_name unless first_name.nil?
+ payload[:middle_name] = middle_name unless middle_name.nil?
+ payload[:last_name] = last_name unless last_name.nil?
+ payload[:email] = email unless email.nil?
+ payload[:password] = password unless password.nil?
+
+ # API V1 will fail if these key fields are defined, and try V0 below if relevant 400 is returned
+ payload[:public_key] = public_key unless public_key.nil?
+ payload[:private_key] = new_key if new_key
+
+ updated_user = chef_root_rest_v1.put("users/#{username}", payload)
+ rescue Net::HTTPServerException => e
+ if e.response.code == "400"
+ # if a 400 is returned but the error message matches the error related to private / public key fields, try V0
+ # else, raise the 400
+ error = Chef::JSONCompat.from_json(e.response.body)["error"].first
+ error_match = /Since Server API v1, all keys must be updated via the keys endpoint/.match(error)
+ if error_match.nil?
+ raise e
+ end
+ else # for other types of errors, test for API versioning errors right away
+ supported_versions = server_client_api_version_intersection(e, SUPPORTED_API_VERSIONS)
+ raise e unless supported_versions && supported_versions.include?(0)
+ end
+ updated_user = chef_root_rest_v0.put("users/#{username}", payload)
+ end
+ Chef::UserV1.from_hash(self.to_hash.merge(updated_user))
+ end
+
+ def save(new_key=false)
+ begin
+ create
+ rescue Net::HTTPServerException => e
+ if e.response.code == "409"
+ update(new_key)
+ else
+ raise e
+ end
+ end
+ end
+
+ # Note: remove after API v0 no longer supported by client (and knife command).
+ def reregister
+ begin
+ payload = self.to_hash.merge({"private_key" => true})
+ reregistered_self = chef_root_rest_v0.put("users/#{username}", payload)
+ private_key(reregistered_self["private_key"])
+ # only V0 supported for reregister
+ rescue Net::HTTPServerException => e
+ # if there was a 406 related to versioning, give error explaining that
+ # only API version 0 is supported for reregister command
+ if e.response.code == "406" && e.response["x-ops-server-api-version"]
+ version_header = Chef::JSONCompat.from_json(e.response["x-ops-server-api-version"])
+ min_version = version_header["min_version"]
+ max_version = version_header["max_version"]
+ error_msg = reregister_only_v0_supported_error_msg(max_version, min_version)
+ raise Chef::Exceptions::OnlyApiVersion0SupportedForAction.new(error_msg)
+ else
+ raise e
+ end
+ end
+ self
+ end
+
+ def to_s
+ "user[#{@username}]"
+ end
+
+ # Class Methods
+
+ def self.from_hash(user_hash)
+ user = Chef::UserV1.new
+ user.username user_hash['username']
+ user.display_name user_hash['display_name'] if user_hash.key?('display_name')
+ user.first_name user_hash['first_name'] if user_hash.key?('first_name')
+ user.middle_name user_hash['middle_name'] if user_hash.key?('middle_name')
+ user.last_name user_hash['last_name'] if user_hash.key?('last_name')
+ user.email user_hash['email'] if user_hash.key?('email')
+ user.password user_hash['password'] if user_hash.key?('password')
+ user.public_key user_hash['public_key'] if user_hash.key?('public_key')
+ user.private_key user_hash['private_key'] if user_hash.key?('private_key')
+ user.create_key user_hash['create_key'] if user_hash.key?('create_key')
+ user
+ end
+
+ def self.from_json(json)
+ Chef::UserV1.from_hash(Chef::JSONCompat.from_json(json))
+ end
+
+ class << self
+ alias_method :json_create, :from_json
+ end
+
+ def self.list(inflate=false)
+ response = Chef::REST.new(Chef::Config[:chef_server_url]).get('users')
+ users = if response.is_a?(Array)
+ # EC 11 / CS 12 V0, V1
+ # GET /organizations/<org>/users
+ transform_list_response(response)
+ else
+ # OSC 11
+ # GET /users
+ # EC 11 / CS 12 V0, V1
+ # GET /users
+ response # OSC
+ end
+
+ if inflate
+ users.inject({}) do |user_map, (name, _url)|
+ user_map[name] = Chef::UserV1.load(name)
+ user_map
+ end
+ else
+ users
+ end
+ end
+
+ def self.load(username)
+ # will default to the current API version (Chef::Authenticator::DEFAULT_SERVER_API_VERSION)
+ response = Chef::REST.new(Chef::Config[:chef_server_url]).get("users/#{username}")
+ Chef::UserV1.from_hash(response)
+ end
+
+ # Gross. Transforms an API response in the form of:
+ # [ { "user" => { "username" => USERNAME }}, ...]
+ # into the form
+ # { "USERNAME" => "URI" }
+ def self.transform_list_response(response)
+ new_response = Hash.new
+ response.each do |u|
+ name = u['user']['username']
+ new_response[name] = Chef::Config[:chef_server_url] + "/users/#{name}"
+ end
+ new_response
+ end
+
+ private_class_method :transform_list_response
+
+ end
+end