Esempio n. 1
0
 def _return_pub(self, msg, ret):
     '''
     Send the return data back via the uxd socket
     '''
     ret_stack = LaneStack(lanename=self.opts['id'],
                           yid=ret['jid'],
                           sockdirpath=self.opts['sock_dir'],
                           dirpath=self.opts['cachedir'])
     ret_stack.Pk = raeting.packKinds.pack
     main_yard = RemoteYard(yid=0,
                            prefix=self.opts['id'],
                            dirpath=self.opts['sock_dir'])
     ret_stack.addRemote(main_yard)
     route = {
         'src': (self.opts['id'], ret_stack.local.name, 'jid_ret'),
         'dst': (msg['route']['src'][0], None, 'remote_cmd')
     }
     ret['cmd'] = '_return'
     ret['id'] = self.opts['id']
     try:
         oput = self.modules.value[ret['fun']].__outputter__
     except (KeyError, AttributeError, TypeError):
         pass
     else:
         if isinstance(oput, str):
             ret['out'] = oput
     msg = {'route': route, 'load': ret}
     ret_stack.transmit(msg, ret_stack.uids.get('yard0'))
     ret_stack.serviceAll()
Esempio n. 2
0
 def _return_pub(self, msg, ret):
     '''
     Send the return data back via the uxd socket
     '''
     ret_stack = LaneStack(
             lanename=self.opts['id'],
             yid=ret['jid'],
             sockdirpath=self.opts['sock_dir'],
             dirpath=self.opts['cachedir'])
     ret_stack.Pk = raeting.packKinds.pack
     main_yard = RemoteYard(
             yid=0,
             prefix=self.opts['id'],
             dirpath=self.opts['sock_dir']
             )
     ret_stack.addRemote(main_yard)
     route = {'src': (self.opts['id'], ret_stack.local.name, 'jid_ret'),
              'dst': (msg['route']['src'][0], None, 'remote_cmd')}
     ret['cmd'] = '_return'
     ret['id'] = self.opts['id']
     try:
         oput = self.modules.value[ret['fun']].__outputter__
     except (KeyError, AttributeError, TypeError):
         pass
     else:
         if isinstance(oput, str):
             ret['out'] = oput
     msg = {'route': route, 'load': ret}
     ret_stack.transmit(msg, ret_stack.uids.get('yard0'))
     ret_stack.serviceAll()
Esempio n. 3
0
    def action(self):

        self.presence_req.value = deque()
        self.availables.value = set()
        self.alloweds.value = odict()
        self.aliveds.value = odict()
        self.reapeds.value = odict()

        # Create event stack
        name = 'event' + nacling.uuid(size=18)
        lanename = self.lane_stack.value.local.lanename
        sock_dir = self.lane_stack.value.local.dirpath
        ryn = 'manor'
        console.terse(
            "Create stack: name = {0}, lanename = {1}, sock_dir = {2}\n".
            format(name, lanename, sock_dir))
        stack = LaneStack(name=name, lanename=lanename, sockdirpath=sock_dir)
        stack.addRemote(
            RemoteYard(stack=stack,
                       lanename=lanename,
                       name=ryn,
                       dirpath=sock_dir))
        self.event_stack.value = stack

        route = {
            'dst': (None, ryn, 'presence_req'),
            'src': (None, stack.local.name, None)
        }
        msg = {'route': route}
        stack.transmit(msg, stack.nameRemotes[ryn].uid)
        serviceLanes([stack, self.lane_stack.value])
Esempio n. 4
0
    def action(self):

        self.stats_req.value = deque()

        # Create event stack
        name = 'event' + nacling.uuid(size=18)
        lanename = self.lane_stack.value.local.lanename
        sock_dir = self.lane_stack.value.local.dirpath
        ryn = 'manor'
        console.terse("Create stack: name = {0}, lanename = {1}, sock_dir = {2}\n".
                      format(name, lanename, sock_dir))
        stack = LaneStack(
            name=name,
            lanename=lanename,
            sockdirpath=sock_dir)
        stack.addRemote(RemoteYard(stack=stack,
                                   lanename=lanename,
                                   name=ryn,
                                   dirpath=sock_dir))
        self.event_stack.value = stack

        route = {'dst': (None, ryn, 'stats_req'),
                 'src': (None, stack.local.name, None)}
        msg = {'route': route}
        stack.transmit(msg, stack.nameRemotes[ryn].uid)
        serviceLanes([stack, self.lane_stack.value])
