Skip to content

New feature: ca_certs support RHEL#633

Merged
OddBloke merged 18 commits into
canonical:masterfrom
cawamata:ca_certs_add_rhel
Dec 17, 2020
Merged

New feature: ca_certs support RHEL#633
OddBloke merged 18 commits into
canonical:masterfrom
cawamata:ca_certs_add_rhel

Conversation

@cawamata
Copy link
Copy Markdown
Contributor

Proposed Commit Message

New feature of ca_certs, support RHEL

Test Steps

user-data: same as Ubuntu case
on RHEL Server, I confirmed the followings

  • /usr/share/pki/ca-trust-source/anchors/cloud-init-ca-certs.crt exist
  • new certificate is included by trust list

Checklist:

  • My code follows the process laid out in the documentation
  • I have updated or added any unit tests accordingly
  • I have updated or added any documentation accordingly

@igalic
Copy link
Copy Markdown
Collaborator

igalic commented Oct 28, 2020

this is really good timing, becausei just opened https://bugs.launchpad.net/cloud-init/+bug/1901915 to add FreeBSD support, so this is fantastic groundwork!

@cawamata cawamata force-pushed the ca_certs_add_rhel branch 2 times, most recently from 59fff6f to bb55661 Compare October 28, 2020 23:23
@OddBloke OddBloke self-assigned this Nov 3, 2020
@github-actions
Copy link
Copy Markdown

Hello! Thank you for this proposed change to cloud-init. This pull request is now marked as stale as it has not seen any activity in 14 days. If no activity occurs within the next 7 days, this pull request will automatically close.

If you are waiting for code review and you are seeing this message, apologies! Please reply, tagging mitechie, and he will ensure that someone takes a look soon.

(If the pull request is closed, please do feel free to reopen it if you wish to continue working on it.)

@github-actions github-actions Bot added the stale-pr Pull request is stale; will be auto-closed soon label Nov 18, 2020
@igalic
Copy link
Copy Markdown
Collaborator

igalic commented Nov 18, 2020

@mitechie yes, this is awaiting code review and it already has someone assigned

@OddBloke OddBloke removed the stale-pr Pull request is stale; will be auto-closed soon label Nov 18, 2020
Copy link
Copy Markdown
Collaborator

@OddBloke OddBloke left a comment

Choose a reason for hiding this comment

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

Hi @cawamata, thanks for taking the time to work on this and improve cloud-init! I have some comment on the code inline. Let me know if you have any questions!

I'd also like to see the testing here expanded: currently it only covers Ubuntu's behaviour in most cases, and we should at least be covering Red Hat's too. Is expanding the testing something you feel comfortable doing?

Thanks again!

Comment thread cloudinit/config/cc_ca_certs.py Outdated
CA_CERT_FULL_PATH = os.path.join(CA_CERT_PATH, CA_CERT_FILENAME)

