staypuft 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/staypuft/nics_assignment.js +5 -5
  3. data/app/assets/javascripts/staypuft/staypuft.js +58 -5
  4. data/app/assets/javascripts/staypuft/subnets_assignment.js +5 -4
  5. data/app/assets/stylesheets/staypuft/bootstrap_and_overrides.css.scss +16 -0
  6. data/app/assets/stylesheets/staypuft/staypuft.css.scss +30 -71
  7. data/app/controllers/staypuft/deployments_controller.rb +23 -0
  8. data/app/controllers/staypuft/interface_assignments_controller.rb +2 -1
  9. data/app/lib/staypuft/network_query.rb +88 -5
  10. data/app/lib/staypuft/seeder.rb +75 -71
  11. data/app/models/staypuft/concerns/host_interface_management.rb +25 -2
  12. data/app/models/staypuft/concerns/subnet_ip_management.rb +17 -0
  13. data/app/models/staypuft/concerns/vip_nic_scopes.rb +13 -0
  14. data/app/models/staypuft/deployment/attribute_param_storage.rb +59 -1
  15. data/app/models/staypuft/deployment/cinder_service/equallogic.rb +80 -0
  16. data/app/models/staypuft/deployment/cinder_service.rb +53 -94
  17. data/app/models/staypuft/deployment/neutron_service.rb +20 -83
  18. data/app/models/staypuft/deployment/nova_service.rb +2 -31
  19. data/app/models/staypuft/deployment.rb +9 -7
  20. data/app/models/staypuft/subnet_type.rb +4 -0
  21. data/app/views/staypuft/deployments/_assigned_hosts.html.erb +23 -4
  22. data/app/views/staypuft/deployments/_deployment_access_all_details_dialogue.html.erb +5 -5
  23. data/app/views/staypuft/deployments/_deployment_hosts.html.erb +1 -1
  24. data/app/views/staypuft/deployments/_free_hosts.html.erb +4 -4
  25. data/app/views/staypuft/interface_assignments/index.html.erb +36 -31
  26. data/app/views/staypuft/interfaces/_drop_zone.html.erb +22 -22
  27. data/app/views/staypuft/steps/_cinder.html.erb +48 -26
  28. data/app/views/staypuft/steps/_cinder_equallogic_form.html.erb +13 -0
  29. data/app/views/staypuft/steps/_neutron.html.erb +0 -28
  30. data/app/views/staypuft/steps/_nova.html.erb +0 -11
  31. data/app/views/staypuft/steps/network_configuration.html.erb +27 -19
  32. data/app/views/staypuft/steps/services_configuration.html.erb +1 -1
  33. data/app/views/staypuft/subnet_typings/destroy.js.erb +1 -1
  34. data/app/views/staypuft/subnets/_drop_zone.html.erb +5 -5
  35. data/app/views/staypuft/subnets/_subnet_pull.html.erb +3 -4
  36. data/lib/staypuft/engine.rb +2 -0
  37. data/lib/staypuft/version.rb +1 -1
  38. metadata +6 -4
  39. data/app/models/staypuft/deployment/ips.rb +0 -25
  40. data/app/models/staypuft/deployment/vips.rb +0 -40
@@ -5,35 +5,13 @@ module Staypuft
5
5
  'cinder'
6
6
  end
7
7
 
8
- param_attr :driver_backend, :nfs_uri, :rbd_secret_uuid,
9
- :san_ip, :san_login, :san_password, :eqlx_group_name, :eqlx_pool
10
- after_save :set_lvm_ptable
8
+ BACKEND_TYPE_PARAMS = :backend_eqlx, :backend_nfs, :backend_lvm, :backend_ceph
9
+ BACKEND_PARAMS = :nfs_uri, :rbd_secret_uuid
11
10
 
