diff options
| -rwxr-xr-x | cloudinit/cmd/devel/net_convert.py | 13 | ||||
| -rw-r--r-- | cloudinit/cmd/tests/test_main.py | 7 | ||||
| -rw-r--r-- | cloudinit/config/cc_debug.py | 3 | ||||
| -rw-r--r-- | cloudinit/config/cc_salt_minion.py | 6 | ||||
| -rw-r--r-- | cloudinit/config/cc_snappy.py | 3 | ||||
| -rw-r--r-- | cloudinit/handlers/cloud_config.py | 3 | ||||
| -rw-r--r-- | cloudinit/net/netplan.py | 15 | ||||
| -rw-r--r-- | cloudinit/net/network_state.py | 5 | ||||
| -rw-r--r-- | cloudinit/safeyaml.py | 15 | ||||
| -rw-r--r-- | cloudinit/util.py | 16 | ||||
| -rw-r--r-- | tests/unittests/test_data.py | 3 | ||||
| -rw-r--r-- | tests/unittests/test_runs/test_merge_run.py | 3 | ||||
| -rw-r--r-- | tests/unittests/test_runs/test_simple_run.py | 7 | 
13 files changed, 53 insertions, 46 deletions
| diff --git a/cloudinit/cmd/devel/net_convert.py b/cloudinit/cmd/devel/net_convert.py index 1ad7e0bd..9b768304 100755 --- a/cloudinit/cmd/devel/net_convert.py +++ b/cloudinit/cmd/devel/net_convert.py @@ -5,13 +5,12 @@ import argparse  import json  import os  import sys -import yaml  from cloudinit.sources.helpers import openstack  from cloudinit.sources import DataSourceAzure as azure  from cloudinit.sources import DataSourceOVF as ovf -from cloudinit import distros +from cloudinit import distros, safeyaml  from cloudinit.net import eni, netplan, network_state, sysconfig  from cloudinit import log @@ -78,13 +77,12 @@ def handle_args(name, args):      if args.kind == "eni":          pre_ns = eni.convert_eni_data(net_data)      elif args.kind == "yaml": -        pre_ns = yaml.load(net_data) +        pre_ns = safeyaml.load(net_data)          if 'network' in pre_ns:              pre_ns = pre_ns.get('network')          if args.debug:              sys.stderr.write('\n'.join( -                ["Input YAML", -                 yaml.dump(pre_ns, default_flow_style=False, indent=4), ""])) +                ["Input YAML", safeyaml.dumps(pre_ns), ""]))      elif args.kind == 'network_data.json':          pre_ns = openstack.convert_net_json(              json.loads(net_data), known_macs=known_macs) @@ -100,9 +98,8 @@ def handle_args(name, args):                             "input data")      if args.debug: -        sys.stderr.write('\n'.join([ -            "", "Internal State", -            yaml.dump(ns, default_flow_style=False, indent=4), ""])) +        sys.stderr.write('\n'.join( +            ["", "Internal State", safeyaml.dumps(ns), ""]))      distro_cls = distros.fetch(args.distro)      distro = distro_cls(args.distro, {}, None)      config = {} diff --git a/cloudinit/cmd/tests/test_main.py b/cloudinit/cmd/tests/test_main.py index a1e534fb..57b8fdf5 100644 --- a/cloudinit/cmd/tests/test_main.py +++ b/cloudinit/cmd/tests/test_main.py @@ -6,8 +6,9 @@ import os  from six import StringIO  from cloudinit.cmd import main +from cloudinit import safeyaml  from cloudinit.util import ( -    ensure_dir, load_file, write_file, yaml_dumps) +    ensure_dir, load_file, write_file)  from cloudinit.tests.helpers import (      FilesystemMockingTestCase, wrap_and_call) @@ -39,7 +40,7 @@ class TestMain(FilesystemMockingTestCase):              ],              'cloud_init_modules': ['write-files', 'runcmd'],          } -        cloud_cfg = yaml_dumps(self.cfg) +        cloud_cfg = safeyaml.dumps(self.cfg)          ensure_dir(os.path.join(self.new_root, 'etc', 'cloud'))          self.cloud_cfg_file = os.path.join(              self.new_root, 'etc', 'cloud', 'cloud.cfg') @@ -113,7 +114,7 @@ class TestMain(FilesystemMockingTestCase):          """When local-hostname metadata is present, call cc_set_hostname."""          self.cfg['datasource'] = {              'None': {'metadata': {'local-hostname': 'md-hostname'}}} -        cloud_cfg = yaml_dumps(self.cfg) +        cloud_cfg = safeyaml.dumps(self.cfg)          write_file(self.cloud_cfg_file, cloud_cfg)          cmdargs = myargs(              debug=False, files=None, force=False, local=False, reporter=None, diff --git a/cloudinit/config/cc_debug.py b/cloudinit/config/cc_debug.py index 0a039eb3..610dbc8b 100644 --- a/cloudinit/config/cc_debug.py +++ b/cloudinit/config/cc_debug.py @@ -33,6 +33,7 @@ from six import StringIO  from cloudinit import type_utils  from cloudinit import util +from cloudinit import safeyaml  SKIP_KEYS = frozenset(['log_cfgs']) @@ -49,7 +50,7 @@ def _make_header(text):  def _dumps(obj): -    text = util.yaml_dumps(obj, explicit_start=False, explicit_end=False) +    text = safeyaml.dumps(obj, explicit_start=False, explicit_end=False)      return text.rstrip() diff --git a/cloudinit/config/cc_salt_minion.py b/cloudinit/config/cc_salt_minion.py index d6a21d72..cd9cb0b0 100644 --- a/cloudinit/config/cc_salt_minion.py +++ b/cloudinit/config/cc_salt_minion.py @@ -45,7 +45,7 @@ specify them with ``pkg_name``, ``service_name`` and ``config_dir``.  import os -from cloudinit import util +from cloudinit import safeyaml, util  # Note: see https://docs.saltstack.com/en/latest/topics/installation/  # Note: see https://docs.saltstack.com/en/latest/ref/configuration/ @@ -97,13 +97,13 @@ def handle(name, cfg, cloud, log, _args):      if 'conf' in s_cfg:          # Add all sections from the conf object to minion config file          minion_config = os.path.join(const.conf_dir, 'minion') -        minion_data = util.yaml_dumps(s_cfg.get('conf')) +        minion_data = safeyaml.dumps(s_cfg.get('conf'))          util.write_file(minion_config, minion_data)      if 'grains' in s_cfg:          # add grains to /etc/salt/grains          grains_config = os.path.join(const.conf_dir, 'grains') -        grains_data = util.yaml_dumps(s_cfg.get('grains')) +        grains_data = safeyaml.dumps(s_cfg.get('grains'))          util.write_file(grains_config, grains_data)      # ... copy the key pair if specified diff --git a/cloudinit/config/cc_snappy.py b/cloudinit/config/cc_snappy.py index 15bee2d3..b94cd04e 100644 --- a/cloudinit/config/cc_snappy.py +++ b/cloudinit/config/cc_snappy.py @@ -68,6 +68,7 @@ is ``auto``. Options are:  from cloudinit import log as logging  from cloudinit.settings import PER_INSTANCE  from cloudinit import temp_utils +from cloudinit import safeyaml  from cloudinit import util  import glob @@ -188,7 +189,7 @@ def render_snap_op(op, name, path=None, cfgfile=None, config=None):              # Note, however, we do not touch config files on disk.              nested_cfg = {'config': {shortname: config}}              (fd, cfg_tmpf) = temp_utils.mkstemp() -            os.write(fd, util.yaml_dumps(nested_cfg).encode()) +            os.write(fd, safeyaml.dumps(nested_cfg).encode())              os.close(fd)              cfgfile = cfg_tmpf diff --git a/cloudinit/handlers/cloud_config.py b/cloudinit/handlers/cloud_config.py index 99bf0e61..2a307364 100644 --- a/cloudinit/handlers/cloud_config.py +++ b/cloudinit/handlers/cloud_config.py @@ -14,6 +14,7 @@ from cloudinit import handlers  from cloudinit import log as logging  from cloudinit import mergers  from cloudinit import util +from cloudinit import safeyaml  from cloudinit.settings import (PER_ALWAYS) @@ -75,7 +76,7 @@ class CloudConfigPartHandler(handlers.Handler):                  '',              ]              lines.extend(file_lines) -            lines.append(util.yaml_dumps(self.cloud_buf)) +            lines.append(safeyaml.dumps(self.cloud_buf))          else:              lines = []          util.write_file(self.cloud_fn, "\n".join(lines), 0o600) diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py index e54a34e5..54be1221 100644 --- a/cloudinit/net/netplan.py +++ b/cloudinit/net/netplan.py @@ -8,6 +8,7 @@ from .network_state import subnet_is_ipv6, NET_CONFIG_TO_V2  from cloudinit import log as logging  from cloudinit import util +from cloudinit import safeyaml  from cloudinit.net import SYS_CLASS_NET, get_devicelist  KNOWN_SNAPD_CONFIG = b"""\ @@ -235,9 +236,9 @@ class Renderer(renderer.Renderer):          # if content already in netplan format, pass it back          if network_state.version == 2:              LOG.debug('V2 to V2 passthrough') -            return util.yaml_dumps({'network': network_state.config}, -                                   explicit_start=False, -                                   explicit_end=False) +            return safeyaml.dumps({'network': network_state.config}, +                                  explicit_start=False, +                                  explicit_end=False)          ethernets = {}          wifis = {} @@ -359,10 +360,10 @@ class Renderer(renderer.Renderer):          # workaround yaml dictionary key sorting when dumping          def _render_section(name, section):              if section: -                dump = util.yaml_dumps({name: section}, -                                       explicit_start=False, -                                       explicit_end=False, -                                       noalias=True) +                dump = safeyaml.dumps({name: section}, +                                      explicit_start=False, +                                      explicit_end=False, +                                      noalias=True)                  txt = util.indent(dump, ' ' * 4)                  return [txt]              return [] diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py index c0c415d0..b485f3d9 100644 --- a/cloudinit/net/network_state.py +++ b/cloudinit/net/network_state.py @@ -12,6 +12,7 @@ import struct  import six +from cloudinit import safeyaml  from cloudinit import util  LOG = logging.getLogger(__name__) @@ -253,7 +254,7 @@ class NetworkStateInterpreter(object):              'config': self._config,              'network_state': self._network_state,          } -        return util.yaml_dumps(state) +        return safeyaml.dumps(state)      def load(self, state):          if 'version' not in state: @@ -272,7 +273,7 @@ class NetworkStateInterpreter(object):              setattr(self, key, state[key])      def dump_network_state(self): -        return util.yaml_dumps(self._network_state) +        return safeyaml.dumps(self._network_state)      def as_dict(self):          return {'version': self._version, 'config': self._config} diff --git a/cloudinit/safeyaml.py b/cloudinit/safeyaml.py index 3bd5e03d..d6f5f95b 100644 --- a/cloudinit/safeyaml.py +++ b/cloudinit/safeyaml.py @@ -6,6 +6,8 @@  import yaml +YAMLError = yaml.YAMLError +  class _CustomSafeLoader(yaml.SafeLoader):      def construct_python_unicode(self, node): @@ -27,4 +29,17 @@ class NoAliasSafeDumper(yaml.dumper.SafeDumper):  def load(blob):      return(yaml.load(blob, Loader=_CustomSafeLoader)) + +def dumps(obj, explicit_start=True, explicit_end=True, noalias=False): +    """Return data in nicely formatted yaml.""" + +    return yaml.dump(obj, +                     line_break="\n", +                     indent=4, +                     explicit_start=explicit_start, +                     explicit_end=explicit_end, +                     default_flow_style=False, +                     Dumper=(NoAliasSafeDumper +                             if noalias else yaml.dumper.Dumper)) +  # vi: ts=4 expandtab diff --git a/cloudinit/util.py b/cloudinit/util.py index 0d338ca7..1f600df4 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -38,7 +38,6 @@ from base64 import b64decode, b64encode  from six.moves.urllib import parse as urlparse  import six -import yaml  from cloudinit import importer  from cloudinit import log as logging @@ -958,7 +957,7 @@ def load_yaml(blob, default=None, allowed=(dict,)):                               " but got %s instead") %                              (allowed, type_utils.obj_name(converted)))          loaded = converted -    except (yaml.YAMLError, TypeError, ValueError) as e: +    except (safeyaml.YAMLError, TypeError, ValueError) as e:          msg = 'Failed loading yaml blob'          mark = None          if hasattr(e, 'context_mark') and getattr(e, 'context_mark'): @@ -1629,19 +1628,6 @@ def json_dumps(data):          raise -def yaml_dumps(obj, explicit_start=True, explicit_end=True, noalias=False): -    """Return data in nicely formatted yaml.""" - -    return yaml.dump(obj, -                     line_break="\n", -                     indent=4, -                     explicit_start=explicit_start, -                     explicit_end=explicit_end, -                     default_flow_style=False, -                     Dumper=(safeyaml.NoAliasSafeDumper -                             if noalias else yaml.dumper.Dumper)) - -  def ensure_dir(path, mode=None):      if not os.path.isdir(path):          # Make the dir and adjust the mode diff --git a/tests/unittests/test_data.py b/tests/unittests/test_data.py index 3efe7adf..22cf8f28 100644 --- a/tests/unittests/test_data.py +++ b/tests/unittests/test_data.py @@ -27,6 +27,7 @@ from cloudinit.settings import (PER_INSTANCE)  from cloudinit import sources  from cloudinit import stages  from cloudinit import user_data as ud +from cloudinit import safeyaml  from cloudinit import util  from cloudinit.tests import helpers @@ -502,7 +503,7 @@ c: 4          data = [{'content': '#cloud-config\npassword: gocubs\n'},                  {'content': '#cloud-config\nlocale: chicago\n'},                  {'content': non_decodable}] -        message = b'#cloud-config-archive\n' + util.yaml_dumps(data).encode() +        message = b'#cloud-config-archive\n' + safeyaml.dumps(data).encode()          self.reRoot()          ci = stages.Init() diff --git a/tests/unittests/test_runs/test_merge_run.py b/tests/unittests/test_runs/test_merge_run.py index d1ac4942..ff27a280 100644 --- a/tests/unittests/test_runs/test_merge_run.py +++ b/tests/unittests/test_runs/test_merge_run.py @@ -7,6 +7,7 @@ import tempfile  from cloudinit.tests import helpers  from cloudinit.settings import PER_INSTANCE +from cloudinit import safeyaml  from cloudinit import stages  from cloudinit import util @@ -26,7 +27,7 @@ class TestMergeRun(helpers.FilesystemMockingTestCase):              'system_info': {'paths': {'run_dir': new_root}}          }          ud = helpers.readResource('user_data.1.txt') -        cloud_cfg = util.yaml_dumps(cfg) +        cloud_cfg = safeyaml.dumps(cfg)          util.ensure_dir(os.path.join(new_root, 'etc', 'cloud'))          util.write_file(os.path.join(new_root, 'etc',                                       'cloud', 'cloud.cfg'), cloud_cfg) diff --git a/tests/unittests/test_runs/test_simple_run.py b/tests/unittests/test_runs/test_simple_run.py index d67c422c..cb3aae60 100644 --- a/tests/unittests/test_runs/test_simple_run.py +++ b/tests/unittests/test_runs/test_simple_run.py @@ -5,6 +5,7 @@ import os  from cloudinit.settings import PER_INSTANCE +from cloudinit import safeyaml  from cloudinit import stages  from cloudinit.tests import helpers  from cloudinit import util @@ -34,7 +35,7 @@ class TestSimpleRun(helpers.FilesystemMockingTestCase):              ],              'cloud_init_modules': ['write-files', 'spacewalk', 'runcmd'],          } -        cloud_cfg = util.yaml_dumps(self.cfg) +        cloud_cfg = safeyaml.dumps(self.cfg)          util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud'))          util.write_file(os.path.join(self.new_root, 'etc',                                       'cloud', 'cloud.cfg'), cloud_cfg) @@ -130,7 +131,7 @@ class TestSimpleRun(helpers.FilesystemMockingTestCase):          # re-write cloud.cfg with unverified_modules override          cfg = copy.deepcopy(self.cfg)          cfg['unverified_modules'] = ['spacewalk']  # Would have skipped -        cloud_cfg = util.yaml_dumps(cfg) +        cloud_cfg = safeyaml.dumps(cfg)          util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud'))          util.write_file(os.path.join(self.new_root, 'etc',                                       'cloud', 'cloud.cfg'), cloud_cfg) @@ -159,7 +160,7 @@ class TestSimpleRun(helpers.FilesystemMockingTestCase):          cfg = copy.deepcopy(self.cfg)          # Represent empty configuration in /etc/cloud/cloud.cfg          cfg['cloud_init_modules'] = None -        cloud_cfg = util.yaml_dumps(cfg) +        cloud_cfg = safeyaml.dumps(cfg)          util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud'))          util.write_file(os.path.join(self.new_root, 'etc',                                       'cloud', 'cloud.cfg'), cloud_cfg) | 
