staypuft 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. checksums.yaml +8 -8
  2. data/app/assets/javascripts/staypuft/staypuft.js +41 -0
  3. data/app/controllers/staypuft/steps_controller.rb +1 -1
  4. data/app/lib/staypuft/network_query.rb +17 -6
  5. data/app/lib/staypuft/seeder.rb +50 -262
  6. data/app/models/staypuft/deployment.rb +8 -32
  7. data/app/models/staypuft/deployment/cinder_service.rb +5 -17
  8. data/app/models/staypuft/deployment/glance_service.rb +2 -9
  9. data/app/models/staypuft/deployment/neutron_service.rb +10 -2
  10. data/app/models/staypuft/deployment/nova_service.rb +11 -2
  11. data/app/models/staypuft/deployment/passwords.rb +2 -2
  12. data/app/models/staypuft/service.rb +1 -21
  13. data/app/views/staypuft/deployments/_deployment_access_all_details_dialogue.html.erb +7 -18
  14. data/app/views/staypuft/deployments/_deployment_hosts.html.erb +1 -1
  15. data/app/views/staypuft/deployments/_deployment_show_header.html.erb +1 -4
  16. data/app/views/staypuft/deployments/_free_hosts.html.erb +2 -2
  17. data/app/views/staypuft/deployments/_free_hosts_table.html.erb +2 -2
  18. data/app/views/staypuft/interface_assignments/_nics_assignment_overview.html.erb +40 -0
  19. data/app/views/staypuft/interface_assignments/index.html.erb +5 -39
  20. data/app/views/staypuft/steps/_cinder.html.erb +0 -1
  21. data/app/views/staypuft/steps/_neutron.html.erb +6 -3
  22. data/app/views/staypuft/steps/_nova.html.erb +3 -0
  23. data/app/views/staypuft/steps/deployment_settings.html.erb +1 -2
  24. data/app/views/staypuft/steps/services_configuration.html.erb +1 -0
  25. data/app/views/staypuft/steps/services_overview.html.erb +1 -2
  26. data/lib/staypuft/version.rb +1 -1
  27. metadata +5 -7
  28. data/app/models/staypuft/service/ui_params.rb +0 -128
  29. data/app/views/staypuft/steps/_neutron_non_ha.html.erb +0 -41
  30. data/app/views/staypuft/steps/_nova_non_ha.html.erb +0 -29
@@ -12,11 +12,11 @@ module Staypuft
12
12
  NEW_NAME_PREFIX = 'uninitialized_'
13
13
 
14
14
  # supporting import/export
15
- EXPORT_PARAMS = [:amqp_provider, :networking, :layout_name, :platform]
15
+ EXPORT_PARAMS = [:amqp_provider, :networking, :platform]
16
16
  EXPORT_SERVICES = [:nova, :neutron, :glance, :cinder, :passwords, :ceph]
17
17
 
18
18
  attr_accessible :description, :name, :layout_id, :layout,
19
- :amqp_provider, :layout_name, :networking, :platform,
19
+ :amqp_provider, :networking, :platform,
20
20
  :custom_repos
21
21
  after_save :update_hostgroup_name
22
22
  after_validation :check_form_complete
@@ -83,7 +83,6 @@ module Staypuft
83
83
 
84
84
  def initialize(attributes = {}, options = {})
85
85
  super({ amqp_provider: AmqpProvider::RABBITMQ,
86
- layout_name: LayoutName::NON_HA,
87
86
  networking: Networking::NEUTRON,
88
87
  platform: Platform::RHEL7 }.merge(attributes),
89
88
  options)
@@ -96,8 +95,7 @@ module Staypuft
96
95
  self.cinder.set_defaults
97
96
  self.passwords.set_defaults
98
97
  self.ceph.set_defaults
99
- self.layout = Layout.where(:name => self.layout_name,
100
- :networking => self.networking).first
98
+ self.layout = Layout.where(:networking => self.networking).first
101
99
  end
102
100
 
103
101
  extend AttributeParamStorage
@@ -176,15 +174,6 @@ module Staypuft
176
174
  HUMAN = N_('Networking')
177
175
  end
178
176
 
179
- module LayoutName
180
- NON_HA = 'Controller / Compute'
181
- HA = 'High Availability Controllers / Compute'
182
- LABELS = { NON_HA => N_('Controller / Compute'),
183
- HA => N_('High Availability Controllers / Compute') }
184
- TYPES = LABELS.keys
185
- HUMAN = N_('High Availability')
186
- end
187
-
188
177
  module Platform
