def from_search(cls, data, api): bag = data.get('data_bag') if not bag: raise ChefError('No data_bag key in data bag item information') name = data.get('name') if not name: raise ChefError('No name key in the data bag item information') item = name[len('data_bag_item_' + bag + '_'):] obj = cls(bag, item, api=api, skip_load=True) obj.exists = True obj._populate(data) return obj
def __call__(self): query = self.query environment = self.environment if environment is _default_environment: environment = env.get('chef_environment', DEFAULT_ENVIRONMENT) if environment: query += ' AND chef_environment:%s' % environment for row in Search('node', query, api=self.api): if row: if callable(self.hostname_attr): val = self.hostname_attr(row.object) if val: yield val else: for attr in self.hostname_attr: try: val = row.object.attributes.get_dotted(attr) if val: # Don't ever give out '' or None, since it will error anyway yield val break except KeyError: pass # Move on to the next else: raise ChefError( 'Cannot find a usable hostname attribute for node %s', row.object)
def chef_environment(name, api=None): """A Fabric task to set the current Chef environment context. This task works alongside :func:`~chef.fabric.chef_roledefs` to set the Chef environment to be used in future role queries. Example:: from chef.fabric import chef_environment, chef_roledefs env.roledefs = chef_roledefs() .. code-block:: bash $ fab env:production deploy The task can be configured slightly via Fabric ``env`` values. ``env.chef_environment_task_alias`` sets the task alias, defaulting to "env". This value must be set **before** :mod:`chef.fabric` is imported. ``env.chef_environment_validate`` sets if :class:`~chef.Environment` names should be validated before use. Defaults to True. .. versionadded:: 0.2 """ if env.get('chef_environment_validate', True): api = _api(api) chef_env = Environment(name, api=api) if not chef_env.exists: raise ChefError('Unknown Chef environment: %s' % name) env['chef_environment'] = name
def chef_roledefs(api=None, hostname_attr='fqdn'): """Build a Fabric roledef dictionary from a Chef server. Example: from fabric.api import env, run, roles from chef.fabric import chef_roledefs env.roledefs = chef_roledefs() @roles('web_app') def mytask(): run('uptime') hostname_attr is the attribute in the chef node that holds the real hostname. to refer to a nested attribute, separate the levels with '.'. for example 'ec2.public_hostname' """ api = api or ChefAPI.get_global() or autoconfigure() if not api: raise ChefError('Unable to load Chef API configuration') roledefs = {} for row in Search('role', api=api): name = row['name'] roledefs[name] = Roledef(name, api, hostname_attr) return roledefs
def __delitem__(self, key): if self.write is None: raise ChefError('This attribute is not writable') dest = self.write for path_key in self.path: dest = dest.setdefault(path_key, {}) del dest[key]
def file_content(self, path): url = self.file_url(path) if not url: raise ChefServerNotFoundError('%s node found in %s' % (path, self.cookbook_name)) result = requests.get(url, verify=False) if result.status_code == 200: return result.text raise ChefError()
def _secret(self, api): if api.client not in self._keys.raw_data: raise ChefError("%s/%s is not encrypted with your public key." % \ (self._bag, self.name) ) cipher = self._vault_cipher(api) dsize = SHA.digest_size sentinel = Random.new().read(15+dsize) return cipher.decrypt(b64decode(self._keys.raw_data[api.client]), sentinel)
def _create_keys(self, api=None): api = api or self.api temp_keys = DataBagItem(self._bag, '%s_keys' % (self.name,), self.api ) if not not temp_keys.raw_data: # make sure we don't overwrite keys that already exist raise ChefError("This library does not yet support the overwriting of existing vault keys.") cipher = self._vault_cipher() secret = self._gen_secret() self._keys.raw_data[api.client] = b64encode(cipher.encrypt(secret))\ .decode() self._keys.save() self._key = secret # set this after we have a successful save
def __call__(self): query = self.query environment = self.environment if environment is _default_environment: environment = env.get('chef_environment', DEFAULT_ENVIRONMENT) if environment: query += ' AND chef_environment:%s' % environment for row in Search('node', query, api=self.api): if row: if callable(self.hostname_attr): yield self.hostname_attr(row.object) else: for attr in self.hostname_attr: try: yield row.object.attributes.get_dotted(attr) break except KeyError: continue else: raise ChefError('Cannot find a usable hostname attribute for node %s', row.object)
def _api(api): api = api or ChefAPI.get_global() or autoconfigure() if not api: raise ChefError('Unable to load Chef API configuration') return api
def _get_chef_api(chef_url, username, chef_pem): if not os.path.exists(chef_pem): raise ChefError('User has no pem to access chef server') api = ChefAPI(chef_url, chef_pem, username) return api