Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #16330 - random and MAC name generators #437

Merged
merged 1 commit into from Jun 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 19 additions & 7 deletions app/models/host/discovered.rb
Expand Up @@ -37,6 +37,12 @@ class Host::Discovered < ::Host::Base
where(taxonomy_conditions).order("hosts.created_at DESC")
}

NAMING_PATTERNS = {
'Fact' => _('Fact + prefix'),
'Random-name' => _('Random name'),
'MAC-name' => _('MAC-based name')
}.freeze

# Discovery import workflow:
# discovered#import_host ->
# discovered#import_facts -> base#import_facts -> base#parse_facts ->
Expand All @@ -51,16 +57,22 @@ def self.import_host facts
raise ::Foreman::Exception.new(N_("Expected discovery_fact '%s' is missing, unable to detect primary interface and set hostname") % FacterUtils::bootif_name) unless FacterUtils::bootif_present(facts)

# construct hostname
prefix_from_settings = Setting[:discovery_prefix]
hostname_prefix = prefix_from_settings if prefix_from_settings.present? && prefix_from_settings.match(/^[a-zA-Z].*/)

name_fact = return_first_valid_fact(Setting::Discovered.discovery_hostname_fact_array, facts)
raise(::Foreman::Exception.new(N_("Invalid facts: hash does not contain a valid value for any of the facts in the discovery_hostname setting: %s"), Setting::Discovered.discovery_hostname_fact_array.join(', '))) unless name_fact && name_fact.present?
hostname = normalize_string_for_hostname("#{hostname_prefix}#{name_fact}")
bootif_mac = FacterUtils::bootif_mac(facts).try(:downcase)
hostname = ''
if Setting[:discovery_naming] == 'MAC-name'
hostname = NameGenerator.new.generate_next_mac_name(bootif_mac)
elsif Setting[:discovery_naming] == 'Random-name'
hostname = NameGenerator.new.generate_next_random_name
else
prefix_from_settings = Setting[:discovery_prefix]
hostname_prefix = prefix_from_settings if prefix_from_settings.present? && prefix_from_settings.match(/^[a-zA-Z].*/)
name_fact = return_first_valid_fact(Setting::Discovered.discovery_hostname_fact_array, facts)
raise(::Foreman::Exception.new(N_("Invalid facts: hash does not contain a valid value for any of the facts in the discovery_hostname setting: %s"), Setting::Discovered.discovery_hostname_fact_array.join(', '))) unless name_fact && name_fact.present?
hostname = normalize_string_for_hostname("#{hostname_prefix}#{name_fact}")
end
Rails.logger.warn "Hostname does not start with an alphabetical character" unless hostname.downcase.match(/^[a-z]/)

# check for existing managed hosts and fail or warn
bootif_mac = FacterUtils::bootif_mac(facts).try(:downcase)
existing_managed = Nic::Managed.joins(:host).where(:mac => bootif_mac, :provision => true, :hosts => {:type => "Host::Managed"}).limit(1)
if existing_managed.count > 0
if Setting[:discovery_error_on_existing]
Expand Down
1 change: 1 addition & 0 deletions app/models/setting/discovered.rb
Expand Up @@ -35,6 +35,7 @@ def self.load_defaults
self.set('discovery_pxegrub2_lock_template', N_("PXEGrub2 template to be used when pinning a host to discovery"), 'pxegrub2_discovery', N_("Locked PXEGrub2 template name"), nil, { :collection => Proc.new {Hash[ProvisioningTemplate.where(:template_kind => TemplateKind.find_by_name(:snippet)).map{|template| [template[:name], template[:name]]}]} }),
self.set('discovery_always_rebuild_dns', N_("Force DNS entries creation when provisioning discovered host"), true, N_("Force DNS")),
self.set('discovery_error_on_existing', N_("Do not allow to discover existing managed host matching MAC of a provisioning NIC (errors out early)"), false, N_("Error on existing NIC")),
self.set('discovery_naming', N_("Discovery hostname naming pattern"), 'Fact', N_("Type of name generator"), nil, {:collection => Proc.new {::Host::Discovered::NAMING_PATTERNS} }),
].compact.each { |s| self.create s.update(:category => "Setting::Discovered")}
end

Expand Down
1 change: 1 addition & 0 deletions test/test_helper_discovery.rb
Expand Up @@ -67,6 +67,7 @@ def set_default_settings
FactoryBot.create(:setting, :name => 'discovery_pxegrub2_lock_template', :value => 'pxegrub2_discovery', :category => 'Setting::Discovered')
FactoryBot.create(:setting, :name => 'discovery_always_rebuild_dns', :value => true, :category => 'Setting::Discovered')
FactoryBot.create(:setting, :name => 'discovery_error_on_existing', :value => false, :category => 'Setting::Discovered')
FactoryBot.create(:setting, :name => 'discovery_naming', :value => 'Fact', :category => 'Setting::Discovered')
end

def setup_hostgroup(host)
Expand Down
13 changes: 13 additions & 0 deletions test/unit/host_discovered_test.rb
Expand Up @@ -19,6 +19,19 @@ class HostDiscoveredTest < ActiveSupport::TestCase
assert Host::Discovered.find_by_name('mace41f13cc3658')
end

test "should import facts from yaml with MAC-based generator as Host::Discovered" do
Setting[:discovery_naming] = "MAC-name"
host = discover_host_from_facts(@facts)
assert_equal "myrna-katie-wesly-maslyn", host.name
end

test "should import facts from yaml with random based generator as Host::Discovered" do
Setting[:discovery_naming] = "Random-name"
Rails.cache.stubs(:fetch).with("name_generator_register").returns(1305)
host = discover_host_from_facts(@facts)
assert_equal "velma-startin", host.name
end

test 'fact value association is set accordingly' do
discovered_host = FactoryBot.create(:discovered_host, :with_facts, :fact_count => 1)
fact_value = discovered_host.fact_values.first
Expand Down