Project

General

Profile

« Previous | Next » 

Revision cad1b13c

Added by Tomáš Strachota over 9 years ago

Fixes #8005 - Convert allowed NIC types to strings

- allowed NIC type classes need to be registered now
- api for interfaces use lowercase human readable values for defining types
- fixed output of api's create action to the standard format

View differences:

app/controllers/api/v2/interfaces_controller.rb
include Api::Version2
include Api::TaxonomyScope
ALLOWED_TYPE_NAMES = Nic::Base.allowed_types.map{ |t| t.humanized_name.downcase }
LEGACY_TYPE_NAMES = Nic::Base.allowed_types.map{ |t| t.name }
before_filter :find_required_nested_object, :only => [:index, :show, :create, :destroy]
before_filter :find_resource, :only => [:show, :update, :destroy]
before_filter :convert_type, :only => [:create, :update]
api :GET, '/hosts/:host_id/interfaces', N_("List all interfaces for host")
api :GET, '/domains/:domain_id/interfaces', N_('List all interfaces for domain')
......
#common parameters
param :mac, String, :required => true, :desc => N_("MAC address of interface")
param :ip, String, :required => true, :desc => N_("IP address of interface")
param :type, Nic::TYPES, :required => true, :desc => N_("Interface type, e.g: Nic::BMC")
param :type, InterfacesController::ALLOWED_TYPE_NAMES, :required => true, :desc => N_("Interface type, e.g: bmc")
param :name, String, :required => true, :desc => N_("Interface name")
param :subnet_id, Fixnum, :desc => N_("Foreman subnet ID of interface")
param :domain_id, Fixnum, :desc => N_("Foreman domain ID of interface")
......
param_group :interface, :as => :create
def create
interface = @nested_obj.interfaces.new(params[:interface], :without_protection => true)
if interface.save
render :json => interface, :status => :created
else
render :json => { :errors => interface.errors.full_messages }, :status => :unprocessable_entity
end
@interface = @nested_obj.interfaces.new(params[:interface], :without_protection => true)
process_response @interface.save
end
api :PUT, "/hosts/:host_id/interfaces/:id", N_("Update a host's interface")
......
def resource_class
Nic::Base
end
def convert_type
type_sent = params[:interface][:type]
if ALLOWED_TYPE_NAMES.include? type_sent
# convert human readable name to the NIC's class name
params[:interface][:type] = Nic::Base.type_by_name(type_sent).to_s
elsif !LEGACY_TYPE_NAMES.include? type_sent
# enable sending class names directly to keep backward compatibility
render_error :custom_error,
:status => :unprocessable_entity,
:locals => {
:message => _("Unknown interface type, must be one of [%s]") % ALLOWED_TYPE_NAMES.join(', ')
}
end
end
end
end
end
app/helpers/interfaces_helper.rb
module InterfacesHelper
def interfaces_types
@types ||= [
[_("Interface"), Nic::Managed],
[_("Bond"), Nic::Bond],
[_("BMC"), Nic::BMC]
]
@types ||= Nic::Base.allowed_types.collect do |nic_type|
[_(nic_type.humanized_name), nic_type]
end
end
end
app/models/nic/base.rb
type.split("::").last
end
def self.humanized_name
# provide class name as a default value
name.split("::").last
end
def self.type_by_name(name)
allowed_types.find{|nic_class| nic_class.humanized_name.downcase == name.to_s.downcase}
end
# NIC types have to be registered to to expose them to users
def self.register_type(type)
allowed_types << type
end
def self.allowed_types
@allowed_types ||= []
end
protected
def uniq_fields_with_hosts
......
def require_host?
true
end
end
require_dependency 'nic/interface'
TYPES = [ Nic::Managed, Nic::Bond, Nic::BMC ]
end
end
require_dependency 'nic/interface'
app/models/nic/bmc.rb
:password => password })
end
def self.humanized_name
N_('BMC')
end
end
Base.register_type(BMC)
end
app/models/nic/bond.rb
self.attached_devices = attached_devices_identifiers.tap { |a| a.delete(identifier) }.join(SEPARATOR)
end
def self.humanized_name
N_('Bond')
end
private
def ensure_virtual
self.virtual = true
end
end
Base.register_type(Bond)
end
app/models/nic/bootable.rb
@dhcp_record ||= host.jumpstart? ? Net::DHCP::SparcRecord.new(dhcp_attrs) : Net::DHCP::Record.new(dhcp_attrs)
end
def self.human_name
N_('Bootable')
end
protected
def dhcp_attrs
app/models/nic/managed.rb
end
end
def self.humanized_name
N_('Interface')
end
protected
def uniq_fields_with_hosts
......
end
end
Base.register_type(Managed)
end
require_dependency 'nic/bmc'
app/views/api/v2/errors/custom_error.json.rabl
node :message do
locals[:message]
end
app/views/api/v2/interfaces/base.json.rabl
object @interface
attributes :id, :name, :type, :ip, :mac
attributes :id, :name, :ip, :mac
node :type do |i|
i.class.humanized_name.downcase
end
app/views/api/v2/interfaces/types/bmc.json.rabl
attributes :username, :password, :provider
extends "api/v2/interfaces/types/managed"
attributes :username, :password, :provider, :virtual
app/views/api/v2/interfaces/types/bond.json.rabl
attributes :mode, :attached_devices, :bond_options
extends "api/v2/interfaces/types/managed"
attributes :mode, :attached_devices, :bond_options, :virtual
test/functional/api/v2/interfaces_controller_test.rb
class Api::V2::InterfacesControllerTest < ActionController::TestCase
valid_attrs = { 'name' => "test.foreman.com", 'ip' => "10.0.1.1", 'mac' => "AA:AA:AA:AA:AA:AA",
'username' => "foo", 'password' => "bar", 'provider' => "IPMI",
'type' => "Nic::BMC" }
'type' => "bmc" }
def setup
@host = FactoryGirl.create(:host)
......
assert_response :success
show_response = ActiveSupport::JSON.decode(@response.body)
assert !show_response.empty?
assert "bmc", show_response["type"]
end
test "create interface" do
assert_difference('@host.interfaces.count') do
post :create, { :host_id => @host.to_param, :interface => valid_attrs }
end
assert_response 201
assert_response :success
end
test "create interface with old style type" do
assert_difference('@host.interfaces.count') do
post :create, { :host_id => @host.to_param, :interface => valid_attrs.merge('type' => 'Nic::BMC') }
end
assert_response :success
end
test "create interface with unknown type" do
post :create, { :host_id => @host.to_param, :interface => valid_attrs.merge('type' => 'UNKNOWN') }
assert_response :unprocessable_entity
end
test "username and password are set on POST (create)" do
test/unit/nic_test.rb
end
end
end
context "allowed type registration" do
setup do
class DefaultTestNic < Nic::Base
end
class HumanizedTestNic < Nic::Base
def self.humanized_name
"Custom"
end
end
class DisallowedTestNic < Nic::Base
end
Nic::Base.allowed_types.clear
Nic::Base.register_type(DefaultTestNic)
Nic::Base.register_type(HumanizedTestNic)
end
test "base registers allowed nic types" do
expected_types = [DefaultTestNic, HumanizedTestNic]
assert_equal expected_types.map(&:name), Nic::Base.allowed_types.map(&:name)
end
test "type_by_name returns nil for an unknown name" do
assert_equal nil, Nic::Base.type_by_name("UNKNOWN_NAME")
end
test "type_by_name finds the class" do
assert_equal HumanizedTestNic, Nic::Base.type_by_name("custom")
end
test "type_by_name returns nil for classes that aren't allowed" do
assert_equal nil, Nic::Base.type_by_name("DisallowedTestNic")
end
end
end

Also available in: Unified diff