Skip to content

Commit

Permalink
schema: pull in james' ca_certs schema. Migrate legacy schema
Browse files Browse the repository at this point in the history
  • Loading branch information
blackboxsw committed Jan 25, 2022
1 parent 9e8c9f8 commit 72c20c9
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 38 deletions.
79 changes: 43 additions & 36 deletions cloudinit/config/cc_ca_certs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,14 @@
#
# This file is part of cloud-init. See LICENSE file for license information.

"""
CA Certs
--------
**Summary:** add ca certificates
This module adds CA certificates to ``/etc/ca-certificates.conf`` and updates
the ssl cert cache using ``update-ca-certificates``. The default certificates
can be removed from the system with the configuration option
``remove-defaults``.
.. note::
certificates must be specified using valid yaml. in order to specify a
multiline certificate, the yaml multiline list syntax must be used
.. note::
For Alpine Linux the "remove-defaults" functionality works if the
ca-certificates package is installed but not if the
ca-certificates-bundle package is installed.
**Internal name:** ``cc_ca_certs``
**Module frequency:** per instance
**Supported distros:** alpine, debian, ubuntu, rhel
**Config keys**::
ca-certs:
remove-defaults: <true/false>
trusted:
- <single line cert>
- |
-----BEGIN CERTIFICATE-----
YOUR-ORGS-TRUSTED-CA-CERT-HERE
-----END CERTIFICATE-----
"""
"""CA Certs: Add ca certificates."""

import os
from textwrap import dedent

from cloudinit import subp, util
from cloudinit.config.schema import get_meta_doc
from cloudinit.settings import PER_INSTANCE

DEFAULT_CONFIG = {
"ca_cert_path": "/usr/share/ca-certificates/",
Expand All @@ -60,9 +28,48 @@
}
}

MODULE_DESCRIPTION = """\
This module adds CA certificates to ``/etc/ca-certificates.conf`` and updates
the ssl cert cache using ``update-ca-certificates``. The default certificates
can be removed from the system with the configuration option
``remove-defaults``.
.. note::
certificates must be specified using valid yaml. in order to specify a
multiline certificate, the yaml multiline list syntax must be used
.. note::
For Alpine Linux the "remove-defaults" functionality works if the
ca-certificates package is installed but not if the
ca-certificates-bundle package is installed.
"""
distros = ["alpine", "debian", "ubuntu", "rhel"]

meta = {
"id": "cc_ca_certs",
"name": "CA Certificates",
"title": "Add ca certificates",
"description": MODULE_DESCRIPTION,
"distros": distros,
"frequency": PER_INSTANCE,
"examples": [
dedent(
"""\
ca-certs:
remove-defaults: true
trusted:
- single_line_cert
- |
-----BEGIN CERTIFICATE-----
YOUR-ORGS-TRUSTED-CA-CERT-HERE
-----END CERTIFICATE-----
"""
)
],
}

__doc__ = get_meta_doc(meta)


def _distro_ca_certs_configs(distro_name):
"""Return a distro-specific ca_certs config dictionary
Expand Down
26 changes: 25 additions & 1 deletion cloudinit/config/cloud-init-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,37 @@
]
}
}
},
"cc_ca_certs": {
"type": "object",
"properties": {
"ca_certs": {
"type": "object",
"properties": {
"remove_defaults": {
"description": "Remove default CA certificates if true. Default: false",
"type": "boolean",
"default": false
},
"trusted": {
"description": "List of trusted CA certificates to add.",
"type": "array",
"items": {"type": "string"},
"minItems": 1
}
},
"additionalProperties": false,
"minProperties": 1
}
}
}
},
"allOf": [
{ "$ref": "#/$defs/cc_apk_configure" },
{ "$ref": "#/$defs/cc_apt_configure" },
{ "$ref": "#/$defs/cc_apt_pipelining" },
{ "$ref": "#/$defs/cc_bootcmd" },
{ "$ref": "#/$defs/cc_byobu" }
{ "$ref": "#/$defs/cc_byobu" },
{ "$ref": "#/$defs/cc_ca_certs" }
]
}
60 changes: 59 additions & 1 deletion tests/unittests/config/test_cc_ca_certs.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
# This file is part of cloud-init. See LICENSE file for license information.
import logging
import re
import shutil
import tempfile
import unittest
from contextlib import ExitStack
from unittest import mock

import pytest

from cloudinit import distros, helpers, subp, util
from cloudinit.config import cc_ca_certs
from tests.unittests.helpers import TestCase
from cloudinit.config.schema import (
SchemaValidationError,
get_schema,
validate_cloudconfig_schema,
)
from tests.unittests.helpers import TestCase, skipUnlessJsonSchema
from tests.unittests.util import get_cloud


Expand Down Expand Up @@ -406,4 +414,54 @@ def test_commands(self):
)


class TestCACertsSchema:
"""Directly test schema rather than through handle."""

@pytest.mark.parametrize(
"config, error_msg",
(
# Invalid schemas
(
{"ca_certs": 1},
"ca_certs: 1 is not of type 'object'",
),
(
{"ca_certs": {}},
re.escape("ca_certs: {} does not have enough properties"),
),
(
{"ca_certs": {"boguskey": 1}},
re.escape(
"ca_certs: Additional properties are not allowed"
" ('boguskey' was unexpected)"
),
),
(
{"ca_certs": {"remove_defaults": 1}},
"ca_certs.remove_defaults: 1 is not of type 'boolean'",
),
(
{"ca_certs": {"trusted": [1]}},
"ca_certs.trusted.0: 1 is not of type 'string'",
),
(
{"ca_certs": {"trusted": []}},
re.escape("ca_certs.trusted: [] is too short"),
),
),
)
@skipUnlessJsonSchema()
def test_schema_validation(self, config, error_msg):
"""Assert expected schema validation and error messages."""
# New-style schema $defs exist in config/cloud-init-schema*.json
schema = get_schema()
if error_msg is None:
validate_cloudconfig_schema(config, schema, strict=True)
else:
with pytest.raises(SchemaValidationError, match=error_msg):
validate_cloudconfig_schema(config, schema, strict=True)


# vi: ts=4 expandtab

# vi: ts=4 expandtab
2 changes: 2 additions & 0 deletions tests/unittests/config/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ def test_get_schema_coalesces_known_schema(self):
"cc_apt_pipelining",
"cc_bootcmd",
"cc_byobu",
"cc_ca_certs",
"cc_keyboard",
"cc_locale",
"cc_ntp",
Expand All @@ -117,6 +118,7 @@ def test_get_schema_coalesces_known_schema(self):
{"$ref": "#/$defs/cc_apt_pipelining"},
{"$ref": "#/$defs/cc_bootcmd"},
{"$ref": "#/$defs/cc_byobu"},
{"$ref": "#/$defs/cc_ca_certs"},
]
found_subschema_defs = []
legacy_schema_keys = []
Expand Down

0 comments on commit 72c20c9

Please sign in to comment.