<s> '''<STR_LIT>''' <EOL> from __future__ import absolute_import <EOL> import collections <EOL> import itertools <EOL> import functools <EOL> import logging <EOL> import json <EOL> import StringIO <EOL> import tarfile <EOL> import time <EOL> from multiprocessing import Process , Pipe <EOL> import cherrypy <EOL> from cherrypy . lib import cpstats <EOL> import yaml <EOL> import salt . ext . six as six <EOL> import salt <EOL> import salt . auth <EOL> import salt . utils . event <EOL> import salt . netapi <EOL> logger = logging . getLogger ( __name__ ) <EOL> try : <EOL> from . tools import websockets <EOL> from . import event_processor <EOL> HAS_WEBSOCKETS = True <EOL> except ImportError : <EOL> websockets = type ( '<STR_LIT>' , ( object , ) , { <EOL> '<STR_LIT>' : None , <EOL> } ) <EOL> HAS_WEBSOCKETS = False <EOL> def html_override_tool ( ) : <EOL> '''<STR_LIT>''' <EOL> apiopts = cherrypy . config [ '<STR_LIT>' ] <EOL> request = cherrypy . request <EOL> url_blacklist = ( <EOL> apiopts . get ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> apiopts . get ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ) <EOL> if '<STR_LIT>' not in cherrypy . config [ '<STR_LIT>' ] : <EOL> return <EOL> if request . path_info . startswith ( url_blacklist ) : <EOL> return <EOL> if request . headers . get ( '<STR_LIT>' ) == '<STR_LIT>' : <EOL> return <EOL> try : <EOL> wants_html = cherrypy . lib . cptools . accept ( '<STR_LIT>' ) <EOL> except cherrypy . HTTPError : <EOL> return <EOL> else : <EOL> if wants_html != '<STR_LIT>' : <EOL> return <EOL> raise cherrypy . InternalRedirect ( apiopts . get ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> def salt_token_tool ( ) : <EOL> '''<STR_LIT>''' <EOL> x_auth = cherrypy . request . headers . get ( '<STR_LIT>' , None ) <EOL> if x_auth : <EOL> cherrypy . request . cookie [ '<STR_LIT>' ] = x_auth <EOL> def salt_api_acl_tool ( username , request ) : <EOL> '''<STR_LIT>''' <EOL> failure_str = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> success_str = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> pass_str = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> acl = None <EOL> salt_config = cherrypy . config . get ( '<STR_LIT>' , None ) <EOL> if salt_config : <EOL> cherrypy_conf = salt_config . get ( '<STR_LIT>' , None ) <EOL> if cherrypy_conf : <EOL> acl = cherrypy_conf . get ( '<STR_LIT>' , None ) <EOL> ip = request . remote . ip <EOL> if acl : <EOL> users = acl . get ( '<STR_LIT>' , { } ) <EOL> if users : <EOL> if username in users : <EOL> if ip in users [ username ] or '<STR_LIT:*>' in users [ username ] : <EOL> logger . info ( success_str . format ( username , ip ) ) <EOL> return True <EOL> else : <EOL> logger . info ( failure_str . format ( username , ip ) ) <EOL> return False <EOL> elif username not in users and '<STR_LIT:*>' in users : <EOL> if ip in users [ '<STR_LIT:*>' ] or '<STR_LIT:*>' in users [ '<STR_LIT:*>' ] : <EOL> logger . info ( success_str . format ( username , ip ) ) <EOL> return True <EOL> else : <EOL> logger . info ( failure_str . format ( username , ip ) ) <EOL> return False <EOL> else : <EOL> logger . info ( failure_str . format ( username , ip ) ) <EOL> return False <EOL> else : <EOL> logger . info ( pass_str . format ( username , ip ) ) <EOL> return True <EOL> def salt_ip_verify_tool ( ) : <EOL> '''<STR_LIT>''' <EOL> salt_config = cherrypy . config . get ( '<STR_LIT>' , None ) <EOL> if salt_config : <EOL> cherrypy_conf = salt_config . get ( '<STR_LIT>' , None ) <EOL> if cherrypy_conf : <EOL> auth_ip_list = cherrypy_conf . get ( '<STR_LIT>' , None ) <EOL> if auth_ip_list : <EOL> logger . debug ( "<STR_LIT>" . format ( auth_ip_list ) ) <EOL> rem_ip = cherrypy . request . headers . get ( '<STR_LIT>' , None ) <EOL> logger . debug ( "<STR_LIT>" . format ( rem_ip ) ) <EOL> if rem_ip not in auth_ip_list : <EOL> logger . error ( "<STR_LIT>" . format ( rem_ip ) ) <EOL> cherrypy . response . status = <NUM_LIT> <EOL> return { <EOL> '<STR_LIT:status>' : cherrypy . response . status , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> } <EOL> def salt_auth_tool ( ) : <EOL> '''<STR_LIT>''' <EOL> if '<STR_LIT>' not in cherrypy . session : <EOL> raise cherrypy . HTTPError ( <NUM_LIT> ) <EOL> cherrypy . response . headers [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> def cors_handler ( * args , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> req_head = cherrypy . request . headers <EOL> resp_head = cherrypy . response . headers <EOL> ac_method = req_head . get ( '<STR_LIT>' , None ) <EOL> allowed_methods = [ '<STR_LIT:GET>' , '<STR_LIT:POST>' ] <EOL> allowed_headers = [ '<STR_LIT>' , '<STR_LIT:Content-Type>' ] <EOL> if ac_method and ac_method in allowed_methods : <EOL> resp_head [ '<STR_LIT>' ] = '<STR_LIT:U+002CU+0020>' . join ( allowed_methods ) <EOL> resp_head [ '<STR_LIT>' ] = '<STR_LIT:U+002CU+0020>' . join ( allowed_headers ) <EOL> resp_head [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> resp_head [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> return { } <EOL> def cors_tool ( ) : <EOL> '''<STR_LIT>''' <EOL> req_head = cherrypy . request . headers <EOL> resp_head = cherrypy . response . headers <EOL> resp_head [ '<STR_LIT>' ] = req_head . get ( '<STR_LIT>' , '<STR_LIT:*>' ) <EOL> resp_head [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> resp_head [ '<STR_LIT>' ] = '<STR_LIT:true>' <EOL> if cherrypy . request . method == '<STR_LIT>' : <EOL> cherrypy . serving . request . handler = cors_handler <EOL> ct_out_map = ( <EOL> ( '<STR_LIT:application/json>' , json . dumps ) , <EOL> ( '<STR_LIT>' , functools . partial ( <EOL> yaml . safe_dump , default_flow_style = False ) ) , <EOL> ) <EOL> def hypermedia_handler ( * args , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> cherrypy . response . processors = dict ( ct_out_map ) <EOL> ret = cherrypy . serving . request . _hypermedia_inner_handler ( * args , ** kwargs ) <EOL> except ( salt . exceptions . EauthAuthenticationError , <EOL> salt . exceptions . TokenAuthenticationError ) : <EOL> raise cherrypy . HTTPError ( <NUM_LIT> ) <EOL> except salt . exceptions . SaltInvocationError : <EOL> raise cherrypy . HTTPError ( <NUM_LIT> ) <EOL> except ( salt . exceptions . SaltDaemonNotRunning , <EOL> salt . exceptions . SaltReqTimeoutError ) as exc : <EOL> raise cherrypy . HTTPError ( <NUM_LIT> , exc . strerror ) <EOL> except cherrypy . CherryPyException : <EOL> raise <EOL> except Exception as exc : <EOL> import traceback <EOL> logger . debug ( "<STR_LIT>" , <EOL> cherrypy . request . path_info , <EOL> exc_info = True ) <EOL> cherrypy . response . status = <NUM_LIT> <EOL> ret = { <EOL> '<STR_LIT:status>' : cherrypy . response . status , <EOL> '<STR_LIT>' : '<STR_LIT>' . format ( traceback . format_exc ( exc ) ) <EOL> if cherrypy . config [ '<STR_LIT>' ] <EOL> else "<STR_LIT>" } <EOL> best = cherrypy . lib . cptools . accept ( [ i for ( i , _ ) in ct_out_map ] ) <EOL> cherrypy . response . headers [ '<STR_LIT:Content-Type>' ] = best <EOL> out = cherrypy . response . processors [ best ] <EOL> return out ( ret ) <EOL> def hypermedia_out ( ) : <EOL> '''<STR_LIT>''' <EOL> request = cherrypy . serving . request <EOL> request . _hypermedia_inner_handler = request . handler <EOL> request . handler = hypermedia_handler <EOL> @ functools . wraps <EOL> def process_request_body ( fn ) : <EOL> '''<STR_LIT>''' <EOL> def wrapped ( * args , ** kwargs ) : <EOL> if cherrypy . request . process_request_body is not False : <EOL> fn ( * args , ** kwargs ) <EOL> return wrapped <EOL> def urlencoded_processor ( entity ) : <EOL> '''<STR_LIT>''' <EOL> cherrypy . _cpreqbody . process_urlencoded ( entity ) <EOL> cherrypy . serving . request . unserialized_data = entity . params <EOL> cherrypy . serving . request . raw_body = '<STR_LIT>' <EOL> @ process_request_body <EOL> def json_processor ( entity ) : <EOL> '''<STR_LIT>''' <EOL> body = entity . fp . read ( ) <EOL> try : <EOL> cherrypy . serving . request . unserialized_data = json . loads ( body ) <EOL> except ValueError : <EOL> raise cherrypy . HTTPError ( <NUM_LIT> , '<STR_LIT>' ) <EOL> cherrypy . serving . request . raw_body = body <EOL> @ process_request_body <EOL> def yaml_processor ( entity ) : <EOL> '''<STR_LIT>''' <EOL> body = entity . fp . read ( ) <EOL> try : <EOL> cherrypy . serving . request . unserialized_data = yaml . safe_load ( body ) <EOL> except ValueError : <EOL> raise cherrypy . HTTPError ( <NUM_LIT> , '<STR_LIT>' ) <EOL> cherrypy . serving . request . raw_body = body <EOL> @ process_request_body <EOL> def text_processor ( entity ) : <EOL> '''<STR_LIT>''' <EOL> body = entity . fp . read ( ) <EOL> try : <EOL> cherrypy . serving . request . unserialized_data = json . loads ( body ) <EOL> except ValueError : <EOL> cherrypy . serving . request . unserialized_data = body <EOL> cherrypy . serving . request . raw_body = body <EOL> def hypermedia_in ( ) : <EOL> '''<STR_LIT>''' <EOL> ct_in_map = { <EOL> '<STR_LIT>' : urlencoded_processor , <EOL> '<STR_LIT:application/json>' : json_processor , <EOL> '<STR_LIT>' : yaml_processor , <EOL> '<STR_LIT>' : yaml_processor , <EOL> '<STR_LIT>' : text_processor , <EOL> } <EOL> if ( cherrypy . request . method . upper ( ) == '<STR_LIT:POST>' <EOL> and cherrypy . request . headers . get ( '<STR_LIT>' , '<STR_LIT:0>' ) == '<STR_LIT:0>' ) : <EOL> cherrypy . request . process_request_body = False <EOL> cherrypy . request . unserialized_data = None <EOL> cherrypy . request . body . processors . clear ( ) <EOL> cherrypy . request . body . default_proc = cherrypy . HTTPError ( <EOL> <NUM_LIT> , '<STR_LIT>' ) <EOL> cherrypy . request . body . processors = ct_in_map <EOL> def lowdata_fmt ( ) : <EOL> '''<STR_LIT>''' <EOL> if cherrypy . request . method . upper ( ) != '<STR_LIT:POST>' : <EOL> return <EOL> data = cherrypy . request . unserialized_data <EOL> if data and not isinstance ( data , list ) : <EOL> if '<STR_LIT>' in data and not isinstance ( data [ '<STR_LIT>' ] , list ) : <EOL> data [ '<STR_LIT>' ] = [ data [ '<STR_LIT>' ] ] <EOL> cherrypy . request . lowstate = [ data ] <EOL> else : <EOL> cherrypy . serving . request . lowstate = data <EOL> cherrypy . tools . html_override = cherrypy . Tool ( '<STR_LIT>' , <EOL> html_override_tool , priority = <NUM_LIT> ) <EOL> cherrypy . tools . salt_token = cherrypy . Tool ( '<STR_LIT>' , <EOL> salt_token_tool , priority = <NUM_LIT> ) <EOL> cherrypy . tools . salt_auth = cherrypy . Tool ( '<STR_LIT>' , <EOL> salt_auth_tool , priority = <NUM_LIT> ) <EOL> cherrypy . tools . hypermedia_in = cherrypy . Tool ( '<STR_LIT>' , <EOL> hypermedia_in ) <EOL> cherrypy . tools . cors_tool = cherrypy . Tool ( '<STR_LIT>' , <EOL> cors_tool , priority = <NUM_LIT:30> ) <EOL> cherrypy . tools . lowdata_fmt = cherrypy . Tool ( '<STR_LIT>' , <EOL> lowdata_fmt , priority = <NUM_LIT> ) <EOL> cherrypy . tools . hypermedia_out = cherrypy . Tool ( '<STR_LIT>' , <EOL> hypermedia_out ) <EOL> cherrypy . tools . salt_ip_verify = cherrypy . Tool ( '<STR_LIT>' , <EOL> salt_ip_verify_tool ) <EOL> class LowDataAdapter ( object ) : <EOL> '''<STR_LIT>''' <EOL> exposed = True <EOL> _cp_config = { <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : <NUM_LIT> * <NUM_LIT:10> , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> } <EOL> def __init__ ( self ) : <EOL> self . opts = cherrypy . config [ '<STR_LIT>' ] <EOL> self . api = salt . netapi . NetapiClient ( self . opts ) <EOL> def exec_lowstate ( self , client = None , token = None ) : <EOL> '''<STR_LIT>''' <EOL> lowstate = cherrypy . request . lowstate <EOL> if cherrypy . request . config . get ( '<STR_LIT>' , False ) : <EOL> cherrypy . session . release_lock ( ) <EOL> if not isinstance ( lowstate , list ) : <EOL> raise cherrypy . HTTPError ( <NUM_LIT> , '<STR_LIT>' ) <EOL> for chunk in lowstate : <EOL> if token : <EOL> chunk [ '<STR_LIT>' ] = token <EOL> if cherrypy . session . get ( '<STR_LIT:user>' ) : <EOL> chunk [ '<STR_LIT>' ] = cherrypy . session . get ( '<STR_LIT:user>' ) <EOL> if cherrypy . session . get ( '<STR_LIT>' ) : <EOL> chunk [ '<STR_LIT>' ] = cherrypy . session . get ( '<STR_LIT>' ) <EOL> if client : <EOL> chunk [ '<STR_LIT>' ] = client <EOL> if '<STR_LIT>' in chunk and not isinstance ( chunk [ '<STR_LIT>' ] , list ) : <EOL> chunk [ '<STR_LIT>' ] = [ chunk [ '<STR_LIT>' ] ] <EOL> ret = self . api . run ( chunk ) <EOL> if isinstance ( ret , collections . Iterator ) : <EOL> for i in ret : <EOL> yield i <EOL> else : <EOL> yield ret <EOL> def GET ( self ) : <EOL> '''<STR_LIT>''' <EOL> import inspect <EOL> return { <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : salt . netapi . CLIENTS , <EOL> } <EOL> @ cherrypy . tools . salt_token ( ) <EOL> @ cherrypy . tools . salt_auth ( ) <EOL> def POST ( self , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> return { <EOL> '<STR_LIT>' : list ( self . exec_lowstate ( <EOL> token = cherrypy . session . get ( '<STR_LIT>' ) ) ) <EOL> } <EOL> class Minions ( LowDataAdapter ) : <EOL> '''<STR_LIT>''' <EOL> _cp_config = dict ( LowDataAdapter . _cp_config , ** { <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> } ) <EOL> def GET ( self , mid = None ) : <EOL> '''<STR_LIT>''' <EOL> cherrypy . request . lowstate = [ { <EOL> '<STR_LIT>' : '<STR_LIT>' , '<STR_LIT>' : mid or '<STR_LIT:*>' , '<STR_LIT>' : '<STR_LIT>' , <EOL> } ] <EOL> return { <EOL> '<STR_LIT>' : list ( self . exec_lowstate ( <EOL> token = cherrypy . session . get ( '<STR_LIT>' ) ) ) , <EOL> } <EOL> def POST ( self , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> job_data = list ( self . exec_lowstate ( client = '<STR_LIT>' , <EOL> token = cherrypy . session . get ( '<STR_LIT>' ) ) ) <EOL> cherrypy . response . status = <NUM_LIT> <EOL> return { <EOL> '<STR_LIT>' : job_data , <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : [ { '<STR_LIT>' : '<STR_LIT>' . format ( i [ '<STR_LIT>' ] ) } <EOL> for i in job_data if i ] , <EOL> } , <EOL> } <EOL> class Jobs ( LowDataAdapter ) : <EOL> _cp_config = dict ( LowDataAdapter . _cp_config , ** { <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> } ) <EOL> def GET ( self , jid = None , timeout = '<STR_LIT>' ) : <EOL> '''<STR_LIT>''' <EOL> lowstate = [ { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' if jid else '<STR_LIT>' , <EOL> '<STR_LIT>' : jid , <EOL> } ] <EOL> if jid : <EOL> lowstate . append ( { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : jid , <EOL> } ) <EOL> cherrypy . request . lowstate = lowstate <EOL> job_ret_info = list ( self . exec_lowstate ( <EOL> token = cherrypy . session . get ( '<STR_LIT>' ) ) ) <EOL> ret = { } <EOL> if jid : <EOL> job_ret , job_info = job_ret_info <EOL> ret [ '<STR_LIT:info>' ] = [ job_info ] <EOL> else : <EOL> job_ret = job_ret_info [ <NUM_LIT:0> ] <EOL> ret [ '<STR_LIT>' ] = [ job_ret ] <EOL> return ret <EOL> class Keys ( LowDataAdapter ) : <EOL> '''<STR_LIT>''' <EOL> @ cherrypy . config ( ** { '<STR_LIT>' : True } ) <EOL> def GET ( self , mid = None ) : <EOL> '''<STR_LIT>''' <EOL> if mid : <EOL> lowstate = [ { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : mid , <EOL> } ] <EOL> else : <EOL> lowstate = [ { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } ] <EOL> cherrypy . request . lowstate = lowstate <EOL> result = self . exec_lowstate ( token = cherrypy . session . get ( '<STR_LIT>' ) ) <EOL> return { '<STR_LIT>' : next ( result , { } ) . get ( '<STR_LIT:data>' , { } ) . get ( '<STR_LIT>' , { } ) } <EOL> @ cherrypy . config ( ** { '<STR_LIT>' : False , '<STR_LIT>' : False } ) <EOL> def POST ( self , ** kwargs ) : <EOL> r'''<STR_LIT>''' <EOL> lowstate = cherrypy . request . lowstate <EOL> lowstate [ <NUM_LIT:0> ] . update ( { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } ) <EOL> if '<STR_LIT>' in lowstate [ <NUM_LIT:0> ] : <EOL> lowstate [ <NUM_LIT:0> ] [ '<STR_LIT>' ] = lowstate [ <NUM_LIT:0> ] . pop ( '<STR_LIT>' ) <EOL> result = self . exec_lowstate ( ) <EOL> ret = next ( result , { } ) . get ( '<STR_LIT:data>' , { } ) . get ( '<STR_LIT>' , { } ) <EOL> pub_key = ret . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> pub_key_file = tarfile . TarInfo ( '<STR_LIT>' ) <EOL> pub_key_file . size = len ( pub_key ) <EOL> priv_key = ret . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> priv_key_file = tarfile . TarInfo ( '<STR_LIT>' ) <EOL> priv_key_file . size = len ( priv_key ) <EOL> fileobj = StringIO . StringIO ( ) <EOL> tarball = tarfile . open ( fileobj = fileobj , mode = '<STR_LIT:w>' ) <EOL> tarball . addfile ( pub_key_file , StringIO . StringIO ( pub_key ) ) <EOL> tarball . addfile ( priv_key_file , StringIO . StringIO ( priv_key ) ) <EOL> tarball . close ( ) <EOL> headers = cherrypy . response . headers <EOL> headers [ '<STR_LIT>' ] = '<STR_LIT>' . format ( lowstate [ <NUM_LIT:0> ] [ '<STR_LIT>' ] ) <EOL> headers [ '<STR_LIT:Content-Type>' ] = '<STR_LIT>' <EOL> headers [ '<STR_LIT>' ] = fileobj . len <EOL> headers [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> fileobj . seek ( <NUM_LIT:0> ) <EOL> return fileobj <EOL> class Login ( LowDataAdapter ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( Login , self ) . __init__ ( * args , ** kwargs ) <EOL> self . auth = salt . auth . Resolver ( self . opts ) <EOL> def GET ( self ) : <EOL> '''<STR_LIT>''' <EOL> cherrypy . response . headers [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> return { <EOL> '<STR_LIT:status>' : cherrypy . response . status , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> } <EOL> def POST ( self , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> if not self . api . _is_master_running ( ) : <EOL> raise salt . exceptions . SaltDaemonNotRunning ( <EOL> '<STR_LIT>' ) <EOL> if isinstance ( cherrypy . serving . request . lowstate , list ) : <EOL> creds = cherrypy . serving . request . lowstate [ <NUM_LIT:0> ] <EOL> else : <EOL> creds = cherrypy . serving . request . lowstate <EOL> username = creds . get ( '<STR_LIT:username>' , None ) <EOL> if not salt_api_acl_tool ( username , cherrypy . request ) : <EOL> raise cherrypy . HTTPError ( <NUM_LIT> ) <EOL> token = self . auth . mk_token ( creds ) <EOL> if '<STR_LIT>' not in token : <EOL> raise cherrypy . HTTPError ( <NUM_LIT> , <EOL> '<STR_LIT>' ) <EOL> cherrypy . response . headers [ '<STR_LIT>' ] = cherrypy . session . id <EOL> cherrypy . session [ '<STR_LIT>' ] = token [ '<STR_LIT>' ] <EOL> cherrypy . session [ '<STR_LIT>' ] = ( token [ '<STR_LIT>' ] - token [ '<STR_LIT:start>' ] ) / <NUM_LIT> <EOL> cherrypy . session [ '<STR_LIT:user>' ] = token [ '<STR_LIT:name>' ] <EOL> if '<STR_LIT>' in token : <EOL> cherrypy . session [ '<STR_LIT>' ] = token [ '<STR_LIT>' ] <EOL> try : <EOL> eauth = self . opts . get ( '<STR_LIT>' , { } ) . get ( token [ '<STR_LIT>' ] , { } ) <EOL> perms = eauth . get ( token [ '<STR_LIT:name>' ] , [ ] ) <EOL> perms . extend ( eauth . get ( '<STR_LIT:*>' , [ ] ) ) <EOL> if '<STR_LIT>' in token and token [ '<STR_LIT>' ] is not False : <EOL> user_groups = set ( token [ '<STR_LIT>' ] ) <EOL> eauth_groups = set ( [ i . rstrip ( '<STR_LIT:%>' ) for i in eauth . keys ( ) if i . endswith ( '<STR_LIT:%>' ) ] ) <EOL> for group in user_groups & eauth_groups : <EOL> perms . extend ( eauth [ '<STR_LIT>' . format ( group ) ] ) <EOL> if not perms : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> except ( AttributeError , IndexError , KeyError , ValueError ) : <EOL> logger . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> . format ( token . get ( '<STR_LIT>' ) , token . get ( '<STR_LIT:name>' ) ) , exc_info = True ) <EOL> raise cherrypy . HTTPError ( <NUM_LIT> , <EOL> '<STR_LIT>' ) <EOL> return { '<STR_LIT>' : [ { <EOL> '<STR_LIT>' : cherrypy . session . id , <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> class Logout ( LowDataAdapter ) : <EOL> '''<STR_LIT>''' <EOL> _cp_config = dict ( LowDataAdapter . _cp_config , ** { <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : False , <EOL> } ) <EOL> def POST ( self ) : <EOL> '''<STR_LIT>''' <EOL> cherrypy . lib . sessions . expire ( ) <EOL> cherrypy . session . regenerate ( ) <EOL> return { '<STR_LIT>' : "<STR_LIT>" } <EOL> class Run ( LowDataAdapter ) : <EOL> '''<STR_LIT>''' <EOL> _cp_config = dict ( LowDataAdapter . _cp_config , ** { <EOL> '<STR_LIT>' : False , <EOL> } ) <EOL> def POST ( self , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> return { <EOL> '<STR_LIT>' : list ( self . exec_lowstate ( ) ) , <EOL> } <EOL> class Events ( object ) : <EOL> '''<STR_LIT>''' <EOL> exposed = True <EOL> _cp_config = dict ( LowDataAdapter . _cp_config , ** { <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : '<STR_LIT:utf-8>' , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : False , <EOL> '<STR_LIT>' : False , <EOL> '<STR_LIT>' : False , <EOL> } ) <EOL> def __init__ ( self ) : <EOL> self . opts = cherrypy . config [ '<STR_LIT>' ] <EOL> self . resolver = salt . auth . Resolver ( self . opts ) <EOL> def _is_valid_token ( self , auth_token ) : <EOL> '''<STR_LIT>''' <EOL> if auth_token is None : <EOL> return False <EOL> orig_session , _ = cherrypy . session . cache . get ( auth_token , ( { } , None ) ) <EOL> salt_token = orig_session . get ( '<STR_LIT>' , auth_token ) <EOL> if salt_token and self . resolver . get_token ( salt_token ) : <EOL> return True <EOL> return False <EOL> def GET ( self , token = None , salt_token = None ) : <EOL> r'''<STR_LIT>''' <EOL> cookies = cherrypy . request . cookie <EOL> auth_token = token or salt_token or ( <EOL> cookies [ '<STR_LIT>' ] . value if '<STR_LIT>' in cookies else None ) <EOL> if not self . _is_valid_token ( auth_token ) : <EOL> raise cherrypy . HTTPError ( <NUM_LIT> ) <EOL> cherrypy . session . release_lock ( ) <EOL> cherrypy . response . headers [ '<STR_LIT:Content-Type>' ] = '<STR_LIT>' <EOL> cherrypy . response . headers [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> cherrypy . response . headers [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> def listen ( ) : <EOL> '''<STR_LIT>''' <EOL> event = salt . utils . event . get_event ( <EOL> '<STR_LIT>' , <EOL> sock_dir = self . opts [ '<STR_LIT>' ] , <EOL> transport = self . opts [ '<STR_LIT>' ] , <EOL> opts = self . opts , <EOL> listen = True ) <EOL> stream = event . iter_events ( full = True ) <EOL> yield u'<STR_LIT>' . format ( <NUM_LIT> ) <EOL> while True : <EOL> data = next ( stream ) <EOL> yield u'<STR_LIT>' . format ( data . get ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> yield u'<STR_LIT>' . format ( json . dumps ( data ) ) <EOL> return listen ( ) <EOL> class WebsocketEndpoint ( object ) : <EOL> '''<STR_LIT>''' <EOL> exposed = True <EOL> _cp_config = dict ( LowDataAdapter . _cp_config , ** { <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : '<STR_LIT:utf-8>' , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : False , <EOL> '<STR_LIT>' : False , <EOL> '<STR_LIT>' : False , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : websockets . SynchronizingWebsocket , <EOL> } ) <EOL> def __init__ ( self ) : <EOL> self . opts = cherrypy . config [ '<STR_LIT>' ] <EOL> self . auth = salt . auth . LoadAuth ( self . opts ) <EOL> def GET ( self , token = None , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> if token : <EOL> orig_session , _ = cherrypy . session . cache . get ( token , ( { } , None ) ) <EOL> salt_token = orig_session . get ( '<STR_LIT>' ) <EOL> else : <EOL> salt_token = cherrypy . session . get ( '<STR_LIT>' ) <EOL> if not salt_token or not self . auth . get_tok ( salt_token ) : <EOL> raise cherrypy . HTTPError ( <NUM_LIT> ) <EOL> cherrypy . session . release_lock ( ) <EOL> handler = cherrypy . request . ws_handler <EOL> def event_stream ( handler , pipe ) : <EOL> '''<STR_LIT>''' <EOL> pipe . recv ( ) <EOL> event = salt . utils . event . get_event ( <EOL> '<STR_LIT>' , <EOL> sock_dir = self . opts [ '<STR_LIT>' ] , <EOL> transport = self . opts [ '<STR_LIT>' ] , <EOL> opts = self . opts , <EOL> listen = True ) <EOL> stream = event . iter_events ( full = True ) <EOL> SaltInfo = event_processor . SaltInfo ( handler ) <EOL> while True : <EOL> data = next ( stream ) <EOL> if data : <EOL> try : <EOL> if '<STR_LIT>' in kwargs : <EOL> SaltInfo . process ( data , salt_token , self . opts ) <EOL> else : <EOL> handler . send ( '<STR_LIT>' . format ( <EOL> json . dumps ( data ) ) , False ) <EOL> except UnicodeDecodeError : <EOL> logger . error ( <EOL> "<STR_LIT>" <EOL> . format ( data ) ) <EOL> time . sleep ( <NUM_LIT:0.1> ) <EOL> parent_pipe , child_pipe = Pipe ( ) <EOL> handler . pipe = parent_pipe <EOL> handler . opts = self . opts <EOL> proc = Process ( target = event_stream , args = ( handler , child_pipe ) ) <EOL> proc . start ( ) <EOL> class Webhook ( object ) : <EOL> '''<STR_LIT>''' <EOL> exposed = True <EOL> tag_base = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> _cp_config = dict ( LowDataAdapter . _cp_config , ** { <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> } ) <EOL> def __init__ ( self ) : <EOL> self . opts = cherrypy . config [ '<STR_LIT>' ] <EOL> self . event = salt . utils . event . get_event ( <EOL> '<STR_LIT>' , <EOL> sock_dir = self . opts [ '<STR_LIT>' ] , <EOL> transport = self . opts [ '<STR_LIT>' ] , <EOL> opts = self . opts , <EOL> listen = False ) <EOL> if cherrypy . config [ '<STR_LIT>' ] . get ( '<STR_LIT>' ) : <EOL> self . _cp_config [ '<STR_LIT>' ] = False <EOL> self . _cp_config [ '<STR_LIT>' ] = False <EOL> def POST ( self , * args , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> tag = '<STR_LIT:/>' . join ( itertools . chain ( self . tag_base , args ) ) <EOL> data = cherrypy . serving . request . unserialized_data <EOL> if not data : <EOL> data = { } <EOL> raw_body = getattr ( cherrypy . serving . request , '<STR_LIT>' , '<STR_LIT>' ) <EOL> headers = dict ( cherrypy . request . headers ) <EOL> ret = self . event . fire_event ( { <EOL> '<STR_LIT:body>' : raw_body , <EOL> '<STR_LIT>' : data , <EOL> '<STR_LIT>' : headers , <EOL> } , tag ) <EOL> return { '<STR_LIT:success>' : ret } <EOL> class Stats ( object ) : <EOL> '''<STR_LIT>''' <EOL> exposed = True <EOL> _cp_config = dict ( LowDataAdapter . _cp_config , ** { <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> } ) <EOL> def GET ( self ) : <EOL> '''<STR_LIT>''' <EOL> if hasattr ( logging , '<STR_LIT>' ) : <EOL> return cpstats . extrapolate_statistics ( logging . statistics ) <EOL> return { } <EOL> class App ( object ) : <EOL> '''<STR_LIT>''' <EOL> exposed = True <EOL> def GET ( self , * args ) : <EOL> '''<STR_LIT>''' <EOL> apiopts = cherrypy . config [ '<STR_LIT>' ] <EOL> return cherrypy . lib . static . serve_file ( apiopts [ '<STR_LIT>' ] ) <EOL> class API ( object ) : <EOL> '''<STR_LIT>''' <EOL> url_map = { <EOL> '<STR_LIT:index>' : LowDataAdapter , <EOL> '<STR_LIT>' : Login , <EOL> '<STR_LIT>' : Logout , <EOL> '<STR_LIT>' : Minions , <EOL> '<STR_LIT>' : Run , <EOL> '<STR_LIT>' : Jobs , <EOL> '<STR_LIT>' : Keys , <EOL> '<STR_LIT>' : Events , <EOL> '<STR_LIT>' : Stats , <EOL> } <EOL> def _setattr_url_map ( self ) : <EOL> '''<STR_LIT>''' <EOL> for url , cls in six . iteritems ( self . url_map ) : <EOL> setattr ( self , url , cls ( ) ) <EOL> def _update_url_map ( self ) : <EOL> '''<STR_LIT>''' <EOL> if HAS_WEBSOCKETS : <EOL> self . url_map . update ( { <EOL> '<STR_LIT>' : WebsocketEndpoint , <EOL> } ) <EOL> self . url_map . update ( { <EOL> self . apiopts . get ( '<STR_LIT>' , '<STR_LIT>' ) . lstrip ( '<STR_LIT:/>' ) : Webhook , <EOL> } ) <EOL> if '<STR_LIT>' in self . apiopts : <EOL> self . url_map . update ( { <EOL> self . apiopts . get ( '<STR_LIT>' , '<STR_LIT>' ) . lstrip ( '<STR_LIT:/>' ) : App , <EOL> } ) <EOL> def __init__ ( self ) : <EOL> self . opts = cherrypy . config [ '<STR_LIT>' ] <EOL> self . apiopts = cherrypy . config [ '<STR_LIT>' ] <EOL> self . _update_url_map ( ) <EOL> self . _setattr_url_map ( ) <EOL> def get_conf ( self ) : <EOL> '''<STR_LIT>''' <EOL> conf = { <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : self . apiopts . get ( '<STR_LIT:host>' , '<STR_LIT>' ) , <EOL> '<STR_LIT>' : self . apiopts . get ( '<STR_LIT:port>' , <NUM_LIT> ) , <EOL> '<STR_LIT>' : self . apiopts . get ( '<STR_LIT>' , <NUM_LIT:100> ) , <EOL> '<STR_LIT>' : self . apiopts . get ( '<STR_LIT>' , <NUM_LIT:30> ) , <EOL> '<STR_LIT>' : self . apiopts . get ( <EOL> '<STR_LIT>' , True ) , <EOL> '<STR_LIT>' : self . apiopts . get ( <EOL> '<STR_LIT>' , <NUM_LIT> ) , <EOL> '<STR_LIT>' : self . apiopts . get ( '<STR_LIT>' , False ) , <EOL> } , <EOL> '<STR_LIT:/>' : { <EOL> '<STR_LIT>' : cherrypy . dispatch . MethodDispatcher ( ) , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : self . apiopts . get ( '<STR_LIT>' , False ) , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> } , <EOL> } <EOL> if '<STR_LIT>' in self . apiopts : <EOL> conf [ '<STR_LIT>' ] = { <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : self . apiopts [ '<STR_LIT>' ] , <EOL> } <EOL> if self . apiopts . get ( '<STR_LIT>' , False ) is False : <EOL> conf [ '<STR_LIT>' ] [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> if '<STR_LIT>' in self . apiopts : <EOL> conf [ self . apiopts . get ( '<STR_LIT>' , '<STR_LIT>' ) ] = { <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : self . apiopts [ '<STR_LIT>' ] , <EOL> } <EOL> cherrypy . config . update ( conf [ '<STR_LIT>' ] ) <EOL> return conf <EOL> def get_app ( opts ) : <EOL> '''<STR_LIT>''' <EOL> apiopts = opts . get ( __name__ . rsplit ( '<STR_LIT:.>' , <NUM_LIT:2> ) [ - <NUM_LIT:2> ] , { } ) <EOL> cherrypy . config [ '<STR_LIT>' ] = opts <EOL> cherrypy . config [ '<STR_LIT>' ] = apiopts <EOL> root = API ( ) <EOL> cpyopts = root . get_conf ( ) <EOL> return root , apiopts , cpyopts </s>
