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
data/app/lib/staypuft/seeder.rb
CHANGED
@@ -203,13 +203,13 @@ module Staypuft
|
|
203
203
|
:layouts => ALL_LAYOUTS}
|
204
204
|
}
|
205
205
|
|
206
|
-
def get_host_format(param_name)
|
207
|
-
{ :string =>
|
206
|
+
def get_host_format(param_name, subnet_type_name)
|
207
|
+
{ :string => "<%= d = @host.deployment; d.ha? ? d.network_query.get_vip(:#{param_name}) : d.network_query.controller_ip('#{subnet_type_name}') %>" }
|
208
208
|
end
|
209
209
|
|
210
210
|
# virtual ip addresses
|
211
211
|
def vip_format(param_name)
|
212
|
-
{ :string => '<%%= @host.deployment.
|
212
|
+
{ :string => '<%%= @host.deployment.network_query.get_vip(:%s) %%>' % param_name }
|
213
213
|
end
|
214
214
|
|
215
215
|
def functional_dependencies
|
@@ -224,8 +224,8 @@ module Staypuft
|
|
224
224
|
network_num_networks = { :string => '<%= @host.deployment.nova.num_networks %>' }
|
225
225
|
network_fixed_range = { :string => '<%= @host.deployment.nova.private_fixed_range %>' }
|
226
226
|
network_floating_range = { :string => '<%= @host.deployment.nova.public_floating_range %>' }
|
227
|
-
network_private_iface = { :string =>
|
228
|
-
network_public_iface = { :string =>
|
227
|
+
network_private_iface = { :string => "<%= @host.deployment.network_query.interface_for_host(@host, '#{Staypuft::SubnetType::TENANT}') %>" }
|
228
|
+
network_public_iface = { :string => "<%= @host.deployment.network_query.interface_for_host(@host, '#{Staypuft::SubnetType::EXTERNAL}') %>" }
|
229
229
|
network_create_networks = true
|
230
230
|
|
231
231
|
# Neutron
|
@@ -237,12 +237,12 @@ module Staypuft
|
|
237
237
|
ml2_tunnel_id_ranges = ['10:1000']
|
238
238
|
ml2_vni_ranges = ['10:1000']
|
239
239
|
ovs_tunnel_types = ['vxlan', 'gre']
|
240
|
-
ovs_tunnel_iface = { :string => '<%= n = @host.deployment.neutron; n.enable_tunneling? ? n.
|
241
|
-
ovs_bridge_mappings = { :array => '<%= @host.deployment.neutron.networker_ovs_bridge_mappings %>' }
|
242
|
-
ovs_bridge_uplinks = { :array => '<%= @host.deployment.neutron.networker_ovs_bridge_uplinks %>' }
|
243
|
-
compute_ovs_tunnel_iface = { :string => '<%= n = @host.deployment.neutron; n.enable_tunneling? ? n.
|
244
|
-
compute_ovs_bridge_mappings = { :array => '<%= @host.deployment.neutron.compute_ovs_bridge_mappings %>' }
|
245
|
-
compute_ovs_bridge_uplinks = { :array => '<%= @host.deployment.neutron.compute_ovs_bridge_uplinks %>' }
|
240
|
+
ovs_tunnel_iface = { :string => '<%= n = @host.deployment.neutron; n.enable_tunneling? ? n.tenant_iface(@host) : "" %>' }
|
241
|
+
ovs_bridge_mappings = { :array => '<%= @host.deployment.neutron.networker_ovs_bridge_mappings(@host) %>' }
|
242
|
+
ovs_bridge_uplinks = { :array => '<%= @host.deployment.neutron.networker_ovs_bridge_uplinks(@host) %>' }
|
243
|
+
compute_ovs_tunnel_iface = { :string => '<%= n = @host.deployment.neutron; n.enable_tunneling? ? n.tenant_iface(@host) : "" %>' }
|
244
|
+
compute_ovs_bridge_mappings = { :array => '<%= @host.deployment.neutron.compute_ovs_bridge_mappings(@host) %>' }
|
245
|
+
compute_ovs_bridge_uplinks = { :array => '<%= @host.deployment.neutron.compute_ovs_bridge_uplinks(@host) %>' }
|
246
246
|
enable_tunneling = { :string => '<%= @host.deployment.neutron.enable_tunneling?.to_s %>' }
|
247
247
|
|
248
248
|
# Glance
|
@@ -263,7 +263,7 @@ module Staypuft
|
|
263
263
|
cinder_backend_iscsi_name = 'iscsi_backend'
|
264
264
|
cinder_backend_nfs = { :string => '<%= @host.deployment.cinder.nfs_backend? %>' }
|
265
265
|
cinder_backend_nfs_name = 'nfs_backend'
|
266
|
-
cinder_multiple_backends =
|
266
|
+
cinder_multiple_backends = { :string => '<%= @host.deployment.cinder.multiple_backends? %>' }
|
267
267
|
cinder_nfs_shares = ['<%= @host.deployment.cinder.nfs_uri %>']
|
268
268
|
cinder_nfs_mount_options = 'nosharecache'
|
269
269
|
|
@@ -280,11 +280,11 @@ module Staypuft
|
|
280
280
|
cinder_backend_eqlx_name = ['eqlx_backend']
|
281
281
|
# TODO: confirm these params and add them to model where user input is needed
|
282
282
|
# below dynamic calls are commented out since the model does not yet have san/chap entries
|
283
|
-
cinder_san_ip =
|
284
|
-
cinder_san_login =
|
285
|
-
cinder_san_password =
|
286
|
-
cinder_eqlx_group_name =
|
287
|
-
cinder_eqlx_pool =
|
283
|
+
cinder_san_ip = { :array => '<%= @host.deployment.cinder.compute_eqlx_san_ips %>' }
|
284
|
+
cinder_san_login = { :array => '<%= @host.deployment.cinder.compute_eqlx_san_logins %>' }
|
285
|
+
cinder_san_password = { :array => '<%= @host.deployment.cinder.compute_eqlx_san_passwords %>' }
|
286
|
+
cinder_eqlx_group_name = { :array => '<%= @host.deployment.cinder.compute_eqlx_group_names %>' }
|
287
|
+
cinder_eqlx_pool = { :array => '<%= @host.deployment.cinder.compute_eqlx_pools %>'}
|
288
288
|
|
289
289
|
cinder_san_thin_provision = ['false']
|
290
290
|
cinder_eqlx_use_chap = ['false']
|
@@ -326,15 +326,20 @@ module Staypuft
|
|
326
326
|
neutron_metadata_proxy_secret = { :string => '<%= @host.deployment.passwords.neutron_metadata_proxy_secret %>' }
|
327
327
|
|
328
328
|
|
329
|
-
private_ip = { :string =>
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
neutron_host = get_host_format :
|
335
|
-
|
329
|
+
private_ip = { :string => "<%= @host.deployment.network_query.ip_for_host(@host, '#{Staypuft::SubnetType::MANAGEMENT}') %>" }
|
330
|
+
# private API/management
|
331
|
+
amqp_host = get_host_format :amqp_vip, Staypuft::SubnetType::MANAGEMENT
|
332
|
+
mysql_host = get_host_format :db_vip, Staypuft::SubnetType::MANAGEMENT
|
333
|
+
glance_host = get_host_format :glance_private_vip, Staypuft::SubnetType::MANAGEMENT
|
334
|
+
neutron_host = get_host_format :neutron_private_vip, Staypuft::SubnetType::MANAGEMENT
|
335
|
+
#admin API
|
336
|
+
auth_host = get_host_format :keystone_admin_vip, Staypuft::SubnetType::ADMIN_API
|
337
|
+
# public API
|
338
|
+
nova_host = get_host_format :nova_public_vip, Staypuft::SubnetType::PUBLIC_API
|
336
339
|
|
337
|
-
|
340
|
+
controller_admin_host = { :string => "<%= d = @host.deployment; d.ha? ? nil : d.network_query.controller_ip('#{Staypuft::SubnetType::ADMIN_API}') %>"}
|
341
|
+
controller_priv_host = { :string => "<%= d = @host.deployment; d.ha? ? nil : d.network_query.controller_ip('#{Staypuft::SubnetType::MANAGEMENT}') %>"}
|
342
|
+
controller_pub_host = { :string => "<%= d = @host.deployment; d.ha? ? nil : d.network_query.controller_ip('#{Staypuft::SubnetType::PUBLIC_API}') %>"}
|
338
343
|
|
339
344
|
{
|
340
345
|
'quickstack::nova_network::controller' => {
|
@@ -394,11 +399,11 @@ module Staypuft
|
|
394
399
|
'mysql_host' => mysql_host,
|
395
400
|
'swift_shared_secret' => swift_shared_secret,
|
396
401
|
'swift_ringserver_ip' => '',
|
397
|
-
'swift_storage_ips' => { :array =>
|
402
|
+
'swift_storage_ips' => { :array => "<%= @host.deployment.network_query.controller_ips('#{Staypuft::SubnetType::MANAGEMENT}') %>" },
|
398
403
|
'cinder_gluster_shares' => [],
|
399
|
-
'controller_admin_host' =>
|
400
|
-
'controller_priv_host' =>
|
401
|
-
'controller_pub_host' =>
|
404
|
+
'controller_admin_host' => controller_admin_host,
|
405
|
+
'controller_priv_host' => controller_priv_host,
|
406
|
+
'controller_pub_host' => controller_pub_host },
|
402
407
|
'quickstack::neutron::controller' => {
|
403
408
|
'amqp_provider' => amqp_provider,
|
404
409
|
'tenant_network_type' => tenant_network_type,
|
@@ -467,11 +472,11 @@ module Staypuft
|
|
467
472
|
'mysql_host' => mysql_host,
|
468
473
|
'swift_shared_secret' => swift_shared_secret,
|
469
474
|
'swift_ringserver_ip' => '',
|
470
|
-
'swift_storage_ips' => { :array =>
|
475
|
+
'swift_storage_ips' => { :array => "<%= @host.deployment.network_query.controller_ips('#{Staypuft::SubnetType::MANAGEMENT}') %>" },
|
471
476
|
'cinder_gluster_shares' => [],
|
472
|
-
'controller_admin_host' =>
|
473
|
-
'controller_priv_host' =>
|
474
|
-
'controller_pub_host' =>
|
477
|
+
'controller_admin_host' => controller_admin_host,
|
478
|
+
'controller_priv_host' => controller_priv_host,
|
479
|
+
'controller_pub_host' => controller_pub_host },
|
475
480
|
'quickstack::pacemaker::params' => {
|
476
481
|
'include_swift' => 'false',
|
477
482
|
'include_neutron' => neutron,
|
@@ -494,43 +499,43 @@ module Staypuft
|
|
494
499
|
'amqp_password' => amqp_pw,
|
495
500
|
'heat_auth_encryption_key' => heat_auth_encrypt_key,
|
496
501
|
'neutron_metadata_proxy_secret' => neutron_metadata_proxy_secret,
|
497
|
-
'ceilometer_admin_vip' => vip_format(:
|
498
|
-
'ceilometer_private_vip' => vip_format(:
|
499
|
-
'ceilometer_public_vip' => vip_format(:
|
500
|
-
'cinder_admin_vip' => vip_format(:
|
501
|
-
'cinder_private_vip' => vip_format(:
|
502
|
-
'cinder_public_vip' => vip_format(:
|
503
|
-
'db_vip' => vip_format(:
|
504
|
-
'glance_admin_vip' => vip_format(:
|
505
|
-
'glance_private_vip' => vip_format(:
|
506
|
-
'glance_public_vip' => vip_format(:
|
507
|
-
'heat_admin_vip' => vip_format(:
|
508
|
-
'heat_private_vip' => vip_format(:
|
509
|
-
'heat_public_vip' => vip_format(:
|
510
|
-
'heat_cfn_admin_vip' => vip_format(:
|
511
|
-
'heat_cfn_private_vip' => vip_format(:
|
512
|
-
'heat_cfn_public_vip' => vip_format(:
|
513
|
-
'horizon_admin_vip' => vip_format(:
|
514
|
-
'horizon_private_vip' => vip_format(:
|
515
|
-
'horizon_public_vip' => vip_format(:
|
516
|
-
'keystone_admin_vip' => vip_format(:
|
517
|
-
'keystone_private_vip' => vip_format(:
|
518
|
-
'keystone_public_vip' => vip_format(:
|
519
|
-
'loadbalancer_vip' => vip_format(:
|
520
|
-
'neutron_admin_vip' => vip_format(:
|
521
|
-
'neutron_private_vip' => vip_format(:
|
522
|
-
'neutron_public_vip' => vip_format(:
|
523
|
-
'nova_admin_vip' => vip_format(:
|
524
|
-
'nova_private_vip' => vip_format(:
|
525
|
-
'nova_public_vip' => vip_format(:
|
526
|
-
'amqp_vip' => vip_format(:
|
527
|
-
'swift_public_vip' => vip_format(:
|
502
|
+
'ceilometer_admin_vip' => vip_format(:ceilometer_admin_vip),
|
503
|
+
'ceilometer_private_vip' => vip_format(:ceilometer_private_vip),
|
504
|
+
'ceilometer_public_vip' => vip_format(:ceilometer_public_vip),
|
505
|
+
'cinder_admin_vip' => vip_format(:cinder_admin_vip),
|
506
|
+
'cinder_private_vip' => vip_format(:cinder_private_vip),
|
507
|
+
'cinder_public_vip' => vip_format(:cinder_public_vip),
|
508
|
+
'db_vip' => vip_format(:db_vip),
|
509
|
+
'glance_admin_vip' => vip_format(:glance_admin_vip),
|
510
|
+
'glance_private_vip' => vip_format(:glance_private_vip),
|
511
|
+
'glance_public_vip' => vip_format(:glance_public_vip),
|
512
|
+
'heat_admin_vip' => vip_format(:heat_admin_vip),
|
513
|
+
'heat_private_vip' => vip_format(:heat_private_vip),
|
514
|
+
'heat_public_vip' => vip_format(:heat_public_vip),
|
515
|
+
'heat_cfn_admin_vip' => vip_format(:heat_cfn_admin_vip),
|
516
|
+
'heat_cfn_private_vip' => vip_format(:heat_cfn_private_vip),
|
517
|
+
'heat_cfn_public_vip' => vip_format(:heat_cfn_public_vip),
|
518
|
+
'horizon_admin_vip' => vip_format(:horizon_admin_vip),
|
519
|
+
'horizon_private_vip' => vip_format(:horizon_private_vip),
|
520
|
+
'horizon_public_vip' => vip_format(:horizon_public_vip),
|
521
|
+
'keystone_admin_vip' => vip_format(:keystone_admin_vip),
|
522
|
+
'keystone_private_vip' => vip_format(:keystone_private_vip),
|
523
|
+
'keystone_public_vip' => vip_format(:keystone_public_vip),
|
524
|
+
'loadbalancer_vip' => vip_format(:loadbalancer_vip),
|
525
|
+
'neutron_admin_vip' => vip_format(:neutron_admin_vip),
|
526
|
+
'neutron_private_vip' => vip_format(:neutron_private_vip),
|
527
|
+
'neutron_public_vip' => vip_format(:neutron_public_vip),
|
528
|
+
'nova_admin_vip' => vip_format(:nova_admin_vip),
|
529
|
+
'nova_private_vip' => vip_format(:nova_private_vip),
|
530
|
+
'nova_public_vip' => vip_format(:nova_public_vip),
|
531
|
+
'amqp_vip' => vip_format(:amqp_vip),
|
532
|
+
'swift_public_vip' => vip_format(:swift_public_vip),
|
528
533
|
'private_ip' => private_ip,
|
529
|
-
'cluster_control_ip' => { :string =>
|
530
|
-
'lb_backend_server_addrs' => { :array =>
|
531
|
-
'lb_backend_server_names' => { :array => '<%= @host.deployment.
|
534
|
+
'cluster_control_ip' => { :string => "<%= @host.deployment.network_query.controller_ips('#{Staypuft::SubnetType::MANAGEMENT}').first %>" },
|
535
|
+
'lb_backend_server_addrs' => { :array => "<%= @host.deployment.network_query.controller_ips('#{Staypuft::SubnetType::MANAGEMENT}') %>" },
|
536
|
+
'lb_backend_server_names' => { :array => '<%= @host.deployment.network_query.controller_fqdns %>' } },
|
532
537
|
'quickstack::pacemaker::common' => {
|
533
|
-
'pacemaker_cluster_members' => { :string =>
|
538
|
+
'pacemaker_cluster_members' => { :string => "<%= @host.deployment.network_query.controller_ips('#{Staypuft::SubnetType::MANAGEMENT}').join(' ') %>" } },
|
534
539
|
'quickstack::pacemaker::neutron' => {
|
535
540
|
'ml2_network_vlan_ranges' => ml2_network_vlan_ranges,
|
536
541
|
'ml2_tenant_network_types' => ml2_tenant_network_types,
|
@@ -580,10 +585,9 @@ module Staypuft
|
|
580
585
|
'secret_key' => horizon_secret_key },
|
581
586
|
'quickstack::pacemaker::galera' => {
|
582
587
|
'mysql_root_password' => mysql_root_pw,
|
583
|
-
'wsrep_cluster_members' => { :array =>
|
588
|
+
'wsrep_cluster_members' => { :array => "<%= @host.deployment.network_query.controller_ips('#{Staypuft::SubnetType::MANAGEMENT}') %>" } },
|
584
589
|
'quickstack::pacemaker::swift' => {
|
585
590
|
'swift_shared_secret' => swift_shared_secret,
|
586
|
-
'swift_internal_vip' => vip_format(:swift),
|
587
591
|
'swift_storage_ips' => [] },
|
588
592
|
'quickstack::pacemaker::nova' => {
|
589
593
|
'multi_host' => 'true',
|
@@ -605,7 +609,7 @@ module Staypuft
|
|
605
609
|
'neutron_metadata_proxy_secret' => neutron_metadata_proxy_secret,
|
606
610
|
'amqp_host' => amqp_host,
|
607
611
|
'mysql_host' => mysql_host,
|
608
|
-
'controller_priv_host' =>
|
612
|
+
'controller_priv_host' => controller_priv_host },
|
609
613
|
'quickstack::storage_backend::cinder' => {
|
610
614
|
'amqp_provider' => amqp_provider,
|
611
615
|
'cinder_db_password' => cinder_db_pw,
|
@@ -13,16 +13,39 @@ module Staypuft
|
|
13
13
|
|
14
14
|
def interfaces_identifiers
|
15
15
|
interfaces = [ self.primary_interface ]
|
16
|
-
interfaces += self.respond_to?(:interfaces) ? self.interfaces.where("type <> 'Nic::BMC'").physical.map(&:identifier) : []
|
16
|
+
interfaces += self.respond_to?(:interfaces) ? self.interfaces.where("type <> 'Nic::BMC'").non_vip.physical.map(&:identifier) : []
|
17
17
|
interfaces
|
18
18
|
end
|
19
19
|
|
20
20
|
def make_all_interfaces_managed
|
21
|
-
self.interfaces.each do |interface|
|
21
|
+
self.interfaces.non_vip.each do |interface|
|
22
22
|
interface.managed = true
|
23
23
|
interface.save!
|
24
24
|
end
|
25
25
|
end
|
26
|
+
|
27
|
+
def build_vips(parameters)
|
28
|
+
deployment = self.hostgroup.deployment
|
29
|
+
typings = deployment.subnet_typings
|
30
|
+
types = SubnetType.where(:name => parameters.values).all
|
31
|
+
n = 0
|
32
|
+
|
33
|
+
parameters.each do |parameter, subnet_type|
|
34
|
+
type = types.find { |t| t.name == subnet_type }
|
35
|
+
raise "unable to find subnet type with name #{subnet_type}" if type.nil?
|
36
|
+
|
37
|
+
subnet = typings.where(:subnet_type_id => type.id).first.subnet
|
38
|
+
raise "unable to find subnet assigned to type #{subnet_type} in deployment #{deployment.name}" if subnet.nil?
|
39
|
+
|
40
|
+
interface = self.interfaces.build(:type => 'Nic::Managed')
|
41
|
+
interface.identifier = "vip#{n}"
|
42
|
+
interface.subnet = subnet
|
43
|
+
interface.managed = false
|
44
|
+
interface.mac = "00:00:00:00:00:#{n.to_s(16).rjust(2, '0')}"
|
45
|
+
interface.tag = parameter
|
46
|
+
n += 1
|
47
|
+
end
|
48
|
+
end
|
26
49
|
end
|
27
50
|
end
|
28
51
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Staypuft
|
2
|
+
module Concerns
|
3
|
+
module SubnetIpManagement
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
before_save :reserve_ip
|
8
|
+
end
|
9
|
+
|
10
|
+
def reserve_ip
|
11
|
+
if self.identifier =~ /\Avip\d+\Z/ && self.subnet.present? && self.subnet.ipam?
|
12
|
+
self.ip ||= self.subnet.unused_ip
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Staypuft
|
2
|
+
module Concerns
|
3
|
+
module VipNicScopes
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
scope :vip, lambda { where(['identifier LIKE ?', 'vip%']) }
|
8
|
+
scope :non_vip, lambda { where(['identifier NOT LIKE ?', 'vip%']) }
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -16,7 +16,7 @@ module Staypuft
|
|
16
16
|
end
|
17
17
|
|
18
18
|
define_method "#{name}=" do |value|
|
19
|
-
instance_variable_set(
|
19
|
+
instance_variable_set(:"@#{name}", value)
|
20
20
|
end
|
21
21
|
|
22
22
|
after_save do
|
@@ -36,6 +36,64 @@ module Staypuft
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
39
|
+
|
40
|
+
def param_attr_array(*names)
|
41
|
+
names.each do |item|
|
42
|
+
item.each do |name, type|
|
43
|
+
ivar_name = :"@#{name}"
|
44
|
+
param_base_name = "ui::#{param_scope}::#{name}"
|
45
|
+
|
46
|
+
define_method name do
|
47
|
+
instance_variable_get(ivar_name) or
|
48
|
+
begin
|
49
|
+
params = hostgroup.group_parameters.where(['name LIKE ?', "#{param_base_name}%"])
|
50
|
+
ivar = []
|
51
|
+
params.each do |param|
|
52
|
+
value = param.try(:value)
|
53
|
+
unless value.nil?
|
54
|
+
full, index = *param.name.match(/#{param_base_name}::(\d+)/)
|
55
|
+
ivar[index.to_i] ||= type.new({id: index.to_i }.merge(JSON.parse(value)))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
instance_variable_set(ivar_name, ivar)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
define_method "#{name}=" do |value|
|
63
|
+
if value.is_a? Hash
|
64
|
+
values = []
|
65
|
+
value.each do |k,v|
|
66
|
+
values << type.new(v)
|
67
|
+
end
|
68
|
+
instance_variable_set(:"@#{name}", values)
|
69
|
+
else
|
70
|
+
instance_variable_set(:"@#{name}", value)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
define_method "#{name}_attributes=" do |attributes|
|
75
|
+
Rails.logger.error attributes
|
76
|
+
end
|
77
|
+
|
78
|
+
after_save do
|
79
|
+
values = send(name)
|
80
|
+
# Delete all params since array can shrink
|
81
|
+
params = hostgroup.group_parameters.where(['name LIKE ?', "#{param_base_name}%"])
|
82
|
+
params.each do |param|
|
83
|
+
param.try(:destroy)
|
84
|
+
end
|
85
|
+
if not values.blank?
|
86
|
+
values.each_with_index do |value, index|
|
87
|
+
param = hostgroup.
|
88
|
+
group_parameters.
|
89
|
+
find_or_initialize_by_name( "#{param_base_name}::#{index}")
|
90
|
+
param.update_attributes!(value: value.to_json(root:false))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
39
97
|
end
|
40
98
|
end
|
41
99
|
|
@@ -0,0 +1,80 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
module Staypuft
|
3
|
+
class Deployment::CinderService::Equallogic
|
4
|
+
include ActiveModel::Serializers::JSON
|
5
|
+
include ActiveModel::Validations
|
6
|
+
extend ActiveModel::Naming
|
7
|
+
|
8
|
+
attr_accessor :id, :san_ip, :san_login, :san_password, :pool, :group_name
|
9
|
+
attr_reader :errors
|
10
|
+
|
11
|
+
def initialize(attrs = {})
|
12
|
+
@errors = ActiveModel::Errors.new(self)
|
13
|
+
self.attributes = attrs
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.human_attribute_name(attr, options = {})
|
17
|
+
attr
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.lookup_ancestors
|
21
|
+
[self]
|
22
|
+
end
|
23
|
+
|
24
|
+
def attributes
|
25
|
+
{ 'san_ip' => nil, 'san_login' => nil, 'san_password' => nil, 'pool' => nil, 'group_name' => nil }
|
26
|
+
end
|
27
|
+
|
28
|
+
def attributes=(attrs)
|
29
|
+
attrs.each { |attr, value| send "#{attr}=", value } unless attrs.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
class SanIpValueValidator < ActiveModel::EachValidator
|
33
|
+
def validate_each(record, attribute, value)
|
34
|
+
return if value.empty?
|
35
|
+
|
36
|
+
begin
|
37
|
+
ip_addr = IPAddr.new(value)
|
38
|
+
ip_range = ip_addr.to_range
|
39
|
+
if ip_range.begin == ip_range.end
|
40
|
+
true
|
41
|
+
else
|
42
|
+
record.errors.add attribute, "Specify single IP address, not range"
|
43
|
+
false
|
44
|
+
end
|
45
|
+
rescue
|
46
|
+
# not IP addr
|
47
|
+
# validating as fqdn
|
48
|
+
if /(?=^.{1,254}$)(^(((?!-)[a-zA-Z0-9-]{1,63}(?<!-))|((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63})$)/ =~ value
|
49
|
+
true
|
50
|
+
else
|
51
|
+
record.errors.add attribute, "Invalid IP address or FQDN supplied"
|
52
|
+
false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
validates :san_ip,
|
59
|
+
presence: true,
|
60
|
+
san_ip_value: true
|
61
|
+
validates :san_login,
|
62
|
+
presence: true,
|
63
|
+
format: /\A[a-zA-Z\d][\w\.\-]*[\w\-]\z/,
|
64
|
+
length: { maximum: 16 }
|
65
|
+
validates :san_password,
|
66
|
+
presence: true,
|
67
|
+
format: /\A[!-~]+\z/,
|
68
|
+
length: { minimum:3, maximum: 16 }
|
69
|
+
validates :pool,
|
70
|
+
presence: true,
|
71
|
+
format: /\A[[^\p{Z}\p{C}!"\#$%&'\(\)\*\+,\/;<=>\?@\[\]\\\^\{\}|~\.\-:]][[^\p{Z}\p{C}!"\#$%&'\(\)\*\+,\/;<=>\?@\[\]\\\^\{\}|~]]+[[^\p{Z}\p{C}!"\#$%&'\(\)\*\+,\/;<=>\?@\[\]\\\^\{\}|~\.\-:]]\z/,
|
72
|
+
length: { maximum: 63,
|
73
|
+
too_long: "Too long: max length is %{count} bytes. Using multibyte characters reduces the maximum number of characters allowed.",
|
74
|
+
tokenizer: lambda {|str| str.bytes.to_a } }
|
75
|
+
validates :group_name,
|
76
|
+
presence: true,
|
77
|
+
format: /\A[a-zA-Z\d][a-zA-Z\d\-]*\z/,
|
78
|
+
length: { maximum: 54 }
|
79
|
+
end
|
80
|
+
end
|