staypuft 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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