foreman_patch 1.1.1

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 (312) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +38 -0
  4. data/Rakefile +53 -0
  5. data/app/assets/javascript/foreman_patch/plan_edit_windows.js +9 -0
  6. data/app/assets/stylesheets/foreman_patch/cycle_plans.scss +6 -0
  7. data/app/assets/stylesheets/foreman_patch/foreman_patch.css +4 -0
  8. data/app/controllers/concerns/foreman_patch/parameters/ticket_field.rb +26 -0
  9. data/app/controllers/foreman_patch/api/v2/base_controller.rb +12 -0
  10. data/app/controllers/foreman_patch/api/v2/cycles_controller.rb +78 -0
  11. data/app/controllers/foreman_patch/api/v2/groups_controller.rb +70 -0
  12. data/app/controllers/foreman_patch/api/v2/host_groups_controller.rb +13 -0
  13. data/app/controllers/foreman_patch/api/v2/invocations_controller.rb +70 -0
  14. data/app/controllers/foreman_patch/api/v2/plans_controller.rb +79 -0
  15. data/app/controllers/foreman_patch/api/v2/rounds_controller.rb +77 -0
  16. data/app/controllers/foreman_patch/api/v2/window_plans_controller.rb +73 -0
  17. data/app/controllers/foreman_patch/api/v2/windows_controller.rb +85 -0
  18. data/app/controllers/foreman_patch/concerns/api/v2/hosts_controller_extensions.rb +21 -0
  19. data/app/controllers/foreman_patch/concerns/hosts_controller_extensions.rb +61 -0
  20. data/app/controllers/foreman_patch/cycles_controller.rb +34 -0
  21. data/app/controllers/foreman_patch/groups_controller.rb +68 -0
  22. data/app/controllers/foreman_patch/invocations_controller.rb +51 -0
  23. data/app/controllers/foreman_patch/plans_controller.rb +59 -0
  24. data/app/controllers/foreman_patch/rounds_controller.rb +18 -0
  25. data/app/controllers/foreman_patch/ticket_fields_controller.rb +37 -0
  26. data/app/controllers/foreman_patch/window_plans_controller.rb +60 -0
  27. data/app/controllers/foreman_patch/windows_controller.rb +58 -0
  28. data/app/helpers/concerns/foreman_patch/hosts_helper_extensions.rb +13 -0
  29. data/app/helpers/foreman_patch/cycles_helper.rb +19 -0
  30. data/app/helpers/foreman_patch/hosts_helper.rb +52 -0
  31. data/app/helpers/foreman_patch/patching_helper.rb +116 -0
  32. data/app/helpers/foreman_patch/plans_helper.rb +45 -0
  33. data/app/helpers/foreman_patch/ticket_helper.rb +11 -0
  34. data/app/helpers/foreman_patch/window_patching_helper.rb +20 -0
  35. data/app/helpers/foreman_patch/window_plans_helper.rb +13 -0
  36. data/app/helpers/foreman_patch/windows_helper.rb +17 -0
  37. data/app/lib/actions/foreman_patch/cycle/complete.rb +41 -0
  38. data/app/lib/actions/foreman_patch/cycle/create.rb +69 -0
  39. data/app/lib/actions/foreman_patch/cycle/initiate.rb +68 -0
  40. data/app/lib/actions/foreman_patch/cycle/plan.rb +73 -0
  41. data/app/lib/actions/foreman_patch/cycle/prepare_content.rb +123 -0
  42. data/app/lib/actions/foreman_patch/host/reschedule.rb +32 -0
  43. data/app/lib/actions/foreman_patch/invocation/action.rb +135 -0
  44. data/app/lib/actions/foreman_patch/invocation/ensure_services.rb +47 -0
  45. data/app/lib/actions/foreman_patch/invocation/patch.rb +93 -0
  46. data/app/lib/actions/foreman_patch/invocation/reschedule.rb +21 -0
  47. data/app/lib/actions/foreman_patch/invocation/restart.rb +101 -0
  48. data/app/lib/actions/foreman_patch/invocation/update_packages.rb +52 -0
  49. data/app/lib/actions/foreman_patch/invocation/wait_for_host.rb +103 -0
  50. data/app/lib/actions/foreman_patch/round/add_missing_hosts.rb +21 -0
  51. data/app/lib/actions/foreman_patch/round/create.rb +37 -0
  52. data/app/lib/actions/foreman_patch/round/patch.rb +81 -0
  53. data/app/lib/actions/foreman_patch/round/plan.rb +33 -0
  54. data/app/lib/actions/foreman_patch/round/resolve_hosts.rb +45 -0
  55. data/app/lib/actions/foreman_patch/window/create.rb +41 -0
  56. data/app/lib/actions/foreman_patch/window/patch.rb +72 -0
  57. data/app/lib/actions/foreman_patch/window/plan.rb +43 -0
  58. data/app/lib/actions/foreman_patch/window/publish.rb +32 -0
  59. data/app/lib/actions/foreman_patch/window/resolve_hosts.rb +31 -0
  60. data/app/lib/actions/helpers/failure_notification.rb +20 -0
  61. data/app/lib/actions/helpers/with_feature_action.rb +102 -0
  62. data/app/lib/actions/middleware/check_exit_status.rb +31 -0
  63. data/app/mailers/foreman_patch/cycle_mailer.rb +17 -0
  64. data/app/mailers/foreman_patch/group_mailer.rb +41 -0
  65. data/app/mailers/foreman_patch/invocation_mailer.rb +19 -0
  66. data/app/models/foreman_patch/concerns/group_facet_host_extensions.rb +35 -0
  67. data/app/models/foreman_patch/concerns/host_managed_extensions.rb +17 -0
  68. data/app/models/foreman_patch/cycle.rb +49 -0
  69. data/app/models/foreman_patch/group.rb +43 -0
  70. data/app/models/foreman_patch/host/group_facet.rb +13 -0
  71. data/app/models/foreman_patch/invocation.rb +60 -0
  72. data/app/models/foreman_patch/plan.rb +110 -0
  73. data/app/models/foreman_patch/plan_task_group.rb +11 -0
  74. data/app/models/foreman_patch/round.rb +68 -0
  75. data/app/models/foreman_patch/ticket_field.rb +23 -0
  76. data/app/models/foreman_patch/window.rb +123 -0
  77. data/app/models/foreman_patch/window_plan.rb +77 -0
  78. data/app/models/foreman_patch/window_task_group.rb +11 -0
  79. data/app/models/setting/patching.rb +57 -0
  80. data/app/services/foreman_patch/cycle_name_generator.rb +38 -0
  81. data/app/services/foreman_patch/ticket/affected_items.rb +110 -0
  82. data/app/services/foreman_patch/ticket/api.rb +68 -0
  83. data/app/services/foreman_patch/ticket/change_request.rb +92 -0
  84. data/app/services/foreman_patch/ticket/field_render.rb +21 -0
  85. data/app/services/foreman_patch/ticket/payload.rb +136 -0
  86. data/app/services/foreman_patch/ticket.rb +14 -0
  87. data/app/views/dashboard/_foreman_patch_widget.html.erb +2 -0
  88. data/app/views/foreman_patch/api/v2/cycles/base.json.rabl +3 -0
  89. data/app/views/foreman_patch/api/v2/cycles/create.json.rabl +3 -0
  90. data/app/views/foreman_patch/api/v2/cycles/index.json.rabl +3 -0
  91. data/app/views/foreman_patch/api/v2/cycles/show.json.rabl +9 -0
  92. data/app/views/foreman_patch/api/v2/cycles/update.json.rabl +3 -0
  93. data/app/views/foreman_patch/api/v2/group_facet/base.json.rabl +7 -0
  94. data/app/views/foreman_patch/api/v2/group_facet/base_with_root.json.rabl +4 -0
  95. data/app/views/foreman_patch/api/v2/group_facet/show.json.rabl +3 -0
  96. data/app/views/foreman_patch/api/v2/groups/base.json.rabl +3 -0
  97. data/app/views/foreman_patch/api/v2/groups/create.json.rabl +3 -0
  98. data/app/views/foreman_patch/api/v2/groups/index.json.rabl +2 -0
  99. data/app/views/foreman_patch/api/v2/groups/show.json.rabl +14 -0
  100. data/app/views/foreman_patch/api/v2/groups/update.json.rabl +3 -0
  101. data/app/views/foreman_patch/api/v2/invocations/base.json.rabl +6 -0
  102. data/app/views/foreman_patch/api/v2/invocations/index.json.rabl +3 -0
  103. data/app/views/foreman_patch/api/v2/invocations/phase.json.rabl +7 -0
  104. data/app/views/foreman_patch/api/v2/invocations/show.json.rabl +7 -0
  105. data/app/views/foreman_patch/api/v2/plans/base.json.rabl +3 -0
  106. data/app/views/foreman_patch/api/v2/plans/create.json.rabl +2 -0
  107. data/app/views/foreman_patch/api/v2/plans/index.json.rabl +3 -0
  108. data/app/views/foreman_patch/api/v2/plans/show.json.rabl +9 -0
  109. data/app/views/foreman_patch/api/v2/plans/update.json.rabl +2 -0
  110. data/app/views/foreman_patch/api/v2/rounds/base.json.rabl +3 -0
  111. data/app/views/foreman_patch/api/v2/rounds/index.json.rabl +3 -0
  112. data/app/views/foreman_patch/api/v2/rounds/show.json.rabl +17 -0
  113. data/app/views/foreman_patch/api/v2/rounds/status.json.rabl +11 -0
  114. data/app/views/foreman_patch/api/v2/window_plans/base.json.rabl +4 -0
  115. data/app/views/foreman_patch/api/v2/window_plans/create.json.rabl +2 -0
  116. data/app/views/foreman_patch/api/v2/window_plans/index.json.rabl +2 -0
  117. data/app/views/foreman_patch/api/v2/window_plans/show.json.rabl +14 -0
  118. data/app/views/foreman_patch/api/v2/window_plans/update.json.rabl +2 -0
  119. data/app/views/foreman_patch/api/v2/windows/base.json.rabl +3 -0
  120. data/app/views/foreman_patch/api/v2/windows/index.json.rabl +3 -0
  121. data/app/views/foreman_patch/api/v2/windows/schedule.json.rabl +13 -0
  122. data/app/views/foreman_patch/api/v2/windows/show.json.rabl +13 -0
  123. data/app/views/foreman_patch/api/v2/windows/update.json.rabl +3 -0
  124. data/app/views/foreman_patch/cycle_mailer/_details.html.erb +4 -0
  125. data/app/views/foreman_patch/cycle_mailer/_round.html.erb +12 -0
  126. data/app/views/foreman_patch/cycle_mailer/_summary.html.erb +6 -0
  127. data/app/views/foreman_patch/cycle_mailer/_window.html.erb +4 -0
  128. data/app/views/foreman_patch/cycle_mailer/planned.html.erb +7 -0
  129. data/app/views/foreman_patch/cycles/_form.html.erb +9 -0
  130. data/app/views/foreman_patch/cycles/edit.html.erb +41 -0
  131. data/app/views/foreman_patch/cycles/index.html.erb +45 -0
  132. data/app/views/foreman_patch/cycles/show.html.erb +26 -0
  133. data/app/views/foreman_patch/group_mailer/_dashboard.html.erb +31 -0
  134. data/app/views/foreman_patch/group_mailer/_list.html.erb +17 -0
  135. data/app/views/foreman_patch/group_mailer/completed.html.erb +16 -0
  136. data/app/views/foreman_patch/group_mailer/initiated.html.erb +4 -0
  137. data/app/views/foreman_patch/groups/_form.html.erb +9 -0
  138. data/app/views/foreman_patch/groups/edit.html.erb +3 -0
  139. data/app/views/foreman_patch/groups/index.html.erb +40 -0
  140. data/app/views/foreman_patch/groups/new.html.erb +3 -0
  141. data/app/views/foreman_patch/hosts/hosts/new_action.html.erb +1 -0
  142. data/app/views/foreman_patch/hosts/new_action.html.erb +1 -0
  143. data/app/views/foreman_patch/invocation_mailer/_output_line_set.html.erb +6 -0
  144. data/app/views/foreman_patch/invocation_mailer/_output_line_set.text.erb +3 -0
  145. data/app/views/foreman_patch/invocation_mailer/failure.html.erb +50 -0
  146. data/app/views/foreman_patch/invocation_mailer/failure.text.erb +10 -0
  147. data/app/views/foreman_patch/invocations/_output_line_set.html.erb +8 -0
  148. data/app/views/foreman_patch/invocations/_phase.html.erb +17 -0
  149. data/app/views/foreman_patch/invocations/_primary.html.erb +1 -0
  150. data/app/views/foreman_patch/invocations/_refresh.js.erb +7 -0
  151. data/app/views/foreman_patch/invocations/show.html.erb +44 -0
  152. data/app/views/foreman_patch/invocations/show.js.erb +17 -0
  153. data/app/views/foreman_patch/layouts/react.html.erb +17 -0
  154. data/app/views/foreman_patch/plans/_form.html.erb +12 -0
  155. data/app/views/foreman_patch/plans/edit.html.erb +6 -0
  156. data/app/views/foreman_patch/plans/index.html.erb +32 -0
  157. data/app/views/foreman_patch/plans/new.html.erb +3 -0
  158. data/app/views/foreman_patch/plans/show.html.erb +19 -0
  159. data/app/views/foreman_patch/rounds/show.html.erb +54 -0
  160. data/app/views/foreman_patch/ticket_fields/_fields.html.erb +66 -0
  161. data/app/views/foreman_patch/ticket_fields/edit.html.erb +6 -0
  162. data/app/views/foreman_patch/ticket_fields/index.html.erb +26 -0
  163. data/app/views/foreman_patch/ticket_fields/new.html.erb +6 -0
  164. data/app/views/foreman_patch/window_plans/_form.html.erb +11 -0
  165. data/app/views/foreman_patch/window_plans/_hidden_layout.html.erb +7 -0
  166. data/app/views/foreman_patch/window_plans/edit.html.erb +3 -0
  167. data/app/views/foreman_patch/window_plans/new.html.erb +3 -0
  168. data/app/views/foreman_patch/windows/_form.html.erb +21 -0
  169. data/app/views/foreman_patch/windows/_groups.html.erb +2 -0
  170. data/app/views/foreman_patch/windows/_rounds.html.erb +24 -0
  171. data/app/views/foreman_patch/windows/_schedule.html.erb +16 -0
  172. data/app/views/foreman_patch/windows/_ticket.html.erb +12 -0
  173. data/app/views/foreman_patch/windows/edit.html.erb +3 -0
  174. data/app/views/foreman_patch/windows/new.html.erb +3 -0
  175. data/app/views/foreman_patch/windows/show.html.erb +27 -0
  176. data/app/views/foreman_patch/windows/show.json.erb +4 -0
  177. data/app/views/hosts/select_multiple_patch_group.html.erb +12 -0
  178. data/app/views/overrides/patch_groups/_host_patch_group_select.html.erb +9 -0
  179. data/app/views/templates/ensure_services.erb +28 -0
  180. data/config/api_routes.rb +37 -0
  181. data/config/initializers/pagelets.rb +6 -0
  182. data/config/initializers/safemode_jail.rb +4 -0
  183. data/config/routes/mount_engine.rb +3 -0
  184. data/config/routes/overrides.rb +10 -0
  185. data/config/routes.rb +47 -0
  186. data/db/migrate/20210202161304_create_foreman_patch_plans.rb +32 -0
  187. data/db/migrate/20210202163323_create_foreman_patch_cycles.rb +38 -0
  188. data/db/migrate/20210202164301_create_foreman_patch_groups.rb +37 -0
  189. data/db/migrate/20210226134103_add_name_to_cycles.rb +31 -0
  190. data/db/migrate/20210226162824_rename_default_window.rb +5 -0
  191. data/db/migrate/20210302165058_add_task_to_window_groups.rb +7 -0
  192. data/db/migrate/20210304141111_create_invocation.rb +16 -0
  193. data/db/migrate/20210519163923_add_cycle_end_date.rb +29 -0
  194. data/db/migrate/20210525154113_expand_window_groups.rb +27 -0
  195. data/db/migrate/20210723160142_add_cycle_plan_task_group.rb +7 -0
  196. data/db/migrate/20210831160044_cycle_plan_start_correction.rb +5 -0
  197. data/db/migrate/20210907104645_rename_group_priority.rb +5 -0
  198. data/db/migrate/20210909130118_remove_old_references.rb +14 -0
  199. data/db/migrate/20210910141428_rename_round.rb +7 -0
  200. data/db/migrate/20210910163542_rename_plan.rb +8 -0
  201. data/db/migrate/20211014212415_round_group_reference.rb +9 -0
  202. data/db/migrate/20220105224803_add_group_label.rb +25 -0
  203. data/db/migrate/20220114153808_plan_add_name_generator.rb +5 -0
  204. data/db/migrate/20220117103808_remove_cycle_description.rb +5 -0
  205. data/db/migrate/20220406110705_add_window_state.rb +37 -0
  206. data/db/migrate/20220407161120_add_round_status.rb +9 -0
  207. data/db/migrate/20220902134800_add_invocation_status.rb +28 -0
  208. data/db/seeds.d/100-assign_features_with_templates.rb +16 -0
  209. data/db/seeds.d/160-mail_notifications.rb +38 -0
  210. data/db/seeds.d/75-job_templates.rb +16 -0
  211. data/lib/foreman_patch/engine.rb +87 -0
  212. data/lib/foreman_patch/plugin.rb +47 -0
  213. data/lib/foreman_patch/version.rb +3 -0
  214. data/lib/foreman_patch.rb +4 -0
  215. data/lib/tasks/foreman_patch_tasks.rake +47 -0
  216. data/locale/Makefile +60 -0
  217. data/locale/en/foreman_patch.po +19 -0
  218. data/locale/foreman_patch.pot +19 -0
  219. data/locale/gemspec.rb +2 -0
  220. data/package.json +35 -0
  221. data/public/assets/foreman_patch/cycle_plans-e5667e178ba389908f5c815b24ec0ea77c340849d56bc39c5ce72bb626bd446a.scss +6 -0
  222. data/public/assets/foreman_patch/cycle_plans-e5667e178ba389908f5c815b24ec0ea77c340849d56bc39c5ce72bb626bd446a.scss.gz +0 -0
  223. data/public/assets/foreman_patch/foreman_patch-ce5805a60c0d5f896f557ff5246e5a09172043004c850b39bea54e618df1c485.css +1 -0
  224. data/public/assets/foreman_patch/foreman_patch-ce5805a60c0d5f896f557ff5246e5a09172043004c850b39bea54e618df1c485.css.gz +0 -0
  225. data/public/assets/foreman_patch/foreman_patch.json +1 -0
  226. data/public/assets/foreman_patch/plan_edit_windows-e656ba411642a7f983b51958ab30ac49c056322d19295a603cff4d5e6c71c8ed.js +1 -0
  227. data/public/assets/foreman_patch/plan_edit_windows-e656ba411642a7f983b51958ab30ac49c056322d19295a603cff4d5e6c71c8ed.js.gz +0 -0
  228. data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.css +1 -0
  229. data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.css.gz +0 -0
  230. data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js +6 -0
  231. data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js.gz +0 -0
  232. data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js.map +1 -0
  233. data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js.map.gz +0 -0
  234. data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.css +1 -0
  235. data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.css.gz +0 -0
  236. data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js +6 -0
  237. data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js.gz +0 -0
  238. data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js.map +1 -0
  239. data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js.map.gz +0 -0
  240. data/public/webpack/foreman_patch/manifest.json +26 -0
  241. data/public/webpack/foreman_patch/manifest.json.gz +0 -0
  242. data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js +2 -0
  243. data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.gz +0 -0
  244. data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.map +1 -0
  245. data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.map.gz +0 -0
  246. data/test/factories/foreman_patch_factories.rb +5 -0
  247. data/test/test_plugin_helper.rb +6 -0
  248. data/test/unit/foreman_patch_test.rb +11 -0
  249. data/webpack/components/Cycle/Cycle.js +57 -0
  250. data/webpack/components/Cycle/CycleActions.js +21 -0
  251. data/webpack/components/Cycle/CycleConstants.js +2 -0
  252. data/webpack/components/Cycle/CycleHelpers.js +3 -0
  253. data/webpack/components/Cycle/CycleSelectors.js +10 -0
  254. data/webpack/components/Cycle/Window.js +32 -0
  255. data/webpack/components/Cycle/index.js +41 -0
  256. data/webpack/components/Groups/Group.js +20 -0
  257. data/webpack/components/Groups/Groups.js +46 -0
  258. data/webpack/components/Groups/GroupsHelpers.js +11 -0
  259. data/webpack/components/Groups/Priority.js +51 -0
  260. data/webpack/components/Invocation/Invocation.js +47 -0
  261. data/webpack/components/Invocation/InvocationActions.js +8 -0
  262. data/webpack/components/Invocation/InvocationConsts.js +1 -0
  263. data/webpack/components/Invocation/InvocationSelectors.js +14 -0
  264. data/webpack/components/Invocation/index.js +36 -0
  265. data/webpack/components/Invocations/Invocations.js +55 -0
  266. data/webpack/components/Invocations/InvocationsConstants.js +1 -0
  267. data/webpack/components/Invocations/InvocationsHelpers.js +11 -0
  268. data/webpack/components/Invocations/InvocationsPage.js +66 -0
  269. data/webpack/components/Invocations/InvocationsPage.scss +3 -0
  270. data/webpack/components/Invocations/InvocationsSelectors.js +21 -0
  271. data/webpack/components/Invocations/components/InvocationItem.js +66 -0
  272. data/webpack/components/Invocations/components/InvocationStatus.js +51 -0
  273. data/webpack/components/Invocations/index.js +99 -0
  274. data/webpack/components/Plan/Plan.js +90 -0
  275. data/webpack/components/Plan/PlanActions.js +12 -0
  276. data/webpack/components/Plan/PlanConstants.js +1 -0
  277. data/webpack/components/Plan/PlanSelectors.js +9 -0
  278. data/webpack/components/Plan/Window.js +33 -0
  279. data/webpack/components/Plan/index.js +36 -0
  280. data/webpack/components/PlanWindow/PlanWindow.js +55 -0
  281. data/webpack/components/PlanWindow/index.js +32 -0
  282. data/webpack/components/RoundProgress/AggregateStatus.js +58 -0
  283. data/webpack/components/RoundProgress/RoundProgress.js +48 -0
  284. data/webpack/components/RoundProgress/RoundProgressActions.js +9 -0
  285. data/webpack/components/RoundProgress/RoundProgressConstants.js +1 -0
  286. data/webpack/components/RoundProgress/RoundProgressSelectors.js +24 -0
  287. data/webpack/components/RoundProgress/index.js +44 -0
  288. data/webpack/components/Rounds/Rounds.js +57 -0
  289. data/webpack/components/Rounds/RoundsActions.js +8 -0
  290. data/webpack/components/Rounds/RoundsConsts.js +1 -0
  291. data/webpack/components/Rounds/RoundsSelectors.js +14 -0
  292. data/webpack/components/Rounds/components/RoundItem.js +52 -0
  293. data/webpack/components/Rounds/components/RoundStatus.js +40 -0
  294. data/webpack/components/Rounds/index.js +37 -0
  295. data/webpack/components/common/Calendar/Calendar.js +86 -0
  296. data/webpack/components/common/Calendar/Calendar.scss +76 -0
  297. data/webpack/components/common/Calendar/CalendarConstants.js +1 -0
  298. data/webpack/components/common/Calendar/CalendarHelpers.js +77 -0
  299. data/webpack/components/common/Calendar/Day/index.js +9 -0
  300. data/webpack/components/common/Calendar/Event.js +25 -0
  301. data/webpack/components/common/Calendar/Month/Day.js +51 -0
  302. data/webpack/components/common/Calendar/Month/Header.js +77 -0
  303. data/webpack/components/common/Calendar/Month/Month.js +47 -0
  304. data/webpack/components/common/Calendar/Month/index.js +1 -0
  305. data/webpack/components/common/Calendar/View.js +20 -0
  306. data/webpack/components/common/Calendar/Week/index.js +13 -0
  307. data/webpack/components/common/Calendar/index.js +2 -0
  308. data/webpack/components/common/Terminal/OutputLine.js +26 -0
  309. data/webpack/components/common/Terminal/Terminal.js +115 -0
  310. data/webpack/components/common/Terminal/Terminal.scss +47 -0
  311. data/webpack/index.js +20 -0
  312. metadata +438 -0
