foreman_acd 0.0.5 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +82 -27
  3. data/app/controllers/foreman_acd/ansible_playbooks_controller.rb +122 -0
  4. data/app/controllers/foreman_acd/api/v2/ansible_playbooks_controller.rb +71 -0
  5. data/app/controllers/foreman_acd/api/v2/app_definitions_controller.rb +1 -2
  6. data/app/controllers/foreman_acd/api/v2/app_instances_controller.rb +54 -0
  7. data/app/controllers/foreman_acd/api/v2/app_playbooks_controller.rb +0 -0
  8. data/app/controllers/foreman_acd/app_definitions_controller.rb +36 -4
  9. data/app/controllers/foreman_acd/app_instances_controller.rb +24 -90
  10. data/app/controllers/foreman_acd/concerns/ansible_playbook_parameters.rb +23 -0
  11. data/app/controllers/foreman_acd/concerns/app_definition_parameters.rb +1 -1
  12. data/app/controllers/foreman_acd/concerns/app_instance_parameters.rb +1 -1
  13. data/app/controllers/foreman_acd/remote_execution_controller.rb +49 -0
  14. data/app/controllers/ui_acd_controller.rb +11 -4
  15. data/app/models/foreman_acd/acd_provider.rb +27 -0
  16. data/app/models/foreman_acd/ansible_playbook.rb +50 -0
  17. data/app/models/foreman_acd/app_definition.rb +2 -1
  18. data/app/models/foreman_acd/app_instance.rb +7 -0
  19. data/app/services/foreman_acd/app_configurator.rb +57 -0
  20. data/app/services/foreman_acd/app_deployer.rb +139 -0
  21. data/app/services/foreman_acd/inventory_creator.rb +67 -0
  22. data/app/views/foreman_acd/ansible_playbooks/_form.html.erb +21 -0
  23. data/app/views/foreman_acd/ansible_playbooks/edit.html.erb +3 -0
  24. data/app/views/foreman_acd/ansible_playbooks/index.html.erb +30 -0
  25. data/app/views/foreman_acd/ansible_playbooks/new.html.erb +3 -0
  26. data/app/views/foreman_acd/api/v2/ansible_playbooks/base.json.rabl +3 -0
  27. data/app/views/foreman_acd/api/v2/ansible_playbooks/index.json.rabl +3 -0
  28. data/app/views/foreman_acd/api/v2/ansible_playbooks/show.json.rabl +3 -0
  29. data/app/views/foreman_acd/api/v2/app_definitions/base.json.rabl +3 -0
  30. data/app/views/foreman_acd/api/v2/app_definitions/index.json.rabl +3 -0
  31. data/app/views/foreman_acd/api/v2/app_definitions/show.json.rabl +3 -0
  32. data/app/views/foreman_acd/api/v2/app_instances/base.json.rabl +3 -0
  33. data/app/views/foreman_acd/api/v2/app_instances/index.json.rabl +3 -0
  34. data/app/views/foreman_acd/api/v2/app_instances/show.json.rabl +3 -0
  35. data/app/views/foreman_acd/app_definitions/_form.html.erb +25 -19
  36. data/app/views/foreman_acd/app_definitions/edit.html.erb +5 -0
  37. data/app/views/foreman_acd/app_definitions/import.html.erb +18 -0
  38. data/app/views/foreman_acd/app_definitions/index.html.erb +9 -5
  39. data/app/views/foreman_acd/app_instances/_form.html.erb +10 -8
  40. data/app/views/foreman_acd/app_instances/deploy.html.erb +19 -0
  41. data/app/views/foreman_acd/app_instances/index.html.erb +10 -5
  42. data/app/views/foreman_acd/app_instances/report.html.erb +19 -0
  43. data/app/views/templates/job/run_acd_ansible_playbook.erb +49 -0
  44. data/app/views/ui_acd/ansible_data.json.rabl +6 -0
  45. data/app/views/ui_acd/app.json.rabl +6 -2
  46. data/app/views/ui_acd/app_definition.json.rabl +1 -1
  47. data/app/views/ui_acd/{fdata.json.rabl → foreman_data.json.rabl} +1 -1
  48. data/config/routes.rb +36 -1
  49. data/db/migrate/20190610202252_create_app_definitions.rb +1 -3
  50. data/db/migrate/20190625140305_create_app_instances.rb +1 -1
  51. data/db/migrate/20200916091018_create_ansible_playbooks.rb +20 -0
  52. data/db/migrate/20200917120220_add_ansible_playbook_id.rb +14 -0
  53. data/db/migrate/20201016002819_add_ansible_vars_all_to_app_definitions.rb +5 -0
  54. data/db/migrate/20201016104338_add_ansible_vars_all_to_app_instances.rb +5 -0
  55. data/db/seeds.d/62_acd_proxy_feature.rb +6 -0
  56. data/db/seeds.d/75-job_templates.rb +8 -0
  57. data/lib/foreman_acd/engine.rb +7 -0
  58. data/lib/foreman_acd/plugin.rb +84 -13
  59. data/lib/foreman_acd/version.rb +1 -1
  60. data/package.json +1 -2
  61. data/webpack/components/ApplicationDefinition/ApplicationDefinition.js +378 -0
  62. data/webpack/components/ApplicationDefinition/ApplicationDefinition.scss +1 -0
  63. data/webpack/components/ApplicationDefinition/ApplicationDefinitionActions.js +295 -0
  64. data/webpack/components/ApplicationDefinition/ApplicationDefinitionConstants.js +14 -0
  65. data/webpack/components/ApplicationDefinition/ApplicationDefinitionHelper.js +26 -0
  66. data/webpack/components/ApplicationDefinition/ApplicationDefinitionReducer.js +243 -0
  67. data/webpack/components/ApplicationDefinition/ApplicationDefinitionSelectors.js +8 -0
  68. data/webpack/components/ApplicationDefinition/components/AnsiblePlaybookSelector.js +49 -0
  69. data/webpack/components/ApplicationDefinition/index.js +33 -0
  70. data/webpack/components/ApplicationInstance/ApplicationInstance.js +414 -0
  71. data/webpack/components/ApplicationInstance/ApplicationInstance.scss +11 -0
  72. data/webpack/components/ApplicationInstance/ApplicationInstanceActions.js +239 -0
  73. data/webpack/components/ApplicationInstance/ApplicationInstanceConstants.js +14 -0
  74. data/webpack/components/ApplicationInstance/ApplicationInstanceReducer.js +295 -0
  75. data/webpack/components/ApplicationInstance/ApplicationInstanceSelectors.js +9 -0
  76. data/webpack/components/ApplicationInstance/components/AppDefinitionSelector.js +49 -0
  77. data/webpack/components/ApplicationInstance/components/Service.js +30 -0
  78. data/webpack/components/ApplicationInstance/components/ServiceCounter.js +37 -0
  79. data/webpack/components/ApplicationInstance/index.js +35 -0
  80. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReport.js +155 -0
  81. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReport.scss +27 -0
  82. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportActions.js +86 -0
  83. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportConstants.js +4 -0
  84. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportReducer.js +52 -0
  85. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportSelectors.js +5 -0
  86. data/webpack/components/ApplicationInstanceReport/components/ReportViewer.js +26 -0
  87. data/webpack/components/ApplicationInstanceReport/index.js +27 -0
  88. data/webpack/components/ParameterSelection/ParameterSelection.js +121 -192
  89. data/webpack/components/ParameterSelection/ParameterSelection.scss +9 -0
  90. data/webpack/components/ParameterSelection/ParameterSelectionActions.js +80 -104
  91. data/webpack/components/ParameterSelection/ParameterSelectionConstants.js +15 -19
  92. data/webpack/components/ParameterSelection/ParameterSelectionHelper.js +3 -35
  93. data/webpack/components/ParameterSelection/ParameterSelectionReducer.js +116 -84
  94. data/webpack/components/ParameterSelection/ParameterSelectionSelectors.js +3 -7
  95. data/webpack/components/ParameterSelection/__fixtures__/parameterSelection.fixtures.js +12 -21
  96. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionData_1.fixtures.js +1 -1
  97. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionReducer.fixtures.js +3 -45
  98. data/webpack/components/ParameterSelection/__tests__/ParameterSelection.test.js +20 -0
  99. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionReducer.test.js +22 -46
  100. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionSelectors.test.js +6 -6
  101. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelection.test.js.snap +40 -265
  102. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionReducer.test.js.snap +11 -96
  103. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionSelectors.test.js.snap +3 -9
  104. data/webpack/components/ParameterSelection/index.js +6 -8
  105. data/webpack/components/common/AddTableEntry.js +30 -0
  106. data/webpack/components/common/DeleteTableEntry.js +38 -0
  107. data/webpack/components/common/EasyHeaderFormatter.js +18 -0
  108. data/webpack/components/common/EditTableEntry.js +49 -0
  109. data/webpack/components/common/ExtSelect.js +43 -0
  110. data/webpack/components/common/LockTableEntry.js +59 -0
  111. data/webpack/components/common/RailsData.js +27 -0
  112. data/webpack/components/common/__tests__/AddTableEntry.test.js +26 -0
  113. data/webpack/components/common/__tests__/DeleteTableEntry.test.js +29 -0
  114. data/webpack/components/common/__tests__/ExtSelect.test.js +38 -0
  115. data/webpack/components/common/__tests__/RailsData.test.js +16 -0
  116. data/webpack/components/common/__tests__/__snapshots__/AddParameter.test.js.snap +35 -0
  117. data/webpack/components/common/__tests__/__snapshots__/AddTableEntry.test.js.snap +35 -0
  118. data/webpack/components/common/__tests__/__snapshots__/DeleteParameter.test.js.snap +41 -0
  119. data/webpack/components/common/__tests__/__snapshots__/DeleteTableEntry.test.js.snap +41 -0
  120. data/webpack/components/common/__tests__/__snapshots__/ExtSelect.test.js.snap +18 -0
  121. data/webpack/components/common/__tests__/__snapshots__/RailsData.test.js.snap +10 -0
  122. data/webpack/helper.js +20 -0
  123. data/webpack/index.js +6 -0
  124. data/webpack/reducer.js +43 -3
  125. metadata +91 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d71f9888fdae570d63f3983bb8b0dc248feb364ff0d4c1703bedeb6b75208c16