12
- class SanIpValueValidator < ActiveModel::EachValidator
13
- def validate_each(record, attribute, value)
14
- return if value.empty?
15
-
16
- begin
17
- ip_addr = IPAddr.new(value)
18
- ip_range = ip_addr.to_range
19
- if ip_range.begin == ip_range.end
20
- true
21
- else
22
- record.errors.add attribute, "Specify single IP address, not range"
23
- false
24
- end
25
- rescue
26
- # not IP addr
27
- # validating as fqdn
28
- if /(?=^.{1,254}$)(^(((?!-)[a-zA-Z0-9-]{1,63}(?<!-))|((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63})$)/ =~ value
29
- true
30
- else
31
- record.errors.add attribute, "Invalid IP address or FQDN supplied"
32
- false
33
- end
34
- end
35
- end
36
- end
11
+ param_attr *BACKEND_TYPE_PARAMS, *BACKEND_PARAMS
12
+ param_attr_array :eqlxs => Equallogic
13
+
14
+ after_save :set_lvm_ptable
37
15
 
38
16
  module DriverBackend
39
17
  LVM = 'lvm'
@@ -47,7 +25,7 @@ module Staypuft
47
25
  TYPES = LABELS.keys
48
26
  HUMAN = N_('Choose Driver Backend')
49
27
  end
50
- validates :driver_backend, presence: true, inclusion: { in: lambda { |c| c.backend_types_for_layout } }
28
+ validate :at_least_one_backend_selected
51
29
 
52
30
  module NfsUri
53
31
  HUMAN = N_('NFS URI:')
@@ -61,81 +39,36 @@ module Staypuft
61
39
  module SanIp
62
40
  HUMAN = N_('SAN IP Addr:')
63
41
  end
64
- validates :san_ip,
65
- :presence => true,
66
- :if => :equallogic_backend?,
67
- :san_ip_value => true
68
- # FIXME: Currently this only validates IP addresses, however hostnames are valid here
69
- # too. In the absence of "IP or hostname" validation, is forcing IP only better than
70
- # no validation, or should we disable this until it works for all valid values?
71
-
72
42
  module SanLogin
73
43
  HUMAN = N_('SAN Login:')
74
44
  end
75
- # Up to 16 alphanumeric characters, including period, hyphen, and underscore.
76
- # First character must be a letter or number. Last character cannot be a period.
77
- # ASCII, Not Unicode
78
- validates :san_login,
79
- :presence => true,
80
- :format => /\A[a-zA-Z\d][\w\.\-]*[\w\-]\z/,
81
- :length => { maximum: 16 },
82
- :if => :equallogic_backend?
83
-
84
45
  module SanPassword
85
46
  HUMAN = N_('SAN Password:')
86
47
  end
87
- # Password must be 3 to 16 printable ASCII characters and is case-sensitive.
88
- # Punctuation characters are allowed, but spaces are not.
89
- # Only the first 8 characters are used, the rest are ignored (without a message).
90
- # ASCII, Not Unicode
91
- validates :san_password,
92
- :presence => true,
93
- :format => /\A[!-~]+\z/,
94
- :length => { minimum:3, maximum: 16 },
95
- :if => :equallogic_backend?
96
-
97
48
  module EqlxPool
98
49
  HUMAN = N_('Pool:')
99
50
  end
100
- # Name can be up to 63 bytes and is case insensitive.
101
- # You can use any printable Unicode character except for
102
- # ! " # $ % & ' ( ) * + , / ; < = > ?@ [ \ ] ^ _ ` { | } ~.
103
- # First and last characters cannot be a period, hyphen, or colon.
104
- # Fewer characters are accepted for this field if you enter the value as a
105
- # Unicode character string, which takes up a variable number of bytes,
106
- # depending on the specific character.
107
- # ASCII, Unicode
108
- validates :eqlx_pool,
109
- :presence => true,
110
- :format => /\A[[^\p{Z}\p{C}!"\#$%&'\(\)\*\+,\/;<=>\?@\[\]\\\^\{\}|~\.\-:]][[^\p{Z}\p{C}!"\#$%&'\(\)\*\+,\/;<=>\?@\[\]\\\^\{\}|~]]+[[^\p{Z}\p{C}!"\#$%&'\(\)\*\+,\/;<=>\?@\[\]\\\^\{\}|~\.\-:]]\z/,
111
- :length => { maximum: 63,
112
- too_long: "Too long: max length is %{count} bytes. Using multibyte characters reduces the maximum number of characters allowed.",
113
- tokenizer: lambda {|str| str.bytes.to_a } },
114
- :if => :equallogic_backend?
115
-
116
51
  module EqlxGroupName
117
52
  HUMAN = N_('Group:')
118
53
  end
119
- # Up to 54 alphanumeric characters and hyphens(dashes).
120
- # The first character must be a letter or a number.
121
- # ASCII, Not Unicode
122
- validates :eqlx_group_name,
123
- :presence => true,
124
- :format => /\A[a-zA-Z\d][a-zA-Z\d\-]*\z/,
125
- :length => { maximum: 54 },
126
- :if => :equallogic_backend?
54
+ validates :eqlxs,
55
+ :presence => true,
56
+ :if => :equallogic_backend?
57
+ validate :equallogic_backends
127
58
 
128
59
  class Jail < Safemode::Jail
129
- allow :lvm_backend?, :nfs_backend?, :nfs_uri, :ceph_backend?, :equallogic_backend?,
130
- :rbd_secret_uuid, :san_ip, :san_login, :san_password, :eqlx_group_name, :eqlx_pool
60
+ allow :lvm_backend?, :nfs_backend?, :ceph_backend?, :equallogic_backend?,
61
+ :multiple_backends?, :rbd_secret_uuid, :nfs_uri, :eqlxs, :eqlxs_attributes=,
62
+ :compute_eqlx_san_ips, :compute_eqlx_san_logins, :compute_eqlx_san_passwords,
63
+ :compute_eqlx_group_names, :compute_eqlx_pools
131
64
  end
132
65
 
133
66
  def set_defaults
134
- self.driver_backend = DriverBackend::LVM
67
+ self.backend_lvm = "false"
68
+ self.backend_ceph = "false"
69
+ self.backend_nfs = "false"
70
+ self.backend_eqlx = "false"
135
71
  self.rbd_secret_uuid = SecureRandom.uuid
136
- self.san_login = 'grpadmin'
137
- self.eqlx_pool = 'default'
138
- self.eqlx_group_name = 'group-0'
139
72
  end
140
73
 
141
74
  # cinder config always shows up
@@ -144,21 +77,25 @@ module Staypuft
144
77
  end
145
78
 
146
79
  def lvm_backend?
147
- !self.deployment.ha? && (self.driver_backend == DriverBackend::LVM)
80
+ !self.deployment.ha? && self.backend_lvm == "true"
148
81
  end
149
82
 
150
83
  def nfs_backend?
151
- self.driver_backend == DriverBackend::NFS
84
+ self.backend_nfs == "true"
152
85
  end
153
86
 
154
87
  def ceph_backend?
155
- self.driver_backend == DriverBackend::CEPH
88
+ self.backend_ceph == "true"
156
89
  end
157
90
 
158
91
  def equallogic_backend?
159
- self.driver_backend == DriverBackend::EQUALLOGIC
92
+ self.backend_eqlx == "true"
160
93
  end
161
94
 
95
+ def multiple_backends?
96
+ (equallogic_backend? and self.eqlxs.length > 1) or
97
+ BACKEND_TYPE_PARAMS.select { |type| send(type.to_s) == "true" }.length > 1
98
+ end
162
99
 
163
100
  # view should use this rather than DriverBackend::LABELS to hide LVM for HA.
164
101
  def backend_labels_for_layout
@@ -173,16 +110,22 @@ module Staypuft
173
110
  end
174
111
 
175
112
  def param_hash
176
- { "driver_backend" => driver_backend, "nfs_uri" => nfs_uri,
177
- "rbd_secret_uuid" => rbd_secret_uuid,
178
- "san_ip" => san_ip, "san_login" => san_login, "san_password" => san_password,
179
- "eqlx_group_name" => eqlx_group_name, "eqlx_pool" => eqlx_pool }
113
+ { "backend_lvm" => backend_lvm, "backend_ceph" => backend_ceph,
114
+ "backend_nfs" => backend_nfs, "backend_eqlx" => backend_eqlx,
115
+ "nfs_uri" => nfs_uri, "rbd_secret_uuid" => rbd_secret_uuid,
116
+ "eqlxs" => self.eqlxs }
180
117
  end
181
118
 
182
119
  def lvm_ptable
183
120
  Ptable.find_by_name('LVM with cinder-volumes')
184
121
  end
185
122
 
123
+ %w{san_ip san_login san_password group_name pool}.each do |name|
124
+ define_method "compute_eqlx_#{name}s" do
125
+ self.eqlxs.collect { |e| e.send name }
126
+ end
127
+ end
128
+
186
129
  private
187
130
 
188
131
  def set_lvm_ptable
@@ -199,5 +142,21 @@ module Staypuft
199
142
  hostgroup.save!
200
143
  end
201
144
  end
145
+
146
+ def at_least_one_backend_selected
147
+ params = BACKEND_TYPE_PARAMS.clone
148
+ if self.deployment.ha?
149
+ params.delete :backend_lvm
150
+ end
151
+ unless params.detect(lambda { false }) { |field| field }
152
+ errors[:base] << _("At least one storage backend must be selected")
153
+ end
154
+ end
155
+
156
+ def equallogic_backends
157
+ unless self.eqlxs.all? { |item| item.valid? }
158
+ errors[:base] << _("Please fix the problems in selected backends")
159
+ end
160
+ end
202
161
  end
203
162
  end
@@ -5,12 +5,9 @@ module Staypuft
5
5
  end
6
6
 
7
7
  SEGMENTATION_LIST = ['vxlan', 'vlan', 'gre', 'flat']
8
- INTERFACE_HELP = N_('(e.g. eth0 or em1)')
9
8
  VLAN_HELP = N_('[1-4094] (e.g. 10:15)')
10
9
 
11
-
12
- param_attr :network_segmentation, :tenant_vlan_ranges, :networker_tenant_interface,
13
- :use_external_interface, :external_interface_name, :compute_tenant_interface
10
+ param_attr :network_segmentation, :tenant_vlan_ranges
14
11
 
15
12
  module NetworkSegmentation
16
13
  VXLAN = 'vxlan'
@@ -41,129 +38,69 @@ module Staypuft
41
38
  :if => :vlan_segmentation?,
42
39
  :neutron_vlan_ranges => true
43
40
 
44
- module NetworkerTenantInterface
45
- HUMAN = N_('Which interface to use for tenant networks')
46
- HUMAN_AFTER = INTERFACE_HELP
47
- end
48
-
49
- validates :networker_tenant_interface,
50
- :presence => true
51
- # TODO: interface name format validation
52
-
53
- module UseExternalInterface
54
- HUMAN = N_('Configure external interface on network node')
55
- end
56
-
57
- validates :use_external_interface, inclusion: { in: [true, false, 'true', 'false'] }
58
-
59
- module ExternalInterfaceName
60
- HUMAN = N_('External interface connected to')
61
- HUMAN_AFTER = INTERFACE_HELP
62
- end
63
-
64
- validates :external_interface_name,
65
- :presence => true,
66
- :if => :use_external_interface?
67
- # TODO: interface name format validation
68
-
69
- module ComputeTenantInterface
70
- HUMAN = N_('Which interface to use for tenant networks')
71
- HUMAN_AFTER = INTERFACE_HELP
72
- end
73
-
74
- validates :compute_tenant_interface,
75
- :presence => true
76
- # TODO: interface name format validation
77
-
78
41
  class Jail < Safemode::Jail
79
42
  allow :networker_vlan_ranges, :compute_vlan_ranges, :network_segmentation, :enable_tunneling?,
80
- :networker_tenant_iface, :networker_ovs_bridge_mappings, :networker_ovs_bridge_uplinks,
81
- :compute_tenant_iface, :compute_ovs_bridge_mappings, :compute_ovs_bridge_uplinks
43
+ :tenant_iface, :networker_ovs_bridge_mappings, :networker_ovs_bridge_uplinks,
44
+ :compute_ovs_bridge_mappings, :compute_ovs_bridge_uplinks
82
45
  end
83
46
 
84
47
  def set_defaults
85
48
  self.network_segmentation = NetworkSegmentation::VXLAN
86
- self.use_external_interface = 'false'
87
49
  end
88
50
 
89
51
  def active?
90
52
  deployment.networking == Deployment::Networking::NEUTRON
91
53
  end
92
54
 
93
- # TODO: make this less clumsy w/ consistent handling of true/false values
94
- def use_external_interface?
95
- (self.use_external_interface == true) || (self.use_external_interface == 'true')
96
- end
97
-
98
55
  # return list of supported segmentation options with selected option at the
99
56
  # beginning of the list
100
57
  def network_segmentation_list
101
- [self.network_segmentation, *(SEGMENTATION_LIST - [self.network_segmentation])]
58
+ [network_segmentation, *(SEGMENTATION_LIST - [network_segmentation])]
102
59
  end
103
60
 
104
- def networker_ovs_bridge_mappings
105
- [("physnet-tenants:br-#{self.networker_tenant_iface}" unless self.enable_tunneling?),
106
- ('physnet-external:br-ex' if self.use_external_interface?)].compact
61
+ def networker_ovs_bridge_mappings(host)
62
+ compute_ovs_bridge_mappings(host) + [*('physnet-external:br-ex' if external_interface_name(host))]
107
63
  end
108
64
 
109
- def networker_ovs_bridge_uplinks
110
- [("br-#{self.networker_tenant_iface}:#{self.networker_tenant_iface}" unless self.enable_tunneling?),
111
- ("br-ex:#{self.external_interface_name.downcase}" if self.use_external_interface?)
112
- ].compact
65
+ def networker_ovs_bridge_uplinks(host)
66
+ compute_ovs_bridge_uplinks(host) + [*("br-ex:#{external_interface_name(host)}" if external_interface_name(host))]
113
67
  end
114
68
 
115
- def compute_ovs_bridge_mappings
116
- if !self.enable_tunneling?
117
- ["physnet-tenants:br-#{self.compute_tenant_iface}"]
118
- else
119
- []
120
- end
69
+ def compute_ovs_bridge_mappings(host)
70
+ [*("physnet-tenants:br-#{tenant_iface(host)}" if !enable_tunneling?)]
121
71
  end
122
72
 
123
- def compute_ovs_bridge_uplinks
124
- if !self.enable_tunneling?
125
- ["br-#{self.compute_tenant_iface}:#{self.compute_tenant_iface}"]
126
- else
127
- []
128
- end
73
+ def compute_ovs_bridge_uplinks(host)
74
+ [*("br-#{tenant_iface(host)}:#{tenant_iface(host)}" if !enable_tunneling?)]
129
75
  end
130
76
 
131
77
  def compute_vlan_ranges
132
- if self.vlan_segmentation?
133
- ["physnet-tenants:#{self.tenant_vlan_ranges}"]
134
- else
135
- []
136
- end
78
+ [*("physnet-tenants:#{tenant_vlan_ranges}" if vlan_segmentation?)]
137
79
  end
138
80
 
139
81
  def networker_vlan_ranges
140
- [("physnet-tenants:#{self.tenant_vlan_ranges}" if self.vlan_segmentation?),
141
- "physnet-external"].compact
82
+ compute_vlan_ranges << "physnet-external"
142
83
  end
143
84
 
144
85
  def vlan_segmentation?
145
- self.network_segmentation == NetworkSegmentation::VLAN
86
+ network_segmentation == NetworkSegmentation::VLAN
146
87
  end
147
88
 
148
89
  def enable_tunneling?
149
90
  [NetworkSegmentation::VXLAN, NetworkSegmentation::GRE].include?(network_segmentation)
150
91
  end
151
92
 
152
- def networker_tenant_iface
153
- networker_tenant_interface.downcase unless networker_tenant_interface.nil?
93
+ def tenant_iface(host)
94
+ deployment.network_query.interface_for_host(host, Staypuft::SubnetType::TENANT)
154
95
  end
155
96
 
156
- def compute_tenant_iface
157
- compute_tenant_interface.downcase unless compute_tenant_interface.nil?
97
+ def external_interface_name(host)
98
+ deployment.network_query.interface_for_host(host, Staypuft::SubnetType::EXTERNAL)
158
99
  end
159
100
 
160
101
  def param_hash
161
102
  { 'network_segmentation' => network_segmentation,
162
- 'tenant_vlan_ranges' => tenant_vlan_ranges,
163
- 'networker_tenant_interface' => networker_tenant_interface,
164
- 'use_external_interface' => use_external_interface,
165
- 'external_interface_name' => external_interface_name,
166
- 'compute_tenant_interface' => compute_tenant_interface }
103
+ 'tenant_vlan_ranges' => tenant_vlan_ranges }
167
104
  end
168
105
 
169
106
  end
@@ -4,11 +4,9 @@ module Staypuft
4
4
  'nova'
5
5
  end
6
6
 
7
- INTERFACE_HELP = Deployment::NeutronService::INTERFACE_HELP
8
7
  VLAN_HELP = Deployment::NeutronService::VLAN_HELP
9
8
 
10
- param_attr :network_manager, :vlan_range, :external_interface_name, :public_floating_range,
11
- :compute_tenant_interface, :private_fixed_range
9
+ param_attr :network_manager, :vlan_range, :public_floating_range, :private_fixed_range
12
10
 
13
11
  class NetworkRangesValidator < ActiveModel::Validator
14
12
  def validate(record)
@@ -73,14 +71,6 @@ module Staypuft
73
71
  :if => :vlan_manager?,
74
72
  :nova_vlan_range => true
75
73
 
76
- module ExternalInterfaceName
77
- HUMAN = N_('Which interface to use for external networks')
78
- HUMAN_AFTER = INTERFACE_HELP
79
- end
80
-
81
- validates :external_interface_name, presence: true
82
- # TODO: interface name format validation
83
-
84
74
  module PublicFloatingRange
85
75
  HUMAN = N_('Floating IP range for external network')
86
76
  HUMAN_AFTER = N_('(e.g. "10.0.0.0/24")')
@@ -88,15 +78,6 @@ module Staypuft
88
78
 
89
79
  validates :public_floating_range, presence: true
90
80
 
91
- module ComputeTenantInterface
92
- HUMAN = N_('Which interface to use for tenant networks')
93
- HUMAN_AFTER = INTERFACE_HELP
94
- end
95
-
96
- validates :compute_tenant_interface,
97
- :presence => true
98
- # TODO: interface name format validation
99
-
100
81
  module PrivateFixedRange
101
82
  HUMAN = N_('Fixed IP range for tenant networks')
102
83
  HUMAN_AFTER = PublicFloatingRange::HUMAN_AFTER
@@ -138,26 +119,16 @@ module Staypuft
138
119
  end
139
120
  end
140
121
 
141
- def private_iface
142
- compute_tenant_interface.downcase unless compute_tenant_interface.nil?
143
- end
144
-
145
- def public_iface
146
- external_interface_name.downcase unless external_interface_name.nil?
147
- end
148
-
149
122
  def param_hash
150
123
  { 'network_manager' => network_manager,
151
124
  'vlan_range' => vlan_range,
152
- 'external_interface_name' => external_interface_name,
153
125
  'public_floating_range' => public_floating_range,
154
- 'compute_tenant_interface' => compute_tenant_interface,
155
126
  'private_fixed_range' => private_fixed_range }
156
127
  end
157
128
 
158
129
  class Jail < Safemode::Jail
159
130
  allow :network_manager, :network_overrides, :private_fixed_range, :public_floating_range,
160
- :private_iface, :public_iface, :num_networks
131
+ :num_networks
161
132
  end
162
133
 
163
134
  end
@@ -60,9 +60,7 @@ module Staypuft
60
60
  [:neutron, :@neutron_service, NeutronService],
61
61
  [:glance, :@glance_service, GlanceService],
62
62
  [:cinder, :@cinder_service, CinderService],
63
- [:passwords, :@passwords, Passwords],
64
- [:vips, :@vips, VIPS],
65
- [:ips, :@ips, IPS]]
63
+ [:passwords, :@passwords, Passwords]]
66
64
 
