Skip to content

Commit

Permalink
Add Puppet proxies to Host(group)
Browse files Browse the repository at this point in the history
Adding Host and Hostgroup puppet proxies.
  • Loading branch information
ezr-ondrej committed May 17, 2021
1 parent a8b9fc6 commit 155215d
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
module ForemanPuppet
# Common methods between host and hostgroup
# mostly for template rendering consistency
module HostCommon
module PuppetFacetCommon
extend ActiveSupport::Concern

include ::BelongsToProxies

included do
belongs_to :environment
has_many :host_config_groups, as: :host, dependent: :destroy
has_many :config_groups, through: :host_config_groups
has_many :config_group_classes, through: :config_groups
has_many :group_puppetclasses, through: :config_groups, source: :puppetclasses

belongs_to_proxy :puppet_proxy,
feature: N_('Puppet'),
label: N_('Puppet Proxy'),
description: N_('Use the Puppetserver configured on this Smart Proxy'),
api_description: N_('Puppet proxy ID')

belongs_to_proxy :puppet_ca_proxy,
feature: 'Puppet CA',
label: N_('Puppet CA Proxy'),
description: N_('Use the Puppetserver CA configured on this Smart Proxy'),
api_description: N_('Puppet CA proxy ID')

alias_method :all_puppetclasses, :classes

before_save :check_puppet_ca_proxy_is_required?
end

def parent_name
Expand Down Expand Up @@ -86,5 +102,52 @@ def available_puppetclasses
return ForemanPuppet::Puppetclass.all.authorized(:view_puppetclasses) if environment.blank?
environment.puppetclasses - parent_classes
end

def puppetca?
return false if respond_to?(:managed?) && !managed?
puppetca_exists?
end

def puppetca_exists?
!!(puppet_ca_proxy && puppet_ca_proxy.url.present?)
end

def puppet_server_uri
return unless puppet_proxy
url = puppet_proxy.setting('Puppet', 'puppet_url')
url ||= "https://#{puppet_proxy}:8140"
URI(url)
end

# The Puppet server FQDN or an empty string. Exposed as a provisioning macro
def puppet_server
puppet_server_uri.try(:host) || ''
end
alias_method :puppetmaster, :puppet_server

def puppet_ca_server_uri
return unless puppet_ca_proxy
url = puppet_ca_proxy.setting('Puppet CA', 'puppet_url')
url ||= "https://#{puppet_ca_proxy}:8140"
URI(url)
end

# The Puppet CA server FQDN or an empty string. Exposed as a provisioning
# macro.
def puppet_ca_server
puppet_ca_server_uri.try(:host) || ''
end

private

# fall back to our puppet proxy in case our puppet ca is not defined/used.
def check_puppet_ca_proxy_is_required?
return true if puppet_ca_proxy_id.present? || puppet_proxy_id.blank?
if puppet_proxy.has_feature?('Puppet CA')
self.puppet_ca_proxy ||= puppet_proxy
end
rescue
true # we don't want to break anything, so just skipping.
end
end
end
6 changes: 3 additions & 3 deletions app/models/foreman_puppet/host_puppet_facet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ class HostPuppetFacet < ApplicationRecord
audited associated_with: :host

include Facets::Base
include ForemanPuppet::HostCommon
include ForemanPuppet::PuppetFacetCommon

has_many :host_classes, dependent: :destroy, class_name: 'ForemanPuppet::HostClass'
has_many :puppetclasses, through: :host_classes

validates :environment_id, presence: true, unless: ->(facet) { facet.host.puppet_proxy_id.blank? }
validates :environment_id, presence: true, unless: ->(facet) { facet.puppet_proxy_id.blank? }

after_validation :ensure_puppet_associations
before_save :clear_puppetinfo, if: :environment_id_changed?
Expand All @@ -27,7 +27,7 @@ def self.populate_fields_from_facts(host, parser, type, source_proxy)

# if proxy authentication is enabled and we have no puppet proxy set and the upload came from puppet,
# use it as puppet proxy.
host.puppet_proxy ||= source_proxy
facet.puppet_proxy ||= source_proxy
end

