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,13 @@
1
+ module ForemanPuppet
2
+ module PuppetLookupValueExtensions
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ validate :value_present?, if: ->(v) { v.lookup_key.is_a?(ForemanPuppet::PuppetclassLookupKey) }
7
+ end
8
+
9
+ def value_present?
10
+ errors.add(:value, :blank) if value.to_s.empty? && !omit
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,45 @@
1
+ module ForemanPuppet
2
+ class ConfigGroup < ApplicationRecord
3
+ self.table_name = 'config_groups'
4
+
5
+ audited
6
+ include Authorizable
7
+ include Parameterizable::ByIdName
8
+
9
+ validates_lengths_from_database
10
+
11
+ has_many :config_group_classes, dependent: :destroy
12
+ has_many :puppetclasses, through: :config_group_classes
13
+ has_many :host_config_groups, dependent: :destroy
14
+ has_many_hosts through: :host_config_groups, source: :host, source_type: 'Host::Managed'
15
+ has_many :hostgroups, through: :host_config_groups, source: :host, source_type: 'Hostgroup'
16
+
17
+ validates :name, presence: true, uniqueness: true
18
+
19
+ scoped_search on: :name, complete_value: true
20
+ scoped_search relation: :puppetclasses, on: :name, complete_value: true, rename: :class, only_explicit: true, operators: ['= ', '~ ']
21
+
22
+ default_scope -> { order('config_groups.name') }
23
+
24
+ # the following methods are required for app/views/puppetclasses/_class_selection.html.erb
25
+ alias_method :classes, :puppetclasses
26
+ alias_method :individual_puppetclasses, :puppetclasses
27
+
28
+ def available_puppetclasses
29
+ Puppetclass.where(nil)
30
+ end
31
+
32
+ # for auditing
33
+ def to_label
34
+ name
35
+ end
36
+
37
+ def hosts_count
38
+ ::Host::Managed.authorized.search_for(%(config_group="#{name}")).size
39
+ end
40
+
41
+ def hostgroups_count
42
+ ::Hostgroup.authorized.search_for(%(config_group="#{name}")).size
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,19 @@
1
+ module ForemanPuppet
2
+ class ConfigGroupClass < ApplicationRecord
3
+ self.table_name = 'config_group_classes'
4
+ audited associated_with: :config_group
5
+
6
+ include Authorizable
7
+
8
+ belongs_to :puppetclass
9
+ belongs_to :config_group
10
+
11
+ validates :puppetclass, presence: true
12
+ validates :config_group, presence: true,
13
+ uniqueness: { scope: :puppetclass_id }
14
+
15
+ def check_permissions_after_save
16
+ true
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,63 @@
1
+ module ForemanPuppet
2
+ class Environment < ApplicationRecord
3
+ self.table_name = 'environments'
4
+
5
+ audited
6
+ extend FriendlyId
7
+ friendly_id :name, reserved_words: []
8
+ include Taxonomix
9
+ include Authorizable
10
+ include Parameterizable::ByName
11
+
12
+ validates_lengths_from_database
13
+ before_destroy EnsureNotUsedBy.new(:hosts, :hostgroups)
14
+
15
+ has_many :environment_classes, dependent: :destroy
16
+ has_many :puppetclasses, -> { distinct }, through: :environment_classes
17
+ has_many :host_puppet_facets, dependent: :destroy
18
+ has_many :hostgroup_puppet_facets, dependent: :destroy
19
+ has_many_hosts through: :host_puppet_facets
20
+ has_many :hostgroups, through: :hostgroup_puppet_facets
21
+
22
+ validates :name, uniqueness: true, presence: true, alphanumeric: true
23
+ has_many :template_combinations, dependent: :destroy
24
+ has_many :provisioning_templates, through: :template_combinations
25
+
26
+ # with proc support, default_scope can no longer be chained
27
+ # include all default scoping here
28
+ default_scope lambda {
29
+ with_taxonomy_scope do
30
+ order('environments.name')
31
+ end
32
+ }
33
+
34
+ scoped_search on: :name, complete_value: true
35
+
36
+ class << self
37
+ # TODO: this needs to be removed, as PuppetDOC generation no longer works
38
+ # if the manifests are not on the foreman host
39
+ # returns an hash of all puppet environments and their relative paths
40
+ def puppetEnvs(proxy = nil)
41
+ url = (proxy || SmartProxy.with_features('Puppet').first).try(:url)
42
+ raise ::Foreman::Exception, N_("Can't find a valid Foreman Proxy with a Puppet feature") if url.blank?
43
+ proxy = ProxyAPI::Puppet.new url: url
44
+ HashWithIndifferentAccess[proxy.environments.map do |e|
45
+ [e, HashWithIndifferentAccess[proxy.classes(e).map do |k|
46
+ klass = k.keys.first
47
+ [klass, k[klass]['params']]
48
+ end]]
49
+ end]
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def taxonomy_foreign_conditions
56
+ HostPuppetFacet.arel_table[:environment_id].eq(id)
57
+ end
58
+
59
+ def used_taxonomy_ids(type)
60
+ Host::Managed.joins(:puppet).where(taxonomy_foreign_conditions).distinct.pluck(type).compact
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,40 @@
1
+ module ForemanPuppet
2
+ class EnvironmentClass < ApplicationRecord
3
+ self.table_name = 'environment_classes'
4
+
5
+ belongs_to :environment
6
+ belongs_to :puppetclass, inverse_of: :environment_classes
7
+ belongs_to :puppetclass_lookup_key, inverse_of: :environment_classes, class_name: 'ForemanPuppet::PuppetclassLookupKey'
8
+ validates :puppetclass_lookup_key_id, uniqueness: { scope: %i[environment_id puppetclass_id] }
9
+ validates :puppetclass_id, :environment_id, presence: true
10
+ after_destroy :delete_orphaned_lookup_keys
11
+
12
+ scope :parameters_for_class, lambda { |puppetclasses_ids, environment_id|
13
+ all_parameters_for_class(puppetclasses_ids, environment_id).where(puppetclass_lookup_keys: { override: true })
14
+ }
15
+
16
+ scope :all_parameters_for_class, lambda { |puppetclasses_ids, environment_id|
17
+ where(puppetclass_id: puppetclasses_ids, environment_id: environment_id)
18
+ .where.not(puppetclass_lookup_key_id: nil)
19
+ .includes(:puppetclass_lookup_key)
20
+ }
21
+
22
+ scope :used_by_other_environment_classes, lambda { |puppetclass_lookup_key_id, this_environment_class_id|
23
+ where(puppetclass_lookup_key_id: puppetclass_lookup_key_id)
24
+ .where("id != #{this_environment_class_id}")
25
+ }
26
+
27
+ # TODO: move these into scopes?
28
+ def self.is_in_any_environment(puppetclass, puppetclass_lookup_key)
29
+ EnvironmentClass.where(puppetclass_id: puppetclass, puppetclass_lookup_key_id: puppetclass_lookup_key).any?
30
+ end
31
+
32
+ def self.key_in_environment(env, puppetclass, puppetclass_lookup_key)
33
+ EnvironmentClass.find_by(environment_id: env, puppetclass_id: puppetclass, puppetclass_lookup_key_id: puppetclass_lookup_key)
34
+ end
35
+
36
+ def delete_orphaned_lookup_keys
37
+ puppetclass_lookup_key.destroy if puppetclass_lookup_key.present? && puppetclass_lookup_key.environment_classes.empty?
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,23 @@
1
+ module ForemanPuppet
2
+ class HostClass < ApplicationRecord
3
+ self.table_name = 'host_classes'
4
+
5
+ audited associated_with: :host
6
+ include Authorizable
7
+
8
+ validates_lengths_from_database
9
+ belongs_to :puppetclass
10
+ belongs_to :host_puppet_facet
11
+ has_one :host, through: :host_puppet_facet
12
+
13
+ validates :puppetclass_id, presence: true, uniqueness: { scope: :host_puppet_facet_id }
14
+
15
+ def name
16
+ "#{host_puppet_facet.host} - #{puppetclass}"
17
+ end
18
+
19
+ def check_permissions_after_save
20
+ true
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ module ForemanPuppet
2
+ class HostConfigGroup < ApplicationRecord
3
+ self.table_name = 'host_config_groups'
4
+ include Authorizable
5
+ audited associated_with: :host
6
+ belongs_to :host, polymorphic: true
7
+ belongs_to :config_group
8
+
9
+ validates :host_id, uniqueness: { scope: %i[config_group_id host_type] }
10
+
11
+ def check_permissions_after_save
12
+ true
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,130 @@
1
+ module ForemanPuppet
2
+ class HostPuppetFacet < ApplicationRecord
3
+ self.table_name = 'host_puppet_facets'
4
+ audited associated_with: :host
5
+
6
+ include Facets::Base
7
+ include ForemanPuppet::HostCommon
8
+
9
+ has_many :host_classes, dependent: :destroy
10
+ has_many :puppetclasses, through: :host_classes
11
+
12
+ validates :environment_id, presence: true, unless: ->(facet) { facet.host.puppet_proxy_id.blank? }
13
+
14
+ after_validation :ensure_puppet_associations
15
+ before_save :clear_puppetinfo, if: :environment_id_changed?
16
+
17
+ def self.populate_fields_from_facts(host, parser, type, source_proxy)
18
+ type ||= 'puppet'
19
+ return unless type == 'puppet'
20
+
21
+ if Setting[:update_environment_from_facts]
22
+ host.set_non_empty_values parser, [:environment]
23
+ elsif parser.environment.present?
24
+ self.environment ||= parser.environment
25
+ end
26
+
27
+ # if proxy authentication is enabled and we have no puppet proxy set and the upload came from puppet,
28
+ # use it as puppet proxy.
29
+ host.puppet_proxy ||= source_proxy
30
+ end
31
+
32
+ def self.inherited_attributes(new_hostgroup, attributes)
33
+ { 'environment_id' => new_hostgroup.puppet&.inherited_environment_id }.merge(attributes)
34
+ end
35
+
36
+ def clear_puppetinfo
37
+ return if environment
38
+ self.puppetclasses = []
39
+ self.config_groups = []
40
+ end
41
+
42
+ # the environment used by #clases nees to be self.environment and not self.parent.environment
43
+ def parent_classes
44
+ return [] unless host.hostgroup
45
+ host.hostgroup.puppet&.classes(environment)
46
+ end
47
+
48
+ def parent_config_groups
49
+ return [] unless host.hostgroup
50
+ host.hostgroup.puppet&.all_config_groups
51
+ end
52
+
53
+ def ensure_puppet_associations
54
+ status = validate_association_taxonomy(:environment)
55
+ return status unless environment
56
+
57
+ puppetclasses.where.not(id: environment.puppetclasses.reorder(nil)).find_each do |puppetclass|
58
+ errors.add(
59
+ :puppetclasses,
60
+ format(_('%{puppetclass} does not belong to the %{environment} environment'), puppetclass: puppetclass, environment: environment)
61
+ )
62
+ status = false
63
+ end
64
+ status
65
+ end
66
+
67
+ # this method accepts a puppets external node yaml output and generate a node in our setup
68
+ # it is assumed that you already have the node (e.g. imported by one of the rack tasks)
69
+ # rubocop:disable Metrics/MethodLength
70
+ # rubocop:disable Metrics/AbcSize
71
+ def import_puppet_node(nodeinfo)
72
+ myklasses = []
73
+ # puppet classes
74
+ classes = nodeinfo['classes']
75
+ classes = classes.keys if classes.is_a?(Hash)
76
+ classes.each do |klass|
77
+ if (pc = ForemanPuppet::Puppetclass.find_by(name: klass.to_s))
78
+ myklasses << pc
79
+ else
80
+ error = format(_("Failed to import %{klass} for %{name}: doesn't exists in our database - ignoring"), klass: klass, name: name)
81
+ logger.warn error
82
+ $stdout.puts error
83
+ end
84
+ self.puppetclasses = myklasses
85
+ end
86
+
87
+ # parameters are a bit more tricky, as some classifiers provide the facts as parameters as well
88
+ # not sure what is puppet priority about it, but we ignore it if has a fact with the same name.
89
+ # additionally, we don't import any non strings values, as puppet don't know what to do with those as well.
90
+
91
+ myparams = host.info['parameters']
92
+ nodeinfo['parameters'].each_pair do |param, value|
93
+ next if host.fact_names.exists? name: param
94
+ next unless value.is_a?(String)
95
+
96
+ # we already have this parameter
97
+ next if myparams.key?(param) && myparams[param] == value
98
+
99
+ unless (hp = host.host_parameters.create(name: param, value: value))
100
+ logger.warn "Failed to import #{param}/#{value} for #{name}: #{hp.errors.full_messages.join(', ')}"
101
+ $stdout.puts $ERROR_INFO
102
+ end
103
+ end
104
+
105
+ host.clear_host_parameters_cache!
106
+ save
107
+ end
108
+ # rubocop:enable Metrics/AbcSize
109
+ # rubocop:enable Metrics/MethodLength
110
+
111
+ private
112
+
113
+ # Copy of method with same name, but for facet associations
114
+ def validate_association_taxonomy(association_name)
115
+ association = self.class.reflect_on_association(association_name)
116
+ raise ArgumentError, "Association #{association_name} not found" unless association
117
+ associated_object_id = public_send(association.foreign_key)
118
+ if associated_object_id.present? &&
119
+ association.klass.with_taxonomy_scope(host.organization, host.location).find_by(id: associated_object_id).blank?
120
+ errors.add(
121
+ association.foreign_key,
122
+ format(_("with id %{object_id} doesn't exist or is not assigned to proper organization and/or location"), object_id: associated_object_id)
123
+ )
124
+ false
125
+ else
126
+ true
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,23 @@
1
+ module ForemanPuppet
2
+ class HostgroupClass < ApplicationRecord
3
+ self.table_name = 'hostgroup_classes'
4
+
5
+ audited associated_with: :hostgroup
6
+ include Authorizable
7
+
8
+ belongs_to :puppetclass
9
+ belongs_to :hostgroup_puppet_facet
10
+ has_one :hostgroup, through: :hostgroup_puppet_facet
11
+
12
+ validates :hostgroup_puppet_facet, presence: true
13
+ validates :puppetclass_id, presence: true, uniqueness: { scope: :hostgroup_puppet_facet_id }
14
+
15
+ def name
16
+ "#{hostgroup} - #{puppetclass}"
17
+ end
18
+
19
+ def check_permissions_after_save
20
+ true
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,98 @@
1
+ module ForemanPuppet
2
+ class HostgroupPuppetFacet < ApplicationRecord
3
+ # ------ ANCESTRY ATTRIBUTES -------
4
+ # This mimic nested attributes, that should probably be provided by Facets::HostgroupFacet
5
+
6
+ class << self
7
+ attr_reader :nested_attribute_fields
8
+
9
+ def nested_attribute_for(*fields)
10
+ @nested_attribute_fields ||= []
11
+ @nested_attribute_fields |= fields
12
+ @nested_attribute_fields.each do |field|
13
+ # Example method
14
+ # def inherited_compute_profile_id
15
+ # read_attribute(:compute_profile_id) || nested_compute_profile_id
16
+ # end
17
+ define_method "inherited_#{field}" do
18
+ self[field] || nested(field)
19
+ end
20
+
21
+ # Example method - only override method generated by assocation if there is ancestry.
22
+ # if ancestry.present?
23
+ # def compute_profile
24
+ # ComputeProfile.find_by_id(inherited_compute_profile_id)
25
+ # end
26
+ # end
27
+ next unless (md = field.to_s.match(/(\w+)_id$/))
28
+ define_method md[1] do
29
+ if hostgroup.ancestry.present?
30
+ klass = "ForemanPuppet::#{md[1].classify}"
31
+ klass = 'SmartProxy' if md[1] == 'puppet_proxy' || md[1] == 'puppet_ca_proxy'
32
+ klass = 'Subnet::Ipv4' if md[1] == 'subnet'
33
+ klass = 'Subnet::Ipv6' if md[1] == 'subnet6'
34
+ klass.constantize.find_by(id: send("inherited_#{field}"))
35
+ else
36
+ # () is required.
37
+ # Otherwise, get RuntimeError: implicit argument passing of super from method defined by define_method() is not supported.
38
+ # Specify all arguments explicitly.
39
+ super()
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ def nested(attr)
47
+ return nil if hostgroup.ancestry.blank?
48
+ Hostgroup.sort_by_ancestry(hostgroup.ancestors.joins(:puppet).where(HostgroupPuppetFacet.arel_table[attr.to_sym].not_eq(nil))).last&.puppet.try(attr)
49
+ end
50
+
51
+ # and helpers
52
+ def parent_facet_id
53
+ parent_facet&.id
54
+ end
55
+
56
+ def parent_facet
57
+ @parent_facet ||= hostgroup.parent_id && HostgroupPuppetFacet.find_by(hostgroup_id: hostgroup.parent_id)
58
+ end
59
+ # ------ END ANCESTRY -------
60
+
61
+ audited associated_with: :hostgroup
62
+ self.table_name = 'hostgroup_puppet_facets'
63
+
64
+ include ForemanPuppet::HostCommon
65
+ include Facets::HostgroupFacet
66
+
67
+ has_many :hostgroup_classes, dependent: :destroy
68
+ has_many :puppetclasses, through: :hostgroup_classes
69
+
70
+ before_save :remove_duplicated_nested_class
71
+
72
+ nested_attribute_for :environment_id
73
+
74
+ def all_config_groups
75
+ (config_groups + parent_config_groups).uniq
76
+ end
77
+
78
+ def parent_config_groups
79
+ return [] unless hostgroup.parent
80
+ groups = []
81
+ hostgroup.ancestors.each do |hostgroup|
82
+ groups += hostgroup.puppet&.config_groups || []
83
+ end
84
+ groups.uniq
85
+ end
86
+
87
+ # the environment used by #clases nees to be self.environment and not self.parent.environment
88
+ def parent_classes
89
+ return [] unless parent_facet
90
+ parent_facet.classes(environment)
91
+ end
92
+
93
+ def remove_duplicated_nested_class
94
+ ancestor_hgs = hostgroup.ancestors.preload(puppet: :puppetclasses)
95
+ self.puppetclasses -= ancestor_hgs.map { |ancestor| ancestor.puppet&.puppetclasses }.compact.flatten
96
+ end
97
+ end
98
+ end