189
178
  RHEL7 = 'rhel7'
190
179
  RHEL6 = 'rhel6'
@@ -193,15 +182,14 @@ module Staypuft
193
182
  HUMAN = N_('Platform')
194
183
  end
195
184
 
196
- param_attr :amqp_provider, :networking, :layout_name, :platform
185
+ param_attr :amqp_provider, :networking, :platform
197
186
  validates :amqp_provider, :presence => true, :inclusion => { :in => AmqpProvider::TYPES }
198
187
  validates :networking, :presence => true, :inclusion => { :in => Networking::TYPES }
199
- validates :layout_name, presence: true, inclusion: { in: LayoutName::TYPES }
200
188
  validates :platform, presence: true, inclusion: { in: Platform::TYPES }
201
189
 
202
190
  class Jail < Safemode::Jail
203
- allow :amqp_provider, :networking, :layout_name, :platform, :nova_networking?, :neutron_networking?,
204
- :nova, :neutron, :glance, :cinder, :passwords, :ceph, :ha?, :non_ha?,
191
+ allow :amqp_provider, :networking, :platform, :nova_networking?, :neutron_networking?,
192
+ :nova, :neutron, :glance, :cinder, :passwords, :ceph,
205
193
  :hide_ceph_notification?, :network_query, :has_custom_repos?, :custom_repos_paths
206
194
  end
207
195
 
@@ -242,14 +230,6 @@ module Staypuft
242
230
  self.form_step.to_sym == Deployment::STEP_COMPLETE
243
231
  end
244
232
 
245
- def ha?
246
- self.layout_name == LayoutName::HA
247
- end
248
-
249
- def non_ha?
250
- self.layout_name == LayoutName::NON_HA
251
- end
252
-
253
233
  def nova_networking?
254
234
  networking == Networking::NOVA
255
235
  end
@@ -259,11 +239,7 @@ module Staypuft
259
239
  end
260
240
 
261
241
  def horizon_url
262
- if ha?
263
- "http://#{network_query.get_vip(:horizon_public_vip)}"
264
- else
265
- network_query.controller_ips(Staypuft::SubnetType::PUBLIC_API).empty? ? nil : "http://#{network_query.controller_ip(Staypuft::SubnetType::PUBLIC_API)}"
266
- end
242
+ "http://#{network_query.get_vip(:horizon_public_vip)}"
267
243
  end
268
244
 
269
245
  def controller_hostgroup
@@ -336,7 +312,7 @@ module Staypuft
336
312
  private
337
313
 
338
314
  def update_layout
339
- self.layout = Layout.where(:name => layout_name, :networking => networking).first
315
+ self.layout = Layout.where(:networking => networking).first
340
316
  end
341
317
 
342
318
  def update_based_on_settings
@@ -62,8 +62,7 @@ module Staypuft
62
62
  :multiple_backends?, :rbd_secret_uuid, :nfs_uri, :eqlxs, :eqlxs_attributes=,
63
63
  :compute_eqlx_san_ips, :compute_eqlx_san_logins, :compute_eqlx_san_passwords,
64
64
  :compute_eqlx_group_names, :compute_eqlx_pools, :compute_eqlx_thin_provision,
65
- :compute_eqlx_use_chap, :compute_eqlx_chap_logins, :compute_eqlx_chap_passwords,
66
- :compute_eqlx_backend_names
65
+ :compute_eqlx_use_chap, :compute_eqlx_chap_logins, :compute_eqlx_chap_passwords
67
66
  end
68
67
 
69
68
  def set_defaults
@@ -80,7 +79,7 @@ module Staypuft
80
79
  end
81
80
 
82
81
  def lvm_backend?
83
- !self.deployment.ha? && self.backend_lvm == "true"
82
+ self.backend_lvm == "true"
84
83
  end
85
84
 
86
85
  def nfs_backend?
@@ -100,16 +99,11 @@ module Staypuft
100
99
  BACKEND_TYPE_PARAMS.select { |type| send(type.to_s) == "true" }.length > 1
101
100
  end
102
101
 
103
- # view should use this rather than DriverBackend::LABELS to hide LVM for HA.
104
102
  def backend_labels_for_layout
105
- ret_list = DriverBackend::LABELS.clone
106
- ret_list.delete(DriverBackend::LVM) if self.deployment.ha?
107
- ret_list
103
+ DriverBackend::LABELS
108
104
  end
