212 lines
4.4 KiB
Ruby
Executable File
212 lines
4.4 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
|
|
begin
|
|
require 'rubygems'
|
|
rescue LoadError
|
|
end
|
|
require 'ohai/system'
|
|
require 'json'
|
|
require 'httpclient'
|
|
require 'logger'
|
|
require 'optparse'
|
|
|
|
module NodeAgentConfig
|
|
extend self
|
|
|
|
attr_accessor :api
|
|
|
|
def define
|
|
yield self
|
|
end
|
|
end
|
|
|
|
|
|
class NodeAgent
|
|
def initialize(logger, config=nil)
|
|
@logger = logger
|
|
|
|
@api_default_address = "localhost"
|
|
@api_default_port = "8000"
|
|
|
|
if not config.nil?
|
|
if not config.api.nil?
|
|
@api_url = config.api
|
|
end
|
|
end
|
|
|
|
if not @api_url
|
|
begin
|
|
cmdline = ::File.read("/proc/cmdline")
|
|
api_ip = cmdline.match(/\burl=http:\/\/((\d{1,3}\.){3}\d{1,3})/)[1]
|
|
@logger.info("Found admin node IP address in kernel cmdline: #{api_ip}")
|
|
rescue
|
|
@logger.error("Can't get API url from /proc/cmdline. Will use localhost.")
|
|
api_ip = "127.0.0.1"
|
|
end
|
|
@api_url = "http://#{api_ip}:#{@api_default_port}/api"
|
|
end
|
|
|
|
@os = Ohai::System.new()
|
|
@os.all_plugins
|
|
end
|
|
|
|
def put
|
|
headers = {"Content-Type" => "application/json"}
|
|
htclient = HTTPClient.new
|
|
@logger.debug("Trying to put host info into #{@api_url}")
|
|
res = htclient.put("#{@api_url}/nodes/", [_data].to_json, headers)
|
|
if res.status < 200 or res.status >= 300
|
|
@logger.error("HTTP PUT failed: #{res.inspect}")
|
|
end
|
|
return res
|
|
end
|
|
|
|
def post
|
|
headers = {"Content-Type" => "application/json"}
|
|
htclient = HTTPClient.new
|
|
@logger.debug("Trying to create host using #{@api_url}")
|
|
res = htclient.post("#{@api_url}/nodes/", _data.to_json, headers)
|
|
return res
|
|
end
|
|
|
|
def _interfaces
|
|
interfaces = @os[:network][:interfaces].inject([]) do |result, elm|
|
|
result << { :name => elm[0], :addresses => elm[1]["addresses"] }
|
|
end
|
|
interfaces << { "default_interface" => @os["network"]["default_interface"] }
|
|
interfaces << { "default_gateway" => @os["network"]["default_gateway"] }
|
|
interfaces
|
|
end
|
|
|
|
def _mac
|
|
@os[:macaddress]
|
|
end
|
|
|
|
def _metadata
|
|
{
|
|
:block_device => @os["block_device"].to_hash,
|
|
:interfaces => _interfaces,
|
|
:cpu => @os["cpu"].to_hash,
|
|
:memory => @os["memory"].to_hash,
|
|
:serial => _serial
|
|
}
|
|
end
|
|
|
|
def _is_virtual
|
|
begin
|
|
if @os["virtualization"]["role"] == "guest"
|
|
return true
|
|
end
|
|
rescue
|
|
end
|
|
return false
|
|
end
|
|
|
|
def _manufacturer
|
|
if _is_virtual
|
|
return @os["virtualization"]["system"].upcase
|
|
else
|
|
begin
|
|
return @os[:dmi][:system][:manufacturer]
|
|
rescue
|
|
return "Unknown"
|
|
end
|
|
end
|
|
end
|
|
|
|
def _product_name
|
|
if _is_virtual
|
|
return @os["virtualization"]["role"]
|
|
else
|
|
begin
|
|
return @os[:dmi][:system][:product_name]
|
|
rescue
|
|
return "Unknown"
|
|
end
|
|
end
|
|
end
|
|
|
|
def _serial
|
|
begin
|
|
return @os[:dmi][:system][:serial_number]
|
|
rescue
|
|
return "Unknown"
|
|
end
|
|
end
|
|
|
|
def _data
|
|
res = {
|
|
:fqdn => @os[:fqdn],
|
|
:mac => @os[:macaddress],
|
|
:ip => @os[:ipaddress],
|
|
:manufacturer => _manufacturer,
|
|
:platform_name => _product_name,
|
|
:os_platform => @os[:platform],
|
|
:meta => _metadata
|
|
}
|
|
|
|
res[:status] = @node_state if @node_state
|
|
res
|
|
end
|
|
|
|
def update_state
|
|
@node_state = nil
|
|
if File.exist?("/opt/nailgun/system_type")
|
|
fl = File.open("/opt/nailgun/system_type", "r")
|
|
system_type = fl.readline.rstrip
|
|
@node_state = "discover" if system_type == "bootstrap"
|
|
else
|
|
fl = File.open("/opt/nailgun/system_type", "w")
|
|
fl.puts("target")
|
|
@node_state = "ready"
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
|
|
logger = Logger.new(STDOUT)
|
|
logger.level = Logger::DEBUG
|
|
|
|
|
|
options = {}
|
|
optparser = OptionParser.new do |opts|
|
|
opts.banner = "Usage: #{__FILE__} [options]"
|
|
|
|
opts.on( '-h', '--help', 'Display this screen' ) do
|
|
puts opts
|
|
exit
|
|
end
|
|
|
|
opts.on("-c", "--config CONFIG", "Config file") do |config_file|
|
|
options[:config_file] = config_file
|
|
end
|
|
|
|
end
|
|
|
|
optparser.parse!
|
|
|
|
if options[:config_file].nil?
|
|
options[:config_file] = "/etc/nailgun-agent/config.rb"
|
|
end
|
|
|
|
begin
|
|
logger.info("Trying to load agent config #{options[:config_file]}")
|
|
load options[:config_file]
|
|
rescue LoadError
|
|
logger.error("Error occured while loading agent config")
|
|
end
|
|
|
|
|
|
agent = NodeAgent.new(logger, NodeAgentConfig)
|
|
begin
|
|
agent.update_state
|
|
res = agent.post
|
|
if res.status == 409:
|
|
agent.put
|
|
end
|
|
rescue Exception => e
|
|
logger.error("Error in sending node info: #{e.message}")
|
|
end
|
|
|