staypuft 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +619 -0
- data/README.md +109 -0
- data/Rakefile +35 -0
- data/app/assets/javascripts/staypuft/staypuft.js +21 -0
- data/app/assets/stylesheets/staypuft/bootstrap_and_overrides.css.scss +80 -0
- data/app/assets/stylesheets/staypuft/staypuft.css.scss +35 -0
- data/app/controllers/staypuft/application_controller.rb +5 -0
- data/app/controllers/staypuft/deployment_steps_controller.rb +51 -0
- data/app/controllers/staypuft/deployments_controller.rb +37 -0
- data/app/helpers/staypuft/application_helper.rb +13 -0
- data/app/helpers/staypuft/deployments_helper.rb +12 -0
- data/app/lib/actions/staypuft/deployment/deploy.rb +32 -0
- data/app/lib/actions/staypuft/host/build.rb +55 -0
- data/app/lib/actions/staypuft/host/create.rb +69 -0
- data/app/lib/actions/staypuft/host/deploy.rb +40 -0
- data/app/lib/actions/staypuft/host/provision.rb +50 -0
- data/app/lib/actions/staypuft/host/puppet_run.rb +36 -0
- data/app/lib/actions/staypuft/host/wait_until_host_ready.rb +72 -0
- data/app/lib/actions/staypuft/host/wait_until_installed.rb +44 -0
- data/app/lib/actions/staypuft/hostgroup/deploy.rb +47 -0
- data/app/lib/actions/staypuft/hostgroup/ordered_deploy.rb +42 -0
- data/app/lib/actions/staypuft/middleware/as_current_user.rb +38 -0
- data/app/lib/staypuft/exception.rb +15 -0
- data/app/models/settings/staypuft.rb +21 -0
- data/app/models/staypuft/concerns/host_orchestration_build_hook.rb +23 -0
- data/app/models/staypuft/concerns/hostgroup_extensions.rb +41 -0
- data/app/models/staypuft/concerns/puppetclass_extensions.rb +12 -0
- data/app/models/staypuft/deployment.rb +61 -0
- data/app/models/staypuft/deployment_role_hostgroup.rb +18 -0
- data/app/models/staypuft/layout.rb +13 -0
- data/app/models/staypuft/layout_role.rb +14 -0
- data/app/models/staypuft/role.rb +20 -0
- data/app/models/staypuft/role_class.rb +12 -0
- data/app/models/staypuft/role_service.rb +13 -0
- data/app/models/staypuft/service.rb +13 -0
- data/app/models/staypuft/service_class.rb +13 -0
- data/app/views/staypuft/deployment_steps/_title.html.erb +2 -0
- data/app/views/staypuft/deployment_steps/deployment_settings.html.erb +54 -0
- data/app/views/staypuft/deployment_steps/services_configuration.html.erb +42 -0
- data/app/views/staypuft/deployment_steps/services_selection.html.erb +39 -0
- data/app/views/staypuft/deployments/index.html.erb +26 -0
- data/app/views/staypuft/deployments/show.html.erb +79 -0
- data/app/views/staypuft/layouts/staypuft.html.erb +9 -0
- data/config/routes.rb +12 -0
- data/config/staypuft.local.rb +1 -0
- data/db/migrate/20140309021811_create_staypuft_layouts.rb +10 -0
- data/db/migrate/20140310004533_create_staypuft_deployments.rb +17 -0
- data/db/migrate/20140310023613_create_staypuft_roles.rb +12 -0
- data/db/migrate/20140310174152_create_staypuft_layout_roles.rb +15 -0
- data/db/migrate/20140310194221_create_staypuft_services.rb +10 -0
- data/db/migrate/20140310203855_create_staypuft_role_services.rb +15 -0
- data/db/migrate/20140312044533_create_staypuft_deployment_role_hostgroups.rb +15 -0
- data/db/migrate/20140312050001_create_staypuft_hostgroup_roles.rb +15 -0
- data/db/migrate/20140312050615_create_staypuft_role_classes.rb +15 -0
- data/db/migrate/20140312051144_create_staypuft_service_classes.rb +15 -0
- data/db/migrate/20140315031754_add_networking_to_staypuft_layout.rb +5 -0
- data/db/migrate/20140318163222_add_deploy_order_to_staypuft_layout_role.rb +6 -0
- data/db/migrate/20140325211410_add_role_to_staypuft_deployment_role_hostgroup.rb +27 -0
- data/db/migrate/20140326032027_drop_staypuft_hostgroup_roles.rb +19 -0
- data/db/seeds.rb +243 -0
- data/lib/staypuft/engine.rb +56 -0
- data/lib/staypuft/version.rb +3 -0
- data/lib/staypuft.rb +6 -0
- data/lib/tasks/staypuft_tasks.rake +31 -0
- data/test/factories/staypuft_factories.rb +5 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/staypuft_test.rb +7 -0
- data/test/test_helper.rb +14 -0
- data/test/test_plugin_helper.rb +6 -0
- data/test/unit/staypuft_test.rb +12 -0
- metadata +153 -0
@@ -0,0 +1,72 @@
|
|
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
|
+
class WaitUntilHostReady < Actions::Base
|
18
|
+
|
19
|
+
middleware.use Actions::Staypuft::Middleware::AsCurrentUser
|
20
|
+
include Dynflow::Action::Polling
|
21
|
+
|
22
|
+
def plan(host_id)
|
23
|
+
plan_self host_id: host_id
|
24
|
+
end
|
25
|
+
|
26
|
+
def external_task
|
27
|
+
output[:status]
|
28
|
+
end
|
29
|
+
|
30
|
+
def done?
|
31
|
+
external_task
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def invoke_external_task
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def external_task=(external_task_data)
|
41
|
+
output[:status] = external_task_data
|
42
|
+
end
|
43
|
+
|
44
|
+
def poll_external_task
|
45
|
+
host_ready?(input[:host_id])
|
46
|
+
end
|
47
|
+
|
48
|
+
def poll_interval
|
49
|
+
5
|
50
|
+
end
|
51
|
+
|
52
|
+
def host_ready?(host_id)
|
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
|
62
|
+
end
|
63
|
+
|
64
|
+
def check_for_failures(report)
|
65
|
+
if report.status['failed'] > 0
|
66
|
+
fail(::Staypuft::Exception, "Latest Puppet Run Contains Failures for Host: #{host.id}")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,44 @@
|
|
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
|
+
class WaitUntilInstalled < Actions::Base
|
18
|
+
|
19
|
+
middleware.use Actions::Staypuft::Middleware::AsCurrentUser
|
20
|
+
|
21
|
+
def run(event = nil)
|
22
|
+
case event
|
23
|
+
when nil
|
24
|
+
suspend do |suspended_action|
|
25
|
+
Rails.cache.write(
|
26
|
+
::Staypuft::Concerns::HostOrchestrationBuildHook.cache_id(input[:host_id]),
|
27
|
+
{ execution_plan_id: suspended_action.execution_plan_id,
|
28
|
+
step_id: suspended_action.step_id })
|
29
|
+
end
|
30
|
+
when Hash
|
31
|
+
output[:installed_at] = event.fetch(:installed_at).to_s
|
32
|
+
else
|
33
|
+
raise TypeError
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def plan(host_id)
|
38
|
+
plan_self host_id: host_id
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,47 @@
|
|
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 Hostgroup
|
16
|
+
class Deploy < Actions::Base
|
17
|
+
|
18
|
+
middleware.use Actions::Staypuft::Middleware::AsCurrentUser
|
19
|
+
|
20
|
+
def plan(hostgroup, hosts)
|
21
|
+
Type! hostgroup, ::Hostgroup
|
22
|
+
(Type! hosts, Array).all? { |v| Type! v, ::Host::Base }
|
23
|
+
|
24
|
+
input.update id: hostgroup.id, name: hostgroup.name
|
25
|
+
|
26
|
+
# hostgroup.hosts returns already converted hosts from Host::Discovered with build flag
|
27
|
+
# set to false so they are not built when assigned to the hostgroup in wizard
|
28
|
+
# run Hostgroup's Hosts filtered by hosts
|
29
|
+
(hostgroup.hosts & hosts).each do |host|
|
30
|
+
# planned in concurrence
|
31
|
+
plan_action Host::Deploy, host
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def humanized_input
|
36
|
+
input[:name]
|
37
|
+
end
|
38
|
+
|
39
|
+
def humanized_output
|
40
|
+
format "Hostgroup: %s\n%s", input[:name],
|
41
|
+
planned_actions.map(&:humanized_output).map { |l| ' ' + l }.join("\n")
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,42 @@
|
|
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 Hostgroup
|
16
|
+
# deploys Hostgroups in given order
|
17
|
+
class OrderedDeploy < Actions::Base
|
18
|
+
|
19
|
+
middleware.use Actions::Staypuft::Middleware::AsCurrentUser
|
20
|
+
|
21
|
+
def plan(hostgroups, hosts = hostgroups.inject([]) { |a, hg| a + hg.hosts })
|
22
|
+
(Type! hostgroups, Array).all? { |v| Type! v, ::Hostgroup }
|
23
|
+
(Type! hosts, Array).all? { |v| Type! v, ::Host::Base }
|
24
|
+
|
25
|
+
sequence do
|
26
|
+
hostgroups.each do |hostgroup|
|
27
|
+
plan_action Hostgroup::Deploy, hostgroup, hosts
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def humanized_input
|
33
|
+
planned_actions.map(&:humanized_input).join(', ')
|
34
|
+
end
|
35
|
+
|
36
|
+
def humanized_output
|
37
|
+
planned_actions.map(&:humanized_output).join("\n")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Actions
|
2
|
+
module Staypuft
|
3
|
+
module Middleware
|
4
|
+
class AsCurrentUser < Dynflow::Middleware
|
5
|
+
|
6
|
+
def plan(*args)
|
7
|
+
pass(*args).tap do
|
8
|
+
raise 'no current user' unless Type? User.current, User
|
9
|
+
action.input.update current_user_id: User.current.id
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def run(*args)
|
14
|
+
as_current_user { pass(*args) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def finalize
|
18
|
+
as_current_user { pass }
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def current_user_id
|
24
|
+
action.input.fetch(:current_user_id)
|
25
|
+
end
|
26
|
+
|
27
|
+
def as_current_user
|
28
|
+
old = User.current
|
29
|
+
User.current = User.find current_user_id
|
30
|
+
yield
|
31
|
+
ensure
|
32
|
+
User.current = old
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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 Staypuft
|
14
|
+
class Exception < ::Foreman::Exception; end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Setting::Staypuft < ::Setting
|
2
|
+
BLANK_ATTRS << "base_hostgroup"
|
3
|
+
|
4
|
+
def self.load_defaults
|
5
|
+
# Check the table exists
|
6
|
+
return unless super
|
7
|
+
|
8
|
+
# fixme: not sure about the best way to store AR objects in settings.
|
9
|
+
# for now, since we know type, store ID. It might be good to add custom
|
10
|
+
# get/set code to decode the ID value into a hostgroup (which methods to call?)
|
11
|
+
Setting.transaction do
|
12
|
+
[
|
13
|
+
self.set("base_hostgroup", _("The base hostgroup which contains the base provisioning config"), nil)
|
14
|
+
].compact.each { |s| self.create s.update(:category => "Setting::Staypuft")}
|
15
|
+
end
|
16
|
+
|
17
|
+
true
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Staypuft
|
2
|
+
module Concerns
|
3
|
+
module HostOrchestrationBuildHook
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
before_provision :wake_up_orchestration
|
8
|
+
end
|
9
|
+
|
10
|
+
def wake_up_orchestration
|
11
|
+
key = HostOrchestrationBuildHook.cache_id(id)
|
12
|
+
ids = Rails.cache.read(key)
|
13
|
+
Rails.cache.delete key
|
14
|
+
ForemanTasks.dynflow.world.event *ids.values_at(:execution_plan_id, :step_id),
|
15
|
+
installed_at: installed_at
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.cache_id(host_id)
|
19
|
+
"host.#{host_id}.wake_up_orchestration"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Staypuft::Concerns::HostgroupExtensions
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
has_one :deployment_role_hostgroup, :dependent => :destroy, :class_name => 'Staypuft::DeploymentRoleHostgroup'
|
6
|
+
has_one :parent_deployment, :through => :deployment_role_hostgroup, :class_name => 'Staypuft::Deployment'
|
7
|
+
has_one :role, :through => :deployment_role_hostgroup, :class_name => 'Staypuft::Role'
|
8
|
+
|
9
|
+
has_one :deployment, :class_name => 'Staypuft::Deployment'
|
10
|
+
|
11
|
+
def add_puppetclasses_from_resource(resource)
|
12
|
+
if resource.respond_to?(:puppetclasses)
|
13
|
+
resource.puppetclasses.each do |puppetclass|
|
14
|
+
unless puppetclasses.include?(puppetclass)
|
15
|
+
puppetclasses << puppetclass
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
Gem::Version.new(SETTINGS[:version].to_s.gsub(/-develop$/, '')) < Gem::Version.new('1.5') or
|
24
|
+
raise 'remove nest method, nesting Hostgroups is fixed in Foreman 1.5, use just parent_id'
|
25
|
+
|
26
|
+
def nest(name, parent)
|
27
|
+
new = parent.dup
|
28
|
+
new.parent_id = parent.id
|
29
|
+
new.name = name
|
30
|
+
|
31
|
+
new.puppetclasses = parent.puppetclasses
|
32
|
+
new.locations = parent.locations
|
33
|
+
new.organizations = parent.organizations
|
34
|
+
|
35
|
+
# Clone any parameters as well
|
36
|
+
new.group_parameters.each { |param| parent.group_parameters << param.dup }
|
37
|
+
new
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Staypuft::Concerns::PuppetclassExtensions
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
has_many :role_classes, :dependent => :destroy, :class_name => 'Staypuft::RoleClass'
|
6
|
+
has_many :roles, :through => :role_classes, :class_name => 'Staypuft::Role'
|
7
|
+
|
8
|
+
has_many :service_classes, :dependent => :destroy, :class_name => 'Staypuft::ServiceClass'
|
9
|
+
has_many :services, :through => :service_classes, :class_name => 'Staypuft::Service'
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class Deployment < ActiveRecord::Base
|
3
|
+
attr_accessible :description, :name, :layout_id, :layout
|
4
|
+
after_save :update_hostgroup_name
|
5
|
+
|
6
|
+
belongs_to :layout
|
7
|
+
belongs_to :hostgroup, :dependent => :destroy
|
8
|
+
|
9
|
+
has_many :deployment_role_hostgroups, :dependent => :destroy
|
10
|
+
has_many :child_hostgroups, :through => :deployment_role_hostgroups, :class_name => 'Hostgroup',
|
11
|
+
:source => :hostgroup
|
12
|
+
has_many :roles, :through => :deployment_role_hostgroups
|
13
|
+
|
14
|
+
validates :name, :presence => true, :uniqueness => true
|
15
|
+
|
16
|
+
validates :layout, :presence => true
|
17
|
+
validates :hostgroup, :presence => true
|
18
|
+
|
19
|
+
scoped_search :on => :name, :complete_value => :true
|
20
|
+
|
21
|
+
def destroy
|
22
|
+
child_hostgroups.each do |h|
|
23
|
+
h.destroy
|
24
|
+
end
|
25
|
+
#do the main destroy
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
# After setting or changing layout, update the set of child hostgroups,
|
30
|
+
# adding groups for any roles not already represented, and removing others
|
31
|
+
# no longer needed.
|
32
|
+
def update_hostgroup_list
|
33
|
+
old_role_hostgroups_arr = deployment_role_hostgroups.to_a
|
34
|
+
layout.layout_roles.each do |layout_role|
|
35
|
+
role_hostgroup = deployment_role_hostgroups.where(:role_id=>layout_role.role).first_or_initialize do |drh|
|
36
|
+
drh.hostgroup = Hostgroup.nest(layout_role.role.name, hostgroup)
|
37
|
+
end
|
38
|
+
|
39
|
+
role_hostgroup.hostgroup.add_puppetclasses_from_resource(layout_role.role)
|
40
|
+
role_hostgroup.hostgroup.save!
|
41
|
+
|
42
|
+
role_hostgroup.deploy_order = layout_role.deploy_order
|
43
|
+
role_hostgroup.save!
|
44
|
+
|
45
|
+
old_role_hostgroups_arr.delete(role_hostgroup)
|
46
|
+
end
|
47
|
+
# delete any prior mappings that remain
|
48
|
+
old_role_hostgroups_arr.each do |role_hostgroup|
|
49
|
+
role_hostgroup.hostgroup.destroy
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def update_hostgroup_name
|
55
|
+
hostgroup.name = self.name
|
56
|
+
hostgroup.save!
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class DeploymentRoleHostgroup < ActiveRecord::Base
|
3
|
+
attr_accessible :deployment, :deployment_id, :hostgroup, :hostgroup_id, :role, :role_id, :deploy_order
|
4
|
+
|
5
|
+
belongs_to :deployment
|
6
|
+
belongs_to :hostgroup
|
7
|
+
belongs_to :role
|
8
|
+
|
9
|
+
validates :deployment, :presence => true
|
10
|
+
validates :role, :presence => true
|
11
|
+
validates :role_id, :uniqueness => {:scope => :deployment_id}
|
12
|
+
validates :hostgroup, :presence => true
|
13
|
+
validates :hostgroup_id, :uniqueness => true
|
14
|
+
|
15
|
+
validates :deploy_order, :presence => true
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class Layout < ActiveRecord::Base
|
3
|
+
has_many :deployments, :dependent => :destroy
|
4
|
+
|
5
|
+
has_many :layout_roles, :dependent => :destroy, :order => "staypuft_layout_roles.deploy_order ASC"
|
6
|
+
has_many :roles, :through => :layout_roles, :order => "staypuft_layout_roles.deploy_order ASC"
|
7
|
+
|
8
|
+
attr_accessible :description, :name, :networking
|
9
|
+
|
10
|
+
validates :name, :presence => true, :uniqueness => {:scope => :networking}
|
11
|
+
validates :networking, :presence => true, :inclusion => {:in =>['nova', 'neutron']}
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class LayoutRole < ActiveRecord::Base
|
3
|
+
attr_accessible :layout, :layout_id, :role, :role_id, :deploy_order
|
4
|
+
|
5
|
+
belongs_to :layout
|
6
|
+
belongs_to :role
|
7
|
+
|
8
|
+
validates :layout, :presence => true
|
9
|
+
validates :role, :presence => true
|
10
|
+
validates :role_id, :uniqueness => {:scope => :layout_id}
|
11
|
+
validates :deploy_order, :presence => true, :uniqueness => {:scope => :layout_id}
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class Role < ActiveRecord::Base
|
3
|
+
has_many :layout_roles, :dependent => :destroy
|
4
|
+
has_many :layouts, :through => :layout_roles
|
5
|
+
|
6
|
+
has_many :role_classes, :dependent => :destroy
|
7
|
+
has_many :puppetclasses, :through => :role_classes
|
8
|
+
|
9
|
+
has_many :deployment_role_hostgroups, :dependent => :destroy
|
10
|
+
has_many :hostgroups, :through => :deployment_role_hostgroups
|
11
|
+
has_many :deployments, :through => :deployment_role_hostgroups
|
12
|
+
|
13
|
+
has_many :role_services, :dependent => :destroy
|
14
|
+
has_many :services, :through => :role_services
|
15
|
+
|
16
|
+
attr_accessible :description, :max_hosts, :min_hosts, :name
|
17
|
+
|
18
|
+
validates :name, :presence => true, :uniqueness => true
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class RoleClass < ActiveRecord::Base
|
3
|
+
attr_accessible :role_id, :role, :puppetclass_id, :puppetclass
|
4
|
+
|
5
|
+
belongs_to :role
|
6
|
+
belongs_to :puppetclass
|
7
|
+
|
8
|
+
validates :role, :presence => true
|
9
|
+
validates :puppetclass, :presence => true
|
10
|
+
validates :puppetclass_id, :uniqueness => {:scope => :role_id}
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class RoleService < ActiveRecord::Base
|
3
|
+
attr_accessible :service, :service_id, :role, :role_id
|
4
|
+
|
5
|
+
belongs_to :service
|
6
|
+
belongs_to :role
|
7
|
+
|
8
|
+
validates :service, :presence => true
|
9
|
+
validates :role, :presence => true
|
10
|
+
validates :role_id, :uniqueness => {:scope => :service_id}
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class Service < ActiveRecord::Base
|
3
|
+
has_many :role_services, :dependent => :destroy
|
4
|
+
has_many :roles, :through => :role_services
|
5
|
+
|
6
|
+
has_many :service_classes, :dependent => :destroy
|
7
|
+
has_many :puppetclasses, :through => :service_classes
|
8
|
+
|
9
|
+
attr_accessible :description, :name
|
10
|
+
|
11
|
+
validates :name, :presence => true, :uniqueness => true
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Staypuft
|
2
|
+
class ServiceClass < ActiveRecord::Base
|
3
|
+
attr_accessible :service_id, :service, :puppetclass_id, :puppetclass
|
4
|
+
|
5
|
+
belongs_to :service
|
6
|
+
belongs_to :puppetclass
|
7
|
+
|
8
|
+
validates :service, :presence => true
|
9
|
+
validates :puppetclass, :presence => true
|
10
|
+
validates :puppetclass_id, :uniqueness => {:scope => :service_id}
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
<%= render :layout => 'title' do %>
|
2
|
+
<%= form_for(@deployment, :url => wizard_path, :method => 'PUT') do |f| %>
|
3
|
+
<%= base_errors_for @deployment %>
|
4
|
+
|
5
|
+
<div class="wizard-container">
|
6
|
+
<%= deployment_wizard 1 %>
|
7
|
+
</div>
|
8
|
+
<%= text_f f, :name %><br />
|
9
|
+
<%= textarea_f f, :description, :rows => 3 %><br />
|
10
|
+
|
11
|
+
<div class="row">
|
12
|
+
<div class="clearfix">
|
13
|
+
<div class="form-group">
|
14
|
+
<label class="col-md-2 control-label" for="layout_id"><%= _("Deployment Layout") %></label>
|
15
|
+
<div class="col-md-4">
|
16
|
+
<% @layouts.each do |layout| %>
|
17
|
+
<%= radio_button_f_non_inline(f, :layout_id, :checked => layout.id == @deployment.layout_id,:value=>layout.id, :text=> "#{layout.name}, #{layout.networking.capitalize} " + _("Networking")) %>
|
18
|
+
<% end %>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<!-- <div class="row">
|
25
|
+
<%= f.label :services_password, _("Services Password"), :class => "col-md-2 control-label" %><br />
|
26
|
+
<div class="row">
|
27
|
+
<div class="col-md-8">
|
28
|
+
<%= f.radio_button :services_password, false, :checked => true %>
|
29
|
+
<%= f.label :services_password, _("Use single password for all services"), :value => "single_password" %><br />
|
30
|
+
<div class="row">
|
31
|
+
<%= f.label :password, _("Password*"), :class=>"col-md-3 control-label"%>
|
32
|
+
<%= f.password_field :password, :class=>"col-md-5" %>
|
33
|
+
</div><br />
|
34
|
+
<div class="row">
|
35
|
+
<%= f.label :confirm_password, _("Confirm Password*"), :class=>"col-md-3 control-label" %>
|
36
|
+
<%= f.password_field :confirm_password, :class=>"col-md-5" %>
|
37
|
+
</div><br />
|
38
|
+
<%= f.radio_button :services_password, false, :checked => false %>
|
39
|
+
<%= f.label :services_password, _("Generate random passwords for all services"), :value => "random_password" %>
|
40
|
+
</div>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
-->
|
44
|
+
<div class="form_actions">
|
45
|
+
<%= link_to _("Cancel"), deployment_path(@deployment), :method => :delete,
|
46
|
+
:confirm => _("This will clear whole deployment configuration. Are you sure?"),
|
47
|
+
:class => "btn btn-danger" %>
|
48
|
+
<%= button_tag(:type => 'submit', :class => "btn btn-primary pull-right") do %>
|
49
|
+
<%= _("Next") %>
|
50
|
+
<span class="glyphicon glyphicon-chevron-right"></span>
|
51
|
+
<% end %>
|
52
|
+
</div>
|
53
|
+
<% end %>
|
54
|
+
<% end %>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<%= render :layout => 'title' do %>
|
2
|
+
<%= form_for(@deployment, :url => wizard_path, :method => 'PUT') do |f| %>
|
3
|
+
<%= base_errors_for @deployment %>
|
4
|
+
|
5
|
+
<%= deployment_wizard 3 %>
|
6
|
+
<div class="form-group tabbed_side_nav_form row">
|
7
|
+
<ul class="nav nav-pills nav-stacked col-md-3" data-tabs="pills">
|
8
|
+
<h3><%= _("Services") %></h3>
|
9
|
+
<% @services.each_with_index do |service, i| %>
|
10
|
+
<li class="<%= 'active' if i == 0 %>">
|
11
|
+
<a href="#<%= service.name.parameterize.underscore %>" data-toggle="tab">
|
12
|
+
<%= service.name %>
|
13
|
+
</a>
|
14
|
+
</li>
|
15
|
+
<% end %>
|
16
|
+
</ul>
|
17
|
+
|
18
|
+
<div class="tab-content col-md-9">
|
19
|
+
<% @services.each_with_index do |service, i| %>
|
20
|
+
<div class="tab-pane <%= 'active' if i == 0 %>" id="<%= service.name.parameterize.underscore %>">
|
21
|
+
<h3><%= "#{service.name} " + _("Service Configuration") %></h3>
|
22
|
+
<%= text_f f, :name %><br />
|
23
|
+
<%= text_f f, :description %><br />
|
24
|
+
</div>
|
25
|
+
<% end %>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
|
29
|
+
<div class="form_actions">
|
30
|
+
<a class="btn btn-default" href="<%= previous_wizard_path %>">
|
31
|
+
<span class="glyphicon glyphicon-chevron-left"></span>
|
32
|
+
<%= _("Back") %>
|
33
|
+
</a>
|
34
|
+
<%= link_to _("Cancel"), deployment_path(@deployment), :method => :delete,
|
35
|
+
:confirm => _("This will clear whole deployment configuration. Are you sure?"),
|
36
|
+
:class => "btn btn-danger" %>
|
37
|
+
<%= button_tag(:type => 'submit', :class => "btn btn-primary pull-right") do %>
|
38
|
+
<%= _("Submit") %>
|
39
|
+
<% end %>
|
40
|
+
</div>
|
41
|
+
<% end %>
|
42
|
+
<% end %>
|