from beach.beach_api import Beach import logging REPO_ROOT = os.path.join( os.path.dirname( os.path.abspath( __file__ ) ), '..', '..' ) if os.geteuid() != 0: print( 'Not currently running as root. If you meant to run this as part of the Cloud-in-a-Can you should run this with sudo.' ) if 1 < len( sys.argv ): BEACH_CONFIG_FILE = os.path.abspath( sys.argv[ 1 ] ) else: BEACH_CONFIG_FILE = os.path.join( os.path.dirname( os.path.abspath( __file__ ) ), 'sample_cluster.yaml' ) beach = Beach( BEACH_CONFIG_FILE, realm = 'hcp' ) if not beach.flush(): print( "Could not flush Beach cluster. Are you sure it is running?" ) sys.exit(-1) ####################################### # BeaconProcessor # This actor will process incoming # beacons from the sensors. # Parameters: # state_db: these are the connection # details for the mysql database # used to store the low-importance # data tracked at runtime. # deployment_key: The deployment key # to enforce if needed, it helps # to filter out sensors beaconing
class BeachShell ( cmd.Cmd ): intro = 'Welcome to Beach shell. Type help or ? to list commands.\n' prompt = '(beach) ' def __init__( self, configFile, realm = None ): cmd.Cmd.__init__( self ) self.realm = 'global' self.updatePrompt() self.beach = Beach( configFile ) def updatePrompt( self ): if self.realm is not None: self.prompt = '(beach/%s) ' % self.realm else: self.prompt = '(beach/global) ' def parse( self, parser, line ): try: return parser.parse_args( shlex.split( line ) ) except SystemExit: return None def do_exit( self, s ): self.beach.close() return True def do_quit( self, s ): self.beach.close() return True def emptyline( self ): pass def printOut( self, data ): print( json.dumps( data, indent = 4 ) ) @report_errors def do_gen_key( self, s ): '''Generate a key that can be used as a beach private key.''' parser = argparse.ArgumentParser( prog = inspect.stack()[0][3][ 3 : ] ) parser.add_argument( 'out', type = str, help = 'the path where to store the key.' ) arguments = self.parse( parser, s ) if arguments is None: return with open( arguments.out, 'w' ) as f: f.write( M2Crypto.Rand.rand_bytes( 0x20 ) ) self.printOut( 'New private key written to %s.' % arguments.out ) @report_errors def do_realm( self, s ): '''Login as a specific user.''' parser = argparse.ArgumentParser( prog = inspect.stack()[0][3][ 3 : ] ) parser.add_argument( 'realm', type = str, default = 'global', help = 'switch context to a specific realm.' ) arguments = self.parse( parser, s ) if arguments is None: return self.realm = arguments.realm if self.realm is None or self.realm.strip() == '': self.ream = 'global' self.updatePrompt() self.beach.setRealm( self.realm ) @report_errors def do_get_dir( self, s ): '''Retrieve the directory of all Actors.''' parser = argparse.ArgumentParser( prog = inspect.stack()[0][3][ 3 : ] ) parser.add_argument( '-c', '--category', type = str, dest = 'category', default = None, help = 'only show the directory for a specific category.' ) arguments = self.parse( parser, s ) if arguments is None: return category = arguments.category resp = self.beach.getDirectory() wanted = False if resp is not False and 'realms' in resp: wanted = resp[ 'realms' ].get( self.realm, {} ) if category is not None: wanted = wanted.get( category, {} ) self.printOut( wanted ) @report_errors def do_flush( self, s ): '''Remove all Actors from all nodes in the cluster.''' parser = argparse.ArgumentParser( prog = inspect.stack()[0][3][ 3 : ] ) parser.add_argument( '--confirm', action = 'store_true', help = 'This command flushes ALL ACTORS from the cluster REGARDLESS of the realm. ' 'Add this flag to confirm you understand this.' ) arguments = self.parse( parser, s ) if arguments is None: return resp = 'Please confirm ( see command help )' if arguments.confirm: resp = self.beach.flush() self.printOut( resp ) @report_errors def do_add_actor( self, s ): '''Add a new Actor to the cluster.''' parser = argparse.ArgumentParser( prog = inspect.stack()[0][3][ 3 : ] ) parser.add_argument( '-n', '--name', type = str, dest = 'name', required = True, help = 'the name of the actor to spawn.' ) parser.add_argument( '-c', '--category', type = str, dest = 'category', required = True, nargs = '+', help = 'category or categories to add the Actor to.' ) parser.add_argument( '-s', '--strategy', type = str, dest = 'strategy', default = None, help = 'the strategy to use to spawn the actor in the beach.' ) parser.add_argument( '-sh', '--hint', type = str, dest = 'strat_hint', default = None, help = 'hint used as part of some strategies.' ) parser.add_argument( '-p', '--params', type = json.loads, dest = 'params', default = None, help = 'parameters to provide to the Actor, as a JSON string.' ) parser.add_argument( '-i', '--isisolated', dest = 'isIsolated', default = False, action = 'store_true', help = 'if the Actor should be started in isolation mode (standalone process).' ) parser.add_argument( '-id', '--ident', type = str, dest = 'ident', default = None, help = 'identifier secret token used for Actor trust model.' ) parser.add_argument( '-t', '--trusted', type = str, dest = 'trusted', default = [], action = 'append', help = 'identifier token trusted by the Actor trust model.' ) parser.add_argument( '-ll', '--log-level', type = str, dest = 'loglevel', default = None, help = 'custom logging level for actor.' ) parser.add_argument( '-ld', '--log-dest', type = str, dest = 'logdest', default = None, help = 'custom logging destination for actor.' ) parser.add_argument( '-o', '--concurrent', type = int, dest = 'n_concurrent', required = False, default = 1, help = 'the number of concurrent requests handled by the actor.' ) arguments = self.parse( parser, s ) if arguments is None: return resp = self.beach.addActor( arguments.name, arguments.category, strategy = arguments.strategy, strategy_hint = arguments.strat_hint, parameters = arguments.params, isIsolated = arguments.isIsolated, secretIdent = arguments.ident, trustedIdents = arguments.trusted, n_concurrent = arguments.n_concurrent, log_level = arguments.log_level, log_dest = arguments.log_dest ) self.printOut( resp ) @report_errors def do_stop_actor( self, s ): '''Stop a specific set of actors.''' parser = argparse.ArgumentParser( prog = inspect.stack()[0][3][ 3 : ] ) parser.add_argument( '-i', '--id', type = str, dest = 'id', required = False, nargs = '+', help = 'the IDs of actors to stop.' ) parser.add_argument( '-c', '--category', type = str, dest = 'cat', required = False, nargs = '+', help = 'the categories of actors to stop.' ) arguments = self.parse( parser, s ) if arguments is None: return if arguments.id is None and arguments.cat is None: argparse.error( 'Must specify one of -i or -c.' ) resp = self.beach.stopActors( withId = arguments.id, withCategory = arguments.cat ) self.printOut( resp ) @report_errors def do_get_cluster_health( self, s ): '''Retrieve the health information of all nodes of the cluster.''' parser = argparse.ArgumentParser( prog = inspect.stack()[0][3][ 3 : ] ) arguments = self.parse( parser, s ) if arguments is None: return resp = self.beach.getClusterHealth() self.printOut( resp ) @report_errors def do_get_load_info( self, s ): '''Retrieve the number of free handlers per actor.''' parser = argparse.ArgumentParser( prog = inspect.stack()[0][3][ 3 : ] ) arguments = self.parse( parser, s ) if arguments is None: return resp = self.beach.getLoadInfo() self.printOut( resp ) @report_errors def do_get_mtd( self, s ): '''Retrieve metadata from all nodes.''' parser = argparse.ArgumentParser( prog = inspect.stack()[0][3][ 3 : ] ) resp = self.beach.getAllNodeMetadata() self.printOut( resp ) @report_errors def do_remove_from_category( self, s ): '''Remove an Actor from a category.''' parser = argparse.ArgumentParser( prog = inspect.stack()[0][3][ 3 : ] ) parser.add_argument( '-i', '--id', type = str, dest = 'id', required = True, help = 'the ID of the actor to add to the category.' ) parser.add_argument( '-c', '--category', type = str, dest = 'category', required = True, help = 'category to add the actor to.' ) arguments = self.parse( parser, s ) if arguments is None: return resp = self.beach.removeFromCategory( arguments.id, arguments.category ) self.printOut( resp ) @report_errors def do_add_to_category( self, s ): '''Add an Actor to a category.''' parser = argparse.ArgumentParser( prog = inspect.stack()[0][3][ 3 : ] ) parser.add_argument( '-i', '--id', type = str, dest = 'id', required = True, help = 'the ID of the actor to add to the category.' ) parser.add_argument( '-c', '--category', type = str, dest = 'category', required = True, help = 'category to add the actor to.' ) arguments = self.parse( parser, s ) if arguments is None: return resp = self.beach.addToCategory( arguments.id, arguments.category ) self.printOut( resp )
class BeachShell(cmd.Cmd): intro = "Welcome to Beach shell. Type help or ? to list commands.\n" prompt = "(beach) " def __init__(self, configFile): cmd.Cmd.__init__(self) self.realm = "global" self.updatePrompt() self.beach = Beach(configFile) def updatePrompt(self): if self.realm is not None: self.prompt = "(beach/%s) " % self.realm else: self.prompt = "(beach/global) " def parse(self, parser, line): try: return parser.parse_args(shlex.split(line)) except SystemExit: return None def do_exit(self, s): self.beach.close() return True def do_quit(self, s): self.beach.close() return True def emptyline(self): pass def printOut(self, data): print(json.dumps(data, indent=4)) @report_errors def do_realm(self, s): """Login as a specific user.""" parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument("realm", type=str, default="global", help="switch context to a specific realm.") arguments = self.parse(parser, s) if arguments is None: return self.realm = arguments.realm if self.realm is None or self.realm.strip() == "": self.ream = "global" self.updatePrompt() self.beach.setRealm(self.realm) @report_errors def do_get_dir(self, s): """Retrieve a specific user's profile by UID.""" parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument( "-c", "--category", type=str, dest="category", default=None, help="only show the directory for a specific category.", ) arguments = self.parse(parser, s) if arguments is None: return category = arguments.category resp = self.beach.getDirectory() wanted = False if isMessageSuccess(resp) and "realms" in resp: wanted = resp["realms"].get(self.realm, {}) if category is not None: wanted = wanted.get(category, {}) self.printOut(wanted) @report_errors def do_flush(self, s): """Retrieve a specific user's profile by UID.""" parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument( "--confirm", action="store_true", help="This command flushes ALL ACTORS from the cluster REGARDLESS of the realm. " "Add this flag to confirm you understand this.", ) arguments = self.parse(parser, s) if arguments is None: return resp = "Please confirm ( see command help )" if arguments.confirm: resp = self.beach.flush() self.printOut(resp) @report_errors def do_add_actor(self, s): """Retrieve a specific user's profile by UID.""" parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument( "-n", "--name", type=str, dest="name", required=True, help="the name of the actor to spawn." ) parser.add_argument( "-c", "--category", type=str, dest="category", required=True, help="only show the directory for a specific category.", ) parser.add_argument( "-s", "--strategy", type=str, dest="strategy", default=None, help="the strategy to use to spawn the actor in the beach.", ) parser.add_argument( "-sh", "--hint", type=str, dest="strat_hint", default=None, help="hint used as part of some strategies." ) arguments = self.parse(parser, s) if arguments is None: return resp = self.beach.addActor(arguments.name, arguments.category, arguments.strategy, arguments.strat_hint) self.printOut(resp) @report_errors def do_stop_actor(self, s): """Stop a specific set of actors.""" parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument( "-i", "--id", type=str, dest="id", required=False, nargs="+", help="the IDs of actors to stop." ) parser.add_argument( "-c", "--category", type=str, dest="cat", required=False, nargs="+", help="the categories of actors to stop.", ) arguments = self.parse(parser, s) if arguments is None: return if arguments.id is None and arguments.cat is None: argparse.error("Must specify one of -i or -c.") resp = self.beach.stopActors(withId=arguments.id, withCategory=arguments.cat) self.printOut(resp) @report_errors def do_get_cluster_health(self, s): """Retrieve the health information of all nodes of the cluster.""" parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) arguments = self.parse(parser, s) if arguments is None: return resp = self.beach.getClusterHealth() self.printOut(resp)
print( "Creating ping actor in resource beach node." ) a1 = beach.addActor( 'Ping', 'pingers', strategy = 'resource' ) print( json.dumps( a1, indent = 4 ) ) print( "Creating pong actor in affinity( pingers ) beach node." ) a2 = beach.addActor( 'Pong', 'pongers', strategy = 'affinity', strategy_hint = 'pingers' ) print( json.dumps( a2, indent = 4 ) ) print( "Creating pong actor in isolation." ) a3 = beach.addActor( 'Pong', 'pongers', isIsolated = True ) print( json.dumps( a3, indent = 4 ) ) print( "Idling for a few seconds..." ) time.sleep( 15 ) print( "Querying for beach directory." ) d = beach.getDirectory() print( json.dumps( d, indent = 4 ) ) print( "Trying some queries to the cluster." ) vHandle = beach.getActorHandle( 'pongers' ) print( "Issuing ping" ) resp = vHandle.request( 'ping', data = { 'source' : 'outside' }, timeout = 10 ) print( "Received: %s" % str( resp ) ) time.sleep( 2 ) print( "Flushing beach." ) f = beach.flush() print( json.dumps( f, indent = 4 ) ) beach.close()
class BeachShell(cmd.Cmd): intro = 'Welcome to Beach shell. Type help or ? to list commands.\n' prompt = '(beach) ' def __init__(self, configFile, realm=None): cmd.Cmd.__init__(self) self.realm = 'global' self.updatePrompt() self.beach = Beach(configFile) def updatePrompt(self): if self.realm is not None: self.prompt = '(beach/%s) ' % self.realm else: self.prompt = '(beach/global) ' def parse(self, parser, line): try: return parser.parse_args(shlex.split(line)) except SystemExit: return None def do_exit(self, s): self.beach.close() return True def do_quit(self, s): self.beach.close() return True def emptyline(self): pass def printOut(self, data): print(json.dumps(data, indent=4)) @report_errors def do_gen_key(self, s): '''Generate a key that can be used as a beach private key.''' parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument('out', type=str, help='the path where to store the key.') arguments = self.parse(parser, s) if arguments is None: return with open(arguments.out, 'w') as f: f.write(M2Crypto.Rand.rand_bytes(0x20)) self.printOut('New private key written to %s.' % arguments.out) @report_errors def do_realm(self, s): '''Login as a specific user.''' parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument('realm', type=str, default='global', help='switch context to a specific realm.') arguments = self.parse(parser, s) if arguments is None: return self.realm = arguments.realm if self.realm is None or self.realm.strip() == '': self.ream = 'global' self.updatePrompt() self.beach.setRealm(self.realm) @report_errors def do_get_dir(self, s): '''Retrieve the directory of all Actors.''' parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument( '-c', '--category', type=str, dest='category', default=None, help='only show the directory for a specific category.') arguments = self.parse(parser, s) if arguments is None: return category = arguments.category resp = self.beach.getDirectory() wanted = False if resp is not False and 'realms' in resp: wanted = resp['realms'].get(self.realm, {}) if category is not None: wanted = wanted.get(category, {}) self.printOut(wanted) @report_errors def do_flush(self, s): '''Remove all Actors from all nodes in the cluster.''' parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument( '--confirm', action='store_true', help= 'This command flushes ALL ACTORS from the cluster REGARDLESS of the realm. ' 'Add this flag to confirm you understand this.') arguments = self.parse(parser, s) if arguments is None: return resp = 'Please confirm ( see command help )' if arguments.confirm: resp = self.beach.flush() self.printOut(resp) @report_errors def do_add_actor(self, s): '''Add a new Actor to the cluster.''' parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument('-n', '--name', type=str, dest='name', required=True, help='the name of the actor to spawn.') parser.add_argument('-c', '--category', type=str, dest='category', required=True, nargs='+', help='category or categories to add the Actor to.') parser.add_argument( '-s', '--strategy', type=str, dest='strategy', default=None, help='the strategy to use to spawn the actor in the beach.') parser.add_argument('-sh', '--hint', type=str, dest='strat_hint', default=None, help='hint used as part of some strategies.') parser.add_argument( '-p', '--params', type=json.loads, dest='params', default=None, help='parameters to provide to the Actor, as a JSON string.') parser.add_argument( '-i', '--isisolated', dest='isIsolated', default=False, action='store_true', help= 'if the Actor should be started in isolation mode (standalone process).' ) parser.add_argument( '-id', '--ident', type=str, dest='ident', default=None, help='identifier secret token used for Actor trust model.') parser.add_argument( '-t', '--trusted', type=str, dest='trusted', default=[], action='append', help='identifier token trusted by the Actor trust model.') parser.add_argument('-ll', '--log-level', type=str, dest='loglevel', default=None, help='custom logging level for actor.') parser.add_argument('-ld', '--log-dest', type=str, dest='logdest', default=None, help='custom logging destination for actor.') parser.add_argument( '-o', '--concurrent', type=int, dest='n_concurrent', required=False, default=1, help='the number of concurrent requests handled by the actor.') parser.add_argument( '-d', '--isdrainable', dest='isDrainable', default=False, action='store_true', help='if the Actor can be requested to drain gracefully.') arguments = self.parse(parser, s) if arguments is None: return resp = self.beach.addActor(arguments.name, arguments.category, strategy=arguments.strategy, strategy_hint=arguments.strat_hint, parameters=arguments.params, isIsolated=arguments.isIsolated, secretIdent=arguments.ident, trustedIdents=arguments.trusted, n_concurrent=arguments.n_concurrent, is_drainable=arguments.isDrainable, log_level=arguments.log_level, log_dest=arguments.log_dest) self.printOut(resp) @report_errors def do_stop_actor(self, s): '''Stop a specific set of actors.''' parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument('-i', '--id', type=str, dest='id', required=False, nargs='+', help='the IDs of actors to stop.') parser.add_argument('-c', '--category', type=str, dest='cat', required=False, nargs='+', help='the categories of actors to stop.') parser.add_argument( '-d', '--delay', type=int, dest='delay', required=False, default=None, help='the number of seconds between stopping each actor.') arguments = self.parse(parser, s) if arguments is None: return if arguments.id is None and arguments.cat is None: argparse.error('Must specify one of -i or -c.') resp = self.beach.stopActors(withId=arguments.id, withCategory=arguments.cat, delay=arguments.delay) self.printOut(resp) @report_errors def do_get_cluster_health(self, s): '''Retrieve the health information of all nodes of the cluster.''' parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) arguments = self.parse(parser, s) if arguments is None: return resp = self.beach.getClusterHealth() self.printOut(resp) @report_errors def do_get_load_info(self, s): '''Retrieve the number of free handlers per actor.''' parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) arguments = self.parse(parser, s) if arguments is None: return resp = self.beach.getLoadInfo() self.printOut(resp) @report_errors def do_get_mtd(self, s): '''Retrieve metadata from all nodes.''' parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) resp = self.beach.getAllNodeMetadata() self.printOut(resp) @report_errors def do_remove_from_category(self, s): '''Remove an Actor from a category.''' parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument('-i', '--id', type=str, dest='id', required=True, help='the ID of the actor to add to the category.') parser.add_argument('-c', '--category', type=str, dest='category', required=True, help='category to add the actor to.') arguments = self.parse(parser, s) if arguments is None: return resp = self.beach.removeFromCategory(arguments.id, arguments.category) self.printOut(resp) @report_errors def do_add_to_category(self, s): '''Add an Actor to a category.''' parser = argparse.ArgumentParser(prog=inspect.stack()[0][3][3:]) parser.add_argument('-i', '--id', type=str, dest='id', required=True, help='the ID of the actor to add to the category.') parser.add_argument('-c', '--category', type=str, dest='category', required=True, help='category to add the actor to.') arguments = self.parse(parser, s) if arguments is None: return resp = self.beach.addToCategory(arguments.id, arguments.category) self.printOut(resp)
print("Creating pong actor in affinity( pingers ) beach node.") a2 = beach.addActor('Pong', 'pongers', strategy='affinity', strategy_hint='pingers') print(json.dumps(a2, indent=4)) print("Creating pong actor in isolation.") a3 = beach.addActor('Pong', 'pongers', isIsolated=True) print(json.dumps(a3, indent=4)) print("Idling for a few seconds...") time.sleep(15) print("Querying for beach directory.") d = beach.getDirectory() print(json.dumps(d, indent=4)) print("Trying some queries to the cluster.") vHandle = beach.getActorHandle('pongers') print("Issuing ping") resp = vHandle.request('ping', data={'source': 'outside'}, timeout=10) print("Received: %s" % str(resp)) time.sleep(2) print("Flushing beach.") f = beach.flush() print(json.dumps(f, indent=4)) beach.close()
from beach.beach_api import Beach import logging REPO_ROOT = os.path.join( os.path.dirname( os.path.abspath( __file__ ) ), '..', '..' ) if os.geteuid() != 0: print( 'Not currently running as root. If you meant to run this as part of the Cloud-in-a-Can you should run this with sudo.' ) if 1 < len( sys.argv ): BEACH_CONFIG_FILE = os.path.abspath( sys.argv[ 1 ] ) else: BEACH_CONFIG_FILE = os.path.join( os.path.dirname( os.path.abspath( __file__ ) ), 'sample_cluster.yaml' ) beach = Beach( BEACH_CONFIG_FILE, realm = 'hcp' ) if not beach.flush(): print( "Could not flush Beach cluster. Are you sure it is running?" ) sys.exit(-1) ####################################### # BeaconProcessor # This actor will process incoming # beacons from the sensors. # Parameters: # state_db: these are the connection # details for the mysql database # used to store the low-importance # data tracked at runtime. # _priv_key: the C2 private key. # task_back_timeout: the number of # seconds to wait during each