staypuft 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 63e9f17728bf3ff2084000a2eb08f08d68340c87
4
+ data.tar.gz: 9d7e070d3e2055b448de53c39dbaa5c7f8830232
5
+ SHA512:
6
+ metadata.gz: 167c564e5be0f73cb35f04292e2ac98f0bf515c8d5cbf2070e87d3fccb9ad948fbc7fb087897c7a8692fe495518219b493408e21339ed77db2edcd00440ac39c
7
+ data.tar.gz: dd33319c9a552308e5ed909038140494c2c0d07304d1016eaf24175956c1b9c6922a03e0615bec1137f043b5299b3a89f2f958988fdfd9dd55f272502b2176c3
data/README.md CHANGED
@@ -11,72 +11,9 @@ Symlink `config/staypuft.local.rb` to yours Foreman `bundle.d`.
11
11
 
12
12
  ln -s ../../Staypuft/config/staypuft.local.rb staypuft.local.rb
13
13
 
14
- ## Enabling Puppet SSH
14
+ ## Development setup
15
15
 
16
- This is required for invoking puppet runs on remote machines.
17
- This is needed in Staypuft for orchestration tasks.
18
-
19
- ### Enable Puppet Run (Based on Foreman 1.4.1)
20
-
21
- Go to the foreman web UI.
22
-
23
- Administer -> Settings -> Puppet
24
-
25
- Set Puppet Run to 'true'
26
-
27
- ### Configure Foreman Proxy
28
-
29
- Add the following lines to the foreman proxy settings.yml
30
-
31
- ```
32
- :puppet_provider: puppetssh
33
- :puppetssh_sudo: false
34
- :puppetssh_user: root
35
- :puppetssh_keyfile: /etc/foreman-proxy/id_rsa
36
- :puppetssh_command: /usr/bin/puppet agent --onetime --no-usecacheonfailure
37
- ```
38
-
39
- ### Create SSH Key fore foreman-proxy
40
-
41
- ```
42
- # Create SSH Key using ssh-keygen
43
-
44
- # cp private key to /etc/foreman-proxy/
45
-
46
- chown foreman-proxy /etc/foreman-proxy/id_rsa
47
-
48
- chmod 600 /etc/foreman-proxy/id_rsa
49
- ```
50
-
51
- ### Turn off StrictHostChecking for the foreman-proxy user
52
-
53
- Create the following file:
54
-
55
- <foreman HOME directory>/.ssh/config
56
- ```
57
- Host *
58
- StrictHostKeyChecking no
59
- ```
60
-
61
- N.B. This is a temporary solution. We are tracking this issue here: http://projects.theforeman.org/issues/4543
62
-
63
- ### Distribute Foreman Public Key to Hosts
64
-
65
- Add the id_rsa.pub public key to .ssh/authorized_keys file for user root on all Hosts
66
-
67
- N.B. This is a temporary solution. We are tracking this issue here: http://projects.theforeman.org/issues/4542
68
-
69
- ### Restart foreman-proxy
70
-
71
- sudo service foreman-proxy restart
72
-
73
- ## Usage
74
-
75
- #### PUPPET RUN
76
-
77
- Assuming that host is created and running and you have enabled puppetssh. See the section Enabling Puppet SSH.
78
-
79
- ForemanTasks.trigger Actions::Host::PuppetRun, Host.find(1)
16
+ See [this](docs/setup.md) document.
80
17
 
81
18
  ## TODO
82
19
 
@@ -34,6 +34,19 @@ module Staypuft
34
34
  when :services_configuration
35
35
  # Collect services across all deployment's roles
36
36
  @services = @deployment.roles(:services).map(&:services).flatten.uniq
37
+ if params[:staypuft_deployment]
38
+ param_data = params[:staypuft_deployment][:hostgroup_params]
39
+ diffs = []
40
+ param_data.each do |hostgroup_id, hostgroup_params|
41
+ hostgroup = Hostgroup.find(hostgroup_id)
42
+ hostgroup_params[:puppetclass_params].each do |puppetclass_id, puppetclass_params|
43
+ puppetclass = Puppetclass.find(puppetclass_id)
44
+ puppetclass_params.each do |param_name, param_value|
45
+ hostgroup.set_param_value_if_changed(puppetclass, param_name, param_value)
46
+ end
47
+ end
48
+ end
49
+ end
37
50
  end
38
51
 
39
52
  render_wizard @deployment
@@ -42,6 +55,7 @@ module Staypuft
42
55
  private
43
56
  def get_deployment
44
57
  @deployment = Deployment.first
58
+ @deployment.name = nil if @deployment.name.starts_with?(Deployment::NEW_NAME_PREFIX)
45
59
  end
46
60
 
47
61
  def redirect_to_finish_wizard(options = {})
@@ -7,12 +7,17 @@ module Staypuft
7
7
  end
8
8
 
9
9
  def new
10
+ if Deployment.first
11
+ flash[:warning] = _('Deployment already exists.')
12
+ redirect_to deployments_url
13
+ return
14
+ end
15
+
10
16
  # TODO get the hostgroup base id from settings
11
17
  base_hostgroup = Hostgroup.where(:name => 'base_hostgroup').first or
12
18
  raise 'missing base_hostgroup'
13
19
 
14
- deployment = Deployment.new(:name => SecureRandom.hex)
15
- deployment.description = "This is a deployment"
20
+ deployment = Deployment.new(:name => Deployment::NEW_NAME_PREFIX+SecureRandom.hex)
16
21
  deployment.layout = Layout.where(:name => "Distributed",
17
22
  :networking => "neutron").first
