staypuft 0.1.22 → 0.2.0

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 (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