staypuft 0.3.1 → 0.3.2

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 (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>