diff options
author | Joshua Harlow <harlowja@gmail.com> | 2013-09-06 23:46:27 -0700 |
---|---|---|
committer | Joshua Harlow <harlowja@gmail.com> | 2013-09-06 23:46:27 -0700 |
commit | e058913486519c2a9e036aad95f6e029dbc89966 (patch) | |
tree | de61cb4024d9d9359f91090684684c15a077e84b /cloudinit | |
parent | c3e070de802ebc0f44722d4238f5447b93cc9fac (diff) | |
download | vyos-cloud-init-e058913486519c2a9e036aad95f6e029dbc89966.tar.gz vyos-cloud-init-e058913486519c2a9e036aad95f6e029dbc89966.zip |
Add jsonschema for namespaced and verifiable module
configuration checking as well as make most of the
module logic happen in the module itself instead of
interacting with the distro object.
Diffstat (limited to 'cloudinit')
-rw-r--r-- | cloudinit/config/cc_seed_random.py | 94 | ||||
-rw-r--r-- | cloudinit/distros/__init__.py | 10 | ||||
-rw-r--r-- | cloudinit/exceptions.py | 21 |
3 files changed, 103 insertions, 22 deletions
diff --git a/cloudinit/config/cc_seed_random.py b/cloudinit/config/cc_seed_random.py index 5d9890d5..acacb8f7 100644 --- a/cloudinit/config/cc_seed_random.py +++ b/cloudinit/config/cc_seed_random.py @@ -16,21 +16,91 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +import base64 +from StringIO import StringIO + +import jsonschema +from jsonschema import exceptions as js_exc + +from cloudinit import exceptions as exc from cloudinit.settings import PER_INSTANCE +from cloudinit import util frequency = PER_INSTANCE +schema = { + 'type': 'object', + 'properties': { + "random_seed": { + "type": "object", + "oneOf": [ + {"$ref": "#/definitions/random_seed"}, + ], + }, + }, + "required": ["random_seed"], + "additionalProperties": True, + "definitions": { + 'random_seed': { + 'type': 'object', + "properties" : { + 'data': { + 'type': "string", + }, + 'file': { + 'type': 'string', + }, + 'encoding': { + "enum": ["base64", 'gzip', 'b64', 'gz', ''], + }, + }, + "additionalProperties": True, + }, + }, +} + + +def validate(cfg): + """Method that can be used to ask if the given configuration will be + accepted as valid by this module, without having to actually activate this + module.""" + try: + jsonschema.validate(cfg, schema) + except js_exc.ValidationError as e: + raise exc.FormatValidationError("Invalid configuration: %s" % str(e)) + + +def _decode(data, encoding=None): + if not encoding: + return data + if not data: + return '' + if encoding.lower() in ['base64', 'b64']: + return base64.b64decode(data) + elif encoding.lower() in ['gzip', 'gz']: + return util.decomp_gzip(data, quiet=False) + else: + raise IOError("Unknown random_seed encoding: %s" % (encoding)) def handle(name, cfg, cloud, log, _args): - random_seed = None - # Prefer metadata over cfg for random_seed - for src in (cloud.datasource.metadata, cfg): - if not src: - continue - tmp_random_seed = src.get('random_seed') - if tmp_random_seed and isinstance(tmp_random_seed, (str, basestring)): - random_seed = tmp_random_seed - break - if random_seed: - log.debug("%s: setting random seed", name) - cloud.distro.set_random_seed(random_seed) + if not cfg or "random_seed" not in cfg: + log.debug(("Skipping module named %s, " + "no 'random_seed' configuration found"), name) + return + + validate(cfg) + my_cfg = cfg['random_seed'] + seed_path = my_cfg.get('file', '/dev/urandom') + seed_buf = StringIO() + seed_buf.write(_decode(my_cfg.get('data', ''), + encoding=my_cfg.get('encoding'))) + + metadata = cloud.datasource.metadata + if metadata and 'random_seed' in metadata: + seed_buf.write(metadata['random_seed']) + + seed_data = seed_buf.getvalue() + if len(seed_data): + log.debug("%s: adding %s bytes of random seed entrophy to %s", name, + len(seed_data), seed_path) + util.append_file(seed_path, seed_data) diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py index 5642b529..74e95797 100644 --- a/cloudinit/distros/__init__.py +++ b/cloudinit/distros/__init__.py @@ -52,7 +52,6 @@ class Distro(object): ci_sudoers_fn = "/etc/sudoers.d/90-cloud-init-users" hostname_conf_fn = "/etc/hostname" tz_zone_dir = "/usr/share/zoneinfo" - random_seed_fn = '/dev/urandom' def __init__(self, name, cfg, paths): self._paths = paths @@ -170,15 +169,6 @@ class Distro(object): distros.extend(OSFAMILIES[family]) return distros - def set_random_seed(self, seed): - if not self.random_seed_fn or not os.path.exists(self.random_seed_fn): - raise IOError("No random seed filename provided for %s" - % (self.name)) - if not seed: - raise IOError("Unable to set empty random seed") - # Ensure we only write 512 bytes worth - util.append_file(self.random_seed_fn, seed[0:512]) - def update_hostname(self, hostname, fqdn, prev_hostname_fn): applying_hostname = hostname diff --git a/cloudinit/exceptions.py b/cloudinit/exceptions.py new file mode 100644 index 00000000..c09d15b1 --- /dev/null +++ b/cloudinit/exceptions.py @@ -0,0 +1,21 @@ +# vi: ts=4 expandtab +# +# Copyright (C) 2013 Yahoo! Inc. +# +# Author: Joshua Harlow <harlowja@yahoo-inc.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +class FormatValidationError(Exception): + pass |