foreman_puppet 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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