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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21289b770a15e38194b88261c2de8622344538f5
4
- data.tar.gz: d53a1a5ca729733020a5da1e539cd3c46f6422e9
3
+ metadata.gz: ffc4713af541fbd45de1031951ef127af36cc43d
4
+ data.tar.gz: 74e411dad81c3260b1d636be7728443c7488863a
5
5
  SHA512:
6
- metadata.gz: 08d0914ace7e6cfeadcc1f618bba70a765a3ff02ed933ffb5272d169a8b8e96654f333dd33dc3342742f6ac862476b7be31bd9e2e82e7543264f26b26c8766de
7
- data.tar.gz: dab396f6ac46c3ca10b0f614ed42671a88a7ecef079887ee47457b96e53e2e169fb5af26236b458a7bcace11785e98268894eebb0bac0e7482da75eaad5833e7
6
+ metadata.gz: 25789e7b3464ad1bdb69777ff80f23f9c5723d33e2c26f544f661f5c00eadd6bba7a3fd65dda4a7a8f25aa060792839fccd30eaee5b8867d5d994d78a28c0c1d
7
+ data.tar.gz: 227301210b654338dc414554bc5b32684ca0719052261003227f05f06e0ec75f850a975ce1702710f844b558f184a11470d61f01234ca708306a3c6977e2e8e2
@@ -1,11 +1,11 @@
1
- $(function() {
1
+ var nics_assignment = (function() {
2
2
  $("div.subnet-pull.active").draggable({
3
3
  revert: 'invalid'
4
4
  });
5
5
 
6
6
  $("div.interface").droppable({
7
- activeClass: "ui-state-default",
8
- hoverClass: "ui-state-hover",
7
+ activeClass: "panel-droppable",
8
+ hoverClass: "panel-success",
9
9
  accept: "div.subnet-pull",
10
10
  drop: function(event, ui) {
11
11
  $.ajax({
@@ -17,8 +17,8 @@ $(function() {
17
17
  }
18
18
  });
19
19
  $("#subnets").droppable({
20
- activeClass: "ui-state-default",
21
- hoverClass: "ui-state-hover",
20
+ activeClass: "panel-droppable",
21
+ hoverClass: "panel-success",
22
22
  accept: "div.subnet-pull.existing",
23
23
  drop: function(event, ui) {
24
24
  $.ajax({
@@ -124,9 +124,9 @@ $(function () {
124
124
  }
125
125
 
126
126
  showCinderNfsUri();
127
- $("input[name='staypuft_deployment[cinder][driver_backend]']").change(showCinderNfsUri);
127
+ $("#staypuft_deployment_cinder_backend_nfs").change(showCinderNfsUri);
128
128
  function showCinderNfsUri() {
129
- if ($('#staypuft_deployment_cinder_driver_backend_nfs').is(":checked")) {
129
+ if ($('#staypuft_deployment_cinder_backend_nfs').is(":checked")) {
130
130
  $('.cinder_nfs_uri').show();
131
131
  }
132
132
  else {
@@ -135,10 +135,13 @@ $(function () {
135
135
  }
136
136
 
137
137
  showCinderEquallogic();
138
- $("input[name='staypuft_deployment[cinder][driver_backend]']").change(showCinderEquallogic);
138
+ $("#staypuft_deployment_cinder_backend_eqlx").change(showCinderEquallogic);
139
139
  function showCinderEquallogic() {
140
- if ($('#staypuft_deployment_cinder_driver_backend_equallogic').is(":checked")) {
140
+ if ($('#staypuft_deployment_cinder_backend_eqlx').is(":checked")) {
141
141
  $('.cinder_equallogic').show();
142
+ if($('#eqlxs').children().length == 0) {
143
+ $('.add_another_server').click();
144
+ }
142
145
  }
143
146
  else {
144
147
  $('.cinder_equallogic').hide();
@@ -206,6 +209,33 @@ $(function () {
206
209
  window.location.hash = "#hosts";
207
210
  });
208
211
 
212
+ $('#configure_networks_modal').on('shown.bs.modal', function(e) {
213
+ var height = $(window).height() - 200;
214
+ $(this).find(".modal-body").css("max-height", height);
215
+ var to_assign = $("input:checkbox[name=host_ids[]]:checked").map(
216
+ function() {
217
+ return $(this).attr('value');
218
+ }).get().join();
219
+ /* remove the first if it's the select all */
220
+ if(to_assign.substr(0,2) == 'on') {
221
+ to_assign = to_assign.substr(3);
222
+ }
223
+ var to_path = $('#configure_networks_modal').data('path');
224
+ $.ajax({
225
+ url: to_path,
226
+ type: "GET",
227
+ //Pass in each variable as a parameter.
228
+ data: {
229
+ host_ids: to_assign
230
+ },
231
+ success: function(data){
232
+ $('#interfaces').html(data).promise().done(function(){
233
+ nics_assignment();
234
+ });
235
+ }
236
+ });
237
+ });
238
+
209
239
  var scrolled = false;
210
240
 
211
241
  $(window).scroll(function(){
@@ -248,5 +278,28 @@ $(function () {
248
278
  }).show();
249
279
  });
250
280
 
251
- $('.inner-nav').click(function(){ hosts_filter.val("").keyup(); });
281
+ /* clear filter if switching */
282
+ $('.inner-nav').click(function(){ hosts_filter.val("").keyup(); });
283
+
284
+ // add more highlighting for tabs with errors
285
+ $(".tab-content").find(".form-group.has-error").each(function(index) {
286
+ var id = $(this).parentsUntil(".tab-content").last().attr("id");
287
+ $("a[href=#"+id+"]").parent().addClass("tab-error");
288
+ })
289
+
290
+ $("button.add_another_server").live("click", function() {
291
+ var eqlx_form = function () {
292
+ return $('#eqlx_form_template').text().replace(/NEW_RECORD/g, new Date().getTime());
293
+ }
294
+ $('#eqlxs').append(eqlx_form());
295
+ if($('#eqlxs').children().length > 1) {
296
+ var added_form_span = $('#eqlxs').children().last().find('h5').find('.server_number');
297
+ var previous_span_number = $('#eqlxs').children().eq(-2).find('h5').find('.server_number');
298
+ added_form_span.html(parseInt(previous_span_number.html(), 10) + 1);
299
+ }
300
+ })
301
+
302
+ $(".eqlx h5 a.remove").live("click", function(){
303
+ $(this).parent().parent().remove();
304
+ });
252
305
  });
@@ -4,8 +4,8 @@ $(function() {
4
4
  });
5
5
 
6
6
  $("div.subnet-drop-zone").droppable({
7
- activeClass: "ui-state-default",
8
- hoverClass: "ui-state-hover",
7
+ activeClass: "panel-droppable",
8
+ hoverClass: "panel-success",
9
9
  accept: "div.subnet-type-pull",
10
10
  drop: function(event, ui) {
11
11
  if(ui.draggable.hasClass('new')) {
@@ -26,8 +26,9 @@ $(function() {
26
26
  }
27
27
  });
28
28
  $("#subnet_types").droppable({
29
- activeClass: "ui-state-default",
30
- hoverClass: "ui-state-hover",
29
+ activeClass: "panel-droppable",
30
+ hoverClass: "panel-success",
31
+ accept: "div.subnet-type-pull",
31
32
  accept: "div.subnet-type-pull.existing",
32
33
  drop: function(event, ui) {
33
34
  $.ajax({
@@ -74,6 +74,22 @@
74
74
  -webkit-transform:rotate(360deg);
75
75
  }
76
76
  }
77
+
78
+ & > li.tab-error > a.tab-error span {
79
+ visibility: visible !important;
80
+ padding-left: 6px;
81
+ }
82
+
83
+ & > li.tab-error.active {
84
+ a {
85
+ background-color: $state-danger-text;
86
+ color: white !important;
87
+ }
88
+
89
+ a:after {
90
+ border-color: transparent transparent transparent $state-danger-text;
91
+ }
92
+ }
77
93
  }
78
94
  .tab-content {
79
95
  min-height: 520px;
@@ -124,92 +124,51 @@ span.editable, span.editable:hover {
124
124
  }
125
125
  }
126
126
 
127
- $pull_line_height: 40px;
128
- .subnet-type-pull, .empty-zone {
129
- height: $pull_line_height;
130
- line-height: $pull_line_height;
131
- }
132
-
127
+ // subnet and nics drag 'n drop association
133
128
  .subnet-type-pull, .subnet-pull, .empty-zone {
134
- float: left;
135
- min-width: 100px;
136
- text-align: center;
137
- margin-left: 10px;
138
- background-color: #f5f5f5;
139
- border-color: #000;
140
- border-width: 1px;
141
- }
142
-
143
- .subnet-type-pull, .subnet-pull {
144
- z-index: 1;
145
- border-style: solid;
146
- background-color: #ffffff;
147
- }
148
-
149
- .subnet-type-pull, .subnet-pull.active {
150
- cursor: pointer;
151
- background-color: #f5f5f5;
129
+ @extend .btn;
130
+ @extend .btn-default;
131
+ background: $well-bg;
132
+ margin: 3px 0;
133
+ &:active, &.active {
134
+ box-shadow: none;
135
+ z-index: 1;
136
+ }
152
137
  }
153
138
 
154
139
  .subnet-pull {
155
- height: $pull_line_height;
156
- display: table;
157
- padding-left: 5px;
158
- padding-right: 5px;
159
- margin-top: 10px;
160
-
161
- .name {
162
- font-weight: bold;
140
+ text-align: left;
141
+ .virtual {
142
+ background-color: #d7f5f5;
163
143
  }
164
-
165
- .content {
166
- display: table-cell;
167
- vertical-align: middle;
168
- }
169
- }
170
-
171
- .subnet-pull.virtual {
172
- background-color: #d7f5f5;
173
- }
174
-
175
- div.cleared {
176
- clear: left;
177
144
  }
178
145
 
179
146
  .empty-zone {
180
147
  border-style: dashed;
148
+ background: transparent;
149
+ min-width: 100px;
150
+ &:hover, &:active {
151
+ background: transparent;
152
+ box-shadow: none;
153
+ }
181
154
  }
182
155
 
183
- .subnet-drop-zone {
184
- border: 1px solid black;
185
- height: 90px;
186
- margin-bottom: 10px;
187
-
188
- .name {
189
- margin-left: 5px;
190
- margin-top: 5px;
191
- margin-bottom: 10px;
192
- font-weight: bold;
156
+ .subnet-drop-zone.panel-droppable,
157
+ #subnet_types.panel-droppable,
158
+ .interface.panel-droppable,
159
+ #subnets.panel-droppable {
160
+ border: 1px solid $panel-success-text;
161
+ .empty-zone {
162
+ border: 1px dashed $panel-success-text;
193
163
  }
194
164
  }
195
165
 
196
- div.interface {
197
- margin-bottom: 10px;
198
-
199
- div.identifier {
200
- float: left;
201
- width: 70px;
202
- border: 1px solid #000;
203
- height: $pull_line_height + 20px;
204
- line-height: $pull_line_height + 20px;
205
- text-align: center;
206
- font-weight: bold;
166
+ #configure_networks_modal {
167
+ .modal-dialog {
168
+ width: 90%;
207
169
  }
208
170
 
209
- div.subnet-drop-zones {
210
- border: 1px solid #000;
211
- padding-top: 10px;
212
- width: 100%;
213
- height: $pull_line_height + 20px;
171
+ .modal-body{
172
+ overflow-y: auto;
214
173
  }
215
174
  }
@@ -115,14 +115,26 @@ module Staypuft
115
115
 
116
116
  hosts_to_unassign = ::Host::Base.find Array(params[:host_ids])
117
117
 
118
+ removed_vips_hostgroup = nil
118
119
  hosts_to_unassign.each do |host|
119
120
  unless host.open_stack_deployed? && deployment_in_progress
121
+ vip_interfaces = host.interfaces.vip
122
+ removed_vips_hostgroup = host.hostgroup unless vip_interfaces.empty?
123
+ vip_interfaces.each(&:destroy)
120
124
  host.open_stack_unassign
121
125
  host.environment = Environment.get_discovery
122
126
  host.save!
123
127
  host.setBuild
124
128
  end
125
129
  end
130
+ if removed_vips_hostgroup
131
+ removed_vips_hostgroup.reload
132
+ newhost = removed_vips_hostgroup.hosts.first
133
+ unless newhost.nil?
134
+ build_vips_if_needed(newhost)
135
+ newhost.save!
136
+ end
137
+ end
126
138
 
127
139
  redirect_to deployment_path(deployment)
128
140
  end
@@ -195,6 +207,9 @@ module Staypuft
195
207
  # by default foreman will try to manage all NICs unless user disables manually after assignment
196
208
  host.make_all_interfaces_managed
197
209
 
210
+ # we create VIPs interfaces if this is the first host in Controller HA hostgroup
211
+ build_vips_if_needed(host)
212
+
198
213
  # I do not why but the final save! adds following condytion to the update SQL command
199
214
  # "WHERE "hosts"."type" IN ('Host::Managed') AND "hosts"."id" = 283"
200
215
  # which will not find the record since it's still Host::Discovered.
@@ -207,6 +222,14 @@ module Staypuft
207
222
  discovered_host.becomes(Host::Base).update_column(:type, original_type) unless saved
208
223
  end
209
224
  end
225
+
226
+ def build_vips_if_needed(host)
227
+ hostgroup = host.hostgroup
228
+ hostgroup.reload if hostgroup
229
+ if hostgroup && hostgroup.deployment.ha? && (hostgroup == hostgroup.deployment.controller_hostgroup) && hostgroup.hosts.all? { |h| h.interfaces.vip.empty? }
230
+ host.build_vips(Staypuft::NetworkQuery::VIP_NAMES)
231
+ end
232
+ end
210
233
  end
211
234
 
212
235
  end
@@ -1,11 +1,12 @@
1
1
  module Staypuft
2
2
  class InterfaceAssignmentsController < Staypuft::ApplicationController
3
+ layout false
3
4
  def index
4
5
  @deployment = Deployment.find(params[:deployment_id])
5
6
  @hosts = Host::Managed.where(:id => params[:host_ids]).includes(:interfaces)
6
7
  @subnets = @deployment.subnets.uniq
7
8
  @host = @hosts.first
8
- @interfaces = @host ? @host.interfaces.where("type <> 'Nic::BMC'").order(:identifier).physical : []
9
+ @interfaces = @host ? @host.interfaces.where("type <> 'Nic::BMC'").non_vip.order(:identifier).physical : []
9
10
 
10
11
  errors = {}
11
12
  @hosts.each do |host|
@@ -1,12 +1,95 @@
1
1
  module Staypuft
2
2
  class NetworkQuery
3
3
 
4
+ VIP_NAMES = {
5
+ :ceilometer_admin_vip => Staypuft::SubnetType::ADMIN_API,
6
+ :ceilometer_private_vip => Staypuft::SubnetType::MANAGEMENT,
7
+ :ceilometer_public_vip => Staypuft::SubnetType::PUBLIC_API,
8
+ :cinder_admin_vip => Staypuft::SubnetType::ADMIN_API,
9
+ :cinder_private_vip => Staypuft::SubnetType::MANAGEMENT,
10
+ :cinder_public_vip => Staypuft::SubnetType::PUBLIC_API,
11
+ :db_vip => Staypuft::SubnetType::MANAGEMENT,
12
+ :glance_admin_vip => Staypuft::SubnetType::ADMIN_API,
13
+ :glance_private_vip => Staypuft::SubnetType::MANAGEMENT,
14
+ :glance_public_vip => Staypuft::SubnetType::PUBLIC_API,
15
+ :heat_admin_vip => Staypuft::SubnetType::ADMIN_API,
16
+ :heat_private_vip => Staypuft::SubnetType::MANAGEMENT,
17
+ :heat_public_vip => Staypuft::SubnetType::PUBLIC_API,
18
+ :heat_cfn_admin_vip => Staypuft::SubnetType::ADMIN_API,
19
+ :heat_cfn_private_vip => Staypuft::SubnetType::MANAGEMENT,
20
+ :heat_cfn_public_vip => Staypuft::SubnetType::PUBLIC_API,
21
+ :horizon_admin_vip => Staypuft::SubnetType::ADMIN_API,
22
+ :horizon_private_vip => Staypuft::SubnetType::MANAGEMENT,
23
+ :horizon_public_vip => Staypuft::SubnetType::PUBLIC_API,
24
+ :keystone_admin_vip => Staypuft::SubnetType::ADMIN_API,
25
+ :keystone_private_vip => Staypuft::SubnetType::MANAGEMENT,
26
+ :keystone_public_vip => Staypuft::SubnetType::PUBLIC_API,
27
+ :loadbalancer_vip => Staypuft::SubnetType::PUBLIC_API,
28
+ :neutron_admin_vip => Staypuft::SubnetType::ADMIN_API,
29
+ :neutron_private_vip => Staypuft::SubnetType::MANAGEMENT,
30
+ :neutron_public_vip => Staypuft::SubnetType::PUBLIC_API,
31
+ :nova_admin_vip => Staypuft::SubnetType::ADMIN_API,
32
+ :nova_private_vip => Staypuft::SubnetType::MANAGEMENT,
33
+ :nova_public_vip => Staypuft::SubnetType::PUBLIC_API,
34
+ :amqp_vip => Staypuft::SubnetType::MANAGEMENT,
35
+ :swift_public_vip => Staypuft::SubnetType::PUBLIC_API,
36
+ :keystone_private_vip => Staypuft::SubnetType::MANAGEMENT
37
+ }
38
+ COUNT = VIP_NAMES.size
39
+
4
40
  def initialize(deployment)
5
41
  @deployment = deployment
6
42
  end
7
43
 
44
+ def ip_for_host(host, subnet_type_name)
45
+ interface_hash_for_host(host, subnet_type_name)[:ip]
46
+ end
47
+
48
+ def interface_for_host(host, subnet_type_name)
49
+ interface_hash_for_host(host, subnet_type_name)[:interface]
50
+ end
51
+
52
+ def controllers
53
+ @controllers ||= @deployment.controller_hostgroup.hosts.order(:id)
54
+ end
55
+
56
+ def controller_ips(subnet_type_name)
57
+ controllers.map { |controller| ip_for_host(controller, subnet_type_name) }
58
+ end
59
+
60
+ def controller_ip(subnet_type_name)
61
+ ip_for_host(controllers.tap { |v| v.size == 1 or raise }.first, subnet_type_name)
62
+ end
63
+
64
+ def controller_fqdns
65
+ controllers.map &:fqdn
66
+ end
67
+
68
+ def vip_controller
69
+ controllers.each do |controller|
70
+ return controller unless controller.interfaces.vip.empty?
71
+ end
72
+ return nil
73
+ end
74
+
75
+ def get_vip(vip_name)
76
+ if VIP_NAMES[vip_name]
77
+ controller = vip_controller
78
+ interface = controller.interfaces.vip.where(:tag => vip_name).first if controller
79
+ interface.ip if interface
80
+ end
81
+ end
82
+
83
+ class Jail < Safemode::Jail
84
+ allow :ip_for_host, :interface_for_host, :controller_ip, :controller_ips, :controller_fqdns, :get_vip
85
+ end
86
+
8
87
  private
9
88
  def interface_hash_for_host(host, subnet_type_name)
89
+ if host.nil?
90
+ raise ArgumentError, "no host specified"
91
+ end
92
+
10
93
  subnet_type = @deployment.layout.subnet_types.where(:name=> subnet_type_name).first
11
94
 
12
95
  # raise error if no subnet with this name is assigned to this layout
@@ -16,19 +99,19 @@ module Staypuft
16
99
 
17
100
  subnet_typing = @deployment.subnet_typings.where(:subnet_type_id => subnet_type.id).first
18
101
  # if this subnet type isn't assigned to a subnet for this deployment, return nil
19
- return nil if subnet_typing.nil?
102
+ return {} if subnet_typing.nil?
20
103
  subnet = subnet_typing.subnet
21
104
 
22
- secondary_iface = host.interfaces.where(:subnet_id => subnet.id).first
105
+ secondary_iface = host.interfaces.non_vip.where(:subnet_id => subnet.id).first
23
106
  # check for primary interface
24
107
  if (host.subnet_id == subnet.id)
25
108
  {:subnet => host.subnet, :ip => host.ip,
26
109
  :interface => host.primary_interface, :mac => host.mac }
27
- elsif !iface.nil?
110
+ elsif !secondary_iface.nil?
28
111
  {:subnet => secondary_iface.subnet, :ip => secondary_iface.ip,
29
- :interface => secondary_iface.name, :mac => secondary_iface.mac }
112
+ :interface => secondary_iface.identifier, :mac => secondary_iface.mac }
30
113
  else
31
- nil
114
+ {}
32
115
  end
33
116
  end
34
117
  end