4
- data.tar.gz: e84d3d6d2002d2e9d151d27b965ffec73ea8a10c3f5c706d295310978600a1b0
3
+ metadata.gz: 0d211aae9186f8f78068084f48a57c33bcc12840c8c187345a195ce90b474b62
4
+ data.tar.gz: ffdefcc21d390b4cd379cae7f5884a1660303408824206bcede99dfc00cac23b
5
5
  SHA512:
6
- metadata.gz: 2460f666269432d8f3f62b983d48927b4849933ce5be2172c2a9bfdd4ec8540cf9656cb70e93773da09e2e74bc4b5f9317556985b2552b60b5af6d0a8e8a49ca
7
- data.tar.gz: a03268372b9c9f8a5831f566d2d269df7a96b38b0295bdf973b183f93843c023307091a42b96159871c4efdda485e040b1edabc260c33193369a56935a55cc5b
6
+ metadata.gz: 596cce7e2dc9f22f8e53da0060d327e3649963a03df3b89bc60e454698c8318f96d2500dc266ef3a430da959437601154ee00682a416baeaaa0db119f2027d36
7
+ data.tar.gz: 357f087227ff418cf2ed0cbcf18e0ec5487fdb55c985c35fe55dea387f93db7eb1ec4268a312e325f925621bdb2cf16fdad1d06b13e893bce672e8d1aa03d2c3
data/README.md CHANGED
@@ -4,67 +4,123 @@
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
- and an Ansible Playbook / saltstack state to configure the application.
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 application definitions including multiple servers and
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 application instances with an easy to use self service portal.
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
- In the current state the plugin can be used to provide an easy to use self service user portal
27
- to deploy new servers.
28
27
 