109
105
  def backend_types_for_layout
110
- ret_list = DriverBackend::TYPES.clone
111
- ret_list.delete(DriverBackend::LVM) if self.deployment.ha?
112
- ret_list
106
+ DriverBackend::TYPES
113
107
  end
114
108
 
115
109
  def param_hash
@@ -135,10 +129,6 @@ module Staypuft
135
129
  end
136
130
  end
137
131
 
138
- def compute_eqlx_backend_names
139
- self.eqlxs.collect.with_index { |e,i| "eqlx#{i+1}" }
140
- end
141
-
142
132
  private
143
133
 
144
134
  def set_lvm_ptable
@@ -157,9 +147,7 @@ module Staypuft
157
147
  end
158
148
 
159
149
  def at_least_one_backend_selected
160
- params = BACKEND_TYPE_PARAMS.clone
161
- params.delete :backend_lvm if self.deployment.ha?
162
- unless params.detect(lambda { false }) { |field| self.send(field) == "true" }
150
+ unless BACKEND_TYPE_PARAMS.detect(lambda { false }) { |field| self.send(field) == "true" }
163
151
  errors.add :base, _("At least one storage backend must be selected")
164
152
  end
165
153
  end
@@ -87,19 +87,12 @@ module Staypuft
87
87
  backend == BACKEND_FILE
88
88
  end
89
89
 
90
- # view should use this rather than DriverBackend::LABELS to hide LOCAL for HA.
91
90
  def backend_labels_for_layout
92
- ret_list = DriverBackend::LABELS.clone
93
- ret_list.delete(DriverBackend::LOCAL) if self.deployment.ha?
94
- ret_list.delete(DriverBackend::NFS) if self.deployment.non_ha?
95
- ret_list
91
+ DriverBackend::LABELS
96
92
  end
97
93
 
98
94
  def backend_types_for_layout
99
- ret_list = DriverBackend::TYPES.clone
100
- ret_list.delete(DriverBackend::LOCAL) if self.deployment.ha?
101
- ret_list.delete(DriverBackend::NFS) if self.deployment.non_ha?
102
- ret_list
95
+ DriverBackend::TYPES
103
96
  end
104
97
 
105
98
  def param_hash
@@ -9,7 +9,7 @@ module Staypuft
9
9
  ML2MECHANISM_TYPES = :ml2_openvswitch, :ml2_l2population, :ml2_cisco_nexus
10
10
  N1KV_PARAMS = :n1kv_vsm_ip, :n1kv_vsm_password
11
11
 
12
- param_attr :network_segmentation, :tenant_vlan_ranges, :core_plugin,
12
+ param_attr :network_segmentation, :tenant_vlan_ranges, :core_plugin, :network_device_mtu,
13
13
  *ML2MECHANISM_TYPES, *N1KV_PARAMS
14
14
  param_attr_array :nexuses => Cisconexus
15
15
 
@@ -85,6 +85,13 @@ module Staypuft
85
85
  :presence => true,
86
86
  :if => [:ml2_plugin?, :cisco_nexus_mechanism?]
87
87
 
88
+ module Mtu
89
+ HUMAN = N_('Tenant Network Device MTU')
90
+ HUMAN_AFTER = N_('(Optional) Only set this if changing the default')
91
+ end
92
+
93
+ validates :network_device_mtu, numericality: { only_integer: true }, allow_blank: true
94
+
88
95
  class Jail < Safemode::Jail
89
96
  allow :networker_vlan_ranges, :compute_vlan_ranges, :network_segmentation, :enable_tunneling?,
90
97
  :tenant_iface, :networker_ovs_bridge_mappings, :networker_ovs_bridge_uplinks,
@@ -92,7 +99,7 @@ module Staypuft
92
99
  :openvswitch_mechanism?, :l2population_mechanism?, :cisco_nexus_mechanism?,
93
100
  :ml2_mechanisms, :nexuses, :active?, :compute_cisco_nexus_config, :core_plugin,
94
101
  :ml2_plugin?, :n1kv_plugin?, :n1kv_vsm_ip, :n1kv_vsm_password,
95
- :core_plugin_module
102
+ :core_plugin_module, :network_device_mtu
96
103
  end
97
104
 
98
105
  def set_defaults
@@ -101,6 +108,7 @@ module Staypuft
101
108
  self.ml2_openvswitch = "true"
