staypuft 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/staypuft/nics_assignment.js +5 -5
- data/app/assets/javascripts/staypuft/staypuft.js +58 -5
- data/app/assets/javascripts/staypuft/subnets_assignment.js +5 -4
- data/app/assets/stylesheets/staypuft/bootstrap_and_overrides.css.scss +16 -0
- data/app/assets/stylesheets/staypuft/staypuft.css.scss +30 -71
- data/app/controllers/staypuft/deployments_controller.rb +23 -0
- data/app/controllers/staypuft/interface_assignments_controller.rb +2 -1
- data/app/lib/staypuft/network_query.rb +88 -5
- data/app/lib/staypuft/seeder.rb +75 -71
- data/app/models/staypuft/concerns/host_interface_management.rb +25 -2
- data/app/models/staypuft/concerns/subnet_ip_management.rb +17 -0
- data/app/models/staypuft/concerns/vip_nic_scopes.rb +13 -0
- data/app/models/staypuft/deployment/attribute_param_storage.rb +59 -1
- data/app/models/staypuft/deployment/cinder_service/equallogic.rb +80 -0
- data/app/models/staypuft/deployment/cinder_service.rb +53 -94
- data/app/models/staypuft/deployment/neutron_service.rb +20 -83
- data/app/models/staypuft/deployment/nova_service.rb +2 -31
- data/app/models/staypuft/deployment.rb +9 -7
- data/app/models/staypuft/subnet_type.rb +4 -0
- data/app/views/staypuft/deployments/_assigned_hosts.html.erb +23 -4
- data/app/views/staypuft/deployments/_deployment_access_all_details_dialogue.html.erb +5 -5
- data/app/views/staypuft/deployments/_deployment_hosts.html.erb +1 -1
- data/app/views/staypuft/deployments/_free_hosts.html.erb +4 -4
- data/app/views/staypuft/interface_assignments/index.html.erb +36 -31
- data/app/views/staypuft/interfaces/_drop_zone.html.erb +22 -22
- data/app/views/staypuft/steps/_cinder.html.erb +48 -26
- data/app/views/staypuft/steps/_cinder_equallogic_form.html.erb +13 -0
- data/app/views/staypuft/steps/_neutron.html.erb +0 -28
- data/app/views/staypuft/steps/_nova.html.erb +0 -11
- data/app/views/staypuft/steps/network_configuration.html.erb +27 -19
- data/app/views/staypuft/steps/services_configuration.html.erb +1 -1
- data/app/views/staypuft/subnet_typings/destroy.js.erb +1 -1
- data/app/views/staypuft/subnets/_drop_zone.html.erb +5 -5
- data/app/views/staypuft/subnets/_subnet_pull.html.erb +3 -4
- data/lib/staypuft/engine.rb +2 -0
- data/lib/staypuft/version.rb +1 -1
- metadata +6 -4
- data/app/models/staypuft/deployment/ips.rb +0 -25
- data/app/models/staypuft/deployment/vips.rb +0 -40
@@ -5,35 +5,13 @@ module Staypuft
|
|
5
5
|
'cinder'
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
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
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
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?, :
|
130
|
-
:
|
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.
|
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? &&
|
80
|
+
!self.deployment.ha? && self.backend_lvm == "true"
|
148
81
|
end
|
149
82
|
|
150
83
|
def nfs_backend?
|
151
|
-
self.
|
84
|
+
self.backend_nfs == "true"
|
152
85
|
end
|
153
86
|
|
154
87
|
def ceph_backend?
|
155
|
-
self.
|
88
|
+
self.backend_ceph == "true"
|
156
89
|
end
|
157
90
|
|
158
91
|
def equallogic_backend?
|
159
|
-
self.
|
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
|
-
{ "
|
177
|
-
"
|
178
|
-
"
|
179
|
-
"
|
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
|
-
:
|
81
|
-
:
|
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
|
-
[
|
58
|
+
[network_segmentation, *(SEGMENTATION_LIST - [network_segmentation])]
|
102
59
|
end
|
103
60
|
|
104
|
-
def networker_ovs_bridge_mappings
|
105
|
-
[(
|
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
|
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 !
|
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 !
|
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
|
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
|
-
|
141
|
-
"physnet-external"].compact
|
82
|
+
compute_vlan_ranges << "physnet-external"
|
142
83
|
end
|
143
84
|
|
144
85
|
def vlan_segmentation?
|
145
|
-
|
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
|
153
|
-
|
93
|
+
def tenant_iface(host)
|
94
|
+
deployment.network_query.interface_for_host(host, Staypuft::SubnetType::TENANT)
|
154
95
|
end
|
155
96
|
|
156
|
-
def
|
157
|
-
|
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, :
|
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
|
-
:
|
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, :
|
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://#{
|
257
|
+
"http://#{network_query.get_vip(:horizon_public_vip)}"
|
260
258
|
else
|
261
|
-
|
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
|
-
|
10
|
-
|
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">×</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::
|
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.
|
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.
|
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">×</button>
|
56
|
-
<h2 class="modal-title" id="
|
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>
|