foreman_puppet 0.0.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 (247) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +38 -0
  4. data/Rakefile +31 -0
  5. data/app/assets/stylesheets/foreman_puppet.scss +117 -0
  6. data/app/controllers/concerns/foreman_puppet/api/import_puppetclasses_common_controller.rb +139 -0
  7. data/app/controllers/concerns/foreman_puppet/environments_import.rb +61 -0
  8. data/app/controllers/concerns/foreman_puppet/extensions/api_hostgroups_controller.rb +40 -0
  9. data/app/controllers/concerns/foreman_puppet/extensions/api_template_combinations_controller.rb +23 -0
  10. data/app/controllers/concerns/foreman_puppet/extensions/api_v2_hosts_controller.rb +48 -0
  11. data/app/controllers/concerns/foreman_puppet/extensions/hostgroups_controller_extensions.rb +58 -0
  12. data/app/controllers/concerns/foreman_puppet/extensions/hosts_controller_extensions.rb +228 -0
  13. data/app/controllers/concerns/foreman_puppet/extensions/operatingsystems_controller.rb +11 -0
  14. data/app/controllers/concerns/foreman_puppet/extensions/parameters_host.rb +75 -0
  15. data/app/controllers/concerns/foreman_puppet/extensions/parameters_hostgroup.rb +70 -0
  16. data/app/controllers/concerns/foreman_puppet/extensions/parameters_template_combination.rb +21 -0
  17. data/app/controllers/concerns/foreman_puppet/parameters/config_group.rb +17 -0
  18. data/app/controllers/concerns/foreman_puppet/parameters/environment.rb +21 -0
  19. data/app/controllers/concerns/foreman_puppet/parameters/puppetclass.rb +24 -0
  20. data/app/controllers/concerns/foreman_puppet/parameters/puppetclass_lookup_key.rb +24 -0
  21. data/app/controllers/foreman_puppet/api/v2/base_controller.rb +26 -0
  22. data/app/controllers/foreman_puppet/api/v2/config_groups_controller.rb +57 -0
  23. data/app/controllers/foreman_puppet/api/v2/environments_controller.rb +91 -0
  24. data/app/controllers/foreman_puppet/api/v2/host_classes_controller.rb +59 -0
  25. data/app/controllers/foreman_puppet/api/v2/hostgroup_classes_controller.rb +46 -0
  26. data/app/controllers/foreman_puppet/api/v2/lookups_common_controller.rb +114 -0
  27. data/app/controllers/foreman_puppet/api/v2/override_values_controller.rb +99 -0
  28. data/app/controllers/foreman_puppet/api/v2/puppetclasses_controller.rb +99 -0
  29. data/app/controllers/foreman_puppet/api/v2/smart_class_parameters_controller.rb +76 -0
  30. data/app/controllers/foreman_puppet/config_groups_controller.rb +46 -0
  31. data/app/controllers/foreman_puppet/environments_controller.rb +51 -0
  32. data/app/controllers/foreman_puppet/puppet_smart_proxies_controller.rb +39 -0
  33. data/app/controllers/foreman_puppet/puppetclass_lookup_keys_controller.rb +33 -0
  34. data/app/controllers/foreman_puppet/puppetclasses_controller.rb +113 -0
  35. data/app/controllers/foreman_puppet/react_controller.rb +19 -0
  36. data/app/helpers/concerns/foreman_puppet/template_renderer_scope.rb +14 -0
  37. data/app/helpers/foreman_puppet/environments_helper.rb +17 -0
  38. data/app/helpers/foreman_puppet/hosts_and_hostgroups_helper.rb +96 -0
  39. data/app/helpers/foreman_puppet/hosts_helper.rb +32 -0
  40. data/app/helpers/foreman_puppet/puppet_smart_proxies_helper.rb +8 -0
  41. data/app/helpers/foreman_puppet/puppetclass_lookup_keys_helper.rb +135 -0
  42. data/app/helpers/foreman_puppet/puppetclasses_and_environments_helper.rb +55 -0
  43. data/app/helpers/foreman_puppet/puppetclasses_helper.rb +59 -0
  44. data/app/helpers/foreman_puppet/template_combinations_helper.rb +33 -0
  45. data/app/models/concerns/foreman_puppet/extensions/host.rb +88 -0
  46. data/app/models/concerns/foreman_puppet/extensions/hostgroup.rb +40 -0
  47. data/app/models/concerns/foreman_puppet/extensions/nic_managed.rb +11 -0
  48. data/app/models/concerns/foreman_puppet/extensions/operatingsystem.rb +11 -0
  49. data/app/models/concerns/foreman_puppet/extensions/provisioning_template.rb +64 -0
  50. data/app/models/concerns/foreman_puppet/extensions/report.rb +11 -0
  51. data/app/models/concerns/foreman_puppet/extensions/taxonomy.rb +19 -0
  52. data/app/models/concerns/foreman_puppet/extensions/template_combination.rb +23 -0
  53. data/app/models/concerns/foreman_puppet/extensions/user.rb +22 -0
  54. data/app/models/concerns/foreman_puppet/host_common.rb +90 -0
  55. data/app/models/concerns/foreman_puppet/puppet_lookup_value_extensions.rb +13 -0
  56. data/app/models/foreman_puppet/config_group.rb +45 -0
  57. data/app/models/foreman_puppet/config_group_class.rb +19 -0
  58. data/app/models/foreman_puppet/environment.rb +63 -0
  59. data/app/models/foreman_puppet/environment_class.rb +40 -0
  60. data/app/models/foreman_puppet/host_class.rb +23 -0
  61. data/app/models/foreman_puppet/host_config_group.rb +15 -0
  62. data/app/models/foreman_puppet/host_puppet_facet.rb +130 -0
  63. data/app/models/foreman_puppet/hostgroup_class.rb +23 -0
  64. data/app/models/foreman_puppet/hostgroup_puppet_facet.rb +98 -0
  65. data/app/models/foreman_puppet/puppetclass.rb +132 -0
  66. data/app/models/foreman_puppet/puppetclass_lookup_key.rb +58 -0
  67. data/app/services/foreman_puppet/host_info_providers/config_groups_info.rb +10 -0
  68. data/app/services/foreman_puppet/host_info_providers/puppet_info.rb +92 -0
  69. data/app/services/foreman_puppet/input_type/puppet_parameter_input.rb +35 -0
  70. data/app/services/foreman_puppet/proxy_status/puppet.rb +17 -0
  71. data/app/services/foreman_puppet/puppet_class_importer.rb +355 -0
  72. data/app/views/api/v2/template_combinations/base.json.erb +9 -0
  73. data/app/views/foreman_puppet/api/v2/config_groups/base.json.rabl +3 -0
  74. data/app/views/foreman_puppet/api/v2/config_groups/create.json.rabl +3 -0
  75. data/app/views/foreman_puppet/api/v2/config_groups/index.json.rabl +3 -0
  76. data/app/views/foreman_puppet/api/v2/config_groups/main.json.rabl +8 -0
  77. data/app/views/foreman_puppet/api/v2/config_groups/show.json.rabl +3 -0
  78. data/app/views/foreman_puppet/api/v2/config_groups/update.json.rabl +3 -0
  79. data/app/views/foreman_puppet/api/v2/environments/base.json.rabl +3 -0
  80. data/app/views/foreman_puppet/api/v2/environments/create.json.rabl +3 -0
  81. data/app/views/foreman_puppet/api/v2/environments/index.json.rabl +3 -0
  82. data/app/views/foreman_puppet/api/v2/environments/main.json.rabl +5 -0
  83. data/app/views/foreman_puppet/api/v2/environments/show.json.rabl +15 -0
  84. data/app/views/foreman_puppet/api/v2/environments/update.json.rabl +3 -0
  85. data/app/views/foreman_puppet/api/v2/host_puppet_facets/base.json.rabl +1 -0
  86. data/app/views/foreman_puppet/api/v2/host_puppet_facets/host_single.json.rabl +17 -0
  87. data/app/views/foreman_puppet/api/v2/host_puppet_facets/show.json.rabl +11 -0
  88. data/app/views/foreman_puppet/api/v2/hostgroup_puppet_facets/base.json.rabl +5 -0
  89. data/app/views/foreman_puppet/api/v2/hostgroup_puppet_facets/hostgroup_single.json.rabl +16 -0
  90. data/app/views/foreman_puppet/api/v2/hostgroup_puppet_facets/show.json.rabl +11 -0
  91. data/app/views/foreman_puppet/api/v2/import_puppetclasses/index.json.rabl +3 -0
  92. data/app/views/foreman_puppet/api/v2/import_puppetclasses/show.json.rabl +36 -0
  93. data/app/views/foreman_puppet/api/v2/override_values/create.json.rabl +3 -0
  94. data/app/views/foreman_puppet/api/v2/override_values/index.json.rabl +3 -0
  95. data/app/views/foreman_puppet/api/v2/override_values/show.json.rabl +3 -0
  96. data/app/views/foreman_puppet/api/v2/override_values/update.json.rabl +3 -0
  97. data/app/views/foreman_puppet/api/v2/puppetclasses/base.json.rabl +3 -0
  98. data/app/views/foreman_puppet/api/v2/puppetclasses/create.json.rabl +3 -0
  99. data/app/views/foreman_puppet/api/v2/puppetclasses/index.json.rabl +4 -0
  100. data/app/views/foreman_puppet/api/v2/puppetclasses/list.json.rabl +3 -0
  101. data/app/views/foreman_puppet/api/v2/puppetclasses/main.json.rabl +5 -0
  102. data/app/views/foreman_puppet/api/v2/puppetclasses/show.json.rabl +15 -0
  103. data/app/views/foreman_puppet/api/v2/puppetclasses/update.json.rabl +3 -0
  104. data/app/views/foreman_puppet/api/v2/smart_class_parameters/base.json.rabl +4 -0
  105. data/app/views/foreman_puppet/api/v2/smart_class_parameters/create.json.rabl +3 -0
  106. data/app/views/foreman_puppet/api/v2/smart_class_parameters/destroy.json.rabl +3 -0
  107. data/app/views/foreman_puppet/api/v2/smart_class_parameters/index.json.rabl +3 -0
  108. data/app/views/foreman_puppet/api/v2/smart_class_parameters/main.json.rabl +23 -0
  109. data/app/views/foreman_puppet/api/v2/smart_class_parameters/show.json.rabl +19 -0
  110. data/app/views/foreman_puppet/api/v2/smart_class_parameters/update.json.rabl +3 -0
  111. data/app/views/foreman_puppet/config_groups/_config_group.html.erb +34 -0
  112. data/app/views/foreman_puppet/config_groups/_config_groups_selection.html.erb +36 -0
  113. data/app/views/foreman_puppet/config_groups/_form.html.erb +9 -0
  114. data/app/views/foreman_puppet/config_groups/edit.html.erb +3 -0
  115. data/app/views/foreman_puppet/config_groups/index.html.erb +31 -0
  116. data/app/views/foreman_puppet/config_groups/new.html.erb +3 -0
  117. data/app/views/foreman_puppet/config_groups/welcome.html.erb +12 -0
  118. data/app/views/foreman_puppet/environments/_form.html.erb +20 -0
  119. data/app/views/foreman_puppet/environments/edit.html.erb +8 -0
  120. data/app/views/foreman_puppet/environments/index.html.erb +32 -0
  121. data/app/views/foreman_puppet/environments/new.html.erb +7 -0
  122. data/app/views/foreman_puppet/environments/welcome.html.erb +16 -0
  123. data/app/views/foreman_puppet/layouts/application_react.html.erb +15 -0
  124. data/app/views/foreman_puppet/puppet_smart_proxies/_dashboard.html.erb +9 -0
  125. data/app/views/foreman_puppet/puppet_smart_proxies/_environments.html.erb +30 -0
  126. data/app/views/foreman_puppet/puppetclass_lookup_keys/edit.html.erb +3 -0
  127. data/app/views/foreman_puppet/puppetclass_lookup_keys/index.html.erb +22 -0
  128. data/app/views/foreman_puppet/puppetclass_lookup_keys/welcome.html.erb +9 -0
  129. data/app/views/foreman_puppet/puppetclasses/_class_parameters.html.erb +37 -0
  130. data/app/views/foreman_puppet/puppetclasses/_class_selection.html.erb +70 -0
  131. data/app/views/foreman_puppet/puppetclasses/_classes.html.erb +22 -0
  132. data/app/views/foreman_puppet/puppetclasses/_classes_in_groups.html.erb +5 -0
  133. data/app/views/foreman_puppet/puppetclasses/_classes_parameters.html.erb +16 -0
  134. data/app/views/foreman_puppet/puppetclasses/_form.html.erb +62 -0
  135. data/app/views/foreman_puppet/puppetclasses/_selected_classes.html.erb +4 -0
  136. data/app/views/foreman_puppet/puppetclasses/edit.html.erb +4 -0
  137. data/app/views/foreman_puppet/puppetclasses/index.html.erb +47 -0
  138. data/app/views/hosts/_form_puppet_enc_tab.html.erb +24 -0
  139. data/app/views/hosts/foreman_puppet/_form_main_tab_fields.html.erb +1 -0
  140. data/app/views/hosts/select_multiple_environment.html.erb +8 -0
  141. data/app/views/provisioning_templates/_combination.html.erb +5 -0
  142. data/app/views/provisioning_templates/_combinations.html.erb +6 -0
  143. data/app/views/smart_proxies/plugins/_puppet.html.erb +24 -0
  144. data/config/api_routes.rb +81 -0
  145. data/config/routes.rb +89 -0
  146. data/db/migrate/20101121140000_add_environment_to_template_combinations.foreman_puppet.rb +9 -0
  147. data/db/migrate/20200720123005_migrate_puppet_core_types.foreman_puppet.rb +19 -0
  148. data/db/migrate/20200722171017_create_host_puppet_facet.foreman_puppet.rb +10 -0
  149. data/db/migrate/20200803113531_create_hostgroup_puppet_facet.foreman_puppet.rb +10 -0
  150. data/db/migrate/20200803113803_migrate_environment_to_puppet_facet.foreman_puppet.rb +22 -0
  151. data/db/migrate/20200803113903_migrate_host_type_in_host_config_groups.foreman_puppet.rb +29 -0
  152. data/db/migrate/20201125113903_migrate_puppetclasses_to_facets.foreman_puppet.rb +47 -0
  153. data/db/migrate_foreman/20090722141107_create_environments.rb +17 -0
  154. data/db/migrate_foreman/20120905095532_create_environment_classes.rb +15 -0
  155. data/db/migrate_foreman/20140407161817_create_config_groups.rb +9 -0
  156. data/db/migrate_foreman/20140407162007_create_config_group_classes.rb +10 -0
  157. data/db/migrate_foreman/20140407162059_create_host_config_groups.rb +11 -0
  158. data/db/migrate_foreman/20161205142618_delete_orphaned_smart_class_parameters.rb +10 -0
  159. data/db/migrate_foreman/20170109115157_fix_lookup_key_auditable_type.rb +15 -0
  160. data/db/migrate_foreman/20180816134832_cast_lookup_key_values.rb +35 -0
  161. data/db/migrate_foreman/20181023112532_add_environment_puppetclass_id.rb +7 -0
  162. data/db/migrate_foreman/20181224174419_add_index_to_environment_class_by_lookup_key_and_puppetclass.rb +6 -0
  163. data/db/seeds.d/111_puppet_proxy_feature.rb +8 -0
  164. data/lib/foreman_puppet.rb +10 -0
  165. data/lib/foreman_puppet/engine.rb +82 -0
  166. data/lib/foreman_puppet/register.rb +218 -0
  167. data/lib/foreman_puppet/version.rb +3 -0
  168. data/lib/tasks/foreman_puppet_tasks.rake +31 -0
  169. data/locale/Makefile +60 -0
  170. data/locale/action_names.rb +5 -0
  171. data/locale/en/foreman_puppet.edit.po +911 -0
  172. data/locale/en/foreman_puppet.po +690 -0
  173. data/locale/en/foreman_puppet.po.time_stamp +0 -0
  174. data/locale/foreman_puppet.pot +1076 -0
  175. data/locale/gemspec.rb +2 -0
  176. data/test/controllers/foreman_puppet/api/v2/config_groups_controller_test.rb +28 -0
  177. data/test/controllers/foreman_puppet/api/v2/environments_controller_test.rb +346 -0
  178. data/test/controllers/foreman_puppet/api/v2/host_classes_controller_test.rb +48 -0
  179. data/test/controllers/foreman_puppet/api/v2/hostgroup_classes_controller_test.rb +41 -0
  180. data/test/controllers/foreman_puppet/api/v2/hostgroups_controller_test.rb +79 -0
  181. data/test/controllers/foreman_puppet/api/v2/hosts_controller_test.rb +101 -0
  182. data/test/controllers/foreman_puppet/api/v2/lookups_common_controller_test.rb +29 -0
  183. data/test/controllers/foreman_puppet/api/v2/override_values_controller_test.rb +169 -0
  184. data/test/controllers/foreman_puppet/api/v2/puppetclasses_controller_test.rb +144 -0
  185. data/test/controllers/foreman_puppet/api/v2/smart_class_parameters_controller_test.rb +557 -0
  186. data/test/controllers/foreman_puppet/api/v2/template_combinations_controller_test.rb +81 -0
  187. data/test/controllers/foreman_puppet/config_groups_controller_test.rb +47 -0
  188. data/test/controllers/foreman_puppet/environments_controller_test.rb +230 -0
  189. data/test/controllers/foreman_puppet/hostgroups_controller_test.rb +72 -0
  190. data/test/controllers/foreman_puppet/hosts_controller_test.rb +346 -0
  191. data/test/controllers/foreman_puppet/puppet_smart_proxies_controller_test.rb +29 -0
  192. data/test/controllers/foreman_puppet/puppetclass_lookup_keys_controller_test.rb +59 -0
  193. data/test/controllers/foreman_puppet/puppetclasses_controller_test.rb +235 -0
  194. data/test/controllers/provisioning_templates_controller_test.rb +70 -0
  195. data/test/factories/foreman_puppet_factories.rb +134 -0
  196. data/test/factories/host_puppet_enhancements.rb +61 -0
  197. data/test/factories/proxy_puppet_enhancements.rb +33 -0
  198. data/test/helpers/foreman_puppet/hosts_and_hostgroups_helper_test.rb +65 -0
  199. data/test/helpers/foreman_puppet/puppetclasses_helper_test.rb +33 -0
  200. data/test/integration/foreman_puppet/environment_js_test.rb +27 -0
  201. data/test/integration/foreman_puppet/host_js_test.rb +371 -0
  202. data/test/integration/foreman_puppet/hostgroup_js_test.rb +100 -0
  203. data/test/integration/foreman_puppet/puppetclass_js_test.rb +37 -0
  204. data/test/integration/foreman_puppet/smartclass_parameter_js_test.rb +84 -0
  205. data/test/models/foreman_puppet/config_group_class_test.rb +9 -0
  206. data/test/models/foreman_puppet/config_group_test.rb +8 -0
  207. data/test/models/foreman_puppet/environment_test.rb +92 -0
  208. data/test/models/foreman_puppet/host_config_group_test.rb +39 -0
  209. data/test/models/foreman_puppet/host_puppet_facet_test.rb +116 -0
  210. data/test/models/foreman_puppet/host_test.rb +288 -0
  211. data/test/models/foreman_puppet/hostgroup_puppet_facet_test.rb +200 -0
  212. data/test/models/foreman_puppet/hostgroup_test.rb +14 -0
  213. data/test/models/foreman_puppet/lookup_value_test.rb +69 -0
  214. data/test/models/foreman_puppet/provisioning_template_test.rb +124 -0
  215. data/test/models/foreman_puppet/puppetclass_lookup_key_test.rb +81 -0
  216. data/test/models/foreman_puppet/puppetclass_test.rb +144 -0
  217. data/test/models/foreman_puppet/smart_proxy_test.rb +28 -0
  218. data/test/qraphql/queries/host_puppet_query_test.rb +36 -0
  219. data/test/qraphql/queries/hostgroup_puppet_query_test.rb +36 -0
  220. data/test/services/foreman_puppet/host_info_providers/puppet_info_test.rb +791 -0
  221. data/test/services/foreman_puppet/input_type/puppet_parameter_input_test.rb +14 -0
  222. data/test/test_puppet_helper.rb +30 -0
  223. data/test/unit/foreman_puppet/access_permissions_test.rb +16 -0
  224. data/test/unit/foreman_puppet/puppet_class_importer_test.rb +247 -0
  225. data/test/unit/foreman_puppet/template_rendering_test.rb +20 -0
  226. data/test/unit/foreman_puppet_test.rb +11 -0
  227. data/webpack/__mocks__/foremanReact/common/I18n.js +7 -0
  228. data/webpack/__mocks__/foremanReact/components/Layout/LayoutActions.js +2 -0
  229. data/webpack/__mocks__/foremanReact/readme.md +11 -0
  230. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +10 -0
  231. data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
  232. data/webpack/__mocks__/foremanReact/redux/actions/toasts.js +8 -0
  233. data/webpack/__mocks__/foremanReact/redux/index.js +1 -0
  234. data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js +5 -0
  235. data/webpack/fills_index.js +30 -0
  236. data/webpack/index.js +18 -0
  237. data/webpack/src/ForemanPuppet.js +11 -0
  238. data/webpack/src/Router/__snapshots__/routes.test.js.snap +3 -0
  239. data/webpack/src/Router/index.js +14 -0
  240. data/webpack/src/Router/routes.js +3 -0
  241. data/webpack/src/Router/routes.test.js +16 -0
  242. data/webpack/src/foreman_class_edit.js +224 -0
  243. data/webpack/src/foreman_puppet_host_form.js +140 -0
  244. data/webpack/src/foreman_puppet_host_form.test.js +65 -0
  245. data/webpack/src/index.js +1 -0
  246. data/webpack/src/reducers.js +7 -0
  247. metadata +340 -0