67
65
  SCOPES.each do |name, ivar, scope_class|
68
66
  define_method name do
@@ -197,8 +195,8 @@ module Staypuft
197
195
 
198
196
  class Jail < Safemode::Jail
199
197
  allow :amqp_provider, :networking, :layout_name, :platform, :nova_networking?, :neutron_networking?,
200
- :nova, :neutron, :glance, :cinder, :passwords, :vips, :ips, :ha?, :non_ha?,
201
- :hide_ceph_notification?
198
+ :nova, :neutron, :glance, :cinder, :passwords, :ha?, :non_ha?,
199
+ :hide_ceph_notification?, :network_query
202
200
  end
203
201
 
204
202
  # TODO(mtaylor)
@@ -256,9 +254,9 @@ module Staypuft
256
254
 
257
255
  def horizon_url
258
256
  if ha?
259
- "http://#{self.vips.get(:horizon)}"
257
+ "http://#{network_query.get_vip(:horizon_public_vip)}"
260
258
  else
261
- self.ips.controller_ips.empty? ? nil : "http://#{self.ips.controller_ip}"
259
+ network_query.controller_ips(Staypuft::SubnetType::PUBLIC_API).empty? ? nil : "http://#{network_query.controller_ip(Staypuft::SubnetType::PUBLIC_API)}"
262
260
  end
