o nnh@sdZddlmZddlZddlZddlZddlZddlZddlZddl m m m Z dddZdddZddd Zdd d Zdd dZdddZddZdddZdS)a This module adds shared support for generic api modules In order to use this module, include it as part of a custom module as shown below. The 'api' module provides the following common argument specs: * rate limit spec - rate: number of requests per time unit (int) - rate_limit: time window in which the limit is applied in seconds * retry spec - retries: number of attempts - retry_pause: delay between attempts in seconds ) annotationsNcCs*ttddtddd}|r|||S)z7Creates an argument spec for working with rate limitinginttype)rate rate_limitdictupdatespecarg_specrC/usr/local/lib/python3.10/dist-packages/ansible/module_utils/api.pyrate_limit_argument_spec&s rcCs,ttddtdddd}|r|||S)z2Creates an argument spec for working with retryingrrfloatrdefaultretries retry_pauserr rrrretry_argument_spec1s  rcCs>ttddtdddtddtdddd}|r|||S)NstrrT)rno_logboolr) api_username api_passwordapi_urlvalidate_certsrr rrrbasic_auth_argument_spec<s   r cs4d|dur|durt|t|fdd}|S)zrate limiting decoratorNcsdgfdd}|S)Ngcsdtjdkr tj}ntj}dur)|d}|}|dkr$t||d<|i|}|S)N)r)sys version_infotime process_timeclocksleep)argskwargs real_timeelapsedleftret)flastminraterr ratelimitedQs   z0rate_limit..wrapper..ratelimitedr)r/r2r1)r/r0rwrapperNszrate_limit..wrapper)r)rrr4rr3rrHs  rrcsfdd}|S)zRetry decoratorcsfdd}|S)Ncsnd}dur5d} |d7}|krtdz |i|}Wn ty)Ynw|r/ |Stq dS)NrTrzRetry limit exceeded: %d) Exceptionr%r()r)r* retry_countr.)r/rrrrretriedgs$   z'retry..wrapper..retriedr)r/r7r)r/rr4eszretry..wrapperr)rrr4rrrretrycsr8 r!<c cs2td|D]}tdt||d|VqdS)aDThe "Full Jitter" backoff strategy. Ref: https://www.awsarchitectureblog.com/2015/03/backoff.html :param retries: The number of delays to generate. :param delay_base: The base time in seconds used to calculate the exponential backoff. :param delay_threshold: The maximum time in seconds for any delay. rN)rangerandomrandintmin)r delay_basedelay_thresholdr8rrrgenerate_jittered_backoff|s rBcCsdS)NFr)exception_or_resultrrr retry_neversrDcs0dd}||~durtfdd}|S)zGeneric retry decorator. :param backoff_iterator: An iterable of delays in seconds. :param should_retry_error: A callable that takes an exception of the decorated function and decides whether to retry or not (returns a bool). css&t|\}}|V t|Vq N) itertoolsteecopy)original_iterator_copiable_iterator_first_iterator_copyrrr_emit_isolated_iterator_copiess  zGretry_with_delays_and_condition.._emit_isolated_iterator_copiesNcstfdd}|S)Nc srtjg|Ri|}tD]%}z|WSty/}z |s%WYd}~nd}~wwt|q|S)zThis assumes the function has not already been called. If backoff_iterator is empty, we should still run the function a single time with no delay. N) functoolspartialnextr5r%r()r)r*call_retryable_functiondelaye)backoff_iterator_generatorfunctionshould_retry_errorrr run_functions    zOretry_with_delays_and_condition..function_wrapper..run_function)rMwraps)rTrVrSrU)rTrfunction_wrappersz9retry_with_delays_and_condition..function_wrapper)rD)backoff_iteratorrUrLrYrrXrretry_with_delays_and_conditionsr[rE)NN)Nr)r9r!r:)__doc__ __future__rrHrMrFr=r#r%"ansible.module_utils.compat.typing module_utilscompattypingtrrr rr8rBrDr[rrrrs"