Changed naming for estates and lane names to not be the same as the key role but to be derived from the role

based on the application kind
the raet role is the same as the minion id in salt

so  minion with id 'alpha' has a raet role of 'alpha'
the minion primary estate name is produced by appending '_' and the application kind
the application kinds are ['master', 'minion', 'syndic', 'call']
If the application kind is 'minion' then
Then the primary minion estate name is  'alpha_minion'
The lanename for the manor lane is also 'alpha_minion'

On a master the estate name is master role with the application kind appended
so if the master id = 'master' = raet role and the application kind is 'minion'
 then the primary estate name is
'master_master'

The lanename for the manor lane on a master is special
this is because salt cloud uses of the raet_channel do not yet have opts associated with them
so there is no way to extract the id or the application kind.
As a result the lanename for the master manor lane is always 'master'
This imposes a constraint that there only be one master on a given directory structure that
is the sock_dir must be unique per master else there will be collisions with the manor lane
of multiple master on the same host.

The estate name must be globally unique for a given raet Road
This convention allows multiple Estares to share the same role as long as they are
of unique application kinds.
The primary use case is to support salt_caller as an independent estate and not use the
minion primary estate to communicate with the master
This commit is contained in:
Samuel M Smith 2014-10-03 17:41:43 -06:00
parent dcf848de53
commit 1999f92173
10 changed files with 151 additions and 77 deletions

View File

@ -405,7 +405,6 @@ class SaltCall(parsers.SaltCallOptionParser):
# Setup file logging!
self.setup_logfile_logger()
#caller = salt.cli.caller.Caller(self.config)
caller = salt.cli.caller.Caller.factory(self.config)
if self.options.doc:

View File

@ -24,6 +24,8 @@ from salt._compat import string_types
from salt.log import LOG_LEVELS
from salt.utils import print_cli
from salt import daemons
log = logging.getLogger(__name__)
try:
@ -281,18 +283,34 @@ class RAETCaller(ZeroMQCaller):
not already setup such as in salt-call to communicate to-from the minion
'''
mid = opts['id']
role = opts.get('id')
if not role:
emsg = ("Missing role required to setup RAETChannel.")
log.error(emsg + "\n")
raise ValueError(emsg)
kind = opts.get('__role') # application kind 'master', 'minion', etc
if kind not in daemons.APPL_KINDS:
emsg = ("Invalid application kind = '{0}' for RAETChannel.".format(kind))
log.error(emsg + "\n")
raise ValueError(emsg)
if kind == 'minion':
lanename = "{0}_{1}".format(role, kind)
else:
emsg = ("Unsupported application kind '{0}' for RAETChannel.".format(kind))
log.error(emsg + '\n')
raise ValueError(emsg)
sockdirpath = opts['sock_dir']
uid = nacling.uuid(size=18)
name = 'caller' + uid
name = 'caller' + nacling.uuid(size=18)
stack = LaneStack(name=name,
lanename=mid,
lanename=lanename,
sockdirpath=sockdirpath)
stack.Pk = raeting.packKinds.pack
stack.addRemote(RemoteYard(stack=stack,
name='manor',
lanename=mid,
lanename=lanename,
dirpath=sockdirpath))
log.debug("Created Caller Jobber Stack {0}\n".format(stack.name))
return stack

View File

@ -17,6 +17,9 @@ import salt.client
import salt.utils
import salt.syspaths as syspaths
from salt import daemons
log = logging.getLogger(__name__)
@ -51,26 +54,32 @@ class LocalClient(salt.client.LocalClient):
jid=jid,
timeout=timeout,
**kwargs)
kind = self.opts['__role']
if kind not in daemons.APPL_KINDS:
emsg = ("Invalid application kind = '{0}' for Raet LocalClient.".format(kind))
log.error(emsg + "\n")
raise ValueError(emsg)
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))
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=self.opts['sock_dir'])
sockdirpath=sockdirpath)
stack.Pk = raeting.packKinds.pack
router_yard = RemoteYard(
manor_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'),
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)

View File

@ -6,3 +6,11 @@ Minion enabling different transports
'''
from collections import namedtuple, OrderedDict
# Python equivalent of an enum
APPL_KINDS = OrderedDict([('master', 0), ('minion', 1), ('syndic', 2), ('call', 3)])
APPL_KIND_NAMES = OrderedDict((v, k) for k, v in APPL_KINDS.iteritems()) # inverse map
ApplKind = namedtuple('ApplKind', APPL_KINDS.keys())
applKinds = ApplKind(**APPL_KINDS)

View File

@ -25,6 +25,7 @@ from raet.road.estating import RemoteEstate
from raet.lane.stacking import LaneStack
from raet.lane.yarding import RemoteYard
from salt import daemons
from salt.daemons import salting
from salt.exceptions import (
@ -131,14 +132,22 @@ class SaltRaetRoadStackSetup(ioflo.base.deeding.Deed):
do salt raet road stack setup at enter
'''
role = self.opts.value.get('id', self.local.data.role)
kind = self.opts.value['__role'] # application kind
if kind not in daemons.APPL_KINDS:
emsg = ("Invalid application kind = '{0}'.".format(kind))
log.error(emsg + '\n')
raise ValueError(emsg)
role = self.opts.value.get('id', '')
if not role:
emsg = ("Missing role required to setup RoadStack.")
log.error(emsg + "\n")
raise ValueError(emsg)
name = "{0}_{1}".format(role, kind)
sigkey = self.local.data.sigkey
prikey = self.local.data.prikey
#name = self.opts.value.get('id', self.local.data.name)
#name = LocalEstate.nameGuid(prefix='road') # name is guid
#name = 'stack_' + role
name = role
main = self.opts.value.get('raet_main', self.local.data.main)
mutable = self.opts.value.get('raet_mutable', self.local.data.mutable)
always = self.opts.value.get('open_mode', False)
@ -586,13 +595,27 @@ class SaltRaetManorLaneSetup(ioflo.base.deeding.Deed):
'''
Run once at enter
'''
name = 'manor'
kind = self.opts.value['__role']
if kind not in daemons.APPL_KINDS:
emsg = ("Invalid application kind = '{0}' for manor lane.".format(kind))
log.error(emsg + "\n")
raise ValueError(emsg)
if kind == 'master':
lanename = 'master'
elif kind == 'minion':
role = self.opts.value.get('id', '')
if not role:
emsg = ("Missing role required to setup manor Lane.")
log.error(emsg + "\n")
raise ValueError(emsg)
lanename = "{0}_{1}".format(role, kind)
else:
lanename = self.opts.value.get('id', self.local.data.lanename)
emsg = ("Unsupported application kind = '{0}' for manor Lane.".format(kind))
log.error(emsg + '\n')
raise ValueError(emsg)
name = 'manor'
self.stack.value = LaneStack(
name=name,
lanename=lanename,
@ -1001,20 +1024,38 @@ class SaltRaetNixJobber(ioflo.base.deeding.Deed):
to communicate with the minion manor yard
'''
mid = self.opts['id']
uid = nacling.uuid(size=18)
name = 'jobber' + uid
role = self.opts.get('id', '')
if not role:
emsg = ("Missing role required to setup Jobber Lane.")
log.error(emsg + "\n")
raise ValueError(emsg)
kind = self.opts['__role']
if kind not in daemons.APPL_KINDS:
emsg = ("Invalid application kind = '{0}' for Jobber lane.".format(kind))
log.error(emsg + "\n")
raise ValueError(emsg)
if kind == 'minion':
lanename = "{0}_{1}".format(role, kind)
else:
emsg = ("Unsupported application kind = '{0}' for Jobber Lane.".format(kind))
log.error(emsg + '\n')
raise ValueError(emsg)
sockdirpath = self.opts['sock_dir']
name = 'jobber' + nacling.uuid(size=18)
stack = LaneStack(
name=name,
lanename=mid,
sockdirpath=self.opts['sock_dir'])
lanename=lanename,
sockdirpath=sockdirpath)
stack.Pk = raeting.packKinds.pack
# add remote for the manor yard
stack.addRemote(RemoteYard(stack=stack,
name='manor',
lanename=mid,
dirpath=self.opts['sock_dir']))
lanename=lanename,
dirpath=sockdirpath))
console.concise("Created Jobber Stack {0}\n".format(stack.name))
return stack

View File

@ -19,7 +19,7 @@ framer minionudpstack be active first setup
bid start bootstrap
bid start eventing
bid start functionmanager
bid start manager
#bid start manager #started below in bootstrap<<router>
bid start outbound
bid start scheduler
@ -73,7 +73,7 @@ framer bootstrap be inactive first join
go router
frame router
bid start manager #start alive presence from minion side
#bid start manager #start alive presence from minion side
do salt raet router
go pillar if .salt.var.pillar_refresh
go loading if .salt.var.module_refresh

View File

@ -16,6 +16,7 @@ from raet import raeting
from raet.lane.stacking import LaneStack
from raet.lane.yarding import RemoteYard
from salt import daemons
# Import ioflo libs
import ioflo.base.deeding
@ -115,23 +116,27 @@ class SaltRaetWorkerSetup(ioflo.base.deeding.Deed):
name = "worker{0}".format(self.windex.value)
# master application kind
kind = self.opts.value['__role']
if kind not in daemons.APPL_KINDS:
emsg = ("Invalid application kind = '{0}' for Master Worker.".format(kind))
log.error(emsg + "\n")
raise ValueError(emsg)
if kind == 'master':
lanename = 'master' #self.local.data.lanename
lanename = 'master'
else: # workers currently are only supported for masters
emsg = ("Invalid application kind '{0}' for worker.".format(kind))
emsg = ("Invalid application kind '{0}' for Master Worker.".format(kind))
log.error(emsg + '\n')
raise ValueError(emsg)
sockdirpath=self.opts.value['sock_dir']
self.stack.value = LaneStack(
name=name,
lanename=lanename,
sockdirpath=self.opts.value['sock_dir'])
sockdirpath=sockdirpath)
self.stack.value.Pk = raeting.packKinds.pack
manor_yard = RemoteYard(
stack=self.stack.value,
name='manor',
lanename=lanename,
dirpath=self.opts.value['sock_dir'])
dirpath=sockdirpath)
self.stack.value.addRemote(manor_yard)
self.remote_loader.value = salt.daemons.masterapi.RemoteFuncs(
self.opts.value)
@ -161,7 +166,6 @@ class SaltRaetWorkerRouter(ioflo.base.deeding.Deed):
'lane_stack': '.salt.lane.manor.stack',
'road_stack': '.salt.road.manor.stack',
'opts': '.salt.opts',
#'windex': '.salt.var.fork.worker.windex',
'worker_verify': '.salt.var.worker_verify',
'remote_loader': '.salt.loader.remote',
'local_loader': '.salt.loader.local',

View File

@ -8,7 +8,6 @@ salting.py module of salt specific interfaces to raet
# Import Python libs
import os
from collections import namedtuple, OrderedDict
# Import ioflo libs
from ioflo.base.odicting import odict
@ -21,13 +20,6 @@ from raet.keeping import Keep
from salt.key import RaetKey
# Python equivalent of an enum
APPL_KINDS = OrderedDict([('master', 0), ('minion', 1), ('syndic', 2), ('call', 3)])
APPL_KIND_NAMES = odict((v, k) for k, v in APPL_KINDS.iteritems()) # inverse map
ApplKind = namedtuple('ApplKind', APPL_KINDS.keys())
applKinds = ApplKind(**APPL_KINDS)
class SaltKeep(Keep):
'''
RAET protocol estate on road data persistence for a given estate

View File

@ -13,6 +13,8 @@ import salt.utils
import logging
from collections import defaultdict
from salt import daemons
log = logging.getLogger(__name__)
try:
@ -78,7 +80,7 @@ class RAETChannel(Channel):
self.dst = (None, None, 'local_cmd') # runner.py master_call
elif usage == 'salt_call':
self.dst = (None, None, 'remote_cmd') # salt_call caller
else: # everything else
else: # everything else minion
self.dst = (None, None, 'remote_cmd') # normal use case minion to master
self.stack = None
@ -88,29 +90,27 @@ class RAETChannel(Channel):
not already setup such as in salt-call to communicate to-from the minion
'''
kind = self.opts.get('__role', '') # application kind 'master', 'minion', etc
if not kind:
emsg = ("Missing opts['__role']. required to setup RAETChannel.")
role = self.opts.get('id')
if not role:
emsg = ("Missing role required to setup RAETChannel.")
log.error(emsg + "\n")
raise ValueError(emsg)
kind = self.opts.get('__role') # application kind 'master', 'minion', etc
if kind not in daemons.APPL_KINDS:
emsg = ("Invalid application kind = '{0}' for RAETChannel.".format(kind))
log.error(emsg + "\n")
raise ValueError(emsg)
if kind == 'master':
lanename = 'master'
elif kind == 'minion':
role = self.opts.get('id', '')
if not role:
emsg = ("Missing opts['id']. required to setup RAETChannel.")
log.error(emsg + "\n")
raise ValueError(emsg)
lanename = role # add kind later
lanename = "{0}_{1}".format(role, kind)
else:
emsg = ("Unsupported application kind '{0}' for RAETChannel "
"Raet.".format(self.node))
emsg = ("Unsupported application kind '{0}' for RAETChannel.".format(kind))
log.error(emsg + '\n')
raise ValueError(emsg)
mid = self.opts.get('id', 'master')
uid = nacling.uuid(size=18)
name = 'channel' + uid
name = 'channel' + nacling.uuid(size=18)
stack = LaneStack(name=name,
lanename=lanename,
sockdirpath=self.opts['sock_dir'])

View File

@ -21,6 +21,8 @@ from raet import raeting, nacling
from raet.lane.stacking import LaneStack
from raet.lane.yarding import RemoteYard
from salt import daemons
log = logging.getLogger(__name__)
@ -41,32 +43,33 @@ class SaltEvent(object):
self.__prep_stack()
def __prep_stack(self):
kind = self.opts.get('__role', '') # opts optional for master
if kind: # not all uses of Raet SaltEvent has opts defined
if kind not in daemons.APPL_KINDS:
emsg = ("Invalid application kind = '{0}' for RAET SaltEvent.".format(kind))
log.error(emsg + "\n")
raise ValueError(emsg)
if kind != self.node:
emsg = ("Mismatch between node = '{0}' and kind = '{1}' in "
"RAET SaltEvent.".format(self.node, kind))
log.error(emsg + '\n')
raise ValueError(emsg)
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))
emsg = ("Missing role required to setup RAET SaltEvent.")
log.error(emsg + "\n")
raise ValueError(emsg)
if not kind:
emsg = "Missing kind required to setup RAET SaltEvent."
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'
lanename = "{0}_{1}".format(role, kind)
else:
emsg = ("Unsupported application node kind '{0}' for SaltEvent "
"Raet.".format(self.node))
emsg = ("Unsupported application node kind '{0}' for RAET SaltEvent.".format(self.node))
log.error(emsg + '\n')
raise ValueError(emsg)