def download(url, target=None, force=False): """ Download and storage file from a url """ if not is_url(url): raise TypeError("Str '%s' is not a valid url." % url) storage_folder = target or settings.get('STORAGE_TEMPLATES') auth = str(settings.get('REPOSITORY_AUTH')).replace("'", '') file_name = path.basename(urlsplit(url).path) file_path = storage_folder + file_name if force or not path.isfile(file_path): Storage.create_folders(storage_folder) try: request = Request(url) if auth: request.add_header('Authorization', auth) with urlopen(request) as response: Storage.file(file_path, response.read(), 'wb') logger.log(url, 'download DONE!') except HTTPError as e: e.msg += ": URL '%s' cannot be downloaded" % url raise e else: logger.log(url, 'from CACHE!') return file_path
def indexing(self, update=False): """ Indexing recipes locally """ if not self.is_indexed() or update: self.index[self.id] = {'remote': self.remote, 'version': self.version, 'filename': self.filename, 'datetime': str(datetime.now())} Storage.json(settings.get('STORAGE_RECIPE_INDEX'), self.index)
def update_secrets(self): """ Replace secret values with encrypt values in recipe """ for instruction in self.instructions: if instruction.secrets: section = instruction.name + ':secrets' for idx, secret in instruction.secrets.items(): self.parser[section][idx] = secret Storage.parser(self.recipe_file, self.parser, write_mod=True)
def generate(key_pass): """ Generate secret key from key pass """ b_key_pass = key_pass.encode(settings.get('ENCODING')) sha256 = SHA256.new(b_key_pass) secret_key = sha256.digest() secret_store = binascii.hexlify(secret_key).decode( settings.get('ENCODING')) Storage.file(settings.get('STORAGE_KEY_PATH'), secret_store) logger.log("Generated secret key '{0}' " "and saved at '{1}'".format( secret_store, settings.get('STORAGE_KEY_PATH'))) return secret_store
def remove(rid): """ Remove locally recipe by id """ location = settings.get('STORAGE_RECIPE_INDEX') index = Storage.json(location) if len(rid) != 64: found = list(filter(lambda idx: idx[:9] == rid, index)) if found: rid = found[0] del index[rid] Storage.json(location, index) logger.log("Removed recipe '%s'" % rid)
def list(all_info=False): """ List of recipes saved in index """ recipes = Storage.json(settings.get('STORAGE_RECIPE_INDEX')) meta = _IndexRecipe.calc_length(recipes) meta['id'] = 64 if all_info else 9 extra_space = 8 list_items = '' for key in recipes.keys(): recipe = recipes[key] recipe_id = key[:meta['id']] created = recipe['datetime'] if all_info else recipe['datetime'][:19] list_items += recipe_id + (' ' * (meta['id'] + extra_space - len(recipe_id))) for attr_name in ['remote', 'version', 'filename']: list_items += (recipe[attr_name] + (' ' * (meta[attr_name] + extra_space - len(recipe[attr_name])))) list_items += created + '\n' header = ListRecipes._list_header(meta, extra_space) logger.log(header + list_items)
def _load_bakerc(): """ Load settings from bakerc file """ def convert_if_bool(string): lower_str = string.lower() if lower_str in ('true', 'false'): return lower_str == 'true' return string if Path(_BAKERC_PATH).is_file(): parser = ConfigParser() Storage.parser(_BAKERC_PATH, parser, chain_items=("[DEFAULT]", )) for key, value in parser.defaults().items(): upper_key = key.upper() if upper_key not in values(): raise AttributeError( "Setting '{0}' at '{1}' is not supported".format( upper_key, _BAKERC_PATH)) values()[upper_key] = convert_if_bool(value)
def values(custom_only=False): """ List of settings custom and defaults """ if custom_only and Path(_BAKERC_PATH).is_file(): lines = Storage.file(_BAKERC_PATH).split('\n') configs = {} for line in lines: if line: key, val = line.split('=') configs[key] = val return configs return globals()['BAKER_SETTINGS']
def download(url, target=None, force=False): """ Download and storage file from a url """ if not is_url(url): raise TypeError("Str '%s' is not a valid url." % url) storage_folder = target or settings.get('STORAGE_TEMPLATES') file_name = path.basename(urlsplit(url).path) file_path = storage_folder + file_name if force or not path.isfile(file_path): Storage.create_folders(storage_folder) try: urlretrieve(url, file_path) logger.log(url, 'download DONE!') except HTTPError as e: e.msg += ": URL '%s' cannot be downloaded" % url raise e else: logger.log(url, 'from CACHE!') return file_path
def replace(self): """ Replace variables in template file based on recipe instructions """ for instruction in self.instructions: target = instruction.template template_path = instruction.template replaced = Storage.file(template_path) if instruction.variables: template = BakerTemplate(replaced) replaced = template.replace(instruction.variables) if hasattr(instruction, 'path'): target = instruction.path if settings.get('TEMPLATE_EXT') and target.endswith( settings.get('TEMPLATE_EXT')): ext_size = len(settings.get('TEMPLATE_EXT')) + 1 target = target[:-ext_size] Storage.file(target, content=replaced) self._add_file_permission(instruction, target) logger.log(instruction.name, instruction.template, target)
def __init__(self, remote, version, filename): self.remote = remote self.version = version self.filename = filename self.id = self._generate_id() self.index = Storage.json(settings.get('STORAGE_RECIPE_INDEX'))
def key(self): """ Read secret key from storage file """ return Storage.file(settings.get('STORAGE_KEY_PATH'))