staypuft 0.1.22 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +6 -0
  3. data/app/assets/javascripts/staypuft/staypuft.js +60 -0
  4. data/app/assets/stylesheets/staypuft/staypuft.css.scss +23 -0
  5. data/app/controllers/staypuft/deployments_controller.rb +1 -1
  6. data/app/helpers/staypuft/application_helper.rb +11 -0
  7. data/app/lib/staypuft/seeder.rb +22 -18
  8. data/app/models/staypuft/concerns/host_details_helper.rb +39 -0
  9. data/app/models/staypuft/deployment.rb +9 -4
  10. data/app/models/staypuft/deployment/cinder_service.rb +104 -17
  11. data/app/models/staypuft/deployment/glance_service.rb +30 -6
  12. data/app/models/staypuft/deployment/neutron_service.rb +1 -1
  13. data/app/models/staypuft/deployment/vlan_range_values_validator.rb +1 -1
  14. data/app/views/staypuft/deployments/{summary.html.erb → _advanced_configuration.html.erb} +20 -18
  15. data/app/views/staypuft/deployments/_assigned_hosts.html.erb +47 -0
  16. data/app/views/staypuft/deployments/_deployed_hosts.html.erb +47 -0
  17. data/app/views/staypuft/deployments/_deployment_hosts.html.erb +21 -0
  18. data/app/views/staypuft/deployments/_deployment_networking.html.erb +1 -0
  19. data/app/views/staypuft/deployments/_deployment_overview.html.erb +95 -0
  20. data/app/views/staypuft/deployments/_deployment_show_header.html.erb +44 -0
  21. data/app/views/staypuft/deployments/_free_hosts.html.erb +48 -0
  22. data/app/views/staypuft/deployments/_free_hosts_table.html.erb +2 -2
  23. data/app/views/staypuft/deployments/edit.html.erb +2 -9
  24. data/app/views/staypuft/deployments/show.html.erb +17 -134
  25. data/app/views/staypuft/steps/_cinder.html.erb +13 -0
  26. data/lib/staypuft/engine.rb +1 -0
  27. data/lib/staypuft/version.rb +1 -1
  28. metadata +94 -96
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b4c1705398e46ec5568abc0ab8335dff279719c9
4
+ data.tar.gz: 3f47eaa170912b118662a4408cc64dc8c284812b
5
+ SHA512:
6
+ metadata.gz: 0aec5dc5dd3bebcf6b3b71baf37c76698afd99b67b3c3f951532ff98149c54b4858c19a4da61b6de1cf37bc69a004583ba2afba782e78727cd606fdbc24b5253
7
+ data.tar.gz: faab17c4c5d7271394c7140f2d92538e4c83c2b073e7cf1827c71072ad92822f0ce81262ee642d14b8ac7ca83ac67359dc74679a8a0a602e53c7cf3d582110ec
data/README.md CHANGED
@@ -33,6 +33,12 @@ remote is github.com/theforeman/staypuft. Now bump the version in lib/staypuft/v
33
33
  Finally build and release new gem by running `rake release`. This will build the package,
34
34
  tag the commit, push the commit and the tag to origin and uploads the gem to rubygems.org.
35
35
 
36
+ To build and RPM we recommend using our specs in [Foreman packaging](https://github.com/theforeman/foreman-packaging).
37
+ You should find the spec in rpm/develop branch. There's also a README.md which explains
38
+ how you should update and build a package. Long story short, you update the gem and spec,
39
+ send and send a PR. Once it's merged you can build in our koji instance (if you have
40
+ access) using tito.
41
+
36
42
  ## Copyright
37
43
 
38
44
  Copyright (c) 2014 Red Hat, Inc. http://redhat.com
@@ -116,8 +116,68 @@ $(function () {
116
116
  }
117
117
  }
118
118
 
119
+ showCinderEquallogic();
120
+ $("input[name='staypuft_deployment[cinder][driver_backend]']").change(showCinderEquallogic);
121
+ function showCinderEquallogic() {
122
+ if ($('#staypuft_deployment_cinder_driver_backend_equallogic').is(":checked")) {
123
+ $('.cinder_equallogic').show();
124
+ }
125
+ else {
126
+ $('.cinder_equallogic').hide();
127
+ }
128
+ }
129
+
119
130
  if ($('.configuration').length > 0) {
120
131
  $('.configuration').find('li').first().find('a')[0].click();
121
132
  }
