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,132 @@
1
+ module ForemanPuppet
2
+ class Puppetclass < ApplicationRecord
3
+ self.table_name = 'puppetclasses'
4
+
5
+ audited
6
+ include Authorizable
7
+ include ScopedSearchExtensions
8
+ extend FriendlyId
9
+ friendly_id :name
10
+ include Parameterizable::ByIdName
11
+
12
+ validates_lengths_from_database
13
+ before_destroy EnsureNotUsedBy.new(:hosts, :hostgroups)
14
+ has_many :environment_classes, dependent: :destroy, inverse_of: :puppetclass
15
+ has_many :environments, -> { distinct }, through: :environment_classes
16
+ has_many :organizations, -> { distinct.reorder(nil) }, through: :environments
17
+ has_many :locations, -> { distinct.reorder(nil) }, through: :environments
18
+
19
+ # rubocop:disable Rails/HasAndBelongsToMany
20
+ has_and_belongs_to_many :operatingsystems
21
+ # rubocop:enable Rails/HasAndBelongsToMany
22
+ has_many :hostgroup_classes, dependent: :destroy
23
+ has_many :hostgroup_puppet_facets, through: :hostgroup_classes
24
+ has_many :hostgroups, through: :hostgroup_puppet_facets
25
+ has_many :host_classes, dependent: :destroy
26
+ has_many :host_puppet_facets, through: :host_classes
27
+ has_many_hosts through: :host_puppet_facets
28
+ has_many :config_group_classes, dependent: :destroy
29
+ has_many :config_groups, through: :config_group_classes
30
+
31
+ has_many :class_params, -> { distinct }, through: :environment_classes, source: :puppetclass_lookup_key
32
+ accepts_nested_attributes_for :class_params, reject_if: ->(a) { a[:key].blank? }, allow_destroy: true
33
+
34
+ validates :name, uniqueness: true, presence: true, no_whitespace: true
35
+
36
+ alias_attribute :smart_class_parameters, :class_params
37
+ alias_attribute :smart_class_parameter_ids, :class_param_ids
38
+
39
+ default_scope -> { order(:name) }
40
+
41
+ scoped_search on: :name, complete_value: true
42
+ scoped_search relation: :environments, on: :name, complete_value: true, rename: 'environment'
43
+ scoped_search relation: :organizations, on: :name, complete_value: true, rename: 'organization', only_explicit: true
44
+ scoped_search relation: :locations, on: :name, complete_value: true, rename: 'location', only_explicit: true
45
+ scoped_search relation: :hostgroups, on: :name, complete_value: true, rename: 'hostgroup', only_explicit: true
46
+ scoped_search relation: :config_groups, on: :name, complete_value: true, rename: 'config_group', only_explicit: true
47
+ scoped_search relation: :hosts, on: :name, complete_value: true, rename: 'host', ext_method: :search_by_host, only_explicit: true
48
+ scoped_search relation: :class_params, on: :key, complete_value: true, only_explicit: true
49
+
50
+ scope :not_in_any_environment, -> { left_outer_joins(:environment_classes).where(environment_classes: { environment_id: nil }) }
51
+
52
+ # returns a hash containing modules and associated classes
53
+ def self.classes2hash(classes)
54
+ hash = {}
55
+ classes.each do |klass|
56
+ next unless (mod = klass.module_name)
57
+ hash[mod] ||= []
58
+ hash[mod] << klass
59
+ end
60
+ hash
61
+ end
62
+
63
+ # For API v2 - eliminate node :puppetclass for each object. returns a hash containing modules and associated classes
64
+ def self.classes2hash_v2(classes)
65
+ hash = {}
66
+ classes.each do |klass|
67
+ if (mod = klass.module_name)
68
+ hash[mod] ||= []
69
+ hash[mod] << { id: klass.id, name: klass.name, created_at: klass.created_at, updated_at: klass.updated_at }
70
+ end
71
+ end
72
+ hash
73
+ end
74
+
75
+ # returns module name (excluding of the class name)
76
+ # if class separator does not exists (the "::" chars), then returns the whole class name
77
+ def module_name
78
+ (i = name.index('::')) ? name[0..i - 1] : name
79
+ end
80
+
81
+ # returns class name (excluding of the module name)
82
+ def klass
83
+ name.gsub("#{module_name}::", '')
84
+ end
85
+
86
+ def all_hostgroups(with_descendants: true, unsorted: false)
87
+ hgs = Hostgroup.authorized
88
+ .left_outer_joins(puppet: [:hostgroup_classes, { config_groups: [:config_group_classes] }])
89
+ .where("#{id} IN (hostgroup_classes.puppetclass_id, config_group_classes.puppetclass_id)")
90
+ .distinct
91
+ hgs = hgs.reorder('') if unsorted
92
+ hgs = hgs.flat_map(&:subtree).uniq if with_descendants
93
+ hgs
94
+ end
95
+
96
+ def hosts_count
97
+ hostgroup_ids = all_hostgroups(unsorted: true).map(&:id)
98
+ Host::Managed.authorized
99
+ .reorder(nil)
100
+ .left_outer_joins(puppet: [:host_classes, { config_groups: [:config_group_classes] }])
101
+ .where('(? IN (host_classes.puppetclass_id, config_group_classes.puppetclass_id)) OR (hosts.hostgroup_id IN (?))', id, hostgroup_ids)
102
+ .distinct
103
+ .count
104
+ end
105
+
106
+ # We are going through two associations, so we are on our own to define modifiers
107
+ def hostgroup_ids=(hg_ids)
108
+ hg_ids = Array(hg_ids).reject(&:blank?)
109
+ hg_to_facets_ids = Hash[HostgroupPuppetFacet.where(hostgroup_id: hg_ids).pluck(:hostgroup_id, :id)]
110
+ missing_facet_ids = hg_ids.map(&:to_i) - hg_to_facets_ids.keys
111
+ new_facet_ids = missing_facet_ids.map { |hg_id| HostgroupPuppetFacet.create(hostgroup_id: hg_id).id }
112
+ self.hostgroup_puppet_facet_ids = hg_to_facets_ids.values + new_facet_ids
113
+ end
114
+
115
+ def self.search_by_host(_key, operator, value)
116
+ conditions = sanitize_sql_for_conditions(["hosts.name #{operator} ?", value_to_sql(operator, value)])
117
+ direct = Puppetclass.joins(host_puppet_facets: :host).where(conditions).pluck(:id).uniq
118
+ hostgroup = Hostgroup.joins(:hosts).find_by(conditions)
119
+ indirect = if hostgroup.blank?
120
+ []
121
+ else
122
+ HostgroupClass.joins(hostgroup_puppet_facet: :hostgroup)
123
+ .where(Hostgroup.arel_table[:id].in(hostgroup.path_ids))
124
+ .pluck(:puppetclass_id).uniq
125
+ end
126
+ return { conditions: '1=0' } if direct.blank? && indirect.blank?
127
+
128
+ puppet_classes = (direct + indirect).uniq
129
+ { conditions: "puppetclasses.id IN(#{puppet_classes.join(',')})" }
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,58 @@
1
+ module ForemanPuppet
2
+ class PuppetclassLookupKey < LookupKey
3
+ has_many :environment_classes, dependent: :destroy, inverse_of: :puppetclass_lookup_key
4
+ has_many :environments, -> { distinct }, through: :environment_classes
5
+ has_many :param_classes, through: :environment_classes, source: :puppetclass
6
+
7
+ before_validation :check_override_selected, if: -> { persisted? && @validation_context != :importer }
8
+
9
+ scoped_search relation: :param_classes, on: :name, rename: :puppetclass, aliases: [:puppetclass_name], complete_value: true
10
+ scoped_search relation: :environments, on: :name, rename: :environment, complete_value: true, only_explicit: true
11
+
12
+ scope :smart_class_parameters_for_class, lambda { |puppetclass_ids, environment_id|
13
+ joins(:environment_classes).where(environment_classes: { puppetclass_id: puppetclass_ids, environment_id: environment_id })
14
+ }
15
+
16
+ scope :parameters_for_class, lambda { |puppetclass_ids, environment_id|
17
+ override.smart_class_parameters_for_class(puppetclass_ids, environment_id)
18
+ }
19
+
20
+ scope :smart_class_parameters, -> { joins(:environment_classes).readonly(false) }
21
+
22
+ def editable_by_user?
23
+ PuppetclassLookupKey.authorized(:edit_external_parameters).exists?(id: id)
24
+ end
25
+
26
+ def param_class
27
+ param_classes.first
28
+ end
29
+
30
+ def audit_class
31
+ param_class
32
+ end
33
+
34
+ def cast_default_value
35
+ super unless omit
36
+ true
37
+ end
38
+
39
+ def validate_default_value
40
+ super unless omit
41
+ true
42
+ end
43
+
44
+ def puppet?
45
+ true
46
+ end
47
+
48
+ def check_override_selected
49
+ return if (changed - %w[description override]).empty?
50
+ return if override?
51
+ errors.add(:override, _('must be true to edit the parameter'))
52
+ end
53
+
54
+ def self.humanize_class_name
55
+ 'Smart class parameter'
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,10 @@
1
+ module ForemanPuppet
2
+ module HostInfoProviders
3
+ class ConfigGroupsInfo < HostInfo::Provider
4
+ def host_info
5
+ config_groups = (host.puppet.config_groups + host.puppet.parent_config_groups).uniq.map(&:name)
6
+ { 'parameters' => { 'foreman_config_groups' => config_groups } }
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,92 @@
1
+ module ForemanPuppet
2
+ module HostInfoProviders
3
+ class PuppetInfo < HostInfo::Provider
4
+ def host_info
5
+ # Static parameters
6
+ param = puppet_static_info
7
+ info_hash = {}
8
+ info_hash['classes'] = classes_info_hash
9
+ info_hash['parameters'] = param
10
+ info_hash['environment'] = param['foreman_env'] if Setting['enc_environment'] && param['foreman_env'].present?
11
+
12
+ info_hash
13
+ end
14
+
15
+ def puppetclass_parameters
16
+ keys = ForemanPuppet::PuppetclassLookupKey.includes(:environment_classes).parameters_for_class(host.puppet&.puppetclass_ids, host.puppet&.environment_id)
17
+ key_hash = hashed_class_keys(keys)
18
+ values = keys.values_hash(host)
19
+
20
+ klasses = {}
21
+ host.puppet.classes.each do |klass|
22
+ klasses[klass.name] = smart_class_params_for(klass, key_hash, values)
23
+ end
24
+ klasses
25
+ end
26
+
27
+ def inherited_puppetclass_parameters
28
+ keys = ForemanPuppet::PuppetclassLookupKey.includes(:environment_classes).parameters_for_class(host.puppet&.puppetclass_ids, host.puppet&.environment_id)
29
+
30
+ keys.inherited_values(host).raw
31
+ end
32
+
33
+ private
34
+
35
+ def puppet_static_info
36
+ params = {}
37
+ # maybe these should be moved to the common parameters, leaving them in for now
38
+ params['puppetmaster'] = host.puppetmaster
39
+ params['puppet_ca'] = host.puppet_ca_server if ca_defined?
40
+ params['foreman_env'] = host.puppet&.environment.to_s if has_environment?
41
+
42
+ params.merge! networking_params if Setting[:ignore_puppet_facts_for_provisioning]
43
+
44
+ params
45
+ end
46
+
47
+ def ca_defined?
48
+ SETTINGS[:unattended] && host.puppetca_exists?
49
+ end
50
+
51
+ def has_environment?
52
+ host.puppet&.environment&.name
53
+ end
54
+
55
+ def networking_params
56
+ {
57
+ 'ip' => host.ip,
58
+ 'ip6' => host.ip6,
59
+ 'mac' => host.mac,
60
+ }
61
+ end
62
+
63
+ def classes_info_hash
64
+ return [] unless has_environment?
65
+ puppetclass_parameters
66
+ end
67
+
68
+ def smart_class_params_for(klass, key_hash, values)
69
+ return nil unless key_hash[klass.id]
70
+
71
+ class_values = {}
72
+ key_hash[klass.id].each do |key|
73
+ key_value = values[key]
74
+ class_values[key.to_s] = key_value unless key_value.nil?
75
+ end
76
+
77
+ return nil if class_values == {}
78
+ class_values
79
+ end
80
+
81
+ def hashed_class_keys(keys)
82
+ h = {}
83
+ keys.each do |key|
84
+ klass_id = key.environment_classes.first.puppetclass_id
85
+ h[klass_id] ||= []
86
+ h[klass_id] << key
87
+ end
88
+ h
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,35 @@
1
+ module ForemanPuppet
2
+ module InputType
3
+ class PuppetParameterInput < ::InputType::Base
4
+ class Resolver < ::InputType::Base::Resolver
5
+ def ready?
6
+ @scope.host &&
7
+ enc_parameters.key?(@input.puppet_class_name) &&
8
+ enc_parameters[@input.puppet_class_name].is_a?(Hash) &&
9
+ enc_parameters[@input.puppet_class_name].key?(@input.puppet_parameter_name)
10
+ end
11
+
12
+ def resolved_value
13
+ enc_parameters[@input.puppet_class_name][@input.puppet_parameter_name]
14
+ end
15
+
16
+ private
17
+
18
+ def enc_parameters
19
+ @enc_parameters ||= ForemanPuppet::HostInfoProviders::PuppetInfo.new(@scope.host).puppetclass_parameters
20
+ end
21
+ end
22
+
23
+ def self.humanized_name
24
+ _('Puppet parameter')
25
+ end
26
+
27
+ attributes :puppet_class_name, :puppet_parameter_name
28
+
29
+ def validate(input)
30
+ input.errors.add(:puppet_class_name, :blank) if input.puppet_class_name.blank?
31
+ input.errors.add(:puppet_parameter_name, :blank) if input.puppet_parameter_name.blank?
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ module ForemanPuppet
2
+ module ProxyStatus
3
+ class Puppet < ::ProxyStatus::Base
4
+ def environment_stats
5
+ fetch_proxy_data do
6
+ env_counts = {}
7
+ api.environments.each { |env| env_counts[env] = api.class_count(env) }
8
+ env_counts
9
+ end
10
+ end
11
+
12
+ def self.humanized_name
13
+ 'Puppet'
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,355 @@
1
+ module ForemanPuppet
2
+ class PuppetClassImporter
3
+ CHANGE_KINDS = %w[new obsolete updated ignored].freeze
4
+
5
+ def initialize(args = {})
6
+ @foreman_classes = {}
7
+ @proxy_classes = {}
8
+ @environment = args[:env]
9
+
10
+ if args[:proxy]
11
+ @proxy = args[:proxy]
12
+ elsif args[:url]
13
+ @proxy = ProxyAPI::Puppet.new(url: args[:url])
14
+ else
15
+ url = SmartProxy.with_features('Puppet').first.try(:url)
16
+ raise ::Foreman::Exception, N_("Can't find a valid Proxy with a Puppet feature") if url.blank?
17
+ @proxy = ProxyAPI::Puppet.new(url: url)
18
+ end
19
+ end
20
+
21
+ # return changes hash, currently exists to keep compatibility with importer html
22
+ def changes
23
+ changes = CHANGE_KINDS.index_with { |_kind| {} }
24
+
25
+ if @environment.nil?
26
+ actual_environments.each do |env|
27
+ changes_for_environment(env, changes)
28
+ end
29
+
30
+ old_environments.each do |env|
31
+ changes['obsolete'][env] ||= []
32
+ changes['obsolete'][env] << '_destroy_' unless actual_environments.include?(env)
33
+ end
34
+
35
+ ignored_environments.each do |env|
36
+ changes['ignored'][env] ||= []
37
+ changes['ignored'][env] << '_ignored_'
38
+ end
39
+ else
40
+ changes_for_environment(@environment, changes)
41
+ end
42
+
43
+ changes
44
+ end
45
+
46
+ # Adds class changes of an environment to a changes hash in new, obsolete and updated
47
+ #
48
+ # Params:
49
+ # * +environment+: {String} of environments name
50
+ # * +changes+: {Hash} to add changes to
51
+ #
52
+ def changes_for_environment(environment, changes)
53
+ new_classes = new_classes_for(environment)
54
+ old_classes = removed_classes_for(environment)
55
+ updated_classes = updated_classes_for(environment)
56
+ ignored_classes = ignored_classes_for(environment)
57
+ changes['new'][environment] = new_classes if new_classes.any?
58
+ changes['obsolete'][environment] = old_classes if old_classes.any?
59
+ changes['updated'][environment] = updated_classes if updated_classes.any?
60
+ changes['ignored'][environment] = ignored_classes if ignored_classes.any?
61
+ end
62
+
63
+ # Update the environments and puppetclasses based upon the user's selection
64
+ # It does a best attempt and can fail to perform all operations due to the
65
+ # user requesting impossible selections. Repeat the operation if errors are
66
+ # shown, after fixing the request.
67
+ # +changed+ : Hash with two keys: :new and :obsolete.
68
+ # changed[:/new|obsolete/] is and Array of Strings
69
+ # Returns : Array of Strings containing all record errors
70
+ def obsolete_and_new(changes = {})
71
+ return if changes.empty?
72
+ changes.values.map(&:keys).flatten.uniq.each do |env_name|
73
+ add_classes_to_foreman(env_name, JSON.parse(changes['new'][env_name])) if changes['new'] && changes['new'][env_name].try(:>, '') # we got new classes
74
+ remove_classes_from_foreman(env_name, JSON.parse(changes['obsolete'][env_name])) if changes['obsolete'] && changes['obsolete'][env_name].try(:>, '') # we need to remove classes
75
+ update_classes_in_foreman(env_name, JSON.parse(changes['updated'][env_name])) if changes['updated'] && changes['updated'][env_name].try(:>, '') # we need to update classes
76
+ end
77
+ []
78
+ rescue StandardError => e
79
+ Foreman::Logging.exception('Failed to calculate obsolete and new', e)
80
+ [e.to_s]
81
+ end
82
+
83
+ # Returns all classes for a given environment
84
+ #
85
+ # Params:
86
+ # * +environment+: {String} containing the name of the environment
87
+ #
88
+ def proxy_classes_for(environment)
89
+ @proxy_classes[environment] ||= proxy.classes(environment)
90
+ end
91
+
92
+ def new_classes_for(environment)
93
+ old_classes = db_classes_name(environment)
94
+ HashWithIndifferentAccess[
95
+ actual_classes(environment).values.map do |actual_class|
96
+ [actual_class.to_s, { 'new' => actual_class.parameters }] unless old_classes.include?(actual_class.to_s)
97
+ end.compact
98
+ ]
99
+ end
100
+
101
+ def removed_classes_for(environment)
102
+ db_classes_name(environment) - actual_classes_name(environment)
103
+ end
104
+
105
+ def updated_classes_for(environment)
106
+ return [] unless db_environments.include?(environment) && actual_environments.include?(environment)
107
+ HashWithIndifferentAccess[
108
+ db_classes(environment).map do |db_class|
109
+ params = EnvironmentClass.all_parameters_for_class(db_class.id, find_or_create_env(environment).id).map(&:puppetclass_lookup_key)
110
+ compare_classes(environment, db_class.name, params)
111
+ end.compact
112
+ ]
113
+ end
114
+
115
+ # Gives back the classes ignored for a given environment
116
+ #
117
+ # Params:
118
+ # * +environment+: {String} name of the environment
119
+ #
120
+ def ignored_classes_for(environment)
121
+ proxy_classes_for(environment).keys.select do |class_name|
122
+ ignored_class?(class_name)
123
+ end
124
+ end
125
+
126
+ # Returns true when the class name matches any pattern in ignored_classes
127
+ #
128
+ # Params:
129
+ # * +class_name+: {String} containing the class to be checked
130
+ #
131
+ def ignored_class?(class_name)
132
+ ignored_classes.any? do |filter|
133
+ filter.is_a?(Regexp) && filter =~ class_name
134
+ end
135
+ end
136
+
137
+ # This method check if the puppet class exists in this environment, and compare the class params.
138
+ # Changes in the params are categorized to new parameters, removed parameters and parameters with a new
139
+ # default value.
140
+ def compare_classes(environment, klass, db_params)
141
+ return nil unless (actual_class = actual_classes(environment)[klass])
142
+ actual_params = actual_class.parameters
143
+ db_param_names = db_params.map(&:to_s)
144
+
145
+ param_changes = {}
146
+ old = db_param_names - actual_params.keys
147
+ param_changes['obsolete'] = old if old.any?
148
+ new = actual_params.reject { |key, _value| db_param_names.include?(key) }
149
+ param_changes['new'] = new if new.any?
150
+ updated = updated_classes(actual_params, db_params)
151
+ param_changes['updated'] = updated if updated.any?
152
+ [klass, param_changes] if param_changes.keys.any?
153
+ end
154
+
155
+ def updated_classes(actual_params, db_params)
156
+ updated = {}
157
+ db_params.map do |p|
158
+ param_name = p.to_s
159
+ updated[param_name] = actual_params[param_name] if !p.override && actual_params.key?(param_name) && actual_params[param_name] != p.default_value
160
+ end
161
+ updated
162
+ end
163
+
164
+ def db_environments
165
+ @db_environments ||= (Environment.pluck('environments.name') - ignored_environments)
166
+ end
167
+
168
+ def actual_environments
169
+ (proxy_environments & (User.current.visible_environments + to_be_created_environments)) - ignored_environments
170
+ end
171
+
172
+ def proxy_environments
173
+ proxy.environments.map(&:to_s)
174
+ end
175
+
176
+ def to_be_created_environments
177
+ proxy_environments - Environment.unscoped.where(name: proxy_environments).pluck(:name)
178
+ end
179
+
180
+ def new_environments
181
+ actual_environments - db_environments
182
+ end
183
+
184
+ def old_environments
185
+ db_environments - actual_environments
186
+ end
187
+
188
+ def db_classes(environment)
189
+ return @foreman_classes[environment] if @foreman_classes[environment]
190
+ return [] unless (env = Environment.find_by(name: environment))
191
+ @foreman_classes[environment] = env.puppetclasses.includes(:class_params)
192
+ end
193
+
194
+ def db_classes_name(environment)
195
+ db_classes(environment).map(&:name)
196
+ end
197
+
198
+ # Returns an {Hash} of puppet class names without ignored classes
199
+ #
200
+ # Params:
201
+ # * +environment+: {String} containing the environment name
202
+ #
203
+ def actual_classes(environment)
204
+ proxy_classes_for(environment).reject { |key, _| ignored_class? key }
205
+ end
206
+
207
+ def actual_classes_name(environment)
208
+ actual_classes(environment).keys
209
+ end
210
+
211
+ def ignored_boolean_environment_names?
212
+ ignored_environments.any? { |item| item.is_a?(TrueClass) || item.is_a?(FalseClass) }
213
+ end
214
+
215
+ private
216
+
217
+ attr_reader :proxy
218
+
219
+ def ignored_environments
220
+ ignored_file[:ignored] || []
221
+ end
222
+
223
+ def ignored_classes
224
+ ignored_file[:filters] || []
225
+ end
226
+
227
+ def ignored_file_path
228
+ Rails.root.join('config/ignored_environments.yml')
229
+ end
230
+
231
+ def load_ignored_file
232
+ File.exist?(ignored_file_path) ? YAML.load_file(ignored_file_path) : {}
233
+ end
234
+
235
+ def ignored_file
236
+ @ignored_file ||= load_ignored_file
237
+ rescue StandardError => e
238
+ Foreman::Logging.exception('Failed to parse environment ignore file', e)
239
+ @ignored_file = {}
240
+ end
241
+
242
+ def logger
243
+ @logger ||= Rails.logger
244
+ end
245
+
246
+ def load_classes_from_json(blob)
247
+ ActiveSupport::JSON.decode blob
248
+ end
249
+
250
+ def add_classes_to_foreman(env_name, klasses)
251
+ env = find_or_create_env env_name
252
+ # look for Puppet class in all scopes to make sure we do not try to create a new record
253
+ # with a name that already exists and hit the uniqueness constraint on name
254
+ new_classes = klasses.map { |k| find_or_create_puppetclass(name: k[0]) }
255
+
256
+ new_classes.each do |new_class|
257
+ EnvironmentClass.find_or_create_by! puppetclass_id: new_class.id, environment_id: env.id
258
+ class_params = klasses[new_class.to_s]
259
+ add_new_parameter(env, new_class, class_params) if class_params.any?
260
+ end
261
+ end
262
+
263
+ def update_classes_in_foreman(environment, klasses)
264
+ env = find_or_create_env(environment)
265
+ db_classes = env.puppetclasses.where(name: klasses.keys)
266
+ db_classes.each do |db_class|
267
+ changed_params = klasses[db_class.to_s]
268
+ # Add new parameters
269
+ add_new_parameter(env, db_class, changed_params) if changed_params['new']
270
+ # Unbind old parameters
271
+ remove_parameter(env, db_class, changed_params) if changed_params['obsolete']
272
+ # Update parameters (affects solely the default value)
273
+ update_parameter(db_class, changed_params) if changed_params['updated']
274
+ end
275
+ end
276
+
277
+ def update_parameter(db_class, changed_params)
278
+ changed_params['updated'].each do |param_name, value|
279
+ key = db_class.class_params.find_by key: param_name
280
+ next unless key.override == false
281
+ key.default_value = value
282
+ key.key_type = nil
283
+ key.validator_type = nil
284
+ key.save!(context: :importer)
285
+ end
286
+ end
287
+
288
+ def remove_parameter(env, db_class, changed_params)
289
+ changed_params['obsolete'].each do |param_name, _value|
290
+ key = db_class.class_params.find_by key: param_name
291
+ key_in_env = EnvironmentClass.key_in_environment(env, db_class, key)
292
+
293
+ next unless key && key_in_env
294
+ # detach
295
+ key_in_env.destroy
296
+ # destroy if the key is not in any environment.
297
+ key.destroy unless EnvironmentClass.is_in_any_environment(db_class, key)
298
+ end
299
+ end
300
+
301
+ def add_new_parameter(env, klass, changed_params)
302
+ changed_params['new'].map do |param_name, value|
303
+ param = find_or_create_puppet_class_param klass, param_name, value
304
+ EnvironmentClass.find_or_create_by! puppetclass_id: klass.id, environment_id: env.id,
305
+ puppetclass_lookup_key_id: param.id
306
+ end
307
+ end
308
+
309
+ def remove_classes_from_foreman(env_name, klasses)
310
+ env = find_or_create_env(env_name)
311
+ classes = find_existing_foreman_classes(klasses)
312
+ env.puppetclasses.destroy classes
313
+ # remove all old classes from hosts
314
+ HostClass.joins(host: :puppet).where(HostPuppetFacet.arel_table[:environment_id].eq(env.id)).where(puppetclass_id: classes).destroy_all
315
+ unless ForemanPuppet.extracted_from_core?
316
+ # rubocop:disable Rails/SkipsModelValidations
317
+ Host.where(environment_id: env).update_all(environment_id: nil)
318
+ Hostgroup.where(environment_id: env).update_all(environment_id: nil)
319
+ # rubocop:enable Rails/SkipsModelValidations
320
+
321
+ # we can't guaranty that the env would be removed as it might have hosts attached to it.
322
+ env.destroy if klasses.include? '_destroy_'
323
+ end
324
+ # remove all klasses that have no environment now
325
+ classes.not_in_any_environment.destroy_all
326
+ end
327
+
328
+ def find_existing_foreman_classes(klasses = [])
329
+ Puppetclass.where(name: klasses)
330
+ end
331
+
332
+ def find_or_create_env(env)
333
+ user_visible_environment(env) || Environment.create!(name: env,
334
+ organizations: User.current.my_organizations,
335
+ locations: User.current.my_locations)
336
+ end
337
+
338
+ def user_visible_environment(env)
339
+ return unless User.current.visible_environments.include? env
340
+ Environment.unscoped.find_by name: env
341
+ end
342
+
343
+ def find_or_create_puppet_class_param(klass, param_name, value)
344
+ klass.class_params.where(key: param_name).first ||
345
+ PuppetclassLookupKey.create!(key: param_name, default_value: value,
346
+ key_type: Foreman::ImporterPuppetclass.suggest_key_type(value))
347
+ end
348
+
349
+ def find_or_create_puppetclass(name:)
350
+ puppetclass = Puppetclass.unscoped.find_or_create_by!(name: name)
351
+ raise Foreman::Exception.new('Failed to create Puppetclass: %s', puppetclass.errors.full_messages.to_sentence) unless puppetclass.errors.empty?
352
+ puppetclass
353
+ end
354
+ end
355
+ end