Esempio n. 5
0
class RAETChannel(Channel):
    '''
    Build the communication framework to communicate over the local process
    uxd socket and send messages forwarded to the master. then wait for the
    relative return message.
    '''
    def __init__(self, opts, **kwargs):
        self.opts = opts
        self.ttype = 'raet'
        self.__prep_stack()

    def __prep_stack(self):
        '''
        Prepare the stack objects
        '''
        yid = salt.utils.gen_jid()
        stackname = self.opts['id'] + yid
        dirpath = os.path.join(self.opts['cachedir'], stackname)
        self.stack = LaneStack(name=stackname,
                               lanename=self.opts['id'],
                               yid=yid,
                               dirpath=dirpath,
                               sockdirpath=self.opts['sock_dir'])
        self.stack.Pk = raeting.packKinds.pack
        self.router_yard = yarding.RemoteYard(stack=self.stack,
                                              yid=0,
                                              lanename=self.opts['id'],
                                              dirpath=self.opts['sock_dir'])
        self.stack.addRemote(self.router_yard)
        src = (self.opts['id'], self.stack.local.name, None)
        dst = ('master', None, 'remote_cmd')
        self.route = {'src': src, 'dst': dst}

    def crypted_transfer_decode_dictentry(self,
                                          load,
                                          dictkey=None,
                                          tries=3,
                                          timeout=60):
        '''
        We don't need to do the crypted_transfer_decode_dictentry routine for
        raet, just wrap send.
        '''
        return self.send(load, tries, timeout)

    def send(self, load, tries=3, timeout=60):
        '''
        Send a message load and wait for a relative reply
        '''
        msg = {'route': self.route, 'load': load}
        self.stack.transmit(msg, self.stack.uids['yard0'])
        while True:
            time.sleep(0.01)
            self.stack.serviceAll()
            if self.stack.rxMsgs:
                for msg in self.stack.rxMsgs:
                    return msg.get('return', {})
Esempio n. 6
0
 def pub(self,
         tgt,
         fun,
         arg=(),
         expr_form='glob',
         ret='',
         jid='',
         timeout=5,
         **kwargs):
     '''
     Publish the command!
     '''
     payload_kwargs = self._prep_pub(
             tgt,
             fun,
             arg=arg,
             expr_form=expr_form,
             ret=ret,
             jid=jid,
             timeout=timeout,
             **kwargs)
     kind = self.opts['__role']
     if kind == 'master':
         lanename = 'master'  # self.opts.value.get('id', self.main.data.lanename)
     else:  # workers currently are only supported for masters
         emsg = ("Invalid application kind '{0}' for client.".format(kind))
         log.error(emsg + '\n')
         raise ValueError(emsg)
     name = 'client' + nacling.uuid(size=18)
     stack = LaneStack(
             name=name,
             lanename=lanename,
             sockdirpath=self.opts['sock_dir'])
     stack.Pk = raeting.packKinds.pack
     router_yard = RemoteYard(
             stack=stack,
             lanename=lanename,
             name='manor',
             dirpath=self.opts['sock_dir'])
     stack.addRemote(router_yard)
     route = {'dst': (None, router_yard.name, 'local_cmd'),
              'src': (None, stack.local.name, None)}
     msg = {'route': route, 'load': payload_kwargs}
     stack.transmit(msg)
     stack.serviceAll()
     while True:
         time.sleep(0.01)
         stack.serviceAll()
         while stack.rxMsgs:
             msg, sender = stack.rxMsgs.popleft()
             ret = msg.get('return', {})
             if 'ret' in ret:
                 stack.server.close()
                 return ret['ret']
             stack.server.close()
             return ret
Esempio n. 7
0
 def pub(self,
         tgt,
         fun,
         arg=(),
         expr_form='glob',
         ret='',
         jid='',
         timeout=5,
         **kwargs):
     '''
     Publish the command!
     '''
     payload_kwargs = self._prep_pub(tgt,
                                     fun,
                                     arg=arg,
                                     expr_form=expr_form,
                                     ret=ret,
                                     jid=jid,
                                     timeout=timeout,
                                     **kwargs)
     kind = self.opts['__role']
     if kind == 'master':
         lanename = 'master'  # self.opts.value.get('id', self.main.data.lanename)
     else:  # workers currently are only supported for masters
         emsg = ("Invalid application kind '{0}' for client.".format(kind))
         log.error(emsg + '\n')
         raise ValueError(emsg)
     name = 'client' + nacling.uuid(size=18)
     stack = LaneStack(name=name,
                       lanename=lanename,
                       sockdirpath=self.opts['sock_dir'])
     stack.Pk = raeting.packKinds.pack
     router_yard = RemoteYard(stack=stack,
                              lanename=lanename,
                              name='manor',
                              dirpath=self.opts['sock_dir'])
     stack.addRemote(router_yard)
     route = {
         'dst': (None, router_yard.name, 'local_cmd'),
         'src': (None, stack.local.name, None)
     }
     msg = {'route': route, 'load': payload_kwargs}
     stack.transmit(msg)
     stack.serviceAll()
     while True:
         time.sleep(0.01)
         stack.serviceAll()
         while stack.rxMsgs:
             msg, sender = stack.rxMsgs.popleft()
             ret = msg.get('return', {})
             if 'ret' in ret:
                 stack.server.close()
                 return ret['ret']
             stack.server.close()
             return ret