122
133
 
134
+ // add a hash to the URL when the user clicks on a tab
135
+ $('a[data-toggle="tab"]').on('click', function(e) {
136
+ if(!$(this).hasClass("sub-tab")){
137
+ history.pushState(null, null, $(this).attr('href'));
138
+ }
139
+ });
140
+ // navigate to a tab when the history changes
141
+ window.addEventListener("popstate", function(e) {
142
+ var activeTab = $('[href=' + location.hash + ']');
143
+ if (activeTab.length) {
144
+ activeTab.tab('show');
145
+ } else {
146
+ $('.nav-tabs a:first').tab('show');
147
+ }
148
+ });
149
+
150
+ // Javascript to enable link to tab
151
+ var hash = document.location.hash;
152
+ var prefix = "tab_";
153
+ if (hash) {
154
+ $('.nav-tabs a[href='+hash.replace(prefix,"")+']').tab('show');
155
+ }
156
+
157
+ // Change hash for page-reload
158
+ $('.nav-tabs a').on('shown', function (e) {
159
+ window.location.hash = e.target.hash.replace("#", "#" + prefix);
160
+ });
161
+
162
+ $('#edit_staypuft_deployment_submit').click(function (e) {
163
+ $('#edit_staypuft_deployment').submit();
164
+ e.preventDefault();
165
+ });
166
+
167
+
168
+ $('#deploy_modal').on('shown.bs.modal', function(e) {
169
+ $('#sub-navigation a[href="#overview"]').tab('show');
170
+ window.location.hash = "#overview";
171
+ });
172
+
173
+ var scrolled = false;
174
+
175
+ $(window).scroll(function(){
176
+ scrolled = true;
177
+ });
178
+
179
+ if ( window.location.hash && scrolled ) {
180
+ $(window).scrollTop( 0 );
181
+ }
182
+
123
183
  });
@@ -15,6 +15,17 @@
15
15
  @import "bootstrap/buttons";
16
16
  @import "bootstrap/forms";
17
17
 
18
+ ul.inner-nav {
19
+ border: 0 !important;
20
+ }
21
+
22
+ li.inner-nav a {
23
+ border: 0 !important;
24
+ }
25
+
26
+ li.inner-nav.active a {
27
+ text-decoration:underline;
28
+ }
18
29
  .deployment-wizard .wizard {
19
30
  width: 100%;
20
31
  float: left;
@@ -27,6 +38,18 @@
27
38
  margin-left: 10px;
28
39
  }
29
40
 
