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,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