102
109
  self.ml2_l2population = "true"
103
110
  self.ml2_cisco_nexus = "false"
111
+ self.network_device_mtu = nil
104
112
  end
105
113
 
106
114
  def active?
@@ -6,7 +6,8 @@ module Staypuft
6
6
 
7
7
  VLAN_HELP = Deployment::NeutronService::VLAN_HELP
8
8
 
9
- param_attr :network_manager, :vlan_range, :public_floating_range, :private_fixed_range
9
+ param_attr :network_manager, :vlan_range, :public_floating_range, :private_fixed_range,
10
+ :network_device_mtu
10
11
 
11
12
  class NetworkRangesValidator < ActiveModel::Validator
12
13
  def validate(record)
@@ -90,8 +91,16 @@ module Staypuft
90
91
 
91
92
  validates :private_fixed_range, presence: true
92
93
 
94
+ module Mtu
95
+ HUMAN = Staypuft::Deployment::NeutronService::Mtu::HUMAN
96
+ HUMAN_AFTER = Staypuft::Deployment::NeutronService::Mtu::HUMAN_AFTER
97
+ end
98
+
99
+ validates :network_device_mtu, numericality: { only_integer: true }, allow_blank: true
100
+
93
101
  def set_defaults
94
102
  self.network_manager = NetworkManager::FLAT_DHCP
103
+ self.network_device_mtu = nil
95
104
  end
96
105
 
97
106
  def active?
@@ -164,7 +173,7 @@ module Staypuft
164
173
 
165
174
  class Jail < Safemode::Jail
166
175
  allow :network_manager, :network_overrides, :private_fixed_range, :public_floating_range,
167
- :num_networks, :network_size
176
+ :num_networks, :network_size, :network_device_mtu
168
177
  end
169
178
 
170
179
  end
@@ -2,10 +2,10 @@ module Staypuft
2
2
  class Deployment::Passwords < Deployment::AbstractParamScope
3
3
 
4
4
  USER_SERVICES_PASSWORDS = :admin, :ceilometer_user, :cinder_user, :glance_user, :heat_user,
5
- :heat_cfn_user, :keystone_user, :neutron_user, :nova_user, :swift_user, :swift_admin, :amqp
5
+ :heat_cfn_user, :keystone_user, :neutron_user, :nova_user, :swift_user, :amqp
6
6
 
7
7
  DB_SERVICES_PASSWORDS = :cinder_db, :glance_db, :heat_db, :mysql_root, :keystone_db,
8
- :neutron_db, :nova_db, :amqp_nssdb
8
+ :neutron_db, :nova_db
9
9
 
10
10
  OTHER_PASSWORDS = :keystone_admin_token, :ceilometer_metering_secret, :heat_auth_encrypt_key,
11
11
  :horizon_secret_key, :swift_shared_secret, :neutron_metadata_proxy_secret
@@ -14,26 +14,7 @@ module Staypuft
14
14
  def ui_params_for_form(hostgroup)
15
15
  return [] if (hostgroup.nil?)
16
16
  role = hostgroup.role
17
- if hostgroup.puppetclasses.blank?
18
- params_from_hash = []
19
- else
20
- puppetclass = hostgroup.puppetclasses.first
21
- params_from_hash = UI_PARAMS.fetch(self.name, []).collect do |param_key|
22
- if param_key.is_a?(Array)
23
- param_name = param_key[0]
24
- param_puppetclass = Puppetclass.find_by_name(param_key[1])
25
- else
26
- param_name = param_key
27
- param_puppetclass = puppetclass
28
- end
29
- param_lookup_key = param_puppetclass.class_params.where(:key => param_key).first
30
- param_lookup_key.nil? ? nil : { :hostgroup => hostgroup,
31
- :role => role,
32
- :puppetclass => param_puppetclass,
33
- :param_key => param_lookup_key }
34
- end.compact
35
- end
36
- params_from_service = self.puppetclasses.collect do |pclass|
17
+ self.puppetclasses.collect do |pclass|
37
18
  pclass.class_params.collect do |class_param|
38
19
  { :hostgroup => hostgroup,
39
20
  :role => role,
@@ -41,7 +22,6 @@ module Staypuft
41
22
  :param_key => class_param }
42
23
  end
43
24
  end.flatten
44
- params_from_hash + params_from_service
45
25
  end
46
26
  end
47
27
  end
@@ -11,25 +11,14 @@
11
11
  <div class="modal-body" style="max-height: 600px; overflow: auto;">
