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.
- checksums.yaml +7 -0
- data/LICENSE +619 -0
- data/README.md +38 -0
- data/Rakefile +31 -0
- data/app/assets/stylesheets/foreman_puppet.scss +117 -0
- data/app/controllers/concerns/foreman_puppet/api/import_puppetclasses_common_controller.rb +139 -0
- data/app/controllers/concerns/foreman_puppet/environments_import.rb +61 -0
- data/app/controllers/concerns/foreman_puppet/extensions/api_hostgroups_controller.rb +40 -0
- data/app/controllers/concerns/foreman_puppet/extensions/api_template_combinations_controller.rb +23 -0
- data/app/controllers/concerns/foreman_puppet/extensions/api_v2_hosts_controller.rb +48 -0
- data/app/controllers/concerns/foreman_puppet/extensions/hostgroups_controller_extensions.rb +58 -0
- data/app/controllers/concerns/foreman_puppet/extensions/hosts_controller_extensions.rb +228 -0
- data/app/controllers/concerns/foreman_puppet/extensions/operatingsystems_controller.rb +11 -0
- data/app/controllers/concerns/foreman_puppet/extensions/parameters_host.rb +75 -0
- data/app/controllers/concerns/foreman_puppet/extensions/parameters_hostgroup.rb +70 -0
- data/app/controllers/concerns/foreman_puppet/extensions/parameters_template_combination.rb +21 -0
- data/app/controllers/concerns/foreman_puppet/parameters/config_group.rb +17 -0
- data/app/controllers/concerns/foreman_puppet/parameters/environment.rb +21 -0
- data/app/controllers/concerns/foreman_puppet/parameters/puppetclass.rb +24 -0
- data/app/controllers/concerns/foreman_puppet/parameters/puppetclass_lookup_key.rb +24 -0
- data/app/controllers/foreman_puppet/api/v2/base_controller.rb +26 -0
- data/app/controllers/foreman_puppet/api/v2/config_groups_controller.rb +57 -0
- data/app/controllers/foreman_puppet/api/v2/environments_controller.rb +91 -0
- data/app/controllers/foreman_puppet/api/v2/host_classes_controller.rb +59 -0
- data/app/controllers/foreman_puppet/api/v2/hostgroup_classes_controller.rb +46 -0
- data/app/controllers/foreman_puppet/api/v2/lookups_common_controller.rb +114 -0
- data/app/controllers/foreman_puppet/api/v2/override_values_controller.rb +99 -0
- data/app/controllers/foreman_puppet/api/v2/puppetclasses_controller.rb +99 -0
- data/app/controllers/foreman_puppet/api/v2/smart_class_parameters_controller.rb +76 -0
- data/app/controllers/foreman_puppet/config_groups_controller.rb +46 -0
- data/app/controllers/foreman_puppet/environments_controller.rb +51 -0
- data/app/controllers/foreman_puppet/puppet_smart_proxies_controller.rb +39 -0
- data/app/controllers/foreman_puppet/puppetclass_lookup_keys_controller.rb +33 -0
- data/app/controllers/foreman_puppet/puppetclasses_controller.rb +113 -0
- data/app/controllers/foreman_puppet/react_controller.rb +19 -0
- data/app/helpers/concerns/foreman_puppet/template_renderer_scope.rb +14 -0
- data/app/helpers/foreman_puppet/environments_helper.rb +17 -0
- data/app/helpers/foreman_puppet/hosts_and_hostgroups_helper.rb +96 -0
- data/app/helpers/foreman_puppet/hosts_helper.rb +32 -0
- data/app/helpers/foreman_puppet/puppet_smart_proxies_helper.rb +8 -0
- data/app/helpers/foreman_puppet/puppetclass_lookup_keys_helper.rb +135 -0
- data/app/helpers/foreman_puppet/puppetclasses_and_environments_helper.rb +55 -0
- data/app/helpers/foreman_puppet/puppetclasses_helper.rb +59 -0
- data/app/helpers/foreman_puppet/template_combinations_helper.rb +33 -0
- data/app/models/concerns/foreman_puppet/extensions/host.rb +88 -0
- data/app/models/concerns/foreman_puppet/extensions/hostgroup.rb +40 -0
- data/app/models/concerns/foreman_puppet/extensions/nic_managed.rb +11 -0
- data/app/models/concerns/foreman_puppet/extensions/operatingsystem.rb +11 -0
- data/app/models/concerns/foreman_puppet/extensions/provisioning_template.rb +64 -0
- data/app/models/concerns/foreman_puppet/extensions/report.rb +11 -0
- data/app/models/concerns/foreman_puppet/extensions/taxonomy.rb +19 -0
- data/app/models/concerns/foreman_puppet/extensions/template_combination.rb +23 -0
- data/app/models/concerns/foreman_puppet/extensions/user.rb +22 -0
- data/app/models/concerns/foreman_puppet/host_common.rb +90 -0
- data/app/models/concerns/foreman_puppet/puppet_lookup_value_extensions.rb +13 -0
- data/app/models/foreman_puppet/config_group.rb +45 -0
- data/app/models/foreman_puppet/config_group_class.rb +19 -0
- data/app/models/foreman_puppet/environment.rb +63 -0
- data/app/models/foreman_puppet/environment_class.rb +40 -0
- data/app/models/foreman_puppet/host_class.rb +23 -0
- data/app/models/foreman_puppet/host_config_group.rb +15 -0
- data/app/models/foreman_puppet/host_puppet_facet.rb +130 -0
- data/app/models/foreman_puppet/hostgroup_class.rb +23 -0
- data/app/models/foreman_puppet/hostgroup_puppet_facet.rb +98 -0
- data/app/models/foreman_puppet/puppetclass.rb +132 -0
- data/app/models/foreman_puppet/puppetclass_lookup_key.rb +58 -0
- data/app/services/foreman_puppet/host_info_providers/config_groups_info.rb +10 -0
- data/app/services/foreman_puppet/host_info_providers/puppet_info.rb +92 -0
- data/app/services/foreman_puppet/input_type/puppet_parameter_input.rb +35 -0
- data/app/services/foreman_puppet/proxy_status/puppet.rb +17 -0
- data/app/services/foreman_puppet/puppet_class_importer.rb +355 -0
- data/app/views/api/v2/template_combinations/base.json.erb +9 -0
- data/app/views/foreman_puppet/api/v2/config_groups/base.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/config_groups/create.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/config_groups/index.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/config_groups/main.json.rabl +8 -0
- data/app/views/foreman_puppet/api/v2/config_groups/show.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/config_groups/update.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/environments/base.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/environments/create.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/environments/index.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/environments/main.json.rabl +5 -0
- data/app/views/foreman_puppet/api/v2/environments/show.json.rabl +15 -0
- data/app/views/foreman_puppet/api/v2/environments/update.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/host_puppet_facets/base.json.rabl +1 -0
- data/app/views/foreman_puppet/api/v2/host_puppet_facets/host_single.json.rabl +17 -0
- data/app/views/foreman_puppet/api/v2/host_puppet_facets/show.json.rabl +11 -0
- data/app/views/foreman_puppet/api/v2/hostgroup_puppet_facets/base.json.rabl +5 -0
- data/app/views/foreman_puppet/api/v2/hostgroup_puppet_facets/hostgroup_single.json.rabl +16 -0
- data/app/views/foreman_puppet/api/v2/hostgroup_puppet_facets/show.json.rabl +11 -0
- data/app/views/foreman_puppet/api/v2/import_puppetclasses/index.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/import_puppetclasses/show.json.rabl +36 -0
- data/app/views/foreman_puppet/api/v2/override_values/create.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/override_values/index.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/override_values/show.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/override_values/update.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/puppetclasses/base.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/puppetclasses/create.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/puppetclasses/index.json.rabl +4 -0
- data/app/views/foreman_puppet/api/v2/puppetclasses/list.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/puppetclasses/main.json.rabl +5 -0
- data/app/views/foreman_puppet/api/v2/puppetclasses/show.json.rabl +15 -0
- data/app/views/foreman_puppet/api/v2/puppetclasses/update.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/smart_class_parameters/base.json.rabl +4 -0
- data/app/views/foreman_puppet/api/v2/smart_class_parameters/create.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/smart_class_parameters/destroy.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/smart_class_parameters/index.json.rabl +3 -0
- data/app/views/foreman_puppet/api/v2/smart_class_parameters/main.json.rabl +23 -0
- data/app/views/foreman_puppet/api/v2/smart_class_parameters/show.json.rabl +19 -0
- data/app/views/foreman_puppet/api/v2/smart_class_parameters/update.json.rabl +3 -0
- data/app/views/foreman_puppet/config_groups/_config_group.html.erb +34 -0
- data/app/views/foreman_puppet/config_groups/_config_groups_selection.html.erb +36 -0
- data/app/views/foreman_puppet/config_groups/_form.html.erb +9 -0
- data/app/views/foreman_puppet/config_groups/edit.html.erb +3 -0
- data/app/views/foreman_puppet/config_groups/index.html.erb +31 -0
- data/app/views/foreman_puppet/config_groups/new.html.erb +3 -0
- data/app/views/foreman_puppet/config_groups/welcome.html.erb +12 -0
- data/app/views/foreman_puppet/environments/_form.html.erb +20 -0
- data/app/views/foreman_puppet/environments/edit.html.erb +8 -0
- data/app/views/foreman_puppet/environments/index.html.erb +32 -0
- data/app/views/foreman_puppet/environments/new.html.erb +7 -0
- data/app/views/foreman_puppet/environments/welcome.html.erb +16 -0
- data/app/views/foreman_puppet/layouts/application_react.html.erb +15 -0
- data/app/views/foreman_puppet/puppet_smart_proxies/_dashboard.html.erb +9 -0
- data/app/views/foreman_puppet/puppet_smart_proxies/_environments.html.erb +30 -0
- data/app/views/foreman_puppet/puppetclass_lookup_keys/edit.html.erb +3 -0
- data/app/views/foreman_puppet/puppetclass_lookup_keys/index.html.erb +22 -0
- data/app/views/foreman_puppet/puppetclass_lookup_keys/welcome.html.erb +9 -0
- data/app/views/foreman_puppet/puppetclasses/_class_parameters.html.erb +37 -0
- data/app/views/foreman_puppet/puppetclasses/_class_selection.html.erb +70 -0
- data/app/views/foreman_puppet/puppetclasses/_classes.html.erb +22 -0
- data/app/views/foreman_puppet/puppetclasses/_classes_in_groups.html.erb +5 -0
- data/app/views/foreman_puppet/puppetclasses/_classes_parameters.html.erb +16 -0
- data/app/views/foreman_puppet/puppetclasses/_form.html.erb +62 -0
- data/app/views/foreman_puppet/puppetclasses/_selected_classes.html.erb +4 -0
- data/app/views/foreman_puppet/puppetclasses/edit.html.erb +4 -0
- data/app/views/foreman_puppet/puppetclasses/index.html.erb +47 -0
- data/app/views/hosts/_form_puppet_enc_tab.html.erb +24 -0
- data/app/views/hosts/foreman_puppet/_form_main_tab_fields.html.erb +1 -0
- data/app/views/hosts/select_multiple_environment.html.erb +8 -0
- data/app/views/provisioning_templates/_combination.html.erb +5 -0
- data/app/views/provisioning_templates/_combinations.html.erb +6 -0
- data/app/views/smart_proxies/plugins/_puppet.html.erb +24 -0
- data/config/api_routes.rb +81 -0
- data/config/routes.rb +89 -0
- data/db/migrate/20101121140000_add_environment_to_template_combinations.foreman_puppet.rb +9 -0
- data/db/migrate/20200720123005_migrate_puppet_core_types.foreman_puppet.rb +19 -0
- data/db/migrate/20200722171017_create_host_puppet_facet.foreman_puppet.rb +10 -0
- data/db/migrate/20200803113531_create_hostgroup_puppet_facet.foreman_puppet.rb +10 -0
- data/db/migrate/20200803113803_migrate_environment_to_puppet_facet.foreman_puppet.rb +22 -0
- data/db/migrate/20200803113903_migrate_host_type_in_host_config_groups.foreman_puppet.rb +29 -0
- data/db/migrate/20201125113903_migrate_puppetclasses_to_facets.foreman_puppet.rb +47 -0
- data/db/migrate_foreman/20090722141107_create_environments.rb +17 -0
- data/db/migrate_foreman/20120905095532_create_environment_classes.rb +15 -0
- data/db/migrate_foreman/20140407161817_create_config_groups.rb +9 -0
- data/db/migrate_foreman/20140407162007_create_config_group_classes.rb +10 -0
- data/db/migrate_foreman/20140407162059_create_host_config_groups.rb +11 -0
- data/db/migrate_foreman/20161205142618_delete_orphaned_smart_class_parameters.rb +10 -0
- data/db/migrate_foreman/20170109115157_fix_lookup_key_auditable_type.rb +15 -0
- data/db/migrate_foreman/20180816134832_cast_lookup_key_values.rb +35 -0
- data/db/migrate_foreman/20181023112532_add_environment_puppetclass_id.rb +7 -0
- data/db/migrate_foreman/20181224174419_add_index_to_environment_class_by_lookup_key_and_puppetclass.rb +6 -0
- data/db/seeds.d/111_puppet_proxy_feature.rb +8 -0
- data/lib/foreman_puppet.rb +10 -0
- data/lib/foreman_puppet/engine.rb +82 -0
- data/lib/foreman_puppet/register.rb +218 -0
- data/lib/foreman_puppet/version.rb +3 -0
- data/lib/tasks/foreman_puppet_tasks.rake +31 -0
- data/locale/Makefile +60 -0
- data/locale/action_names.rb +5 -0
- data/locale/en/foreman_puppet.edit.po +911 -0
- data/locale/en/foreman_puppet.po +690 -0
- data/locale/en/foreman_puppet.po.time_stamp +0 -0
- data/locale/foreman_puppet.pot +1076 -0
- data/locale/gemspec.rb +2 -0
- data/test/controllers/foreman_puppet/api/v2/config_groups_controller_test.rb +28 -0
- data/test/controllers/foreman_puppet/api/v2/environments_controller_test.rb +346 -0
- data/test/controllers/foreman_puppet/api/v2/host_classes_controller_test.rb +48 -0
- data/test/controllers/foreman_puppet/api/v2/hostgroup_classes_controller_test.rb +41 -0
- data/test/controllers/foreman_puppet/api/v2/hostgroups_controller_test.rb +79 -0
- data/test/controllers/foreman_puppet/api/v2/hosts_controller_test.rb +101 -0
- data/test/controllers/foreman_puppet/api/v2/lookups_common_controller_test.rb +29 -0
- data/test/controllers/foreman_puppet/api/v2/override_values_controller_test.rb +169 -0
- data/test/controllers/foreman_puppet/api/v2/puppetclasses_controller_test.rb +144 -0
- data/test/controllers/foreman_puppet/api/v2/smart_class_parameters_controller_test.rb +557 -0
- data/test/controllers/foreman_puppet/api/v2/template_combinations_controller_test.rb +81 -0
- data/test/controllers/foreman_puppet/config_groups_controller_test.rb +47 -0
- data/test/controllers/foreman_puppet/environments_controller_test.rb +230 -0
- data/test/controllers/foreman_puppet/hostgroups_controller_test.rb +72 -0
- data/test/controllers/foreman_puppet/hosts_controller_test.rb +346 -0
- data/test/controllers/foreman_puppet/puppet_smart_proxies_controller_test.rb +29 -0
- data/test/controllers/foreman_puppet/puppetclass_lookup_keys_controller_test.rb +59 -0
- data/test/controllers/foreman_puppet/puppetclasses_controller_test.rb +235 -0
- data/test/controllers/provisioning_templates_controller_test.rb +70 -0
- data/test/factories/foreman_puppet_factories.rb +134 -0
- data/test/factories/host_puppet_enhancements.rb +61 -0
- data/test/factories/proxy_puppet_enhancements.rb +33 -0
- data/test/helpers/foreman_puppet/hosts_and_hostgroups_helper_test.rb +65 -0
- data/test/helpers/foreman_puppet/puppetclasses_helper_test.rb +33 -0
- data/test/integration/foreman_puppet/environment_js_test.rb +27 -0
- data/test/integration/foreman_puppet/host_js_test.rb +371 -0
- data/test/integration/foreman_puppet/hostgroup_js_test.rb +100 -0
- data/test/integration/foreman_puppet/puppetclass_js_test.rb +37 -0
- data/test/integration/foreman_puppet/smartclass_parameter_js_test.rb +84 -0
- data/test/models/foreman_puppet/config_group_class_test.rb +9 -0
- data/test/models/foreman_puppet/config_group_test.rb +8 -0
- data/test/models/foreman_puppet/environment_test.rb +92 -0
- data/test/models/foreman_puppet/host_config_group_test.rb +39 -0
- data/test/models/foreman_puppet/host_puppet_facet_test.rb +116 -0
- data/test/models/foreman_puppet/host_test.rb +288 -0
- data/test/models/foreman_puppet/hostgroup_puppet_facet_test.rb +200 -0
- data/test/models/foreman_puppet/hostgroup_test.rb +14 -0
- data/test/models/foreman_puppet/lookup_value_test.rb +69 -0
- data/test/models/foreman_puppet/provisioning_template_test.rb +124 -0
- data/test/models/foreman_puppet/puppetclass_lookup_key_test.rb +81 -0
- data/test/models/foreman_puppet/puppetclass_test.rb +144 -0
- data/test/models/foreman_puppet/smart_proxy_test.rb +28 -0
- data/test/qraphql/queries/host_puppet_query_test.rb +36 -0
- data/test/qraphql/queries/hostgroup_puppet_query_test.rb +36 -0
- data/test/services/foreman_puppet/host_info_providers/puppet_info_test.rb +791 -0
- data/test/services/foreman_puppet/input_type/puppet_parameter_input_test.rb +14 -0
- data/test/test_puppet_helper.rb +30 -0
- data/test/unit/foreman_puppet/access_permissions_test.rb +16 -0
- data/test/unit/foreman_puppet/puppet_class_importer_test.rb +247 -0
- data/test/unit/foreman_puppet/template_rendering_test.rb +20 -0
- data/test/unit/foreman_puppet_test.rb +11 -0
- data/webpack/__mocks__/foremanReact/common/I18n.js +7 -0
- data/webpack/__mocks__/foremanReact/components/Layout/LayoutActions.js +2 -0
- data/webpack/__mocks__/foremanReact/readme.md +11 -0
- data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +10 -0
- data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
- data/webpack/__mocks__/foremanReact/redux/actions/toasts.js +8 -0
- data/webpack/__mocks__/foremanReact/redux/index.js +1 -0
- data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js +5 -0
- data/webpack/fills_index.js +30 -0
- data/webpack/index.js +18 -0
- data/webpack/src/ForemanPuppet.js +11 -0
- data/webpack/src/Router/__snapshots__/routes.test.js.snap +3 -0
- data/webpack/src/Router/index.js +14 -0
- data/webpack/src/Router/routes.js +3 -0
- data/webpack/src/Router/routes.test.js +16 -0
- data/webpack/src/foreman_class_edit.js +224 -0
- data/webpack/src/foreman_puppet_host_form.js +140 -0
- data/webpack/src/foreman_puppet_host_form.test.js +65 -0
- data/webpack/src/index.js +1 -0
- data/webpack/src/reducers.js +7 -0
- 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
|