I have the next code:
import gnupg
import re
import textwrap
from pprint import pprint
import yaml
from yaml.events import *
class AppendableEvents:
def __init__(self, path, events):
self.path = path
self.events = events
def correct_position(self, levels):
if len(self.path) != len(levels):
return False
for index, expected in enumerate(self.path):
if expected != levels[index].cur_id:
return False
return True
class Level:
def __init__(self, mode):
self.mode = mode
self.cur_id = -1 if mode == "item" else ""
def append_to_yaml(yamlFile, targetFile, items):
events = []
levels = []
with open(yamlFile, 'r') as handle:
for event in yaml.parse(handle):
if isinstance(event, StreamStartEvent) or \
isinstance(event, StreamEndEvent) or \
isinstance(event, DocumentStartEvent) or \
isinstance(event, DocumentEndEvent):
pass
elif isinstance(event, CollectionStartEvent):
if len(levels) > 0:
if levels[-1].mode == "key":
# we can only handle scalar keys
raise ValueError("encountered complex key!")
else:
if levels[-1].mode == "value":
levels[-1].mode = "key"
if isinstance(event, MappingStartEvent):
levels.append(Level("key"))
else: # SequenceStartEvent
levels.append(Level("item"))
elif isinstance(event, ScalarEvent):
if len(levels) > 0:
if levels[-1].mode == "item":
levels[-1].cur_id += 1
elif levels[-1].mode == "key":
levels[-1].cur_id = event.value
levels[-1].mode = "value"
else: # mode == "value"
levels[-1].mode = "key"
elif isinstance(event, CollectionEndEvent):
# here we check whether we want to append anything
levels.pop()
for item in items:
if item.correct_position(levels):
for additional_event in item.events:
events.append(additional_event)
events.append(event)
with open(targetFile, mode="w") as handle:
yaml.emit(events, handle,line_break=True)
def key(name):
return ScalarEvent(None, None, (True, True), name)
def literal_value(content):
return ScalarEvent(None, None, (False, True), content, style="|")
def map(*scalarValues):
return [MappingStartEvent(None, None, True)] + \
[ScalarEvent(None, None, (False, True), v, style="|") for v in scalarValues] + \
[MappingEndEvent()]
gpg = gnupg.GPG(gnupghome='~/.gnupg')
gpg.encoding = 'utf-8'
def ExistingFile():
with open(creds) as sensitive_data:
for line in sensitive_data:
encrypted_value = gpg.encrypt(
re.sub(r'^( +?|[A-Za-z0-9]|[A-Za]|[0-9])+( +)?' + '=' + '( +)?', '', line, 1),
recipients="test", always_trust=True)
if not encrypted_value.ok:
print(encrypted_value.status, '\n', encrypted_value.stderr)
break
line = re.sub(r'^( +)?|( +)?' + '=' + '.*', '', line.rstrip('\n'))
append_to_yaml(f1, f1, [
AppendableEvents(["global","app1"], [
key("app2")] + map(line, encrypted_value.data.decode()))])
#key(line), literal_value(encrypted_value.data.decode())])])
ExistingFile()
Content of creds file is:
1=1
sadsa=ars
Content of f1 file is:
global:
app1:
test: |
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
-----END PGP MESSAGE-----
In this code necessary key, subkey and values are being appended to appropriate block in yaml file.
But the problem is that value which I pass in key methods is being iterated and thus appends twice or more depending on content in creds file:
global:
app1:
test: |
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
-----END PGP MESSAGE-----
app2:
"1": |
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
-----END PGP MESSAGE-----
app2:
"sadsa": |
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
-----END PGP MESSAGE-----
Also subkeys "1" and "sadsa" are being appended with double quotes.
I want to get rid of double quotes and that value which I pass in key method will be appended to file only one time when I combine it with map method.
So the final result will be for example:
global:
app1:
test: |
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
-----END PGP MESSAGE-----
app2:
1: |
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
-----END PGP MESSAGE-----
sadsa: |
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
-----END PGP MESSAGE-----
Note: Commented line with literal_value method works pretty fine so I don't want to break it's logic doing changes for case with map method.
First of all, please provide a minimal example when asking a question. I removed the
gnupg
stuff from your code because it is not relevant at all to your question. It is your responsibility to provide only relevant parts of your actual code so that people trying to help you do not need to dig through irrelevant lines.Now, to solve your question: You simply need to construct the events you output appropriately. Here's a solution (without the
gnupg
stuff):As you can see, I construct the scalar event for the key differently from that for the value, so that the value is presented as literal scalar and the key as plain scalar (without quotes).
I also call
append_to_yaml
only once so thatapp2
is only created once.