Changeset 2f45140 for starbed_plugin


Ignore:
Timestamp:
Aug 27, 2012 3:02:51 AM (12 years ago)
Author:
ABDULLA ALWABEL <abdullaalwabel@…>
Branches:
master
Children:
b9ec635
Parents:
9d40cc9
Message:

Handeling ssh key properly and portal connection

Location:
starbed_plugin
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • starbed_plugin/starbed.py

    r9d40cc9 r2f45140  
    1 #!/usr/local/bin/python
     1#!/usr/bin/python
    22
    33import os,sys
     4#temp
     5import traceback
     6#
     7import shutil
    48import subprocess
    59import signal
     
    2125from federation.proof import proof
    2226from topdltok import klanguage
    23 
     27from peer_setup import Peer
    2428# Make log messages disappear if noone configures a fedd logger.  This is
    2529# something of an incantation, but basically it creates a logger object
     
    6165        access_base.__init__(self, config, auth)
    6266
     67        self.ssh_port = config.get("access","ssh_port") or "22"
     68        self.domain = config.get('globals','domain')
    6369        #Available ports for kuma!
    6470        ports = config.get('globals','freeports')
    65         self.domain = config.get('globals','domain')
    6671        try:
    6772                if not ports or ports.count('-') != 1:
     
    8388                self.available_ports = set(range(3456,3458))
    8489                self.log.warning("Setting default freeports due to missing or malformed configuration. %s" % (e))
     90        #Available internal and external interfaces for the commander!
     91        internal_iface = config.get('globals','internal_interfaces')
     92        external_iface = config.get('globals','external_interfaces')
     93        if internal_iface:
     94                try:
     95                        self.iiface = internal_iface.split(',')
     96                except BaseException as e:
     97                        self.log.warning('Could not retrieve internal interfaces')
     98        else:
     99                self.log.warning("No internal interfaces specificed in the configration!")
     100        if external_iface:
     101                try:
     102                        self.eiface = external_iface.split(',')
     103                except BaseException as e:
     104                        selflog.warning('Could not retrive external interfaces')
     105        else:
     106                self.log.warning("No external interfaces specificed in the configration!")
     107
    85108        #Get reserved ports saved in state and remove them from the available set!
    86109        self.state_lock.acquire()
     
    92115                elif 'ESQP' in self.state[k]:
    93116                        self.available_ports.discard(self.state[k]['ESQP'])
     117                #Get reserved interfaces in state and remove them from the available set!
     118                elif 'iiface' in self.state[k]:
     119                        self.iiface.remove(self.state[k]['iiface'] )
     120                elif 'eiface' in self.state[k]:
     121                        self.eiface.remove(self.state[k]['eiface'] )
    94122        self.state_lock.release()
    95123       
     
    135163            'TerminateSegment': soap_handler("TerminateSegment",
    136164                self.TerminateSegment),
     165            'InfoSegment': soap_handler("InfoSegment", self.InfoSegment),
     166            'OperationSegment': soap_handler("OperationSegment",
     167                self.OperationSegment),
     168
    137169            }
    138170        self.xmlrpc_services =  {\
     
    144176            'TerminateSegment': xmlrpc_handler('TerminateSegment',
    145177                self.TerminateSegment),
     178            'InfoSegment': xmlrpc_handler("InfoSegment", self.InfoSegment),
     179            'OperationSegment': xmlrpc_handler("OperationSegment",
     180                self.OperationSegment),
    146181            }
     182
     183        self.call_SetValue = service_caller('SetValue', log=self.log)
     184        self.call_GetValue = service_caller('GetValue', log=self.log)
     185
    147186        self.log.debug("Starbed AC started!")
    148187    def RequestAccess(self, req, fid):
     
    230269                self.state_lock.release()
    231270                raise service_error(service_error.req, "No such allocation")
    232 
     271    def exportInfo(self,certfile,connInfo,peer_ip):
     272
     273        for c in connInfo:
     274                 for p in [ p for p in c.get('parameter', []) if p.get('type', '') == 'output']:
     275                        if p.get('name', '') == 'peer':
     276                                 k = p.get('key', None)
     277                                 surl = p.get('store', None)
     278                                 if surl :
     279                                        if k and k.index('/') != -1:
     280                                                value = peer_ip
     281                                                #value = "%s.%s.%s" % \
     282                                                #       (k[k.index('/')+1:], "tcarch02" , self.domain)
     283                                        else:
     284                                                self.log.error("Bad export request: %s" % p)
     285                                                continue
     286                                        self.log.debug("Setting %s to %s on %s" % \
     287                                                (k, value, surl))
     288                                        req = { 'name': k, 'value': value }
     289                                        self.call_SetValue(surl, req, certfile)
     290                                 else:
     291                                        self.log.error("Bad export request: %s" % p)
     292                        elif p.get('name', '') == 'ssh_port':
     293                                k = p.get('key', None)
     294                                surl = p.get('store', None)
     295                                if surl and k:
     296                                        req = { 'name': k, 'value': self.ssh_port }
     297                                        self.log.debug("Setting %s to %s on %s" % \
     298                                                (k, self.ssh_port, surl))
     299                                        self.call_SetValue(surl, req, certfile )
     300                                else:
     301                                        self.log.error("Bad export request: %s" % p)
     302                        else:
     303                                self.log.error("Unknown export parameter: %s" % \
     304                                        p.get('name'))
     305                                continue
     306    def fetchConfiguration(self,attrs,aid,certfile,tmpdir):
     307        configs = ('hosts', 'ssh_pubkey', 'ssh_secretkey')
     308        pubkey_base = None
     309        secretkey_base = None
     310       
     311        for a in attrs:
     312                if a['attribute'] in configs:
     313                        try:
     314                                self.log.debug("Retrieving %s from %s to %s" % (a['attribute'], a['value'],tmpdir))
     315                                get_url(a['value'], certfile, tmpdir, log=self.log)
     316                        except:
     317                                t, v, st = sys.exc_info()
     318                                raise service_error(service_error.internal,
     319                                        "Error retrieving %s: %s" % (a.get('value', ""), v))
     320                if a['attribute'] == 'ssh_pubkey':
     321                        pubkey_base = a['value'].rpartition('/')[2]
     322                if a['attribute'] == 'ssh_secretkey':
     323                        secretkey_base = a['value'].rpartition('/')[2]
     324        if not pubkey_base:
     325                raise service_error(service_error.req,
     326                        "No public key attribute")
     327        if not secretkey_base:
     328                raise service_error(service_error.req,
     329                        "No secret key attribute")
     330        return (pubkey_base,secretkey_base)
     331    def getPortalInfo(self,connInfo):
     332        peer = None
     333        conn_type = None
     334                               
    233335    def StartSegment(self, req, fid):
    234336        #self.log.debug("data = %s" %(req));
     
    236338        try:
    237339            req = req['StartSegmentRequestBody']
    238             self.log.debug(req)
    239340            # Get the request topology.  If not present, a KeyError is thrown.
    240341            topref = req['segmentdescription']['topdldescription']
     
    245346            raise service_error(server_error.req, "Badly formed request")
    246347
     348        connInfo = req.get('connection', [])
     349        attrs = req.get('fedAttr', [])
    247350        # String version of the allocation ID for keying
    248351        aid = "%s" % auth_attr
     
    306409        level, kname = tempfile.mkstemp()
    307410        k.to_file(kname)
    308         #proc = subprocess.Popen(['/usr/local/springos/bin/kuma', '-p',self.state[aid]['passwd'],kname,'-P',str(ENCD),'-Q',str(ESQP)])
    309         #pid = proc.pid
    310         pid = 100000
     411       
     412        pubkey_base = None
     413        secretkey_base = None
     414        tmpdir = None
     415        peer = None
     416
     417        if k.isPortal():
     418                self.log.debug("Setting up a portal!")
     419                try:   
     420                        #pick interface
     421                        self.state_lock.acquire()
     422                        if len(self.iiface) > 1:
     423                                IIFACE = random.choice([i for i in self.iiface] )
     424                                self.iiface.remove(IIFACE)
     425                                self.state[aid]['iiface'] = IIFACE
     426                                ip,substrate = k.getPortalInfo()
     427                                self.log.debug("IIFACE = %s, ip = %s" ,IIFACE,ip)
     428                                Peer.setIP(IIFACE,ip)
     429                                #set interface IP!
     430                                #bridge name always have the following convention interfacenamebr
     431                                Peer.setBridge("%sbr" % (IIFACE) )
     432                                Peer.addIfaceToBridge(IIFACE,"%sbr" % (IIFACE) )
     433
     434                        else:
     435                                raise BaseException("No available internal interfaces!")
     436                        if len(self.eiface) > 1:
     437                                EIFACE = random.choice([i for i in self.eiface] )
     438                                self.eiface.remove(EIFACE)
     439                                self.state[aid]['eiface'] = EIFACE
     440                                peer_ip = Peer.getIP(EIFACE)
     441                        else:
     442                                raise BaseException("No available external interfaces!")
     443                        self.state_lock.release()
     444                        tmpdir = tempfile.mkdtemp(prefix="access-")
     445                        pubkey_base, secretkey_base = self.fetchConfiguration(attrs,aid,certfile,tmpdir)
     446                        self.exportInfo(certfile,connInfo,peer_ip)
     447                        self.import_store_info(certfile, connInfo)
     448                        peer = connInfo[0].get('peer')
     449                        con_type = connInfo[0].get('type')
     450                        self.log.debug("peer = %s, type = %s, ", str(peer),con_type)
     451                except BaseException as e:
     452                        self.state_lock.release()
     453                        self.log.error("Problem reteriving peer information")
     454                        traceback.print_exc(file=sys.stdout)   
     455                        raise service_error(service_error.internal, "Cannot handel peer information!")
     456        proc = subprocess.Popen(['/usr/local/springos/bin/kuma', '-p',self.state[aid]['passwd'],kname,'-P',str(ENCD),'-Q',str(ESQP)])
     457        pid = proc.pid
     458        #pid = 100000
    311459        self.log.debug(['/usr/local/springos/bin/kuma', '-p',self.state[aid]['passwd'],kname,'-P',str(ENCD),'-Q',str(ESQP)])
    312460        #os.unlink(kname)
     
    319467        connInfo = req.get('connection', [])
    320468
     469        proce1 = None
     470        if k.isPortal():
     471                try:
     472                        proce1 = subprocess.Popen(['./peer_setup.py','-d',peer,'-k','%s/%s'% (tmpdir,pubkey_base),'-b',"%sbr" % (IIFACE),'-i', IIFACE])
     473                except:
     474                        self.log.warning("Could not start connection with peer!")
    321475        self.state_lock.acquire()
    322476        # It's possible that the StartSegment call gets retried (!).
     
    324478        # than redo the setup.  The integer allocation was saved when we made
    325479        # it.
     480        if pubkey_base:
     481                self.state[aid]['pubkey_base'] = pubkey_base
     482        if secretkey_base:
     483                self.state[aid]['secretkey_base'] = secretkey_base
     484        if tmpdir:
     485                self.state[aid]['tmpdir'] = tmpdir
     486        if peer:
     487                self.state[aid]['peer'] = peer
     488        if proce1:
     489                self.state[aid]['ssh_pid'] = proce1.pid
    326490        self.state[aid]['pid'] = pid
    327491        self.state[aid]['descfile'] = kname
     
    376540                except OSError as ex:
    377541                        self.log.warning("Cannot kill process %s " % (pid))
     542            if 'ssh_pid' in self.state[aid]:
     543                try:
     544                        os.kill(int(self.state[aid]['ssh_pid'] ) )
     545                        os.wait()
     546                except OSError as ex:
     547                        self.log.warning("Cannot kill process")
    378548            descfile = self.state[aid].get('descfile',None)
    379549            if descfile:
    380                 #os.unlink(descfile)
     550                os.unlink(descfile)
    381551                del self.state[aid]['descfile']
    382552            if 'ENCD' in self.state[aid]:
     
    385555                del self.state[aid]['ESQP']
    386556            del self.state[aid]['started']
     557
     558            if 'eiface' in self.state[aid]:
     559                del self.state[aid]['eiface']
     560            if 'iiface' in self.state[aid]:
     561                try:
     562                        Peer.delBridge("%sbr" % self.state[aid]['iiface'] )
     563                except:
     564                        self.log.warning("Problem removing bridge %sbr" % self.state[aid]['eiface'] )
     565                del self.state[aid]['iiface']
     566            if 'pubkey_base' in self.state[aid]:
     567                del self.state[aid]['pubkey_base']
     568            if 'secretkey_base' in self.state[aid]:
     569                del self.state[aid]['secretkey_base']
     570            if 'tmpdir' in self.state[aid]:
     571                try:   
     572                        shutil.rmtree(self.state[aid]['tmpdir'])
     573                except  OSError as e:
     574                        self.log.warning("Problem removing directory %s" % (self.state[aid]['tmpdir'] ))
     575                del self.state[aid]['tmpdir']
     576            if 'peer' in self.state[aid]:
     577                del self.state[aid]['peer']
    387578            self.write_state()
    388579        self.state_lock.release()
     
    392583        self.log.info("InfoSegment called by %s" % fid)
    393584
     585    def OperationSegment(self, req, fid):
     586        self.log.info("OperationSegment called by %s" % (fid) )
     587        self.log.debug("req = %s " % req )
  • starbed_plugin/topdltok.py

    r9d40cc9 r2f45140  
    4444                self.sparenoderatio = sparenoderatio
    4545                self.gut = ""
     46                #WE handle portal configuration manually since we do it in the commander!
     47                self.portal_iip = None
     48                self.portal_substrate = None
     49        def isPortal(self):
     50                if self.portal_iip and self.portal_substrate:
     51                        return True
     52                else:
     53                        return False
     54        def getPortalInfo(self):
     55                return (self.portal_iip,self.portal_substrate)
    4656        def to_file(self,name):
    4757                f = open(name, 'w+')
     
    99109                                nodedef = nodedef + "}\n"
    100110                                nodeinst = nodeinst + "nodeset %s class %sclass num 1\n" % (name,name)
    101 
     111                        elif isinstance(elt, topdl.Computer) and elt.get_attribute('portal') == 'true':
     112                                for iface in elt.interface:
     113                                        #We need a portal! we handle outside kuma!
     114                                        if not iface.get_attribute('portal'):
     115                                                self.portal_iip = str(iface.get_attribute('ip4_address'))
     116                                                self.portal_substrate = str(iface.substrate[0])
    102117                #This should be replaced to specificlly define each LAN when required!
    103118                lanclass = "ethernet"
Note: See TracChangeset for help on using the changeset viewer.