12
12
  <div class="row">
13
13
  <div class="col-sm-12">
14
- <h4><%= @deployment.ha? ? _("VIP list") : _("Controller IPs") %></h4>
15
- <% if @deployment.ha? %>
16
- <% Staypuft::NetworkQuery::VIP_NAMES.keys.each do | vip_name | %>
17
- <div class="row">
18
- <label class="col-sm-4 control-label text-muted"><%= "#{vip_name}:" %></label>
19
- <div class="col-sm-8">
20
- <p class="form-control-static"><%= @deployment.network_query.get_vip(vip_name) %></p>
21
- </div>
22
- </div>
23
- <% end %>
24
- <% else %>
25
- <% [Staypuft::SubnetType::PUBLIC_API, Staypuft::SubnetType::MANAGEMENT, Staypuft::SubnetType::ADMIN_API].each do |subnet_type| %>
26
- <div class="row">
27
- <label class="col-sm-4 control-label text-muted"><%= "#{subnet_type}:" %></label>
28
- <div class="col-sm-8">
29
- <p class="form-control-static"><%= @deployment.network_query.controller_ips(subnet_type).first %></p>
30
- </div>
14
+ <h4><%= _("VIP list") %></h4>
15
+ <% Staypuft::NetworkQuery::VIP_NAMES.keys.each do | vip_name | %>
16
+ <div class="row">
17
+ <label class="col-sm-4 control-label text-muted"><%= "#{vip_name}:" %></label>
18
+ <div class="col-sm-8">
19
+ <p class="form-control-static"><%= @deployment.network_query.get_vip(vip_name) %></p>
31
20
  </div>
32
- <% end %>
21
+ </div>
33
22
  <% end %>
34
23
  </div>
35
24
  </div>
@@ -4,7 +4,7 @@
4
4
 
5
5
  <% sub_nav = [ {:title => "#{_('Deployed')} (#{deployed_hosts.count})", :target_id => '#deployed-hosts', :class => "inner-nav", :active => true},
6
6
  {:title => "#{_('Assigned')} (#{assigned_hosts.count})", :target_id => '#assigned-hosts', :class => "inner-nav"},
7
- {:title => "#{_('Free')} (#{free_hosts.count})", :target_id => '#free-hosts', :class => "inner-nav"} ] %>
7
+ {:title => "#{_('Unassigned')} (#{free_hosts.count})", :target_id => '#free-hosts', :class => "inner-nav"} ] %>
8
8
 
9
9
  <%= tabbed_nav_menu(sub_nav, 'hosts-navigation', 'nav nav-tabs inner-nav', 'sub-tab') %>
10
10
 
@@ -1,10 +1,7 @@
1
1
  <% title(@deployment.name,
2
2
  edit_textfield(@deployment,
3
3
  :name,
4
- options={ :update_url => deployment_path(@deployment) }) +
5
- content_tag(:small,
6
- @deployment.ha? ? _("with High Availability") : _("without High Availability"),
7
- :class => "text-muted")) %>
4
+ options={ :update_url => deployment_path(@deployment) }) ) %>
8
5
 
9
6
  <% content_for(:top_actions) do %>
