staypuft 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/staypuft/nics_assignment.js +32 -0
- data/app/assets/javascripts/staypuft/staypuft.js +38 -0
- data/app/assets/javascripts/staypuft/subnets_assignment.js +40 -0
- data/app/assets/stylesheets/staypuft/bootstrap_and_overrides.css.scss +5 -1
- data/app/assets/stylesheets/staypuft/staypuft.css.scss +102 -0
- data/app/controllers/staypuft/deployments_controller.rb +5 -0
- data/app/controllers/staypuft/interface_assignments_controller.rb +76 -0
- data/app/controllers/staypuft/steps_controller.rb +15 -1
- data/app/controllers/staypuft/subnet_typings_controller.rb +42 -0
- data/app/helpers/staypuft/deployments_helper.rb +18 -3
- data/app/lib/actions/staypuft/hostgroup/deploy.rb +38 -1
- data/app/lib/staypuft/network_query.rb +35 -0
- data/app/lib/staypuft/seeder.rb +113 -39
- data/app/models/staypuft/concerns/host_interface_management.rb +28 -0
- data/app/models/staypuft/deployment.rb +35 -3
- data/app/models/staypuft/interface_assigner.rb +137 -0
- data/app/models/staypuft/layout.rb +3 -0
- data/app/models/staypuft/layout_subnet_type.rb +12 -0
- data/app/models/staypuft/role.rb +15 -0
- data/app/models/staypuft/subnet_type.rb +27 -0
- data/app/models/staypuft/subnet_typing.rb +11 -0
- data/app/views/staypuft/deployments/_assigned_hosts.html.erb +5 -2
- data/app/views/staypuft/deployments/_assigned_hosts_table.html.erb +13 -46
- data/app/views/staypuft/deployments/_deployed_hosts_table.html.erb +12 -33
- data/app/views/staypuft/deployments/_deployment_overview.html.erb +12 -9
- data/app/views/staypuft/deployments/_deployment_summary.html.erb +18 -0
- data/app/views/staypuft/deployments/_empty_hosts.html.erb +8 -0
- data/app/views/staypuft/deployments/_free_hosts.html.erb +1 -1
- data/app/views/staypuft/deployments/_free_hosts_table.html.erb +11 -34
- data/app/views/staypuft/deployments/_host_head_row.html.erb +11 -0
- data/app/views/staypuft/deployments/_host_row.html.erb +30 -0
- data/app/views/staypuft/deployments/_hosts_header.html.erb +7 -0
- data/app/views/staypuft/deployments/index.html.erb +1 -1
- data/app/views/staypuft/deployments/show.html.erb +2 -2
- data/app/views/staypuft/interface_assignments/create.js.erb +12 -0
- data/app/views/staypuft/interface_assignments/destroy.js.erb +12 -0
- data/app/views/staypuft/interface_assignments/index.html.erb +38 -0
- data/app/views/staypuft/interfaces/_drop_zone.html.erb +30 -0
- data/app/views/staypuft/steps/network_configuration.html.erb +52 -0
- data/app/views/staypuft/steps/services_configuration.html.erb +45 -39
- data/app/views/staypuft/steps/services_overview.html.erb +1 -1
- data/app/views/staypuft/subnet_types/_subnet_type_pull.html.erb +9 -0
- data/app/views/staypuft/subnet_typings/create.js.erb +12 -0
- data/app/views/staypuft/subnet_typings/destroy.js.erb +12 -0
- data/app/views/staypuft/subnet_typings/update.js.erb +14 -0
- data/app/views/staypuft/subnets/_drop_zone.html.erb +16 -0
- data/app/views/staypuft/subnets/_subnet_pull.html.erb +9 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20140701074900_create_subnet_type.rb +9 -0
- data/db/migrate/20140701075033_create_layout_subnet.rb +10 -0
- data/db/migrate/20140701090256_create_staypuft_subnet_typings.rb +14 -0
- data/db/migrate/20140825164900_add_orchestration_to_staypuft_role.rb +5 -0
- data/db/migrate/20140831234000_add_required_to_subnet_types.rb +5 -0
- data/db/seeds.rb +1 -1
- data/lib/staypuft/engine.rb +11 -8
- data/lib/staypuft/version.rb +1 -1
- metadata +135 -91
data/app/lib/staypuft/seeder.rb
CHANGED
@@ -103,7 +103,9 @@ module Staypuft
|
|
103
103
|
:horizon_ha => { :name => 'Horizon (HA)', :class => ['quickstack::pacemaker::horizon'] },
|
104
104
|
:galera_ha => { :name => 'Galera (HA)', :class => ['quickstack::pacemaker::galera'] },
|
105
105
|
:mysql_ha => { :name => 'Mysql (HA)', :class => ['quickstack::pacemaker::mysql'] },
|
106
|
-
:neutron_ha => { :name => 'Neutron (HA)', :class => ['quickstack::pacemaker::neutron'] }
|
106
|
+
:neutron_ha => { :name => 'Neutron (HA)', :class => ['quickstack::pacemaker::neutron'] },
|
107
|
+
:generic_rhel_7 => { :name => 'Generic RHEL 7', :class => ['quickstack::openstack_common'] },
|
108
|
+
:ceph_osd => { :name => 'Ceph Storage (OSD) (node)', :class => ['quickstack::openstack_common'] },
|
107
109
|
}
|
108
110
|
|
109
111
|
# The list of roles is still from astapor
|
@@ -112,44 +114,94 @@ module Staypuft
|
|
112
114
|
# until we get the real list of roles per layout
|
113
115
|
# layout refs below specify layout keys from layouts hash
|
114
116
|
ROLES = [
|
115
|
-
{ :name
|
116
|
-
:class
|
117
|
-
:layouts
|
118
|
-
:services
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
:
|
123
|
-
:
|
124
|
-
|
125
|
-
:
|
126
|
-
|
127
|
-
:
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
:
|
132
|
-
|
133
|
-
|
134
|
-
:
|
135
|
-
:
|
136
|
-
:
|
137
|
-
{ :name
|
138
|
-
:class
|
139
|
-
:layouts
|
140
|
-
:services
|
141
|
-
|
142
|
-
|
143
|
-
:
|
144
|
-
:
|
145
|
-
|
146
|
-
:
|
147
|
-
|
148
|
-
:
|
149
|
-
|
150
|
-
|
117
|
+
{ :name => 'Controller (Nova)',
|
118
|
+
:class => 'quickstack::nova_network::controller',
|
119
|
+
:layouts => [[:non_ha_nova, 1]],
|
120
|
+
:services => [:non_ha_amqp, :mysql, :non_ha_keystone, :nova_controller, :non_ha_glance,
|
121
|
+
:cinder_controller, :heat, :ceilometer],
|
122
|
+
:orchestration => 'concurrent' },
|
123
|
+
{ :name => 'Compute (Nova)',
|
124
|
+
:class => [],
|
125
|
+
:layouts => [[:ha_nova, 10], [:non_ha_nova, 10]],
|
126
|
+
:services => [:nova_compute],
|
127
|
+
:orchestration => 'leader' },
|
128
|
+
{ :name => 'Controller (Neutron)',
|
129
|
+
:class => 'quickstack::neutron::controller',
|
130
|
+
:layouts => [[:non_ha_neutron, 1]],
|
131
|
+
:services => [:non_ha_amqp, :mysql, :non_ha_keystone, :neutron_controller, :non_ha_glance,
|
132
|
+
:cinder_controller, :heat, :ceilometer],
|
133
|
+
:orchestration => 'concurrent' },
|
134
|
+
{ :name => 'Compute (Neutron)',
|
135
|
+
:class => [],
|
136
|
+
:layouts => [[:ha_neutron, 10], [:non_ha_neutron, 10]],
|
137
|
+
:services => [:neutron_compute],
|
138
|
+
:orchestration => 'concurrent' },
|
139
|
+
{ :name => 'Neutron Networker',
|
140
|
+
:class => [],
|
141
|
+
:layouts => [[:non_ha_neutron, 3]],
|
142
|
+
:services => [:neutron_networker],
|
143
|
+
:orchestration => 'concurrent' },
|
144
|
+
{ :name => 'Cinder Block Storage',
|
145
|
+
:class => [],
|
146
|
+
:layouts => [],
|
147
|
+
:services => [:cinder_node],
|
148
|
+
:orchestration => 'concurrent' },
|
149
|
+
{ :name => 'Swift Storage Node',
|
150
|
+
:class => [],
|
151
|
+
:layouts => [],
|
152
|
+
:services => [:swift],
|
153
|
+
:orchestration => 'concurrent' },
|
154
|
+
{ :name => 'HA Controller',
|
155
|
+
:class => [],
|
156
|
+
:layouts => [[:ha_nova, 1], [:ha_neutron, 1]],
|
157
|
+
:services => [:ha_controller, :keystone_ha, :load_balancer_ha, :memcached_ha, :qpid_ha,
|
158
|
+
:glance_ha, :nova_ha, :heat_ha, :cinder_ha, :swift_ha, :horizon_ha, :mysql_ha,
|
159
|
+
:neutron_ha, :galera_ha],
|
160
|
+
:orchestration => 'concurrent' },
|
161
|
+
{ :name => 'Generic RHEL 7',
|
162
|
+
:class => '',
|
163
|
+
:layouts => [[:non_ha_nova, 20],[:non_ha_neutron, 20], [:ha_nova, 20], [:ha_neutron, 20]],
|
164
|
+
:services => [:generic_rhel_7],
|
165
|
+
:orchestration => 'concurrent' },
|
166
|
+
{ :name => 'Ceph Storage Node (OSD)',
|
167
|
+
:class => '',
|
168
|
+
:layouts => [[:non_ha_nova, 20], [:non_ha_neutron, 20], [:ha_nova, 20], [:ha_neutron, 20]],
|
169
|
+
:services => [:ceph_osd],
|
170
|
+
:orchestration => 'concurrent' },
|
171
|
+
]
|
151
172
|
|
152
173
|
CONTROLLER_ROLES = ROLES.select { |h| h.fetch(:name) =~ /Controller/ }
|
174
|
+
CEPH_ROLES = ROLES.select {|h| h.fetch(:name) =~ /Ceph/ }
|
175
|
+
|
176
|
+
ALL_LAYOUTS = LAYOUTS.keys
|
177
|
+
SUBNET_TYPES = { :pxe => { :name => Staypuft::SubnetType::PXE,
|
178
|
+
:required => true,
|
179
|
+
:layouts => ALL_LAYOUTS},
|
180
|
+
:management => { :name => Staypuft::SubnetType::MANAGEMENT,
|
181
|
+
:required => true,
|
182
|
+
:layouts => ALL_LAYOUTS},
|
183
|
+
:external => { :name => Staypuft::SubnetType::EXTERNAL,
|
184
|
+
:required => true,
|
185
|
+
:layouts => ALL_LAYOUTS},
|
186
|
+
:cluster_mgmt => { :name => Staypuft::SubnetType::CLUSTER_MGMT,
|
187
|
+
:required => true,
|
188
|
+
:layouts => ALL_LAYOUTS},
|
189
|
+
:admin_api => { :name => Staypuft::SubnetType::ADMIN_API,
|
190
|
+
:required => true,
|
191
|
+
:layouts => ALL_LAYOUTS},
|
192
|
+
:public_api => { :name => Staypuft::SubnetType::PUBLIC_API,
|
193
|
+
:required => true,
|
194
|
+
:layouts => ALL_LAYOUTS},
|
195
|
+
:tenant => { :name => Staypuft::SubnetType::TENANT,
|
196
|
+
:required => true,
|
197
|
+
:layouts => ALL_LAYOUTS},
|
198
|
+
:storage => { :name => Staypuft::SubnetType::STORAGE,
|
199
|
+
:required => false,
|
200
|
+
:layouts => ALL_LAYOUTS},
|
201
|
+
:storage_cluster => { :name => Staypuft::SubnetType::STORAGE_CLUSTERING,
|
202
|
+
:required => false,
|
203
|
+
:layouts => ALL_LAYOUTS}
|
204
|
+
}
|
153
205
|
|
154
206
|
def get_host_format(param_name)
|
155
207
|
{ :string => '<%%= d = @host.deployment; d.ha? ? d.vips.get(:%s) : d.ips.controller_ip %%>' % param_name }
|
@@ -201,7 +253,7 @@ module Staypuft
|
|
201
253
|
pcmk_fs_manage = { :string => '<%= @host.deployment.glance.pcmk_fs_manage %>' }
|
202
254
|
pcmk_fs_options = { :string => '<%= @host.deployment.glance.pcmk_fs_options %>' }
|
203
255
|
glance_rbd_store_user = 'images'
|
204
|
-
glance_rbd_store_pool = 'images'
|
256
|
+
glance_rbd_store_pool = 'images'
|
205
257
|
|
206
258
|
# Cinder
|
207
259
|
volume = true
|
@@ -662,13 +714,15 @@ module Staypuft
|
|
662
714
|
|
663
715
|
def seed_roles
|
664
716
|
ROLES.each do |role_hash|
|
665
|
-
role = Staypuft::Role.where(:name => role_hash[:name]).
|
717
|
+
role = Staypuft::Role.where(:name => role_hash[:name]).first_or_initialize
|
666
718
|
|
667
719
|
puppet_classes = collect_puppet_classes(Array(role_hash[:class]))
|
668
720
|
puppet_classes.each { |pc| apply_astapor_defaults pc }
|
669
721
|
role.puppetclasses = puppet_classes
|
670
722
|
|
671
723
|
role.description = role_hash[:description]
|
724
|
+
role.orchestration = role_hash[:orchestration]
|
725
|
+
role.save!
|
672
726
|
old_role_services_arr = role.role_services.to_a
|
673
727
|
role_hash[:services].each do |key|
|
674
728
|
role_service = role.role_services.where(:service_id => SERVICES[key][:obj].id).first_or_create!
|
@@ -719,11 +773,31 @@ module Staypuft
|
|
719
773
|
end
|
720
774
|
end
|
721
775
|
|
776
|
+
def seed_subnet_types
|
777
|
+
# default subnet types
|
778
|
+
SUBNET_TYPES.each do |key, subnet_type_hash|
|
779
|
+
subnet_type = Staypuft::SubnetType.where(:name => subnet_type_hash[:name]).first_or_initialize
|
780
|
+
subnet_type.is_required = subnet_type_hash[:required]
|
781
|
+
subnet_type.save!
|
782
|
+
old_layout_subnet_types_arr = subnet_type.layout_subnet_types.to_a
|
783
|
+
subnet_type_hash[:layouts].each do |layout|
|
784
|
+
layout_subnet_type = subnet_type.layout_subnet_types.where(:layout_id => LAYOUTS[layout][:obj].id).first_or_create!
|
785
|
+
old_layout_subnet_types_arr.delete(layout_subnet_type)
|
786
|
+
end
|
787
|
+
# delete any prior mappings that remain
|
788
|
+
old_layout_subnet_types_arr.each do |layout_subnet_type|
|
789
|
+
Rails.logger.warn "destroying old layout_subnet_type for #{layout_subnet_type.layout.name}, #{subnet_type.name}: This should not happen on a clean install"
|
790
|
+
subnet_type.layouts.destroy(layout_subnet_type.layout)
|
791
|
+
end
|
792
|
+
end
|
793
|
+
end
|
794
|
+
|
722
795
|
def seed
|
723
796
|
seed_layouts
|
724
797
|
seed_services
|
725
798
|
seed_roles
|
726
799
|
seed_functional_dependencies
|
800
|
+
seed_subnet_types
|
727
801
|
end
|
728
802
|
|
729
803
|
def collect_puppet_classes(puppet_class_names)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Staypuft
|
2
|
+
module Concerns
|
3
|
+
module HostInterfaceManagement
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
def clean_vlan_interfaces
|
11
|
+
self.interfaces.virtual.map(&:destroy)
|
12
|
+
end
|
13
|
+
|
14
|
+
def interfaces_identifiers
|
15
|
+
interfaces = [ self.primary_interface ]
|
16
|
+
interfaces += self.respond_to?(:interfaces) ? self.interfaces.where("type <> 'Nic::BMC'").physical.map(&:identifier) : []
|
17
|
+
interfaces
|
18
|
+
end
|
19
|
+
|
20
|
+
def make_all_interfaces_managed
|
21
|
+
self.interfaces.each do |interface|
|
22
|
+
interface.managed = true
|
23
|
+
interface.save!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -7,12 +7,13 @@ module Staypuft
|
|
7
7
|
STEP_CONFIGURATION = :configuration
|
8
8
|
STEP_COMPLETE = :complete
|
9
9
|
STEP_OVERVIEW = :overview
|
10
|
+
STEP_NETWORKING = :networking
|
10
11
|
|
11
12
|
NEW_NAME_PREFIX = 'uninitialized_'
|
12
13
|
|
13
14
|
# supporting import/export
|
14
15
|
EXPORT_PARAMS = [:amqp_provider, :networking, :layout_name, :platform]
|
15
|
-
EXPORT_SERVICES = [:nova, :neutron, :glance, :cinder, :passwords]
|
16
|
+
EXPORT_SERVICES = [:nova, :neutron, :glance, :cinder, :passwords]
|
16
17
|
|
17
18
|
attr_accessible :description, :name, :layout_id, :layout,
|
18
19
|
:amqp_provider, :layout_name, :networking, :platform
|
@@ -40,11 +41,17 @@ module Staypuft
|
|
40
41
|
has_many :services, :through => :roles
|
41
42
|
has_many :hosts, :through => :child_hostgroups
|
42
43
|
|
44
|
+
has_many :subnet_typings, :dependent => :destroy
|
45
|
+
has_many :subnet_types, :through => :subnet_typings
|
46
|
+
has_many :subnets, :through => :subnet_typings
|
47
|
+
|
43
48
|
validates :name, :presence => true, :uniqueness => true
|
44
49
|
|
45
50
|
validates :layout, :presence => true
|
46
51
|
validates :hostgroup, :presence => true
|
47
52
|
|
53
|
+
validate :all_required_subnet_types_associated, :if => Proc.new { |o| o.form_step == STEP_NETWORKING }
|
54
|
+
|
48
55
|
after_validation :check_form_complete
|
49
56
|
before_save :update_layout
|
50
57
|
after_save :update_based_on_settings
|
@@ -114,6 +121,10 @@ module Staypuft
|
|
114
121
|
ForemanTasks::Lock.locked? self, nil
|
115
122
|
end
|
116
123
|
|
124
|
+
def hide_ceph_notification?
|
125
|
+
ceph_hostgroup.hosts.empty?
|
126
|
+
end
|
127
|
+
|
117
128
|
# Helper method for getting the in progress foreman task for this
|
118
129
|
# deployment.
|
119
130
|
def task
|
@@ -127,7 +138,7 @@ module Staypuft
|
|
127
138
|
end
|
128
139
|
|
129
140
|
def progress_summary
|
130
|
-
self.in_progress? ? self.task.humanized[:output] : nil
|
141
|
+
self.in_progress? ? self.task.humanized[:output] : nil
|
131
142
|
end
|
132
143
|
|
133
144
|
# Helper method for getting the progress of this deployment
|
@@ -186,7 +197,8 @@ module Staypuft
|
|
186
197
|
|
187
198
|
class Jail < Safemode::Jail
|
188
199
|
allow :amqp_provider, :networking, :layout_name, :platform, :nova_networking?, :neutron_networking?,
|
189
|
-
:nova, :neutron, :glance, :cinder, :passwords, :vips, :ips, :ha?, :non_ha
|
200
|
+
:nova, :neutron, :glance, :cinder, :passwords, :vips, :ips, :ha?, :non_ha?,
|
201
|
+
:hide_ceph_notification?
|
190
202
|
end
|
191
203
|
|
192
204
|
# TODO(mtaylor)
|
@@ -257,6 +269,17 @@ module Staypuft
|
|
257
269
|
first
|
258
270
|
end
|
259
271
|
|
272
|
+
def unassigned_subnet_types
|
273
|
+
self.layout.subnet_types - self.subnet_types
|
274
|
+
end
|
275
|
+
|
276
|
+
def ceph_hostgroup
|
277
|
+
Hostgroup.includes(:deployment_role_hostgroup).
|
278
|
+
where(DeploymentRoleHostgroup.table_name => { deployment_id: self,
|
279
|
+
role_id: Staypuft::Role.cephosd }).
|
280
|
+
first
|
281
|
+
end
|
282
|
+
|
260
283
|
private
|
261
284
|
|
262
285
|
def update_layout
|
@@ -269,6 +292,15 @@ module Staypuft
|
|
269
292
|
update_hostgroup_list
|
270
293
|
end
|
271
294
|
|
295
|
+
def all_required_subnet_types_associated
|
296
|
+
associated_subnet_types = self.subnet_typings.map(&:subnet_type)
|
297
|
+
missing_required = self.layout.subnet_types.required.select { |t| !associated_subnet_types.include?(t) }
|
298
|
+
unless missing_required.empty?
|
299
|
+
errors.add :base,
|
300
|
+
_("Some required subnet types are missing association of a subnet. Please drag and drop following types: %s") % missing_required.map(&:name).join(', ')
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
272
304
|
def update_hostgroup_name
|
273
305
|
hostgroup.name = self.name
|
274
306
|
hostgroup.save!
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class InterfaceAssigner
|
3
|
+
attr_accessor :deployment, :interface, :subnet, :errors
|
4
|
+
|
5
|
+
def initialize(deployment, interface, subnet)
|
6
|
+
@deployment = deployment
|
7
|
+
if interface.is_a?(Nic::Base)
|
8
|
+
@interface = interface
|
9
|
+
else
|
10
|
+
# interface may be Host::Managed which means primary interface, so we create pseudo-interface object
|
11
|
+
@interface = Nic::Managed.new(
|
12
|
+
:mac => interface.mac,
|
13
|
+
:virtual => false,
|
14
|
+
:identifier => interface.primary_interface,
|
15
|
+
:host => interface,
|
16
|
+
:subnet => interface.subnet)
|
17
|
+
end
|
18
|
+
|
19
|
+
@host = @interface.host
|
20
|
+
@subnet = subnet
|
21
|
+
@errors = []
|
22
|
+
end
|
23
|
+
|
24
|
+
def assign
|
25
|
+
if virtual_assignment?
|
26
|
+
if (existing = conflicting_interface)
|
27
|
+
@errors.push _("Another interface %s on same physical interface with same VLAN exists") % existing.identifier
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
ActiveRecord::Base.transaction do
|
31
|
+
unassign_from_other_nics
|
32
|
+
assign_virtual
|
33
|
+
raise ActiveRecord::Rollback if @errors.present?
|
34
|
+
return true
|
35
|
+
end
|
36
|
+
else
|
37
|
+
if @interface.subnet.present? && @interface.subnet != @subnet
|
38
|
+
@errors.push _("Interface is already assigned to subnet %s") % @interface.subnet.name
|
39
|
+
return false
|
40
|
+
end
|
41
|
+
ActiveRecord::Base.transaction do
|
42
|
+
unassign_from_other_nics
|
43
|
+
assign_physical
|
44
|
+
raise ActiveRecord::Rollback if @errors.present?
|
45
|
+
return true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
return false # we can get there only after rollback
|
50
|
+
end
|
51
|
+
|
52
|
+
def unassign
|
53
|
+
base = @host.interfaces
|
54
|
+
base = virtual_assignment? ? base.virtual : base.physical
|
55
|
+
ActiveRecord::Base.transaction do
|
56
|
+
base.where(:subnet_id => @subnet.id).each do |interface|
|
57
|
+
virtual_assignment? ? unassign_virtual(interface) : unassign_physical(interface)
|
58
|
+
end
|
59
|
+
raise ActiveRecord::Rollback if @errors.present?
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def virtual_assignment?
|
64
|
+
@subnet.vlanid.present?
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def assign_virtual
|
70
|
+
interface = Nic::Managed.new(
|
71
|
+
:subnet => @subnet,
|
72
|
+
:physical_device => @interface.identifier,
|
73
|
+
:mac => @interface.mac,
|
74
|
+
:host => @host,
|
75
|
+
:virtual => true,
|
76
|
+
:identifier => @interface.identifier + ".#{@subnet.vlanid}")
|
77
|
+
suggest_ip(interface) if @subnet.ipam?
|
78
|
+
unless interface.save
|
79
|
+
@errors.push(*interface.errors.full_messages)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def assign_physical
|
84
|
+
@interface.subnet = @subnet
|
85
|
+
suggest_ip(@interface) if @subnet.ipam?
|
86
|
+
unless @interface.save
|
87
|
+
@errors.push(*@interface.errors.full_messages)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# we have to be sure that we remove both physical and virtual,
|
92
|
+
# subnet could become virtual/physical meanwhile
|
93
|
+
def unassign_from_other_nics
|
94
|
+
unassign_physicals
|
95
|
+
unassign_virtuals
|
96
|
+
end
|
97
|
+
|
98
|
+
def unassign_physicals
|
99
|
+
@host.interfaces.physical.where(:subnet_id => @subnet.id).each do |interface|
|
100
|
+
unassign_physical(interface)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# if subnet has IP suggesting enabled we also clear the IP that was suggested
|
105
|
+
# this IP will be used for another interface
|
106
|
+
def unassign_physical(interface)
|
107
|
+
interface.ip = nil if interface.subnet.ipam?
|
108
|
+
interface.subnet_id = nil
|
109
|
+
unless interface.save
|
110
|
+
@errors.push(interface.errors.full_messages)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def unassign_virtuals
|
115
|
+
@host.interfaces.virtual.where(:subnet_id => @subnet.id).each do |interface|
|
116
|
+
unassign_virtual(interface)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def unassign_virtual(interface)
|
121
|
+
unless interface.destroy
|
122
|
+
@errors.push _("Interface %s could not be destroyed") % interface.name
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def conflicting_interface
|
127
|
+
@host.interfaces.
|
128
|
+
where(:identifier => @interface.identifier + ".#{subnet.vlanid}").
|
129
|
+
where(['id <> ?', @interface.id]).
|
130
|
+
first
|
131
|
+
end
|
132
|
+
|
133
|
+
def suggest_ip(interface)
|
134
|
+
interface.ip = @subnet.unused_ip if interface.ip.blank?
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -5,6 +5,9 @@ module Staypuft
|
|
5
5
|
has_many :layout_roles, :dependent => :destroy, :order => "staypuft_layout_roles.deploy_order ASC"
|
6
6
|
has_many :roles, :through => :layout_roles, :order => "staypuft_layout_roles.deploy_order ASC"
|
7
7
|
|
8
|
+
has_many :layout_subnet_types, :dependent => :destroy
|
9
|
+
has_many :subnet_types, :through => :layout_subnet_types
|
10
|
+
|
8
11
|
attr_accessible :description, :name, :networking
|
9
12
|
|
10
13
|
validates :name, :presence => true, :uniqueness => {:scope => :networking}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class LayoutSubnetType < ActiveRecord::Base
|
3
|
+
attr_accessible :layout_id, :layout, :subnet_type_id, :subnet_type
|
4
|
+
|
5
|
+
belongs_to :layout
|
6
|
+
belongs_to :subnet_type
|
7
|
+
|
8
|
+
validates :layout, :presence => true
|
9
|
+
validates :subnet_type, :presence => true
|
10
|
+
validates :layout_id, :uniqueness => { :scope => :subnet_type_id }
|
11
|
+
end
|
12
|
+
end
|
data/app/models/staypuft/role.rb
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
module Staypuft
|
2
2
|
class Role < ActiveRecord::Base
|
3
|
+
# until we have puppetssh, "run puppet" below means "provision and run puppet"
|
4
|
+
|
5
|
+
# run puppet on all nodes concurrently
|
6
|
+
ORCHESTRATION_CONCURRENT = "concurrent"
|
7
|
+
# run puppet on one node at a time
|
8
|
+
ORCHESTRATION_SERIAL = "serial"
|
9
|
+
# run puppet on the first mode, then the rest concurrently
|
10
|
+
ORCHESTRATION_LEADER = "leader"
|
11
|
+
|
12
|
+
ORCHESTRATION_MODES = [ORCHESTRATION_CONCURRENT, ORCHESTRATION_SERIAL, ORCHESTRATION_LEADER]
|
13
|
+
|
3
14
|
has_many :layout_roles, :dependent => :destroy
|
4
15
|
has_many :layouts, :through => :layout_roles
|
5
16
|
|
@@ -17,11 +28,15 @@ module Staypuft
|
|
17
28
|
|
18
29
|
validates :name, :presence => true, :uniqueness => true
|
19
30
|
|
31
|
+
validates :orchestration, :inclusion => {:in => ORCHESTRATION_MODES }
|
32
|
+
|
20
33
|
scope(:in_deployment, lambda do |deployment|
|
21
34
|
joins(:deployment_role_hostgroups).
|
22
35
|
where(DeploymentRoleHostgroup.table_name => { deployment_id: deployment })
|
23
36
|
end)
|
24
37
|
|
25
38
|
scope(:controller, where(name: Seeder::CONTROLLER_ROLES.map { |h| h.fetch(:name) }))
|
39
|
+
|
40
|
+
scope(:cephosd, where(name: Seeder::CEPH_ROLES.map { |h| h.fetch(:name) }))
|
26
41
|
end
|
27
42
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class SubnetType < ActiveRecord::Base
|
3
|
+
PXE = 'Provisioning/PXE'
|
4
|
+
|
5
|
+
MANAGEMENT = 'Management'
|
6
|
+
EXTERNAL = 'External'
|
7
|
+
CLUSTER_MGMT = 'Cluster Management'
|
8
|
+
ADMIN_API = 'Admin API'
|
9
|
+
PUBLIC_API = 'Public API'
|
10
|
+
TENANT = 'Tenant'
|
11
|
+
|
12
|
+
STORAGE = 'Storage'
|
13
|
+
STORAGE_CLUSTERING = 'Storage Clustering'
|
14
|
+
|
15
|
+
validates :name, :presence => true
|
16
|
+
|
17
|
+
has_many :layout_subnet_types, :dependent => :destroy
|
18
|
+
has_many :layouts, :through => :layout_subnet_types
|
19
|
+
|
20
|
+
attr_accessible :name
|
21
|
+
|
22
|
+
has_many :subnet_typings
|
23
|
+
has_many :subnets, :through => :subnet_typings
|
24
|
+
|
25
|
+
scope :required, lambda { where(:is_required => true) }
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class SubnetTyping < ActiveRecord::Base
|
3
|
+
belongs_to :deployment
|
4
|
+
belongs_to :subnet_type
|
5
|
+
belongs_to :subnet
|
6
|
+
|
7
|
+
attr_accessible :subnet_type, :subnet_type_id, :subnet, :subnet_id
|
8
|
+
|
9
|
+
validates :subnet_type_id, :uniqueness => { :scope => :deployment_id }
|
10
|
+
end
|
11
|
+
end
|
@@ -5,7 +5,10 @@
|
|
5
5
|
<div class="pull-right top_actions">
|
6
6
|
<%= render partial: "hosts_filter" %>
|
7
7
|
<div class="pull-right">
|
8
|
-
|
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"%>
|
9
12
|
<%= submit_tag _("Unassign Hosts"), :class => "btn btn-primary btn-sm", :disabled => true, :id => "unassign_hosts_button" %>
|
10
13
|
</div>
|
11
14
|
</div>
|
@@ -40,7 +43,7 @@
|
|
40
43
|
</td>
|
41
44
|
<td><%= host.cpus %></td>
|
42
45
|
<td><%= host.mem %></td>
|
43
|
-
<td><%= host
|
46
|
+
<td><%= host_nics(host) %></td>
|
44
47
|
<td class="hidden-s hidden-xs"><%= host.ip %></td>
|
45
48
|
</tr>
|
46
49
|
<% end %>
|
@@ -1,60 +1,27 @@
|
|
1
1
|
<div class="tab-pane" id="<%= child_hostgroup.name.parameterize.underscore %>_assigned_hosts">
|
2
|
-
<% if
|
2
|
+
<% if hosts.present? %>
|
3
3
|
<%= form_tag(unassign_host_deployment_path(id: deployment), class: 'form-horizontal well association') do |f| %>
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
<p class="clearfix"></p>
|
8
|
-
<%= hidden_field_tag :hostgroup_id, child_hostgroup.id %>
|
4
|
+
|
5
|
+
<%= render 'hosts_header', :header => _("Assigned Hosts"), :child_hostgroup => child_hostgroup, :assign_text => _("Unassign Hosts") %>
|
6
|
+
|
9
7
|
<table class="table table-bordered table-striped table-condensed">
|
10
8
|
<thead>
|
11
|
-
|
12
|
-
<th class="ca">
|
13
|
-
<%= tag :input, type: 'checkbox', class: 'check_all' %>
|
14
|
-
</th>
|
15
|
-
<th><%= sort :name, :as => _('Name') %></th>
|
16
|
-
<th class="hidden-s hidden-xs"><%= _('Deploying?') %></th>
|
17
|
-
<th class="hidden-s hidden-xs"><%= sort :ip, :as => _('IP Address') %></th>
|
18
|
-
</tr>
|
9
|
+
<%= render 'host_head_row', :deploying_col => true %>
|
19
10
|
</thead>
|
20
11
|
<tbody>
|
21
|
-
<%
|
12
|
+
<% hosts.each do |host| %>
|
22
13
|
<% disabled = ForemanTasks::Lock.locked?(deployment, nil) && host.open_stack_deployed? %>
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
host.id,
|
29
|
-
false,
|
30
|
-
id: "host_ids_#{host.id}",
|
31
|
-
disabled: disabled %>
|
32
|
-
<%= hidden_field_tag 'host_ids[]', host.id if disabled %>
|
33
|
-
</td>
|
34
|
-
<td class="ellipsis">
|
35
|
-
<%= host_label(host) %>
|
36
|
-
</td>
|
37
|
-
<td class="hidden-s hidden-xs">
|
38
|
-
<% if disabled %>
|
39
|
-
<span class="glyphicon glyphicon-cloud-upload"></span>
|
40
|
-
<% else %>
|
41
|
-
<span class="glyphicon glyphicon-minus"></span>
|
42
|
-
<% end %>
|
43
|
-
</td>
|
44
|
-
<td class="hidden-s hidden-xs"><%= host.ip %></td>
|
45
|
-
</tr>
|
14
|
+
<%= render 'host_row',
|
15
|
+
:custom_css_class => disabled ? 'deploying' : '',
|
16
|
+
:disabled => disabled,
|
17
|
+
:host => host,
|
18
|
+
:checkbox_value => false %>
|
46
19
|
<% end %>
|
47
20
|
</tbody>
|
48
21
|
</table>
|
22
|
+
|
49
23
|
<% end %>
|
50
24
|
<% else %>
|
51
|
-
|
52
|
-
<button type="button" class="close pull-right" aria-hidden="true">×</button>
|
53
|
-
<h4><%= _("Assigned Hosts") %></h4>
|
54
|
-
<div class="alert alert-warning">
|
55
|
-
<span class="glyphicon glyphicon-warning-sign"> </span>
|
56
|
-
<%= _("No hosts were assigned to this group yet.") %>
|
57
|
-
</div>
|
58
|
-
</div>
|
25
|
+
<%= render 'empty_hosts', :header => _("Assigned Hosts"), :message => _("No hosts were assigned to this group yet.") %>
|
59
26
|
<% end %>
|
60
27
|
</div>
|