Class: Host::Discovered

Inherits:
Base
  • Object
show all
Includes:
ScopedSearchExtensions
Defined in:
app/models/host/discovered.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.import_host_and_facts(facts) ⇒ Object

Raises:

  • (::Foreman::Exception)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'app/models/host/discovered.rb', line 39

def self.import_host_and_facts facts
  raise(::Foreman::Exception.new(N_("Invalid facts, must be a Hash"))) unless facts.is_a?(Hash)
  fact_name = Setting[:discovery_fact] || 'discovery_bootif'
  prefix_from_settings = Setting[:discovery_prefix]
  hostname_prefix = prefix_from_settings if prefix_from_settings.present? && prefix_from_settings.match(/^[a-zA-Z].*/)
  hostname_prefix ||= 'mac'
  hostname = facts[fact_name].try(:downcase).try(:gsub,/:/,'').try(:sub,/^/, hostname_prefix)
  raise(::Foreman::Exception.new(N_("Invalid facts: hash does not contain the required fact '%s'"), fact_name)) unless hostname
  raise(::Foreman::Exception.new(N_("Invalid facts: hash does not contain IP address"))) unless facts['ipaddress']

  # filter facts
  facts.reject!{|k,v| k =~ /kernel|operatingsystem|osfamily|ruby|path|time|swap|free|filesystem/i }

  h = ::Host::Discovered.find_by_name hostname
  h ||= Host.new :name => hostname, :type => "Host::Discovered"
  h.type = "Host::Discovered"

  macfact = facts[fact_name].try(:downcase)
  begin
    macfact = Net::Validations.normalize_mac(macfact)
  rescue ArgumentError => e
    macfact = facts['discovery_bootif'].try(:downcase)
    h.name = facts['discovery_bootif'].try(:downcase).try(:gsub,/:/,'').try(:sub,/^/, hostname_prefix)
  end
  h.mac = macfact


  if SETTINGS[:locations_enabled]
    begin
      h.location = (Location.find_by_name Setting[:discovery_location]) || Location.first
    rescue
      h.location = Location.first
    end
  end
  if SETTINGS[:organizations_enabled]
    begin
      h.organization = (Organization.find_by_name Setting[:discovery_organization]) || Organization.first
    rescue
      h.organization = Organization.first
    end
  end

  h.save(:validate => false) if h.new_record?
  state = h.import_facts(facts)
  return h, state
end

.model_nameObject



177
178
179
# File 'app/models/host/discovered.rb', line 177

def self.model_name
  ActiveModel::Name.new(Host)
end

Instance Method Details

#attributes_to_import_from_factsObject



99
100
101
# File 'app/models/host/discovered.rb', line 99

def attributes_to_import_from_facts
  super
end

#compute_resourceObject



181
182
183
# File 'app/models/host/discovered.rb', line 181

def compute_resource
  false
end

#import_facts(facts) ⇒ Object



86
87
88
89
90
91
# File 'app/models/host/discovered.rb', line 86

def import_facts facts
  # Discovered Hosts won't report in via puppet, so we can use that field to
  # record the last time it sent facts...
  self.last_report = Time.now
  super
end

#import_from_facts(facts = self.facts_hash) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'app/models/host/discovered.rb', line 116

def import_from_facts(facts = self.facts_hash)
  cpu_count  = facts['physicalprocessorcount'].to_i rescue 0
  memory     = facts['memorysize_mb'].to_f.ceil rescue 0
  disks      = facts.select { |key, value| key.to_s =~ /blockdevice.*_size/ }
  disks_size = 0
  disk_count = 0

  if disks.any?
    disks.values.each { |size| disks_size += (size.to_f rescue 0) }
    disk_count = disks.size
    # Turning disks_size to closest Mega for easier to read UI
    disks_size = (disks_size / 1024 / 1024).ceil if disks_size > 0
  end

  {:cpu_count => cpu_count, :memory => memory, :disk_count => disk_count, :disks_size => disks_size}
end

#lookup_value_matchObject



185
186
187
188
189
# File 'app/models/host/discovered.rb', line 185

def lookup_value_match
  # We don't really expect lookup values to be used to match discovered hosts,
  # so simply put a string that won't match anything here
  "discovery-not-matched"
end

#populate_fields_from_facts(facts = self.facts_hash, type = 'puppet') ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
# File 'app/models/host/discovered.rb', line 103

def populate_fields_from_facts facts = self.facts_hash, type = 'puppet'
  # type arg only added in 1.7
  if Gem::Dependency.new('', '>= 1.7').match?('', SETTINGS[:version].notag)
    importer = super
  else
    importer = super(facts)
  end
  self.primary_interface.subnet = Subnet.subnet_for(self.primary_interface.ip)
  self.discovery_attribute_set = DiscoveryAttributeSet.where(:host_id => id).first_or_create
  self.discovery_attribute_set.update_attributes(import_from_facts)
  self.save
end

#proxy_urlObject



138
139
140
141
142
143
144
# File 'app/models/host/discovered.rb', line 138

def proxy_url
  if subnet.present? && subnet.discovery.present?
    { :url => subnet.discovery.url + "/discovery/#{self.ip}", :type => 'proxy'}
  else
    { :url => "http://#{self.ip}:8443", :type => 'foreman' }
  end
end

#rebootObject



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'app/models/host/discovered.rb', line 158

def reboot
  logger.info "ForemanDiscovery: Rebooting #{name}"
  proxy_url = self.proxy_url

  if proxy_url[:type] == 'proxy'
    status = ForemanDiscovery::ProxyOperations.new(:url => proxy_url[:url], :operation => 'reboot').parse_put_operation
  else
    status = ::ProxyAPI::BMC.new(:url => "http://#{self.ip}:8443").power :action => "cycle"
  end

  msg = status ? 'successful' : 'failed'
  logger.info "ForemanDiscovery: reboot result: #{msg}"
  status
  rescue => e
    logger.info "ForemanDiscovery: reboot result: failed"
    logger.warn e.backtrace.join('\n')
    raise e
end

#refresh_factsObject



146
147
148
149
150
151
152
153
154
155
156
# File 'app/models/host/discovered.rb', line 146

def refresh_facts
  # TODO: Can we rely on self.ip? The lease might expire/change....
  begin
    logger.debug "retrieving facts from proxy from url: #{proxy_url[:url]}"
    facts = ForemanDiscovery::ProxyOperations.new(:url => proxy_url[:url], :operation => 'facts').parse_get_operation
  rescue Exception => e
    raise _("Could not get facts from proxy %{url}: %{error}") % {:url => proxy_url[:url], :error => e}
  end

  return self.class.import_host_and_facts facts
end

#root_passObject

no need to store anything in the db if the password is our default



134
135
136
# File 'app/models/host/discovered.rb', line 134

def root_pass
  read_attribute(:root_pass).blank? ? (hostgroup.try(:root_pass) || Setting[:root_pass]) : read_attribute(:root_pass)
end

#setup_cloneObject



93
94
95
96
97
# File 'app/models/host/discovered.rb', line 93

def setup_clone
  # Nic::Managed needs this method but Discovered hosts shouldn't
  # be doing orchestration anyway...
  clone
end