foreman_acd 0.4.0 → 0.9.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 (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