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.')
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
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)
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')
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
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')
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')
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.')
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.')
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
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')
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')