41
+ .deployment-wizard form {
42
+ min-height: 705px;
43
+ position: relative;
44
+ padding-bottom: 60px;
45
+ }
46
+
47
+ .deployment-wizard .form_actions {
48
+ position: absolute;
49
+ bottom: 20px;
50
+ right: 20px;
51
+ }
52
+
30
53
  .top_actions {
31
54
  //same margin as h1 (title)
32
55
  margin: 20px 0 10px;
@@ -44,7 +44,7 @@ module Staypuft
44
44
  end
45
45
  end
46
46
  end
47
- redirect_to summary_deployment_path(params[:id])
47
+ redirect_to "#{deployment_path(params[:id])}#advanced_configuration"
48
48
  end
49
49
 
50
50
  format.json do
@@ -5,6 +5,17 @@ module Staypuft
5
5
  content_for(:subtitle, page_subtitle.to_s)
6
6
  end
7
7
 
8
+ def tabbed_nav_menu(menu_items, id=nil, class_name=nil, subclass_name=nil)
9
+ content_tag(:ul, :class => class_name, :id => id) do
10
+ menu_items.each do | item |
11
+ concat(content_tag(:li, link_to(item[:title], "#{item[:target_id]}",
12
+ :class => subclass_name,
13
+ :data => { :id => item[:target_id], :toggle => 'tab'}),
14
+ :class => item[:active] ? "#{item[:class]} active" : item[:class] ))
15
+ end
16
+ end
17
+ end
18
+
8
19
  def radio_button_f_non_inline(f, attr, options = {})
9
20
  text = options.delete(:text)
10
21
  value = options.delete(:value)
@@ -182,8 +182,8 @@ module Staypuft
182
182
  ml2_network_vlan_ranges = ovs_vlan_ranges
183
183
  tenant_network_type = '<%= @host.deployment.neutron.network_segmentation %>'
184
184
  ml2_tenant_network_types = [ tenant_network_type ]
185
- ml2_tunnel_id_ranges = ['10:100000']
186
- ml2_vni_ranges = ['10:100000']
185
+ ml2_tunnel_id_ranges = ['10:1000']
186
+ ml2_vni_ranges = ['10:1000']
187
187
  ovs_tunnel_types = ['vxlan', 'gre']
188
188
  ovs_tunnel_iface = { :string => '<%= n = @host.deployment.neutron; n.enable_tunneling? ? n.networker_tenant_interface : "" %>' }
189
189
  ovs_bridge_mappings = { :array => '<%= @host.deployment.neutron.networker_ovs_bridge_mappings %>' }
@@ -194,13 +194,13 @@ module Staypuft
194
194
  enable_tunneling = { :string => '<%= @host.deployment.neutron.enable_tunneling?.to_s %>' }
195
195
 
196
196
  # Glance
197
- backend = 'file'
198
- pcmk_fs_type = { :string => '<%= @host.deployment.glance.driver_backend %>' }
197
+ backend = { :string => '<%= @host.deployment.glance.backend %>' }
198
+ pcmk_fs_type = { :string => '<%= @host.deployment.glance.pcmk_fs_type %>' }
199
199
  pcmk_fs_device = { :string => '<%= @host.deployment.glance.pcmk_fs_device %>' }
200
200
  pcmk_fs_dir = '/var/lib/glance/images'
201
- pcmk_fs_manage = 'true'
201
+ pcmk_fs_manage = { :string => '<%= @host.deployment.glance.pcmk_fs_manage %>' }
202
202
  pcmk_fs_options = { :string => '<%= @host.deployment.glance.pcmk_fs_options %>' }
203
- glance_rbd_store_user = 'glance'
203
+ glance_rbd_store_user = 'images'
204
204
  glance_rbd_store_pool = 'images'
205
205
 
206
206
  # Cinder
@@ -213,31 +213,31 @@ module Staypuft
213
213
  cinder_backend_nfs_name = 'nfs_backend'
214
214
  cinder_multiple_backends = false
215
215
  cinder_nfs_shares = ['<%= @host.deployment.cinder.nfs_uri %>']
216
- cinder_nfs_mount_options = ''
216
+ cinder_nfs_mount_options = 'nosharecache'
217
217
 
218
218
  cinder_backend_rbd = { :string => '<%= @host.deployment.cinder.ceph_backend? %>' }
219
219
  cinder_backend_rbd_name = 'rbd_backend'
220
- # TODO: confirm these params and add them to model where user input is needed
221
220
  cinder_rbd_pool = 'volumes'
222
- cinder_rbd_ceph_conf = '/etc/ceph/ceph.conf/'
221
+ cinder_rbd_ceph_conf = '/etc/ceph/ceph.conf'
223
222
  cinder_rbd_flatten_volume_from_snapshot = 'false'
224
223
  cinder_rbd_max_clone_depth = '5'
225
- cinder_rbd_user = 'cinder'
226
- cinder_rbd_secret_uuid = ''
224
+ cinder_rbd_user = 'volumes'
225
+ cinder_rbd_secret_uuid = { :string => '<%= @host.deployment.cinder.rbd_secret_uuid %>' }
227
226
 
228
227
  cinder_backend_eqlx = { :string => '<%= @host.deployment.cinder.equallogic_backend? %>' }
229
228
  cinder_backend_eqlx_name = ['eqlx_backend']
230
229
  # TODO: confirm these params and add them to model where user input is needed
231
230
  # below dynamic calls are commented out since the model does not yet have san/chap entries
232
- cinder_san_ip = [''] # ['<%= #@host.deployment.cinder.san_ip %>']
233
- cinder_san_login = [''] # ['<%= #@host.deployment.cinder.san_login %>']
234
- cinder_san_password = [''] # ['<%= #@host.deployment.cinder.san_password %>']
231
+ cinder_san_ip = ['<%= @host.deployment.cinder.san_ip %>']
232
+ cinder_san_login = ['<%= @host.deployment.cinder.san_login %>']
233
+ cinder_san_password = ['<%= @host.deployment.cinder.san_password %>']
234
+ cinder_eqlx_group_name = ['<%= @host.deployment.cinder.eqlx_group_name %>']
235
+ cinder_eqlx_pool = ['<%= @host.deployment.cinder.eqlx_pool %>']
236
+
235
237
  cinder_san_thin_provision = ['false']
236
- cinder_eqlx_group_name = ['group-0']
237
- cinder_eqlx_pool = ['default']
238
238
  cinder_eqlx_use_chap = ['false']
239
- cinder_eqlx_chap_login = [''] # ['<%= #@host.deployment.cinder.chap_login %>']
240
- cinder_eqlx_chap_password = [''] # ['<%= #@host.deployment.cinder.chap_password %>']
239
+ cinder_eqlx_chap_login = ['']
240
+ cinder_eqlx_chap_password = ['']
241
241
 
242
242
 
243
243
  # effective_value grabs shared password if deployment is in shared password mode,
@@ -560,6 +560,8 @@ module Staypuft
560
560
  'ceilometer' => ceilometer,
561
561
  'cinder_backend_gluster' => cinder_backend_gluster,
562
562
  'cinder_backend_nfs' => cinder_backend_nfs,
563
+ 'cinder_backend_rbd' => cinder_backend_rbd,
564
+ 'rbd_secret_uuid' => cinder_rbd_secret_uuid,
563
565
  'network_manager' => network_manager,
564
566
  'network_overrides' => network_overrides,
565
567
  'network_num_networks' => network_num_networks,
@@ -585,6 +587,8 @@ module Staypuft
585
587
  'ceilometer' => ceilometer,
586
588
  'cinder_backend_gluster' => cinder_backend_gluster,
587
589
  'cinder_backend_nfs' => cinder_backend_nfs,
590
+ 'cinder_backend_rbd' => cinder_backend_rbd,
591
+ 'rbd_secret_uuid' => cinder_rbd_secret_uuid,
588
592
  'enable_tunneling' => enable_tunneling,
589
593
  'tenant_network_type' => tenant_network_type,
590
594
  'ovs_bridge_mappings' => compute_ovs_bridge_mappings,
@@ -0,0 +1,39 @@
1
+ module Staypuft
2
+ module Concerns
3
+ module HostDetailsHelper
4
+ extend ActiveSupport::Concern
5
+
6
+ # Returns memory in GB
7
+ def mem
8
+ if self.facts_hash["memorytotal"]
9
+ self.facts_hash["memorytotal"].split(" ").first.to_f / 1000
10
+ else
11
+ nil
12
+ end
13
+ end
14
+
15
+ # Returns total number of processes
16
+ def cpus
17
+ self.facts_hash["processorcount"]
18
+ end
19
+
20
+ # Returns array of NIC names
21
+ def network_interfaces
22
+ if self.facts_hash["interfaces"]
23
+ self.facts_hash["interfaces"].split(",")
24
+ else
25
+ nil
26
+ end
27
+ end
28
+
29
+ # Returns architecture
30
+ def architectures
31
+ if self.facts_hash["architecture"]
32
+ self.facts_hash["architecture"].name
33
+ else
34
+ nil
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -94,10 +94,15 @@ module Staypuft
94
94
 
95
95
  # Helper method for looking up a Deployment based on a foreman task
96
96
  def self.find_by_foreman_task(foreman_task)
97
- Deployment.find(ForemanTasks::Lock.where(task_id: foreman_task.id,
98
- name: :deploy,
99
- resource_type: 'Staypuft::Deployment')
100
- .first.resource_id)
97
+ task = ForemanTasks::Lock.where(task_id: foreman_task.id,
98
+ name: :deploy,
99
+ resource_type: 'Staypuft::Deployment').first
100
+ unless task.nil?
101
+ Deployment.find(task.resource_id)
102
+ else
103
+ nil
104
+ end
105
+
101
106
  end
102
107
 
103
108
  # Returns a list of hosts that are currently being deployed.
@@ -1,12 +1,40 @@
1
+ # encoding: utf-8
1
2
  module Staypuft
2
3
  class Deployment::CinderService < Deployment::AbstractParamScope
3
4
  def self.param_scope
4
5
  'cinder'
5
6
  end
6
7
 
7
- param_attr :driver_backend, :nfs_uri
8
+ param_attr :driver_backend, :nfs_uri, :rbd_secret_uuid,
9
+ :san_ip, :san_login, :san_password, :eqlx_group_name, :eqlx_pool
8
10
  after_save :set_lvm_ptable
9
11
 
12
+ class SanIpValueValidator < ActiveModel::EachValidator
13
+ def validate_each(record, attribute, value)
14
+ return if value.empty?
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
37
+
10
38
  module DriverBackend
11
39
  LVM = 'lvm'
12
40
  NFS = 'nfs'
@@ -30,17 +58,84 @@ module Staypuft
30
58
  :if => :nfs_backend?
31
59
  # TODO: uri validation
32
60
 
33
- # TODO: add ceph UI parameters
61
+ module SanIp
62
+ HUMAN = N_('SAN IP Addr:')
63
+ 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
+ module SanLogin
73
+ HUMAN = N_('SAN Login:')
74
+ 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?
34
83
 
35
- # TODO: add EqualLogic UI parameters
84
+ module SanPassword
85
+ HUMAN = N_('SAN Password:')
86
+ 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?
36
96
 
97
+ module EqlxPool
98
+ HUMAN = N_('Pool:')
99
+ 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
+ module EqlxGroupName
117
+ HUMAN = N_('Group:')
118
+ end
119
+ # Up to 54 alphanumeric characters and hyphens(dashes).
120
+ # The first character must be a letter or a number.
121
+ # ASCII, Not Unicode
122
+ validates :eqlx_group_name,
123
+ :presence => true,
124
+ :format => /\A[a-zA-Z\d][a-zA-Z\d\-]*\z/,
125
+ :length => { maximum: 54 },
126
+ :if => :equallogic_backend?
37
127
 
38
128
  class Jail < Safemode::Jail
39
- allow :lvm_backend?, :nfs_backend?, :nfs_uri, :ceph_backend?, :equallogic_backend?
129
+ allow :lvm_backend?, :nfs_backend?, :nfs_uri, :ceph_backend?, :equallogic_backend?,
130
+ :rbd_secret_uuid, :san_ip, :san_login, :san_password, :eqlx_group_name, :eqlx_pool
40
131
  end
41
132
 
42
133
  def set_defaults
43
- self.driver_backend = DriverBackend::LVM
134
+ self.driver_backend = DriverBackend::LVM
135
+ self.rbd_secret_uuid = SecureRandom.uuid
136
+ self.san_login = 'grpadmin'
137
+ self.eqlx_pool = 'default'
138
+ self.eqlx_group_name = 'group-0'
44
139
  end
45
140
 
46
141
  # cinder config always shows up
@@ -66,30 +161,22 @@ module Staypuft
66
161
 
67
162
 
68
163
  # view should use this rather than DriverBackend::LABELS to hide LVM for HA.
69
- # TODO: Add back CEPH and EQUALLOGIC as they're suppoirted
70
164
  def backend_labels_for_layout
71
165
  ret_list = DriverBackend::LABELS.clone
72
166
  ret_list.delete(DriverBackend::LVM) if self.deployment.ha?
73
- # TODO: remove this line when Ceph is supported
74
- ret_list.delete(DriverBackend::CEPH)
75
- # TODO: remove this line when EqualLogic is supported
76
- ret_list.delete(DriverBackend::EQUALLOGIC)
77
-
78
167
  ret_list
79
168
  end
80
169
  def backend_types_for_layout
81
170
  ret_list = DriverBackend::TYPES.clone
82
171
  ret_list.delete(DriverBackend::LVM) if self.deployment.ha?
83
- # TODO: remove this line when Ceph is supported
84
- ret_list.delete(DriverBackend::CEPH)
85
- # TODO: remove this line when EqualLogic is supported
86
- ret_list.delete(DriverBackend::EQUALLOGIC)
87
-
88
172
  ret_list
89
173
  end
90
174
 
91
175
  def param_hash
92
- { "driver_backend" => driver_backend, "nfs_uri" => nfs_uri}
176
+ { "driver_backend" => driver_backend, "nfs_uri" => nfs_uri,
177
+ "rbd_secret_uuid" => rbd_secret_uuid,
178
+ "san_ip" => san_ip, "san_login" => san_login, "san_password" => san_password,
179
+ "eqlx_group_name" => eqlx_group_name, "eqlx_pool" => eqlx_pool }
93
180
  end
94
181
 
95
182
  def lvm_ptable