Beispiel #1
0
def get_registration_conf():
    """Attempts to get registration config information from the cloud.

    Returns:
      the config data

    Raises:
      RegistrationError if the request does not return 200
    """
    bts_uuid = _get_snowflake()
    params = {'bts_uuid': bts_uuid}
    try:
        return _send_cloud_req(requests.get,
                               '/bts/sslconf',
                               'get cert config',
                               params=params)
    except RegistrationServerError as ex:
        if ex.status_code == 403:
            msg = 'BTS already registered - manually generate new snowflake'
            # unrecoverable error - exit
            logger.critical(msg)
            raise SystemExit(msg)
        if ex.status_code == 404:
            logger.warning('*** ensure BTS UUID (%s) is registered' %
                           (bts_uuid, ))
        raise
Beispiel #2
0
def _get_snowflake():
    """ Read UUID from /etc/snowflake. If it doesn't exist, die. """
    bts_uuid = snowflake()
    if bts_uuid:
        return bts_uuid

    SNOWFLAKE_MISSING = '/etc/snowflake missing'
    logger.critical(SNOWFLAKE_MISSING)
    raise SystemExit(SNOWFLAKE_MISSING)
 def _reset_bts_config(self):
     logger.notice("Performing set_factory")
     try:
         if bts.set_factory_config():
             logger.notice("Restarting BTS")
             bts.restart()
             Service.SystemService("freeswitch").restart()
     except BSSError as e:
         logger.error("bts is probably down: %s" % e)
     except Exception as e:
         # OSError, IOError or whatever envoy will raise
         logger.critical("something unexpected happened: %s" % e)
Beispiel #4
0
def update_vpn():
    """
    If the BTS is registered, try to start the VPN. If the BTS is not
    registered, skip.

    If the BTS is unregistered (on the dashboard), no services are available.

    Regardless of whether the VPN is up or down, all services should be started
    (this will enable disconnected operation). However, when the VPN comes
    online, we need to restart FS to make sure that we're bound to the VPN IP
    so outgoing calls can work.
    """
    if not ('bts_registered' in conf and conf['bts_registered']):
        logger.error('BTS is not yet registered, skipping VPN setup, killing'
                     ' all services.')
        for s in SERVICES:
            if s.name == 'endagad':
                continue
            s.stop()
        return

    # If the VPN is down, try to start it, then restart FS if we succeed.
    if not system_utilities.get_vpn_ip():
        max_attempts = 10
        for _ in range(0, max_attempts):
            # Sometimes the vpn service is started, but the VPN is still down.
            # If this is the case, stop the vpn service first.
            openvpn_service = Service.SystemService('ccm-openvpn')
            if openvpn_service.status() == ServiceState.Running:
                openvpn_service.stop()
            if openvpn_service.start():
                logger.notice('VPN service started')
                if system_utilities.get_vpn_ip():
                    logger.notice('VPN up - restarting freeswitch')
                    Service.SystemService('freeswitch').restart()
                else:
                    logger.error('VPN interface (%s) is down' %
                                 conf.get('external_interface'))
            else:
                logger.error(
                    'VPN failed to start after registration, retrying.')
                time.sleep(3)
        if not system_utilities.get_vpn_ip():
            logger.error('Failed to set up VPN after %d attempts!' %
                         max_attempts)
    # Start all the other services.  This is safe to run if services are
    # already started.
    for s in SERVICES:
        try:
            s.start()
        except Exception as e:
            logger.critical("Exception %s while starting %s" % (e, s.name))
Beispiel #5
0
    def process_update(self, net_subs):
        """
        Processes the subscriber list. Format is:

        {
            IMSI1: {'number': [<numbers>,...], 'balance': {<PN counter>}},
            IMSI2: ...
        }

        This updates the BTS with all subscribers instructed by the cloud; any
        subscribers that are not reported by the cloud will be removed from
        this BTS.
        """
        # dict where keys are imsis and values are sub info
        bts_subs = {s['name']: s for s in self.get_subscribers()}

        bts_imsis = set(bts_subs.keys())
        net_imsis = set(net_subs.keys())

        subs_to_add = net_imsis.difference(bts_imsis)
        subs_to_delete = bts_imsis.difference(net_imsis)
        subs_to_update = bts_imsis.intersection(net_imsis)

        for imsi in subs_to_add:
            sub = net_subs[imsi]
            numbers = sub['numbers']
            if not numbers:
                logger.notice("IMSI with no numbers? %s" % imsi)
                continue
            self.create_subscriber(imsi, numbers[0])
            for n in numbers[1:]:
                self.add_number(imsi, n)
            try:
                bal = crdt.PNCounter.from_state(sub['balance'])
                self.update_balance(imsi, bal)
            except (SubscriberNotFound, ValueError) as e:
                logger.critical("Balance sync fail! IMSI: %s, %s Error: %s" %
                                (imsi, sub['balance'], e))

        for imsi in subs_to_delete:
            self.delete_subscriber(imsi)

        # TODO(shasan) does not add new numbers
        for imsi in subs_to_update:
            sub = net_subs[imsi]
            try:
                bal = crdt.PNCounter.from_state(sub['balance'])
                self.update_balance(imsi, bal)
            except (SubscriberNotFound, ValueError) as e:
                logger.critical("Balance sync fail! IMSI: %s, %s Error: %s" %
                                (imsi, sub['balance'], e))
def verify_cert(_, ca_file):
    """ Validate that cert has been signed by the Etage CA. """
    r = delegator.run("openssl verify -CAfile %s %s/endaga-client.crt" %
                  (ca_file, os.path.dirname(ca_file)))
    if r.return_code != 0:
        """
        Any error requires manual intervention, i.e., updating the CA
        cert, and hence cannot be resolved by retrying
        registration. Therefore we just raise an exception that
        terminates the agent.
        """
        msg = ("Unable to verify client cert against CA bundle:\n%s" %
               (r.out))
        logger.critical(msg)
        raise SystemExit(msg)
    logger.info("Verified client cert against CA %s" % (ca_file, ))
Beispiel #7
0
 def process(processors):
     try:
         if processors:
             p, processors = processors[0], processors[1:]
             return p(lambda: process(processors))
         else:
             return self.handle()
     except web.HTTPError as e:
         logger.error("Web error: %s" % e)
         raise
     except (KeyboardInterrupt, SystemExit):
         raise
     except Exception as e:
         logger.critical("Unhandled exception raised",
                         traceback=traceback.format_exc())
         raise self.internalerror()