Esempio n. 8
0
 def pub(self,
         tgt,
         fun,
         arg=(),
         expr_form='glob',
         ret='',
         jid='',
         timeout=5,
         **kwargs):
     '''
     Publish the command!
     '''
     payload_kwargs = self._prep_pub(
             tgt,
             fun,
             arg=arg,
             expr_form=expr_form,
             ret=ret,
             jid=jid,
             timeout=timeout,
             **kwargs)
     yid = nacling.uuid(size=18)
     stack = LaneStack(
             name=('client' + yid),
             yid=yid,
             lanename='master',
             sockdirpath=self.opts['sock_dir'])
     stack.Pk = raeting.packKinds.pack
     router_yard = RemoteYard(
             stack=stack,
             lanename='master',
             yid=0,
             name='manor',
             dirpath=self.opts['sock_dir'])
     stack.addRemote(router_yard)
     route = {'dst': (None, router_yard.name, 'local_cmd'),
              'src': (None, stack.local.name, None)}
     msg = {'route': route, 'load': payload_kwargs}
     stack.transmit(msg)
     stack.serviceAll()
     while True:
         time.sleep(0.01)
         stack.serviceAll()
         while stack.rxMsgs:
             msg, sender = stack.rxMsgs.popleft()
             ret = msg.get('return', {})
             if 'ret' in ret:
                 stack.server.close()
                 return ret['ret']
             stack.server.close()
             return ret
Esempio n. 9
0
 def pub(self,
         tgt,
         fun,
         arg=(),
         expr_form='glob',
         ret='',
         jid='',
         timeout=5,
         **kwargs):
     '''
     Publish the command!
     '''
     payload_kwargs = self._prep_pub(
             tgt,
             fun,
             arg=arg,
             expr_form=expr_form,
             ret=ret,
             jid=jid,
             timeout=timeout,
             **kwargs)
     uid = nacling.uuid(size=18)
     stack = LaneStack(
             name=('client' + uid),
             uid=uid,
             lanename='master',
             sockdirpath=self.opts['sock_dir'])
     stack.Pk = raeting.packKinds.pack
     router_yard = RemoteYard(
             stack=stack,
             lanename='master',
             uid=0,
             name='manor',
             dirpath=self.opts['sock_dir'])
     stack.addRemote(router_yard)
     route = {'dst': (None, router_yard.name, 'local_cmd'),
              'src': (None, stack.local.name, None)}
     msg = {'route': route, 'load': payload_kwargs}
     stack.transmit(msg)
     stack.serviceAll()
     while True:
         time.sleep(0.01)
         stack.serviceAll()
         while stack.rxMsgs:
             msg, sender = stack.rxMsgs.popleft()
             ret = msg.get('return', {})
             if 'ret' in ret:
                 stack.server.close()
                 return ret['ret']
             stack.server.close()
             return ret
Esempio n. 10
0
class RAETChannel(Channel):
    '''
    Build the communication framework to communicate over the local process
    uxd socket and send messages forwarded to the master. then wait for the
    relative return message.
    '''
    def __init__(self, opts, **kwargs):
        self.opts = opts
        self.ttype = 'raet'
        self.__prep_stack()

    def __prep_stack(self):
        '''
        Prepare the stack objects
        '''
        self.stack = LaneStack(
                lanename=self.opts['id'],
                yid=salt.utils.gen_jid(),
                dirpath=self.opts['cachedir'],
                sockdirpath=self.opts['sock_dir'])
        self.stack.Pk = raeting.packKinds.pack
        self.router_yard = yarding.RemoteYard(
                yid=0,
                prefix=self.opts['id'],
                dirpath=self.opts['sock_dir'])
        self.stack.addRemote(self.router_yard)
        src = (self.opts['id'], self.stack.local.name, None)
        dst = ('master', None, 'remote_cmd')
        self.route = {'src': src, 'dst': dst}

    def crypted_transfer_decode_dictentry(self, load, dictkey=None, tries=3, timeout=60):
        '''
        We don't need to do the crypted_transfer_decode_dictentry routine for
        raet, just wrap send.
        '''
        return self.send(load, tries, timeout)

    def send(self, load, tries=3, timeout=60):
        '''
        Send a message load and wait for a relative reply
        '''
        msg = {'route': self.route, 'load': load}
        self.stack.transmit(msg, self.stack.uids['yard0'])
        while True:
            time.sleep(0.01)
            self.stack.serviceAll()
            if self.stack.rxMsgs:
                for msg in self.stack.rxMsgs:
                    return msg.get('return', {})
Esempio n. 11
0
 def pub(self,
         tgt,
         fun,
         arg=(),
         expr_form='glob',
         ret='',
         jid='',
         timeout=5,
         **kwargs):
     '''
     Publish the command!
     '''
     payload_kwargs = self._prep_pub(tgt,
                                     fun,
                                     arg=arg,
                                     expr_form=expr_form,
                                     ret=ret,
                                     jid=jid,
                                     timeout=timeout,
                                     **kwargs)
     yid = salt.utils.gen_jid()
     basedirpath = os.path.join(self.opts['cachedir'], 'raet')
     stack = LaneStack(name=('client' + yid),
                       yid=yid,
                       lanename='master',
                       basedirpath=basedirpath,
                       sockdirpath=self.opts['sock_dir'])
     stack.Pk = raeting.packKinds.pack
     router_yard = RemoteYard(stack=stack,
                              lanename='master',
                              yid=0,
                              dirpath=self.opts['sock_dir'])
     stack.addRemote(router_yard)
     route = {
         'dst': (None, router_yard.name, 'local_cmd'),
         'src': (None, stack.local.name, None)
     }
     msg = {'route': route, 'load': payload_kwargs}
     stack.transmit(msg)
     stack.serviceAll()
     while True:
         time.sleep(0.01)
         stack.serviceAll()
         for msg in stack.rxMsgs:
             ret = msg.get('return', {})
             if 'ret' in ret:
                 return ret['ret']
             return ret
