def action(self, resource, action_name): inventory_file = self._create_inventory(resource) playbook_file = self._create_playbook(resource, action_name) log.debug('inventory_file: %s', inventory_file) log.debug('playbook_file: %s', playbook_file) # self.transport_sync.copy(resource, self.dirs[resource.name], self.dirs[resource.name]) self._copy_templates_and_scripts(resource, action_name) self.transport_sync.copy(resource, self.dst, '/tmp') self.transport_sync.copy(resource, '/vagrant/library', '/tmp') self.transport_sync.sync_all() # remote paths are not nested inside solar_local remote_playbook_file = playbook_file.replace(SOLAR_TEMP_LOCAL_LOCATION, '/tmp/') remote_inventory_file = inventory_file.replace( SOLAR_TEMP_LOCAL_LOCATION, '/tmp/') call_args = [ 'ansible-playbook', '--module-path', '/tmp/library', '-i', remote_inventory_file, remote_playbook_file ] log.debug('EXECUTING: %s', ' '.join(call_args)) out = self.transport_run.run(resource, *call_args) log.debug(out) if out.failed: raise errors.SolarError(out)
def action(self, resource, action_name): action_file = self._compile_action_file(resource, action_name) log.debug('action_file: %s', action_file) action_file_name = os.path.join(self.dirs[resource.name], action_file) action_file_name = action_file_name.replace( SOLAR_TEMP_LOCAL_LOCATION, '/tmp/') self._copy_templates_and_scripts(resource, action_name) self.transport_sync.copy(resource, self.dst, '/tmp') self.transport_sync.sync_all() cmd = self.transport_run.run( resource, 'bash', action_file_name, use_sudo=True, warn_only=True ) if cmd.return_code: raise errors.SolarError( 'Bash execution for {} failed with {}'.format( resource.name, cmd.return_code)) return cmd
def action(self, resource, action_name): log.debug('Executing Puppet manifest %s %s', action_name, resource.name) action_file = self._compile_action_file(resource, action_name) log.debug('action_file: %s', action_file) self.upload_hiera_resource(resource) action_file_name = '/tmp/{}.pp'.format(resource.name) self.prepare_templates_and_scripts(resource, action_file, '') self.transport_sync.copy(resource, action_file, action_file_name) self.transport_sync.sync_all() cmd_args = [ 'puppet', 'apply', '-vd', action_file_name, '--detailed-exitcodes' ] if 'puppet_modules' in resource.args: cmd_args.append('--modulepath={}'.format( resource.args['puppet_modules'])) cmd = self.transport_run.run(resource, *cmd_args, env={ 'FACTER_resource_name': resource.name, }, use_sudo=True, warn_only=True) # 0 - no changes, 2 - successfull changes if cmd.return_code not in [0, 2]: raise errors.SolarError('Puppet for {} failed with {}'.format( resource.name, cmd.return_code)) return cmd
def verify_run_result(self, cmd, result): rc, out, err = result.return_code, result.stdout, result.stderr log.debug('CMD %r RC %s OUT %s ERR %s', cmd, rc, out, err) if not result.success: message = 'CMD %r failed RC %s ERR %s' % (cmd, rc, err) log.error(message) raise errors.SolarError(result.output)
def action(self, resource, action): call_args = self.prepare(resource, action) log.debug('EXECUTING: %s', ' '.join(call_args)) ret, out, err = execute(call_args) if ret == 0: return else: # ansible returns errors on stdout raise errors.SolarError(out)
def __new__(cls, name, parents, dct): collection = dct.get('_collection') if not collection: raise NotImplementedError('Collection is required.') dct['_meta'] = {} dct['_meta']['fields'] = {} dct['_meta']['related_to'] = {} has_primary = False for field_name, field_klass in dct.items(): if not inspect.isclass(field_klass): continue if issubclass(field_klass, DBField): dct['_meta']['fields'][field_name] = field_klass if field_klass.is_primary: if has_primary: raise errors.SolarError('Object cannot have 2 primary fields.') has_primary = True dct['_meta']['primary'] = field_name elif issubclass(field_klass, DBRelatedField): dct['_meta']['related_to'][field_name] = field_klass if not has_primary: raise errors.SolarError('Object needs to have a primary field.') klass = super(DBObjectMeta, cls).__new__(cls, name, parents, dct) # Support for self-references in relations for field_name, field_klass in klass._meta['related_to'].items(): field_klass.source_db_class = klass if field_klass.destination_db_class == klass.__name__: field_klass.destination_db_class = klass return klass
def add_hash(self, destination_db_object, destination_key, tag=None): if not isinstance(destination_db_object, self.destination_db_class): raise errors.SolarError( 'Object {} is of incompatible type {}.'.format( destination_db_object, self.destination_db_class ) ) db.get_or_create_relation( self.source_db_object._db_node, destination_db_object._db_node, properties={'destination_key': destination_key, 'tag': tag}, type_=self.relation_type )
def add(self, *destination_db_objects): for dest in destination_db_objects: if not isinstance(dest, self.destination_db_class): raise errors.SolarError( 'Object {} is of incompatible type {}.'.format( dest, self.destination_db_class ) ) db.get_or_create_relation( self.source_db_object._db_node, dest._db_node, properties={}, type_=self.relation_type )
def run(self, transport): if self.valid: executor_result = self._executor(transport) if isinstance(executor_result, tuple) \ and len(executor_result) == 3: # TODO Include file information in result obj = SolarTransportResult.from_tuple(*executor_result) log.debug('RC %s OUT %s ERR %s', obj.return_code, obj.stdout, obj.stderr) if obj.success is False: raise errors.SolarError(obj.output) elif obj.success is None: log.debug("Cannot verify result") elif executor_result is None: pass else: log.debug("Unknown executor_result %r", executor_result)
def action(self, resource, action): # This would require to put this file to remote and execute it (mostly) log.debug("Ansible playbook is not ported to pluggable transports") action_file = os.path.join(resource.metadata['actions_path'], resource.metadata['actions'][action]) stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) variables = resource.args_dict() if 'roles' in variables: self.download_roles(variables['roles']) remote_user = variables.get('ssh_user') or C.DEFAULT_REMOTE_USER private_key_file = variables.get( 'ssh_key') or C.DEFAULT_PRIVATE_KEY_FILE if variables.get('ip'): host = variables['ip'] transport = C.DEFAULT_TRANSPORT else: host = 'localhost' transport = 'local' C.HOST_KEY_CHECKING = False play = PlayBook(playbook=action_file, remote_user=remote_user, host_list=[host], private_key_file=private_key_file, extra_vars=variables, callbacks=playbook_cb, runner_callbacks=runner_cb, stats=stats, transport=transport) play.run() summary = stats.summarize(host) if summary.get('unreachable') or summary.get('failures'): raise errors.SolarError( 'Ansible playbook %s failed with next summary %s', action_file, summary)
def __init__(self, **kwargs): wrong_fields = set(kwargs) - set(self._meta['fields']) if wrong_fields: raise errors.SolarError( 'Unknown fields {}'.format(wrong_fields) ) self._fields = {} for field_name, field_klass in self._meta['fields'].items(): value = kwargs.get(field_name, field_klass.default_value) self._fields[field_name] = field_klass(field_name, value=value) self._related_to = {} for field_name, field_klass in self._meta['related_to'].items(): inst = field_klass(field_name, self) self._related_to[field_name] = inst self._update_values()
def action(self, resource, action_name): inventory_file = self._create_inventory(resource) playbook_file = self._create_playbook(resource, action_name) log.debug('inventory_file: %s', inventory_file) log.debug('playbook_file: %s', playbook_file) # self.transport_sync.copy(resource, self.dirs[resource.name], self.dirs[resource.name]) self._copy_templates_and_scripts(resource, action_name) self.transport_sync.copy(resource, self.dst, '/tmp') self.transport_sync.copy(resource, '/vagrant/library', '/tmp') self.transport_sync.sync_all() call_args = [ 'ansible-playbook', '--module-path', '/tmp/library', '-i', inventory_file, playbook_file ] log.debug('EXECUTING: %s', ' '.join(call_args)) out = self.transport_run.run(resource, *call_args) log.debug(out) if out.failed: raise errors.SolarError(out)
def _abort_exception(self, output): raise errors.SolarError(output)