10
7
  <%= link_to(_("Deploy"),
@@ -1,5 +1,5 @@
1
1
  <% if hosts.exists? %>
2
- <h4 class="pull-left"><%= _("Free Hosts") %></h4>
2
+ <h4 class="pull-left"><%= _("Unassigned Hosts") %></h4>
3
3
  <div class="" id="table_free_hosts">
4
4
  <%= form_tag(associate_host_deployment_path(id: @deployment), class: 'form-horizontal association') do |f| %>
5
5
  <div class="pull-right top_actions">
@@ -44,7 +44,7 @@
44
44
  </div>
45
45
  <% else %>
46
46
  <div class="association">
47
- <h4><%= _("Free Hosts") %></h4>
47
+ <h4><%= _("Unassigned Hosts") %></h4>
48
48
  <div class="alert alert-warning">
49
49
  <span class="glyphicon glyphicon-warning-sign">&nbsp;</span>
50
50
  <%= _("All available hosts have been already assigned.") %>
@@ -2,7 +2,7 @@
2
2
  <% if hosts.present? %>
3
3
  <%= form_tag(associate_host_deployment_path(id: deployment), class: 'form-horizontal well association') do |f| %>
4
4
 
5
- <%= render 'hosts_header', :header => _("Free Hosts"), :child_hostgroup => child_hostgroup, :assign_text => _("Assign Hosts") %>
5
+ <%= render 'hosts_header', :header => _("Unassigned Hosts"), :child_hostgroup => child_hostgroup, :assign_text => _("Assign Hosts") %>
6
6
 
7
7
  <table class="table table-bordered table-striped table-condensed">
8
8
  <thead>
@@ -19,6 +19,6 @@
19
19
 
20
20
  <% end %>
21
21
  <% else %>
22
- <%= render 'empty_hosts', :header => _("Free Hosts"), :message => _("All available hosts have been already assigned.") %>
22
+ <%= render 'empty_hosts', :header => _("Unassigned Hosts"), :message => _("All available hosts have been already assigned.") %>
23
23
  <% end %>
24
24
  </div>
@@ -0,0 +1,40 @@
1
+ <div class="row">
2
+ <div class="col-md-12">
3
+ <h3 data-toggle="collapse" data-target="#hosts_to_configure"><%= @hosts.count %> <%= "#{n_('Host', 'Hosts', @hosts.count)} #{_('to be configured')}" %> <span class="small glyphicon glyphicon-chevron-down"></span></h3>
4
+ <div id="hosts_to_configure" class="collapse">
5
+ <table class="table table-striped table-condensed">
6
+ <thead>
7
+ <tr>
8
+ <th><%= sort :name, :as => _('Host Name') %></th>
9
+ <th><%= @host.primary_interface %></th>
10
+ <% @interfaces.each do |interface| %>
11
+ <th><%= interface.identifier %></th>
12
+ <% end %>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <% @hosts.each do |host| %>
17
+ <tr>
18
+ <td class="ellipsis">
19
+ <%= host_label(host) %>
20
+ </td>
21
+ <td>
22
+ <%= host.mac %><br/>
23
+ <%= host.ip %>
24
+ </td>
25
+ <% if host.interfaces.present? %>
26
+ <% @interfaces.each do |iface| %>
27
+ <% interface = host.interfaces.where(identifier: iface.identifier).first %>
28
+ <td>
29
+ <%= interface.mac %><br/>
30
+ <%= interface.ip %>
31
+ </td>
32
+ <% end %>
33
+ <% end %>
34
+ </tr>
35
+ <% end %>
36
+ </tbody>
37
+ </table>
38
+ </div>
39
+ </div>
40
+ </div>
@@ -5,46 +5,12 @@
5
5
 
6
6
  <% title _("Configure Interfaces (%s hosts)") % @hosts.size %>
7
7
 
8
- <div class="row">
9
- <div class="col-md-12">
10
- <h3 data-toggle="collapse" data-target="#hosts_to_configure"><%= @hosts.count %> <%= "#{n_('Host', 'Hosts', @hosts.count)} #{_('to be configured')}" %> <span class="small glyphicon glyphicon-chevron-down"></span></h3>
11
- <div id="hosts_to_configure" class="collapse">
12
- <table class="table table-striped table-condensed">
13
- <thead>
14
- <tr>
15
- <th><%= sort :name, :as => _('Host Name') %></th>
16
- <th><%= @host.primary_interface %></th>
17
- <% @interfaces.each do |interface| %>
18
- <th><%= interface.identifier %></th>
19
- <% end %>
20
- </tr>
21
- </thead>
22
- <tbody>
23
- <% @hosts.each do |host| %>
24
- <tr>
25
- <td class="ellipsis">
26
- <%= host_label(host) %>
27
- </td>
28
- <td>
29
- <%= host.mac %><br/>
30
- <%= host.ip %>
31
- </td>
32
- <% if host.interfaces.present? %>
33
- <td>
34
- <% host.interfaces.each do |interface| %>
35
- <%= interface.mac %><br/>
36
- <%= interface.ip %>
37
- <% end %>
38
- </td>
39
- <% end %>
40
- </tr>
41
- <% end %>
42
- </tbody>
43
- </table>
44
- </div>
45
- </div>
8
+ <div id="nics_assignment_overview">
9
+ <%= render 'staypuft/interface_assignments/nics_assignment_overview',
10
+ :host => @host,
11
+ :hosts => @hosts,
12
+ :interfaces => @interfaces %>
46
13
  </div>
47
-
48
14
  <div id="nics_assignment">
49
15
  <%= render 'staypuft/interface_assignments/nics_assignment',
50
16
  :host => @host,