<s> from __future__ import absolute_import , print_function <EOL> '''<STR_LIT>''' <EOL> import time <EOL> import math <EOL> import fnmatch <EOL> import logging <EOL> from copy import copy <EOL> from collections import defaultdict <EOL> import cgi <EOL> import yaml <EOL> import tornado . httpserver <EOL> import tornado . ioloop <EOL> import tornado . web <EOL> import tornado . gen <EOL> from tornado . concurrent import Future <EOL> from zmq . eventloop import ioloop <EOL> import salt . ext . six as six <EOL> ioloop . install ( ) <EOL> import salt . netapi <EOL> import salt . utils <EOL> import salt . utils . event <EOL> from salt . utils . event import tagify <EOL> import salt . client <EOL> import salt . runner <EOL> import salt . auth <EOL> from salt . exceptions import EauthAuthenticationError <EOL> json = salt . utils . import_json ( ) <EOL> logger = logging . getLogger ( ) <EOL> class SaltClientsMixIn ( object ) : <EOL> '''<STR_LIT>''' <EOL> __saltclients = None <EOL> @ property <EOL> def saltclients ( self ) : <EOL> if SaltClientsMixIn . __saltclients is None : <EOL> local_client = salt . client . get_local_client ( mopts = self . application . opts ) <EOL> SaltClientsMixIn . __saltclients = { <EOL> '<STR_LIT>' : local_client . run_job , <EOL> '<STR_LIT>' : local_client . cmd_batch , <EOL> '<STR_LIT>' : local_client . run_job , <EOL> '<STR_LIT>' : salt . runner . RunnerClient ( opts = self . application . opts ) . cmd_async , <EOL> '<STR_LIT>' : None , <EOL> } <EOL> return SaltClientsMixIn . __saltclients <EOL> AUTH_TOKEN_HEADER = '<STR_LIT>' <EOL> AUTH_COOKIE_NAME = '<STR_LIT>' <EOL> class TimeoutException ( Exception ) : <EOL> pass <EOL> class Any ( Future ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , futures ) : <EOL> super ( Any , self ) . __init__ ( ) <EOL> for future in futures : <EOL> future . add_done_callback ( self . done_callback ) <EOL> def done_callback ( self , future ) : <EOL> if not self . done ( ) : <EOL> self . set_result ( future ) <EOL> class EventListener ( object ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , mod_opts , opts ) : <EOL> self . mod_opts = mod_opts <EOL> self . opts = opts <EOL> self . event = salt . utils . event . get_event ( <EOL> '<STR_LIT>' , <EOL> opts [ '<STR_LIT>' ] , <EOL> opts [ '<STR_LIT>' ] , <EOL> opts = opts , <EOL> listen = True , <EOL> io_loop = tornado . ioloop . IOLoop . current ( ) <EOL> ) <EOL> self . tag_map = defaultdict ( list ) <EOL> self . request_map = defaultdict ( list ) <EOL> self . timeout_map = { } <EOL> self . event . set_event_handler ( self . _handle_event_socket_recv ) <EOL> def clean_timeout_futures ( self , request ) : <EOL> '''<STR_LIT>''' <EOL> if request not in self . request_map : <EOL> return <EOL> for tag , future in self . request_map [ request ] : <EOL> self . _timeout_future ( tag , future ) <EOL> if future in self . timeout_map : <EOL> tornado . ioloop . IOLoop . current ( ) . remove_timeout ( self . timeout_map [ future ] ) <EOL> del self . timeout_map [ future ] <EOL> del self . request_map [ request ] <EOL> def get_event ( self , <EOL> request , <EOL> tag = '<STR_LIT>' , <EOL> callback = None , <EOL> timeout = None <EOL> ) : <EOL> '''<STR_LIT>''' <EOL> if request . _finished : <EOL> future = Future ( ) <EOL> future . set_exception ( TimeoutException ( ) ) <EOL> return future <EOL> future = Future ( ) <EOL> if callback is not None : <EOL> def handle_future ( future ) : <EOL> tornado . ioloop . IOLoop . current ( ) . add_callback ( callback , future ) <EOL> future . add_done_callback ( handle_future ) <EOL> self . tag_map [ tag ] . append ( future ) <EOL> self . request_map [ request ] . append ( ( tag , future ) ) <EOL> if timeout : <EOL> timeout_future = tornado . ioloop . IOLoop . current ( ) . call_later ( timeout , self . _timeout_future , tag , future ) <EOL> self . timeout_map [ future ] = timeout_future <EOL> return future <EOL> def _timeout_future ( self , tag , future ) : <EOL> '''<STR_LIT>''' <EOL> if tag not in self . tag_map : <EOL> return <EOL> if not future . done ( ) : <EOL> future . set_exception ( TimeoutException ( ) ) <EOL> self . tag_map [ tag ] . remove ( future ) <EOL> if len ( self . tag_map [ tag ] ) == <NUM_LIT:0> : <EOL> del self . tag_map [ tag ] <EOL> def _handle_event_socket_recv ( self , raw ) : <EOL> '''<STR_LIT>''' <EOL> mtag , data = self . event . unpack ( raw , self . event . serial ) <EOL> for tag_prefix , futures in six . iteritems ( self . tag_map ) : <EOL> if mtag . startswith ( tag_prefix ) : <EOL> for future in futures : <EOL> if future . done ( ) : <EOL> continue <EOL> future . set_result ( { '<STR_LIT:data>' : data , '<STR_LIT>' : mtag } ) <EOL> self . tag_map [ tag_prefix ] . remove ( future ) <EOL> if future in self . timeout_map : <EOL> tornado . ioloop . IOLoop . current ( ) . remove_timeout ( self . timeout_map [ future ] ) <EOL> del self . timeout_map [ future ] <EOL> def get_batch_size ( batch , num_minions ) : <EOL> '''<STR_LIT>''' <EOL> partition = lambda x : float ( x ) / <NUM_LIT> * num_minions <EOL> try : <EOL> if '<STR_LIT:%>' in batch : <EOL> res = partition ( float ( batch . strip ( '<STR_LIT:%>' ) ) ) <EOL> if res < <NUM_LIT:1> : <EOL> return int ( math . ceil ( res ) ) <EOL> else : <EOL> return int ( res ) <EOL> else : <EOL> return int ( batch ) <EOL> except ValueError : <EOL> print ( ( '<STR_LIT>' <EOL> '<STR_LIT>' ) . format ( batch ) ) <EOL> class BaseSaltAPIHandler ( tornado . web . RequestHandler , SaltClientsMixIn ) : <EOL> ct_out_map = ( <EOL> ( '<STR_LIT:application/json>' , json . dumps ) , <EOL> ( '<STR_LIT>' , yaml . safe_dump ) , <EOL> ) <EOL> def _verify_client ( self , low ) : <EOL> '''<STR_LIT>''' <EOL> if '<STR_LIT>' not in low or low . get ( '<STR_LIT>' ) not in self . saltclients : <EOL> self . set_status ( <NUM_LIT> ) <EOL> self . write ( "<STR_LIT>" ) <EOL> self . finish ( ) <EOL> return False <EOL> return True <EOL> def initialize ( self ) : <EOL> '''<STR_LIT>''' <EOL> if not hasattr ( self . application , '<STR_LIT>' ) : <EOL> logger . critical ( '<STR_LIT>' ) <EOL> self . application . event_listener = EventListener ( <EOL> self . application . mod_opts , <EOL> self . application . opts , <EOL> ) <EOL> @ property <EOL> def token ( self ) : <EOL> '''<STR_LIT>''' <EOL> if AUTH_TOKEN_HEADER in self . request . headers : <EOL> return self . request . headers [ AUTH_TOKEN_HEADER ] <EOL> else : <EOL> return self . get_cookie ( AUTH_COOKIE_NAME ) <EOL> def _verify_auth ( self ) : <EOL> '''<STR_LIT>''' <EOL> return self . token and bool ( self . application . auth . get_tok ( self . token ) ) <EOL> def prepare ( self ) : <EOL> '''<STR_LIT>''' <EOL> accept_header = self . request . headers . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> parsed_accept_header = [ cgi . parse_header ( h ) [ <NUM_LIT:0> ] for h in accept_header . split ( '<STR_LIT:U+002C>' ) ] <EOL> def find_acceptable_content_type ( parsed_accept_header ) : <EOL> for media_range in parsed_accept_header : <EOL> for content_type , dumper in self . ct_out_map : <EOL> if fnmatch . fnmatch ( content_type , media_range ) : <EOL> return content_type , dumper <EOL> return None , None <EOL> content_type , dumper = find_acceptable_content_type ( parsed_accept_header ) <EOL> if not content_type : <EOL> self . send_error ( <NUM_LIT> ) <EOL> self . content_type = content_type <EOL> self . dumper = dumper <EOL> self . start = time . time ( ) <EOL> self . connected = True <EOL> self . lowstate = self . _get_lowstate ( ) <EOL> def timeout_futures ( self ) : <EOL> '''<STR_LIT>''' <EOL> self . application . event_listener . clean_timeout_futures ( self ) <EOL> def on_finish ( self ) : <EOL> '''<STR_LIT>''' <EOL> self . timeout_futures ( ) <EOL> def on_connection_close ( self ) : <EOL> '''<STR_LIT>''' <EOL> self . finish ( ) <EOL> def serialize ( self , data ) : <EOL> '''<STR_LIT>''' <EOL> self . set_header ( '<STR_LIT:Content-Type>' , self . content_type ) <EOL> return self . dumper ( data ) <EOL> def _form_loader ( self , _ ) : <EOL> '''<STR_LIT>''' <EOL> data = { } <EOL> for key , val in six . iteritems ( self . request . arguments ) : <EOL> if len ( val ) == <NUM_LIT:1> : <EOL> data [ key ] = val [ <NUM_LIT:0> ] <EOL> else : <EOL> data [ key ] = val <EOL> return data <EOL> def deserialize ( self , data ) : <EOL> '''<STR_LIT>''' <EOL> ct_in_map = { <EOL> '<STR_LIT>' : self . _form_loader , <EOL> '<STR_LIT:application/json>' : json . loads , <EOL> '<STR_LIT>' : yaml . safe_load , <EOL> '<STR_LIT>' : yaml . safe_load , <EOL> '<STR_LIT>' : json . loads <EOL> } <EOL> try : <EOL> header = cgi . parse_header ( self . request . headers [ '<STR_LIT:Content-Type>' ] ) <EOL> value , parameters = header <EOL> return ct_in_map [ value ] ( data ) <EOL> except KeyError : <EOL> self . send_error ( <NUM_LIT> ) <EOL> except ValueError : <EOL> self . send_error ( <NUM_LIT> ) <EOL> def _get_lowstate ( self ) : <EOL> '''<STR_LIT>''' <EOL> if not self . request . body : <EOL> return <EOL> data = self . deserialize ( self . request . body ) <EOL> self . raw_data = copy ( data ) <EOL> if '<STR_LIT>' in data and not isinstance ( data [ '<STR_LIT>' ] , list ) : <EOL> data [ '<STR_LIT>' ] = [ data [ '<STR_LIT>' ] ] <EOL> if not isinstance ( data , list ) : <EOL> lowstate = [ data ] <EOL> else : <EOL> lowstate = data <EOL> return lowstate <EOL> def set_default_headers ( self ) : <EOL> '''<STR_LIT>''' <EOL> mod_opts = self . application . mod_opts <EOL> if mod_opts . get ( '<STR_LIT>' ) : <EOL> origin = self . request . headers . get ( '<STR_LIT>' ) <EOL> allowed_origin = _check_cors_origin ( origin , mod_opts [ '<STR_LIT>' ] ) <EOL> if allowed_origin : <EOL> self . set_header ( "<STR_LIT>" , allowed_origin ) <EOL> def options ( self , * args , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> request_headers = self . request . headers . get ( '<STR_LIT>' ) <EOL> allowed_headers = request_headers . split ( '<STR_LIT:U+002C>' ) <EOL> self . set_header ( '<STR_LIT>' , '<STR_LIT:U+002C>' . join ( allowed_headers ) ) <EOL> self . set_header ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . set_header ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . set_status ( <NUM_LIT> ) <EOL> self . finish ( ) <EOL> class SaltAuthHandler ( BaseSaltAPIHandler ) : <EOL> '''<STR_LIT>''' <EOL> def get ( self ) : <EOL> '''<STR_LIT>''' <EOL> self . set_status ( <NUM_LIT> ) <EOL> self . set_header ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> ret = { '<STR_LIT:status>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' } <EOL> self . write ( self . serialize ( ret ) ) <EOL> def post ( self ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> request_payload = self . deserialize ( self . request . body ) <EOL> if not isinstance ( request_payload , dict ) : <EOL> self . send_error ( <NUM_LIT> ) <EOL> return <EOL> creds = { '<STR_LIT:username>' : request_payload [ '<STR_LIT:username>' ] , <EOL> '<STR_LIT:password>' : request_payload [ '<STR_LIT:password>' ] , <EOL> '<STR_LIT>' : request_payload [ '<STR_LIT>' ] , <EOL> } <EOL> except KeyError : <EOL> self . send_error ( <NUM_LIT> ) <EOL> return <EOL> token = self . application . auth . mk_token ( creds ) <EOL> if '<STR_LIT>' not in token : <EOL> self . send_error ( <NUM_LIT> ) <EOL> return <EOL> try : <EOL> perms = self . application . opts [ '<STR_LIT>' ] [ token [ '<STR_LIT>' ] ] [ token [ '<STR_LIT:name>' ] ] <EOL> except KeyError : <EOL> self . send_error ( <NUM_LIT> ) <EOL> return <EOL> except ( AttributeError , IndexError ) : <EOL> logging . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> . format ( token . get ( '<STR_LIT>' ) , token . get ( '<STR_LIT:name>' ) ) , exc_info = True ) <EOL> self . send_error ( <NUM_LIT> ) <EOL> return <EOL> ret = { '<STR_LIT>' : [ { <EOL> '<STR_LIT>' : token [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : token [ '<STR_LIT>' ] , <EOL> '<STR_LIT:start>' : token [ '<STR_LIT:start>' ] , <EOL> '<STR_LIT:user>' : token [ '<STR_LIT:name>' ] , <EOL> '<STR_LIT>' : token [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : perms , <EOL> } ] } <EOL> self . write ( self . serialize ( ret ) ) <EOL> class SaltAPIHandler ( BaseSaltAPIHandler , SaltClientsMixIn ) : <EOL> '''<STR_LIT>''' <EOL> def get ( self ) : <EOL> '''<STR_LIT>''' <EOL> ret = { "<STR_LIT>" : list ( self . saltclients . keys ( ) ) , <EOL> "<STR_LIT>" : "<STR_LIT>" } <EOL> self . write ( self . serialize ( ret ) ) <EOL> @ tornado . web . asynchronous <EOL> def post ( self ) : <EOL> '''<STR_LIT>''' <EOL> if not self . _verify_auth ( ) : <EOL> self . redirect ( '<STR_LIT>' ) <EOL> return <EOL> self . disbatch ( ) <EOL> @ tornado . gen . coroutine <EOL> def disbatch ( self ) : <EOL> '''<STR_LIT>''' <EOL> ret = [ ] <EOL> for low in self . lowstate : <EOL> if not self . _verify_client ( low ) : <EOL> return <EOL> if self . token is not None and '<STR_LIT>' not in low : <EOL> low [ '<STR_LIT>' ] = self . token <EOL> if not ( ( '<STR_LIT>' in low ) <EOL> or ( '<STR_LIT:username>' in low and '<STR_LIT:password>' in low and '<STR_LIT>' in low ) ) : <EOL> ret . append ( '<STR_LIT>' ) <EOL> break <EOL> try : <EOL> chunk_ret = yield getattr ( self , '<STR_LIT>' . format ( low [ '<STR_LIT>' ] ) ) ( low ) <EOL> ret . append ( chunk_ret ) <EOL> except EauthAuthenticationError as exc : <EOL> ret . append ( '<STR_LIT>' ) <EOL> break <EOL> except Exception as ex : <EOL> ret . append ( '<STR_LIT>' . format ( ex ) ) <EOL> logger . error ( '<STR_LIT>' , exc_info = True ) <EOL> self . write ( self . serialize ( { '<STR_LIT>' : ret } ) ) <EOL> self . finish ( ) <EOL> @ tornado . gen . coroutine <EOL> def _disbatch_local_batch ( self , chunk ) : <EOL> '''<STR_LIT>''' <EOL> f_call = salt . utils . format_call ( self . saltclients [ '<STR_LIT>' ] , chunk ) <EOL> ping_ret = yield self . _disbatch_local ( { '<STR_LIT>' : chunk [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : f_call [ '<STR_LIT>' ] [ '<STR_LIT>' ] } ) <EOL> chunk_ret = { } <EOL> if not isinstance ( ping_ret , dict ) : <EOL> raise tornado . gen . Return ( chunk_ret ) <EOL> minions = list ( ping_ret . keys ( ) ) <EOL> maxflight = get_batch_size ( f_call [ '<STR_LIT>' ] [ '<STR_LIT>' ] , len ( minions ) ) <EOL> inflight_futures = [ ] <EOL> f_call [ '<STR_LIT>' ] [ '<STR_LIT>' ] = '<STR_LIT:list>' <EOL> while len ( minions ) > <NUM_LIT:0> or len ( inflight_futures ) > <NUM_LIT:0> : <EOL> while len ( inflight_futures ) < maxflight and len ( minions ) > <NUM_LIT:0> : <EOL> minion_id = minions . pop ( <NUM_LIT:0> ) <EOL> batch_chunk = dict ( chunk ) <EOL> batch_chunk [ '<STR_LIT>' ] = [ minion_id ] <EOL> batch_chunk [ '<STR_LIT>' ] = '<STR_LIT:list>' <EOL> future = self . _disbatch_local ( batch_chunk ) <EOL> inflight_futures . append ( future ) <EOL> if len ( inflight_futures ) == <NUM_LIT:0> : <EOL> continue <EOL> finished_future = yield Any ( inflight_futures ) <EOL> try : <EOL> b_ret = finished_future . result ( ) <EOL> except TimeoutException : <EOL> break <EOL> chunk_ret . update ( b_ret ) <EOL> inflight_futures . remove ( finished_future ) <EOL> raise tornado . gen . Return ( chunk_ret ) <EOL> @ tornado . gen . coroutine <EOL> def _disbatch_local ( self , chunk ) : <EOL> '''<STR_LIT>''' <EOL> chunk_ret = { } <EOL> f_call = salt . utils . format_call ( self . saltclients [ '<STR_LIT>' ] , chunk ) <EOL> try : <EOL> pub_data = self . saltclients [ '<STR_LIT>' ] ( * f_call . get ( '<STR_LIT:args>' , ( ) ) , ** f_call . get ( '<STR_LIT>' , { } ) ) <EOL> except EauthAuthenticationError : <EOL> raise tornado . gen . Return ( '<STR_LIT>' ) <EOL> if '<STR_LIT>' not in pub_data : <EOL> raise tornado . gen . Return ( '<STR_LIT>' ) <EOL> minions_remaining = pub_data [ '<STR_LIT>' ] <EOL> syndic_min_wait = None <EOL> if self . application . opts [ '<STR_LIT>' ] : <EOL> syndic_min_wait = tornado . gen . sleep ( self . application . opts [ '<STR_LIT>' ] ) <EOL> job_not_running = self . job_not_running ( pub_data [ '<STR_LIT>' ] , <EOL> chunk [ '<STR_LIT>' ] , <EOL> f_call [ '<STR_LIT>' ] [ '<STR_LIT>' ] , <EOL> minions_remaining = minions_remaining <EOL> ) <EOL> if syndic_min_wait is not None : <EOL> yield syndic_min_wait <EOL> chunk_ret = yield self . all_returns ( pub_data [ '<STR_LIT>' ] , <EOL> finish_futures = [ job_not_running ] , <EOL> minions_remaining = minions_remaining , <EOL> ) <EOL> raise tornado . gen . Return ( chunk_ret ) <EOL> @ tornado . gen . coroutine <EOL> def all_returns ( self , <EOL> jid , <EOL> finish_futures = None , <EOL> minions_remaining = None , <EOL> ) : <EOL> '''<STR_LIT>''' <EOL> if finish_futures is None : <EOL> finish_futures = [ ] <EOL> if minions_remaining is None : <EOL> minions_remaining = [ ] <EOL> ret_tag = tagify ( [ jid , '<STR_LIT>' ] , '<STR_LIT>' ) <EOL> chunk_ret = { } <EOL> while True : <EOL> ret_event = self . application . event_listener . get_event ( self , <EOL> tag = ret_tag , <EOL> ) <EOL> f = yield Any ( [ ret_event ] + finish_futures ) <EOL> if f in finish_futures : <EOL> raise tornado . gen . Return ( chunk_ret ) <EOL> event = f . result ( ) <EOL> chunk_ret [ event [ '<STR_LIT:data>' ] [ '<STR_LIT:id>' ] ] = event [ '<STR_LIT:data>' ] [ '<STR_LIT>' ] <EOL> try : <EOL> minions_remaining . remove ( event [ '<STR_LIT:data>' ] [ '<STR_LIT:id>' ] ) <EOL> except ValueError : <EOL> pass <EOL> if len ( minions_remaining ) == <NUM_LIT:0> : <EOL> raise tornado . gen . Return ( chunk_ret ) <EOL> @ tornado . gen . coroutine <EOL> def job_not_running ( self , <EOL> jid , <EOL> tgt , <EOL> tgt_type , <EOL> minions_remaining = None , <EOL> ) : <EOL> '''<STR_LIT>''' <EOL> if minions_remaining is None : <EOL> minions_remaining = [ ] <EOL> ping_pub_data = self . saltclients [ '<STR_LIT>' ] ( tgt , <EOL> '<STR_LIT>' , <EOL> [ jid ] , <EOL> expr_form = tgt_type ) <EOL> ping_tag = tagify ( [ ping_pub_data [ '<STR_LIT>' ] , '<STR_LIT>' ] , '<STR_LIT>' ) <EOL> minion_running = False <EOL> while True : <EOL> try : <EOL> event = yield self . application . event_listener . get_event ( self , <EOL> tag = ping_tag , <EOL> timeout = self . application . opts [ '<STR_LIT>' ] , <EOL> ) <EOL> except TimeoutException : <EOL> if not minion_running : <EOL> raise tornado . gen . Return ( True ) <EOL> else : <EOL> ping_pub_data = self . saltclients [ '<STR_LIT>' ] ( tgt , <EOL> '<STR_LIT>' , <EOL> [ jid ] , <EOL> expr_form = tgt_type ) <EOL> ping_tag = tagify ( [ ping_pub_data [ '<STR_LIT>' ] , '<STR_LIT>' ] , '<STR_LIT>' ) <EOL> minion_running = False <EOL> continue <EOL> if event [ '<STR_LIT:data>' ] . get ( '<STR_LIT>' , { } ) == { } : <EOL> continue <EOL> minion_running = True <EOL> id_ = event [ '<STR_LIT:data>' ] [ '<STR_LIT:id>' ] <EOL> if id_ not in minions_remaining : <EOL> minions_remaining . append ( event [ '<STR_LIT:data>' ] [ '<STR_LIT:id>' ] ) <EOL> @ tornado . gen . coroutine <EOL> def _disbatch_local_async ( self , chunk ) : <EOL> '''<STR_LIT>''' <EOL> f_call = salt . utils . format_call ( self . saltclients [ '<STR_LIT>' ] , chunk ) <EOL> pub_data = self . saltclients [ '<STR_LIT>' ] ( * f_call . get ( '<STR_LIT:args>' , ( ) ) , ** f_call . get ( '<STR_LIT>' , { } ) ) <EOL> raise tornado . gen . Return ( pub_data ) <EOL> @ tornado . gen . coroutine <EOL> def _disbatch_runner ( self , chunk ) : <EOL> '''<STR_LIT>''' <EOL> pub_data = self . saltclients [ '<STR_LIT>' ] ( chunk ) <EOL> tag = pub_data [ '<STR_LIT>' ] + '<STR_LIT>' <EOL> try : <EOL> event = yield self . application . event_listener . get_event ( self , tag = tag ) <EOL> raise tornado . gen . Return ( event [ '<STR_LIT:data>' ] [ '<STR_LIT>' ] ) <EOL> except TimeoutException : <EOL> raise tornado . gen . Return ( '<STR_LIT>' ) <EOL> @ tornado . gen . coroutine <EOL> def _disbatch_runner_async ( self , chunk ) : <EOL> '''<STR_LIT>''' <EOL> pub_data = self . saltclients [ '<STR_LIT>' ] ( chunk ) <EOL> raise tornado . gen . Return ( pub_data ) <EOL> class MinionSaltAPIHandler ( SaltAPIHandler ) : <EOL> '''<STR_LIT>''' <EOL> @ tornado . web . asynchronous <EOL> def get ( self , mid = None ) : <EOL> '''<STR_LIT>''' <EOL> if not self . _verify_auth ( ) : <EOL> self . redirect ( '<STR_LIT>' ) <EOL> return <EOL> self . lowstate = [ { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : mid or '<STR_LIT:*>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } ] <EOL> self . disbatch ( ) <EOL> @ tornado . web . asynchronous <EOL> def post ( self ) : <EOL> '''<STR_LIT>''' <EOL> if not self . _verify_auth ( ) : <EOL> self . redirect ( '<STR_LIT>' ) <EOL> return <EOL> for low in self . lowstate : <EOL> if '<STR_LIT>' not in low : <EOL> low [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> continue <EOL> if low . get ( '<STR_LIT>' ) != '<STR_LIT>' : <EOL> self . set_status ( <NUM_LIT> ) <EOL> self . write ( '<STR_LIT>' ) <EOL> self . finish ( ) <EOL> return <EOL> self . disbatch ( ) <EOL> class JobsSaltAPIHandler ( SaltAPIHandler ) : <EOL> '''<STR_LIT>''' <EOL> @ tornado . web . asynchronous <EOL> def get ( self , jid = None ) : <EOL> '''<STR_LIT>''' <EOL> if not self . _verify_auth ( ) : <EOL> self . redirect ( '<STR_LIT>' ) <EOL> return <EOL> if jid : <EOL> self . lowstate = [ { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : jid , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } ] <EOL> else : <EOL> self . lowstate = [ { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } ] <EOL> self . disbatch ( ) <EOL> class RunSaltAPIHandler ( SaltAPIHandler ) : <EOL> '''<STR_LIT>''' <EOL> @ tornado . web . asynchronous <EOL> def post ( self ) : <EOL> '''<STR_LIT>''' <EOL> self . disbatch ( ) <EOL> class EventsSaltAPIHandler ( SaltAPIHandler ) : <EOL> '''<STR_LIT>''' <EOL> @ tornado . gen . coroutine <EOL> def get ( self ) : <EOL> r'''<STR_LIT>''' <EOL> if not self . _verify_auth ( ) : <EOL> self . redirect ( '<STR_LIT>' ) <EOL> return <EOL> self . set_header ( '<STR_LIT:Content-Type>' , '<STR_LIT>' ) <EOL> self . set_header ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . set_header ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . write ( u'<STR_LIT>' . format ( <NUM_LIT> ) ) <EOL> self . flush ( ) <EOL> while True : <EOL> try : <EOL> event = yield self . application . event_listener . get_event ( self ) <EOL> self . write ( u'<STR_LIT>' . format ( event . get ( '<STR_LIT>' , '<STR_LIT>' ) ) ) <EOL> self . write ( u'<STR_LIT>' . format ( json . dumps ( event ) ) ) <EOL> self . flush ( ) <EOL> except TimeoutException : <EOL> break <EOL> class WebhookSaltAPIHandler ( SaltAPIHandler ) : <EOL> '''<STR_LIT>''' <EOL> def post ( self , tag_suffix = None ) : <EOL> '''<STR_LIT>''' <EOL> disable_auth = self . application . mod_opts . get ( '<STR_LIT>' ) <EOL> if not disable_auth and not self . _verify_auth ( ) : <EOL> self . redirect ( '<STR_LIT>' ) <EOL> return <EOL> tag = '<STR_LIT>' <EOL> if tag_suffix : <EOL> tag += tag_suffix <EOL> self . event = salt . utils . event . get_event ( <EOL> '<STR_LIT>' , <EOL> self . application . opts [ '<STR_LIT>' ] , <EOL> self . application . opts [ '<STR_LIT>' ] , <EOL> opts = self . application . opts , <EOL> listen = False ) <EOL> ret = self . event . fire_event ( { <EOL> '<STR_LIT>' : self . raw_data , <EOL> '<STR_LIT>' : dict ( self . request . query_arguments ) , <EOL> '<STR_LIT>' : dict ( self . request . headers ) , <EOL> } , tag ) <EOL> self . write ( self . serialize ( { '<STR_LIT:success>' : ret } ) ) <EOL> def _check_cors_origin ( origin , allowed_origins ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( allowed_origins , list ) : <EOL> if origin in allowed_origins : <EOL> return origin <EOL> elif allowed_origins == '<STR_LIT:*>' : <EOL> return allowed_origins <EOL> elif allowed_origins == origin : <EOL> return allowed_origins </s>
