foreman_acd 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +79 -26
- data/app/controllers/foreman_acd/ansible_playbooks_controller.rb +5 -5
- data/app/controllers/foreman_acd/app_definitions_controller.rb +2 -1
- data/app/controllers/foreman_acd/app_instances_controller.rb +17 -39
- data/app/controllers/foreman_acd/remote_execution_controller.rb +49 -0
- data/app/models/foreman_acd/ansible_playbook.rb +1 -1
- data/app/services/foreman_acd/app_deployer.rb +1 -5
- data/app/views/foreman_acd/ansible_playbooks/index.html.erb +2 -2
- data/app/views/foreman_acd/app_instances/index.html.erb +2 -2
- data/config/routes.rb +2 -1
- data/lib/foreman_acd/version.rb +1 -1
- data/webpack/components/ApplicationDefinition/ApplicationDefinition.js +3 -3
- data/webpack/components/ApplicationDefinition/ApplicationDefinitionActions.js +3 -3
- data/webpack/components/ApplicationInstance/ApplicationInstance.js +3 -3
- data/webpack/components/ApplicationInstance/ApplicationInstanceActions.js +2 -2
- data/webpack/components/ParameterSelection/ParameterSelectionActions.js +3 -3
- data/webpack/components/common/EasyHeaderFormatter.js +18 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 433f2c68da81192db3c98fc013ed2149490f2471e84d372db8241522a33b6630
|
4
|
+
data.tar.gz: aa46c833de3feb1cce0802de82dec78f1610331984e6df8df649fdadfffa2b2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0accbf314dd5776a5b012507d97619be98beff2c11e523da4d27f69e9fdb1bf1d284c134dba6549719312a66ede8cb80c8a06e3851f01a14951b1752ef2e29e8
|
7
|
+
data.tar.gz: d003bc7a5de1c180b2e33ade4e85b2912776db564d59ff9d8eca4f9ccc00c38591fd061649df07bb89e76ad0b0ac5efe1c64dd506132148aaf087b758a18c078
|
data/README.md
CHANGED
@@ -4,67 +4,121 @@
|
|
4
4
|
|
5
5
|
A plugin to bring an user self service portal and application centric deployment to Foreman.
|
6
6
|
|
7
|
+
|
7
8
|
# Description
|
8
9
|
|
9
|
-
The target of this plugin is, to deploy whole applications which include multiple hosts
|
10
|
-
|
10
|
+
The target of this plugin is, to deploy whole applications which include multiple hosts and
|
11
|
+
configure them using an Ansible Playbook / saltstack state.
|
11
12
|
|
12
13
|
This plugin follows the idea of different user types working together.
|
13
|
-
The administrative user creates
|
14
|
+
The administrative user creates Application Definition including multiple servers and
|
14
15
|
configuration management items (Ansible Playbook, saltstack state).
|
15
|
-
The user can create and deploy new
|
16
|
+
The user can create and deploy new Application Instaces with an easy to use self service portal.
|
16
17
|
|
17
|
-
*Example Application Definition:*
|
18
|
-
To run a complex web application, a loadbalancer is required.
|
18
|
+
*Example Application Definition:* To run a complex web application, a loadbalancer is required.
|
19
19
|
The loadbalancer routes the requests to 3 different web servers.
|
20
20
|
The web servers are using a database which is in high availability mode on 2 hosts.
|
21
21
|
=> 6 hosts are required.
|
22
22
|
|
23
23
|
This plugin aims to setup all 6 hosts and to deploy the application.
|
24
24
|
|
25
|
+
|
25
26
|
# Current State
|
26
|
-
|
27
|
-
|
27
|
+
|
28
|
+
## Application Definition
|
29
|
+
|
30
|
+
- Configure a ansible playbook
|
31
|
+
- Use the configured ansible playbook in a Application Definition
|
32
|
+
- Overwrite ansible playbook's group variables for the Application Definition
|
33
|
+
- Set foreman parameters in the Application Definition
|
34
|
+
- Setup various services like webservers, database-servers, etc.
|
35
|
+
|
36
|
+
## Application Instance
|
37
|
+
|
38
|
+
- Use an Application Definition for your Application Instance
|
39
|
+
- Configure specific hosts which uses the Application Definitions services
|
40
|
+
- Deploy these hosts
|
41
|
+
- Configure the hosts using the configured ansible playbook
|
42
|
+
|
28
43
|
|
29
44
|
# Road Map
|
30
|
-
-
|
31
|
-
- Add
|
32
|
-
- Add
|
45
|
+
-
|
46
|
+
- Add Application deployment with single host requirements
|
47
|
+
- Add Application deployment with multi host requirements
|
33
48
|
|
34
49
|
## WARNING
|
35
50
|
|
36
51
|
This plugin is in development.
|
37
|
-
In the current state, a self service portal to deploy single servers can be created.
|
38
52
|
|
39
53
|
## Installation
|
40
54
|
|
41
|
-
See [How_to_Install_a_Plugin](
|
42
|
-
for how to install Foreman plugins
|
55
|
+
See [How_to_Install_a_Plugin](https://theforeman.org/plugins/#2.Installation)
|
56
|
+
for how to install Foreman plugins.
|
57
|
+
|
58
|
+
### TL;DR:
|
59
|
+
|
60
|
+
yum install tfm-rubygem-foreman_acd
|
61
|
+
foreman-maintain service restart --only foreman
|
62
|
+
|
63
|
+
In some cases you need to do manally
|
64
|
+
|
65
|
+
foreman-rake db:migrate
|
66
|
+
foreman-rake db:seed
|
67
|
+
|
68
|
+
### Hints
|
43
69
|
|
44
|
-
|
70
|
+
Katello plugin need to exist, too.
|
71
|
+
|
72
|
+
### Configuration
|
73
|
+
|
74
|
+
To get ansible playbooks running, you need to:
|
75
|
+
|
76
|
+
cat /var/lib/foreman-proxy/ssh/id_rsa_foreman_proxy.pub >> /root/.ssh/authorized_keys
|
77
|
+
|
78
|
+
Make sure, that the job template 'Run ACD Ansible Playbook - SSH Default' is part of your organization / location.
|
45
79
|
|
46
80
|
## Usage
|
47
81
|
|
48
|
-
|
82
|
+
### Ansible Playbook
|
83
|
+
|
84
|
+
* Copy (or checkout a git repository) to e.g. /opt/ansible-playbook
|
85
|
+
* Add a new Ansible Playbook via Configure -> Ansible Playbook
|
86
|
+
* Set the path to /opt/ansible-playbook and name the playbook file. (e.g. site.yml)
|
87
|
+
* Save it and press "Import group variables" for this newly created ansible playbook.
|
88
|
+
|
89
|
+
### Application Definition (Admin)
|
90
|
+
|
49
91
|
* Create an Application Definition (Configure -> Application Definition) first
|
50
|
-
* Select the
|
92
|
+
* Select the Ansible Playbook you want to use.
|
93
|
+
* Add new services and specifiy the host group you want to use.
|
51
94
|
* Specifiy the values, a user could overwrite.
|
52
95
|
(you can set a default value, if you want)
|
53
96
|
|
54
|
-
Application Instance (User)
|
55
|
-
|
97
|
+
### Application Instance (User)
|
98
|
+
|
99
|
+
* Create an Application Instance (Configure -> Application Instance)
|
56
100
|
* Select the Application Definition which should be used
|
57
101
|
* Set the values.
|
58
102
|
Remember, all parameters need to have a value.
|
59
103
|
* Save the Application Instance
|
60
|
-
|
61
|
-
|
104
|
+
|
105
|
+
### Deploy & Configure the Application Instance (User)
|
106
|
+
|
107
|
+
* To Deploy the host, select "Deploy" in the action selection dropdown field
|
108
|
+
on the Application Instance index site.
|
109
|
+
* See if the hosts are deployed via action selection dropdown -> report.
|
110
|
+
* After all hosts are deployed, run the ansible playbook via
|
111
|
+
action selection dropdown -> Run ansible playbook
|
112
|
+
|
62
113
|
|
63
114
|
## TODO
|
64
115
|
|
65
|
-
- Add
|
66
|
-
-
|
67
|
-
-
|
116
|
+
- Add saltstack support to configure the application
|
117
|
+
- "git" support for the ansible playbooks
|
118
|
+
- Automatically run the ansible playbook after all hosts are deployed
|
119
|
+
- More parameter / value validation
|
120
|
+
- Deliver ansible playbooks to the connected foreman smart proxies
|
121
|
+
|
68
122
|
|
69
123
|
## Contributing
|
70
124
|
|
@@ -72,7 +126,7 @@ Fork and send a Pull Request. Thanks!
|
|
72
126
|
|
73
127
|
## Copyright
|
74
128
|
|
75
|
-
Copyright (c)
|
129
|
+
Copyright (c) 2020 ATIX AG
|
76
130
|
|
77
131
|
This program is free software: you can redistribute it and/or modify
|
78
132
|
it under the terms of the GNU General Public License as published by
|
@@ -86,4 +140,3 @@ GNU General Public License for more details.
|
|
86
140
|
|
87
141
|
You should have received a copy of the GNU General Public License
|
88
142
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
89
|
-
|
@@ -86,11 +86,11 @@ module ForemanAcd
|
|
86
86
|
|
87
87
|
# We need to support: group_vars/group_file and group_vars/group_dir/yaml_files
|
88
88
|
dir_and_file = File.split(vars_file)
|
89
|
-
|
90
|
-
if basename == 'group_vars'
|
91
|
-
group_name = dir_and_file[1]
|
92
|
-
else
|
93
|
-
group_name = basename
|
89
|
+
|
90
|
+
if File.basename(dir_and_file[0]) == 'group_vars' # in case of group_vars/group_file
|
91
|
+
group_name = File.basename(dir_and_file[1], '.*')
|
92
|
+
else # in case of group_vars/group_dir/yaml_files
|
93
|
+
group_name = File.basename(dir_and_file[0])
|
94
94
|
end
|
95
95
|
|
96
96
|
logger.debug("Add ansible vars from file #{vars_file} to group #{group_name}")
|
@@ -16,7 +16,8 @@ module ForemanAcd
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def read_ansible_playbooks
|
19
|
-
|
19
|
+
# Only use ansible playbooks for which the user pressed import group vars once.
|
20
|
+
@ansible_playbooks = AnsiblePlaybook.where.not(vars: nil).map { |elem| { elem.id => elem.name } }.reduce({}) { |h, v| h.merge v }
|
20
21
|
end
|
21
22
|
|
22
23
|
def read_hostgroups
|
@@ -6,17 +6,13 @@ module ForemanAcd
|
|
6
6
|
include Foreman::Controller::AutoCompleteSearch
|
7
7
|
include ::ForemanAcd::Concerns::AppInstanceParameters
|
8
8
|
|
9
|
-
before_action :find_resource, :only => [:edit, :update, :destroy, :deploy, :report
|
9
|
+
before_action :find_resource, :only => [:edit, :update, :destroy, :deploy, :report]
|
10
10
|
before_action :read_applications, :only => [:new, :edit]
|
11
11
|
|
12
12
|
def index
|
13
13
|
@app_instances = resource_base.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
|
14
14
|
end
|
15
15
|
|
16
|
-
def read_applications
|
17
|
-
@applications = AppDefinition.all.map { |elem| { elem.id => elem.name } }.reduce({}) { |h, v| h.merge v }
|
18
|
-
end
|
19
|
-
|
20
16
|
def new
|
21
17
|
@app_instance = AppInstance.new
|
22
18
|
end
|
@@ -55,8 +51,6 @@ module ForemanAcd
|
|
55
51
|
:deploy
|
56
52
|
when 'report'
|
57
53
|
:report
|
58
|
-
when 'configure'
|
59
|
-
:configure
|
60
54
|
else
|
61
55
|
super
|
62
56
|
end
|
@@ -64,51 +58,35 @@ module ForemanAcd
|
|
64
58
|
|
65
59
|
def deploy
|
66
60
|
app_deployer = ForemanAcd::AppDeployer.new(@app_instance)
|
61
|
+
app_hosts = app_deployer.deploy
|
67
62
|
|
68
63
|
# save any change to the app_hosts json
|
69
|
-
@app_instance.hosts =
|
64
|
+
@app_instance.hosts = app_hosts.to_json
|
70
65
|
@app_instance.save
|
71
66
|
|
72
|
-
@deploy_hosts =
|
67
|
+
@deploy_hosts = collect_host_report_data(app_hosts)
|
73
68
|
end
|
74
69
|
|
75
70
|
def report
|
76
|
-
@report_hosts = []
|
77
71
|
app_hosts = JSON.parse(@app_instance.hosts)
|
78
|
-
|
79
|
-
h = Host.find(host_data['foreman_host_id'])
|
80
|
-
@report_hosts.push({id: h.id, name: host_data['hostname'], hostname: h.hostname, hostUrl: host_path(h), powerStatusUrl: power_api_host_path(h) })
|
81
|
-
end
|
72
|
+
@report_hosts = collect_host_report_data(app_hosts)
|
82
73
|
|
83
74
|
logger.debug("deploy report hosts are: #{@report_hosts.inspect}")
|
84
75
|
end
|
85
76
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
logger.debug("Created #{job_count} to configure #{@app_instance} - customize: #{customize_first}")
|
98
|
-
|
99
|
-
if job_count == 1 && customize_first == false
|
100
|
-
jobs.first.trigger!
|
101
|
-
redirect_to job_invocation_path(jobs.first.job_invocation)
|
102
|
-
elsif customize_first == false
|
103
|
-
jobs.each do |composer|
|
104
|
-
composer.save
|
105
|
-
end
|
106
|
-
# redirect to the job itself if we want to customize the job
|
107
|
-
redirect_to job_invocations_path
|
108
|
-
else
|
109
|
-
# redirect to the job itself if we only have one job, otherwise to the index page
|
110
|
-
redirect_to job_invocations_path
|
77
|
+
private
|
78
|
+
|
79
|
+
def read_applications
|
80
|
+
@applications = AppDefinition.all.map { |elem| { elem.id => elem.name } }.reduce({}) { |h, v| h.merge v }
|
81
|
+
end
|
82
|
+
|
83
|
+
def collect_host_report_data(app_hosts)
|
84
|
+
report_data = []
|
85
|
+
app_hosts.each do |host_data|
|
86
|
+
host = Host.find(host_data['foreman_host_id'])
|
87
|
+
report_data << { id: host.id, name: host_data['hostname'], hostname: host.hostname, hostUrl: host_path(host), progress_report_id: host.progress_report_id}
|
111
88
|
end
|
89
|
+
report_data
|
112
90
|
end
|
113
91
|
end
|
114
92
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ForemanAcd
|
4
|
+
# Class to run remote execution jobs
|
5
|
+
class RemoteExecutionController < JobInvocationsController
|
6
|
+
|
7
|
+
def new
|
8
|
+
jobs = init_configuration
|
9
|
+
@composer = jobs.first
|
10
|
+
end
|
11
|
+
|
12
|
+
def create
|
13
|
+
customize_first = params[:customize] || false
|
14
|
+
jobs = init_configuration
|
15
|
+
|
16
|
+
if jobs.count == 1 && customize_first == false
|
17
|
+
@composer = jobs.first
|
18
|
+
@composer.trigger!
|
19
|
+
redirect_to job_invocation_path(@composer.job_invocation)
|
20
|
+
elsif customize_first == false
|
21
|
+
jobs.each do |composer|
|
22
|
+
composer.trigger
|
23
|
+
end
|
24
|
+
# redirect to the job itself if we want to customize the job
|
25
|
+
redirect_to job_invocations_path
|
26
|
+
else
|
27
|
+
@composer = jobs.first
|
28
|
+
render :action => 'new'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# to overcome the isolated namespace engine difficulties with paths
|
33
|
+
helper Rails.application.routes.url_helpers
|
34
|
+
def _routes
|
35
|
+
Rails.application.routes
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def init_configuration
|
41
|
+
app_instance = ForemanAcd::AppInstance.find_by(:name => params[:id])
|
42
|
+
app_configurator = ForemanAcd::AppConfigurator.new(app_instance)
|
43
|
+
|
44
|
+
jobs = app_configurator.configure
|
45
|
+
logger.debug("Creating #{jobs.count} job(s) to configure the app #{app_instance}. Customize first: #{params[:customize]}")
|
46
|
+
return jobs
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -8,7 +8,7 @@ module ForemanAcd
|
|
8
8
|
friendly_id :name
|
9
9
|
|
10
10
|
self.table_name = 'acd_ansible_playbooks'
|
11
|
-
has_many :app_definitions, :inverse_of => :ansible_playbook, :
|
11
|
+
has_many :app_definitions, :inverse_of => :ansible_playbook, :foreign_key => 'acd_ansible_playbook_id', dependent: :restrict_with_error
|
12
12
|
validates :name, :presence => true, :uniqueness => true
|
13
13
|
scoped_search :on => :name
|
14
14
|
default_scope -> { order("acd_ansible_playbooks.name") }
|
@@ -5,11 +5,9 @@ module ForemanAcd
|
|
5
5
|
class AppDeployer
|
6
6
|
|
7
7
|
delegate :logger, :to => :Rails
|
8
|
-
attr_reader :deploy_hosts
|
9
8
|
|
10
9
|
def initialize(app_instance)
|
11
10
|
@app_instance = app_instance
|
12
|
-
@deploy_hosts = []
|
13
11
|
end
|
14
12
|
|
15
13
|
def deploy
|
@@ -44,7 +42,7 @@ module ForemanAcd
|
|
44
42
|
end
|
45
43
|
|
46
44
|
# REMOVE ME (but very nice for testing)
|
47
|
-
#host.mac = "00:11:22:33:44:55"
|
45
|
+
# host.mac = "00:11:22:33:44:55"
|
48
46
|
|
49
47
|
apply_compute_profile(host)
|
50
48
|
host.suggest_default_pxe_loader
|
@@ -52,8 +50,6 @@ module ForemanAcd
|
|
52
50
|
|
53
51
|
# save the foreman host id
|
54
52
|
host_data['foreman_host_id'] = host.id
|
55
|
-
|
56
|
-
@deploy_hosts.push({ id: host.id, name: host_data['hostname'], hostname: host.hostname, hostUrl: host_path(h), progress_report_id: host.progress_report_id})
|
57
53
|
rescue StandardError => e
|
58
54
|
logger.error("Failed to initiate host creation: #{e.class}: #{e.message}\n#{e.backtrace.join($INPUT_RECORD_SEPARATOR)}")
|
59
55
|
end
|
@@ -16,9 +16,9 @@
|
|
16
16
|
<td><%= ansible_playbook.description %></td>
|
17
17
|
<td>
|
18
18
|
<%= action_buttons(
|
19
|
+
display_link_if_authorized(_("Import group variables"), hash_for_import_vars_ansible_playbook_path(:id => ansible_playbook).merge(:auth_object => ansible_playbook, :authorizer => authorizer)),
|
19
20
|
display_delete_if_authorized(hash_for_ansible_playbook_path(:id => ansible_playbook).merge(:auth_object => ansible_playbook, :authorizer => authorizer),
|
20
|
-
:data => { 'confirm': _('Delete %s?') % ansible_playbook.name })
|
21
|
-
display_link_if_authorized(_("Import group variables"), hash_for_import_vars_ansible_playbook_path(:id => ansible_playbook).merge(:auth_object => ansible_playbook, :authorizer => authorizer))
|
21
|
+
:data => { 'confirm': _('Delete %s?') % ansible_playbook.name })
|
22
22
|
) %>
|
23
23
|
</td>
|
24
24
|
</tr>
|
@@ -17,9 +17,9 @@
|
|
17
17
|
<td>
|
18
18
|
<%= action_buttons(display_link_if_authorized(_("Deploy"), hash_for_deploy_app_instance_path(:id => app_instance), :method => :post,
|
19
19
|
:title => _("Deploy application #{app_instance}")),
|
20
|
-
display_link_if_authorized(_("Run Playbook"),
|
20
|
+
display_link_if_authorized(_("Run Playbook"), hash_for_remote_execution_path(:id => app_instance), :method => :post,
|
21
21
|
:title => _("Run ansible playbook for application #{app_instance}")),
|
22
|
-
display_link_if_authorized(_("Run Playbook - customize first"),
|
22
|
+
display_link_if_authorized(_("Run Playbook - customize first"), hash_for_remote_execution_path(:id => app_instance, :customize => true), :method => :post,
|
23
23
|
:title => _("Prepare job to run ansible playbook for application #{app_instance}")),
|
24
24
|
display_link_if_authorized(_("Report"), hash_for_report_app_instance_path(:id => app_instance), :method => :get,
|
25
25
|
:title => _("Show last deployment report for application #{app_instance}")),
|
data/config/routes.rb
CHANGED
@@ -31,11 +31,12 @@ Rails.application.routes.draw do
|
|
31
31
|
|
32
32
|
member do
|
33
33
|
post 'deploy'
|
34
|
-
post 'configure'
|
35
34
|
get 'report'
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
38
|
+
match '/remote_execution', :controller => 'foreman_acd/remote_execution', :action => 'create', :via => [:post]
|
39
|
+
|
39
40
|
get 'ui_acd_app/:id', :to => 'ui_acd#app', :constraints => { :id => /[\w\.-]+/ }, :as => :ui_acd_app
|
40
41
|
get 'ui_acd_foreman_data/:id', :to => 'ui_acd#foreman_data', :constraints => { :id => /[\w\.-]+/ }, :as => :ui_acd_foreman_data
|
41
42
|
get 'ui_acd_ansible_data/:id', :to => 'ui_acd#ansible_data', :constraints => { :id => /[\w\.-]+/ }, :as => :ui_acd_ansible_data
|
data/lib/foreman_acd/version.rb
CHANGED
@@ -11,7 +11,8 @@ import Select from 'foremanReact/components/common/forms/Select';
|
|
11
11
|
import ParameterSelection from '../ParameterSelection';
|
12
12
|
import AddTableEntry from '../common/AddTableEntry';
|
13
13
|
import DeleteTableEntry from '../common/DeleteTableEntry';
|
14
|
-
import RailsData from '../common/RailsData'
|
14
|
+
import RailsData from '../common/RailsData';
|
15
|
+
import EasyHeaderFormatter from '../common/EasyHeaderFormatter';
|
15
16
|
import AnsiblePlaybookSelector from './components/AnsiblePlaybookSelector';
|
16
17
|
|
17
18
|
import {
|
@@ -118,8 +119,7 @@ class ApplicationDefinition extends React.Component {
|
|
118
119
|
});
|
119
120
|
this.inlineEditButtonsFormatter = inlineEditButtonsFormatter;
|
120
121
|
|
121
|
-
|
122
|
-
this.headerFormatter = headerFormatter;
|
122
|
+
this.headerFormatter = EasyHeaderFormatter;
|
123
123
|
|
124
124
|
const inlineEditFormatterImpl = {
|
125
125
|
renderValue: (value, additionalData) => (
|
@@ -55,7 +55,7 @@ export const initApplicationDefinition = (
|
|
55
55
|
props: {
|
56
56
|
index: 0,
|
57
57
|
style: {
|
58
|
-
width: '
|
58
|
+
width: '15%'
|
59
59
|
}
|
60
60
|
},
|
61
61
|
},
|
@@ -71,7 +71,7 @@ export const initApplicationDefinition = (
|
|
71
71
|
props: {
|
72
72
|
index: 1,
|
73
73
|
style: {
|
74
|
-
width: '
|
74
|
+
width: '10%'
|
75
75
|
}
|
76
76
|
},
|
77
77
|
},
|
@@ -151,7 +151,7 @@ export const initApplicationDefinition = (
|
|
151
151
|
props: {
|
152
152
|
index: 6,
|
153
153
|
style: {
|
154
|
-
width: '
|
154
|
+
width: '15%'
|
155
155
|
}
|
156
156
|
},
|
157
157
|
},
|
@@ -10,7 +10,8 @@ import Select from 'foremanReact/components/common/forms/Select';
|
|
10
10
|
import ParameterSelection from '../ParameterSelection';
|
11
11
|
import AddTableEntry from '../common/AddTableEntry';
|
12
12
|
import DeleteTableEntry from '../common/DeleteTableEntry';
|
13
|
-
import RailsData from '../common/RailsData'
|
13
|
+
import RailsData from '../common/RailsData';
|
14
|
+
import EasyHeaderFormatter from '../common/EasyHeaderFormatter';
|
14
15
|
import AppDefinitionSelector from './components/AppDefinitionSelector';
|
15
16
|
import ServiceCounter from './components/ServiceCounter';
|
16
17
|
import { arrayToObject } from '../../helper';
|
@@ -145,8 +146,7 @@ class ApplicationInstance extends React.Component {
|
|
145
146
|
});
|
146
147
|
this.inlineEditButtonsFormatter = inlineEditButtonsFormatter;
|
147
148
|
|
148
|
-
|
149
|
-
this.headerFormatter = headerFormatter;
|
149
|
+
this.headerFormatter = EasyHeaderFormatter;
|
150
150
|
|
151
151
|
const inlineEditFormatterImpl = {
|
152
152
|
renderValue: (value, additionalData) => (
|
@@ -50,7 +50,7 @@ export const initApplicationInstance = (
|
|
50
50
|
props: {
|
51
51
|
index: 0,
|
52
52
|
style: {
|
53
|
-
width: '
|
53
|
+
width: '30%'
|
54
54
|
}
|
55
55
|
},
|
56
56
|
},
|
@@ -66,7 +66,7 @@ export const initApplicationInstance = (
|
|
66
66
|
props: {
|
67
67
|
index: 1,
|
68
68
|
style: {
|
69
|
-
width: '
|
69
|
+
width: '30%'
|
70
70
|
}
|
71
71
|
},
|
72
72
|
},
|
@@ -77,7 +77,7 @@ export const initParameterSelection = (
|
|
77
77
|
props: {
|
78
78
|
sort: true,
|
79
79
|
style: {
|
80
|
-
width: '
|
80
|
+
width: '25%'
|
81
81
|
}
|
82
82
|
},
|
83
83
|
transforms: [sortableTransform],
|
@@ -96,7 +96,7 @@ export const initParameterSelection = (
|
|
96
96
|
props: {
|
97
97
|
sort: true,
|
98
98
|
style: {
|
99
|
-
width: '
|
99
|
+
width: '25%'
|
100
100
|
}
|
101
101
|
},
|
102
102
|
transforms: [sortableTransform],
|
@@ -159,7 +159,7 @@ export const initParameterSelection = (
|
|
159
159
|
label: 'Actions',
|
160
160
|
props: {
|
161
161
|
style: {
|
162
|
-
width: '
|
162
|
+
width: '10%'
|
163
163
|
}
|
164
164
|
},
|
165
165
|
formatters: [actionHeaderCellFormatter]
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import {
|
4
|
+
Table,
|
5
|
+
} from 'patternfly-react';
|
6
|
+
|
7
|
+
const EasyHeaderFormatter = (value, { column }) => (
|
8
|
+
<Table.Heading aria-label={column.header.label} {...column.header.props}>
|
9
|
+
{value}
|
10
|
+
</Table.Heading>
|
11
|
+
);
|
12
|
+
|
13
|
+
EasyHeaderFormatter.propTypes = {
|
14
|
+
value: PropTypes.string.isRequired,
|
15
|
+
column: PropTypes.object.isRequired,
|
16
|
+
};
|
17
|
+
|
18
|
+
export default EasyHeaderFormatter;
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_acd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ATIX AG
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -62,6 +62,7 @@ files:
|
|
62
62
|
- app/controllers/foreman_acd/concerns/ansible_playbook_parameters.rb
|
63
63
|
- app/controllers/foreman_acd/concerns/app_definition_parameters.rb
|
64
64
|
- app/controllers/foreman_acd/concerns/app_instance_parameters.rb
|
65
|
+
- app/controllers/foreman_acd/remote_execution_controller.rb
|
65
66
|
- app/controllers/ui_acd_controller.rb
|
66
67
|
- app/models/foreman_acd/ansible_playbook.rb
|
67
68
|
- app/models/foreman_acd/app_definition.rb
|
@@ -175,6 +176,7 @@ files:
|
|
175
176
|
- webpack/components/ParameterSelection/index.js
|
176
177
|
- webpack/components/common/AddTableEntry.js
|
177
178
|
- webpack/components/common/DeleteTableEntry.js
|
179
|
+
- webpack/components/common/EasyHeaderFormatter.js
|
178
180
|
- webpack/components/common/ExtSelect.js
|
179
181
|
- webpack/components/common/RailsData.js
|
180
182
|
- webpack/components/common/__tests__/AddTableEntry.test.js
|