From a2d1332bb1732be4fc97c755daad983f55d173bf Mon Sep 17 00:00:00 2001
From: Paul Kelly
<%= f.collection_select :dns_id, Netsvc.servertype_name_is("DNS"), :id, :name %>
+ <%= f.label :tftp_id %>
+ <%= f.collection_select :tftp_id, Netsvc.servertype_name_is("TFTP"), :id, :name %>
+
<%= f.submit "Submit" %>
diff --git a/app/views/home/_settings.html.erb b/app/views/home/_settings.html.erb index 5b61f4f..d644e7e 100644 --- a/app/views/home/_settings.html.erb +++ b/app/views/home/_settings.html.erb @@ -10,7 +10,7 @@ ['Host Groups', hostgroups_url], ['Installation Medias', medias_url], ['LDAP Authentication', auth_source_ldaps_url], - ['Network Datbases', netsvcs_url], + ['Network Services', netsvcs_url], ['Operating Systems', operatingsystems_url], ['Partition Tables', ptables_url], ['Puppet Classes', puppetclasses_url], diff --git a/db/migrate/20101015100000_add_dns_column.rb b/db/migrate/20101015100000_add_dns_and_tftp_column.rb similarity index 100% rename from db/migrate/20101015100000_add_dns_column.rb rename to db/migrate/20101015100000_add_dns_and_tftp_column.rb diff --git a/lib/netsvc_manager/domain_ext.rb b/lib/netsvc_manager/domain_ext.rb index 3ada14a..4ab0877 100644 --- a/lib/netsvc_manager/domain_ext.rb +++ b/lib/netsvc_manager/domain_ext.rb @@ -4,7 +4,8 @@ def self.included(base) #:nodoc: base.extend ClassMethods base.send :include, InstanceMethods base.class_eval do - belongs_to :dns, :class_name => 'Netsvc' + belongs_to :dns, :class_name => 'Netsvc' + belongs_to :tftp, :class_name => 'Netsvc' end end diff --git a/lib/netsvc_manager/host_ext.rb b/lib/netsvc_manager/host_ext.rb index 945e8cc..7c3648a 100644 --- a/lib/netsvc_manager/host_ext.rb +++ b/lib/netsvc_manager/host_ext.rb @@ -21,8 +21,8 @@ def self.included(base) base.send :include, InstanceMethods base.class_eval do attr_accessor :dns, :dhcp - before_create :initialize_proxies, :check_netsvcs - after_create :create_netsvcs, :initialize_tftp + before_create :initialize_proxies, :cache_tftp_files, :check_netdbs + after_create :create_netsvcs after_update :initialize_proxies, :update_netsvcs after_destroy :initialize_proxies, :destroy_netsvcs end @@ -31,12 +31,20 @@ def self.included(base) module InstanceMethods # Ensure that the tftp bootfiles are available on the proxy host - def initialize_tftp - + def cache_tftp_files + for bootfile_info in operatingsystem.pxe_files(media, architecture) + for prefix, path in bootfile_info do + return false unless \ + log_transaction("Download a bootfile from #{path} into #{prefix}", @tftp, true) do |tftp| + tftp.fetch_boot_file :prefix => prefix.to_s, :path => path + end + end + end end + # Checks whether DNS or DHCP entries already exist # Returns: Boolean true if no entries exists - def check_netsvcs + def check_netdbs continue = true if (address = @resolver.getaddress(name) rescue false) errors.add_to_base "#{name} is already in DNS with an address of #{address}" @@ -123,8 +131,8 @@ def delDNS } end - def log_transaction message, server - logger.info "#{message}" + def log_transaction message, server, only_log_errors = false + logger.info "#{message}" unless only_log_errors unless result = yield(server) first, rest = message.match(/(\w*)(.*)/)[1,2] message = "Failed to " + first.downcase + rest + ": #{server.error}" @@ -135,9 +143,9 @@ def log_transaction message, server end def initialize_proxies - proxy_address = "http://#{subnet.dhcp.address}:4567" - @dhcp = ProxyAPI::DHCP.new(:url => proxy_address) - @dns = ProxyAPI::DNS.new(:url => proxy_address) + @dhcp = ProxyAPI::DHCP.new(:url => "http://#{subnet.dhcp.address}:4567") + @dns = ProxyAPI::DNS.new( :url => "http://#{domain.dns.address}:4567") + @tftp = ProxyAPI::TFTP.new(:url => "http://#{domain.tftp.address}:4567") @resolver = Resolv::DNS.new :search => domain.name, :nameserver => domain.dns.address end diff --git a/lib/proxy_api.rb b/lib/proxy_api.rb index 66b3a71..41dff67 100644 --- a/lib/proxy_api.rb +++ b/lib/proxy_api.rb @@ -27,6 +27,10 @@ def initialize(args) :headers => { :accept => :json, :content_type => :json }} end + def hostname + match = @resource.to_s.match(/:\/\/([^\/:]+)/) + match ? match[1] : "hostname in #{@resource}" + end def list strip_hash_name(parse(get(path_prefix))) @@ -68,7 +72,7 @@ def parse reply def _get_ path @resource[URI.escape(path)].get{|response, request, result| [result, response] } rescue Exception => e - [ OpenStruct.new(:code => "500"), e.message] + [ OpenStruct.new(:code => "500"), e.message =~ /getaddrinfo/ ? "Unable to locate #{hostname}" : e.message] end # Perform POST operation with the supplied payload on the supplied path @@ -78,7 +82,7 @@ def _get_ path def _post_ payload, path @resource[path].post(payload){|response, request, result| [result, response] } rescue Exception => e - [ OpenStruct.new(:code => "500"), e.message] + [ OpenStruct.new(:code => "500"), e.message =~ /getaddrinfo/ ? "Unable to locate #{hostname}" : e.message] end # Perform PUT operation with the supplied payload on the supplied path @@ -88,7 +92,7 @@ def _post_ payload, path def _put_ payload, path @resource[path].put(payload){|response, request, result| [result, response] } rescue Exception => e - [ OpenStruct.new(:code => "500"), e.message] + [ OpenStruct.new(:code => "500"), e.message =~ /getaddrinfo/ ? "Unable to locate #{hostname}" : e.message] end # Perform DELETE operation on the supplied path @@ -98,7 +102,7 @@ def _put_ payload, path def _delete_ path @resource[path].delete{|response, request, result| [result, response] } rescue Exception => e - [ OpenStruct.new(:code => "500"), e.message] + [ OpenStruct.new(:code => "500"), e.message =~ /getaddrinfo/ ? "Unable to locate #{hostname}" : e.message] end def hash_name @@ -112,8 +116,7 @@ def opts class DHCP < Resource def initialize args - @url = args[:url] || raise("Must provide a URL") - @url += "/dhcp" + @url = args[:url] + "/dhcp" || raise("Must provide a URL") super args end @@ -121,7 +124,7 @@ def initialize args # Returns: Array of Hashes or false # Example [{"network":"192.168.11.0","netmask":"255.255.255.0"},{"network":"192.168.122.0","netmask":"255.255.255.0"}] def subnets - parse(_get_(".json")) + parse(_get_("")) end # Retrieves a DHCP entry @@ -129,7 +132,7 @@ def subnets # [+mac+] : String in coloned sexpulet format # Returns : Hash or false def get subnet, mac - parse(_get_("#{subnet}/#{mac}.json")) + parse(_get_("#{subnet}/#{mac}")) end # Sets a DHCP entry @@ -152,8 +155,7 @@ def delete subnet, mac class DNS < Resource def initialize args - @url = args[:url] || raise("Must provide a URL") - @url += "/dns" + @url = args[:url] + "/dns" || raise("Must provide a URL") super args end @@ -172,6 +174,25 @@ def delete key parse(_delete_("#{key}")) end end + + class TFTP < Resource + def initialize args + @url = args[:url] + "/tftp" || raise("Must provide a URL") + super args + end + + def set mac, args + parse(_post_(args, mac)) + end + + def delete mac + parse(_delete_("#{mac}")) + end + + def fetch_boot_file args + parse(_post_(args, "fetch_boot_file")) + end + end end if __FILE__.gsub(/\.\//, "") == $0