Esempio n. 12
0
 def pub(self,
         tgt,
         fun,
         arg=(),
         expr_form='glob',
         ret='',
         jid='',
         timeout=5,
         **kwargs):
     '''
     Publish the command!
     '''
     payload_kwargs = self._prep_pub(
             tgt,
             fun,
             arg=arg,
             expr_form=expr_form,
             ret=ret,
             jid=jid,
             timeout=timeout,
             **kwargs)
     yid = salt.utils.gen_jid()
     stack = LaneStack(
             yid=yid,
             lanename='master',
             sockdirpath=self.opts['sock_dir'])
     stack.Pk = raeting.packKinds.pack
     router_yard = RemoteYard(
             prefix='master',
             yid=0,
             dirpath=self.opts['sock_dir'])
     stack.addRemote(router_yard)
     route = {'dst': (None, router_yard.name, 'local_cmd'),
              'src': (None, stack.local.name, None)}
     msg = {'route': route, 'load': payload_kwargs}
     stack.transmit(msg)
     stack.serviceAll()
     while True:
         time.sleep(0.01)
         stack.serviceAll()
         for msg in stack.rxMsgs:
             return msg.get('return', {}).get('ret', {})
Esempio n. 13
0
    def action(self):

        self.presence_req.value = deque()
        self.availables.value = set()
        self.alloweds.value = odict()
        self.aliveds.value = odict()
        self.reapeds.value = odict()

        # Create event stack
        name = "event" + nacling.uuid(size=18)
        lanename = self.lane_stack.value.local.lanename
        sock_dir = self.lane_stack.value.local.dirpath
        ryn = "manor"
        console.terse("Create stack: name = {0}, lanename = {1}, sock_dir = {2}\n".format(name, lanename, sock_dir))
        stack = LaneStack(name=name, lanename=lanename, sockdirpath=sock_dir)
        stack.addRemote(RemoteYard(stack=stack, lanename=lanename, name=ryn, dirpath=sock_dir))
        self.event_stack.value = stack

        route = {"dst": (None, ryn, "presence_req"), "src": (None, stack.local.name, None)}
        msg = {"route": route}
        stack.transmit(msg, stack.nameRemotes[ryn].uid)
        serviceLanes([stack, self.lane_stack.value])
Esempio n. 14
0
    def pub(self,
            tgt,
            fun,
            arg=(),
            tgt_type='glob',
            ret='',
            jid='',
            timeout=5,
            **kwargs):
        '''
        Publish the command!
        '''
        if 'expr_form' in kwargs:
            salt.utils.warn_until(
                'Fluorine',
                'The target type should be passed using the \'tgt_type\' '
                'argument instead of \'expr_form\'. Support for using '
                '\'expr_form\' will be removed in Salt Fluorine.'
            )
            tgt_type = kwargs.pop('expr_form')

        payload_kwargs = self._prep_pub(
                tgt,
                fun,
                arg=arg,
                tgt_type=tgt_type,
                ret=ret,
                jid=jid,
                timeout=timeout,
                **kwargs)

        kind = self.opts['__role']
        if kind not in kinds.APPL_KINDS:
            emsg = ("Invalid application kind = '{0}' for Raet LocalClient.".format(kind))
            log.error(emsg + "\n")
            raise ValueError(emsg)
        if kind in [kinds.APPL_KIND_NAMES[kinds.applKinds.master],
                    kinds.APPL_KIND_NAMES[kinds.applKinds.syndic]]:
            lanename = 'master'
        else:
            emsg = ("Unsupported application kind '{0}' for Raet LocalClient.".format(kind))
            log.error(emsg + '\n')
            raise ValueError(emsg)

        sockdirpath = self.opts['sock_dir']
        name = 'client' + nacling.uuid(size=18)
        stack = LaneStack(
                name=name,
                lanename=lanename,
                sockdirpath=sockdirpath)
        stack.Pk = raeting.PackKind.pack.value
        manor_yard = RemoteYard(
                stack=stack,
                lanename=lanename,
                name='manor',
                dirpath=sockdirpath)
        stack.addRemote(manor_yard)
        route = {'dst': (None, manor_yard.name, 'local_cmd'),
                 'src': (None, stack.local.name, None)}
        msg = {'route': route, 'load': payload_kwargs}
        stack.transmit(msg)
        stack.serviceAll()
        while True:
            time.sleep(0.01)
            stack.serviceAll()
            while stack.rxMsgs:
                msg, sender = stack.rxMsgs.popleft()
                ret = msg.get('return', {})
                if 'ret' in ret:
                    stack.server.close()
                    return ret['ret']
                stack.server.close()
                return ret
Esempio n. 15
0
class SaltEvent(object):
    '''
    The base class used to manage salt events
    '''
    def __init__(self, node, sock_dir=None, listen=True, opts=None):
        '''
        Set up the stack and remote yard
        '''
        self.node = node
        self.sock_dir = sock_dir
        self.listen = listen
        if opts is None:
            opts = {}
        self.opts = opts
        self.__prep_stack()

    def __prep_stack(self):
        self.yid = salt.utils.gen_jid()
        name = 'event' + self.yid
        cachedir = self.opts.get('cachedir', os.path.join(syspaths.CACHE_DIR, self.node))
        basedirpath = os.path.abspath(
                os.path.join(cachedir, 'raet'))
        self.connected = False
        self.stack = LaneStack(
                name=name,
                yid=self.yid,
                lanename=self.node,
                basedirpath=basedirpath,
                sockdirpath=self.sock_dir)
        self.stack.Pk = raeting.packKinds.pack
        self.router_yard = RemoteYard(
                stack=self.stack,
                lanename=self.node,
                yid=0,
                dirpath=self.sock_dir)
        self.stack.addRemote(self.router_yard)
        self.connect_pub()

    def subscribe(self, tag=None):
        '''
        Included for compat with zeromq events, not required
        '''
        return

    def unsubscribe(self, tag=None):
        '''
        Included for compat with zeromq events, not required
        '''
        return

    def connect_pub(self):
        '''
        Establish the publish connection
        '''
        if not self.connected and self.listen:
            try:
                route = {'dst': (None, self.router_yard.name, 'event_req'),
                         'src': (None, self.stack.local.name, None)}
                msg = {
                        'route': route,
                        'load': {'yid': self.yid, 'dirpath': self.sock_dir}}
                self.stack.transmit(msg, self.router_yard.uid)
                self.stack.serviceAll()
                self.connected = True
            except Exception:
                pass

    def connect_pull(self, timeout=1000):
        '''
        Included for compat with zeromq events, not required
        '''
        return

    @classmethod
    def unpack(cls, raw, serial=None):
        '''
        Included for compat with zeromq events, not required
        '''
        return raw

    def get_event(self, wait=5, tag='', full=False):
        '''
        Get a single publication.
        IF no publication available THEN block for up to wait seconds
        AND either return publication OR None IF no publication available.

        IF wait is 0 then block forever.
        '''
        self.connect_pub()
        start = time.time()
        while True:
            self.stack.serviceAll()
            if self.stack.rxMsgs:
                msg = self.stack.rxMsgs.popleft()
                event = msg.get('event', {})
                if 'tag' not in event and 'data' not in event:
                    # Invalid event, how did this get here?
                    continue
                if not event['tag'].startswith(tag):
                    # Not what we are looking for, throw it away
                    continue
                if full:
                    return event
                else:
                    return event['data']
            if start + wait < time.time():
                return None
            time.sleep(0.01)

    def get_event_noblock(self):
        '''
        Get the raw event without blocking or any other niceties
        '''
        self.connect_pub()
        self.stack.serviceAll()
        if self.stack.rxMsgs:
            event = self.stack.rxMsgs.popleft()
            if 'tag' not in event and 'data' not in event:
                # Invalid event, how did this get here?
                return None
            return event

    def iter_events(self, tag='', full=False):
        '''
        Creates a generator that continuously listens for events
        '''
        while True:
            data = self.get_event(tag=tag, full=full)
            if data is None:
                continue
            yield data

    def fire_event(self, data, tag, timeout=1000):
        '''
        Send a single event into the publisher with paylod dict "data" and event
        identifier "tag"
        '''
        self.connect_pub()
        # Timeout is retained for compat with zeromq events
        if not str(tag):  # no empty tags allowed
            raise ValueError('Empty tag.')

        if not isinstance(data, MutableMapping):  # data must be dict
            raise ValueError('Dict object expected, not "{0!r}".'.format(data))
        route = {'dst': (None, self.router_yard.name, 'event_fire'),
                 'src': (None, self.stack.local.name, None)}
        msg = {'route': route, 'tag': tag, 'data': data}
        self.stack.transmit(msg)
        self.stack.serviceAll()

    def fire_ret_load(self, load):
        '''
        Fire events based on information in the return load
        '''
        if load.get('retcode') and load.get('fun'):
            # Minion fired a bad retcode, fire an event
            if load['fun'] in salt.utils.event.SUB_EVENT:
                try:
                    for tag, data in load.get('return', {}).items():
                        data['retcode'] = load['retcode']
                        tags = tag.split('_|-')
                        if data.get('result') is False:
                            self.fire_event(
                                    data,
                                    '{0}.{1}'.format(tags[0], tags[-1]))  # old dup event
                            data['jid'] = load['jid']
                            data['id'] = load['id']
                            data['success'] = False
                            data['return'] = 'Error: {0}.{1}'.format(tags[0], tags[-1])
                            data['fun'] = load['fun']
                            data['user'] = load['user']
                            self.fire_event(
                                data,
                                salt.utils.event.tagify([load['jid'],
                                        'sub',
                                        load['id'],
                                        'error',
                                        load['fun']],
                                       'job'))
                except Exception:
                    pass
Esempio n. 16
0
    def pub(self,
            tgt,
            fun,
            arg=(),
            tgt_type='glob',
            ret='',
            jid='',
            timeout=5,
            **kwargs):
        '''
        Publish the command!
        '''
        if 'expr_form' in kwargs:
            salt.utils.warn_until(
                'Fluorine',
                'The target type should be passed using the \'tgt_type\' '
                'argument instead of \'expr_form\'. Support for using '
                '\'expr_form\' will be removed in Salt Fluorine.'
            )
            tgt_type = kwargs.pop('expr_form')

        payload_kwargs = self._prep_pub(
                tgt,
                fun,
                arg=arg,
                tgt_type=tgt_type,
                ret=ret,
                jid=jid,
                timeout=timeout,
                **kwargs)

        kind = self.opts['__role']
        if kind not in kinds.APPL_KINDS:
            emsg = ("Invalid application kind = '{0}' for Raet LocalClient.".format(kind))
            log.error(emsg + "\n")
            raise ValueError(emsg)
        if kind in [kinds.APPL_KIND_NAMES[kinds.applKinds.master],
                    kinds.APPL_KIND_NAMES[kinds.applKinds.syndic]]:
            lanename = 'master'
        else:
            emsg = ("Unsupported application kind '{0}' for Raet LocalClient.".format(kind))
            log.error(emsg + '\n')
            raise ValueError(emsg)

        sockdirpath = self.opts['sock_dir']
        name = 'client' + nacling.uuid(size=18)
        stack = LaneStack(
                name=name,
                lanename=lanename,
                sockdirpath=sockdirpath)
        stack.Pk = raeting.PackKind.pack.value
        manor_yard = RemoteYard(
                stack=stack,
                lanename=lanename,
                name='manor',
                dirpath=sockdirpath)
        stack.addRemote(manor_yard)
        route = {'dst': (None, manor_yard.name, 'local_cmd'),
                 'src': (None, stack.local.name, None)}
        msg = {'route': route, 'load': payload_kwargs}
        stack.transmit(msg)
        stack.serviceAll()
        while True:
            time.sleep(0.01)
            stack.serviceAll()
            while stack.rxMsgs:
                msg, sender = stack.rxMsgs.popleft()
                ret = msg.get('return', {})
                if 'ret' in ret:
                    stack.server.close()
                    return ret['ret']
                stack.server.close()
                return ret