@@ -0,0 +1,81 @@
1
+ require 'test_puppet_helper'
2
+
3
+ module ForemanPuppet
4
+ module Api
5
+ module V2
6
+ class TemplateCombinationsControllerTest < ActionController::TestCase
7
+ tests ::Api::V2::TemplateCombinationsController
8
+
9
+ let(:environment) { FactoryBot.create(:environment) }
10
+ let(:template_combination) { FactoryBot.create(:template_combination) }
11
+
12
+ test 'should get index by environment' do
13
+ FactoryBot.create(:template_combination, environment: template_combination.environment)
14
+ get :index, params: { environment_id: template_combination.environment.to_param }
15
+ json_response = ActiveSupport::JSON.decode(@response.body)
16
+ assert_equal 2, json_response['results'].size, 'Should contain template_combinations in the response'
17
+ assert_response :success
18
+ end
19
+
20
+ context 'with provisioning_template_id' do
21
+ setup do
22
+ Foreman::Deprecation.stubs(:api_deprecation_warning).never
23
+ end
24
+
25
+ test 'should get index' do
26
+ FactoryBot.create(:template_combination, provisioning_template: template_combination.provisioning_template)
27
+ get :index, params: { provisioning_template_id: template_combination.provisioning_template.id }
28
+ json_response = ActiveSupport::JSON.decode(@response.body)
29
+ assert_equal 2, json_response['results'].size, 'Should contain template_combinations in the response'
30
+ assert_response :success
31
+ end
32
+
33
+ test 'should get template combination for template' do
34
+ get :show, params: { provisioning_template_id: template_combination.provisioning_template.to_param, id: template_combination.id }
35
+ assert_response :success
36
+ json_response = ActiveSupport::JSON.decode(@response.body)
37
+ assert_not json_response.empty?
38
+ assert_equal json_response['provisioning_template_id'], template_combination.provisioning_template_id
39
+ end
40
+
41
+ test 'should get template combination for environment' do
42
+ get :show, params: { provisioning_template_id: template_combination.provisioning_template.to_param, id: template_combination.id }
43
+ assert_response :success
44
+ json_response = ActiveSupport::JSON.decode(@response.body)
45
+ assert_not json_response.empty?
46
+ assert_equal json_response['environment_id'], template_combination.environment_id
47
+ assert_equal json_response['environment_name'], template_combination.environment.name
48
+ end
49
+
50
+ test 'should create valid' do
51
+ as_admin do
52
+ post :create, params: { template_combination: { environment_id: environment.id, hostgroup_id: hostgroups(:unusual).id },
53
+ provisioning_template_id: template_combination.provisioning_template.id }
54
+ end
55
+ json_response = ActiveSupport::JSON.decode(@response.body)
56
+ assert_equal(json_response['environment_id'], environment.id)
57
+ assert_equal(json_response['hostgroup_id'], hostgroups(:unusual).id)
58
+ assert_equal(json_response['provisioning_template_id'], template_combination.provisioning_template.id)
59
+ assert_response :created
60
+ end
61
+
62
+ test 'should update template combination' do
63
+ put :update, params: { template_combination: { environment_id: environment.id, hostgroup_id: hostgroups(:common).id },
64
+ environment_id: template_combination.environment.id, id: template_combination.id }
65
+
66
+ json_response = ActiveSupport::JSON.decode(@response.body)
67
+ assert_equal(json_response['environment_id'], environment.id)
68
+ assert_equal(json_response['hostgroup_id'], hostgroups(:common).id)
69
+ assert_response :success
70
+ end
71
+
72
+ test 'should destroy' do
73
+ delete :destroy, params: { id: template_combination.id }
74
+ assert_response :ok
75
+ assert_not TemplateCombination.exists?(template_combination.id)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,47 @@
1
+ require 'test_puppet_helper'
2
+
3
+ module ForemanPuppet
4
+ class ConfigGroupsControllerTest < ActionController::TestCase
5
+ setup do
6
+ @routes = ForemanPuppet::Engine.routes
7
+ end
8
+
9
+ basic_pagination_per_page_test
10
+ basic_pagination_rendered_test
11
+
12
+ test 'should get index' do
13
+ get :index, session: set_session_user
14
+ assert_response :success
15
+ assert_not_empty assigns(:config_groups)
16
+ end
17
+
18
+ test 'should get new' do
19
+ get :new, session: set_session_user
20
+ assert_response :success
21
+ end
22
+
23
+ test 'should create config_group' do
24
+ assert_difference('ForemanPuppet::ConfigGroup.count') do
25
+ post :create, params: { config_group: { name: 'Custom Dev Group' } }, session: set_session_user
26
+ end
27
+ assert_redirected_to config_groups_path
28
+ end
29
+
30
+ test 'should get edit' do
31
+ get :edit, params: { id: config_groups(:one) }, session: set_session_user
32
+ assert_response :success
33
+ end
34
+
35
+ test 'should update config_group' do
36
+ put :update, params: { id: config_groups(:one), config_group: { name: 'new name' } }, session: set_session_user
37
+ assert_redirected_to config_groups_path
38
+ end
39
+
40
+ test 'should destroy config_group' do
41
+ assert_difference('ForemanPuppet::ConfigGroup.count', -1) do
42
+ delete :destroy, params: { id: config_groups(:three) }, session: set_session_user
43
+ end
44
+ assert_redirected_to config_groups_path
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,230 @@
1
+ require 'test_puppet_helper'
2
+
3
+ module ForemanPuppet
4
+ class EnvironmentsControllerTest < ActionController::TestCase
5
+ setup do
6
+ @routes = ForemanPuppet::Engine.routes
7
+ @model = FactoryBot.create(:environment)
8
+ end
9
+
10
+ basic_index_test(:environments)
11
+ basic_new_test
12
+ basic_edit_test(:environment)
13
+ basic_pagination_per_page_test
14
+ basic_pagination_rendered_test
15
+
16
+ test 'should create new environment' do
17
+ assert_difference -> { ForemanPuppet::Environment.unscoped.count } do
18
+ post :create, params: { commit: 'Create', environment: { name: 'some_environment' } }, session: set_session_user
19
+ end
20
+ assert_redirected_to environments_path
21
+ end
22
+
23
+ test 'should update environment' do
24
+ setup_users
25
+ environment = Environment.new name: 'some_environment'
26
+ assert environment.save!
27
+
28
+ put :update, params: { commit: 'Update', id: environment.name, environment: { name: 'other_environment' } }, session: set_session_user
29
+ env = Environment.unscoped.find(environment.id)
30
+ assert_equal('other_environment', env.name)
31
+
32
+ assert_redirected_to environments_path
33
+ end
34
+
35
+ test 'should destroy environment' do
36
+ setup_users
37
+ environment = Environment.new name: 'some_environment'
38
+ assert environment.save!
39
+
40
+ assert_difference('Environment.unscoped.count', -1) do
41
+ delete :destroy, params: { id: environment.name }, session: set_session_user
42
+ end
43
+
44
+ assert_redirected_to environments_path
45
+ end
46
+
47
+ describe 'environments import' do
48
+ let(:puppet_proxy) { FactoryBot.create(:puppet_smart_proxy) }
49
+
50
+ test 'should import as admin when organization changed' do
51
+ setup_import_classes
52
+ Organization.current = taxonomies(:organization2)
53
+ post :obsolete_and_new, params:
54
+ { 'changed' =>
55
+ { 'new' =>
56
+ { 'env1' => '{"a":{"new":{}}}' } } }, session: set_session_user
57
+ assert_redirected_to environments_url
58
+ end
59
+
60
+ test 'should handle disk environment containing additional classes' do
61
+ setup_import_classes
62
+ Environment.find_by(name: 'env1').puppetclasses.delete(Puppetclass.find_by(name: 'a'))
63
+ # db_tree of {"env1" => ["b", "c"], "env2" => ["a", "b", "c"]}
64
+ # disk_tree of {"env1" => ["a", "b", "c"],"env2" => ["a", "b", "c"]}
65
+ get :import_environments, params: { proxy: puppet_proxy }, session: set_session_user
66
+ assert_template 'common/_puppetclasses_or_envs_changed'
67
+ assert_select 'input#changed_new_env1'
68
+ post :obsolete_and_new, params:
69
+ { 'changed' =>
70
+ { 'new' =>
71
+ { 'env1' => '{"a":{"new":{}}}' } } }, session: set_session_user
72
+ assert_redirected_to environments_url
73
+ assert_equal 'Successfully updated environments and Puppet classes from the on-disk Puppet installation', flash[:success]
74
+ assert_equal %w[a b c],
75
+ Environment.unscoped.find_by(name: 'env1').puppetclasses.map(&:name).sort
76
+ end
77
+
78
+ test 'should handle disk environment containing less classes' do
79
+ setup_import_classes
80
+ as_admin { Puppetclass.create(name: 'd') }
81
+ Environment.find_by(name: 'env1').puppetclasses << Puppetclass.find_by(name: 'd')
82
+ # db_tree of {"env1" => ["a", "b", "c", "d"], "env2" => ["a", "b", "c"]}
83
+ # disk_tree of {"env1" => ["a", "b", "c"], "env2" => ["a", "b", "c"]}
84
+ get :import_environments, params: { proxy: puppet_proxy }, session: set_session_user
85
+ assert_template 'common/_puppetclasses_or_envs_changed'
86
+ assert_select 'input#changed_obsolete_env1[value*="d"]'
87
+ post :obsolete_and_new,
88
+ params: { 'changed' =>
89
+ { 'obsolete' =>
90
+ { 'env1' => '["d"]' } } }, session: set_session_user
91
+ assert_redirected_to environments_url
92
+ assert_equal 'Successfully updated environments and Puppet classes from the on-disk Puppet installation', flash[:success]
93
+ envs = Environment.unscoped.find_by(name: 'env1').puppetclasses.map(&:name).sort
94
+ assert_equal %w[a b c], envs
95
+ end
96
+ test 'should handle disk environment containing less environments' do
97
+ setup_import_classes
98
+ as_admin { Environment.create(name: 'env3') }
99
+ # db_tree of {"env1" => ["a", "b", "c"], "env2" => ["a", "b", "c"], "env3" => []}
100
+ # disk_tree of {"env1" => ["a", "b", "c"], "env2" => ["a", "b", "c"]}
101
+ get :import_environments, params: { proxy: puppet_proxy.id }, session: set_session_user
102
+ assert_template 'common/_puppetclasses_or_envs_changed'
103
+ assert_select 'input#changed_obsolete_env3'
104
+ post :obsolete_and_new, params:
105
+ { 'changed' =>
106
+ { 'obsolete' =>
107
+ { 'env3' => '[]' } } }, session: set_session_user
108
+ assert_redirected_to environments_url
109
+ assert_equal 'Successfully updated environments and Puppet classes from the on-disk Puppet installation', flash[:success]
110
+ assert_equal [], Environment.unscoped.find_by(name: 'env3').puppetclasses.map(&:name).sort
111
+ end
112
+
113
+ test 'should fail to remove active environments' do
114
+ disable_orchestration
115
+ setup_import_classes
116
+ as_admin do
117
+ host = FactoryBot.create(:host)
118
+ Environment.find_by(name: 'env1').puppetclasses += [FactoryBot.create(:puppetclass)]
119
+ host.attributes = { puppet_attributes: { environment_id: Environment.find_by(name: 'env1').id } }
120
+ assert host.save!
121
+ assert_empty host.errors
122
+ assert Environment.find_by(name: 'env1').hosts.count.positive?
123
+ end
124
+
125
+ # assert_template "puppetclasses_or_envs_changed". This assertion will fail. And it should fail. See above.
126
+ post :obsolete_and_new, params:
127
+ { 'changed' =>
128
+ { 'obsolete' =>
129
+ { 'env1' => '["a","b","c","_destroy_"]' } } }, session: set_session_user
130
+ assert Environment.unscoped.find_by(name: 'env1').hosts.count.positive?
131
+ # assert flash[:error] =~ /^Failed to update the environments and puppetclasses from the on-disk puppet installation/
132
+ assert Environment.unscoped.find_by(name: 'env1')
133
+ end
134
+
135
+ test 'should obey config/ignored_environments.yml' do
136
+ @request.env['HTTP_REFERER'] = environments_url
137
+ setup_import_classes
138
+ as_admin do
139
+ Environment.create name: 'env3'
140
+ Environment.find_by(name: 'env2').destroy
141
+ end
142
+ # db_tree of {"env1" => ["a", "b", "c"], "env3" => []}
143
+ # disk_tree of {"env1" => ["a", "b", "c"], "env2" => ["a", "b", "c"]}
144
+
145
+ PuppetClassImporter.any_instance.stubs(:ignored_environments).returns(%w[env1 env2 env3])
146
+ get :import_environments, params: { proxy: puppet_proxy }, session: set_session_user
147
+
148
+ assert_equal "No changes to your environments detected\nIgnored environments: env1, env2, and env3", flash[:info]
149
+ end
150
+
151
+ test 'should obey puppet class filters in config/ignored_environments.yml' do
152
+ setup_import_classes
153
+ PuppetClassImporter.any_instance.stubs(:updated_classes_for).returns([])
154
+ PuppetClassImporter.any_instance.stubs(:removed_classes_for).returns([])
155
+
156
+ PuppetClassImporter.any_instance.stubs(:ignored_environments).returns([])
157
+ PuppetClassImporter.any_instance.stubs(:ignored_classes).returns([/^a$/])
158
+ get :import_environments, params: { proxy: puppet_proxy }, session: set_session_user
159
+
160
+ assert_equal "No changes to your environments detected\nIgnored classes in the environments: env1 and env2", flash[:info]
161
+ end
162
+
163
+ test 'it adds a warning when boolean keys are found' do
164
+ setup_import_classes
165
+ PuppetClassImporter.any_instance.stubs(:ignored_environments).returns([true])
166
+
167
+ get :import_environments, params: { proxy: puppet_proxy }, session: set_session_user
168
+ assert_equal 'Ignored environment names resulting in booleans found. Please quote strings like true/false and yes/no in config/ignored_environments.yml', flash[:warning]
169
+ end
170
+
171
+ test 'user with viewer rights should fail to edit an environment' do
172
+ setup_user
173
+ get :edit, params: { id: environments(:production).name }, session: set_session_user.merge(user: users(:one).id)
174
+ assert_equal(403, @response.status)
175
+ end
176
+
177
+ test 'user with viewer rights should succeed in viewing environments' do
178
+ setup_user
179
+ get :index, session: set_session_user
180
+ assert_response :success
181
+ end
182
+
183
+ test "should accept environment with name 'name'" do
184
+ @request.env['HTTP_REFERER'] = environments_url
185
+ ProxyAPI::Puppet.any_instance.stubs(:environments).returns(['new'])
186
+ post :obsolete_and_new, params:
187
+ { 'changed' =>
188
+ { 'new' =>
189
+ { 'new' => '{"a":{"new":{}}}' } } }, session: set_session_user
190
+ assert_includes(Environment.unscoped.all.map(&:name), 'new', 'Should include environment with name "new"')
191
+ end
192
+
193
+ private
194
+
195
+ def setup_import_classes
196
+ as_admin do
197
+ Host::Managed.all.each { |h| h.update(environment_id: nil) }
198
+ Hostgroup.all.each { |h| h.update(environment_id: nil) }
199
+ Puppetclass.destroy_all
200
+ Environment.destroy_all
201
+ end
202
+ @request.env['HTTP_REFERER'] = environments_url
203
+ # This is the database status
204
+ # and should result in a db_tree of {"env1" => ["a", "b", "c"], "env2" => ["a", "b", "c"]}
205
+ orgs = [taxonomies(:organization1)]
206
+ locs = [taxonomies(:location1)]
207
+ as_admin do
208
+ klasses = %w[a b c].map { |name| FactoryBot.create :puppetclass, name: name }
209
+ %w[env1 env2].each do |name|
210
+ env = FactoryBot.create :environment, name: name, organizations: orgs, locations: locs
211
+ env.puppetclasses += klasses
212
+ end
213
+ end
214
+ # This is the on-disk status
215
+ # and should result in a disk_tree of {"env1" => ["a", "b", "c"],"env2" => ["a", "b", "c"]}
216
+ envs = HashWithIndifferentAccess.new(env1: %w[a b c], env2: %w[a b c])
217
+ pcs = [HashWithIndifferentAccess.new('a' => { 'name' => 'a', 'module' => '', 'params' => {} })]
218
+ classes = Hash[pcs.map { |k| [k.keys.first, Foreman::ImporterPuppetclass.new(k.values.first)] }]
219
+ Environment.expects(:puppetEnvs).returns(envs).at_least(0)
220
+ ProxyAPI::Puppet.any_instance.stubs(:environments).returns(%w[env1 env2])
221
+ ProxyAPI::Puppet.any_instance.stubs(:classes).returns(classes)
222
+ end
223
+ end
224
+
225
+ def setup_user
226
+ @request.session[:user] = users(:one).id
227
+ users(:one).roles = [Role.default, Role.find_by(name: 'Viewer')]
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,72 @@
1
+ require 'test_puppet_helper'
2
+
3
+ module ForemanPuppet
4
+ class HostgroupsControllerTest < ActionController::TestCase
5
+ tests ::HostgroupsController
6
+
7
+ setup do
8
+ @routes = ForemanPuppet::Engine.routes
9
+ end
10
+
11
+ describe '#environment_selected' do
12
+ setup do
13
+ @environment = FactoryBot.create(:environment)
14
+ @puppetclass = FactoryBot.create(:puppetclass)
15
+ @hostgroup = FactoryBot.create(:hostgroup, :with_puppet_enc, environment: @environment)
16
+ @params = {
17
+ id: @hostgroup.id,
18
+ hostgroup: {
19
+ name: @hostgroup.name,
20
+ environment_id: '',
21
+ puppetclass_ids: [@puppetclass.id],
22
+ },
23
+ }
24
+ end
25
+
26
+ test 'should return the selected puppet classes on environment change' do
27
+ assert_equal 0, @hostgroup.puppet.puppetclasses.length
28
+
29
+ post :environment_selected, params: @params, session: set_session_user, xhr: true
30
+ assert_equal(1, assigns(:hostgroup).puppet.puppetclasses.length)
31
+ assert_include assigns(:hostgroup).puppet.puppetclasses, @puppetclass
32
+ end
33
+
34
+ context 'environment_id param is set' do
35
+ test 'it will take the hostgroup params environment_id' do
36
+ other_environment = FactoryBot.create(:environment)
37
+ @params[:hostgroup][:environment_id] = other_environment.id
38
+
39
+ post :environment_selected, params: @params, session: set_session_user, xhr: true
40
+ assert_equal assigns(:environment), other_environment
41
+ end
42
+ end
43
+
44
+ test 'should not escape lookup values on environment change' do
45
+ hostgroup = FactoryBot.create(:hostgroup, :with_puppet_enc, environment: @environment, puppetclasses: [@puppetclass])
46
+ lookup_key = FactoryBot.create(:puppetclass_lookup_key, :array, default_value: %w[a b],
47
+ override: true,
48
+ puppetclass: @puppetclass,
49
+ overrides: { "hostgroup=#{hostgroup.name}" => %w[c d] })
50
+ lookup_value = lookup_key.lookup_values.first
51
+ FactoryBot.create(:environment_class, puppetclass: @puppetclass, environment: @environment, puppetclass_lookup_key: lookup_key)
52
+
53
+ # sending exactly what the host form would send which is lookup_value.value_before_type_cast
54
+ lk = { 'lookup_values_attributes' => { lookup_key.id.to_s => { 'value' => lookup_value.value_before_type_cast,
55
+ 'id' => lookup_value.id,
56
+ 'lookup_key_id' => lookup_key.id,
57
+ '_destroy' => false } } }
58
+
59
+ params = {
60
+ hostgroup_id: hostgroup.id,
61
+ hostgroup: hostgroup.attributes.merge(lk),
62
+ }
63
+
64
+ # environment change calls puppetclass_parameters which caused the extra escaping
65
+ post :puppetclass_parameters, params: params, session: set_session_user, xhr: true
66
+
67
+ # if this was escaped during refresh_host the value in response.body after unescapeHTML would include "[\\\"c\\\",\\\"d\\\"]"
68
+ assert_includes CGI.unescapeHTML(response.body), '["c","d"]'
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,346 @@
1
+ require 'test_puppet_helper'
2
+
3
+ module ForemanPuppet
4
+ class HostsControllerTest < ActionController::TestCase
5
+ tests ::HostsController
6
+
7
+ setup do
8
+ @routes = ForemanPuppet::Engine.routes
9
+ as_admin do
10
+ host1
11
+ host2
12
+ end
13
+ end
14
+
15
+ let(:org) { users(:one).organizations.first }
16
+ let(:loc) { users(:one).locations.first }
17
+ let(:environment1) { FactoryBot.create(:environment, organizations: [org], locations: [loc]) }
18
+ let(:environment2) { FactoryBot.create(:environment, organizations: [org], locations: [loc]) }
19
+ let(:hostgroup) { FactoryBot.create(:hostgroup, :with_puppet_enc, environment: environment2, organizations: [org], locations: [loc]) }
20
+ let(:host_defaults) { { hostgroup: hostgroup, environment: environment1, organization: org, location: loc } }
21
+ let(:host1) { FactoryBot.create(:host, :with_puppet_enc, :with_puppetclass, host_defaults) }
22
+ let(:host2) { FactoryBot.create(:host, :with_puppet_enc, :with_puppetclass, host_defaults) }
23
+
24
+ test 'user with edit host rights with update environments should change environments' do
25
+ @request.env['HTTP_REFERER'] = '/hosts'
26
+ setup_user 'edit', 'hosts'
27
+
28
+ post :update_multiple_environment, params: { host_ids: [host1.id, host2.id],
29
+ environment: { id: environment2.id } },
30
+ session: set_session_user(:one)
31
+ assert_equal environment2.id, host1.reload.puppet.environment_id
32
+ assert_equal environment2.id, host2.reload.puppet.environment_id
33
+ assert_equal 'Updated hosts: changed environment', flash[:success]
34
+ end
35
+
36
+ test 'should inherit the hostgroup environment if *inherit from hostgroup* selected' do
37
+ @request.env['HTTP_REFERER'] = '/hosts'
38
+ setup_user 'edit', 'hosts'
39
+
40
+ params = { host_ids: [host1.id, host2.id], environment: { id: 'inherit' } }
41
+ post :update_multiple_environment, params: params, session: set_session_user(:one)
42
+
43
+ assert_equal hostgroup.puppet.environment_id, host1.reload.puppet.environment_id
44
+ assert_equal hostgroup.puppet.environment_id, host2.reload.puppet.environment_id
45
+ end
46
+
47
+ describe '#edit' do
48
+ setup { @routes = Rails.application.routes }
49
+
50
+ test 'lookup value and description should be html escaped' do
51
+ skip 'Needs complete migration to be done' unless ForemanPuppet.extracted_from_core?
52
+ FactoryBot.create(:puppetclass_lookup_key,
53
+ default_value: "<script>alert('hacked!');</script>",
54
+ description: "<script>alert('hacked!');</script>",
55
+ puppetclass: host1.puppet.puppetclasses.first)
56
+ get :edit, params: { id: host1.to_param }, session: set_session_user
57
+ assert_not response.body.include?('<script>alert(')
58
+ assert_includes response.body, '&lt;script&gt;alert('
59
+ assert_equal 2, response.body.scan('&lt;script&gt;alert(').count
60
+ end
61
+ end
62
+
63
+ describe '#hostgroup_or_environment_selected' do
64
+ let(:hostgroup) { FactoryBot.create(:hostgroup, :with_puppet_enc, organizations: [org], locations: [loc]) }
65
+
66
+ test 'choosing only one of hostgroup or environment renders classes' do
67
+ post :hostgroup_or_environment_selected, params: {
68
+ host_id: nil,
69
+ host: {
70
+ puppet_attributes: {
71
+ environment_id: environment1.id,
72
+ },
73
+ },
74
+ }, session: set_session_user, xhr: true
75
+ assert_response :success
76
+ assert_template partial: 'hosts/_form_puppet_enc_tab'
77
+ end
78
+
79
+ test 'choosing both hostgroup and environment renders classes' do
80
+ post :hostgroup_or_environment_selected, params: {
81
+ host_id: host1.id,
82
+ host: {
83
+ hostgroup_id: hostgroup.id,
84
+ puppet_attributes: {
85
+ environment_id: environment1.id,
86
+ },
87
+ },
88
+ }, session: set_session_user, xhr: true
89
+ assert_response :success
90
+ assert_template partial: 'hosts/_form_puppet_enc_tab'
91
+ end
92
+
93
+ test 'should not escape lookup values on environment change' do
94
+ host = FactoryBot.create(:host, :with_puppet_enc, :with_puppetclass)
95
+
96
+ host.environment.locations = [host.location]
97
+ host.environment.organizations = [host.organization]
98
+
99
+ lookup_key = FactoryBot.create(:puppetclass_lookup_key, :array, default_value: %w[a b],
100
+ override: true,
101
+ puppetclass: host.puppet.puppetclasses.first,
102
+ overrides: { "fqdn=#{host.fqdn}" => %w[c d] })
103
+ lookup_value = lookup_key.lookup_values.first
104
+
105
+ # sending exactly what the host form would send which is lookup_value.value_before_type_cast
106
+ lk_params = { 'lookup_values_attributes' => { lookup_key.id.to_s => { 'value' => lookup_value.value_before_type_cast,
107
+ 'id' => lookup_value.id,
108
+ 'lookup_key_id' => lookup_key.id,
109
+ '_destroy' => false } } }
110
+ params = {
111
+ host_id: host.id,
112
+ host: host.attributes.merge(lk_params),
113
+ }
114
+
115
+ # environment change calls puppetclass_parameters which caused the extra escaping
116
+ post :puppetclass_parameters, params: params, session: set_session_user, xhr: true
117
+
118
+ # if this was escaped during refresh_host the value in response.body after unescapeHTML would include "[\\\"c\\\",\\\"d\\\"]"
119
+ assert_includes CGI.unescapeHTML(response.body), '["c","d"]'
120
+ end
121
+ end
122
+
123
+ describe 'setting puppet proxy on multiple hosts' do
124
+ test 'should change the puppet proxy' do
125
+ proxy = FactoryBot.create(:puppet_smart_proxy)
126
+
127
+ @request.env['HTTP_REFERER'] = '/hosts'
128
+ params = { host_ids: [host1.id, host2.id], proxy: { proxy_id: proxy.id } }
129
+
130
+ setup_user 'edit', 'hosts'
131
+ post :update_multiple_puppet_proxy, params: params, session: set_session_user(:one)
132
+
133
+ assert_empty flash[:error]
134
+
135
+ set_admin
136
+ [host1, host2].each do |host|
137
+ assert_equal proxy, host.reload.puppet_proxy
138
+ end
139
+ end
140
+
141
+ test 'should clear the puppet proxy of multiple hosts' do
142
+ @request.env['HTTP_REFERER'] = '/hosts'
143
+
144
+ params = { host_ids: [host1.id, host2.id], proxy: { proxy_id: '' } }
145
+
146
+ setup_user 'edit', 'hosts'
147
+ post :update_multiple_puppet_proxy, params: params, session: set_session_user(:one)
148
+
149
+ assert_empty flash[:error]
150
+
151
+ set_admin
152
+ [host1, host2].each do |host|
153
+ assert_nil host.reload.puppet_proxy
154
+ end
155
+ end
156
+ end
157
+
158
+ describe '#externalNodes' do
159
+ test 'externalNodes should render YAML hashes correctly' do
160
+ HostInfoProviders::PuppetInfo.any_instance.expects(:classes_info_hash).returns(
161
+ 'dhcp' => {
162
+ 'bootfiles' => [
163
+ { 'name' => 'foo', 'mount_point' => '/bar' }.with_indifferent_access,
164
+ { 'name' => 'john', 'mount_point' => '/doe' }.with_indifferent_access,
165
+ ],
166
+ }
167
+ ).at_least_once
168
+
169
+ get :externalNodes, params: { name: host1.name, format: 'yml' }, session: set_session_user
170
+ assert_response :success
171
+ enc = nil
172
+ as_admin { enc = host1.info.deep_stringify_keys.to_yaml }
173
+ assert_equal enc, response.body
174
+ end
175
+
176
+ test 'externalNodes should render correctly when format text/html is given' do
177
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
178
+ get :externalNodes, params: { name: host1.name }, session: set_session_user
179
+ assert_response :success
180
+ as_admin { @enc = host1.info.to_yaml }
181
+ assert_equal "<pre>#{ERB::Util.html_escape(@enc)}</pre>", response.body
182
+ end
183
+
184
+ test 'externalNodes should render yml request correctly' do
185
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
186
+ get :externalNodes, params: { name: host1.name, format: 'yml' }, session: set_session_user
187
+ assert_response :success
188
+ as_admin { @enc = host1.info.deep_stringify_keys.to_yaml(line_width: -1) }
189
+ assert_equal @enc, response.body
190
+ end
191
+
192
+ test 'when ":restrict_registered_smart_proxies" is false, HTTP requests should be able to get externalNodes' do
193
+ User.current = nil
194
+ Setting[:restrict_registered_smart_proxies] = false
195
+ SETTINGS[:require_ssl] = false
196
+
197
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
198
+ get :externalNodes, params: { name: host1.name, format: 'yml' }
199
+ assert_response :success
200
+ end
201
+
202
+ test 'hosts with a registered smart proxy on should get externalNodes successfully' do
203
+ User.current = nil
204
+ Setting[:restrict_registered_smart_proxies] = true
205
+ Setting[:require_ssl_smart_proxies] = false
206
+
207
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
208
+ get :externalNodes, params: { name: host1.name, format: 'yml' }
209
+ assert_response :success
210
+ end
211
+
212
+ test 'hosts without a registered smart proxy on should not be able to get externalNodes' do
213
+ User.current = nil
214
+ Setting[:restrict_registered_smart_proxies] = true
215
+ Setting[:require_ssl_smart_proxies] = false
216
+
217
+ Resolv.any_instance.stubs(:getnames).returns(['another.host'])
218
+ get :externalNodes, params: { name: host1.name, format: 'yml' }
219
+ assert_equal 403, @response.status
220
+ end
221
+
222
+ test 'hosts with a registered smart proxy and SSL cert should get externalNodes successfully' do
223
+ User.current = nil
224
+ Setting[:restrict_registered_smart_proxies] = true
225
+ Setting[:require_ssl_smart_proxies] = true
226
+
227
+ @request.env['HTTPS'] = 'on'
228
+ @request.env['SSL_CLIENT_S_DN'] = 'CN=else.where'
229
+ @request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
230
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
231
+ get :externalNodes, params: { name: host1.name, format: 'yml' }
232
+ assert_response :success
233
+ end
234
+
235
+ test 'hosts in trusted hosts list and SSL cert should get externalNodes successfully' do
236
+ User.current = nil
237
+ Setting[:restrict_registered_smart_proxies] = true
238
+ Setting[:require_ssl_smart_proxies] = true
239
+ Setting[:trusted_hosts] = ['else.where']
240
+
241
+ @request.env['HTTPS'] = 'on'
242
+ @request.env['SSL_CLIENT_S_DN'] = 'CN=else.where'
243
+ @request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
244
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
245
+ get :externalNodes, params: { name: host1.name, format: 'yml' }
246
+ assert_response :success
247
+ end
248
+
249
+ test 'hosts with comma-separated SSL DN should get externalNodes successfully' do
250
+ User.current = nil
251
+ Setting[:restrict_registered_smart_proxies] = true
252
+ Setting[:require_ssl_smart_proxies] = true
253
+ Setting[:trusted_hosts] = ['foreman.example']
254
+
255
+ @request.env['HTTPS'] = 'on'
256
+ @request.env['SSL_CLIENT_S_DN'] = 'CN=foreman.example,OU=PUPPET,O=FOREMAN,ST=North Carolina,C=US'
257
+ @request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
258
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
259
+ get :externalNodes, params: { name: host1.name, format: 'yml' }
260
+ assert_response :success
261
+ end
262
+
263
+ test 'hosts with slash-separated SSL DN should get externalNodes successfully' do
264
+ User.current = nil
265
+ Setting[:restrict_registered_smart_proxies] = true
266
+ Setting[:require_ssl_smart_proxies] = true
267
+ Setting[:trusted_hosts] = ['foreman.linux.lab.local']
268
+
269
+ @request.env['HTTPS'] = 'on'
270
+ @request.env['SSL_CLIENT_S_DN'] = '/C=US/ST=NC/L=City/O=Example/OU=IT/CN=foreman.linux.lab.local/emailAddress=user@example.com'
271
+ @request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
272
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
273
+ get :externalNodes, params: { name: host1.name, format: 'yml' }
274
+ assert_response :success
275
+ end
276
+
277
+ test 'hosts without a registered smart proxy but with an SSL cert should not be able to get externalNodes' do
278
+ User.current = nil
279
+ Setting[:restrict_registered_smart_proxies] = true
280
+ Setting[:require_ssl_smart_proxies] = true
281
+
282
+ @request.env['HTTPS'] = 'on'
283
+ @request.env['SSL_CLIENT_S_DN'] = 'CN=another.host'
284
+ @request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
285
+ get :externalNodes, params: { name: host1.name, format: 'yml' }
286
+ assert_equal 403, @response.status
287
+ end
288
+
289
+ test 'hosts with an unverified SSL cert should not be able to get externalNodes' do
290
+ User.current = nil
291
+ Setting[:restrict_registered_smart_proxies] = true
292
+ Setting[:require_ssl_smart_proxies] = true
293
+
294
+ @request.env['HTTPS'] = 'on'
295
+ @request.env['SSL_CLIENT_S_DN'] = 'CN=else.where'
296
+ @request.env['SSL_CLIENT_VERIFY'] = 'FAILURE'
297
+ get :externalNodes, params: { name: host1.name, format: 'yml' }
298
+ assert_equal 403, @response.status
299
+ end
300
+
301
+ test 'when "require_ssl_smart_proxies" and "require_ssl" are true, HTTP requests should not be able to get externalNodes' do
302
+ User.current = nil
303
+ Setting[:restrict_registered_smart_proxies] = true
304
+ Setting[:require_ssl_smart_proxies] = true
305
+ SETTINGS[:require_ssl] = true
306
+
307
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
308
+ get :externalNodes, params: { name: host1.name, format: 'yml' }
309
+ assert_equal 403, @response.status
310
+ end
311
+
312
+ test 'when "require_ssl_smart_proxies" is true and "require_ssl" is false, HTTP requests should be able to get externalNodes' do
313
+ User.current = nil
314
+ # since require_ssl_smart_proxies is only applicable to HTTPS connections, both should be set
315
+ Setting[:restrict_registered_smart_proxies] = true
316
+ Setting[:require_ssl_smart_proxies] = true
317
+ SETTINGS[:require_ssl] = false
318
+
319
+ Resolv.any_instance.stubs(:getnames).returns(['else.where'])
320
+ get :externalNodes, params: { name: host1.name, format: 'yml' }
321
+ assert_response :success
322
+ end
323
+
324
+ test 'authenticated users over HTTP should be able to get externalNodes' do
325
+ Setting[:restrict_registered_smart_proxies] = true
326
+ Setting[:require_ssl_smart_proxies] = true
327
+ SETTINGS[:require_ssl] = false
328
+
329
+ Resolv.any_instance.stubs(:getnames).returns(['users.host'])
330
+ get :externalNodes, params: { name: host1.name, format: 'yml' }, session: set_session_user
331
+ assert_response :success
332
+ end
333
+
334
+ test 'authenticated users over HTTPS should be able to get externalNodes' do
335
+ Setting[:restrict_registered_smart_proxies] = true
336
+ Setting[:require_ssl_smart_proxies] = true
337
+ SETTINGS[:require_ssl] = false
338
+
339
+ Resolv.any_instance.stubs(:getnames).returns(['users.host'])
340
+ @request.env['HTTPS'] = 'on'
341
+ get :externalNodes, params: { name: host1.name, format: 'yml' }, session: set_session_user
342
+ assert_response :success
343
+ end
344
+ end
345
+ end
346
+ end