263
261
  end
264
262
 
@@ -280,6 +278,10 @@ module Staypuft
280
278
  first
281
279
  end
282
280
 
281
+ def network_query
282
+ @network_query || NetworkQuery.new(self)
283
+ end
284
+
283
285
  private
284
286
 
285
287
  def update_layout
@@ -23,5 +23,9 @@ module Staypuft
23
23
  has_many :subnets, :through => :subnet_typings
24
24
 
25
25
  scope :required, lambda { where(:is_required => true) }
26
+
27
+ class Jail < Safemode::Jail
28
+ allow :layouts, :layout_subnet_types, :name, :subnets, :subnet_typings, :required
29
+ end
26
30
  end
27
31
  end
@@ -5,10 +5,9 @@
5
5
  <div class="pull-right top_actions">
6
6
  <%= render partial: "hosts_filter" %>
7
7
  <div class="pull-right">
8
-
9
- <%= submit_tag _("Configure Networks"), :class => "btn btn-default btn-sm dynamic-submit", :disabled => true,
10
- :'data-submit-to' => deployment_interface_assignments_path(@deployment), :'data-method' => 'GET',
11
- :id => "configure_networks_button"%>
8
+ <button type="button" class= "btn btn-default btn-sm"
9
+ id="configure_networks_button" data-toggle = "modal"
10
+ data-target = "#configure_networks_modal" disabled="true"><%= _("Configure Networks") %></button>
12
11
  <%= submit_tag _("Unassign Hosts"), :class => "btn btn-primary btn-sm", :disabled => true, :id => "unassign_hosts_button" %>
13
12
  </div>
14
13
  </div>
@@ -49,6 +48,26 @@
49
48
  <% end %>
50
49
  </tbody>
51
50
  </table>
51
+ <div class="modal fade" id="configure_networks_modal" tabindex="-1" role="dialog" aria-labelledby="<%= _("Configure Networks") %>" aria-hidden="true" data-path="<%= deployment_interface_assignments_path(@deployment.id) %>">
52
+ <div class="modal-dialog modal-lg">
53
+ <div class="modal-content">
54
+ <div class="modal-header">
55
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
56
+ <h2 class="modal-title" id="configure_networks_modal_label">
57
+ <span class="glyphicon glyphicon-link">
58
+ </span> <%= _("Configure Networks") %>
59
+ </h2>
60
+ </div>
61
+ <div class="modal-body">
62
+ <div id="interfaces"><%= image_tag '/assets/spinner.gif', style: "display: block; margin-left: auto; margin-right: auto" %></div>
63
+ </div>
64
+ <div class="modal-footer">
65
+ <button type="button" class="btn btn-default" data-dismiss="modal"><%= _("Cancel") %></button>
66
+ <button type="button" class="btn btn-primarym" data-dismiss="modal"><%= _("Done") %></button>
67
+ </div>
68
+ </div>
69
+ </div>
70
+ </div>
52
71
  <% end %>
