summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordermotbradley <dermot_bradley@yahoo.com>2020-07-15 21:24:43 +0100
committerGitHub <noreply@github.com>2020-07-15 16:24:43 -0400
commitc0d239c7eadeae9c9e0b4e692b49e79c8ffcafd2 (patch)
tree4aa743d2d61dd0617747f90d4d684b72705fc240
parent295f88052ba4cd452b55eb5fbd907f90aa6f9c52 (diff)
downloadvyos-cloud-init-c0d239c7eadeae9c9e0b4e692b49e79c8ffcafd2.tar.gz
vyos-cloud-init-c0d239c7eadeae9c9e0b4e692b49e79c8ffcafd2.zip
cc_ca_certs.py: fix blank line problem when removing CAs and adding new one (#483)
Problem: When cc_ca_certs configuration has both "remove-defaults: true" and also specifies one, or more, new trusted CAs to add then the resultant /etc/ca-certificates.conf file's 1st line is blank. As noted in comments in the existing cc_ca_certs.py code blank lines in this file cause problems. Fix: Before adding the cloud-init CA filename to this file first check the size of the file - if is is empty (as all existing CAs have been deleted) then write only the cloud-init CA filename to the file rather than appending it to the file.
-rw-r--r--cloudinit/config/cc_ca_certs.py20
-rw-r--r--tests/unittests/test_handler/test_handler_ca_certs.py22
2 files changed, 35 insertions, 7 deletions
diff --git a/cloudinit/config/cc_ca_certs.py b/cloudinit/config/cc_ca_certs.py
index 7617a8ea..910b78de 100644
--- a/cloudinit/config/cc_ca_certs.py
+++ b/cloudinit/config/cc_ca_certs.py
@@ -67,13 +67,19 @@ def add_ca_certs(certs):
cert_file_contents = "\n".join([str(c) for c in certs])
util.write_file(CA_CERT_FULL_PATH, cert_file_contents, mode=0o644)
- # 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(CA_CERT_CONFIG)
- cur_cont = '\n'.join([line for line in orig.splitlines()
- if line != CA_CERT_FILENAME])
- out = "%s\n%s\n" % (cur_cont.rstrip(), CA_CERT_FILENAME)
+ if os.stat(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" % 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(CA_CERT_CONFIG)
+ cur_cont = '\n'.join([line for line in orig.splitlines()
+ if line != CA_CERT_FILENAME])
+ out = "%s\n%s\n" % (cur_cont.rstrip(), CA_CERT_FILENAME)
util.write_file(CA_CERT_CONFIG, out, omode="wb")
diff --git a/tests/unittests/test_handler/test_handler_ca_certs.py b/tests/unittests/test_handler/test_handler_ca_certs.py
index db0cdf9b..c1aff181 100644
--- a/tests/unittests/test_handler/test_handler_ca_certs.py
+++ b/tests/unittests/test_handler/test_handler_ca_certs.py
@@ -201,6 +201,28 @@ class TestAddCaCerts(TestCase):
mock_load.assert_called_once_with("/etc/ca-certificates.conf")
+ def test_single_cert_to_empty_existing_ca_file(self):
+ """Test adding a single certificate to the trusted CAs
+ when existing ca-certificates.conf is empty"""
+ cert = "CERT1\nLINE2\nLINE3"
+
+ expected = "cloud-init-ca-certs.crt\n"
+
+ with ExitStack() as mocks:
+ mock_write = mocks.enter_context(
+ mock.patch.object(util, 'write_file', autospec=True))
+ mock_stat = mocks.enter_context(
+ mock.patch("cloudinit.config.cc_ca_certs.os.stat")
+ )
+ mock_stat.return_value.st_size = 0
+
+ cc_ca_certs.add_ca_certs([cert])
+
+ mock_write.assert_has_calls([
+ mock.call("/usr/share/ca-certificates/cloud-init-ca-certs.crt",
+ cert, mode=0o644),
+ mock.call("/etc/ca-certificates.conf", expected, omode="wb")])
+
def test_multiple_certs(self):
"""Test adding multiple certificates to the trusted CAs."""
certs = ["CERT1\nLINE2\nLINE3", "CERT2\nLINE2\nLINE3"]