Project

General

Profile

170.patch

Ohad Levy, 05/16/2010 04:08 PM

View differences:

app/controllers/hosts_controller.rb
49 49
    # Clone any parameters as well
50 50
    @original.host_parameters.each{|param| @host.host_parameters << param.clone}
51 51
    flash[:error_customisation] = {:header_message => nil, :class => "flash notice", :id => nil,
52
      :message => "The following fields will need modification:" }
52
      :message => "The following fields will need reviewing:" }
53 53
    @host.valid?
54 54
    render :action => :new
55 55
  end
app/controllers/usergroups_controller.rb
2 2
  def index
3 3
    @usergroups = Usergroup.all
4 4
  end
5
  
5

  
6 6
  def new
7 7
    @usergroup = Usergroup.new
8 8
  end
9
  
9

  
10 10
  def create
11 11
    @usergroup = Usergroup.new(params[:usergroup])
12 12
    if @usergroup.save
......
16 16
      render :action => 'new'
17 17
    end
18 18
  end
19
  
19

  
20 20
  def edit
21 21
    @usergroup = Usergroup.find(params[:id])
22
    
22

  
23 23
    render :action => :edit
24 24
  end
25
  
25

  
26 26
  def update
27 27
    @usergroup = Usergroup.find(params[:id])
28
    @usergroup.user_ids      = params[:usergroup][:user_ids]      || []
29
    @usergroup.usergroup_ids = params[:usergroup][:usergroup_ids] || []   
30 28

  
31
    if @usergroup.valid?
29
    if @usergroup.update_attributes(params[:usergroup])
32 30
      flash[:foreman_notice] = "Successfully updated usergroup."
33 31
      redirect_to usergroups_path
34 32
    else
35 33
      render :action => 'edit'
36 34
    end
37 35
  end
38
  
36

  
39 37
  def destroy
40 38
    @usergroup = Usergroup.find(params[:id])
41
    if u = @usergroup.destroy
39
    if @usergroup.destroy
42 40
      flash[:foreman_notice] = "Successfully destroyed usergroup."
43 41
    else
44
      logger.error u.errors.full_messages
45
      flash[:foreman_error] = u.errors.full_messages.join "<br>"
42
      logger.error @usergrup.errors.full_messages
43
      flash[:foreman_error] = @usergroup.errors.full_messages.join "<br>"
46 44
    end
47 45
    redirect_to usergroups_path
48 46
  end
app/helpers/hosts_helper.rb
6 6
      link_to_if(Report.maximum('id', :conditions => {:host_id => record.id}), time, report_host_path(record))
7 7
  end
8 8

  
9
  def root_pass_form_column(record, field_name)
10
      password_field_tag field_name, record.root_pass
11
  end
12

  
13
  def is_owned_by_form_column(record, options)
14
    owner = record.owner || @user || User.first
15
    grouped_options = {"Users"       => User.all.map(&:select_title).sort,
16
                       "User Groups" => Usergroup.all.map(&:select_title).sort
17
                      }
18
    select "record", "is_owned_by",  grouped_options_for_select(grouped_options, owner.select_title)
9
  def grouped_options
10
    { "Users"       => User.all.map(&:select_title).sort,
11
      "User Groups" => Usergroup.all.map(&:select_title).sort }
19 12
  end
20 13

  
21 14
# method that reformats the hostname column by adding the status icons
app/models/auth_source_ldap.rb
36 36
    attrs = []
37 37
    # get user's DN
38 38
    if not account.nil? and self.account.include? "$login" then
39
    	logger.debug "LDAP-Auth with User login"
40
   	  ldap_con = initialize_ldap_con(self.account.sub("$login", login), password)
39
      logger.debug "LDAP-Auth with User login"
40
      ldap_con = initialize_ldap_con(self.account.sub("$login", login), password)
41 41
    else
42
        ldap_con = initialize_ldap_con(self.account, self.account_password)
42
      ldap_con = initialize_ldap_con(self.account, self.account_password)
43 43
    end
44 44
    login_filter = Net::LDAP::Filter.eq( self.attr_login, login )
45 45
    object_filter = Net::LDAP::Filter.eq( "objectClass", "*" )
46 46
    dn = String.new
47 47
    ldap_con.search( :base => self.base_dn,
48
                     :filter => object_filter & login_filter,
49
                     # only ask for the DN if on-the-fly registration is disabled
50
                     :attributes=> (onthefly_register? ? ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail] : ['dn'])) do |entry|
