Revision 7b7d7d1d
Added by Timo Goebel almost 8 years ago
app/controllers/api/v1/hosts_controller.rb | ||
---|---|---|
param :location_id, :number, :required => true, :desc => "required if locations are enabled" if SETTINGS[:locations_enabled]
|
||
param :organization_id, :number, :required => true, :desc => "required if organizations are enabled" if SETTINGS[:organizations_enabled]
|
||
param :environment_id, String, :desc => "required if host is managed and value is not inherited from host group"
|
||
param :ip, String, :desc => "not required if using a subnet with DHCP proxy"
|
||
param :ip, String, :desc => "IPv4 address"
|
||
param :ip6, String, :desc => "IPv6 address"
|
||
param :mac, String, :desc => "required for managed host that is bare metal, not required if it's a virtual machine"
|
||
param :architecture_id, :number, :desc => "required if host is managed and value is not inherited from host group"
|
||
param :domain_id, :number, :desc => "required if host is managed and value is not inherited from host group"
|
||
... | ... | |
param :operatingsystem_id, String, :desc => "required if host is managed and value is not inherited from host group"
|
||
param :medium_id, String, :desc => "required if not imaged based provisioning and host is managed and value is not inherited from host group"
|
||
param :ptable_id, :number, :desc => "required if host is managed and custom partition has not been defined"
|
||
param :subnet_id, :number, :desc => "required if host is managed and value is not inherited from host group"
|
||
param :subnet_id, :number, :desc => "IPv4 subnet"
|
||
param :subnet6_id, :number, :desc => "IPv6 subnet"
|
||
param :compute_resource_id, :number, :desc => "nil means host is bare metal"
|
||
param :root_pass, String, :desc => "required if host is managed and value is not inherited from host group or default password in settings"
|
||
param :model_id, :number
|
||
... | ... | |
param :host, Hash, :required => true do
|
||
param :name, String
|
||
param :environment_id, String
|
||
param :ip, String, :desc => "not required if using a subnet with dhcp proxy"
|
||
param :ip, String, :desc => "IPv4 address, not required if using a subnet with dhcp proxy"
|
||
param :ip6, String, :desc => "IPv6 address"
|
||
param :mac, String, :desc => "not required if its a virtual machine"
|
||
param :architecture_id, :number
|
||
param :domain_id, :number
|
||
... | ... | |
param :puppetclass_ids, Array
|
||
param :medium_id, :number
|
||
param :ptable_id, :number
|
||
param :subnet_id, :number
|
||
param :subnet_id, :number, :desc => "IPv4 subnet"
|
||
param :subnet6_id, :number, :desc => "IPv6 subnet"
|
||
param :compute_resource_id, :number
|
||
param :sp_subnet_id, :number
|
||
param :model_id, :number
|
app/controllers/api/v1/subnets_controller.rb | ||
---|---|---|
api :POST, '/subnets', 'Create a subnet'
|
||
param :subnet, Hash, :required => true do
|
||
param :name, String, :desc => 'Subnet name', :required => true
|
||
param :network_type, Subnet::SUBNET_TYPES.values, :desc => 'Type or protocol, IPv4 or IPv6, defaults to IPv4'
|
||
param :network, String, :desc => 'Subnet network', :required => true
|
||
param :mask, String, :desc => 'Netmask for this subnet', :required => true
|
||
param :gateway, String, :desc => 'Primary DNS for this subnet'
|
||
... | ... | |
end
|
||
|
||
def create
|
||
@subnet = Subnet.new(params[:subnet])
|
||
@subnet = Subnet.new_network_type(params[:subnet])
|
||
process_response @subnet.save
|
||
end
|
||
|
app/controllers/api/v2/interfaces_controller.rb | ||
---|---|---|
def_param_group :interface_attributes do
|
||
#common parameters
|
||
param :mac, String, :desc => N_("MAC address of interface. Required for managed interfaces on bare metal.")
|
||
param :ip, String, :desc => N_("IP address of interface")
|
||
param :ip, String, :desc => N_("IPv4 address of interface")
|
||
param :ip6, String, :desc => N_("IPv6 address of interface")
|
||
param :type, InterfaceTypeMapper::ALLOWED_TYPE_NAMES, :desc => N_("Interface type, e.g. bmc. Default is %{default_nic_type}")
|
||
param :name, String, :desc => N_("Interface's DNS name")
|
||
param :subnet_id, Fixnum, :desc => N_("Foreman subnet ID of interface")
|
||
param :subnet_id, Fixnum, :desc => N_("Foreman subnet ID of IPv4 interface")
|
||
param :subnet6_id, Fixnum, :desc => N_("Foreman subnet ID of IPv6 interface")
|
||
param :domain_id, Fixnum, :desc => N_("Foreman domain ID of interface. Required for primary interfaces on managed hosts.")
|
||
param :identifier, String, :desc => N_("Device identifier, e.g. eth0 or eth1.1")
|
||
param :managed, :bool, :desc => N_("Should this interface be managed via DHCP and DNS smart proxy and should it be configured during provisioning?")
|
app/controllers/api/v2/subnets_controller.rb | ||
---|---|---|
def_param_group :subnet do
|
||
param :subnet, Hash, :required => true, :action_aware => true do
|
||
param :name, String, :desc => N_("Subnet name"), :required => true
|
||
param :network_type, Subnet::SUBNET_TYPES.values, :desc => N_('Type or protocol, IPv4 or IPv6, defaults to IPv4')
|
||
param :network, String, :desc => N_("Subnet network"), :required => true
|
||
param :mask, String, :desc => N_("Netmask for this subnet"), :required => true
|
||
param :gateway, String, :desc => N_("Primary DNS for this subnet")
|
||
... | ... | |
param_group :subnet, :as => :create
|
||
|
||
def create
|
||
@subnet = Subnet.new(params[:subnet])
|
||
@subnet = Subnet.new_network_type(params[:subnet])
|
||
process_response @subnet.save
|
||
end
|
||
|
app/models/subnet.rb | ||
---|---|---|
|
||
attr_accessible :name, :type, :network, :mask, :gateway, :dns_primary, :dns_secondary, :ipam, :from,
|
||
:to, :vlanid, :boot_mode, :dhcp_id, :dhcp, :tftp_id, :tftp, :dns_id, :dns, :domain_ids, :domain_names,
|
||
:subnet_parameters_attributes, :cidr
|
||
:subnet_parameters_attributes, :cidr, :network_type
|
||
|
||
attr_exportable :name, :network, :mask, :gateway, :dns_primary, :dns_secondary, :from, :to, :boot_mode,
|
||
:ipam, :vlanid, :type
|
||
:ipam, :vlanid, :network_type
|
||
|
||
# This casts Subnet to Subnet::Ipv4 if no type is set
|
||
def self.new(*attributes, &block)
|
||
(h = attributes.first).is_a?(Hash) && (type = h.with_indifferent_access.delete(:type))
|
||
type = attributes.first.with_indifferent_access.delete(:type) if attributes.first.is_a?(Hash)
|
||
return Subnet::Ipv4.new_without_cast(*attributes, &block) if self == Subnet && type.nil?
|
||
super
|
||
end
|
||
... | ... | |
name
|
||
end
|
||
|
||
def network_type
|
||
SUBNET_TYPES[type.to_sym]
|
||
end
|
||
|
||
def network_type=(value)
|
||
self[:type] = SUBNET_TYPES.key(value)
|
||
end
|
||
|
||
# Subnets are sorted on their priority value
|
||
# [+other+] : Subnet object with which to compare ourself
|
||
# +returns+ : Subnet object with higher precedence
|
||
... | ... | |
ip = IPAddr.new(ip)
|
||
Subnet.all.detect {|s| s.family == ip.family && s.contains?(ip)}
|
||
end
|
||
|
||
# allows to create a specific subnet class based on the network_type.
|
||
# network_type is more user friendly than the class names
|
||
def new_network_type(args)
|
||
network_type = args.delete(:network_type) || 'IPv4'
|
||
SUBNET_TYPES.each do |network_type_class, network_type_name|
|
||
return network_type_class.to_s.constantize.new(args) if network_type_name.downcase == network_type.downcase
|
||
end
|
||
raise ::Foreman::Exception.new N_("unknown network_type")
|
||
end
|
||
end
|
||
|
||
private
|
app/views/api/v1/subnets/show.json.rabl | ||
---|---|---|
object @subnet
|
||
|
||
attributes :id, :name, :network, :mask, :priority, :vlanid,
|
||
attributes :id, :name, :network_type, :network, :mask, :priority, :vlanid,
|
||
:gateway, :dns_primary, :dns_secondary, :from, :to, :domain_ids,
|
||
:dns_id, :dhcp_id, :tftp_id, :cidr, :ipam
|
||
|
app/views/api/v2/hosts/main.json.rabl | ||
---|---|---|
@object.configuration_status(:last_reports => @last_reports)
|
||
@object.configuration_status_label(:last_reports => @last_reports)
|
||
|
||
attributes :ip, :environment_id, :environment_name, :last_report, :mac, :realm_id, :realm_name,
|
||
attributes :ip, :ip6, :environment_id, :environment_name, :last_report, :mac, :realm_id, :realm_name,
|
||
:sp_mac, :sp_ip, :sp_name, :domain_id, :domain_name, :architecture_id, :architecture_name, :operatingsystem_id, :operatingsystem_name,
|
||
:subnet_id, :subnet_name, :sp_subnet_id, :ptable_id, :ptable_name, :medium_id, :medium_name, :build,
|
||
:subnet_id, :subnet_name, :subnet6_id, :subnet6_name, :sp_subnet_id, :ptable_id, :ptable_name, :medium_id, :medium_name, :build,
|
||
:comment, :disk, :installed_at, :model_id, :hostgroup_id, :owner_id, :owner_type,
|
||
:enabled, :puppet_ca_proxy_id, :managed, :use_image, :image_file, :uuid, :compute_resource_id, :compute_resource_name,
|
||
:compute_profile_id, :compute_profile_name, :capabilities, :provision_method,
|
app/views/api/v2/interfaces/main.json.rabl | ||
---|---|---|
|
||
extends "api/v2/interfaces/base"
|
||
|
||
attributes :subnet_id, :subnet_name, :domain_id, :domain_name, :created_at, :updated_at,
|
||
attributes :subnet_id, :subnet_name, :subnet6_id, :subnet6_name, :domain_id, :domain_name, :created_at, :updated_at,
|
||
:managed, :identifier
|
||
|
||
node do |interface|
|
app/views/api/v2/subnets/main.json.rabl | ||
---|---|---|
|
||
extends "api/v2/subnets/base"
|
||
|
||
attributes :network, :cidr, :mask, :priority, :vlanid, :gateway, :dns_primary, :dns_secondary,
|
||
attributes :network, :network_type, :cidr, :mask, :priority, :vlanid, :gateway,
|
||
:dns_primary, :dns_secondary,
|
||
:from, :to, :created_at, :updated_at, :ipam, :boot_mode
|
||
|
||
child :dhcp => :dhcp do
|
test/functional/api/v1/subnets_controller_test.rb | ||
---|---|---|
require 'test_helper'
|
||
|
||
class Api::V1::SubnetsControllerTest < ActionController::TestCase
|
||
valid_attrs = { :name => 'QA2', :network => '10.35.2.27', :mask => '255.255.255.0' }
|
||
valid_v4_attrs = { :name => 'QA2', :network_type => 'IPv4', :network => '10.35.2.27', :mask => '255.255.255.0' }
|
||
valid_v6_attrs = { :name => 'QA2', :network_type => 'IPv6', :network => '2001:db8::', :mask => 'ffff:ffff:ffff:ffff::', :ipam => 'None' }
|
||
|
||
def test_index
|
||
get :index
|
||
... | ... | |
assert !show_response.empty?
|
||
end
|
||
|
||
test "should create subnet" do
|
||
assert_difference('Subnet.count') do
|
||
post :create, { :subnet => valid_attrs }
|
||
test "should create IPv4 subnet" do
|
||
assert_difference('Subnet::Ipv4.count') do
|
||
post :create, { :subnet => valid_v4_attrs }
|
||
end
|
||
assert_response :success
|
||
assert_equal 'Subnet::Ipv4', Subnet.find_by_name('QA2').type
|
||
end
|
||
|
||
test "should create IPv6 subnet" do
|
||
assert_difference('Subnet::Ipv6.count') do
|
||
post :create, { :subnet => valid_v6_attrs }
|
||
end
|
||
assert_response :success
|
||
assert_equal 'Subnet::Ipv6', Subnet.find_by_name('QA2').type
|
||
end
|
||
|
||
test "does not create subnet with non-existent domain" do
|
||
post :create, { :subnet => valid_attrs.merge(:domain_ids => [1, 2]) }
|
||
post :create, { :subnet => valid_v4_attrs.merge(:domain_ids => [1, 2]) }
|
||
assert_response :not_found
|
||
end
|
||
|
||
test "should update subnet" do
|
||
put :update, { :id => subnets(:one).to_param, :subnet => valid_attrs }
|
||
put :update, { :id => subnets(:one).to_param, :subnet => valid_v4_attrs }
|
||
assert_response :success
|
||
end
|
||
|
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' => "bmc" }
|
||
'type' => "bmc", 'ip6' => '2001:db8::1' }
|
||
|
||
def setup
|
||
@host = FactoryGirl.create(:host)
|
test/functional/api/v2/subnets_controller_test.rb | ||
---|---|---|
require 'test_helper'
|
||
|
||
class Api::V2::SubnetsControllerTest < ActionController::TestCase
|
||
valid_attrs = { :name => 'QA2', :network => '10.35.2.27', :mask => '255.255.255.0' }
|
||
valid_v4_attrs = { :name => 'QA2', :network_type => 'IPv4', :network => '10.35.2.27', :mask => '255.255.255.0' }
|
||
valid_v6_attrs = { :name => 'QA2', :network_type => 'IPv6', :network => '2001:db8::', :mask => 'ffff:ffff:ffff:ffff::', :ipam => 'None' }
|
||
|
||
test "index content is a JSON array" do
|
||
get :index
|
||
... | ... | |
assert !show_response.empty?
|
||
end
|
||
|
||
test "should create subnet" do
|
||
test "should create IPv4 subnet" do
|
||
assert_difference('Subnet.count') do
|
||
post :create, { :subnet => valid_attrs }
|
||
post :create, { :subnet => valid_v4_attrs }
|
||
end
|
||
assert_response :created
|
||
end
|
||
|
||
test "should create IPv4 subnet if type is not defined" do
|
||
assert_difference('Subnet.count') do
|
||
post :create, { :subnet => valid_v4_attrs.reject {|k, v| k == :network_type} }
|
||
end
|
||
subnet = Subnet.find_by_name(valid_v4_attrs[:name])
|
||
assert_equal valid_v4_attrs[:network_type], subnet.network_type
|
||
assert_response :created
|
||
end
|
||
|
||
test "should create IPv6 subnet" do
|
||
assert_difference('Subnet.count') do
|
||
post :create, { :subnet => valid_v6_attrs }
|
||
end
|
||
assert_response :created
|
||
end
|
||
|
||
test "does not create subnet with non-existent domain" do
|
||
post :create, { :subnet => valid_attrs.merge(:domain_ids => [1, 2]) }
|
||
post :create, { :subnet => valid_v4_attrs.merge(:domain_ids => [1, 2]) }
|
||
assert_response :not_found
|
||
end
|
||
|
||
test "should update subnet" do
|
||
put :update, { :id => subnets(:one).to_param, :subnet => valid_attrs }
|
||
put :update, { :id => subnets(:one).to_param, :subnet => valid_v4_attrs }
|
||
assert_response :success
|
||
end
|
||
|
||
test "should not update subnet and change type" do
|
||
put :update, { :id => subnets(:one).to_param, :subnet => valid_v6_attrs }
|
||
assert_response :unprocessable_entity
|
||
end
|
||
|
||
test "should destroy subnets" do
|
||
assert_difference('Subnet.count', -1) do
|
||
delete :destroy, { :id => subnets(:four).to_param }
|
test/unit/host_test.rb | ||
---|---|---|
test '#info ENC YAML contains ipv4 and ipv6 subnets' do
|
||
host = FactoryGirl.build(:host, :with_subnet, :with_ipv6_subnet)
|
||
enc = host.info
|
||
assert enc['parameters']['foreman_subnets'].any? {|s| s['type'] == 'Subnet::Ipv4'}
|
||
assert enc['parameters']['foreman_subnets'].any? {|s| s['type'] == 'Subnet::Ipv6'}
|
||
assert enc['parameters']['foreman_subnets'].any? {|s| s['network_type'] == 'IPv4'}
|
||
assert enc['parameters']['foreman_subnets'].any? {|s| s['network_type'] == 'IPv6'}
|
||
end
|
||
|
||
describe 'cloning' do
|
test/unit/subnet_test.rb | ||
---|---|---|
assert_equal Subnet::Ipv4, subnet.class
|
||
end
|
||
|
||
test 'should be cast to Subnet::Ipv6 if type is set accordingly' do
|
||
subnet = Subnet.new(:type => 'Subnet::Ipv6')
|
||
assert_equal Subnet::Ipv6, subnet.class
|
||
end
|
||
|
||
test 'child class should not be cast to default sti class even if no type is set' do
|
||
class Subnet::Test < Subnet; end
|
||
subnet = Subnet::Test.new
|
||
assert_equal Subnet::Test, subnet.class
|
||
end
|
||
|
||
test '#network_type returns the subnets type in human friendly form' do
|
||
subnet = Subnet.new(:type => 'Subnet::Ipv4')
|
||
assert_equal 'IPv4', subnet.network_type
|
||
subnet6 = Subnet.new(:type => 'Subnet::Ipv6')
|
||
assert_equal 'IPv6', subnet6.network_type
|
||
end
|
||
|
||
test '#network_type= should set #type' do
|
||
subnet = Subnet.new(:type => 'Subnet::Ipv4')
|
||
subnet.network_type = 'IPv6'
|
||
assert_equal 'Subnet::Ipv6', subnet.type
|
||
end
|
||
|
||
test '.new_network_type instantiates network_type from arguments' do
|
||
assert_instance_of Subnet::Ipv6, Subnet.new_network_type(:network_type => 'IPv6')
|
||
end
|
||
|
||
test '.new_network_type raises error for unknown network type' do
|
||
e = assert_raise(Foreman::Exception) { Subnet.new_network_type({:network_type => 'Unknown'}) }
|
||
assert_match /unknown network_type/, e.message
|
||
end
|
||
|
||
test "the name should be unique in the domain scope" do
|
||
first = FactoryGirl.create(:subnet_ipv6, :with_domains)
|
||
subnet = FactoryGirl.build(:subnet_ipv6, :name => first.name, :domains => first.domains)
|
Also available in: Unified diff
fixes #14665 - support IPv6 via API