18
23
  deployment_hostgroup = ::Hostgroup.nest deployment.name, base_hostgroup
@@ -25,7 +30,7 @@ module Staypuft
25
30
  end
26
31
 
27
32
  def show
28
- @hostgroups = Hostgroup.all
33
+ @deployment = Deployment.find(params[:id])
29
34
  end
30
35
 
31
36
  def destroy
@@ -33,5 +38,33 @@ module Staypuft
33
38
  process_success
34
39
  end
35
40
 
41
+ def deploy
42
+ task = ForemanTasks.async_task ::Actions::Staypuft::Deployment::Deploy, Deployment.first
43
+ redirect_to foreman_tasks_task_url(id: task)
44
+ end
45
+
46
+ # TODO remove, it's temporary
47
+ def populate
48
+ task = ForemanTasks.async_task ::Actions::Staypuft::Deployment::Populate,
49
+ Deployment.first,
50
+ fake: !!params[:fake],
51
+ assign: !!params[:assign]
52
+ redirect_to foreman_tasks_task_url(id: task)
53
+ end
54
+
55
+ def associate_host
56
+ hostgroup = ::Hostgroup.find params[:hostgroup_id]
57
+ hosts = Array(::Host::Base.find *params[:host_ids])
58
+ hosts.each do |host|
59
+ host = host.becomes(::Host::Managed)
60
+ host.type = 'Host::Managed'
61
+ host.managed = true
62
+ host.build = false
63
+ host.hostgroup = hostgroup
64
+ host.save!
65
+ end
66
+ redirect_to deployment_path(id: ::Staypuft::Deployment.first)
67
+ end
68
+
36
69
  end
37
70
  end
@@ -13,7 +13,6 @@
13
13
  module Actions
14
14
  module Staypuft
15
15
  module Deployment
16
- # just a mock, models and seeds are not ready yet
17
16
  class Deploy < Actions::Base
18
17
 
19
18
  middleware.use Actions::Staypuft::Middleware::AsCurrentUser
@@ -21,11 +20,21 @@ module Actions
21
20
  def plan(deployment)
22
21
  Type! deployment, ::Staypuft::Deployment
23
22
 
24
- ordered_hostgroups = deployment.child_hostgroups.
25
- reorder("staypuft_deployment_role_hostgroups.deploy_order")
23
+ ordered_hostgroups = deployment.child_hostgroups.
24
+ reorder("#{::Staypuft::DeploymentRoleHostgroup.table_name}.deploy_order").to_a
25
+ input.update id: deployment.id, name: deployment.name
26
26
 
27
27
  plan_action Hostgroup::OrderedDeploy, ordered_hostgroups
28
28
  end
29
+
30
+ def humanized_input
31
+ input[:name]
32
+ end
33
+
34
+ def humanized_output
35
+ planned_actions.map(&:humanized_output).join("\n")
36
+ end
37
+
29
38
  end
30
39
  end
31
40
  end
@@ -0,0 +1,67 @@
1
+ #
2
+ # Copyright 2014 Red Hat, Inc.
3
+ #
4
+ # This software is licensed to you under the GNU General Public
5
+ # License as published by the Free Software Foundation; either version
6
+ # 2 of the License (GPLv2) or (at your option) any later version.
7
+ # There is NO WARRANTY for this software, express or implied,
8
+ # including the implied warranties of MERCHANTABILITY,
9
+ # NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should
10
+ # have received a copy of GPLv2 along with this software; if not, see
11
+ # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
12
+
13
+ module Actions
14
+ module Staypuft
15
+ module Deployment
16
+ # TODO remove, it's temporary
17
+ class Populate < Actions::Base
18
+
19
+ middleware.use Actions::Staypuft::Middleware::AsCurrentUser
20
+
21
+ def plan(deployment, options = {})
22
+ Type! deployment, ::Staypuft::Deployment
23
+
24
+ fake = options[:fake].nil? ? false : options[:fake]
25
+ assign = options[:assign].nil? ? false : options[:assign]
26
+ Type! fake, TrueClass, FalseClass
27
+
28
+ compute_resource = options[:compute_resource] ||= ::Foreman::Model::Libvirt.first
29
+ Type! compute_resource, *[ComputeResource, (NilClass if fake)].compact
30
+
31
+ sequence do
32
+ plan_self deployment_id: deployment.id,
33
+ deployment_name: deployment.name,
34
+ fake: fake,
35
+ assign: assign
36
+
37
+ hostgroups = deployment.child_hostgroups
38
+ hostgroups.each do |hostgroup|
39
+ plan_action Actions::Staypuft::Host::Create,
40
+ rand(1000).to_s,
41
+ hostgroup,
42
+ compute_resource,
43
+ start: false,
44
+ assign: assign,
45
+ fake: fake
46
+ end
47
+ end
48
+ end
49
+
50
+ def run
51
+ deployment = ::Staypuft::Deployment.find input.fetch(:deployment_id)
52
+ hostgroups = deployment.child_hostgroups
53
+ hostgroups.each do |hostgroup|
54
+ hostgroup.hosts.each do |host|
55
+ host.destroy # TODO make action for it
56
+ end
57
+ end
58
+ end
59
+
60
+ def humanized_input
61
+ "#{input[:deployment_name]} #{input[:fake] ? 'fake' : 'real'}"
62
+ end
63
+
64
+ end
65
+ end
66
+ end
67
+ end
@@ -18,41 +18,63 @@ module Actions
18
18
  middleware.use Actions::Staypuft::Middleware::AsCurrentUser
19
19
 
20
20
  def plan(name, hostgroup, compute_resource, options = {})
