foreman/app/controllers/hosts_controller.rb @ d97375e0
2f077f63 | Ohad Levy | class HostsController < ApplicationController
|
|
bf37a972 | Ohad Levy | skip_before_filter :require_login, :only => [ :query, :externalNodes, :lookup ]
|
|
skip_before_filter :require_ssl, :only => [ :query, :externalNodes, :lookup ]
|
|||
0e12dbfc | Ohad Levy | before_filter :find_hosts, :only => :query
|
|
b09b4515 | Ohad Levy | before_filter :ajax_methods, :only => [:environment_selected, :architecture_selected, :os_selected]
|
|
52538203 | Ohad Levy | before_filter :find_multiple, :only => [:multiple_actions, :update_multiple_parameters,
|
|
58b01247 | Eric Shamow | :select_multiple_hostgroup, :select_multiple_environment, :multiple_parameters, :multiple_destroy,
|
|
:multiple_enable, :multiple_disable, :submit_multiple_disable, :submit_multiple_enable]
|
|||
86744a6b | Ohad Levy | before_filter :find_host, :only => %w[show edit update destroy puppetrun setBuild cancelBuild report
|
|
0f77c7f2 | Ohad Levy | reports facts storeconfig_klasses clone externalNodes pxe_config]
|
|
cdd8bb6f | Paul Kelly | ||
459e0feb | Paul Kelly | helper :hosts, :reports
|
|
0e12dbfc | Ohad Levy | ||
b09b4515 | Ohad Levy | def index
|
|
3c7750e1 | Ohad Levy | respond_to do |format|
|
|
format.html do
|
|||
@search = Host.search(params[:search])
|
|||
@hosts = @search.paginate :page => params[:page], :include => [:hostgroup, :domain, :operatingsystem, :environment]
|
|||
@via = "fact_values_"
|
|||
@last_reports = Report.maximum(:id, :group => :host_id, :conditions => {:host_id => @hosts})
|
|||
end
|
|||
format.json { render :json => Host.all(:select => [:name]).to_json(:only => :name) }
|
|||
end
|
|||
a393106d | Ohad Levy | end
|
|
8e4c0917 | Ohad Levy | ||
72e65b31 | Ohad Levy | def show
|
|
86744a6b | Ohad Levy | respond_to do |format|
|
|
format.html {
|
|||
# filter graph time range
|
|||
@range = (params["range"].empty? ? 7 : params["range"].to_i)
|
|||
range = @range.days.ago
|
|||
graphs = @host.graph(range)
|
|||
# runtime graph
|
|||
data = { :labels => graphs[:runtime_labels], :values => graphs[:runtime] }
|
|||
options = { :title => "Runtime"}
|
|||
@runtime_graph = setgraph(GoogleVisualr::AnnotatedTimeLine.new, data, options)
|
|||
# resource graph
|
|||
data = { :labels => graphs[:resources_labels], :values => graphs[:resources] }
|
|||
options = { :title => "Resource", :width => 800, :height => 300, :legend => 'bottom'}
|
|||
@resource_graph = setgraph(GoogleVisualr::LineChart.new, data, options)
|
|||
# summary report text
|
|||
@report_summary = Report.summarise(range, @host)
|
|||
}
|
|||
format.yaml { render :text => @host.info.to_yaml }
|
|||
3c7750e1 | Ohad Levy | format.json { render :json => @host }
|
|
86744a6b | Ohad Levy | end
|
|
72e65b31 | Ohad Levy | end
|
|
b09b4515 | Ohad Levy | def new
|
|
@host = Host.new
|
|||
@host.host_parameters.build
|
|||
end
|
|||
dad78fb6 | Paul Kelly | # Clone the host
|
|
def clone
|
|||
86744a6b | Ohad Levy | new = @host.clone
|
|
dad78fb6 | Paul Kelly | load_vars_for_ajax
|
|
86744a6b | Ohad Levy | new.puppetclasses = @host.puppetclasses
|
|
dad78fb6 | Paul Kelly | # Clone any parameters as well
|
|
86744a6b | Ohad Levy | @host.host_parameters.each{|param| new.host_parameters << param.clone}
|
|
dad78fb6 | Paul Kelly | flash[:error_customisation] = {:header_message => nil, :class => "flash notice", :id => nil,
|
|
19bd108a | Paul Kelly | :message => "The following fields will need reviewing:" }
|
|
86744a6b | Ohad Levy | new.valid?
|
|
@host = new
|
|||
dad78fb6 | Paul Kelly | render :action => :new
|
|
end
|
|||
b09b4515 | Ohad Levy | def create
|
|
@host = Host.new(params[:host])
|
|||
c90663ad | Ohad Levy | respond_to do |format|
|
|
if @host.save
|
|||
format.html do
|
|||
flash[:foreman_notice] = "Successfully created host."
|
|||
redirect_to @host
|
|||
end
|
|||
format.json { render :json => @host, :status => :created, :location => @host }
|
|||
else
|
|||
format.html do
|
|||
load_vars_for_ajax
|
|||
render :action => 'new'
|
|||
end
|
|||
format.json { render :json => @host.errors, :status => :unprocessable_entity }
|
|||
end
|
|||
b09b4515 | Ohad Levy | end
|
|
end
|
|||
def edit
|
|||
dad78fb6 | Paul Kelly | load_vars_for_ajax
|
|
b09b4515 | Ohad Levy | end
|
|
def update
|
|||
if @host.update_attributes(params[:host])
|
|||
flash[:foreman_notice] = "Successfully updated host."
|
|||
redirect_to @host
|
|||
else
|
|||
003ae9a1 | Ohad Levy | load_vars_for_ajax
|
|
b09b4515 | Ohad Levy | render :action => 'edit'
|
|
end
|
|||
end
|
|||
def destroy
|
|||
if @host.destroy
|
|||
c90663ad | Ohad Levy | respond_to do |format|
|
|
format.html { flash[:foreman_notice] = "Successfully destroyed host." }
|
|||
format.json { render :json => @host, :status => :ok and return }
|
|||
end
|
|||
b09b4515 | Ohad Levy | else
|
|
c90663ad | Ohad Levy | respond_to do |format|
|
|
format.html { flash[:foreman_error] = @host.errors.full_messages.join("<br/>") }
|
|||
format.json { render :json => @host.errors, :status => :unprocessable_entity and return }
|
|||
end
|
|||
b09b4515 | Ohad Levy | end
|
|
redirect_to hosts_url
|
|||
end
|
|||
# form AJAX methods
|
|||
def environment_selected
|
|||
if params[:environment_id].to_i > 0 and @environment = Environment.find(params[:environment_id])
|
|||
render :partial => 'puppetclasses/class_selection', :locals => {:obj => (@host ||= Host.new)}
|
|||
else
|
|||
return head(:not_found)
|
|||
end
|
|||
end
|
|||
def architecture_selected
|
|||
assign_parameter "architecture"
|
|||
end
|
|||
def os_selected
|
|||
assign_parameter "operatingsystem"
|
|||
end
|
|||
ad36b317 | Ohad Levy | #returns a yaml file ready to use for puppet external nodes script
|
|
#expected a fqdn parameter to provide hostname to lookup
|
|||
#see example script in extras directory
|
|||
#will return HTML error codes upon failure
|
|||
8e4c0917 | Ohad Levy | def externalNodes
|
|
03e9a623 | Ohad Levy | @host ||= Host.find_by_name(params[:name]) if params[:name]
|
|
not_found and return unless @host
|
|||
bc2625b5 | Ohad Levy | ||
begin
|
|||
respond_to do |format|
|
|||
be96f201 | Ohad Levy | format.html { render :text => @host.info.to_yaml.gsub("\n","<br/>") }
|
|
bc2625b5 | Ohad Levy | format.yml { render :text => @host.info.to_yaml }
|
|
38a6bbd9 | Ohad Levy | end
|
|
bc2625b5 | Ohad Levy | rescue
|
|
# failed
|
|||
logger.warn "Failed to generate external nodes for #{@host.name} with #{$!}"
|
|||
03e9a623 | Ohad Levy | render :text => 'Unable to generate output, Check log files\n', :status => 412 and return
|
|
8e4c0917 | Ohad Levy | end
|
|
end
|
|||
0ce8fa05 | Ohad Levy | ||
e1e9e09b | Ohad Levy | def puppetrun
|
|
7ee08e59 | Ohad Levy | if GW::Puppet.run @host.name
|
|
ce1e6b20 | Frank Sweetser | flash[:foreman_notice] = "Successfully executed, check log files for more details"
|
|
e1e9e09b | Ohad Levy | else
|
|
ce1e6b20 | Frank Sweetser | flash[:foreman_error] = "Failed, check log files"
|
|
e1e9e09b | Ohad Levy | end
|
|
ce1e6b20 | Frank Sweetser | redirect_to :back
|
|
e1e9e09b | Ohad Levy | end
|
|
8613dec9 | Ohad Levy | def setBuild
|
|
86744a6b | Ohad Levy | if @host.setBuild != false
|
|
c90663ad | Ohad Levy | respond_to do |format|
|
|
format.html { flash[:foreman_notice] = "Enabled #{@host.name} for rebuild on next boot" }
|
|||
format.json { render :json => @host, :status => :ok and return }
|
|||
end
|
|||
8613dec9 | Ohad Levy | else
|
|
c90663ad | Ohad Levy | respond_to do |format|
|
|
format.html { flash[:foreman_error] = "Failed to enable #{@host.name} for installation" }
|
|||
format.json { render :json => @host.errors, :status => :unprocessable_entity and return }
|
|||
end
|
|||
8613dec9 | Ohad Levy | end
|
|
redirect_to :back
|
|||
end
|
|||
b0d3f4ee | Ohad Levy | ||
7700f32f | Frank Sweetser | def cancelBuild
|
|
86744a6b | Ohad Levy | if @host.built(false)
|
|
flash[:foreman_notice] = "Canceled pending build for #{@host.name}"
|
|||
7700f32f | Frank Sweetser | else
|
|
86744a6b | Ohad Levy | flash[:foreman_error] = "Failed to cancel pending build for #{@host.name}"
|
|
7700f32f | Frank Sweetser | end
|
|
redirect_to :back
|
|||
end
|
|||
767bbf03 | Ohad Levy | # shows the last report for a host
|
|
def report
|
|||
# is it safe to assume that the biggest ID is the last report?
|
|||
86744a6b | Ohad Levy | redirect_to :controller => "reports", :action => "show", :id => Report.maximum('id', :conditions => {:host_id => @host})
|
|
767bbf03 | Ohad Levy | end
|
|
cdd8bb6f | Paul Kelly | # shows all reports for a certain host
|
|
767bbf03 | Ohad Levy | def reports
|
|
459e0feb | Paul Kelly | # set defaults search order - cant use default scope due to bug in AR
|
|
# http://github.com/binarylogic/searchlogic/issues#issue/17
|
|||
params[:search] ||= {}
|
|||
params[:search][:order] ||= "ascend_by_reported_at"
|
|||
@search = Report.search(params[:search])
|
|||
@reports = @search.paginate(:page => params[:page], :conditions => {:host_id => @host}, :include => :host)
|
|||
767bbf03 | Ohad Levy | end
|
|
0e12dbfc | Ohad Levy | def query
|
|
fdc22cbd | Ohad Levy | if @verbose
|
|
@hosts.map! do |host|
|
|||
hash = {}
|
|||
h = Host.find_by_name host
|
|||
hash[host] = h.info
|
|||
3c7750e1 | Ohad Levy | hash[host]["facts"]= h.facts_hash
|
|
fdc22cbd | Ohad Levy | hash
|
|
end
|
|||
end
|
|||
0e12dbfc | Ohad Levy | respond_to do |format|
|
|
b09b4515 | Ohad Levy | format.html
|
|
format.yml { render :text => @hosts.to_yaml }
|
|||
0e12dbfc | Ohad Levy | end
|
|
end
|
|||
456d537a | Martin Englund | def facts
|
|
3c7750e1 | Ohad Levy | respond_to do |format|
|
|
format.html { redirect_to fact_values_path(:search => {:host_name_eq => @host})}
|
|||
format.json { render :json => @host.facts_hash }
|
|||
end
|
|||
456d537a | Martin Englund | end
|
|
0f77c7f2 | Ohad Levy | def pxe_config
|
|
redirect_to(:controller => "unattended", :action => "pxe_#{@host.operatingsystem.pxe_type}_config", :host_id => @host) if @host
|
|||
end
|
|||
5af52b3b | Ohad Levy | def storeconfig_klasses
|
|
end
|
|||
52538203 | Ohad Levy | # multiple host selection methods
|
|
# present the available actions to the user
|
|||
def multiple_actions
|
|||
end
|
|||
def multiple_parameters
|
|||
dde34153 | Paul Kelly | @parameters = HostParameter.reference_id_is(@hosts).all(:select => "distinct name")
|
|
52538203 | Ohad Levy | end
|
|
def reset_multiple
|
|||
session[:selected] = []
|
|||
2195e30c | Ohad Levy | flash.keep
|
|
52538203 | Ohad Levy | flash[:foreman_notice] = 'Selection cleared.'
|
|
redirect_to hosts_path and return
|
|||
end
|
|||
def update_multiple_parameters
|
|||
if params[:name].empty?
|
|||
flash[:foreman_notice] = "No parameters were allocted to the selected hosts, can't mass assign."
|
|||
redirect_to hosts_path and return
|
|||
end
|
|||
@skipped_parameters = {}
|
|||
counter = 0
|
|||
@hosts.each do |host|
|
|||
skipped = []
|
|||
params[:name].each do |name, value|
|
|||
next if value.empty?
|
|||
if host_param = host.host_parameters.find_by_name(name)
|
|||
counter += 1 if host_param.update_attribute(:value, value)
|
|||
else
|
|||
skipped << name
|
|||
end
|
|||
@skipped_parameters[host.name] = skipped unless skipped.empty?
|
|||
end
|
|||
end
|
|||
session[:selected] = []
|
|||
if @skipped_parameters.empty?
|
|||
flash[:foreman_notice] = 'Updated all hosts!'
|
|||
redirect_to(hosts_path) and return
|
|||
else
|
|||
flash[:foreman_notice] = "#{counter} Parameters updated, see below for more information"
|
|||
end
|
|||
end
|
|||
def select_multiple_hostgroup
|
|||
end
|
|||
def update_multiple_hostgroup
|
|||
# simple validations
|
|||
if (id=params["hostgroup"]["id"]).empty?
|
|||
flash[:foreman_error] = 'No Hostgroup selected!'
|
|||
91dcf7dc | Ohad Levy | redirect_to(select_multiple_hostgroup_hosts) and return
|
|
52538203 | Ohad Levy | end
|
|
if (hg = Hostgroup.find id).nil?
|
|||
flash[:foreman_error] = 'Empty Hostgroup selected!'
|
|||
91dcf7dc | Ohad Levy | redirect_to(select_multiple_hostgroup_hosts) and return
|
|
52538203 | Ohad Levy | end
|
|
#update the hosts
|
|||
Host.find(session[:selected]).each do |host|
|
|||
host.hostgroup=hg
|
|||
host.save(perform_validation = false)
|
|||
end
|
|||
session[:selected] = []
|
|||
flash[:foreman_notice] = 'Updated hosts: Changed Hostgroup'
|
|||
redirect_to(hosts_path)
|
|||
end
|
|||
6b728fdc | Ashay Humane | def select_multiple_environment
|
|
end
|
|||
def update_multiple_environment
|
|||
# simple validations
|
|||
dde34153 | Paul Kelly | if (params[:environment].nil?) or (id=params["environment"]["id"]).nil?
|
|
6b728fdc | Ashay Humane | flash[:foreman_error] = 'No Environment selected!'
|
|
redirect_to(select_multiple_environment_hosts_path) and return
|
|||
end
|
|||
if (ev = Environment.find id).nil?
|
|||
flash[:foreman_error] = 'Empty Environment selected!'
|
|||
redirect_to(select_multiple_environment_hosts_path) and return
|
|||
end
|
|||
#update the hosts
|
|||
Host.find(session[:selected]).each do |host|
|
|||
host.environment=ev
|
|||
host.save(perform_validation = false)
|
|||
end
|
|||
session[:selected] = []
|
|||
flash[:foreman_notice] = 'Updated hosts: Changed Environment'
|
|||
redirect_to(hosts_path)
|
|||
end
|
|||
89569baa | Jochen Schalanda | def multiple_destroy
|
|
end
|
|||
def submit_multiple_destroy
|
|||
# destroy the hosts
|
|||
hosts = Host.find(session[:selected])
|
|||
# keep all the ones that were not deleted for notification.
|
|||
hosts.delete_if {|host| host.destroy}
|
|||
session[:selected] = []
|
|||
be96f201 | Ohad Levy | flash[:foreman_notice] = hosts.empty? ? "Destroyed selected hosts" : "The following hosts were not deleted: #{hosts.map(&:name).join('<br/>')}"
|
|
89569baa | Jochen Schalanda | redirect_to(hosts_path)
|
|
end
|
|||
58b01247 | Eric Shamow | def multiple_disable
|
|
end
|
|||
def submit_multiple_disable
|
|||
toggle_hostmode false
|
|||
end
|
|||
def multiple_enable
|
|||
end
|
|||
def submit_multiple_enable
|
|||
toggle_hostmode
|
|||
end
|
|||
52538203 | Ohad Levy | # AJAX method to update our session each time a host has been selected
|
|
# we are using AJAX and JS as the user might select multiple hosts across different pages (or requests).
|
|||
def save_checkbox
|
|||
return unless request.xhr?
|
|||
session[:selected] ||= []
|
|||
case params[:is_checked]
|
|||
when "true"
|
|||
session[:selected] << params[:box]
|
|||
when "false"
|
|||
session[:selected].delete params[:box]
|
|||
end
|
|||
render :nothing => true
|
|||
end
|
|||
0e12dbfc | Ohad Levy | private
|
|
def find_hosts
|
|||
d34ea57f | Ohad Levy | fact, klass, group = params[:fact], params[:class], params[:hostgroup]
|
|
06160506 | Ohad Levy | ||
fdc22cbd | Ohad Levy | @verbose = params[:verbose] == "yes"
|
|
72a5a1de | Ohad Levy | case params[:state]
|
|
when "out_of_sync"
|
|||
state = "out_of_sync"
|
|||
when "all"
|
|||
state = "all"
|
|||
when "active", nil
|
|||
state = "recent"
|
|||
else
|
|||
raise invalid_request and return
|
|||
end
|
|||
a541cdd9 | Ohad Levy | @hosts = Host.send(state).map(&:name) if fact.empty? and klass.empty? and group.empty?
|
|
0f2c33bc | Ohad Levy | @hosts ||= []
|
|
counter = 0
|
|||
06160506 | Ohad Levy | # TODO: rewrite this part, my brain stopped working
|
|
# it should be possible for a one join
|
|||
fact.each do |f|
|
|||
# split facts based on name => value pairs
|
|||
5539907c | Ohad Levy | q = f.split("-seperator-")
|
|
06160506 | Ohad Levy | invalid_request unless q.size == 2
|
|
72a5a1de | Ohad Levy | list = Host.with_fact(*q).send(state).map(&:name)
|
|
5859a64c | Ohad Levy | @hosts = counter == 0 ? list : @hosts & list
|
|
counter +=1
|
|||
06160506 | Ohad Levy | end unless fact.nil?
|
|
klass.each do |k|
|
|||
f217c950 | Ohad Levy | list = Host.with_class(k).send(state).map(&:name)
|
|
5859a64c | Ohad Levy | @hosts = counter == 0 ? list : @hosts & list
|
|
counter +=1
|
|||
06160506 | Ohad Levy | end unless klass.nil?
|
|
d34ea57f | Ohad Levy | group.each do |k|
|
|
list = Host.hostgroup_name_eq(k).send(state).map(&:name)
|
|||
@hosts = counter == 0 ? list : @hosts & list
|
|||
counter +=1
|
|||
end unless group.nil?
|
|||
03e9a623 | Ohad Levy | not_found if @hosts.empty?
|
|
0e12dbfc | Ohad Levy | end
|
|
b09b4515 | Ohad Levy | def ajax_methods
|
|
return head(:method_not_allowed) unless request.xhr?
|
|||
@host = Host.find(params[:id]) unless params[:id].empty?
|
|||
end
|
|||
def assign_parameter name
|
|||
if params["#{name}_id"].to_i > 0 and eval("@#{name} = #{name.capitalize}.find(params['#{name}_id'])")
|
|||
render :partial => name, :locals => {:host => (@host ||= Host.new)}
|
|||
else
|
|||
return head(:not_found)
|
|||
end
|
|||
end
|
|||
dad78fb6 | Paul Kelly | def load_vars_for_ajax
|
|
return unless @host
|
|||
@environment = @host.environment
|
|||
@architecture = @host.architecture
|
|||
@operatingsystem = @host.operatingsystem
|
|||
end
|
|||
52538203 | Ohad Levy | def find_multiple
|
|
if session[:selected].empty?
|
|||
flash[:foreman_error] = 'No Hosts selected'
|
|||
redirect_to(hosts_path)
|
|||
else
|
|||
2195e30c | Ohad Levy | begin
|
|
@hosts = Host.find(session[:selected], :order => "hostgroup_id ASC")
|
|||
rescue
|
|||
flash[:foreman_error] = "Something went wrong while selecting hosts - resetting ..."
|
|||
flash.keep(:foreman_error)
|
|||
redirect_to reset_multiple_hosts_path
|
|||
end
|
|||
52538203 | Ohad Levy | end
|
|
end
|
|||
58b01247 | Eric Shamow | def toggle_hostmode mode=true
|
|
# keep all the ones that were not disabled for notification.
|
|||
@hosts.delete_if { |host| host.update_attribute(:enabled, mode) }
|
|||
action = mode ? "enabled" : "disabled"
|
|||
session[:selected] = []
|
|||
be96f201 | Ohad Levy | flash[:foreman_notice] = @hosts.empty? ? "#{action.capitalize} selected hosts" : "The following hosts were not #{action}: #{hosts.map(&:name).join('<br/>')}"
|
|
58b01247 | Eric Shamow | redirect_to(hosts_path) and return
|
|
end
|
|||
86744a6b | Ohad Levy | def find_host
|
|
03e9a623 | Ohad Levy | if params[:id]
|
|
render not_found unless @host = Host.find_by_name(params[:id])
|
|||
end
|
|||
86744a6b | Ohad Levy | end
|
|
2f077f63 | Ohad Levy | end
|