1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 # and others. All rights reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
20 from cryptography.hazmat.primitives import serialization
23 import urllib.request as urllib
25 import urllib2 as urllib
29 __author__ = 'spisarski'
32 Utilities for basic file handling
35 logger = logging.getLogger('file_utils')
38 def file_exists(file_path):
40 Returns True if the image file already exists and throws an exception if
41 the path is a directory
44 expanded_path = os.path.expanduser(file_path)
45 if os.path.exists(expanded_path):
46 if os.path.isdir(expanded_path):
48 return os.path.isfile(expanded_path)
52 def download(url, dest_path, name=None):
54 Download a file to a destination path given a URL
55 :param url: the endpoint to the file to download
56 :param dest_path: the directory to save the file
57 :param name: the file name (optional)
61 name = url.rsplit('/')[-1]
62 dest = dest_path + '/' + name
63 logger.debug('Downloading file from - ' + url)
64 # Override proxy settings to use localhost to download file
67 if not os.path.isdir(dest_path):
73 with open(dest, 'wb') as download_file:
74 logger.debug('Saving file to - %s',
75 os.path.abspath(download_file.name))
76 response = __get_url_response(url)
77 download_file.write(response.read())
84 def save_keys_to_files(keys=None, pub_file_path=None, priv_file_path=None):
86 Saves the generated RSA generated keys to the filesystem
87 :param keys: the keys to save generated by cryptography
88 :param pub_file_path: the path to the public keys
89 :param priv_file_path: the path to the private keys
94 pub_expand_file = os.path.expanduser(pub_file_path)
95 pub_dir = os.path.dirname(pub_expand_file)
97 if not os.path.isdir(pub_dir):
102 public_handle = open(pub_expand_file, 'wb')
103 public_bytes = keys.public_key().public_bytes(
104 serialization.Encoding.OpenSSH,
105 serialization.PublicFormat.OpenSSH)
106 public_handle.write(public_bytes)
109 public_handle.close()
111 os.chmod(pub_expand_file, 0o400)
112 logger.info("Saved public key to - " + pub_expand_file)
115 priv_expand_file = os.path.expanduser(priv_file_path)
116 priv_dir = os.path.dirname(priv_expand_file)
117 if not os.path.isdir(priv_dir):
120 private_handle = None
122 private_handle = open(priv_expand_file, 'wb')
123 private_handle.write(
125 encoding=serialization.Encoding.PEM,
126 format=serialization.PrivateFormat.TraditionalOpenSSL,
127 encryption_algorithm=serialization.NoEncryption()))
130 private_handle.close()
132 os.chmod(priv_expand_file, 0o400)
133 logger.info("Saved private key to - " + priv_expand_file)
136 def save_string_to_file(string, file_path, mode=None):
139 :param string: the string contents to store
140 :param file_path: the file path to create
141 :param mode: the file's mode
142 :return: the file object
144 save_file = open(file_path, 'w')
146 save_file.write(string)
148 os.chmod(file_path, mode)
154 def get_content_length(url):
156 Returns the number of bytes to be downloaded from the given URL
157 :param url: the URL to inspect
158 :return: the number of bytes
160 response = __get_url_response(url)
161 return response.headers['Content-Length']
164 def __get_url_response(url):
166 Returns a response object for a given URL
168 :return: the response
170 proxy_handler = urllib.ProxyHandler({})
171 opener = urllib.build_opener(proxy_handler)
172 urllib.install_opener(opener)
173 context = ssl._create_unverified_context()
174 return urllib.urlopen(url, context=context)
177 def read_yaml(config_file_path):
179 Reads the yaml file and returns a dictionary object representation
180 :param config_file_path: The file path to config
181 :return: a dictionary
183 logger.debug('Attempting to load configuration file - ' + config_file_path)
186 with open(config_file_path, 'r') as config_file:
187 config = yaml.safe_load(config_file)
188 logger.info('Loaded configuration')
192 logger.info('Closing configuration file')
196 def persist_dict_to_yaml(the_dict, file_name):
198 Creates a YAML file from a dict
199 :param the_dict: the dictionary to store
200 :param conf_dir: the directory used to store the config file
201 :return: the file object
203 logger.info('Persisting %s to [%s]', the_dict, file_name)
204 file_path = os.path.expanduser(file_name)
205 yaml_from_dict = yaml.dump(
206 the_dict, default_flow_style=False, default_style='')
207 return save_string_to_file(yaml_from_dict, file_path)
210 def read_os_env_file(os_env_filename):
212 Reads the OS environment source file and returns a map of each key/value
213 Will ignore lines beginning with a '#' and will replace any single or
214 double quotes contained within the value
215 :param os_env_filename: The name of the OS environment file to read
216 :return: a dictionary
219 logger.info('Attempting to read OS environment file - %s',
224 env_file = open(os_env_filename)
225 for line in env_file:
227 if not line.startswith('#') and line.startswith('export '):
228 line = line.lstrip('export ').strip()
229 tokens = line.split('=')
231 # Remove leading and trailing ' & " characters from
233 out[tokens[0]] = tokens[1].lstrip('\'').lstrip('\"').rstrip('\'').rstrip('\"')
240 def read_file(filename):
242 Returns the contents of a file as a string
243 :param filename: the name of the file
249 the_file = open(filename)
250 for line in the_file: