Beispiel #1
0
def _admin_api(ctx, scope=None):
    """Resolve admin API SRV records."""

    # Default.
    #
    def _lookup(ctx, scope):
        if scope:
            srv = '_http._tcp.adminapi.{scope}'.format(scope=scope)
        else:
            srv = '_http._tcp.adminapi'

        return _api(ctx, srv, 'http')

    if scope is not None:
        return _lookup(ctx, scope)
    else:
        api_scopes = ctx.get('api_scope', [])
        # Append global scope for admin api by default.
        api_scopes.append(None)
        for api_scope in api_scopes:
            try:
                result = _lookup(ctx, api_scope)
                if result:
                    return result
            except context.ContextError:
                pass

        raise context.ContextError('no admin api found.')
Beispiel #2
0
def resolve(ctx, attr):
    """Resolve context attribute."""

    if attr != 'zk_url':
        raise KeyError(attr)

    # TODO: in case of invalid cell it will throw ldap exception.
    #                need to standardize on ContextError raised lazily
    #                on first connection attempt, and keep resolve
    #                exception free.
    try:
        admin_cell = admin.Cell(ctx.ldap.conn)
        cell = admin_cell.get(ctx.cell)
        scheme = cell.get('zk-auth-scheme')
        if not scheme:
            scheme = 'zookeeper'

        zk_hostports = [
            '{hostname}:{port}'.format(hostname=master['hostname'],
                                       port=master['zk-client-port'])
            for master in cell['masters']
        ]
        return '{scheme}://{username}@{hostports}/treadmill/{cell}'.format(
            scheme=scheme,
            username=cell['username'],
            hostports=','.join(zk_hostports),
            cell=ctx.cell)
    except ldap_exceptions.LDAPNoSuchObjectResult:
        exception = context.ContextError('Cell {} not defined in LDAP'.format(
            ctx.cell))
        _LOGGER.debug(str(exception))
        raise exception
Beispiel #3
0
def _api(ctx, target, proto=None):
    """Resolve cell api."""
    srv_recs = _resolve_srv(ctx.dns_domain, ctx.dns_server, target)
    if not srv_recs:
        raise context.ContextError('No srv records found: %s' % target)

    return (srv_recs, proto)
Beispiel #4
0
def _ldap_url(ctx):
    """Resolve LDAP for given cell."""

    if not ctx.cell:
        raise context.ContextError('Cell not specified.')

    ldap_srv_rec = dnsutils.srv(
        '_ldap._tcp.%s.%s' % (ctx.cell, ctx.dns_domain), ctx.dns_server)
    return _srv_to_urls(ldap_srv_rec, 'ldap')
Beispiel #5
0
def _resolve_srv(dns_domain, dns_server, srv_rec):
    """Returns randomized list of host, port tuples for given srv record.
    """
    _LOGGER.debug('Query DNS -t SRV %s.%s', srv_rec, dns_domain)
    if not dns_domain:
        raise context.ContextError('Treadmill DNS domain not specified.')

    result = dnsutils.srv(srv_rec + '.' + dns_domain, dns_server)
    random.shuffle(result)
    return result
Beispiel #6
0
def _ws_api(ctx, scope=None):
    """Resolve webscocket api given context and scope.

    Default srv lookup - _ws._tcp.wsapi.<cell>.cell

    Override - environment var: TREADMILL_WS_LOOKUP_<cell>
    all upper case.
    """
    if scope is None:
        if not ctx.cell:
            raise context.ContextError('Cell not specified.')
        scope = cell_scope(ctx.cell)

    env_override = 'TREADMILL_WSAPI_LOOKUP_{cell}'.format(
        cell=ctx.cell).upper()

    srvlookup = os.environ.get(env_override, '_ws._tcp.wsapi.{scope}')
    return _api(ctx, srvlookup.format(scope=scope, cell=ctx.cell), 'ws')
