Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #23799 - Refactor: Make PuppetCa pluggable #586

Merged
merged 1 commit into from
Jun 21, 2018

Conversation

juliantodt
Copy link
Member

@juliantodt juliantodt commented Jun 7, 2018

Since we are planning to offer alternative options for autosinging in the future (token based instead of hostname based) (see redmine issue) and want to allow users to choose their autosigning variant (primarily to allow compatibility with old versions, old foreman versions etc) we need to make the PuppetCA module pluggable, which means moving the autosinging functionality to a provider, which can then be swapped using the SmartProxy settings. We also want to clean up the module a bit and use dependency injections etc. The common logic for listing/signing/cleaning certificates (not autosign-entries) that uses the puppet cert command will remain in the puppetca-module.

This is btw an alternative approach to #576 which should allow for backwards compatibility and a compatible API between the autosigning variants.

Copy link
Member

@timogoebel timogoebel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@juliantodt: Thanks. Looks like solid work. I just left some small comments regarding naming. If they are resolved this looks ready to 🚢.

@@ -2,7 +2,9 @@
# Can be true, false, or http/https to enable just one of the protocols
:enabled: false

# valid providers:
# - puppetca_hostverify (verify CSRs based on hostnames)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puppet calls this basic autosigning. I think we should stick with the term or use something like autosignfile.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like basic autosigning because it says nothing about how it works, autosignfile is better, but because the token based approach will also use a file it is not clear which is which. The thing that will distinguish the providers is the attribute which is compared during autosigning which is certname vs. token.
So imho the best name would be puppetca_hostnamebasedautosigning (or certnamebased) but this is a pain to read.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about HostnameWhitelisting?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that, but wouldn't we want to use snake_case?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, 🐍.


class NotPresent < RuntimeError; end

class << self
class Certmanager
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we find a better name for this? It's not clear what this is doing. Maybe something like CaInterface or CertificateAuthority?

@@ -0,0 +1,57 @@
module ::Proxy::PuppetCa::Hostverify
class Autosigner
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry to be so picky about the names, but what about FileBasedAutosign.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The token-based-autosigning-approach will also use a file, so that would not work. See above.

@@ -2,14 +2,18 @@

module Proxy::PuppetCa
class Api < ::Sinatra::Base
extend Proxy::PuppetCa::DependencyInjection
inject_attr :cert_manager, :cert_manager
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd call this ca or ca_interface or something similar.

E.g. inject_attr :ca_provider, :ca reads a lot cleaner in my opinion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well ca is the whole thing, which consists of managing certificates and autosign-entries. Since the cert_manager basically uses the puppet cert command for everything it does, I thought this would be matching name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see autosigning as part of the CA. Basically you have two separate strings:

  1. Interface to the CA (ask the ca to issue/remove/... a certificate, ...)
  2. Interface to an autosigning provider (list whitelisted hosts, whitelist a host, ...). This is typically not part of the CA, but of the RA.

Certmanager is definitely misleading. Please use something else.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, its part of the puppetCA module and under the puppet/ca/ api endpoint...
But I can understand that that may be confusing, how about just puppet_cert so its obvious it uses the puppet cert command?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, works for me.

@@ -2,14 +2,18 @@

module Proxy::PuppetCa
class Api < ::Sinatra::Base
extend Proxy::PuppetCa::DependencyInjection
inject_attr :cert_manager, :cert_manager
inject_attr :autosigner, :autosigner
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about just autosign?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like to refer to objects with nouns, makes it better to read imho ^^

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, works for me.

require 'puppetca_hostverify/puppetca_hostverify'
require 'puppetca_hostverify/puppetca_hostverify_plugin'

class PuppetCAHostverifyConfigTest < Test::Unit::TestCase
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Please stick either to Ca or CA. I'd prefer the former.

Copy link
Member Author

@juliantodt juliantodt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Left some thoughts about the naming inline @timogoebel

@@ -2,7 +2,9 @@
# Can be true, false, or http/https to enable just one of the protocols
:enabled: false

# valid providers:
# - puppetca_hostverify (verify CSRs based on hostnames)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like basic autosigning because it says nothing about how it works, autosignfile is better, but because the token based approach will also use a file it is not clear which is which. The thing that will distinguish the providers is the attribute which is compared during autosigning which is certname vs. token.
So imho the best name would be puppetca_hostnamebasedautosigning (or certnamebased) but this is a pain to read.

@@ -2,14 +2,18 @@

module Proxy::PuppetCa
class Api < ::Sinatra::Base
extend Proxy::PuppetCa::DependencyInjection
inject_attr :cert_manager, :cert_manager
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well ca is the whole thing, which consists of managing certificates and autosign-entries. Since the cert_manager basically uses the puppet cert command for everything it does, I thought this would be matching name.

@@ -2,14 +2,18 @@

module Proxy::PuppetCa
class Api < ::Sinatra::Base
extend Proxy::PuppetCa::DependencyInjection
inject_attr :cert_manager, :cert_manager
inject_attr :autosigner, :autosigner
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like to refer to objects with nouns, makes it better to read imho ^^

@@ -0,0 +1,57 @@
module ::Proxy::PuppetCa::Hostverify
class Autosigner
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The token-based-autosigning-approach will also use a file, so that would not work. See above.

@juliantodt
Copy link
Member Author

Updated the PR with the requested naming changes.

@@ -2,14 +2,18 @@

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The line above has to be changed to require 'puppetca/puppetca_puppet_cert' as modules/puppetca/puppetca_main.rb is renamed to modules/puppetca/puppetca_puppet_cert.rb so it can load the feature.

Copy link
Member Author

@juliantodt juliantodt Jun 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

puppetca/puppetca_puppet_cert is loaded via plugin_configuration::load_classes, so we don't need it here. This require can therefore be deleted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, deleting it works also.

@juliantodt
Copy link
Member Author

Fixed @dgoetz. Added a migration for the settings, so that users who had set the autosignfile setting will not experience problems.

Copy link
Member

@dgoetz dgoetz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested the latest commit including the migration and it works.

@timogoebel timogoebel merged commit e325683 into theforeman:develop Jun 21, 2018
@timogoebel
Copy link
Member

Thanks, @juliantodt.

@tbrisker
Copy link
Member

Looks like nightly bats tests are now failing with an error regarding PuppetCA, could it be related to this change? http://ci.theforeman.org/blue/rest/organizations/jenkins/pipelines/foreman-nightly-release/runs/248/nodes/34/steps/41/log/?start=0

@dgoetz
Copy link
Member

dgoetz commented Jun 25, 2018

@tbrisker: Yes, it is probably related. The proxy logs could be helpful.
@timogoebel, @juliantodt: Puppet code needs to be adjusted as it adds still autosign file to puppetca after installation and migration.

@timogoebel
Copy link
Member

We already have a PR open to fix the puppet modules, see theforeman/puppet-foreman_proxy#433.
@juliantodt is going to address the comments today.

@tbrisker
Copy link
Member

Thanks @juliantodt and @timogoebel! in the future, when something requires changes in multiple repos, please make sure all PRs are ready to merge first and are merged in coordination to avoid breakages such as this.

@tbrisker
Copy link
Member

@juliantodt @timogoebel Care to update the manuals for 1.19 forward with this change? Looks like some users are stumbling on it - https://community.theforeman.org/t/puppetca-foreman-proxy-disabled-beacuse-of-autosign-issue/12290

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants