diskimage-builder/elements/svc-map/extra-data.d/10-merge-svc-map-files
Luong Anh Tuan ff8ae43265 Replace yaml.load() with yaml.safe_load()
Avoid dangerous file parsing and object serialization libraries.
yaml.load is the obvious function to use but it is dangerous[1]
Because yaml.load return Python object may be dangerous if you
receive a YAML document from an untrusted source such as the
Internet. The function yaml.safe_load limits this ability to
simple Python objects like integers or lists.

In addition, Bandit flags yaml.load() as security risk so replace
all occurrences with yaml.safe_load(). Thus I replace yaml.load()
with yaml.safe_load()

[1]https://security.openstack.org/guidelines/dg_avoid-dangerous-input-parsing-libraries.html

Change-Id: I84640973fd9f45a69d2b21f6d594cd5bf10660a6
Closes-Bug: #1634265
2017-01-16 15:07:05 +07:00

90 lines
3 KiB
Python
Executable file

#!/usr/bin/env python
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
import sys
import yaml
def os_family(distro):
"Given a distribution, returns a operating system family."
family = None
if distro in ['centos', 'centos7', 'fedora', 'rhel', 'rhel7']:
family = 'redhat'
elif distro in ['debian', 'ubuntu']:
family = 'debian'
elif distro == 'opensuse':
family = 'suse'
return family
def merge_data(source, destination, distro):
"""Merges two dictionaries and filters on distro.
Merges two dictionaries and filters on distro family, or default (in order)
"""
result = dict()
result.update(destination)
family = os_family(distro)
for servicename, mapping in source.items():
if servicename in result:
raise Exception("%s already found in services list" % servicename)
if distro in mapping:
result[servicename] = mapping.get(distro)
elif family in mapping:
result[servicename] = mapping.get(family)
elif 'default' in mapping:
result[servicename] = mapping.get('default')
else:
result[servicename] = servicename
return result
def write_data_to_file(data, service_file_path):
"""Writes yaml data to a specified path."""
with open(service_file_path, 'w') as destination:
yaml.dump(data, destination, default_flow_style=False)
def main():
elements = os.environ.get("IMAGE_ELEMENT").split(' ')
element_paths = os.environ.get("ELEMENTS_PATH").split(':')
service_names = dict()
for element in elements:
if not element.strip():
continue
for element_path in element_paths:
data_path = os.path.join(element_path, element, "svc-map")
if os.path.exists(data_path):
with open(data_path, 'r') as dataFile:
data = yaml.safe_load(dataFile.read())
try:
service_names = merge_data(
data,
service_names,
os.environ.get("DISTRO_NAME"))
except Exception as err:
print("%s. Check %s for duplicate"
" service name." % (err, element))
sys.exit(1)
write_data_to_file(
service_names,
os.path.join(os.environ['TMP_MOUNT_PATH'], 'tmp', 'svc-map-services'))
if __name__ == "__main__":
main()