Beispiel #7
0
def _cell_api(ctx, scope=None):
    """Resolve cell api given context and scope.

    Default srv lookup - _http._tcp.cellapi.<cell>.cell

    Override - environment var: TREADMILL_CELLAPI_LOOKUP_<cell>
    all upper case.
    """

    if scope is None:
        if not ctx.cell:
            raise context.ContextError('Cell not specified.')
        scope = cell_scope(ctx.cell)

    # Check if there is srv record override for the given cell.
    env_override = 'TREADMILL_CELLAPI_LOOKUP_{cell}'.format(
        cell=ctx.cell).upper()

    srvlookup = os.environ.get(env_override, '_http._tcp.cellapi.{scope}')
    return _api(ctx, srvlookup.format(scope=scope, cell=ctx.cell), 'http')
Beispiel #8
0
def _admin_api(ctx, scope=None):
    """Resolve admin API SRV records."""

    # Default.
    #
    def _lookup(ctx, scope):
        return _api(ctx, '_http._tcp.adminapi.{scope}'.format(scope=scope),
                    'http')

    if scope is not None:
        return _lookup(ctx, scope)

    else:
        for api_scope in ctx.get('api_scope', []):
            try:
                result = _lookup(ctx, api_scope)
                if result:
                    return result
            except context.ContextError:
                pass

        raise context.ContextError('no admin api found.')
Beispiel #9
0
def _admin_api(ctx, scope=None):
    """Resolve admin API SRV records."""

    # Default.
    def _lookup(ctx, scope):
        """Lookup admin api based on scope."""

        if scope == 'global':
            default_lookup = '_http._tcp.adminapi'
        else:
            default_lookup = '_http._tcp.adminapi.{scope}'

        env_override = 'TREADMILL_ADMINAPI_LOOKUP_{scope}'.format(
            scope=scope).upper().replace('.', '_')

        srvlookup = os.environ.get(env_override, default_lookup)
        if not srvlookup:
            return None

        return _api(ctx, srvlookup.format(scope=scope), 'http')

    if scope is not None:
        return _lookup(ctx, scope)
    else:
        scopes = ctx.get('api_scope', [])
        if 'global' not in scopes:
            scopes.append('global')

        for api_scope in scopes:
            try:
                result = _lookup(ctx, api_scope)
                if result:
                    return result
            except context.ContextError:
                pass

        raise context.ContextError('no admin api found.')
Beispiel #10
0
def resolve(ctx, attr):
    """Resolve context attribute."""

    if attr != 'zk_url':
        raise KeyError(attr)

    # TODO: in case of invalid cell it will throw ldap exception.
    #                need to standardize on ContextError raised lazily
    #                on first connection attempt, and keep resolve
    #                exception free.
    try:
        admin_cell = admin.Cell(ctx.ldap.conn)
        cell = admin_cell.get(ctx.cell)
        zk_hostports = [
            '%s:%s' % (master['hostname'], master['zk-client-port'])
            for master in cell['masters']
        ]
        return 'zookeeper://%s@%s/treadmill/%s' % (
            cell['username'], ','.join(zk_hostports), ctx.cell)
    except ldap_exceptions.LDAPNoSuchObjectResult:
        exception = context.ContextError('Cell not defined in LDAP {}'.format(
            ctx.cell))
        _LOGGER.debug(str(exception))
        raise exception
Beispiel #11
0
def _ws_api(ctx, scope=None):
    if scope is None:
        if not ctx.cell:
            raise context.ContextError('Cell not specified.')
        scope = cell_scope(ctx.cell)
    return _api(ctx, '_ws._tcp.wsapi.{scope}'.format(scope=scope), 'ws')
Beispiel #12
0
def _state_api(ctx, scope=None):
    if scope is None:
        if not ctx.cell:
            raise context.ContextError('Cell not specified.')
        scope = cell_scope(ctx.cell)
    return _api(ctx, '_http._tcp.stateapi.{scope}'.format(scope=scope), 'http')