53
72
  </div>
54
73
  <% else %>
@@ -13,17 +13,17 @@
13
13
  <div class="col-sm-8 col-sm-offset-1">
14
14
  <h4><%= @deployment.ha? ? _("VIP list") : _("Controller IPs") %></h4>
15
15
  <% if @deployment.ha? %>
16
- <% Staypuft::Deployment::VIPS::VIP_NAMES.each do | vip_name | %>
16
+ <% Staypuft::NetworkQuery::VIP_NAMES.keys.each do | vip_name | %>
17
17
  <div class="row">
18
18
  <label class="col-sm-4 control-label text-muted"><%= "#{vip_name}:" %></label>
19
19
  <div class="col-sm-8">
20
- <p class="form-control-static"><%= @deployment.vips.get(vip_name) %></p>
20
+ <p class="form-control-static"><%= @deployment.network_query.get_vip(vip_name) %></p>
21
21
  </div>
22
22
  </div>
23
23
  <% end %>
24
24
  <% else %>
25
- <% @deployment.ips.controller_ips.each do |ip| %>
26
- <%= ip %>
25
+ <% @deployment.network_query.controller_ips(Staypuft::SubnetType::MANAGEMENT).each do |ip| %>
26
+ <%= ip %> what subnet type here?
27
27
  <% end %>