def self.inherited_attributes(new_hostgroup, attributes)
Expand Down
2 changes: 1 addition & 1 deletion app/models/foreman_puppet/hostgroup_puppet_facet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def parent_facet
audited associated_with: :hostgroup
self.table_name = 'hostgroup_puppet_facets'

include ForemanPuppet::HostCommon
include ForemanPuppet::PuppetFacetCommon
include Facets::HostgroupFacet

has_many :hostgroup_classes, dependent: :destroy
Expand Down
10 changes: 10 additions & 0 deletions db/migrate/20210427122719_add_puppet_ca_proxy_column.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class AddPuppetCaProxyColumn < ActiveRecord::Migration[6.0]
def change
change_table :host_puppet_facets do |t|
t.references :puppet_ca_proxy, foreign_key: { to_table: :smart_proxies }
end
change_table :hostgroup_puppet_facets do |t|
t.references :puppet_ca_proxy, foreign_key: { to_table: :smart_proxies }
end
end
end
5 changes: 3 additions & 2 deletions lib/foreman_puppet/register.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,14 @@
api_view list: 'foreman_puppet/api/v2/host_puppet_facets/base',
single: 'foreman_puppet/api/v2/host_puppet_facets/host_single'
template_compatibility_properties :environment, :environment_id, :environment_name,
:puppetclasses, :all_puppetclasses
:puppetclasses, :all_puppetclasses, :puppet_server, :puppet_ca_server
set_dependent_action :destroy
end
configure_hostgroup(ForemanPuppet::HostgroupPuppetFacet) do
api_view list: 'foreman_puppet/api/v2/hostgroup_puppet_facets/base',
single: 'foreman_puppet/api/v2/hostgroup_puppet_facets/hostgroup_single'
template_compatibility_properties :environment, :environment_id, :environment_name
template_compatibility_properties :environment, :environment_id, :environment_name,
:puppet_server, :puppet_ca_server
set_dependent_action :destroy
end
end
Expand Down
24 changes: 24 additions & 0 deletions test/models/foreman_puppet/host_puppet_facet_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class HostPuppetFacetTest < ActiveSupport::TestCase
let(:config_group_diff_env) { FactoryBot.create(:config_group, :with_puppetclass, class_environments: [diff_environment]) }

describe '.populate_fields_from_facts' do
let(:puppet_proxy) { FactoryBot.create(:puppet_smart_proxy) }

test 'populate environment without any puppet info' do
h = FactoryBot.create(:host)
parser = stub(environment: environment)
Expand Down Expand Up @@ -39,6 +41,28 @@ class HostPuppetFacetTest < ActiveSupport::TestCase
HostPuppetFacet.populate_fields_from_facts(h, parser, 'puppet', FactoryBot.create(:puppet_smart_proxy))
assert_not_equal environment, h.puppet.environment
end

test "should update puppet_proxy_id to the id of the validated proxy" do
raw = read_json_fixture('facts/facts_with_caps.json')
host = Host.import_host(raw['name'], nil)
assert HostFactImporter.new(host).import_facts(raw['facts'], puppet_proxy)
assert_equal puppet_proxy.id, Host.find_by_name('sinn1636.lan').puppet_proxy_id
end

test "should not update puppet_proxy_id if it was not puppet upload" do
raw = read_json_fixture('facts/facts_with_caps.json')
host = Host.import_host(raw['name'])
assert HostFactImporter.new(host).import_facts(raw['facts'].merge(:_type => 'chef'), puppet_proxy)
assert_nil host.puppet_proxy_id
end

test "shouldn't update puppet_proxy_id if it has been set" do
Host.new(:name => 'sinn1636.lan', :puppet_proxy_id => puppet_proxy.id).save(:validate => false)
raw = read_json_fixture('facts/facts_with_certname.json')
host = Host.import_host(raw['name'])
assert HostFactImporter.new(host).import_facts(raw['facts'], puppet_proxy)
assert_equal smart_proxies(:puppetmaster).id, Host.find_by_name('sinn1636.lan').puppet_proxy_id
end
end

describe '#classes_in_groups' do
Expand Down

0 comments on commit 155215d

Please sign in to comment.