distros = ['alpine', 'debian', 'ubuntu']
DISTRO_DEFAULT_CONFIG = {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's a lot of repetition in here; perhaps it's worth having a DEFAULT_CONFIG and a DISTRO_OVERRIDES, so we only capture the Ubuntu/Debian/Alpine settings once? _distro_ca_certs_config would then look in DISTRO_OVERRIDES and return a value found in there, otherwise return DEFAULT_CONFIG.

What do you think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure Ubuntu/Debian/Alpine is set as DEFAULT_CONFIG, because I don't know cloud-init's default distros..
However, if we can use I agree your proposal

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

cloud-init doesn't really have default distros. All I mean here is that those three distros share a common config, so we only need to store it once; as that'll be what we use if there isn't a more specific configuration to use, it is the default configuration, by definition.

Does that make sense?

Comment thread cloudinit/config/cc_ca_certs.py Outdated
Comment on lines +83 to +84
"""Construct a distro-specific ca_certs config dictionary by merging
distro specific changes into base config.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This docstring doesn't sound quite right: this doesn't perform any merging, and we don't have a base config.

Comment thread cloudinit/config/cc_ca_certs.py Outdated
distro specific changes into base config.

@param distro: String providing the distro class name.
@returns: Dict of distro configurations for ntp clients.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

"ntp"

Comment thread cloudinit/config/cc_ca_certs.py Outdated
@param certs: A list of certificate strings.
"""
distro_cfg = _distro_ca_certs_configs(distro_name)
if certs:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You didn't add this line, but as you're already modifying this entire function, inverting this to:

if not certs:
    return

would allow you to dedent everything else in here by one step.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

(that's one of my favourite things to do)

Comment thread cloudinit/config/cc_ca_certs.py Outdated
'rhel': {
'ca_cert_path': '/usr/share/pki/ca-trust-source/',
'ca_cert_filename': 'anchors/cloud-init-ca-certs.crt',
'ca_cert_config': '',
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It's preferable to use None to indicate absence of a value, rather than the empty value.

Comment thread cloudinit/config/cc_ca_certs.py Outdated
Comment on lines +123 to +137
if os.stat(distro_cfg['ca_cert_config']).st_size == 0:
# If the CA_CERT_CONFIG file is empty (i.e. all existing
# CA certs have been deleted) then simply output a single
# line with the cloud-init cert filename.
out = "%s\n" % distro_cfg['ca_cert_filename']
else:
# Append cert filename to CA_CERT_CONFIG file.
# We have to strip the content because blank lines in the file
# causes subsequent entries to be ignored. (LP: #1077020)
orig = util.load_file(distro_cfg['ca_cert_config'])
cr_cont = '\n'.join([line for line in orig.splitlines()
if line != distro_cfg['ca_cert_filename']])
out = "%s\n%s\n" % (cr_cont.rstrip(),
distro_cfg['ca_cert_filename'])
util.write_file(distro_cfg['ca_cert_config'], out, omode="wb")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This feels like it could quite naturally be refactored to a separate function; what do you think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

current function is included add_ca_certs and update_cert_config, so I agree to separate this

Comment thread cloudinit/config/cc_ca_certs.py Outdated
util.write_file(distro_cfg['ca_cert_config'], "", mode=0o644)

if distro_name != 'alpine':
if distro_name == 'debian' or distro_name == 'ubuntu':
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if distro_name == 'debian' or distro_name == 'ubuntu':
if distro_name in ['debian', 'ubuntu']:

reflect PR review comments
Copy link
Copy Markdown
Collaborator

@igalic igalic left a comment

Choose a reason for hiding this comment

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

🙋🏻‍♀️

Comment thread cloudinit/config/cc_ca_certs.py Outdated
Co-authored-by: Mina Galić <me+github@igalic.co>
Copy link
Copy Markdown
Collaborator

@igalic igalic left a comment

Choose a reason for hiding this comment

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

i'd like to see more explicit rhel tests

Comment thread cloudinit/config/cc_ca_certs.py Outdated
'ca_cert_filename': 'cloud-init-ca-certs.crt',
'ca_cert_config': '/etc/ca-certificates.conf',
'ca_cert_system_path': '/etc/ssl/certs/',
'ca_cert_update_exe': 'update-ca-certificates'
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

i would call this ca_cert_update_cmd and make it an array, which is what subp expects

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I updated, please check

Comment thread cloudinit/config/cc_ca_certs.py Outdated
"""
subp.subp(["update-ca-certificates"], capture=False)
distro_cfg = _distro_ca_certs_configs(distro_name)
subp.subp([distro_cfg['ca_cert_update_exe']], capture=False)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

that way, we're ready for a future distro where the update command is actually a sub-command, that this function cannot possibly know about

Comment thread cloudinit/config/cc_ca_certs.py Outdated
Copy link
Copy Markdown
Collaborator

@igalic igalic left a comment

Choose a reason for hiding this comment

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

this looks pretty good from my perspective

@cawamata
Copy link
Copy Markdown
Contributor Author

@OddBloke san
Sorry for late, I updated test case.
Can you re-review this?

Copy link
Copy Markdown
Collaborator

@OddBloke OddBloke left a comment

Choose a reason for hiding this comment

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

Thanks for the update @cawamata! I have three inline comments: the most important is the third, where I propose a modification to pass the config dict around. Let me know what you think!

Comment thread cloudinit/config/cc_ca_certs.py Outdated
Comment thread cloudinit/config/cc_ca_certs.py Outdated

def update_ca_certs():

def _distro_ca_certs_configs(distro):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

A nit (so no need to address it for this to land), but distro is used elsewhere in this file to mean "a Distro instance"; using distro_name instead would avoid that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I updated, please check

Comment thread cloudinit/config/cc_ca_certs.py Outdated
@param distro: String providing the distro class name.
"""
subp.subp(["update-ca-certificates"], capture=False)
distro_cfg = _distro_ca_certs_configs(distro_name)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We call _distro_ca_certs_config(distro_name) in many different places in this PR. Do you think it would make sense to instead call it once (in handle) and then pass the configuration dict itself around?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Okay, to update this, I have to update test case, too.
So I will try

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I updated, please confirm

Copy link
Copy Markdown
Collaborator

@OddBloke OddBloke left a comment

Choose a reason for hiding this comment

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

Thanks for all the work here, @cawamata, this LGTM now!

@OddBloke OddBloke merged commit a5484d0 into canonical:master Dec 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants