foreman_acd 0.4.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (237) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +84 -84
  3. data/app/controllers/foreman_acd/ansible_playbooks_controller.rb +103 -11
  4. data/app/controllers/foreman_acd/api/v2/ansible_playbooks_controller.rb +21 -3
  5. data/app/controllers/foreman_acd/api/v2/app_definitions_controller.rb +1 -0
  6. data/app/controllers/foreman_acd/api/v2/app_instances_controller.rb +9 -1
  7. data/app/controllers/foreman_acd/app_definitions_controller.rb +117 -15
  8. data/app/controllers/foreman_acd/app_instances_controller.rb +104 -30
  9. data/app/controllers/foreman_acd/concerns/ansible_playbook_parameters.rb +1 -1
  10. data/app/controllers/foreman_acd/concerns/app_definition_parameters.rb +1 -1
  11. data/app/controllers/foreman_acd/concerns/app_instance_mixins.rb +36 -0
  12. data/app/controllers/foreman_acd/concerns/app_instance_parameters.rb +1 -1
  13. data/app/controllers/foreman_acd/remote_execution_controller.rb +36 -23
  14. data/app/controllers/ui_acd_controller.rb +46 -0
  15. data/app/lib/actions/foreman_acd/deploy_all_hosts.rb +47 -0
  16. data/app/lib/actions/foreman_acd/run_configurator.rb +45 -0
  17. data/app/models/concerns/foreman_acd/host_managed_extensions.rb +39 -0
  18. data/app/models/foreman_acd/acd_provider.rb +36 -0
  19. data/app/models/foreman_acd/ansible_playbook.rb +32 -14
  20. data/app/models/foreman_acd/app_definition.rb +24 -1
  21. data/app/models/foreman_acd/app_instance.rb +85 -5
  22. data/app/models/foreman_acd/foreman_host.rb +31 -0
  23. data/app/models/foreman_acd/taxonomy_extensions.rb +17 -0
  24. data/app/services/foreman_acd/acd_proxy_proxy_selector.rb +17 -0
  25. data/app/services/foreman_acd/app_configurator.rb +64 -36
  26. data/app/services/foreman_acd/app_deployer.rb +83 -48
  27. data/app/services/foreman_acd/inventory_creator.rb +36 -25
  28. data/app/views/foreman_acd/ansible_playbooks/_form.html.erb +50 -7
  29. data/app/views/foreman_acd/ansible_playbooks/edit.html.erb +9 -1
  30. data/app/views/foreman_acd/ansible_playbooks/index.html.erb +3 -3
  31. data/app/views/foreman_acd/api/v2/ansible_playbooks/base.json.rabl +2 -0
  32. data/app/views/foreman_acd/api/v2/ansible_playbooks/index.json.rabl +2 -0
  33. data/app/views/foreman_acd/api/v2/ansible_playbooks/show.json.rabl +6 -0
  34. data/app/views/foreman_acd/api/v2/app_definitions/base.json.rabl +2 -0
  35. data/app/views/foreman_acd/api/v2/app_definitions/index.json.rabl +2 -0
  36. data/app/views/foreman_acd/api/v2/app_definitions/show.json.rabl +6 -0
  37. data/app/views/foreman_acd/api/v2/app_instances/base.json.rabl +3 -1
  38. data/app/views/foreman_acd/api/v2/app_instances/index.json.rabl +2 -0
  39. data/app/views/foreman_acd/api/v2/app_instances/show.json.rabl +2 -0
  40. data/app/views/foreman_acd/app_definitions/_form.html.erb +9 -1
  41. data/app/views/foreman_acd/app_definitions/edit.html.erb +10 -5
  42. data/app/views/foreman_acd/app_definitions/import.html.erb +20 -1
  43. data/app/views/foreman_acd/app_definitions/index.html.erb +5 -8
  44. data/app/views/foreman_acd/app_instances/_form.html.erb +4 -4
  45. data/app/views/foreman_acd/app_instances/edit.html.erb +10 -0
  46. data/app/views/foreman_acd/app_instances/index.html.erb +93 -14
  47. data/app/views/foreman_acd/app_instances/report.html.erb +12 -4
  48. data/app/views/templates/job/run_acd_ansible_playbook.erb +28 -15
  49. data/app/views/ui_acd/app_definition.json.rabl +1 -1
  50. data/app/views/ui_acd/host_report.json.rabl +4 -0
  51. data/app/views/ui_acd/report_data.json.rabl +10 -0
  52. data/app/views/ui_acd/validate_hostname.json.rabl +6 -0
  53. data/config/routes.rb +12 -3
  54. data/db/migrate/20200917120220_add_ansible_playbook_id.rb +1 -1
  55. data/db/migrate/20201016002819_add_ansible_vars_all_to_app_definitions.rb +3 -0
  56. data/db/migrate/20201016104338_add_ansible_vars_all_to_app_instances.rb +3 -0
  57. data/db/migrate/20210112111548_add_organization_to_app_instance.rb +22 -0
  58. data/db/migrate/20210112113853_add_location_to_app_instance.rb +8 -0
  59. data/db/migrate/20210202141658_create_foreman_hosts.rb +24 -0
  60. data/db/migrate/20210204111306_remove_hosts_from_app_instances.rb +8 -0
  61. data/db/migrate/20210209091014_rename_acd_tables.rb +16 -0
  62. data/db/migrate/20210216083522_add_last_progress_report.rb +8 -0
  63. data/db/migrate/20210216091529_add_last_deploy_task.rb +8 -0
  64. data/db/migrate/20210316151145_add_git_commit_to_ansible_playbooks.rb +8 -0
  65. data/db/migrate/20210503122809_add_git_url_to_ansible_playbooks.rb +8 -0
  66. data/db/migrate/20210818125913_add_is_existing_host_to_foreman_host.rb +8 -0
  67. data/db/migrate/20210902110645_add_initial_configure_task.rb +8 -0
  68. data/db/seeds.d/62_acd_proxy_feature.rb +4 -0
  69. data/db/seeds.d/75-job_templates.rb +6 -1
  70. data/lib/foreman_acd/engine.rb +40 -3
  71. data/lib/foreman_acd/plugin.rb +60 -45
  72. data/lib/foreman_acd/version.rb +1 -1
  73. data/lib/foreman_acd.rb +30 -0
  74. data/lib/tasks/foreman_acd_tasks.rake +0 -12
  75. data/locale/en/foreman_acd.edit.po +326 -0
  76. data/locale/en/foreman_acd.po +232 -2
  77. data/{app/controllers/foreman_acd/api/v2/app_playbooks_controller.rb → locale/en/foreman_acd.po.time_stamp} +0 -0
  78. data/locale/foreman_acd.pot +343 -8
  79. data/package.json +8 -8
  80. data/test/controllers/ansible_playbooks_controller_test.rb +27 -0
  81. data/test/controllers/app_instances_controller_test.rb +8 -3
  82. data/test/controllers/ui_acd_controller_test.rb +22 -6
  83. data/test/factories/foreman_acd_factories.rb +18 -4
  84. data/test/models/acd_provider_test.rb +37 -0
  85. data/test/models/ansible_playbook_test.rb +11 -0
  86. data/test/models/app_definition_test.rb +1 -1
  87. data/test/models/app_instance_test.rb +2 -0
  88. data/test/models/concerns/host_extensions_test.rb +26 -0
  89. data/test/models/foreman_host_test.rb +12 -0
  90. data/webpack/__mocks__/foremanReact/API.js +2 -0
  91. data/webpack/__mocks__/foremanReact/common/I18n.js +3 -0
  92. data/webpack/__mocks__/foremanReact/common/helpers.js +2 -0
  93. data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalActions.js +2 -0
  94. data/webpack/__mocks__/foremanReact/components/ForemanModal.js +7 -0
  95. data/webpack/__mocks__/foremanReact/components/common/forms/CommonForm.js +2 -0
  96. data/webpack/__mocks__/foremanReact/components/common/forms/TextInput.js +2 -0
  97. data/webpack/__mocks__/foremanReact/components/hosts/powerStatus.js +1 -0
  98. data/webpack/__snapshots__/helper.test.js.snap +14 -0
  99. data/webpack/components/ApplicationDefinition/ApplicationDefinition.js +55 -21
  100. data/webpack/components/ApplicationDefinition/ApplicationDefinitionActions.js +14 -0
  101. data/webpack/components/ApplicationDefinition/ApplicationDefinitionConstants.js +2 -0
  102. data/webpack/components/ApplicationDefinition/ApplicationDefinitionReducer.js +48 -1
  103. data/webpack/components/ApplicationDefinition/ApplicationDefinitionSelectors.js +4 -0
  104. data/webpack/components/ApplicationDefinition/__fixtures__/applicationDefinitionConfData_1.fixtures.js +288 -0
  105. data/webpack/components/ApplicationDefinition/__fixtures__/applicationDefinitionReducer.fixtures.js +79 -0
  106. data/webpack/components/ApplicationDefinition/__tests__/ApplicationDefinition.test.js +26 -0
  107. data/webpack/components/ApplicationDefinition/__tests__/ApplicationDefinitionReducer.test.js +119 -0
  108. data/webpack/components/ApplicationDefinition/__tests__/ApplicationDefinitionSelectors.test.js +41 -0
  109. data/webpack/components/ApplicationDefinition/__tests__/__snapshots__/ApplicationDefinition.test.js.snap +225 -0
  110. data/webpack/components/ApplicationDefinition/__tests__/__snapshots__/ApplicationDefinitionReducer.test.js.snap +3033 -0
  111. data/webpack/components/ApplicationDefinition/__tests__/__snapshots__/ApplicationDefinitionSelectors.test.js.snap +299 -0
  112. data/webpack/components/ApplicationDefinition/components/AnsiblePlaybookSelector.js +2 -1
  113. data/webpack/components/ApplicationDefinition/components/__tests__/AnsiblePlaybookSelector.test.js +41 -0
  114. data/webpack/components/ApplicationDefinition/components/__tests__/__snapshots__/AnsiblePlaybookSelector.test.js.snap +121 -0
  115. data/webpack/components/ApplicationDefinition/index.js +8 -0
  116. data/webpack/components/ApplicationDefinitionImport/ApplicationDefinitionImport.js +214 -0
  117. data/webpack/components/ApplicationDefinitionImport/ApplicationDefinitionImport.scss +1 -0
  118. data/webpack/components/ApplicationDefinitionImport/ApplicationDefinitionImportActions.js +161 -0
  119. data/webpack/components/ApplicationDefinitionImport/ApplicationDefinitionImportConstants.js +6 -0
  120. data/webpack/components/ApplicationDefinitionImport/ApplicationDefinitionImportReducer.js +79 -0
  121. data/webpack/components/ApplicationDefinitionImport/ApplicationDefinitionImportSelectors.js +8 -0
  122. data/webpack/components/ApplicationDefinitionImport/__fixtures__/applicationDefinitionImportConfData_1.fixtures.js +129 -0
  123. data/webpack/components/ApplicationDefinitionImport/__fixtures__/applicationDefinitionImportReducer.fixtures.js +29 -0
  124. data/webpack/components/ApplicationDefinitionImport/__tests__/ApplicationDefinitionImport.test.js +20 -0
  125. data/webpack/components/ApplicationDefinitionImport/__tests__/ApplicationDefinitionImportReducer.test.js +43 -0
  126. data/webpack/components/ApplicationDefinitionImport/__tests__/ApplicationDefinitionImportSelectors.test.js +29 -0
  127. data/webpack/components/ApplicationDefinitionImport/__tests__/__snapshots__/ApplicationDefinitionImport.test.js.snap +62 -0
  128. data/webpack/components/ApplicationDefinitionImport/__tests__/__snapshots__/ApplicationDefinitionImportReducer.test.js.snap +362 -0
  129. data/webpack/components/ApplicationDefinitionImport/__tests__/__snapshots__/ApplicationDefinitionImportSelectors.test.js.snap +130 -0
  130. data/webpack/components/ApplicationDefinitionImport/index.js +32 -0
  131. data/webpack/components/ApplicationInstance/ApplicationInstance.js +153 -45
  132. data/webpack/components/ApplicationInstance/ApplicationInstanceActions.js +120 -6
  133. data/webpack/components/ApplicationInstance/ApplicationInstanceConstants.js +5 -0
  134. data/webpack/components/ApplicationInstance/ApplicationInstanceHelper.js +15 -0
  135. data/webpack/components/ApplicationInstance/ApplicationInstanceReducer.js +77 -22
  136. data/webpack/components/ApplicationInstance/ApplicationInstanceSelectors.js +4 -0
  137. data/webpack/components/ApplicationInstance/__fixtures__/applicationInstanceConfData_1.fixtures.js +263 -0
  138. data/webpack/components/ApplicationInstance/__fixtures__/applicationInstanceReducer.fixtures.js +80 -0
  139. data/webpack/components/ApplicationInstance/__tests__/ApplicationInstance.test.js +24 -0
  140. data/webpack/components/ApplicationInstance/__tests__/ApplicationInstanceReducer.test.js +131 -0
  141. data/webpack/components/ApplicationInstance/__tests__/ApplicationInstanceSelectors.test.js +44 -0
  142. data/webpack/components/ApplicationInstance/__tests__/__snapshots__/ApplicationInstance.test.js.snap +299 -0
  143. data/webpack/components/ApplicationInstance/__tests__/__snapshots__/ApplicationInstanceReducer.test.js.snap +2990 -0
  144. data/webpack/components/ApplicationInstance/__tests__/__snapshots__/ApplicationInstanceSelectors.test.js.snap +276 -0
  145. data/webpack/components/ApplicationInstance/components/AppDefinitionSelector.js +1 -0
  146. data/webpack/components/ApplicationInstance/components/Service.js +1 -1
  147. data/webpack/components/ApplicationInstance/components/ServiceCounter.js +1 -1
  148. data/webpack/components/ApplicationInstance/helper.js +0 -0
  149. data/webpack/components/ApplicationInstance/index.js +8 -0
  150. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReport.js +128 -60
  151. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReport.scss +17 -0
  152. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportActions.js +40 -50
  153. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportConstants.js +5 -4
  154. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportReducer.js +19 -14
  155. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportSelectors.js +4 -1
  156. data/webpack/components/ApplicationInstanceReport/__fixtures__/applicationInstanceReportData_1.fixtures.js +349 -0
  157. data/webpack/components/ApplicationInstanceReport/__fixtures__/applicationInstanceReportReducer.fixtures.js +20 -0
  158. data/webpack/components/ApplicationInstanceReport/__tests__/ApplicationInstanceReport.test.js +47 -0
  159. data/webpack/components/ApplicationInstanceReport/__tests__/ApplicationInstanceReportReducer.test.js +41 -0
  160. data/webpack/components/ApplicationInstanceReport/__tests__/ApplicationInstanceReportSelectors.test.js +26 -0
  161. data/webpack/components/ApplicationInstanceReport/__tests__/__snapshots__/ApplicationInstanceReport.test.js.snap +7 -0
  162. data/webpack/components/ApplicationInstanceReport/__tests__/__snapshots__/ApplicationInstanceReportReducer.test.js.snap +718 -0
  163. data/webpack/components/ApplicationInstanceReport/__tests__/__snapshots__/ApplicationInstanceReportSelectors.test.js.snap +347 -0
  164. data/webpack/components/ApplicationInstanceReport/components/ReportViewer.js +1 -1
  165. data/webpack/components/ApplicationInstanceReport/components/__tests__/ReportViewer.test.js +24 -0
  166. data/webpack/components/ApplicationInstanceReport/components/__tests__/__snapshots__/ReportViewer.test.js.snap +24 -0
  167. data/webpack/components/ApplicationInstanceReport/index.js +8 -3
  168. data/webpack/components/ExistingHostSelection/ExistingHostSelection.js +104 -0
  169. data/webpack/components/ExistingHostSelection/ExistingHostSelection.scss +15 -0
  170. data/webpack/components/ExistingHostSelection/ExistingHostSelectionActions.js +71 -0
  171. data/webpack/components/ExistingHostSelection/ExistingHostSelectionConstants.js +4 -0
  172. data/webpack/components/ExistingHostSelection/ExistingHostSelectionHelper.js +0 -0
  173. data/webpack/components/ExistingHostSelection/ExistingHostSelectionReducer.js +90 -0
  174. data/webpack/components/ExistingHostSelection/ExistingHostSelectionSelectors.js +8 -0
  175. data/webpack/components/ExistingHostSelection/__fixtures__/existingHostSelectionConfData_1.fixtures.js +191 -0
  176. data/webpack/components/ExistingHostSelection/__fixtures__/existingHostSelectionReducer.fixtures.js +203 -0
  177. data/webpack/components/ExistingHostSelection/__tests__/ExistingHostSelection.test.js +19 -0
  178. data/webpack/components/ExistingHostSelection/__tests__/ExistingHostSelectionReducer.test.js +59 -0
  179. data/webpack/components/ExistingHostSelection/__tests__/ExistingHostSelectionSelectors.test.js +36 -0
  180. data/webpack/components/ExistingHostSelection/__tests__/__snapshots__/ExistingHostSelection.test.js.snap +35 -0
  181. data/webpack/components/ExistingHostSelection/__tests__/__snapshots__/ExistingHostSelectionReducer.test.js.snap +614 -0
  182. data/webpack/components/ExistingHostSelection/__tests__/__snapshots__/ExistingHostSelectionSelectors.test.js.snap +27 -0
  183. data/webpack/components/ExistingHostSelection/components/ServiceSelector.js +48 -0
  184. data/webpack/components/ExistingHostSelection/components/__tests__/ServiceSelector.test.js +35 -0
  185. data/webpack/components/ExistingHostSelection/components/__tests__/__snapshots__/ServiceSelector.test.js.snap +77 -0
  186. data/webpack/components/ExistingHostSelection/index.js +26 -0
  187. data/webpack/components/ParameterSelection/ParameterSelection.js +138 -15
  188. data/webpack/components/ParameterSelection/ParameterSelection.scss +7 -0
  189. data/webpack/components/ParameterSelection/ParameterSelectionActions.js +52 -9
  190. data/webpack/components/ParameterSelection/ParameterSelectionConstants.js +3 -0
  191. data/webpack/components/ParameterSelection/ParameterSelectionReducer.js +62 -25
  192. data/webpack/components/ParameterSelection/ParameterSelectionSelectors.js +1 -0
  193. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionData_1.fixtures.js +116 -84
  194. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionReducer.fixtures.js +10 -4
  195. data/webpack/components/ParameterSelection/__tests__/ParameterSelection.test.js +36 -46
  196. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionReducer.test.js +33 -25
  197. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionSelectors.test.js +6 -6
  198. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelection.test.js.snap +84 -112
  199. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionReducer.test.js.snap +1488 -872
  200. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionSelectors.test.js.snap +117 -79
  201. data/webpack/components/ParameterSelection/index.js +2 -1
  202. data/webpack/components/SyncGitRepo/SyncGitRepo.js +202 -0
  203. data/webpack/components/SyncGitRepo/SyncGitRepo.scss +1 -0
  204. data/webpack/components/SyncGitRepo/SyncGitRepoActions.js +123 -0
  205. data/webpack/components/SyncGitRepo/SyncGitRepoConstants.js +8 -0
  206. data/webpack/components/SyncGitRepo/SyncGitRepoReducer.js +80 -0
  207. data/webpack/components/SyncGitRepo/SyncGitRepoSelectors.js +6 -0
  208. data/webpack/components/SyncGitRepo/__fixtures__/syncGitRepoConfData_1.fixtures.js +7 -0
  209. data/webpack/components/SyncGitRepo/__fixtures__/syncGitRepoReducer.fixtures.js +44 -0
  210. data/webpack/components/SyncGitRepo/__tests__/SyncGitRepo.test.js +27 -0
  211. data/webpack/components/SyncGitRepo/__tests__/SyncGitRepoReducer.test.js +95 -0
  212. data/webpack/components/SyncGitRepo/__tests__/SyncGitRepoSelectors.test.js +32 -0
  213. data/webpack/components/SyncGitRepo/__tests__/__snapshots__/SyncGitRepo.test.js.snap +31 -0
  214. data/webpack/components/SyncGitRepo/__tests__/__snapshots__/SyncGitRepoReducer.test.js.snap +137 -0
  215. data/webpack/components/SyncGitRepo/__tests__/__snapshots__/SyncGitRepoSelectors.test.js.snap +13 -0
  216. data/webpack/components/SyncGitRepo/components/FormTextInput.js +42 -0
  217. data/webpack/components/SyncGitRepo/components/ScmTypeSelector.js +47 -0
  218. data/webpack/components/SyncGitRepo/index.js +28 -0
  219. data/webpack/components/common/DeleteTableEntry.js +18 -4
  220. data/webpack/components/common/EditTableEntry.js +50 -0
  221. data/webpack/components/common/ExtTextInput.js +43 -0
  222. data/webpack/components/common/LockTableEntry.js +60 -0
  223. data/webpack/components/common/__tests__/EditTableEntry.test.js +53 -0
  224. data/webpack/components/common/__tests__/LockTableEntry.test.js +35 -0
  225. data/webpack/components/common/__tests__/__snapshots__/DeleteTableEntry.test.js.snap +40 -2
  226. data/webpack/components/common/__tests__/__snapshots__/EditTableEntry.test.js.snap +81 -0
  227. data/webpack/components/common/__tests__/__snapshots__/LockTableEntry.test.js.snap +60 -0
  228. data/webpack/helper.js +20 -1
  229. data/webpack/helper.test.js +37 -0
  230. data/webpack/index.js +7 -0
  231. data/webpack/js-yaml.js +3874 -0
  232. data/webpack/reducer.js +16 -1
  233. metadata +182 -11
  234. data/app/views/foreman_acd/app_instances/deploy.html.erb +0 -19
  235. data/webpack/components/common/EasyHeaderFormatter.js +0 -18
  236. data/webpack/components/common/__tests__/__snapshots__/AddParameter.test.js.snap +0 -35
  237. data/webpack/components/common/__tests__/__snapshots__/DeleteParameter.test.js.snap +0 -41
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 433f2c68da81192db3c98fc013ed2149490f2471e84d372db8241522a33b6630
4
- data.tar.gz: aa46c833de3feb1cce0802de82dec78f1610331984e6df8df649fdadfffa2b2a
3
+ metadata.gz: ca6ffd04ba17f399f8ecbf17615fde7ba6391cf389e16d83e427adb2c15cff9f
4
+ data.tar.gz: 9de27331a51e5bb6887250b01e40d6557fb9e5f66f96005f16e8d5fb2e6999f8
5
5
  SHA512:
6
- metadata.gz: 0accbf314dd5776a5b012507d97619be98beff2c11e523da4d27f69e9fdb1bf1d284c134dba6549719312a66ede8cb80c8a06e3851f01a14951b1752ef2e29e8
7
- data.tar.gz: d003bc7a5de1c180b2e33ade4e85b2912776db564d59ff9d8eca4f9ccc00c38591fd061649df07bb89e76ad0b0ac5efe1c64dd506132148aaf087b758a18c078
6
+ metadata.gz: ee8e1c5f4b7d842ce1f153c282b74a07a83edd6405e0b0ba7476602bd0c225bf8fefdb7e19aacfd2d79033f0c5429bc675e9c0dd1d794b2f1cfbe9d91764e9ed
7
+ data.tar.gz: 1d74484d949e080478432b0d76cba89b87fde3eda56a1d6cf7c69dc2207cdca2308a73b9f11de6a25d5713b2de12a546423b3d251d793925f55c33440cad108c
data/README.md CHANGED
@@ -1,142 +1,142 @@
1
- [![Build Status master](https://travis-ci.org/ATIX-AG/foreman_acd.svg?branch=master)](https://travis-ci.org/ATIX-AG/foreman_acd)
2
-
3
1
  # Foreman Application Centric Deployment
4
2
 
5
- A plugin to bring an user self service portal and application centric deployment to Foreman.
6
-
3
+ A Foreman plugin providing application centric deployment and a self-service portal.
7
4
 
8
- # Description
5
+ # Introduction
9
6
 
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.
7
+ The target of this plugin is to deploy whole applications which include multiple hosts and configure them using an Ansible playbook.
12
8
 
13
9
  This plugin follows the idea of different user types working together.
14
- The administrative user creates Application Definition including multiple servers and
15
- configuration management items (Ansible Playbook, saltstack state).
16
- The user can create and deploy new Application Instaces with an easy to use self service portal.
10
+ The _administrative user_ creates Application Definitions including multiple servers and configuration management items (Ansible Playbooks).
11
+ The _user_ can create and deploy new Application Instances with an easy to use self-service portal.
12
+
13
+ *Example Application Definition*
14
+ To run a complex web application, a load balancer is required.
15
+ The load balancer routes the requests to three different web servers.
16
+ The web servers are using a database which runs in high availability mode on two hosts.
17
+ Therefore, six hosts in total are required.
18
+
19
+ This plugin aims to setup all six hosts and to deploy the application.
17
20
 
18
- *Example Application Definition:* To run a complex web application, a loadbalancer is required.
19
- The loadbalancer routes the requests to 3 different web servers.
20
- The web servers are using a database which is in high availability mode on 2 hosts.
21
- => 6 hosts are required.
21
+ # Architecture
22
22
 
23
- This plugin aims to setup all 6 hosts and to deploy the application.
23
+ ## Ansible Playbooks
24
24
 
25
+ * Specify the path on your Foreman server to the Ansible playbook and playfile
26
+ * Read groups configured in the Ansible playbook
25
27
 
26
- # Current State
28
+ ## Application Definitions
27
29
 
28
- ## Application Definition
30
+ * Use the configured Ansible playbook in an Application Definition
31
+ * Overwrite group variables of the Ansible playbook for the Application Definition
32
+ * Set Foreman parameters in the Application Definition
33
+ * Setup various services like web servers, database servers, etc.
29
34
 
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
+ ## Application Instances
35
36
 
36
- ## Application Instance
37
+ * Use an Application Definition for your Application Instance
38
+ * Configure specific hosts which use the Application Definition's services
39
+ * Deploy these hosts
40
+ * Configure the hosts using the configured Ansible playbook
37
41
 
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
+ # How It Works
42
43
 
44
+ * Configure an Ansible playbook, an Application Definition, and create an Application Instance.
45
+ * All hosts are created when deploying the Application Instance.
46
+ * After provisioning, the hosts are configured with the linked Ansible playbook.
47
+ * This uses the [Smart Proxy ACD](https://github.com/ATIX-AG/smart_proxy_acd) component.
48
+ * The job to configure the hosts will be send to the Smart Proxy ACD component which will
49
+ * download the Ansible playbook from your Foreman server (provided by an foreman_acd API);
50
+ * extract the Ansible playbook on the Smart Proxy;
51
+ * and run the Ansible playbook on the Smart Proxy.
52
+ * You can see the output of the Ansible playbook run on the *Monitor > Job* page.
43
53
 
44
- # Road Map
45
- -
46
- - Add Application deployment with single host requirements
47
- - Add Application deployment with multi host requirements
54
+ :warning: This plugin is still in development.
48
55
 
49
- ## WARNING
56
+ ## Documentation
50
57
 
51
- This plugin is in development.
58
+ See [Application Centric Deployment Guide](https://docs.theforeman.org/nightly/Application_Centric_Deployment/index-foreman-el.html)
52
59
 
53
60
  ## Installation
54
61
 
55
- See [How_to_Install_a_Plugin](https://theforeman.org/plugins/#2.Installation)
56
- for how to install Foreman plugins.
62
+ See the [installation](https://theforeman.org/plugins/#2.Installation) chapter of the Foreman plugins documentation on how to install Foreman plugins.
57
63
 
58
64
  ### TL;DR:
59
65
 
60
66
  yum install tfm-rubygem-foreman_acd
61
- foreman-maintain service restart --only foreman
67
+ foreman-maintain service restart
62
68
 
63
- In some cases you need to do manally
69
+ In some cases, you need to manually run
64
70
 
65
71
  foreman-rake db:migrate
66
72
  foreman-rake db:seed
67
73
 
68
- ### Hints
74
+ ### Smart Proxy Installation
69
75
 
70
- Katello plugin need to exist, too.
76
+ You will need to install [Smart Proxy ACD](https://github.com/ATIX-AG/smart_proxy_acd), too.
71
77
 
72
- ### Configuration
78
+ yum install tfm-rubygem-smart_proxy_acd tfm-rubygem-smart_proxy_acd_core
79
+ foreman-maintain service restart
73
80
 
74
- To get ansible playbooks running, you need to:
81
+ You need to refresh the smart proxy features in *Infrastructure > Smart Proxies > Your Smart-Proxy > Actions > Refresh* after the installation of the Smart Proxy ACD components.
75
82
 
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.
83
+ ### Tips
84
+
85
+ * Make sure you have the [Katello](https://theforeman.org/plugins/katello/) plugin installed.
86
+ * Make sure the Job Template `Run ACD Ansible Playbook - ACD Default` is part of your organization/location context.
79
87
 
80
88
  ## Usage
81
89
 
82
90
  ### Ansible Playbook
83
91
 
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.
92
+ * Copy (or checkout a git repository) an Ansible playbook.
93
+ Store it in `/var/lib/foreman/foreman_acd/ansible-playbooks/` so that SELinux is able to read it.
94
+ * Add a new Ansible Playbook via *Applications > Ansible Playbooks*.
95
+ * Specify the path to the Ansible playbook and name of the playbook file. (e.g. `site.yml`).
96
+ * Save it and press *Import group variables* for this newly created Ansible playbook.
88
97
 
89
- ### Application Definition (Admin)
98
+ ### Application Definition (for Admins)
90
99
 
91
- * Create an Application Definition (Configure -> Application Definition) first
100
+ * Create an Application Definition via *Applications > Application Definitions*.
92
101
  * Select the Ansible Playbook you want to use.
93
- * Add new services and specifiy the host group you want to use.
94
- * Specifiy the values, a user could overwrite.
95
- (you can set a default value, if you want)
96
-
97
- ### Application Instance (User)
102
+ * Add new services and specify the host group you want to use.
103
+ * Specify any values a user will be allowed to overwrite.
104
+ You may also set a default value.
98
105
 
99
- * Create an Application Instance (Configure -> Application Instance)
100
- * Select the Application Definition which should be used
101
- * Set the values.
102
- Remember, all parameters need to have a value.
103
- * Save the Application Instance
106
+ ### Application Instance (for Users)
104
107
 
105
- ### Deploy & Configure the Application Instance (User)
108
+ * Create an Application Instance via *Applications > Application Instances*.
109
+ * Select the Application Definition you want to use.
110
+ * Overwrite desired values.
111
+ All Foreman parameters require a value.
112
+ * Save the Application Instance.
106
113
 
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
114
+ ### Deploy and Configure the Application Instance (for Users)
112
115
 
116
+ * Select *Deploy* in the action drop down menu via *Applications > Application Instance* to deploy a host.
117
+ * Verify if the hosts are deployed via the *Report* button from the action drop down menu.
118
+ * Run the Ansible playbook via *Run Ansible playbook* from the action drop down menu after all hosts are deployed.
113
119
 
114
120
  ## TODO
115
121
 
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
-
122
+ * Add `git` support for the Ansible playbooks.
123
+ * Provide application templates which contains application definition and the required Ansible-playbook.
124
+ * Add Saltstack support to configure the application.
125
+ * Extend the Foreman parameter and value validation.
122
126
 
123
127
  ## Contributing
124
128
 
125
- Fork and send a Pull Request. Thanks!
129
+ Fork and send a Pull Request.
130
+ Thanks!
126
131
 
127
132
  ## Copyright
128
133
 
129
- Copyright (c) 2020 ATIX AG
134
+ Copyright (c) 2021 ATIX AG
130
135
 
131
- This program is free software: you can redistribute it and/or modify
132
- it under the terms of the GNU General Public License as published by
133
- the Free Software Foundation, either version 3 of the License, or
134
- (at your option) any later version.
136
+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
135
137
 
136
- This program is distributed in the hope that it will be useful,
137
- but WITHOUT ANY WARRANTY; without even the implied warranty of
138
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
139
- GNU General Public License for more details.
138
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
139
+ See the GNU General Public License for more details.
140
140
 
141
- You should have received a copy of the GNU General Public License
142
- along with this program. If not, see <http://www.gnu.org/licenses/>.
141
+ You should have received a copy of the GNU General Public License along with this program.
142
+ If not, see <http://www.gnu.org/licenses/>.
@@ -7,6 +7,7 @@ module ForemanAcd
7
7
  include ::ForemanAcd::Concerns::AnsiblePlaybookParameters
8
8
 
9
9
  before_action :find_resource, :only => [:edit, :update, :destroy, :import_vars]
10
+ after_action :delete_synced_repo, :only => [:new, :edit, :create, :update, :destroy, :index]
10
11
 
11
12
  def index
12
13
  @ansible_playbooks = resource_base.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
@@ -18,17 +19,36 @@ module ForemanAcd
18
19
 
19
20
  def create
20
21
  @ansible_playbook = AnsiblePlaybook.new(ansible_playbook_params)
22
+ if session[:git_path]
23
+ @ansible_playbook.update(:path => ansible_playbook_full_path(ansible_playbook_rename(@ansible_playbook[:name])))
24
+ FileUtils.mv(session[:git_path], @ansible_playbook[:path])
25
+ session[:git_path] = nil
26
+ end
21
27
  if @ansible_playbook.save
22
- process_success
28
+ process_success :success_msg => _("Successfully created %s. You need to press the \"Import groups\" button
29
+ before this ansible playbook can be used in App Definitions!") % @ansible_playbook
23
30
  else
24
31
  process_error
25
32
  end
26
33
  end
27
34
 
28
- def edit
29
- end
35
+ def edit; end
30
36
 
31
37
  def update
38
+ # Move synced repo to new path if ansible_playbook name is changed
39
+ if !session[:git_path].nil? && ansible_playbook_params[:name] != @ansible_playbook[:name]
40
+ FileUtils.mv(@ansible_playbook[:path], ansible_playbook_full_path(ansible_playbook_rename(ansible_playbook_params[:name])))
41
+ @ansible_playbook.update(:path => ansible_playbook_full_path(ansible_playbook_rename(ansible_playbook_params[:name])))
42
+ session[:git_path] = nil
43
+
44
+ # Remove old version and copy new version of synced repository
45
+ elsif !session[:git_path].nil? && ansible_playbook_params[:name] == @ansible_playbook.name
46
+ remove_ansible_dir(@ansible_playbook[:path]) if @ansible_playbook.path
47
+ @ansible_playbook.update(:path => ansible_playbook_full_path(ansible_playbook_rename(@ansible_playbook[:name])))
48
+ FileUtils.mv(session[:git_path], @ansible_playbook[:path])
49
+ session[:git_path] = nil
50
+ end
51
+
32
52
  if @ansible_playbook.update(ansible_playbook_params)
33
53
  process_success
34
54
  else
@@ -44,10 +64,64 @@ module ForemanAcd
44
64
  end
45
65
  end
46
66
 
67
+ def sync_git_repo
68
+ @ansible_playbook = AnsiblePlaybook.new
69
+ sync_params = params[:ansible_playbook]
70
+ dir = Dir.mktmpdir
71
+
72
+ begin
73
+ git = Git.init(dir)
74
+
75
+ if ForemanAcd.proxy_setting.present?
76
+ git.config('http.proxy', ForemanAcd.proxy_setting)
77
+ logger.info("HTTP Proxy used: #{git.config['http.proxy']}")
78
+ end
79
+
80
+ if sync_params[:git_commit].empty?
81
+ if ForemanAcd.proxy_setting.present?
82
+ err_msg = _('Please set the Git Branch/Tag/Commit. This setting is necessary if a HTTP proxy is used!')
83
+ raise StandardError.new err_msg
84
+ else
85
+ commit = Git.ls_remote(sync_params[:git_url])['head'][:sha]
86
+ end
87
+ else
88
+ commit = sync_params[:git_commit]
89
+ end
90
+
91
+ git.add_remote('origin', sync_params[:git_url])
92
+ git.fetch
93
+ git.checkout(commit)
94
+
95
+ session[:git_path] = git.dir.path
96
+ rescue StandardError => e
97
+ logger.error("Failed to sync git repository: #{e}")
98
+ render :json => { :status => 'error', :message => e }, :status => :internal_server_error
99
+ end
100
+ end
101
+
102
+ # Remove abandoned synced git repositories
103
+ def delete_synced_repo
104
+ names = []
105
+ AnsiblePlaybook.all.each do |ansible_playbook|
106
+ names.push(ansible_playbook_rename(ansible_playbook.name))
107
+ end
108
+ names.push('.', '..')
109
+ return unless Dir.exist?(ForemanAcd.ansible_playbook_path)
110
+ Dir.foreach(ForemanAcd.ansible_playbook_path) do |dirname|
111
+ next if names.include? dirname
112
+ remove_ansible_dir(ansible_playbook_full_path(dirname))
113
+ logger.info("Successfully removed #{dirname}")
114
+ end
115
+ end
116
+
47
117
  def action_permission
48
118
  case params[:action]
49
119
  when 'import_vars'
50
120
  :import_vars
121
+ when 'sync_git_repo'
122
+ :sync_git_repo
123
+ when 'grab'
124
+ :grab
51
125
  else
52
126
  super
53
127
  end
@@ -87,15 +161,15 @@ module ForemanAcd
87
161
  # We need to support: group_vars/group_file and group_vars/group_dir/yaml_files
88
162
  dir_and_file = File.split(vars_file)
89
163
 
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
164
+ group_name = if File.basename(dir_and_file[0]) == 'group_vars' # in case of group_vars/group_file
165
+ File.basename(dir_and_file[1], '.*')
166
+ else # in case of group_vars/group_dir/yaml_files
167
+ File.basename(dir_and_file[0])
168
+ end
95
169
 
96
170
  logger.debug("Add ansible vars from file #{vars_file} to group #{group_name}")
97
171
 
98
- if vars.has_key?(group_name)
172
+ if vars.key?(group_name)
99
173
  vars[group_name].merge!(loaded_yaml)
100
174
  else
101
175
  vars[group_name] = loaded_yaml
@@ -104,7 +178,7 @@ module ForemanAcd
104
178
 
105
179
  errors << "No ansible group variable in #{playbook_path} defined." if everything_empty
106
180
 
107
- return vars, errors
181
+ [vars, errors]
108
182
  end
109
183
 
110
184
  def import_vars
@@ -113,10 +187,28 @@ module ForemanAcd
113
187
  @ansible_playbook.vars = vars.to_json
114
188
  @ansible_playbook.save
115
189
  if errors.empty?
116
- process_success :success_msg => _("Successfully loaded ansible group variables from %s") % @ansible_playbook.name, :redirect => ansible_playbooks_path
190
+ process_success :success_msg => _('Successfully loaded ansible group variables from %s') % @ansible_playbook.name, :redirect => ansible_playbooks_path
117
191
  else
118
192
  process_error :error_msg => _(errors.join(' ')), :redirect => ansible_playbooks_path
119
193
  end
120
194
  end
195
+
196
+ private
197
+
198
+ def ansible_playbook_rename(name)
199
+ name.split(/\W+/).join('_')
200
+ end
201
+
202
+ def remove_ansible_dir(dirpath)
203
+ unless dirpath.start_with? ForemanAcd.ansible_playbook_path
204
+ logger.error("Sorry, the directory #{dirpath} is not within #{ForemanAcd.ansible_playbook_path} and will therefore not be cleaned up!")
205
+ return false
206
+ end
207
+ FileUtils.rm_rf(dirpath) if Dir.exist?(dirpath)
208
+ end
209
+
210
+ def ansible_playbook_full_path(dirname)
211
+ File.join(ForemanAcd.ansible_playbook_path, dirname)
212
+ end
121
213
  end
122
214
  end
@@ -5,9 +5,12 @@ module ForemanAcd
5
5
  module V2
6
6
  # API controller for Ansible Playbooks
7
7
  class AnsiblePlaybooksController < ::ForemanAcd::Api::V2::BaseController
8
+ include ::Foreman::Controller::SmartProxyAuth
8
9
  include ::ForemanAcd::Concerns::AnsiblePlaybookParameters
9
10
 
10
- before_action :find_resource, :except => [:index, :create]
11
+ before_action :find_resource, :except => [:index, :create, :grab]
12
+
13
+ add_smart_proxy_filters :grab, :features => 'ACD'
11
14
 
12
15
  api :GET, '/ansible_playbooks/:id', N_('Show ansible playbook')
13
16
  param :id, :identifier, :required => true
@@ -23,6 +26,7 @@ module ForemanAcd
23
26
  def_param_group :ansible_playbook do
24
27
  param :ansible_playbook, Hash, :required => true, :action_aware => true do
25
28
  param :name, String, :required => true
29
+ param_group :taxonomies, ::Api::V2::BaseController
26
30
  param :description, String, :required => true
27
31
  param :services, String, :required => true
28
32
  end
@@ -41,8 +45,22 @@ module ForemanAcd
41
45
  process_response @ansible_playbook.destroy
42
46
  end
43
47
 
44
- def controller_permission
45
- 'ansible_playbooks'
48
+ api :GET, '/ansible_playbooks/:id/grab', N_('Grab ansible playbook')
49
+ param :id, :identifier, :required => true
50
+ def grab
51
+ ap = resource_class.find(params['id'])
52
+ command = "tar cz -C #{ap.path} --exclude \".git\" . 2>/dev/null | base64"
53
+ result = `#{command}`
54
+ send_data result, :type => 'text/plain', :disposition => 'inline'
55
+ end
56
+
57
+ def action_permission
58
+ case params[:action]
59
+ when 'grab'
60
+ 'grab'
61
+ else
62
+ super
63
+ end
46
64
  end
47
65
 
48
66
  def resource_class
@@ -23,6 +23,7 @@ module ForemanAcd
23
23
  def_param_group :app_definition do
24
24
  param :app_definition, Hash, :required => true, :action_aware => true do
25
25
  param :name, String, :required => true
26
+ param_group :taxonomies, ::Api::V2::BaseController
26
27
  param :description, String, :required => true
27
28
  param :services, String, :required => true
28
29
  end
@@ -11,18 +11,26 @@ module ForemanAcd
11
11
 
12
12
  api :GET, '/app_instances/:id', N_('Show application instance')
13
13
  param :id, :identifier, :required => true
14
+ param :organization_id, :identifier, :required => true
15
+ param :location_id, :identifier, :required => true
14
16
  def show; end
15
17
 
16
18
  api :GET, '/app_instances', N_('List application instances')
19
+ param :organization_id, :identifier, :required => true
20
+ param :location_id, :identifier, :required => true
17
21
  param_group :search_and_pagination, ::Api::V2::BaseController
18
22
  add_scoped_search_description_for(AppInstance)
19
23
  def index
20
- @app_instances = resource_scope_for_index
24
+ scope = resource_scope_for_index.where(:organization => params[:organization_id]) if params[:organization_id].present?
25
+ scope = scope.where(:location => params[:location_id]) if params[:location_id].present?
26
+ @app_instances = scope
21
27
  end
22
28
 
23
29
  def_param_group :app_instance do
24
30
  param :app_instance, Hash, :required => true, :action_aware => true do
25
31
  param :name, String, :required => true
32
+ param :organization_id, :identifier, :required => true
33
+ param :location_id, :identifier, :required => true
26
34
  param :description, String, :required => true
27
35
  param :services, String, :required => true
28
36
  end