def _dump_yaml(applied):
"""
Dumps dict correctly processing multiline pre & postDescription string
:param applied: dict -> filled config ready to be converted to yaml
:return: str -> yaml config
"""
def str_presenter(dumper, data):
# check for multiline strings
if len(data.splitlines()) == 1 and data[-1] == '\n':
return dumper.represent_scalar(
'tag:yaml.org,2002:str', data, style='>')
if len(data.splitlines()) > 1:
return dumper.represent_scalar(
'tag:yaml.org,2002:str', data, style='|')
return dumper.represent_scalar(
'tag:yaml.org,2002:str', data.strip())
yaml.add_representer(unicode, str_presenter)
yaml.add_representer(str, str_presenter)
return yaml.dump(applied, default_flow_style=False, width=1000)
python类add_representer()的实例源码
def device_add(device, mgmt, role, network, username, password):
device_conf = device + '.yaml'
print device_conf
device_dir = inv_dir + device + '/'
print device_dir
directory = os.path.dirname(device_dir) + '/'
print directory
if not os.path.exists(directory):
os.makedirs(directory)
target_dict = defaultdict(dict)
target_dict[device]['name'] = device
target_dict[device]['mgmt_ip'] = mgmt_ip
target_dict[device]['role'] = role
target_dict[device]['network'] = network
target_dict[device]['username'] = username
target_dict[device]['password'] = password
with open(directory + device_conf, 'w') as outfile:
yaml.add_representer(defaultdict, Representer.represent_dict)
yaml.dump(target_dict, outfile, default_flow_style=False)
return device + ' config added to inventory'
def configure_yml(self):
def represent_ordereddict(dumper, data):
value = []
for item_key, item_value in data.items():
node_key = dumper.represent_data(item_key)
node_value = dumper.represent_data(item_value)
value.append((node_key, node_value))
return yaml.nodes.MappingNode(u'tag:yaml.org,2002:map', value)
self.collect_answers()
cfg = self.process_answers()
yaml.add_representer(OrderedDict, represent_ordereddict)
return yaml.dump(cfg, default_flow_style=False)
def get_yaml(self, restrict_to_fields=ZettelFieldsOrdered):
yaml.add_representer(quoted, quoted_presenter)
yaml.add_representer(literal, str_presenter)
yaml.add_representer(OrderedDict, ordered_dict_presenter)
parse_zettel(self.zettel)
yaml_zettel = OrderedDict()
for key in ZettelFields:
if key not in self.zettel:
continue
if key not in restrict_to_fields:
continue
if key in ZettelStringFields:
yaml_zettel[key] = literal(self.zettel[key])
else:
yaml_zettel[key] = self.zettel[key].copy()
return yaml.dump(yaml_zettel, default_flow_style=False)
def __init__(self, full):
super(YamlOutput, self).__init__(full)
yaml.add_representer(unicode, self.string_presenter)
yaml.add_representer(str, self.string_presenter)
def _install_customer_representers():
""" Installs custom yaml representers so that yaml.dump() can use print out our custom classes like
LineStr, LineDict, LineList """
# TODO(jroovers): we need to support different yaml types like Float, Int, etc so that we don't print
# everything like a string (i.e. wrap atomic type in quotes)
def linestr_representer(dumper, data):
node = dumper.represent_str(str(data))
# If the linestring was entered as a string starting with |, we want to print it in the | again, because
# otherwise pyyaml will insert too many newlines
if hasattr(data, 'style') and '|' == data.style:
node.style = data.style
return node
def lineint_representer(dumper, data):
return dumper.represent_int(data)
def linefloat_representer(dumper, data):
return dumper.represent_float(data)
def linedict_representer(dumper, data):
return dumper.represent_dict(data)
def linelist_representer(dumper, data):
return dumper.represent_list(data)
yaml.add_representer(LineInt, lineint_representer)
yaml.add_representer(LineFloat, linefloat_representer)
yaml.add_representer(LineStr, linestr_representer)
yaml.add_representer(LineDict, linedict_representer)
yaml.add_representer(LineList, linelist_representer)
def setup_yaml():
""" http://stackoverflow.com/a/8661021 """
represent_dict_order = lambda self, data: self.represent_mapping(
'tag:yaml.org,2002:map', data.items())
yaml.add_representer(collections.OrderedDict, represent_dict_order)
def write_content(self, content=None):
if content:
self.content = content
self.__documents[self.__document_id] = self.content
def representer(dumper, data):
"""Represents a dict key started with '!' as a YAML tag
Assumes that there is only one !tag in the dict at the
current indent.
Python object:
{"!unknown_tag": ["some content", ]}
Resulting yaml:
!unknown_tag
- some content
"""
key = data.keys()[0]
if key.startswith("!"):
value = data[key]
if type(value) is dict:
node = dumper.represent_mapping(key, value)
elif type(value) is list:
node = dumper.represent_sequence(key, value)
else:
node = dumper.represent_scalar(key, value)
else:
node = dumper.represent_mapping(u'tag:yaml.org,2002:map', data)
return node
yaml.add_representer(dict, representer)
with self.__get_file("w") as file_obj:
yaml.dump_all(self.__documents, file_obj,
default_flow_style=self.default_flow_style,
default_style=self.default_style)
def dump(self):
dumpdata = {}
dumpdata['hosts'] = self.dump_hosts()
dumpdata['hostgroup'] = self.dump_hostgroups()
dumpdata['architecture'] = self.dump_arch()
dumpdata['environment'] = self.dump_env()
dumpdata['os'] = self.dump_os()
dumpdata['model'] = self.dump_model()
dumpdata['media'] = self.dump_media()
dumpdata['domain'] = self.dump_domain()
dumpdata['settings'] = self.dump_settings()
dumpdata['subnet'] = self.dump_subnet()
dumpdata['smart-proxy'] = self.dump_smartproxy()
dumpdata['partition-table'] = self.dump_ptable()
dumpdata['provisioning-template'] = self.dump_provisioningtpl()
dumpdata['users'] = self.dump_users()
dumpdata['users'] = self.dump_users()
dumpdata['auth-source-ldap'] = self.dump_ldaps()
dumpdata['usergroups'] = self.dump_usergroups()
dumpdata['roles'] = self.dump_roles()
# print the result
fmyml = { 'foreman': dumpdata }
def str_presenter(dumper, data):
try:
dlen = len(data.splitlines())
except TypeError:
return dumper.represent_scalar('tag:yaml.org,2002:str', data)
if (dlen > 1):
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')
return dumper.represent_scalar('tag:yaml.org,2002:str', data)
yaml.add_representer(unicode, str_presenter)
yaml.add_representer(str, str_presenter)
yml = yaml.dump(fmyml, allow_unicode=True, default_flow_style=False )
print( (yml) )
def load_ordered_config(config_path):
"""
Loads the configuration in the same order as it's defined in yaml file,
so that, while saving it in new format, order is maintained
Args:
config_path (str): Path to the configuration file
Returns:
config(dict): Returns the configurations in the defined ordered
"""
# To load data from yaml in ordered dict format
_mapping_tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG
def dict_representer(dumper, data):
return dumper.represent_mapping(_mapping_tag, data.iteritems())
def dict_constructor(loader, node):
return collections.OrderedDict(loader.construct_pairs(node))
yaml.add_representer(collections.OrderedDict, dict_representer)
yaml.add_constructor(_mapping_tag, dict_constructor)
# format the output to print a blank scalar rather than null
def represent_none(self, _):
return self.represent_scalar('tag:yaml.org,2002:null', u'')
yaml.add_representer(type(None), represent_none)
# read input from home directory for pull requests
with open(config_path, 'r') as f:
config = yaml.load(f)
return config
def read(self):
# ensure yaml uses a defaultdict(str)
yaml.add_representer(collections.defaultdict,
Representer.represent_str)
try:
with open(os.path.expanduser(self.path), 'r') as fh:
self.conf = yaml.load(fh)
except Exception as ex:
logger.error("Unable to read config (%s): %s" % (self.path, ex))
sys.exit(1)
def _readConfig():
# ensure yaml uses a defaultdict(str)
yaml.add_representer(collections.defaultdict,
Representer.represent_str)
try:
with open(os.path.expanduser(ConfigBase.path), 'r') as fh:
config = yaml.load(fh)
except Exception as ex:
logger.error("Unable to read config (%s): %s" % (ConfigBase.path, ex))
sys.exit(1)
return config
def __init__(self, **options):
super(YamlReaderWriter, self).__init__(**options)
try:
import yaml
import yaml.resolver
except ImportError:
raise RuntimeError('To use YAML, please install PyYAML first')
#
# The code to preserve order of items is taken from here:
# https://stackoverflow.com/a/21048064/38611
#
_mapping_tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG
def dict_representer(dumper, data):
return dumper.represent_dict(data.items())
def dict_constructor(loader, node):
return collections.OrderedDict(loader.construct_pairs(node))
yaml.add_representer(collections.OrderedDict, dict_representer)
yaml.add_constructor(_mapping_tag, dict_constructor)
self.yaml = yaml
self.default_dump_options = {
'indent': 2,
'default_flow_style': False,
}
def _dict_representer(dumper, data):
return dumper.represent_dict(data.items())
#yaml.add_representer(recdefaultdict, _dict_representer)
def _init_yaml_ordereddict():
def ordered_dict_presenter(dumper, data):
return dumper.represent_dict(data.items())
yaml.add_representer(collections.OrderedDict, ordered_dict_presenter)
def write_content(self, content=None):
if content:
self.content = content
self.__documents[self.__document_id] = self.content
def representer(dumper, data):
"""Represents a dict key started with '!' as a YAML tag
Assumes that there is only one !tag in the dict at the
current indent.
Python object:
{"!unknown_tag": ["some content", ]}
Resulting yaml:
!unknown_tag
- some content
"""
key = data.keys()[0]
if key.startswith("!"):
value = data[key]
if type(value) is dict:
node = dumper.represent_mapping(key, value)
elif type(value) is list:
node = dumper.represent_sequence(key, value)
else:
node = dumper.represent_scalar(key, value)
else:
node = dumper.represent_mapping(u'tag:yaml.org,2002:map', data)
return node
yaml.add_representer(dict, representer)
with self.__get_file("w") as file_obj:
yaml.dump_all(self.__documents, file_obj,
default_flow_style=self.default_flow_style,
default_style=self.default_style)
def ordered_dump(data, stream=None, Dumper=yaml.Dumper, **kwds):
# ordered_dump(data, Dumper=yaml.SafeDumper)
class OrderedDumper(Dumper):
pass
def _dict_representer(dumper, data):
return dumper.represent_mapping(
yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
data.items())
OrderedDumper.add_representer(OrderedDict, _dict_representer)
return yaml.dump(data, stream, OrderedDumper, **kwds)
def dump(self, ser_obj):
if not self.representers_added:
for SerializableChild in Serializable.__subclasses__():
yaml.add_representer(SerializableChild, self.init_representer)
self.representers_added = True
return yaml.dump(ser_obj)
def arrow_representer(dumper, data):
"""Represent an `arrow.arrow.Arrow` object as a scalar in ISO format.
>>> yaml.add_representer(arrow.arrow.Arrow, arrow_representer)
>>> yaml.dump(arrow.get(1367900664))
"! '2013-05-07T04:24:24+00:00'\\n"
"""
return dumper.represent_scalar(u'!', six.text_type(data.isoformat(b'T' if six.PY2 else 'T')))
def main():
parser = argparse.ArgumentParser(
description="""Pull records for a batch of users and submit to external services."""
)
parser.add_argument('--timeout', dest="timeout", type=int, default=10)
parser.add_argument('--limit', dest="limit", type=int, default=10,
help="""Retrieve data for at most this many users concurrently.""")
parser.add_argument('--log-file', dest='logfile', default='batch.log')
parser.add_argument('input', nargs='?', type=argparse.FileType('r'), default=None)
parser.add_argument('--collect-only', dest="collect_only", action="store_true")
parser.add_argument('--debug', dest="debug", action="store_true", default=False)
config = stethoscope.api.factory.get_config()
args = parser.parse_args()
for plugin in ['BITFIT', 'JAMF']:
config[plugin + '_TIMEOUT'] = args.timeout
config['LOGBOOK'] = stethoscope.utils.setup_logbook(args.logfile)
config['LOGBOOK'].push_application()
config['DEBUG'] = args.debug
config['TESTING'] = args.debug
yaml.add_representer(arrow.arrow.Arrow, arrow_representer)
yaml.SafeDumper.add_representer(arrow.arrow.Arrow, arrow_representer)
task.react(_main, (args, config))
def setup_yaml():
_mapping_tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG
yaml.add_representer(collections.OrderedDict, dict_representer)
yaml.add_representer(os._Environ, dict_representer)
yaml.add_constructor(_mapping_tag, dict_constructor)
def dict_as_yaml(data):
yaml.add_representer(quoted, quoted_presenter)
yaml.add_representer(literal, str_presenter)
yaml.add_representer(OrderedDict, ordered_dict_presenter)
presented_data = OrderedDict()
for key in data:
presented_data[key] = data[key]
return yaml.dump(presented_data, default_flow_style=False)
def register_yaml_representer():
# Register our custom representer for YAML output
yaml.add_representer(OrderedDict, represent_ordereddict)
# Custom representer for getting clean YAML output that preserves the order in
# an OrderedDict.
# Inspired by:
# http://stackoverflow.com/a/16782282/7169408
def setup_yaml():
"""Set YAML to use OrderedDict
http://stackoverflow.com/a/8661021"""
represent_dict_order = lambda self, data: self.represent_mapping( # noqa
'tag:yaml.org,2002:map', data.items()
)
yaml.add_representer(OrderedDict, represent_dict_order)
def main():
"""Main application entry point."""
if len(sys.argv) != 2:
print "Usage: yamlcalc <input-file>"
return
mapping_tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG
sequence_tag = yaml.resolver.BaseResolver.DEFAULT_SEQUENCE_TAG
yaml.add_constructor(mapping_tag, dict_constructor)
yaml.add_constructor(sequence_tag, list_constructor)
yaml.add_representer(CalcDict, dict_representer)
yaml.add_representer(CalcList, list_representer)
try:
with open(sys.argv[1]) as infp:
top = yaml.load(infp)
if not isinstance(top, CalcDict):
type_name = type(top).__name__
err("Top level element should be dict not {0}".format(type_name))
defs = {}
defs_str = top.get("DEFS", "")
try:
exec defs_str in defs
except Exception as exc:
err("Error executing DEFS: {0}".format(exc))
CalcContainer.set_top(defs, top)
view = top.get("VIEW", {})
writer_type = view.get("type", "raw")
writer_func_name = "_".join(writer_type.split("-"))
try:
write = globals()["write_" + writer_func_name]
except KeyError:
err("Error unsupporter writer: {0}".format(writer_type))
outdir, ext = os.path.splitext(sys.argv[1])
if os.path.exists(outdir):
if not os.path.isdir(outdir):
err("Path exists but is not a directory: {0}".format(outdir))
else:
try:
os.mkdir(outdir)
except OSError as exc:
err("Error create directory: {0}".format(outdir))
write(view, top, outdir)
except IOError as exc:
err("Error opening file: {0}".format(exc))
except yaml.YAMLError as exc:
err("Error parsing input: {0}".format(exc))
def juju_state_to_yaml(yaml_path, namespace_separator=':',
allow_hyphens_in_keys=True, mode=None):
"""Update the juju config and state in a yaml file.
This includes any current relation-get data, and the charm
directory.
This function was created for the ansible and saltstack
support, as those libraries can use a yaml file to supply
context to templates, but it may be useful generally to
create and update an on-disk cache of all the config, including
previous relation data.
By default, hyphens are allowed in keys as this is supported
by yaml, but for tools like ansible, hyphens are not valid [1].
[1] http://www.ansibleworks.com/docs/playbooks_variables.html#what-makes-a-valid-variable-name
"""
config = charmhelpers.core.hookenv.config()
# Add the charm_dir which we will need to refer to charm
# file resources etc.
config['charm_dir'] = charm_dir
config['local_unit'] = charmhelpers.core.hookenv.local_unit()
config['unit_private_address'] = charmhelpers.core.hookenv.unit_private_ip()
config['unit_public_address'] = charmhelpers.core.hookenv.unit_get(
'public-address'
)
# Don't use non-standard tags for unicode which will not
# work when salt uses yaml.load_safe.
yaml.add_representer(six.text_type,
lambda dumper, value: dumper.represent_scalar(
six.u('tag:yaml.org,2002:str'), value))
yaml_dir = os.path.dirname(yaml_path)
if not os.path.exists(yaml_dir):
os.makedirs(yaml_dir)
if os.path.exists(yaml_path):
with open(yaml_path, "r") as existing_vars_file:
existing_vars = yaml.load(existing_vars_file.read())
else:
with open(yaml_path, "w+"):
pass
existing_vars = {}
if mode is not None:
os.chmod(yaml_path, mode)
if not allow_hyphens_in_keys:
config = dict_keys_without_hyphens(config)
existing_vars.update(config)
update_relations(existing_vars, namespace_separator)
with open(yaml_path, "w+") as fp:
fp.write(yaml.dump(existing_vars, default_flow_style=False))