48
                    :filter => object_filter & login_filter,
49
                    # only ask for the DN if on-the-fly registration is disabled
50
                    :attributes=> (onthefly_register? ? ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail] : ['dn'])) do |entry|
51 51
      dn = entry.dn
52 52
      attrs = [:firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
53
               :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
54
               :mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
55
               :auth_source_id => self.id ] if onthefly_register?
56
    end
53
        :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
54
        :mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
55
        :auth_source_id => self.id ] if onthefly_register?
56
                    end
57 57
    return nil if dn.empty?
58 58
    logger.debug "DN found for #{login}: #{dn}" if logger && logger.debug?
59 59
    # authenticate user
......
88 88

  
89 89
  def initialize_ldap_con(ldap_user, ldap_password)
90 90
    options = { :host => self.host,
91
                :port => self.port,
92
                :encryption => (self.tls ? :simple_tls : nil)
93
              }
91
      :port => self.port,
92
      :encryption => (self.tls ? :simple_tls : nil)
93
    }
94 94
    options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank?
95 95
    Net::LDAP.new options
96 96
  end
app/models/domain_parameter.rb
1 1
class DomainParameter < Parameter
2 2
  belongs_to :domain
3 3
  validates_presence_of :domain_id, :message => "parameters require an associated domain", :unless => :nested
4
  validates_uniqueness_of :name
4
  validates_uniqueness_of :name, :scope => :domain_id
5 5
end
app/models/group_parameter.rb
1 1
class GroupParameter < Parameter
2 2
  belongs_to :hostgroup
3
  validates_presence_of :hostgroup_id
3
  validates_presence_of :hostgroup_id, :unless => :nested
4
  validates_uniqueness_of :name, :scope => :hostgroup_id
