def _update_grains(self, content, filename="/etc/salt/grains"):
"""
Update the yaml file without destroying other content
"""
log.info("Updating {}".format(filename))
# Keep yaml human readable/editable
friendly_dumper = yaml.SafeDumper
friendly_dumper.ignore_aliases = lambda self, data: True
with open(filename, 'w') as minion_grains:
minion_grains.write(yaml.dump(content,
Dumper=friendly_dumper,
default_flow_style=False))
log.info("Syncing grains")
__salt__['saltutil.sync_grains']()
python类SafeDumper()的实例源码
def default():
"""
Remove the .../stack/defaults directory. Preserve available_roles
"""
# Keep yaml human readable/editable
friendly_dumper = yaml.SafeDumper
friendly_dumper.ignore_aliases = lambda self, data: True
preserve = {}
content = None
pathname = "/srv/pillar/ceph/stack/default/{}/cluster.yml".format('ceph')
with open(pathname, "r") as sls_file:
content = yaml.safe_load(sls_file)
preserve['available_roles'] = content['available_roles']
stack_default = "/srv/pillar/ceph/stack/default"
shutil.rmtree(stack_default)
os.makedirs("{}/{}".format(stack_default, 'ceph'))
with open(pathname, "w") as sls_file:
sls_file.write(yaml.dump(preserve, Dumper=friendly_dumper,
default_flow_style=False))
uid = pwd.getpwnam("salt").pw_uid
gid = grp.getgrnam("salt").gr_gid
for path in [stack_default, "{}/{}".format(stack_default, 'ceph'), pathname]:
os.chown(path, uid, gid)
def to_yaml(self):
"""
Pretty print dump as YAML.
"""
return dump(
self.to_safe_dict(),
# show every document in its own block
default_flow_style=False,
# start a new document (via "---") before every resource
explicit_start=True,
# follow (modern) PEP8 max line length and indent
width=99,
indent=4,
Dumper=SafeDumper,
)
def save(self):
"""Persist the rules to disk"""
try:
logger.debug("Backing up rules")
if os.path.exists(self._db):
shutil.copyfile(self._db, "{}.bak".format(self._db))
except Exception as e:
logger.exception("Failed to backup rules")
return
try:
logger.debug("Saving rules")
with open(self._db, 'w') as f:
f.write(ordered_dump(OrderedDict(
((k, self._rules[k]) for k in self._rules_with_index)), Dumper=yaml.SafeDumper, default_flow_style=False, explicit_start=True))
except:
logger.exception("Failed to save rules")
def convert_yaml(data):
"""
***Converter Special ***
Convert data structure to yaml format
:param data: OrderedDict to convert
:return: yaml formated data
"""
ordered = (type(data).__name__ == 'OrderedDict')
dict_type = 'dict'
if ordered:
dict_type = 'OrderedDict'
sdata = _ordered_dump(data, Dumper=yaml.SafeDumper, version=yaml_version, indent=indent_spaces, block_seq_indent=2, width=12288, allow_unicode=True, default_flow_style=False)
else:
sdata = yaml.dump(data, Dumper=yaml.SafeDumper, indent=indent_spaces, block_seq_indent=2, width=12288, allow_unicode=True, default_flow_style=False)
sdata = _format_yaml_dump(sdata)
return sdata
def _ordered_dump(data, stream=None, Dumper=yaml.Dumper, **kwds):
"""
Ordered yaml dumper
Use this instead ot yaml.Dumper/yaml.SaveDumper to get an Ordereddict
:param stream: stream to write to
:param Dumper: yaml-dumper to use
:**kwds: Additional keywords
:return: OrderedDict structure
"""
# usage example: 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(data, stream=None, dumper_class=yaml.SafeDumper, object_pairs_hook=OrderedDict, **kwds):
class OrderedDumper(dumper_class):
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,
default_flow_style=False,
**kwds
)
def ordered_dump(data, stream=None, Dumper=yaml.SafeDumper, **kwds):
"""Dump a yaml configuration as an OrderedDict."""
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 __init__(self):
"""
Set yaml dumper, initialize Salt client
"""
self.data = {}
self.friendly_dumper = yaml.SafeDumper
self.friendly_dumper.ignore_aliases = lambda self, data: True
self.local = salt.client.LocalClient()
def __init__(self, dryrun=False):
"""
The source is proposals_dir and the destination is pillar_dir
"""
self.proposals_dir = "/srv/pillar/ceph/proposals"
self.pillar_dir = "/srv/pillar/ceph"
self.dryrun = dryrun
# Keep yaml human readable/editable
self.friendly_dumper = yaml.SafeDumper
self.friendly_dumper.ignore_aliases = lambda self, data: True
def __init__(self, **kwargs):
"""
Keep yaml human readable/editable. Disable yaml references.
"""
self.dumper = yaml.SafeDumper
self.dumper.ignore_aliases = lambda self, data: True
if 'overwrite' in kwargs:
self.overwrite = kwargs['overwrite']
else:
self.overwrite = False
def save(data, stream=None, Dumper=yaml.SafeDumper,
default_flow_style=False,
encoding='utf-8',
**kwds):
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)
OrderedDumper.add_representer(np.float64,
lambda dumper, data: dumper.represent_float(float(data)))
OrderedDumper.add_representer(complex,
lambda dumper, data: dumper.represent_str(str(data)))
OrderedDumper.add_representer(np.complex128,
lambda dumper, data: dumper.represent_str(str(data)))
OrderedDumper.add_representer(np.ndarray,
lambda dumper, data: dumper.represent_list(list(data)))
# I added the following two lines to make pyrpl compatible with pyinstruments. In principle they can be erased
if isinstance(data, dict) and not isinstance(data, OrderedDict):
data = OrderedDict(data)
return yaml.dump(data,
stream=stream,
Dumper=OrderedDumper,
default_flow_style=default_flow_style,
encoding=encoding,
**kwds)
# usage example:
# load(stream, yaml.SafeLoader)
# save(data, stream=f, Dumper=yaml.SafeDumper)
def ToYAML(self):
"""Print validated object as simplified YAML.
Returns:
Object as a simplified YAML string compatible with parsing using the
SafeLoader.
"""
return yaml.dump(self.ToDict(),
default_flow_style=False,
Dumper=yaml.SafeDumper)
def ToYAML(self):
"""Print validated object as simplified YAML.
Returns:
Object as a simplified YAML string compatible with parsing using the
SafeLoader.
"""
return yaml.dump(self.ToDict(),
default_flow_style=False,
Dumper=yaml.SafeDumper)
def write_policy_file(self, policy, format='yaml'):
""" Write a policy file to disk in the specified format.
Input a dictionary and a format. Valid formats are `yaml` and `json`
Returns the file path.
"""
fh = tempfile.NamedTemporaryFile(mode='w+b', suffix='.' + format)
if format == 'json':
fh.write(json.dumps(policy).encode('utf8'))
else:
fh.write(yaml.dump(policy, encoding='utf8', Dumper=yaml.SafeDumper))
fh.flush()
self.addCleanup(fh.close)
return fh.name
def convert(self):
"""
conversion of the raml info into the word document
:return:
"""
try:
parsetree = ramlparser.load(self.inputname)
except ValidationError as e:
print ('validation error:', e.errors)
print ("could not load file: error loading file")
traceback.print_exc()
return
# make it a member..
self.parsetree = parsetree
self.list_x_resources(parsetree)
# print parsetree
# output = dump(parsetree, Dumper=Dumper,default_flow_style=False)
# output = dump(parsetree, Dumper=SafeDumper)
# print output
try:
self.document = Document(docx=self.resourcedoc)
except:
print ("could not load file: ", self.resourcedoc)
print ("make sure that docx file exist..")
return
self.generate_sections(parsetree, self.resource_name)
self.document.save(self.resource_out)
print ("document saved..", self.resource_out)
def convert(self):
try:
parsetree = ramlparser.load(self.inputname)
except ValidationError as e:
print 'validation error:', e.errors
#print "could not load file: error loading file"
#traceback.print_exc()
return
# make it a member..
self.parsetree = parsetree
self.listXResources(parsetree)
#print parsetree
#output = dump(parsetree, Dumper=Dumper,default_flow_style=False)
#output = dump(parsetree, Dumper=SafeDumper)
#print output
try:
self.document = Document(docx=self.resourcedoc)
except:
print "could not load file: ", self.resourcedoc
print "make sure that docx file exist in same directory as executable"
return
self.generateSections(parsetree, self.ResourceName)
self.document.save(self.resourceout)
def ToYAML(self):
"""Print validated object as simplified YAML.
Returns:
Object as a simplified YAML string compatible with parsing using the
SafeLoader.
"""
return yaml.dump(self.ToDict(),
default_flow_style=False,
Dumper=yaml.SafeDumper)
def dump_migration_session_state(raw):
"""
Serialize a migration session state to yaml using nicer formatting
Args:
raw: object to serialize
Returns: string (of yaml)
Specifically, this forces the "output" member of state step dicts (e.g.
state[0]['output']) to use block formatting. For example, rather than this:
- migration: [app, migration_name]
output: "line 1\nline2\nline3"
You get this:
- migration: [app, migration_name]
output: |
line 1
line 2
line 3
"""
class BlockStyle(str): pass
class SessionDumper(yaml.SafeDumper): pass
def str_block_formatter(dumper, data):
return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='|')
SessionDumper.add_representer(BlockStyle, str_block_formatter)
raw = deepcopy(raw)
for step in raw:
step['output'] = BlockStyle(step['output'])
step['traceback'] = BlockStyle(step['traceback'])
return yaml.dump(raw, Dumper=SessionDumper)
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 ToYAML(self):
"""Print validated object as simplified YAML.
Returns:
Object as a simplified YAML string compatible with parsing using the
SafeLoader.
"""
return yaml.dump(self.ToDict(),
default_flow_style=False,
Dumper=yaml.SafeDumper)
def ToYAML(self):
"""Print validated object as simplified YAML.
Returns:
Object as a simplified YAML string compatible with parsing using the
SafeLoader.
"""
return yaml.dump(self.ToDict(),
default_flow_style=False,
Dumper=yaml.SafeDumper)
def _ordered_dump(self, data, stream=None, Dumper=yaml.SafeDumper, **kwds):
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,
default_flow_style=False,
indent=4,
**kwds)
def __init__(self, dryrun):
"""
The source is proposals_dir and the destination is pillar_dir
"""
self.proposals_dir = "/srv/pillar/ceph/proposals"
self.pillar_dir = "/srv/pillar/ceph"
self.dryrun = dryrun
# Keep yaml human readable/editable
self.friendly_dumper = yaml.SafeDumper
self.friendly_dumper.ignore_aliases = lambda self, data: True
def __init__(self):
"""
Keep yaml human readable/editable. Disable yaml references.
"""
self.dumper = yaml.SafeDumper
self.dumper.ignore_aliases = lambda self, data: True
def __init__(self, **kwargs):
"""
Keep yaml human readable/editable. Disable yaml references.
"""
self.dumper = yaml.SafeDumper
self.dumper.ignore_aliases = lambda self, data: True
if 'overwrite' in kwargs:
self.overwrite = kwargs['overwrite']
else:
self.overwrite = False
def get_yaml_dumper(context):
"""Return yaml dumper that handles all needed object types."""
class CustomDumper(yaml.SafeDumper):
"""Custom YAML Dumper."""
def default_representer(self, data):
"""Convert data to string."""
if isinstance(data, int):
return self.represent_int(data)
if isinstance(data, float):
return self.represent_float(data)
return self.represent_str(str(data))
def ordered_dict_representer(self, data):
"""Representer for OrderedDict."""
return self.represent_mapping('tag:yaml.org,2002:map', data.items())
def default_language_representer(self, data):
"""Convert language to string."""
return self.represent_str(format_language(data, context['profile']))
def default_quantity_representer(self, data):
"""Convert quantity to string."""
return self.default_representer(format_quantity(data, context['profile']))
def default_duration_representer(self, data):
"""Convert quantity to string."""
return self.default_representer(format_duration(data, context['profile']))
CustomDumper.add_representer(OrderedDict, CustomDumper.ordered_dict_representer)
CustomDumper.add_representer(babelfish.Language, CustomDumper.default_language_representer)
CustomDumper.add_representer(timedelta, CustomDumper.default_duration_representer)
CustomDumper.add_representer(units.Quantity, CustomDumper.default_quantity_representer)
return CustomDumper
def _get_minions_and_write_data(selector, cluster, overwrite):
# Keep yaml human readable/editable
friendly_dumper = yaml.SafeDumper
friendly_dumper.ignore_aliases = lambda self, data: True
cluster_dir = '/srv/pillar/ceph/cluster'
local = salt.client.LocalClient()
node_count = 0
master_count = 0
skipped_count = 0
cluster_minions = local.cmd(selector, 'grains.get', ['nodename'], expr_form="compound")
for minion in cluster_minions.keys():
master = local.cmd(minion, 'grains.get', ['master'])
filename = '{}/{}.sls'.format(cluster_dir, minion)
contents = {}
# check if minion has a cluster assigned already
assigned_cluster = local.cmd(minion, 'pillar.get', ['cluster'])
if (not overwrite and assigned_cluster[minion] != ''):
skipped_count += 1
continue
# check if minion is also master
if (master[minion] == '127.0.0.1' or master[minion] == minion):
print 'recognized {} as master'.format(minion)
contents['cluster'] = 'unassigned'
master_count += 1
else:
contents['cluster'] = cluster
node_count += 1
# verify that user salt has ownership cluster_dir
if getpwuid(stat(cluster_dir).st_uid).pw_name != 'salt':
raise Exception('Please make sure {dir} is owned by the salt user.'.format(dir=cluster_dir))
with open(filename, 'w') as yml:
yml.write(yaml.dump(contents, Dumper=friendly_dumper, default_flow_style=False))
# refresh pillar data here so a subsequent run of this runner will not
# overwrite already assigned minion
local.cmd(selector, 'saltutil.refresh_pillar', [], expr_form="compound")
return '''wrote cluster config to {}/
newly assigned nodes:\t{}
masters:\t\t\t{}
skipped nodes:\t\t{}'''.format(cluster_dir, node_count, master_count, skipped_count)