21
- # TODO: set action_subject
22
- # TODO: compute_resource or mac
23
-
24
21
  Type! hostgroup, ::Hostgroup
25
- Type! compute_resource, ComputeResource
22
+ Type! compute_resource, ComputeResource, NilClass
26
23
 
27
- compute_attributes = hostgroup.
28
- compute_profile.
29
- compute_attributes.
30
- where(compute_resource_id: compute_resource.id).
31
- first.
32
- vm_attrs
24
+ options = { start: true, assign: true, fake: false }.merge options
33
25
 
34
- options = { :start => true }.merge options
26
+ compute_attributes = if options[:fake]
27
+ {}
28
+ else
29
+ hostgroup.
30
+ compute_profile.
31
+ compute_attributes.
32
+ where(compute_resource_id: compute_resource.id).
33
+ first.
34
+ vm_attrs
35
+ end
35
36
 
36
- plan_self name: name,
37
- hostgroup_id: hostgroup.id,
38
- compute_resource_id: compute_resource.id,
39
- compute_attributes: compute_attributes,
40
- options: options
41
37
 
38
+ plan_self name: name,
39
+ hostgroup_id: hostgroup.id,
40
+ compute_attributes: compute_attributes,
41
+ options: options
42
+ input.update compute_resource_id: compute_resource.id if compute_resource
42
43
  end
43
44
 
44
45
  def run
45
- #noinspecti on RubyArgCount
46
- host = ::Host::Managed.new(
47
- name: input[:name],
48
- hostgroup_id: input[:hostgroup_id],
49
- compute_resource_id: input[:compute_resource_id],
50
- compute_attributes: input[:compute_attributes],
51
- build: false,
52
- managed: true,
53
- enabled: true)
46
+ fake = input.fetch(:options).fetch(:fake)
47
+ assign = input.fetch(:options).fetch(:assign)
48
+
49
+ host = if fake
50
+ raise if assign
51
+ ::Host::Managed.new(
52
+ name: input[:name],
53
+ hostgroup_id: input[:hostgroup_id],
54
+ build: false,
55
+ managed: true,
56
+ enabled: true,
57
+ mac: '0a:' + Array.new(5).map { format '%0.2X', rand(256) }.join(':'))
58
+ else
59
+ ::Host::Managed.new(
60
+ name: input[:name],
61
+ hostgroup_id: input[:hostgroup_id],
62
+ build: false,
63
+ managed: true,
64
+ enabled: true,
65
+ compute_resource_id: input.fetch(:compute_resource_id),
66
+ compute_attributes: input[:compute_attributes])
67
+ end
68
+
54
69
  host.save!
