staypuft 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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