29
- # Road Map
30
- - Self service portal for single host deployments (current version)
31
- - Add application deployment with single host requirements
32
- - Add application deployment with multi host requirements
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
+
43
+ # How it works
44
+
45
+ - Configure ansible playbook, application definition and create an instance.
46
+ - If you deploy the application instance, all hosts are created.
47
+ - When done, you can configure the hosts with the linked ansible-playbook.
48
+ - To do so, the [Smart Proxy ACD](https://github.com/ATIX-AG/smart_proxy_acd) is used.
49
+ - The job to configure the hosts will be send to the Smart Proxy ACD which will
50
+ - download the ansible playbook from foreman (provided by an foreman_acd API)
51
+ - extract the ansible playbook on the Smart Proxy
52
+ - run the ansible-playbook on the Smart Proxy
53
+ - On the Monitor -> Job page you see the output of the ansible-playbook run.
54
+
33
55
 
34
56
  ## WARNING
35
57
 
36
58
  This plugin is in development.
37
- In the current state, a self service portal to deploy single servers can be created.
38
59
 
39
60
  ## Installation
40
61
 
41
- See [How_to_Install_a_Plugin](http://projects.theforeman.org/projects/foreman/wiki/How_to_Install_a_Plugin)
42
- for how to install Foreman plugins
62
+ See [How_to_Install_a_Plugin](https://theforeman.org/plugins/#2.Installation)
63
+ for how to install Foreman plugins.
64
+
65
+ You will need to install [Smart Proxy ACD](https://github.com/ATIX-AG/smart_proxy_acd), too.
66
+
67
+ ### TL;DR:
68
+
69
+ yum install tfm-rubygem-foreman_acd tfm-rubygem-smart_proxy_acd tfm-rubygem-smart_proxy_acd_core
70
+ foreman-maintain service restart
71
+
72
+ In some cases you need to do manally
43
73
 
44
- ATM, Katello plugin need to exist, too.
74
+ foreman-rake db:migrate
75
+ foreman-rake db:seed
76
+
77
+ ### Hints
78
+
79
+ Katello plugin need to exist, too.
45
80
 
46
81
  ## Usage
47
82
 
48
- Application Definition (Admin)
83
+ ### Ansible Playbook
84
+
85
+ * Copy (or checkout a git repository) to e.g. /opt/ansible-playbook
86
+ * Add a new Ansible Playbook via Configure -> Ansible Playbook
87
+ * Set the path to /opt/ansible-playbook and name the playbook file. (e.g. site.yml)
88
+ * Save it and press "Import group variables" for this newly created ansible playbook.
89
+
90
+ ### Application Definition (Admin)
91
+
49
92
  * Create an Application Definition (Configure -> Application Definition) first
50
- * Select the Hostgroup you want to use.
93
+ * Select the Ansible Playbook you want to use.
94
+ * Add new services and specifiy the host group you want to use.
51
95
  * Specifiy the values, a user could overwrite.
52
96
  (you can set a default value, if you want)
53
97
 
54
- Application Instance (User)
55
- * Create an Application Instance (Configure -> Application Instrane)
98
+ ### Application Instance (User)
99
+
100
+ * Create an Application Instance (Configure -> Application Instance)
56
101
  * Select the Application Definition which should be used
57
102
  * Set the values.
58
103
  Remember, all parameters need to have a value.
59
104
  * Save the Application Instance
60
- * To Deploy the host, select "Deploy" in the Action selection dropdown field
61
- on the Application Instance index site
105
+
106
+ ### Deploy & Configure the Application Instance (User)
107
+
108
+ * To Deploy the host, select "Deploy" in the action selection dropdown field
109
+ on the Application Instance index site.
110
+ * See if the hosts are deployed via action selection dropdown -> report.
111
+ * After all hosts are deployed, run the ansible playbook via
112
+ action selection dropdown -> Run ansible playbook
113
+
62
114
 
63
115
  ## TODO
64
116
 
65
- - Add ansible playbook / saltstack support to configure the application
66
- - Multi-host support
67
- - Add validation to the different parameter types
117
+ - "git" support for the ansible playbooks
118
+ - Provide application templates which contains application definition and
119
+ the required ansible-playbook.
120
+ - Add saltstack support to configure the application
121
+ - Automatically run the ansible playbook after all hosts are deployed
122
+ - More parameter / value validation
123
+
68
124
 
69
125
  ## Contributing
70
126
 
@@ -72,7 +128,7 @@ Fork and send a Pull Request. Thanks!
72
128
 
73
129
  ## Copyright
74
130
 
75
- Copyright (c) 2019 ATIX AG
131
+ Copyright (c) 2021 ATIX AG
76
132
 
77
133
  This program is free software: you can redistribute it and/or modify
78
134
  it under the terms of the GNU General Public License as published by
@@ -86,4 +142,3 @@ GNU General Public License for more details.
86
142
 
87
143
  You should have received a copy of the GNU General Public License
88
144
  along with this program. If not, see <http://www.gnu.org/licenses/>.
89
-
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ # Ansible Playbook Controller
5
+ class AnsiblePlaybooksController < ::ForemanAcd::ApplicationController
6
+ include Foreman::Controller::AutoCompleteSearch
7
+ include ::ForemanAcd::Concerns::AnsiblePlaybookParameters
8
+
9
+ before_action :find_resource, :only => [:edit, :update, :destroy, :import_vars]
10
+
11
+ def index
12
+ @ansible_playbooks = resource_base.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
13
+ end
14
+
15
+ def new
16
+ @ansible_playbook = AnsiblePlaybook.new
17
+ end
18
+
19
+ def create
20
+ @ansible_playbook = AnsiblePlaybook.new(ansible_playbook_params)
21
+ if @ansible_playbook.save
22
+ process_success
23
+ else
24
+ process_error
25
+ end
26
+ end
27
+
28
+ def edit
29
+ end
30
+
31
+ def update
32
+ if @ansible_playbook.update(ansible_playbook_params)
33
+ process_success
34
+ else
35
+ process_error
36
+ end
37
+ end
38
+
39
+ def destroy
40
+ if @ansible_playbook.destroy
41
+ process_success
42
+ else
43
+ process_error
44
+ end
45
+ end
46
+
47
+ def action_permission
48
+ case params[:action]
49
+ when 'import_vars'
50
+ :import_vars
51
+ else
52
+ super
53
+ end
54
+ end
55
+
56
+ # We need to move these to a smart_proxy_acd
57
+ def extract_variables(playbook_path)
58
+ errors = []
59
+ vars = {}
60
+
61
+ unless File.directory?(playbook_path) || File.directory?("#{playbook_path}/group_vars")
62
+ errors << "Playbook path '#{playbook_path}' or '#{playbook_path}/group_vars' doesn't exist"
63
+ return vars, errors
64
+ end
65
+
66
+ everything_empty = true
67
+
68
+ vars_files = Dir.glob("#{playbook_path}/group_vars/**/*")
69
+ vars_files.each do |vars_file|
70
+ loaded_yaml = {}
71
+ next if File.directory?(vars_file)
72
+
73
+ begin
74
+ loaded_yaml = YAML.load_file(vars_file)
75
+ rescue Psych::SyntaxError
76
+ err = "#{vars_file} is not YAML file"
77
+ logger.error(err)
78
+ errors << err
79
+ end
80
+ unless loaded_yaml.is_a? Hash
81
+ err = "Could not parse YAML file #{vars_file}"
82
+ logger.error(err)
83
+ errors << err
84
+ end
85
+ everything_empty = false unless loaded_yaml.empty?
86
+
87
+ # We need to support: group_vars/group_file and group_vars/group_dir/yaml_files
88
+ dir_and_file = File.split(vars_file)
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
+ end
95
+
96
+ logger.debug("Add ansible vars from file #{vars_file} to group #{group_name}")
97
+
98
+ if vars.has_key?(group_name)
99
+ vars[group_name].merge!(loaded_yaml)
100
+ else
101
+ vars[group_name] = loaded_yaml
102
+ end
103
+ end
104
+
105
+ errors << "No ansible group variable in #{playbook_path} defined." if everything_empty
106
+
107
+ return vars, errors
108
+ end
109
+
110
+ def import_vars
111
+ logger.debug("Load ansible group vars for #{@ansible_playbook} from #{@ansible_playbook.path}")
112
+ vars, errors = extract_variables(@ansible_playbook.path)
113
+ @ansible_playbook.vars = vars.to_json
114
+ @ansible_playbook.save
115
+ if errors.empty?
116
+ process_success :success_msg => _("Successfully loaded ansible group variables from %s") % @ansible_playbook.name, :redirect => ansible_playbooks_path
117
+ else
118
+ process_error :error_msg => _(errors.join(' ')), :redirect => ansible_playbooks_path
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ module Api
5
+ module V2
6
+ # API controller for Ansible Playbooks
7
+ class AnsiblePlaybooksController < ::ForemanAcd::Api::V2::BaseController
8
+ include ::Foreman::Controller::SmartProxyAuth
9
+ include ::ForemanAcd::Concerns::AnsiblePlaybookParameters
10
+
11
+ before_action :find_resource, :except => [:index, :create, :grab]
12
+
13
+ add_smart_proxy_filters :grab, :features => 'ACD'
14
+
15
+ api :GET, '/ansible_playbooks/:id', N_('Show ansible playbook')
16
+ param :id, :identifier, :required => true
17
+ def show; end
18
+
19
+ api :GET, '/ansible_playbooks', N_('List ansible playbooks')
20
+ param_group :search_and_pagination, ::Api::V2::BaseController
21
+ add_scoped_search_description_for(AnsiblePlaybook)
22
+ def index
23
+ @ansible_playbooks = resource_scope_for_index
24
+ end
25
+
26
+ def_param_group :ansible_playbook do
27
+ param :ansible_playbook, Hash, :required => true, :action_aware => true do
28
+ param :name, String, :required => true
29
+ param :description, String, :required => true
30
+ param :services, String, :required => true
31
+ end
32
+ end
33
+
34
+ api :POST, '/ansible_playbooks', N_('Create a ansible playbook')
35
+ param_group :ansible_playbook, :as => :create
36
+ def create
37
+ @ansible_playbook = AnsiblePlaybook.new(ansible_playbook_params)
38
+ process_response @ansible_playbook.save
39
+ end
40
+
41
+ api :DELETE, '/ansible_playbooks/:id', N_('Deletes ansible playbook')
42
+ param :id, :identifier, :required => true
43
+ def destroy
44
+ process_response @ansible_playbook.destroy
45
+ end
46
+
47
+ api :GET, '/ansible_playbooks/:id/grab', N_('Grab ansible playbook')
48
+ param :id, :identifier, :required => true
49
+ def grab
50
+ ap = resource_class.find(params['id'])
51
+ command = "tar cz -C #{ap.path} --exclude \".git\" . 2>/dev/null | base64"
52
+ result = %x<#{command}>
53
+ send_data result, type: "text/plain", disposition: 'inline'
54
+ end
55
+
56
+ def action_permission
57
+ case params[:action]
58
+ when 'grab'
59
+ 'grab'
60
+ else
61
+ super
62
+ end
63
+ end
64
+
65
+ def resource_class
66
+ ForemanAcd::AnsiblePlaybook
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -24,8 +24,7 @@ module ForemanAcd
24
24
  param :app_definition, Hash, :required => true, :action_aware => true do
25
25
  param :name, String, :required => true
26
26
  param :description, String, :required => true
27
- param :hostgroup_id, :number, :required => true
28
- param :parameters, String, :required => true
27
+ param :services, String, :required => true
29
28
  end
30
29
  end
31
30
 
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ module Api
5
+ module V2
6
+ # API controller for App Instances
7
+ class AppInstancesController < ::ForemanAcd::Api::V2::BaseController
8
+ include ::ForemanAcd::Concerns::AppInstanceParameters
9
+
10
+ before_action :find_resource, :except => [:index, :create]
11
+
12
+ api :GET, '/app_instances/:id', N_('Show application instance')
13
+ param :id, :identifier, :required => true
14
+ def show; end
15
+
16
+ api :GET, '/app_instances', N_('List application instances')
17
+ param_group :search_and_pagination, ::Api::V2::BaseController
18
+ add_scoped_search_description_for(AppInstance)
19
+ def index
20
+ @app_instances = resource_scope_for_index
21
+ end
22
+
23
+ def_param_group :app_instance do
24
+ param :app_instance, Hash, :required => true, :action_aware => true do
25
+ param :name, String, :required => true
26
+ param :description, String, :required => true
27
+ param :services, String, :required => true
28
+ end
29
+ end
30
+
31
+ api :POST, '/app_instances', N_('Create a application instance')
32
+ param_group :app_instance, :as => :create
33
+ def create
34
+ @app_instance = AppInstance.new(app_instance_params)
35
+ process_response @app_instance.save
36
+ end
37
+
38
+ api :DELETE, '/app_instances/:id', N_('Deletes application instance')
39
+ param :id, :identifier, :required => true
40
+ def destroy
41
+ process_response @app_instance.destroy
42
+ end
43
+
44
+ def controller_permission
45
+ 'app_instances'
46
+ end
47
+
48
+ def resource_class
49
+ ForemanAcd::AppInstance
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -6,18 +6,25 @@ module ForemanAcd
6
6
  include Foreman::Controller::AutoCompleteSearch
7
7
  include ::ForemanAcd::Concerns::AppDefinitionParameters
8
8
 
9
- before_action :find_resource, :only => [:edit, :update, :destroy]
9
+ before_action :find_resource, :only => [:edit, :update, :destroy, :export]
10
+ before_action :read_hostgroups, :only => [:edit, :new, :import]
11
+ before_action :read_ansible_playbooks, :only => [:edit, :new]
12
+ before_action :handle_file_upload, :only => [:create]
10
13
 
11
14
  def index
12
15
  @app_definitions = resource_base.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
13
16
  end
14
17
 
18
+ def read_ansible_playbooks
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 }
21
+ end
22
+
15
23
  def read_hostgroups
16
24
  @hostgroups = Hostgroup.all.map { |elem| { elem.id => elem.name } }.reduce({}) { |h, v| h.merge v }
17
25
  end
18
26
 
19
27
  def new
20
- read_hostgroups
21
28
  @app_definition = AppDefinition.new
22
29
  end
23
30
 
@@ -31,11 +38,10 @@ module ForemanAcd
31
38
  end
32
39
 
33
40
  def edit
34
- read_hostgroups
35
41
  end
36
42
 
37
43
  def update
38
- if @app_definition.update(app_definition_params)
44
+ if @app_definition.update_attributes(app_definition_params)
39
45
  process_success
40
46
  else
41
47
  process_error
@@ -49,5 +55,31 @@ module ForemanAcd
49
55
  process_error
50
56
  end
51
57
  end
58
+
59
+ def action_permission
60
+ case params[:action]
61
+ when 'export'
62
+ :export
63
+ else
64
+ super
65
+ end
66
+ end
67
+
68
+ def import
69
+ @app_definition = AppDefinition.new
70
+ end
71
+
72
+ def export
73
+ filename = "#{@app_definition.name}.yaml"
74
+ data = JSON.parse(@app_definition.services).to_yaml
75
+ send_data data, :type => 'text/yaml', :disposition => 'attachment', :filename => filename
76
+ end
77
+
78
+ private
79
+
80
+ def handle_file_upload
81
+ return unless params[:foreman_acd_app_definition] && raw_file = params[:foreman_acd_app_definition][:app_definition_file]
82
+ params[:foreman_acd_app_definition][:services] = YAML.load_file(raw_file.tempfile).to_json
83
+ end
52
84
  end
53
85
  end