Esempio n. 17
0
class SaltEvent(object):
    '''
    The base class used to manage salt events
    '''
    def __init__(self, node, sock_dir=None, listen=True, opts=None):
        '''
        Set up the stack and remote yard
        '''
        self.node = node  # application kind 'master', 'minion', 'syndic', 'call' etc
        self.sock_dir = sock_dir
        self.listen = listen
        if opts is None:
            opts = {}
        self.opts = opts
        self.__prep_stack()

    def __prep_stack(self):
        if self.node == 'master':
            lanename = 'master'
            if self.opts:
                kind = self.opts.get('__role', '')  # opts optional for master
                if kind and kind != self.node:
                    emsg = ("Mismatch between node '{0}' and kind '{1}' in setup "
                            "of SaltEvent on Raet.".format(self.node, kind))
                    log.error(emsg + '\n')
                    raise ValueError(emsg)
        elif self.node == 'minion':
            role = self.opts.get('id', '')  # opts required for minion
            if not role:
                emsg = ("Missing opts['id'] required by SaltEvent on Raet with "
                       "node kind {0}.".format(self.node))
                log.error(emsg + '\n')
                raise ValueError(emsg)
            kind = self.opts.get('__role', '')
            if kind != self.node:
                emsg = ("Mismatch between node '{0}' and kind '{1}' in setup "
                       "of SaltEvent on Raet.".format(self.node, kind))
                log.error(emsg + '\n')
                raise ValueError(emsg)
            lanename = role  # add '_minion'
        else:
            emsg = ("Unsupported application node kind '{0}' for SaltEvent "
                    "Raet.".format(self.node))
            log.error(emsg + '\n')
            raise ValueError(emsg)

        name = 'event' + nacling.uuid(size=18)
        cachedir = self.opts.get('cachedir', os.path.join(syspaths.CACHE_DIR, self.node))
        self.connected = False
        self.stack = LaneStack(
                name=name,
                lanename=lanename,
                sockdirpath=self.sock_dir)
        self.stack.Pk = raeting.packKinds.pack
        self.router_yard = RemoteYard(
                stack=self.stack,
                lanename=lanename,
                name='manor',
                dirpath=self.sock_dir)
        self.stack.addRemote(self.router_yard)
        self.connect_pub()

    def subscribe(self, tag=None):
        '''
        Included for compat with zeromq events, not required
        '''
        return

    def unsubscribe(self, tag=None):
        '''
        Included for compat with zeromq events, not required
        '''
        return

    def connect_pub(self):
        '''
        Establish the publish connection
        '''
        if not self.connected and self.listen:
            try:
                route = {'dst': (None, self.router_yard.name, 'event_req'),
                         'src': (None, self.stack.local.name, None)}
                msg = {'route': route}
                self.stack.transmit(msg, self.router_yard.uid)
                self.stack.serviceAll()
                self.connected = True
            except Exception:
                pass

    def connect_pull(self, timeout=1000):
        '''
        Included for compat with zeromq events, not required
        '''
        return

    @classmethod
    def unpack(cls, raw, serial=None):
        '''
        Included for compat with zeromq events, not required
        '''
        return raw

    def get_event(self, wait=5, tag='', full=False):
        '''
        Get a single publication.
        IF no publication available THEN block for up to wait seconds
        AND either return publication OR None IF no publication available.

        IF wait is 0 then block forever.
        '''
        self.connect_pub()
        start = time.time()
        while True:
            self.stack.serviceAll()
            if self.stack.rxMsgs:
                msg, sender = self.stack.rxMsgs.popleft()
                if 'tag' not in msg and 'data' not in msg:
                    # Invalid event, how did this get here?
                    continue
                if not msg['tag'].startswith(tag):
                    # Not what we are looking for, throw it away
                    continue
                if full:
                    return msg
                else:
                    return msg['data']
            if start + wait < time.time():
                return None
            time.sleep(0.01)

    def get_event_noblock(self):
        '''
        Get the raw event msg without blocking or any other niceties
        '''
        self.connect_pub()
        self.stack.serviceAll()
        if self.stack.rxMsgs:
            msg, sender = self.stack.rxMsgs.popleft()
            if 'tag' not in msg and 'data' not in msg:
                # Invalid event, how did this get here?
                return None
            return msg

    def iter_events(self, tag='', full=False):
        '''
        Creates a generator that continuously listens for events
        '''
        while True:
            data = self.get_event(tag=tag, full=full)
            if data is None:
                continue
            yield data

    def fire_event(self, data, tag, timeout=1000):
        '''
        Send a single event into the publisher with paylod dict "data" and event
        identifier "tag"
        '''
        self.connect_pub()
        # Timeout is retained for compat with zeromq events
        if not str(tag):  # no empty tags allowed
            raise ValueError('Empty tag.')

        if not isinstance(data, MutableMapping):  # data must be dict
            raise ValueError('Dict object expected, not "{0!r}".'.format(data))
        route = {'dst': (None, self.router_yard.name, 'event_fire'),
                 'src': (None, self.stack.local.name, None)}
        msg = {'route': route, 'tag': tag, 'data': data}
        self.stack.transmit(msg, self.router_yard.uid)
        self.stack.serviceAll()

    def fire_ret_load(self, load):
        '''
        Fire events based on information in the return load
        '''
        if load.get('retcode') and load.get('fun'):
            # Minion fired a bad retcode, fire an event
            if load['fun'] in salt.utils.event.SUB_EVENT:
                try:
                    for tag, data in load.get('return', {}).items():
                        data['retcode'] = load['retcode']
                        tags = tag.split('_|-')
                        if data.get('result') is False:
                            self.fire_event(
                                    data,
                                    '{0}.{1}'.format(tags[0], tags[-1]))  # old dup event
                            data['jid'] = load['jid']
                            data['id'] = load['id']
                            data['success'] = False
                            data['return'] = 'Error: {0}.{1}'.format(tags[0], tags[-1])
                            data['fun'] = load['fun']
                            data['user'] = load['user']
                            self.fire_event(
                                data,
                                salt.utils.event.tagify([load['jid'],
                                        'sub',
                                        load['id'],
                                        'error',
                                        load['fun']],
                                       'job'))
                except Exception:
                    pass

    def destroy(self):
        if hasattr(self, 'stack'):
            self.stack.server.close()

    def __del__(self):
        self.destroy()
Esempio n. 18
0
    def pub(self,
            tgt,
            fun,
            arg=(),
            expr_form='glob',
            ret='',
            jid='',
            timeout=5,
            **kwargs):
        '''
        Publish the command!
        '''
        payload_kwargs = self._prep_pub(tgt,
                                        fun,
                                        arg=arg,
                                        expr_form=expr_form,
                                        ret=ret,
                                        jid=jid,
                                        timeout=timeout,
                                        **kwargs)

        kind = self.opts['__role']
        if kind not in kinds.APPL_KINDS:
            emsg = ("Invalid application kind = '{0}' for Raet LocalClient.".
                    format(kind))
            log.error(emsg + "\n")
            raise ValueError(emsg)
        if kind in [
                kinds.APPL_KIND_NAMES[kinds.applKinds.master],
                kinds.APPL_KIND_NAMES[kinds.applKinds.syndic]
        ]:
            lanename = 'master'
        else:
            emsg = ("Unsupported application kind '{0}' for Raet LocalClient.".
                    format(kind))
            log.error(emsg + '\n')
            raise ValueError(emsg)

        sockdirpath = self.opts['sock_dir']
        name = 'client' + nacling.uuid(size=18)
        stack = LaneStack(name=name,
                          lanename=lanename,
                          sockdirpath=sockdirpath)
        stack.Pk = raeting.packKinds.pack
        manor_yard = RemoteYard(stack=stack,
                                lanename=lanename,
                                name='manor',
                                dirpath=sockdirpath)
        stack.addRemote(manor_yard)
        route = {
            'dst': (None, manor_yard.name, 'local_cmd'),
            'src': (None, stack.local.name, None)
        }
        msg = {'route': route, 'load': payload_kwargs}
        stack.transmit(msg)
        stack.serviceAll()
        while True:
            time.sleep(0.01)
            stack.serviceAll()
            while stack.rxMsgs:
                msg, sender = stack.rxMsgs.popleft()
                ret = msg.get('return', {})
                if 'ret' in ret:
                    stack.server.close()
                    return ret['ret']
                stack.server.close()
                return ret