@@ -0,0 +1,21 @@
1
+ module ForemanPatch
2
+ module Concerns
3
+ module Api::V2::HostsControllerExtensions
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ after_action :reschedule_patching, only: :update
8
+
9
+ def reschedule_patching
10
+ return if @host.group_facet.nil?
11
+ return unless @host.group_facet.saved_change_to_attribute?(:group_id)
12
+
13
+ schedule = params.dig('host', 'group_facet_attributes', 'schedule') || 'future-only'
14
+
15
+ ForemanTasks.async_task(Actions::ForemanPatch::Host::Reschedule, @host, include_active: schedule == 'all') unless schedule == 'none'
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,61 @@
1
+ module ForemanPatch
2
+ module Concerns
3
+ module HostsControllerExtensions
4
+ extend ActiveSupport::Concern
5
+
6
+ module Overrides
7
+ def action_permission
8
+ case params[:action]
9
+ when 'select_multiple_patch_group', 'update_multiple_patch_group'
10
+ :edit
11
+ else
12
+ super
13
+ end
14
+ end
15
+ end
16
+
17
+ included do
18
+ prepend Overrides
19
+
20
+ after_action :reschedule_patching, only: :update
21
+
22
+ def select_multiple_patch_group
23
+ find_multiple
24
+ end
25
+
26
+ def update_multiple_patch_group
27
+ find_multiple
28
+
29
+ if (params['patch_group']['id'].blank?)
30
+ @hosts.each do |host|
31
+ group_facet = host.group_facet
32
+ group_facet.group = nil unless group_facet.blank?
33
+ host.save!
34
+ end
35
+ else
36
+ patch_group = ForemanPatch::Group.find(params['patch_group']['id'])
37
+
38
+ @hosts.each do |host|
39
+ group_facet = host.group_facet || host.build_group_facet
40
+ group_facet.group = patch_group
41
+ host.save!
42
+ end
43
+ end
44
+
45
+ ForemanTasks.async_task(Actions::ForemanPatch::Host::Reschedule, @hosts, include_active: params['patch_group']['include_active'])
46
+
47
+ success _('Updated hosts: changed patch group')
48
+ redirect_back_or_to hosts_path
49
+ end
50
+
51
+ def reschedule_patching
52
+ return if @host.group_facet.nil?
53
+ return unless @host.group_facet.saved_change_to_attribute?(:group_id)
54
+
55
+ ForemanTasks.async_task(Actions::ForemanPatch::Host::Reschedule, @host)
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,34 @@
1
+ module ForemanPatch
2
+ class CyclesController < ApplicationController
3
+ include Foreman::Controller::AutoCompleteSearch
4
+
5
+ before_action :find_resource, only: [:show, :destroy]
6
+
7
+ def index
8
+ params[:order] ||= 'start_date DESC'
9
+ @cycles = resource_base_search_and_page
10
+ end
11
+
12
+ def show
13
+ end
14
+
15
+ def destroy
16
+ if @cycle.destroy
17
+ process_success object: @cycle
18
+ else
19
+ process_error object: @cycle
20
+ end
21
+ end
22
+
23
+ def resource_class
24
+ ForemanPatch::Cycle
25
+ end
26
+
27
+ private
28
+
29
+ def cycle_params
30
+ params.require(:cycle).permit(:name, :description, :start_date)
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,68 @@
1
+ module ForemanPatch
2
+ class GroupsController < ApplicationController
3
+ include Foreman::Controller::AutoCompleteSearch
4
+ include Foreman::Controller::CsvResponder
5
+
6
+ before_action :find_resource, only: [:edit, :update, :destroy]
7
+ before_action :setup_search_options, only: :index
8
+
9
+ def index
10
+ respond_to do |format|
11
+ format.html do
12
+ @groups = resource_base_search_and_page
13
+ render :index
14
+ end
15
+ format.csv do
16
+ csv_response(resource_base_with_search)
17
+ end
18
+ end
19
+ end
20
+
21
+ def new
22
+ @group = Group.new
23
+ end
24
+
25
+ def create
26
+ @group = Group.new(group_params)
27
+ if @group.save
28
+ process_success object: @group
29
+ else
30
+ process_error object: @group
31
+ end
32
+ end
33
+
34
+ def edit
35
+ end
36
+
37
+ def update
38
+ if @group.update(group_params)
39
+ process_success object: @group
40
+ else
41
+ process_error object: @group
42
+ end
43
+ end
44
+
45
+ def destroy
46
+ if @group.destroy
47
+ process_success object: @group
48
+ else
49
+ process_error object: @group
50
+ end
51
+ end
52
+
53
+ def resource_class
54
+ ForemanPatch::Group
55
+ end
56
+
57
+ def csv_columns
58
+ [:name, :label, :default_window_plan, :hosts_count]
59
+ end
60
+
61
+ private
62
+
63
+ def group_params
64
+ params.require(:group).permit(:name, :description, :default_window_plan_id, :max_unavailable, :priority)
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,51 @@
1
+ module ForemanPatch
2
+ class InvocationsController < ApplicationController
3
+ include Foreman::Controller::AutoCompleteSearch
4
+
5
+ before_action :find_resource
6
+
7
+ helper ForemanPatch::PatchingHelper
8
+
9
+ def show
10
+ @invocation = ForemanPatch::Invocation.find(params[:id])
11
+ @host = @invocation.host
12
+
13
+ @round = @invocation.round
14
+ @window = @round.window
15
+ @cycle = @window.cycle
16
+
17
+ @auto_refresh = !@invocation.complete?
18
+ @since = params[:since].to_f if params[:since].present?
19
+
20
+ @invocation.phases.each do |phase|
21
+ @line_sets = phase.live_output
22
+ @line_sets = @line_sets.drop_while { |o| o['timestamp'].to_f <= @since } if @since
23
+
24
+ unless @line_sets.empty?
25
+ @phase = phase.label.demodulize.underscore
26
+ break
27
+ end
28
+ end
29
+
30
+ @line_counter = params[:line_counter].to_i
31
+ end
32
+
33
+ def destroy
34
+ if @invocation.destroy!
35
+ else
36
+ process_error
37
+ end
38
+ end
39
+
40
+ def resource_class
41
+ ForemanPatch::Invocation
42
+ end
43
+
44
+ private
45
+
46
+ def create_override
47
+ ForemanPatch::Override.create!(source: @invocation, user: User.current, reason: params[:reason])
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,59 @@
1
+ module ForemanPatch
2
+ class PlansController < ApplicationController
3
+
4
+ before_action :find_resource, only: [:show, :edit, :iterate, :update, :destroy]
5
+
6
+ def index
7
+ @plans = resource_base_search_and_page
8
+ end
9
+
10
+ def new
11
+ @plan = Plan.new
12
+ end
13
+
14
+ def create
15
+ @plan = Plan.new(plan_params)
16
+ end
17
+
18
+ def show
19
+ end
20
+
21
+ def edit
22
+ end
23
+
24
+ def iterate
25
+ @plan.iterate
26
+ end
27
+
28
+ def update
29
+ if @plan.update(plan_params)
30
+ process_success success_hash
31
+ else
32
+ process_error
33
+ end
34
+ end
35
+
36
+ def destroy
37
+ if @plan.destroy
38
+ process_success success_hash
39
+ else
40
+ process_error
41
+ end
42
+ end
43
+
44
+ def resource_class
45
+ ForemanPatch::Plan
46
+ end
47
+
48
+ private
49
+
50
+ def plan_params
51
+ params.require(:plan).permit(:name, :description, :cycle_name, :start_date, :interval, :units, :active_count)
52
+ end
53
+
54
+ def success_hash
55
+ { success_redirect: params[:redirect].presence }
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,18 @@
1
+ module ForemanPatch
2
+ class RoundsController < ApplicationController
3
+
4
+ before_action :find_resource, only: [:move, :chart, :show]
5
+
6
+ helper ForemanPatch::PatchingHelper
7
+
8
+ def show
9
+ end
10
+
11
+ def resource_class
12
+ ForemanPatch::Round
13
+ end
14
+
15
+ private
16
+
17
+ end
18
+ end
@@ -0,0 +1,37 @@
1
+ module ForemanPatch
2
+ class TicketFieldsController < ::LookupKeysController
3
+ include Foreman::Controller::AutoCompleteSearch
4
+ include ForemanPatch::Parameters::TicketField
5
+
6
+ before_action :find_resource, only: [:edit, :update, :destroy], if: proc { params[:id] }
7
+
8
+ def index
9
+ @ticket_fields = resource_base_search_and_page
10
+ end
11
+
12
+ def new
13
+ @ticket_field = TicketField.new
14
+ end
15
+
16
+ def create
17
+ @ticket_field = TicketField.new(ticket_field_params)
18
+ if @ticket_field.save
19
+ process_success
20
+ else
21
+ process_error
22
+ end
23
+ end
24
+
25
+ def resource_class
26
+ ForemanPatch::TicketField
27
+ end
28
+
29
+ def resource
30
+ @ticket_field
31
+ end
32
+
33
+ def resource_params
34
+ ticket_field_params
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,60 @@
1
+ module ForemanPatch
2
+ class WindowPlansController < ApplicationController
3
+ helper ForemanPatch::PlansHelper
4
+
5
+ before_action :find_resource, only: [:edit, :update, :destroy]
6
+ before_action :find_plan, only: [:new, :create]
7
+
8
+ def new
9
+ @window_plan = WindowPlan.new
10
+ end
11
+
12
+ def create
13
+ @window_plan = WindowPlan.new(window_plan_params)
14
+ end
15
+
16
+ def edit
17
+ @plan = @window_plan.plan
18
+ end
19
+
20
+ def update
21
+ if @window_plan.update(window_plan_params)
22
+ process_success success_hash
23
+ else
24
+ process_error
25
+ end
26
+ end
27
+
28
+ def destroy
29
+ if @window_plan.destroy
30
+ process_success success_hash
31
+ else
32
+ process_error
33
+ end
34
+ end
35
+
36
+ def resource_class
37
+ ForemanPatch::WindowPlan
38
+ end
39
+
40
+ private
41
+
42
+ def allowed_nested_id
43
+ %w(plan_id)
44
+ end
45
+
46
+ def find_plan
47
+ @plan ||= ForemanPatch::Plan.find(params[:plan_id])
48
+ end
49
+
50
+ def window_plan_params
51
+ params[:window_plan][:plan_id] = params[:plan_id] unless params[:plan_id].nil?
52
+ params.require(:window_plan).permit(:name, :description, :state_day, :start_time, :duration, :plan_id)
53
+ end
54
+
55
+ def success_hash
56
+ { success_redirect: params[:redirect].presence || plan_path(@plan) }
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,58 @@
1
+ module ForemanPatch
2
+ class WindowsController < ApplicationController
3
+
4
+ before_action :find_cycle, only: [:new, :create]
5
+ before_action :find_resource, only: [:show, :destroy]
6
+
7
+ helper ForemanPatch::WindowPatchingHelper
8
+ helper ForemanPatch::TicketHelper
9
+
10
+ def new
11
+ @window = Window.new
12
+ end
13
+
14
+ def create
15
+ @window = Window.new(window_params)
16
+ if @window.save
17
+ process_success object: @window
18
+ else
19
+ process_error object: @window
20
+ end
21
+ end
22
+
23
+ def show
24
+ @cycle = @window.cycle
25
+
26
+ @auto_refresh = @window.task.try(:pending?)
27
+
28
+ respond_to do |format|
29
+ format.json
30
+ format.html
31
+ end
32
+ end
33
+
34
+ def destroy
35
+ if @window.destroy
36
+ process_success object: @window
37
+ else
38
+ process_error object: @window
39
+ end
40
+ end
41
+
42
+ def resource_class
43
+ ForemanPatch::Window
44
+ end
45
+
46
+ private
47
+
48
+ def find_cycle
49
+ @cycle ||= Cycle.find(params[:cycle_id])
50
+ end
51
+
52
+ def window_params
53
+ params[:window][:cycle_id] = @cycle.id unless @cycle.nil?
54
+ params.require(:window).permit(:name, :description, :start_at, :end_by)
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,13 @@
1
+ module ForemanPatch
2
+ module HostsHelperExtensions
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ # execute callbacks
7
+ end
8
+
9
+ # create or overwrite instance methods...
10
+ def instance_method_name
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module ForemanPatch
2
+ module CyclesHelper
3
+
4
+ def cycle_length(cycle)
5
+ if ForemanPatch::Cycle === cycle
6
+ cycle = cycle.plan
7
+ end
8
+
9
+ cycle.interval.send(cycle.units).value / ActiveSupport::Duration::SECONDS_PER_DAY
10
+ end
11
+
12
+ def cycle_windows(cycle, date)
13
+ cycle.windows.select do |window|
14
+ window.start_at.to_date === date
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,52 @@
1
+ module ForemanPatch
2
+ module HostsHelper
3
+
4
+ def patch_host_multiple_actions
5
+ [
6
+ {action: [_('Change Patch Group'), select_multiple_patch_group_hosts_path], priority: 1000}
7
+ ]
8
+ end
9
+
10
+ def patch_groups_for_host(host, options)
11
+ include_blank = options.fetch(:include_blank, nil)
12
+ if include_blank == true
13
+ include_blank = '<option></option>'
14
+ end
15
+
16
+ group_options = ForemanPatch::Group.all.map do |group|
17
+ selected = host.group.try(:id) == group.id ? 'selected' : ''
18
+ %(<option #{selected} value="#{group.id}">#{h(group.name)}</option>)
19
+ end
20
+
21
+ group_options = group_options.join
22
+ group_options.insert(0, include_blank) if include_blank
23
+ group_options.html_safe
24
+ end
25
+
26
+ def patch_host_overview_fields(host)
27
+ fields = []
28
+ if host.group_facet.present?
29
+ name = host.group_facet.group || 'None'
30
+ search = (host.group_facet.group.present? ? "patch_group = #{host.group_facet.group}" : 'not has patch_group')
31
+
32
+ fields << {
33
+ field: [
34
+ _('Patch Group'),
35
+ link_to(name, hosts_path(search: search)),
36
+ ],
37
+ priority: 1001,
38
+ }
39
+
40
+ fields << {
41
+ field: [
42
+ _('Last Patch Date'),
43
+ host.group_facet.last_patched_at,
44
+ ],
45
+ priority: 1002,
46
+ }
47
+ end
48
+ fields
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,116 @@
1
+ module ForemanPatch
2
+ module PatchingHelper
3
+
4
+ def round_hosts_authorizer
5
+ @round_hosts_authorizer ||= Authorizer.new(User.current, collection: @hosts)
6
+ end
7
+
8
+ def patch_invocation_actions(round, invocation)
9
+ host = invocation.host
10
+ task = invocation.task
11
+
12
+ links = []
13
+
14
+ if authorized_for(main_app.hash_for_host_path(host).merge(auth_object: host, permission: :view_hosts, authorizer: round_hosts_authorizer))
15
+ links << { title: _('Host Detail'),
16
+ action: { href: main_app.host_path(host), 'data-method': 'get', id: "#{host.name}-actions-detail" } }
17
+ end
18
+
19
+ if task.present? && authorized_for(main_app.hash_for_foreman_tasks_task_path(task).merge(auth_object: task, permission: :view_foreman_tasks))
20
+ links << { title: _('Task Detail'),
21
+ action: { href: main_app.foreman_tasks_task_path(task),
22
+ 'data-method': 'get',
23
+ id: "#{host.name}-actions-task" }
24
+ }
25
+ end
26
+
27
+ unless task.present?
28
+ links << { title: _('Cancel'),
29
+ action: { href: invocation_path(invocation),
30
+ 'data-method': 'delete',
31
+ id: "#{host.name}-actions-cancel" }
32
+ }
33
+ end
34
+
35
+ if task.present? and task.pending?
36
+ links << { title: _('Cancel'),
37
+ action: { href: main_app.cancel_foreman_tasks_task_path(task),
38
+ 'data-method': 'post',
39
+ id: "#{host.name}-actions-cancel" }
40
+ }
41
+
42
+ links << { title: _('Abort'),
43
+ action: { href: main_app.abort_foreman_tasks_task_path(task),
44
+ 'data-method': 'post',
45
+ id: "#{host.name}-actions-abort" }
46
+ }
47
+ end
48
+
49
+ links
50
+ end
51
+
52
+ def round_invocation_hosts(round)
53
+ round.invocations.map do |invocation|
54
+ {
55
+ name: invocation.host.name,
56
+ link: invocation_path(invocation),
57
+ state: invocation.state,
58
+ result: invocation.result,
59
+ actions: patch_invocation_actions(round, invocation)
60
+ }
61
+ end
62
+ end
63
+
64
+ def round_task_buttons(task)
65
+ buttons = []
66
+
67
+ if authorized_for(permission: :view_foreman_tasks, auth_object: task, authorizer: Authorizer.new(User.current, collection: [task]))
68
+ buttons << link_to(_('Task Details'), main_app.foreman_tasks_task_path(task),
69
+ class: 'btn btn-default',
70
+ title: _('See the task details'))
71
+ end
72
+
73
+ # if authorized
74
+ buttons << link_to(_('Cancel'), main_app.cancel_foreman_tasks_task_path(task),
75
+ class: 'btn btn-danger',
76
+ title: _('Try to cancel the patching round'),
77
+ disabled: !task.cancellable?,
78
+ method: :post)
79
+ buttons << link_to(_('Abort'), main_app.abort_foreman_tasks_task_path(task),
80
+ class: 'btn btn-danger',
81
+ title: _('Try to abort the patching round without waiting for its result'),
82
+ disabled: !task.cancellable?,
83
+ method: :post)
84
+ # end
85
+
86
+ buttons
87
+ end
88
+
89
+ def invocation_task_buttons(task, invocation)
90
+ buttons = []
91
+
92
+ if task.present? && authorized_for(permission: :view_foreman_tasks, auth_object: task)
93
+ buttons << link_to(_('Task Details'), main_app.foreman_tasks_task_path(task),
94
+ class: 'btn btn-default',
95
+ title: _('See the task details'))
96
+ end
97
+
98
+ #if authorized_for... eventually
99
+ if task.present?
100
+ buttons << link_to(_('Cancel Patch'), main_app.cancel_foreman_tasks_task_path(task),
101
+ class: 'btn btn-danger',
102
+ title: _('Try to cancel the patch of the host'),
103
+ disabled: !task.cancellable?,
104
+ method: :post)
105
+ buttons << link_to(_('Abort Patch'), main_app.abort_foreman_tasks_task_path(task),
106
+ class: 'btn btn-danger',
107
+ title: _('Try to abort the patching of the host without waiting for its result'),
108
+ disabled: !task.cancellable?,
109
+ method: :post)
110
+ end
111
+ #end
112
+ buttons
113
+ end
114
+
115
+ end
116
+ end