55
- host.power.start if input[:options][:start]
70
+ host.power.start if input.fetch(:options).fetch(:start)
71
+
72
+ unless assign
73
+ host.reload
74
+ host.hostgroup = nil
75
+ host.save!
76
+ end
77
+
56
78
  output.update host: { id: host.id,
57
79
  name: host.name,
58
80
  ip: host.ip,
@@ -30,7 +30,7 @@ module Actions
30
30
  def humanized_output
31
31
  # TODO: fix dynflow to allow better progress getting
32
32
  steps = planned_actions.inject([]) { |s, a| s + a.steps[1..2] }.compact
33
- progress = steps.map(&:progress).map(&:first).reduce(&:+) / steps.size
33
+ progress = steps.map(&:progress_done).reduce(&:+) / steps.size
34
34
  format '%3d%% Host: %s', progress * 100, input[:host][:name]
35
35
  end
36
36
 
@@ -51,18 +51,12 @@ module Actions
51
51
 
52
52
  def host_ready?(host_id)
53
53
  host = ::Host.find(host_id)
54
- host.reports.order('reported_at DESC').any? do |report|
55
- check_for_failures(report)
56
- report_change?(report)
57
- end
58
- end
59
-
60
- def report_change?(report)
61
- report.status['applied'] > 0
54
+ check_for_failures(host)
55
+ host.skipped == 0 && host.pending == 0
62
56
  end
63
57
 
64
- def check_for_failures(report)
65
- if report.status['failed'] > 0
58
+ def check_for_failures(host)
59
+ if host.failed > 0
66
60
  fail(::Staypuft::Exception, "Latest Puppet Run Contains Failures for Host: #{host.id}")
67
61
  end
68
62
  end
@@ -17,6 +17,35 @@ module Staypuft::Concerns::HostgroupExtensions
17
17
  end
18
18
  end
19
19
  end
20
+
21
+ def current_param_value(key)
22
+ if (v = LookupValue.where(:lookup_key_id => key.id, :id => lookup_values).first)
23
+ return v.value, to_label
24
+ end
25
+ return inherited_lookup_value(key)
26
+ end
27
+
28
+ def current_param_value_str(key)
29
+ val = current_param_value(key)[0]
30
+ val.is_a?(Array) ? val.join(", ") : val
31
+ end
32
+
33
+ def set_param_value_if_changed(puppetclass, key, value)
34
+ lookup_key = puppetclass.class_params.where(:key => key).first
35
+ current_value = current_param_value(lookup_key)[0]
36
+ new_value = current_value.is_a?(Array) ? value.split(", ") : value
37
+ unless current_value == new_value
38
+ lookup = LookupValue.where(:match => hostgroup.send(:lookup_value_match),
39
+ :lookup_key_id => lookup_key.id).first_or_initialize
40
+ lookup.value = new_value
41
+ lookup.save!
42
+ end
43
+ end
44
+
45
+ def own_and_free_hosts
46
+ # TODO update to Discovered
47
+ Host::Base.where("hostgroup_id = ? OR hostgroup_id IS NULL", id)
48
+ end
20
49
  end
21
50
 
22
51
  module ClassMethods
@@ -1,5 +1,8 @@
1
1
  module Staypuft
2
2
  class Deployment < ActiveRecord::Base
3
+
4
+ NEW_NAME_PREFIX="uninitialized_"
5
+
3
6
  attr_accessible :description, :name, :layout_id, :layout
4
7
  after_save :update_hostgroup_name
5
8
 
@@ -2,6 +2,7 @@ module Staypuft
2
2
  class Service < ActiveRecord::Base
3
3
  has_many :role_services, :dependent => :destroy
4
4
  has_many :roles, :through => :role_services
5
+ has_many :hostgroups, :through => :roles
5
6
 
6
7
  has_many :service_classes, :dependent => :destroy
7
8
  has_many :puppetclasses, :through => :service_classes
@@ -9,5 +10,91 @@ module Staypuft
9
10
  attr_accessible :description, :name
10
11
 
11
12
  validates :name, :presence => true, :uniqueness => true
13
+
14
+ # for each service, a list of param names. Optionally, instead of a string
15
+ # for a param name, an array of [param_name, puppetclass] in the case where
16
+ # there are possibly multiple puppetclass matches. without this, we'll
17
+ # just grab the first puppetclass from the matching hostgroup
18
+ UI_PARAMS = {
19
+ "qpid"=> ["qpid_ca", "qpid_cert", "qpid_host", "qpid_key", "qpid_nssdb_password"],
20
+ "MySQL"=> ["mysql_ca", "mysql_cert", "mysql_host", "mysql_key",
21
+ "mysql_root_password"],
22
+ "Keystone"=> ["keystone_admin_token", "keystone_db_password"],
23
+ "Nova (Controller)"=> ["admin_email", "admin_password", "auto_assign_floating_ip",
24
+ "controller_admin_host", "controller_priv_host",
25
+ "controller_pub_host", "freeipa", "horizon_ca",
26
+ "horizon_cert", "horizon_key", "horizon_secret_key",
27
+ "nova_db_password", "nova_user_password", "ssl"],
28
+ "Neutron (Controller)" => ["admin_email", "admin_password",
29
+ "cisco_nexus_plugin", "cisco_vswitch_plugin",
30
+ "controller_admin_host", "controller_priv_host",
31
+ "controller_pub_host", "enable_tunneling",
32
+ "freeipa", "horizon_ca", "horizon_cert",
33
+ "horizon_key", "horizon_secret_key",
34
+ "ml2_flat_networks", "ml2_install_deps",
35
+ "ml2_mechanism_drivers", "ml2_network_vlan_ranges",
36
+ "ml2_tenant_network_types", "ml2_tunnel_id_ranges",
37
+ "ml2_type_drivers", "ml2_vni_ranges",
38
+ "ml2_vxlan_group", "neutron_core_plugin",
39
+ "neutron_db_password", "neutron_metadata_proxy_secret",
40
+ "neutron_user_password", "nexus_config",
41
+ "nexus_credentials", "nova_db_password",
42
+ "nova_user_password", "ovs_vlan_ranges",
43
+ "provider_vlan_auto_create", "provider_vlan_auto_trunk",
44
+ "ssl", "tenant_network_type", "tunnel_id_ranges",
45
+ "verbose"],
46
+ "Glance"=> ["glance_db_password", "glance_user_password"],
47
+ "Cinder"=> ["cinder_backend_gluster", "cinder_backend_iscsi",
48
+ "cinder_db_password", "cinder_gluster_servers",
49
+ "cinder_gluster_volume", "cinder_user_password"],
50
+ "Heat"=> ["heat_cfn", "heat_cloudwatch", "heat_db_password", "heat_user_password"],
51
+ "Ceilometer"=> ["ceilometer_metering_secret", "ceilometer_user_password"
52
+ ],
53
+ "Neutron - L3" => [],
54
+ "DHCP" => [],
55
+ "OVS" => [],
56
+ "Nova-compute" => ["admin_password", "auto_assign_floating_ip",
57
+ "ceilometer_metering_secret", "ceilometer_user_password",
58
+ "cinder_backend_gluster", "controller_priv_host",
59
+ "controller_pub_host", "fixed_network_range",
60
+ "floating_network_range", "mysql_ca", "mysql_host",
61
+ "nova_db_password", "nova_network_private_iface",
62
+ "nova_network_public_iface", "nova_user_password",
63
+ "qpid_host", "ssl", "verbose"],
64
+ "Neutron-compute" => ["admin_password", "ceilometer_metering_secret",
65
+ "ceilometer_user_password", "cinder_backend_gluster",
66
+ "controller_admin_host", "controller_priv_host",
67
+ "controller_pub_host", "enable_tunneling", "mysql_ca",
68
+ "mysql_host", "neutron_core_plugin",
69
+ "neutron_db_password", "neutron_user_password",
70
+ "nova_db_password", "nova_user_password",
71
+ "ovs_bridge_mappings", "ovs_tunnel_iface",
72
+ "ovs_tunnel_types", "ovs_vlan_ranges",
73
+ "ovs_vxlan_udp_port", "qpid_host", "ssl",
74
+ "tenant_network_type", "tunnel_id_ranges", "verbose"],
75
+ "Neutron-ovs-agent"=> [],
76
+ "Swift" => ["swift_admin_password", "swift_ringserver_ip",
77
+ "swift_shared_secret", "swift_storage_device",
78
+ "swift_storage_ips"]
79
+ }
80
+
81
+ def ui_params_for_form(hostgroup = self.hostgroups.first)
82
+ return [] if (hostgroup.nil? || hostgroup.puppetclasses.nil?)
83
+ puppetclass = hostgroup.puppetclasses.first
84
+ # nil puppetclass means grab the first one from matching hostgroup
85
+ UI_PARAMS[self.name].collect do |param_key|
86
+ if param_key.is_a?(Array)
87
+ param_name = param_key[0]
88
+ param_puppetclass = param_key[1]
89
+ else
90
+ param_name = param_key
91
+ param_puppetclass = puppetclass
92
+ end
93
+ param_lookup_key = param_puppetclass.class_params.where(:key=>param_key).first
94
+ param_lookup_key.nil? ? nil : {:hostgroup => hostgroup,
95
+ :puppetclass => param_puppetclass,
96
+ :param_key => param_lookup_key}
97
+ end.compact
98
+ end
12
99
  end
13
100
  end
@@ -19,8 +19,22 @@
19
19
  <% @services.each_with_index do |service, i| %>
20
20
  <div class="tab-pane <%= 'active' if i == 0 %>" id="<%= service.name.parameterize.underscore %>">
21
21
  <h3><%= "#{service.name} " + _("Service Configuration") %></h3>
22
- <%= text_f f, :name %><br />
23
- <%= text_f f, :description %><br />
22
+ <% if (params_hash = service.ui_params_for_form).size > 0 %>
23
+ <% params_hash.each do |param_hash| %>
24
+ <div class="row">
25
+ <div class="col-md-4 control-label">
26
+ <%= label_tag param_hash[:param_key].key %>
27
+ </div>
28
+ <div class="col-md-5">
29
+ <%= text_field_tag "staypuft_deployment[hostgroup_params][#{param_hash[:hostgroup].id}][puppetclass_params][#{param_hash[:puppetclass].id}][#{param_hash[:param_key].key}]", param_hash[:hostgroup].current_param_value_str(param_hash[:param_key]), :class=>"form-control", :size=>"45"%>
30
+ </div>
31
+ </div>
32
+ <br/>
33
+ <% end %>
34
+ <% else %>
35
+ <p><%= _("No configuration needed for this service.") %></p>
36
+ <% end %>
37
+ <% # render "puppetclasses/classes_parameters", { :obj => service.hostgroups.first } %>
24
38
  </div>
25
39
  <% end %>
26
40
  </div>
@@ -1,37 +1,56 @@
1
- <% title Staypuft::Deployment.first.name %>
2
- <% title_actions display_link_if_authorized(_("Deploy changes"), hash_for_deployment_steps_path, :class => 'btn-success'), help_path %>
1
+ <% title @deployment.name %>
2
+
3
+ <% content_for(:title_actions) do %>
4
+
5
+ <%# TODO remove Populate dropdown, it's temporary %>
6
+ <div class="btn-group">
7
+ <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
8
+ <%= _('Populate with') %>
9
+ <span class="caret"></span>
10
+ </button>
11
+ <ul class="dropdown-menu" role="menu">
12
+ <li>
13
+ <%= display_link_if_authorized(_("Real assigned Hosts"), hash_for_populate_deployment_path(assign: true)) %>
14
+ </li>
15
+ <li>
16
+ <%= display_link_if_authorized(_("Real unassigned Hosts"), hash_for_populate_deployment_path) %>
17
+ </li>
18
+ <li>
19
+ <%= display_link_if_authorized(_("Fake unassigned Hosts"), hash_for_populate_deployment_path(:fake => true)) %>
20
+ </li>
21
+ </ul>
22
+ </div>
23
+
24
+
25
+ <%= display_link_if_authorized(_("Deploy"), hash_for_deploy_deployment_path, :class => 'btn-success') %>
26
+ <%= help_path %>
27
+ <% end %>
3
28
 
4
29
  <div class="row tabbed_side_nav_table">
5
30
  <ul class="nav nav-pills nav-stacked col-md-4" data-tabs="pills">
6
31
  <h3><%= _("Host Groups") %></h3>
7
- <li class="active">
8
- <a href="#controller" data-toggle="tab" class="roles_list">
9
- <div class="col-xs-2 text-center"><span class="glyphicon glyphicon-ok"></span><span>0</span></div>
10
- <div class="col-xs-2 text-center"><span class="glyphicon glyphicon-warning-sign"><span>0</span></div>
11
- <div class="col-xs-2 text-center"><span class="glyphicon glyphicon-time"><span>0</span></div>
12
- <div class="col-xs-6"><%= _("Controller") %></div>
13
- <span class="clearfix"></span>
14
- </a>
15
- </li>
16
- <li>
17
- <a href="#network" data-toggle="tab" class="roles_list">
18
- <div class="col-xs-2 text-center"><span class="glyphicon glyphicon-ok"></span><span>0</span></div>
19
- <div class="col-xs-2 text-center"><span class="glyphicon glyphicon-warning-sign"><span>0</span></div>
20
- <div class="col-xs-2 text-center"><span class="glyphicon glyphicon-time"><span>0</span></div>
21
- <div class="col-xs-6"><%= _("Network") %></div>
22
- <span class="clearfix"></span>
23
- </a>
24
- </li>
32
+ <% @deployment.child_hostgroups.each_with_index do |child_hostgroup, i| %>
33
+ <li class="<%= 'active' if i == 0 %>">
34
+ <a href="#<%= child_hostgroup.name.parameterize.underscore %>" data-toggle="tab" class="roles_list">
35
+ <div class="col-xs-2 text-center"><span class="glyphicon glyphicon-ok"></span><span>0</span></div>
36
+ <div class="col-xs-2 text-center"><span class="glyphicon glyphicon-warning-sign"></span><span>0</span></div>
37
+ <div class="col-xs-2 text-center"><span class="glyphicon glyphicon-time"></span><span>0</span></div>
38
+ <div class="col-xs-6"><%= child_hostgroup.name %></div>
39
+ <span class="clearfix"></span>
40
+ </a>
41
+ </li>
42
+ <% end %>
25
43
  </ul>
26
44
 
27
45
  <div class="tab-content col-md-8">
28
- <div class="tab-pane active" id="controller">
29
- <h3><%= _("Available Hosts") %></h3>
30
- <%= form_for(:host_group) do |f| %>
31
- <p>
32
- <%= f.submit _("Apply"), :class => "btn btn-primary btn-sm" %>
33
- </p>
34
- <%= f.fields_for :hosts do |host_form| %>
46
+ <% @deployment.child_hostgroups.each_with_index do |child_hostgroup, i| %>
47
+ <div class="tab-pane <%= 'active' if i == 0 %>" id="<%= child_hostgroup.name.parameterize.underscore %>">
48
+ <h3><%= _("Hosts") %></h3>
49
+ <%= form_tag(associate_host_deployments_path, class: 'form-horizontal well') do |f| %>
50
+ <p>
51
+ <%= submit_tag _("Apply"), :class => "btn btn-primary btn-sm" %>
52
+ </p>
53
+ <%= hidden_field_tag :hostgroup_id, child_hostgroup.id %>
35
54
  <table class="table table-bordered table-striped table-condensed">
36
55
  <tr>
37
56
  <th>
@@ -39,41 +58,22 @@
39
58
  </th>
40
59
  <th><%= sort :label, :as => _('Host MAC Address') %></th>
41
60
  <th><%= sort :label, :as => _('Host IP Address') %></th>
61
+ <th><%= _('Type') %></th>
42
62
  </tr>
43
- <tr>
44
- <td>
45
- <%= check_box_tag "hostgroup[host_ids][]", 1, true , :id => "hostgroup_host_ids_#{1}" %>
46
- </td>
47
- <td>44:1e:a1:71:a9:be</td>
48
- <td>10.35.160.11</td>
49
- </tr>
50
- <tr>
51
- <td>
52
- <%= check_box_tag "hostgroup[host_ids][]", 2, true , :id => "hostgroup_host_ids_#{2}" %>
53
- </td>
54
- <td>44:1e:a1:71:a9:be</td>
55
- <td>10.35.160.11</td>
56
- </tr>
57
- <tr>
58
- <td>
59
- <%= check_box_tag "hostgroup[host_ids][]", 3, false , :id => "hostgroup_host_ids_#{3}" %>
60
- </td>
61
- <td>44:1e:a1:71:a9:be</td>
62
- <td>10.35.160.11</td>
63
- </tr>
64
- <tr>
65
- <td>
66
- <%= check_box_tag "hostgroup[host_ids][]", 4, false , :id => "hostgroup_host_ids_#{4}" %>
67
- </td>
68
- <td>44:1e:a1:71:a9:be</td>
69
- <td>10.35.160.11</td>
70
- </tr>
63
+ <% child_hostgroup.own_and_free_hosts.each do |host| %>
64
+ <tr>
65
+ <td>
66
+ <%= check_box_tag "host_ids[]", host.id, child_hostgroup.host_ids.include?(host.id), :id => "host_ids_#{host.id}" %>
67
+ </td>
68
+ <td><%= host.mac %></td>
69
+ <td><%= host.ip %></td>
70
+ <td><%= host.type %></td>
71
+ </tr>
72
+ <% end %>
71
73
  </table>
72
74
  <% end %>
73
- <% end %>
74
- </div>
75
- <div class="tab-pane" id="network">
76
- <h3><%= _("Available Hosts") %></h3>
77
- </div>
75
+ </div>
76
+ <% end %>
78
77
  </div>
79
78
  </div>
79
+
@@ -1,5 +1,6 @@
1
- <%= stylesheet "staypuft/staypuft" %>
2
-
1
+ <%= content_for(:stylesheets) do %>
2
+ <%= stylesheet "staypuft/staypuft" %>
3
+ <% end %>
3
4
 
4
5
  <%= content_for(:javascripts) do %>
5
6
  <%= javascript "staypuft/staypuft" %>
data/config/routes.rb CHANGED
@@ -3,8 +3,12 @@ Rails.application.routes.draw do
3
3
  resources :deployments do
4
4
  collection do
5
5
  get 'auto_complete_search'
6
+ post 'associate_host'
7
+ end
8
+ member do
9
+ get 'deploy'
10
+ get 'populate'
6
11
  end
7
-
8
12
  end
9
13
 
10
14
  resources :deployment_steps
@@ -36,7 +36,10 @@ module Staypuft
36
36
  ForemanTasks.dynflow.require!
37
37
  action_paths = %W[#{Staypuft::Engine.root}/app/lib/actions]
38
38
  ForemanTasks.dynflow.config.eager_load_paths.concat(action_paths)
39
- ForemanTasks.dynflow.config.remote = true
39
+ end
40
+
41
+ initializer "staypuft.assets.precompile" do |app|
42
+ app.config.assets.precompile += %w(staypuft/staypuft.css staypuft/staypuft.js)
40
43
  end
41
44
 
42
45
  end
@@ -1,3 +1,3 @@
1
1
  module Staypuft
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/staypuft.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "foreman-tasks"
2
+ require "foreman_discovery"
2
3
  require "wicked"
3
4
  require "staypuft/engine"
4
5
 
metadata CHANGED
@@ -1,46 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: staypuft
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 0.0.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Staypuft team
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-04-02 00:00:00.000000000 Z
11
+ date: 2014-04-04 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: foreman-tasks
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: wicked
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: oj
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: foreman_discovery
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
44
67
  - !ruby/object:Gem::Version
45
68
  version: '0'
46
69
  description: OpenStack Foreman Installer
@@ -50,62 +73,62 @@ executables: []
50
73
  extensions: []
51
74
  extra_rdoc_files: []
52
75
  files:
53
- - app/assets/javascripts/staypuft/staypuft.js
54
- - app/assets/stylesheets/staypuft/bootstrap_and_overrides.css.scss
55
- - app/assets/stylesheets/staypuft/staypuft.css.scss
56
- - app/controllers/staypuft/application_controller.rb
57
- - app/controllers/staypuft/deployment_steps_controller.rb
58
- - app/controllers/staypuft/deployments_controller.rb
59
76
  - app/helpers/staypuft/application_helper.rb
60
77
  - app/helpers/staypuft/deployments_helper.rb
61
- - app/lib/actions/staypuft/deployment/deploy.rb
62
- - app/lib/actions/staypuft/host/build.rb
63
- - app/lib/actions/staypuft/host/create.rb
64
- - app/lib/actions/staypuft/host/deploy.rb
65
- - app/lib/actions/staypuft/host/provision.rb
66
- - app/lib/actions/staypuft/host/puppet_run.rb
67
- - app/lib/actions/staypuft/host/wait_until_host_ready.rb
68
- - app/lib/actions/staypuft/host/wait_until_installed.rb
69
- - app/lib/actions/staypuft/hostgroup/deploy.rb
70
- - app/lib/actions/staypuft/hostgroup/ordered_deploy.rb
71
- - app/lib/actions/staypuft/middleware/as_current_user.rb
72
- - app/lib/staypuft/exception.rb
73
- - app/models/settings/staypuft.rb
74
- - app/models/staypuft/concerns/host_orchestration_build_hook.rb
75
- - app/models/staypuft/concerns/hostgroup_extensions.rb
76
- - app/models/staypuft/concerns/puppetclass_extensions.rb
78
+ - app/assets/javascripts/staypuft/staypuft.js
79
+ - app/assets/stylesheets/staypuft/staypuft.css.scss
80
+ - app/assets/stylesheets/staypuft/bootstrap_and_overrides.css.scss
81
+ - app/models/staypuft/service.rb
82
+ - app/models/staypuft/role_class.rb
77
83
  - app/models/staypuft/deployment.rb
84
+ - app/models/staypuft/role_service.rb
78
85
  - app/models/staypuft/deployment_role_hostgroup.rb
79
86
  - app/models/staypuft/layout.rb
87
+ - app/models/staypuft/service_class.rb
88
+ - app/models/staypuft/concerns/host_orchestration_build_hook.rb
89
+ - app/models/staypuft/concerns/hostgroup_extensions.rb
90
+ - app/models/staypuft/concerns/puppetclass_extensions.rb
80
91
  - app/models/staypuft/layout_role.rb
81
92
  - app/models/staypuft/role.rb
82
- - app/models/staypuft/role_class.rb
83
- - app/models/staypuft/role_service.rb
84
- - app/models/staypuft/service.rb
85
- - app/models/staypuft/service_class.rb
86
- - app/views/staypuft/deployment_steps/_title.html.erb
87
- - app/views/staypuft/deployment_steps/deployment_settings.html.erb
88
- - app/views/staypuft/deployment_steps/services_configuration.html.erb
89
- - app/views/staypuft/deployment_steps/services_selection.html.erb
93
+ - app/models/settings/staypuft.rb
94
+ - app/lib/staypuft/exception.rb
95
+ - app/lib/actions/staypuft/middleware/as_current_user.rb
96
+ - app/lib/actions/staypuft/hostgroup/deploy.rb
97
+ - app/lib/actions/staypuft/hostgroup/ordered_deploy.rb
98
+ - app/lib/actions/staypuft/host/deploy.rb
99
+ - app/lib/actions/staypuft/host/build.rb
100
+ - app/lib/actions/staypuft/host/wait_until_host_ready.rb
101
+ - app/lib/actions/staypuft/host/puppet_run.rb
102
+ - app/lib/actions/staypuft/host/create.rb
103
+ - app/lib/actions/staypuft/host/wait_until_installed.rb
104
+ - app/lib/actions/staypuft/deployment/deploy.rb
105
+ - app/lib/actions/staypuft/deployment/populate.rb
106
+ - app/controllers/staypuft/deployments_controller.rb
107
+ - app/controllers/staypuft/application_controller.rb
108
+ - app/controllers/staypuft/deployment_steps_controller.rb
90
109
  - app/views/staypuft/deployments/index.html.erb
91
110
  - app/views/staypuft/deployments/show.html.erb
111
+ - app/views/staypuft/deployment_steps/deployment_settings.html.erb
112
+ - app/views/staypuft/deployment_steps/services_selection.html.erb
113
+ - app/views/staypuft/deployment_steps/_title.html.erb
114
+ - app/views/staypuft/deployment_steps/services_configuration.html.erb
92
115
  - app/views/staypuft/layouts/staypuft.html.erb
93
- - config/routes.rb
94
116
  - config/staypuft.local.rb
117
+ - config/routes.rb
118
+ - db/migrate/20140312050615_create_staypuft_role_classes.rb
95
119
  - db/migrate/20140309021811_create_staypuft_layouts.rb
96
- - db/migrate/20140310004533_create_staypuft_deployments.rb
120
+ - db/migrate/20140310203855_create_staypuft_role_services.rb
97
121
  - db/migrate/20140310023613_create_staypuft_roles.rb
98
- - db/migrate/20140310174152_create_staypuft_layout_roles.rb
122
+ - db/migrate/20140325211410_add_role_to_staypuft_deployment_role_hostgroup.rb
123
+ - db/migrate/20140326032027_drop_staypuft_hostgroup_roles.rb
99
124
  - db/migrate/20140310194221_create_staypuft_services.rb
100
- - db/migrate/20140310203855_create_staypuft_role_services.rb
101
- - db/migrate/20140312044533_create_staypuft_deployment_role_hostgroups.rb
102
125
  - db/migrate/20140312050001_create_staypuft_hostgroup_roles.rb
103
- - db/migrate/20140312050615_create_staypuft_role_classes.rb
104
- - db/migrate/20140312051144_create_staypuft_service_classes.rb
105
- - db/migrate/20140315031754_add_networking_to_staypuft_layout.rb
126
+ - db/migrate/20140310174152_create_staypuft_layout_roles.rb
106
127
  - db/migrate/20140318163222_add_deploy_order_to_staypuft_layout_role.rb
107
- - db/migrate/20140325211410_add_role_to_staypuft_deployment_role_hostgroup.rb
108
- - db/migrate/20140326032027_drop_staypuft_hostgroup_roles.rb
128
+ - db/migrate/20140315031754_add_networking_to_staypuft_layout.rb
129
+ - db/migrate/20140312051144_create_staypuft_service_classes.rb
130
+ - db/migrate/20140312044533_create_staypuft_deployment_role_hostgroups.rb
131
+ - db/migrate/20140310004533_create_staypuft_deployments.rb
109
132
  - db/seeds.rb
110
133
  - lib/staypuft/engine.rb
111
134
  - lib/staypuft/version.rb
@@ -114,40 +137,39 @@ files:
114
137
  - LICENSE
115
138
  - Rakefile
116
139
  - README.md
117
- - test/factories/staypuft_factories.rb
118
- - test/integration/navigation_test.rb
119
- - test/staypuft_test.rb
120
140
  - test/test_helper.rb
121
- - test/test_plugin_helper.rb
141
+ - test/staypuft_test.rb
122
142
  - test/unit/staypuft_test.rb
123
- homepage: https://github.com/theforeman/OFI
143
+ - test/integration/navigation_test.rb
144
+ - test/factories/staypuft_factories.rb
145
+ - test/test_plugin_helper.rb
146
+ homepage: https://github.com/theforeman/staypuft
124
147
  licenses: []
148
+ metadata: {}
125
149
  post_install_message:
126
150
  rdoc_options: []
127
151
  require_paths:
128
152
  - lib
129
153
  required_ruby_version: !ruby/object:Gem::Requirement
130
- none: false
131
154
  requirements:
132
- - - ! '>='
155
+ - - '>='
133
156
  - !ruby/object:Gem::Version
134
157
  version: '0'
135
158
  required_rubygems_version: !ruby/object:Gem::Requirement
136
- none: false
137
159
  requirements:
138
- - - ! '>='
160
+ - - '>='
139
161
  - !ruby/object:Gem::Version
140
162
  version: '0'
141
163
  requirements: []
142
164
  rubyforge_project:
143
- rubygems_version: 1.8.23
165
+ rubygems_version: 2.0.3
144
166
  signing_key:
145
- specification_version: 3
167
+ specification_version: 4
146
168
  summary: OpenStack Foreman Installer
147
169
  test_files:
148
- - test/factories/staypuft_factories.rb
149
- - test/integration/navigation_test.rb
150
- - test/staypuft_test.rb
151
170
  - test/test_helper.rb
152
- - test/test_plugin_helper.rb
171
+ - test/staypuft_test.rb
153
172
  - test/unit/staypuft_test.rb
173
+ - test/integration/navigation_test.rb
174
+ - test/factories/staypuft_factories.rb
175
+ - test/test_plugin_helper.rb
@@ -1,50 +0,0 @@
1
- #
2
- # Copyright 2014 Red Hat, Inc.
3
- #
4
- # This software is licensed to you under the GNU General Public
5
- # License as published by the Free Software Foundation; either version
6
- # 2 of the License (GPLv2) or (at your option) any later version.
7
- # There is NO WARRANTY for this software, express or implied,
8
- # including the implied warranties of MERCHANTABILITY,
9
- # NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should
10
- # have received a copy of GPLv2 along with this software; if not, see
11
- # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
12
-
13
- module Actions
14
- module Staypuft
15
- module Host
16
-
17
- # creates and provisions Host waiting until it's ready
18
- class Provision < Actions::Base
19
-
20
- middleware.use Actions::Staypuft::Middleware::AsCurrentUser
21
-
22
- def plan(name, hostgroup, compute_resource)
23
- Type! hostgroup, ::Hostgroup
24
- Type! compute_resource, ComputeResource
25
-
26
- input[:name] = name
27
-
28
- sequence do
29
- creation = plan_action Host::Create, name, hostgroup, compute_resource
30
- plan_action Host::Build, creation.output[:host][:id]
31
- plan_action Host::WaitUntilInstalled, creation.output[:host][:id]
32
- # TODO: wait until restarted
33
- end
34
- end
35
-
36
- def humanized_input
37
- input[:name]
38
- end
39
-
40
- def task_output
41
- planned_actions(Host::Create).first.output
42
- end
43
-
44
- def humanized_output
45
- task_output.fetch(:host, {})[:name]
46
- end
47
- end
48
- end
49
- end
50
- end