Esempio n. 19
0
class SaltEvent(object):
    '''
    The base class used to manage salt events
    '''
    def __init__(self, node, sock_dir=None, listen=True):
        '''
        Set up the stack and remote yard
        '''
        #import  wingdbstub

        self.node = node
        self.sock_dir = sock_dir
        self.listen = listen
        self.__prep_stack()

    def __prep_stack(self):
        self.yid = salt.utils.gen_jid()
        self.connected = False
        self.stack = LaneStack(
                yid=self.yid,
                lanename=self.node,
                sockdirpath=self.sock_dir)
        self.stack.Pk = raeting.packKinds.pack
        self.router_yard = RemoteYard(
                prefix=self.node,
                yid=0,
                dirpath=self.sock_dir)
        self.stack.addRemote(self.router_yard)
        self.connect_pub()

    def subscribe(self, tag=None):
        '''
        Included for compat with zeromq events, not required
        '''
        return

    def unsubscribe(self, tag=None):
        '''
        Included for compat with zeromq events, not required
        '''
        return

    def connect_pub(self):
        '''
        Establish the publish connection
        '''
        if not self.connected and self.listen:
            try:
                route = {'dst': (None, self.router_yard.name, 'event_req'),
                         'src': (None, self.stack.local.name, None)}
                msg = {
                        'route': route,
                        'load': {'yid': self.yid, 'dirpath': self.sock_dir}}
                self.stack.transmit(msg, self.router_yard.uid)
                self.stack.serviceAll()
                self.connected = True
            except Exception:
                pass

    def connect_pull(self, timeout=1000):
        '''
        Included for compat with zeromq events, not required
        '''
        return

    @classmethod
    def unpack(cls, raw, serial=None):
        '''
        Included for compat with zeromq events, not required
        '''
        return raw

    def get_event(self, wait=5, tag='', full=False):
        '''
        Get a single publication.
        IF no publication available THEN block for up to wait seconds
        AND either return publication OR None IF no publication available.

        IF wait is 0 then block forever.
        '''
        self.connect_pub()
        start = time.time()
        while True:
            self.stack.serviceAll()
            if self.stack.rxMsgs:
                msg = self.stack.rxMsgs.popleft()
                event = msg.get('event', {})
                if 'tag' not in event and 'data' not in event:
                    # Invalid event, how did this get here?
                    continue
                if not event['tag'].startswith(tag):
                    # Not what we are looking for, throw it away
                    continue
                if full:
                    return event
                else:
                    return event['data']
            if start + wait < time.time():
                return None
            time.sleep(0.01)

    def get_event_noblock(self):
        '''
        Get the raw event without blocking or any other niceties
        '''
        self.connect_pub()
        self.stack.serviceAll()
        if self.stack.rxMsgs:
            event = self.stack.rxMsgs.popleft()
            if 'tag' not in event and 'data' not in event:
                # Invalid event, how did this get here?
                return None
            return event

    def iter_events(self, tag='', full=False):
        '''
        Creates a generator that continuously listens for events
        '''
        while True:
            data = self.get_event(tag=tag, full=full)
            if data is None:
                continue
            yield data

    def fire_event(self, data, tag, timeout=1000):
        '''
        Send a single event into the publisher with paylod dict "data" and event
        identifier "tag"
        '''
        self.connect_pub()
        # Timeout is retained for compat with zeromq events
        if not str(tag):  # no empty tags allowed
            raise ValueError('Empty tag.')

        if not isinstance(data, MutableMapping):  # data must be dict
            raise ValueError('Dict object expected, not "{0!r}".'.format(data))
        route = {'dst': (None, self.router_yard.name, 'event_fire'),
                 'src': (None, self.stack.local.name, None)}
        msg = {'route': route, 'tag': tag, 'data': data}
        self.stack.transmit(msg)
        self.stack.serviceAll()

    def fire_ret_load(self, load):
        '''
        Fire events based on information in the return load
        '''
        if load.get('retcode') and load.get('fun'):
            # Minion fired a bad retcode, fire an event
            if load['fun'] in salt.utils.event.SUB_EVENT:
                try:
                    for tag, data in load.get('return', {}).items():
                        data['retcode'] = load['retcode']
                        tags = tag.split('_|-')
                        if data.get('result') is False:
                            self.fire_event(
                                    data,
                                    '{0}.{1}'.format(tags[0], tags[-1]))  # old dup event
                            data['jid'] = load['jid']
                            data['id'] = load['id']
                            data['success'] = False
                            data['return'] = 'Error: {0}.{1}'.format(tags[0], tags[-1])
                            data['fun'] = load['fun']
                            data['user'] = load['user']
                            self.fire_event(
                                data,
                                salt.utils.event.tagify([load['jid'],
                                        'sub',
                                        load['id'],
                                        'error',
                                        load['fun']],
                                       'job'))
                except Exception:
                    pass