4 5
end
app/models/host.rb
44 44
    ((puppet_status >> #{Report::BIT_NUM*Report::METRIC.index("skipped")} & #{Report::MAX}) != 0)"
45 45
  }
46 46

  
47

  
48 47
  named_scope :with_changes, { :conditions => "(puppet_status > 0) and
49 48
    ((puppet_status >> #{Report::BIT_NUM*Report::METRIC.index("applied")} & #{Report::MAX}) != 0) or
50 49
    ((puppet_status >> #{Report::BIT_NUM*Report::METRIC.index("restarted")} & #{Report::MAX}) !=0)"
......
72 71
    validates_length_of      :root_pass, :minimum => 8,:too_short => 'should be 8 characters or more'
73 72
    validates_format_of      :mac,       :with => /([a-f0-9]{1,2}:){5}[a-f0-9]{1,2}/
74 73
    validates_format_of      :ip,        :with => /(\d{1,3}\.){3}\d{1,3}/
75
    validates_presence_of    :ptable, :message => "Cant be blank unless a custom partition has been defined",
74
    validates_presence_of    :ptable, :message => "cant be blank unless a custom partition has been defined",
76 75
                             :if => Proc.new { |host| host.disk.empty? and not defined?(Rake) }
77 76
    validates_format_of      :sp_mac,    :with => /([a-f0-9]{1,2}:){5}[a-f0-9]{1,2}/, :allow_nil => true, :allow_blank => true
78 77
    validates_format_of      :sp_ip,     :with => /(\d{1,3}\.){3}\d{1,3}/, :allow_nil => true, :allow_blank => true
......
85 84
  def <=>(other)
86 85
    self.name <=> other.name
87 86
  end
88
  
87

  
89 88
  # Returns the name of this host as a string
90 89
  # String: the host's name
91 90
  def to_label
......
106 105
  end
107 106

  
108 107
  def is_owned_by
109
    
108

  
110 109
  end
111 110

  
112 111
  def is_owned_by=(the_owner)
......
114 113
    if match = the_owner.match(/^[^\(]+\(([^\)]+)\)/)
115 114
      owner = User.find_by_login(match[1])
116 115
    else
117
      owner = Usergroup.find_by_name(the_owner) 
116
      owner = Usergroup.find_by_name(the_owner)
118 117
    end
119 118
    if owner
120
      update_attribute :owner, owner 
119
      update_attribute :owner, owner
121 120
    else
122 121
      errors.add_to_base "Unable to set the owner of this host to #{the_owner}"
123 122
    end
app/models/host_mailer.rb
44 44

  
45 45
  def error_state(report)
46 46
    host = report.host
47
    if SETTINGS[:ldap]
48
      email = host.owner.recipients
49
    else
50
      email = SETTINGS[:administrator]
51
    end
47
    email = SETTINGS[:ldap] ? host.owner.recipients : SETTINGS[:administrator]
52 48
    raise "unable to find recipients" if email.empty?
53 49
    recipients email
54 50
    from "Foreman-noreply"
app/models/host_parameter.rb
1 1
class HostParameter < Parameter
2 2
  belongs_to :host
3 3
  validates_presence_of :host_id, :message => "parameters require an associated host", :unless => :nested
4
  validates_uniqueness_of :name, :scope => :host_id
4 5

  
5 6
  def to_s
6 7
    "#{host_id ? host.name : "unassociated"}: #{name} = #{value}"
app/models/user.rb
2 2
  belongs_to :auth_source
3 3
  has_many :changes, :class_name => 'Audit', :as => :user
4 4
  has_many :usergroups, :through => :usergroup_member
5
  
5

  
6 6
  has_many :direct_hosts, :as => :owner, :class_name => "Host"
7 7

  
8 8
  validates_uniqueness_of :login, :message => "already exists"
......
21 21
  end
22 22
  alias_method :to_s, :to_label
23 23
  alias_method :name, :to_label
24
  
24

  
25 25
  def <=>(other)
26 26
    self.name <=> other.name
27 27
  end
28
  
28

  
29 29
  # The text item to see in a select dropdown menu
30 30
  def select_title
31 31
    name + " (#{login})"
32 32
  end
33
  
33

  
34 34
  def self.try_to_login(login, password)
35 35
    # Make sure no one can sign in with an empty password
36 36
    return nil if password.to_s.empty?
......
70 70
    end
71 71
    all_groups.uniq.map{|g| g.hosts}.flatten.uniq
72 72
  end
73
  
73

  
74 74
  def hosts
75 75
    direct_hosts + indirect_hosts
76 76
  end
77
  
77

  
78 78
  def recipients
79 79
    [mail]
80 80
  end
81
  
81

  
82 82
  protected
83
  
83

  
84 84
  def validate
85 85
    if Usergroup.all.map(&:name).include?(self.login)
86 86
      errors.add_to_base "A usergroup already exists with this name"
app/models/usergroup.rb
1 1
class Usergroup < ActiveRecord::Base
2 2
  has_many_polymorphs :members, :from => [:usergroups, :users ], :as => :member, :through => :usergroup_member, :foreign_key => :usergroup_id, :dependent => :destroy
3 3
  has_many :hosts, :as => :owner
4
 
4

  
5 5
  validates_uniqueness_of :name
6
  
6

  
7 7
  before_destroy Ensure_not_used_by.new(:hosts, :usergroups)
8
  
8

  
9 9
  def to_s
10 10
    name
11 11
  end
12
  
12

  
13 13
  # The text item to see in a select dropdown menu
14 14
  alias_method :select_title, :to_s
15 15

  
......
23 23
  def recipients
24 24
    all_users.map(&:mail)
25 25
  end
26
  
26

  
27 27
  # This methods retrieves all users in a usergroup
28 28
  # Returns: Array of users
29 29
  def all_users(group_list=[self], user_list=[])
30 30
    retrieve_users_and_groups group_list, user_list
31 31
    user_list.sort.uniq
32 32
  end
33
  
33

  
34 34
  # This methods retrieves all usergroups in a usergroup
35 35
  # Returns: Array of usergroups
36 36
  def all_usergroups(group_list=[self], user_list=[])
......
42 42
  # Recurses down the tree of usergroups and finds the users
43 43
  # [+group_list+]: Array of Usergroups that have already been processed
44 44
  # [+users+]     : Array of users accumulated at this point
45
  # Returns       : Array of non unique users 
45
  # Returns       : Array of non unique users
46 46
  def retrieve_users_and_groups(group_list, user_list)
47 47
    for group in usergroups
48 48
      next if group_list.include? group
49 49
      group_list << group
50
      
51
      group.retrieve_users_and_groups(group_list, user_list) 
50

  
51
      group.retrieve_users_and_groups(group_list, user_list)
52 52
    end
53 53
    user_list.concat users
54 54
  end
......
58 58
      errors.add :name, "is already used by a user account"
59 59
    end
60 60
  end
61
  
61

  
62 62
end
app/views/hosts/_architecture.html.erb
1
<%= label :host, :operatingsystem, "Operating system" %>
1
Operating system
2 2
<%= collection_select :host, :operatingsystem_id, @architecture.operatingsystems, :id, :to_label, :include_blank => true %>
3 3
<span id=os_sub_select>
4 4
  <% if @operatingsystem -%>
app/views/hosts/_form.html.erb
4 4
  <% field_set_tag 'Primary settings' do -%>
5 5
    <table>
6 6
      <tr>
7
        <td><%= f.label :name %></td>
7
        <td>Name</td>
8 8
        <td><%= f.text_field :name, :size => 16, :value => @host.shortname %></td>
9
        <td><%= f.label :hostgroup, "Host group" %></td>
9
        <td>Host group</td>
10 10
        <td><%= f.collection_select :hostgroup_id, Hostgroup.all, :id, :name, :include_blank => true %></td>
11
        <td><%= f.label :environment %></td>
11
        <td>Environment</td>
12 12
        <td><%= f.collection_select :environment_id, Environment.all, :id, :to_label, :include_blank => true %></td>
13
        <td><%= f.label :puppetmaster %></td>
13
        <td>Puppetmaster</td>
14 14
        <td><%= f.text_field :puppetmaster, :size => 10, :value => @host.puppetmaster %></td>
15 15
        <td><%= link_to_function "Additional Classes", toggle_div(:classlist) %></td>
16 16
      </tr>
......
35 35
    <%= render 'unattended', :f => f %>
36 36
  <% end -%>
37 37

  
38
  <% if SETTINGS[:ldap] -%>
39
    <%= f.select :owner, grouped_options_for_select(grouped_options) %>
40
  <% end -%>
41

  
38 42
  <% field_set_tag 'Additional Information' do -%>
39 43
    <%= f.text_area :comment, :size => "120x5" %>
40 44
  <% end -%>
app/views/hosts/_operatingsystem.html.erb
1
<%= label :host, :media %>
1
Media
2 2
<%= collection_select :host, :media_id, @operatingsystem.medias, :id, :to_label %>
3
<%= label :host, :ptable, "Partition Table" %>
3
Partition Table
4 4
<%= collection_select :host, :ptable_id, @operatingsystem.ptables, :id, :to_label %>
app/views/hosts/_unattended.html.erb
2 2
  <% field_set_tag 'Network settings', :id => "network" do -%>
3 3
    <table>
4 4
      <tr>
5
        <td><%= f.label :domain %></td>
5
        <td>Domain</td>
6 6
        <td><%= f.collection_select :domain_id, Domain.all, :id, :to_label %></td>
7
        <td><%= f.label :ip %></td>
7
        <td>IP</td>
8 8
        <td><%= f.text_field :ip, :size => 16 %></td>
9
        <td><%= f.label :mac, "MAC" %></td>
9
        <td>MAC</td>
10 10
        <td><%= f.text_field :mac, :size => 17 %></td>
11 11
      </tr>
12 12
    </table>
......
17 17
      <tr>
18 18
        <td colspan="6">
19 19
          <span id="architecture">
20
            <%= f.label :architecture %>
20
            Architecture
21 21
            <%= f.collection_select :architecture_id, Architecture.all, :id, :to_label, :include_blank => true %>
22 22
            <span id="host_os">
23 23
              <% if @architecture -%>
......
28 28
        </td>
29 29
      </tr>
30 30
      <tr>
31
        <td><%= f.label :root_pass, "Root password" %></td>
31
        <td>Root password</td>
32 32
        <td><%= f.password_field :root_pass %></td>
33
        <td><%= f.label :model %></td>
33
        <td>Model</td>
34 34
        <td><%= f.collection_select :model_id, Model.all, :id, :to_label, :include_blank => true %></td>
35
        <td><%= f.label :serial %></td>
35
        <td>Serial</td>
36 36
        <td><%= f.select :serial, ["","0,9600n8","0,19200n8","1,9600n8","1,19200n8"] %></td>
37 37
      </tr>
38 38
      <tr>
39 39
        <td colspan="6">
40 40
          <%= link_to_function "Switch to custom disk layout", toggle_div("custom_disk") %>
41 41
          <div id="custom_disk", style=display:none;>
42
            <%= f.label :disk, "Custom Disk layout" %>
42
            Custom Disk layout
43 43
            <%= f.text_area :disk, :size => "50x10", :disabled => true %>
44 44
          </div>
45 45
        </td>
app/views/usergroups/_form.html.erb
4 4
    <tr>
5 5
      <td>
6 6
        Name
7
			</td>
8
			<td>
7
      </td>
8
      <td>
9 9
        <%= f.text_field :name %>
10
     </td>
10
      </td>
11 11
    </tr>
12 12
    <tr>
13 13
      <td>
14
      	User groups
15
			</td><td>
14
        User groups
15
        </td><td>
16 16
        <%= edit_habtm @usergroup, Usergroup, @usergroup %>
17 17
      </td>
18 18
    </tr>
19
		<tr>
20
			<td>
21
				Users
22
			</td><td>
23
				<%= edit_habtm @usergroup, User %>
24
			</td>
25
		</tr>
19
    <tr>
20
      <td>
21
        Users
22
        </td><td>
23
        <%= edit_habtm @usergroup, User %>
24
      </td>
25
    </tr>
26 26
    <tr><td><%= f.submit "Submit" %></td></tr>
27 27
  </table>
28 28
<% end %>
config/initializers/foreman.rb
72 72
    end
73 73
  end
74 74
end
75
module ActionView::Helpers::ActiveRecordHelper
76
  def error_messages_for_with_customisation(*params)
77
    if flash[:error_customisation]
78
      if params[-1].is_a? Hash
79
        params[-1].update flash[:error_customisation]
80
      else
81
        params << flash[:error_customisation]
82
      end
83
    end
84
    error_messages_for_without_customisation(*params)
85
  end
86
  alias_method_chain :error_messages_for, :customisation
87
end
config/settings.yaml
2 2
#:modulepath: /etc/puppet/modules/
3 3
:tftppath: tftp/
4 4
#:rrd_report_url: report/
5
#:ldap: true
5
:ldap: true
6 6
#your default puppet server - can be overridden in the host level
7 7
#if none specified, plain "puppet" will be used.
8 8
#:puppet_server: puppet
9 9
#:unattended: false
10 10
#use the following setting to override the default 30 minutes puppet run interval - value must be in minutes
11
#:puppet_interval: 60
11
#:puppet_interval: 60
lib/family.rb
42 42
    def mediapath host
43 43
      uri = media_uri(host)
44 44
      server = uri.select(:host, :port).compact.join(':')
45
      dir = uri.select(:path, :query).compact.join('?')
45
      dir = uri.select(:path, :query).compact.join('?') unless uri.scheme == 'ftp'
46 46

  
47 47
      case uri.scheme
48 48
        when 'http', 'https', 'ftp'
......
61 61
        epel_url.gsub!("$os","4-9")
62 62
      when "5"
63 63
        epel_url.gsub!("$os","5-3")
64
      when "6"
65
         epel_url.gsub!("$os","6-1").
66
           gsub!("/pub/epel/","/pub/epel/beta/") # workaround for hardcoded beta in url, should be remove once RH6 is released
64 67
      else
65 68
        return ""
66 69
      end
67
      return "su -c 'rpm -Uvh #{media_uri(host, epel_url)}"
70
      return "su -c 'rpm -Uvh #{media_uri(host, epel_url)}'"
68 71
    end
69 72

  
70 73
    def yumrepo host
test/fixtures/parameters.yml
4 4
  name: test
5 5
  value: myvalue
6 6
  type: CommonParameter
7
#
8
# two:
9
#   column: value
7

  
8
two:
9
  name: parameter
10
  value: value1
11

  
test/unit/domain_parameter_test.rb
9 9
    parameter.domain_id = domain.id
10 10
    assert parameter.save
11 11
  end
12

  
13
  test "should have a unique parameter name" do
14
    p1 = DomainParameter.new(:name => "parameter", :value => "value1", :domain_id => Domain.first)
15
    assert p1.save
16
    p2 = DomainParameter.new(:name => "parameter", :value => "value2", :domain_id => Domain.first)
17
    assert !p2.save
18
  end
12 19
end
13 20

  
test/unit/parameter_test.rb
30 30
    parameter.value.strip!.squeeze!(" ").empty?
31 31
    assert parameter.save
32 32
  end
33

  
34
  test  "name must not be unique accross different parameter groups" do
35
    p1 = HostParameter.new :name => "param", :value => "value1", :host_id => Host.first
36
    assert p1.save
37
    p2 = DomainParameter.new :name => "param", :value => "value2", :domain_id => Domain.first
38
    assert p2.save
39
    p3 = CommonParameter.new :name => "param", :value => "value3"
40
    assert p3.save
41
    p4 = GroupParameter.new :name => "param", :value => "value4", :hostgroup_id => Hostgroup.first
42
    assert p4.save
43
  end
33 44
end