28
28
  <% end %>
29
29
  </div>
@@ -60,4 +60,4 @@
60
60
  </div>
61
61
  </div>
62
62
  </div>
63
- </div>
63
+ </div>
@@ -1,6 +1,6 @@
1
1
  <% deployed_hosts = @deployment.hosts.select { |h| h.open_stack_deployed? } %>
2
2
  <% assigned_hosts = @deployment.hosts.select { |h| !h.open_stack_deployed? } %>
3
- <% free_hosts = ::Host.where("hostgroup_id IS NULL") %>
3
+ <% free_hosts = ::Host::Base.where("hostgroup_id IS NULL") %>
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"},
@@ -38,10 +38,10 @@
38
38
  <%= host_label(host) %>
39
39
  </td>
40
40
  <td class="ellipsis">
41
- <%= link_to(host.os.to_label, hosts_path(:search => "os_description = #{host.os.description}")) if host.os %>
41
+ <%= link_to(host.os.to_label, hosts_path(:search => "os_description = #{host.os.description}")) if host.respond_to?(:os) && host.os %>
42
42
  </td>
43
- <td><%= host.cpus %></td>
44
- <td><%= host.mem %></td>
43
+ <td><%= host.cpus if host.respond_to?(:cpu) %></td>
44
+ <td><%= host.mem if host.respond_to?(:mem) %></td>
45
45
  <td><%= host_nics(host) %></td>
46
46
  <td class="hidden-s hidden-xs"><%= host.ip %></td>
47
47
  </tr>
@@ -53,7 +53,7 @@
53
53
  <div class="modal-content">
54
54
  <div class="modal-header">
55
55
  <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
56
- <h2 class="modal-title" id="deploy_modal_label">
56
+ <h2 class="modal-title" id="role_modal_label">
57
57
  <span class="glyphicon glyphicon-th-list">
58
58
  </span> <%= _("Deployment Roles") %>
59
59
  </h2>