1
0

test_git_pillar.py 110 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479
  1. # -*- coding: utf-8 -*-
  2. """
  3. Integration tests for git_pillar
  4. The base classes for all of these tests are in tests/support/gitfs.py.
  5. Repositories for the tests are generated on the fly (look for the "make_repo"
  6. function).
  7. Where possible, a test case in this module should be reproduced in the
  8. following ways:
  9. 1. GitPython over SSH (TestGitPythonSSH)
  10. 2. GitPython over HTTP (TestGitPythonHTTP)
  11. 3. GitPython over HTTP w/basic auth (TestGitPythonAuthenticatedHTTP)
  12. 4. pygit2 over SSH (TestPygit2SSH)
  13. 5. pygit2 over HTTP (TestPygit2HTTP)
  14. 6. pygit2 over HTTP w/basic auth (TestPygit2AuthenticatedHTTP)
  15. For GitPython, this is easy, since it does not support the authentication
  16. configuration parameters that pygit2 does. Therefore, this test module includes
  17. a GitPythonMixin class which can be reused for all three GitPython test
  18. classes. The only thing we vary for these tests is the URL that we use.
  19. For pygit2 this is more complicated, since it supports A) both passphraseless
  20. and passphrase-protected SSH keys, and B) both global and per-remote credential
  21. parameters. So, for SSH tests we need to run each GitPython test case in 4
  22. different ways to cover pygit2:
  23. 1. Passphraseless key, global credential options
  24. 2. Passphraseless key, per-repo credential options
  25. 3. Passphrase-protected key, global credential options
  26. 4. Passphrase-protected key, per-repo credential options
  27. For HTTP tests, we need to run each GitPython test case in 2 different ways to
  28. cover pygit2 with authentication:
  29. 1. Global credential options
  30. 2. Per-repo credential options
  31. For unauthenticated HTTP, we can just run a single case just like for a
  32. GitPython test function, with the only change being to the git_pillar_provider
  33. config option.
  34. The way we accomplish the extra test cases for pygit2 is not by writing more
  35. test functions, but to keep the same test function names both in the GitPython
  36. test classes and the pygit2 test classes, and just perform multiple pillar
  37. compilations and asserts in each pygit2 test function.
  38. For SSH tests, a system user is added and a temporary sshd instance is started
  39. on a randomized port. The user and sshd server are torn down after the tests
  40. are run.
  41. For HTTP tests, nginx + uWSGI + git-http-backend handles serving the repo.
  42. However, there was a change in git 2.4.4 which causes a fetch to hang when
  43. using uWSGI. This was worked around in uWSGI 2.0.13 by adding an additional
  44. setting. However, Ubuntu 16.04 LTS ships with uWSGI 2.0.12 in their official
  45. repos, so to work around this we pip install a newer uWSGI (with CGI support
  46. baked in) within a virtualenv the test suite creates, and then uses that uwsgi
  47. binary to start the uWSGI daemon. More info on the git issue and the uWSGI
  48. workaround can be found in the below two links:
  49. https://github.com/git/git/commit/6bc0cb5
  50. https://github.com/unbit/uwsgi/commit/ac1e354
  51. """
  52. from __future__ import absolute_import, print_function, unicode_literals
  53. import random
  54. import string
  55. import pytest
  56. import salt.utils.path
  57. import salt.utils.platform
  58. from salt.ext.six.moves import range
  59. from salt.modules.virtualenv_mod import KNOWN_BINARY_NAMES as VIRTUALENV_NAMES
  60. from salt.utils.gitfs import (
  61. GITPYTHON_MINVER,
  62. GITPYTHON_VERSION,
  63. LIBGIT2_MINVER,
  64. LIBGIT2_VERSION,
  65. PYGIT2_MINVER,
  66. PYGIT2_VERSION,
  67. )
  68. from tests.support.gitfs import (
  69. PASSWORD,
  70. USERNAME,
  71. GitPillarHTTPTestBase,
  72. GitPillarSSHTestBase,
  73. )
  74. from tests.support.helpers import requires_system_grains
  75. from tests.support.unit import skipIf
  76. # Check for requisite components
  77. try:
  78. HAS_GITPYTHON = GITPYTHON_VERSION >= GITPYTHON_MINVER
  79. except Exception: # pylint: disable=broad-except
  80. HAS_GITPYTHON = False
  81. try:
  82. HAS_PYGIT2 = PYGIT2_VERSION >= PYGIT2_MINVER and LIBGIT2_VERSION >= LIBGIT2_MINVER
  83. except Exception: # pylint: disable=broad-except
  84. HAS_PYGIT2 = False
  85. HAS_SSHD = bool(salt.utils.path.which("sshd"))
  86. HAS_NGINX = bool(salt.utils.path.which("nginx"))
  87. HAS_VIRTUALENV = bool(salt.utils.path.which_bin(VIRTUALENV_NAMES))
  88. def _rand_key_name(length):
  89. return "id_rsa_{0}".format(
  90. "".join(random.choice(string.ascii_letters) for _ in range(length))
  91. )
  92. def _windows_or_mac():
  93. return salt.utils.platform.is_windows() or salt.utils.platform.is_darwin()
  94. class GitPythonMixin(object):
  95. """
  96. GitPython doesn't support anything fancy in terms of authentication
  97. options, so all of the tests for GitPython can be re-used via this mixin.
  98. """
  99. def test_single_source(self):
  100. """
  101. Test using a single ext_pillar repo
  102. """
  103. ret = self.get_pillar(
  104. """\
  105. file_ignore_regex: []
  106. file_ignore_glob: []
  107. git_pillar_provider: gitpython
  108. cachedir: {cachedir}
  109. extension_modules: {extmods}
  110. ext_pillar:
  111. - git:
  112. - master {url}
  113. """
  114. )
  115. self.assertEqual(
  116. ret,
  117. {
  118. "branch": "master",
  119. "mylist": ["master"],
  120. "mydict": {
  121. "master": True,
  122. "nested_list": ["master"],
  123. "nested_dict": {"master": True},
  124. },
  125. },
  126. )
  127. def test_multiple_sources_master_dev_no_merge_lists(self):
  128. """
  129. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  130. into a single dictionary, ordering matters.
  131. This tests with the master branch followed by dev, and with
  132. pillar_merge_lists disabled.
  133. """
  134. ret = self.get_pillar(
  135. """\
  136. file_ignore_regex: []
  137. file_ignore_glob: []
  138. git_pillar_provider: gitpython
  139. cachedir: {cachedir}
  140. extension_modules: {extmods}
  141. pillar_merge_lists: False
  142. ext_pillar:
  143. - git:
  144. - master {url}
  145. - dev {url}
  146. """
  147. )
  148. self.assertEqual(
  149. ret,
  150. {
  151. "branch": "dev",
  152. "mylist": ["dev"],
  153. "mydict": {
  154. "master": True,
  155. "dev": True,
  156. "nested_list": ["dev"],
  157. "nested_dict": {"master": True, "dev": True},
  158. },
  159. },
  160. )
  161. def test_multiple_sources_dev_master_no_merge_lists(self):
  162. """
  163. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  164. into a single dictionary, ordering matters.
  165. This tests with the dev branch followed by master, and with
  166. pillar_merge_lists disabled.
  167. """
  168. ret = self.get_pillar(
  169. """\
  170. file_ignore_regex: []
  171. file_ignore_glob: []
  172. git_pillar_provider: gitpython
  173. cachedir: {cachedir}
  174. extension_modules: {extmods}
  175. pillar_merge_lists: False
  176. ext_pillar:
  177. - git:
  178. - dev {url}
  179. - master {url}
  180. """
  181. )
  182. self.assertEqual(
  183. ret,
  184. {
  185. "branch": "master",
  186. "mylist": ["master"],
  187. "mydict": {
  188. "master": True,
  189. "dev": True,
  190. "nested_list": ["master"],
  191. "nested_dict": {"master": True, "dev": True},
  192. },
  193. },
  194. )
  195. def test_multiple_sources_master_dev_merge_lists(self):
  196. """
  197. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  198. into a single dictionary, ordering matters.
  199. This tests with the master branch followed by dev, and with
  200. pillar_merge_lists enabled.
  201. """
  202. ret = self.get_pillar(
  203. """\
  204. file_ignore_regex: []
  205. file_ignore_glob: []
  206. git_pillar_provider: gitpython
  207. cachedir: {cachedir}
  208. extension_modules: {extmods}
  209. pillar_merge_lists: True
  210. ext_pillar:
  211. - git:
  212. - master {url}
  213. - dev {url}
  214. """
  215. )
  216. self.assertEqual(
  217. ret,
  218. {
  219. "branch": "dev",
  220. "mylist": ["master", "dev"],
  221. "mydict": {
  222. "master": True,
  223. "dev": True,
  224. "nested_list": ["master", "dev"],
  225. "nested_dict": {"master": True, "dev": True},
  226. },
  227. },
  228. )
  229. def test_multiple_sources_dev_master_merge_lists(self):
  230. """
  231. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  232. into a single dictionary, ordering matters.
  233. This tests with the dev branch followed by master, and with
  234. pillar_merge_lists enabled.
  235. """
  236. ret = self.get_pillar(
  237. """\
  238. file_ignore_regex: []
  239. file_ignore_glob: []
  240. git_pillar_provider: gitpython
  241. cachedir: {cachedir}
  242. extension_modules: {extmods}
  243. pillar_merge_lists: True
  244. ext_pillar:
  245. - git:
  246. - dev {url}
  247. - master {url}
  248. """
  249. )
  250. self.assertEqual(
  251. ret,
  252. {
  253. "branch": "master",
  254. "mylist": ["dev", "master"],
  255. "mydict": {
  256. "master": True,
  257. "dev": True,
  258. "nested_list": ["dev", "master"],
  259. "nested_dict": {"master": True, "dev": True},
  260. },
  261. },
  262. )
  263. def test_multiple_sources_with_pillarenv(self):
  264. """
  265. Test using pillarenv to restrict results to those from a single branch
  266. """
  267. ret = self.get_pillar(
  268. """\
  269. file_ignore_regex: []
  270. file_ignore_glob: []
  271. git_pillar_provider: gitpython
  272. cachedir: {cachedir}
  273. extension_modules: {extmods}
  274. pillarenv: base
  275. ext_pillar:
  276. - git:
  277. - master {url}
  278. - dev {url}
  279. """
  280. )
  281. self.assertEqual(
  282. ret,
  283. {
  284. "branch": "master",
  285. "mylist": ["master"],
  286. "mydict": {
  287. "master": True,
  288. "nested_list": ["master"],
  289. "nested_dict": {"master": True},
  290. },
  291. },
  292. )
  293. def test_includes_enabled(self):
  294. """
  295. Test with git_pillar_includes enabled. The top_only branch references
  296. an SLS file from the master branch, so we should see the key from that
  297. SLS file (included_pillar) in the compiled pillar data.
  298. """
  299. ret = self.get_pillar(
  300. """\
  301. file_ignore_regex: []
  302. file_ignore_glob: []
  303. git_pillar_provider: gitpython
  304. cachedir: {cachedir}
  305. extension_modules: {extmods}
  306. ext_pillar:
  307. - git:
  308. - master {url}
  309. - top_only {url}:
  310. - env: base
  311. """
  312. )
  313. self.assertEqual(
  314. ret,
  315. {
  316. "branch": "master",
  317. "mylist": ["master"],
  318. "mydict": {
  319. "master": True,
  320. "nested_list": ["master"],
  321. "nested_dict": {"master": True},
  322. },
  323. "included_pillar": True,
  324. },
  325. )
  326. def test_includes_disabled(self):
  327. """
  328. Test with git_pillar_includes enabled. The top_only branch references
  329. an SLS file from the master branch, but since includes are disabled it
  330. will not find the SLS file and the "included_pillar" key should not be
  331. present in the compiled pillar data. We should instead see an error
  332. message in the compiled data.
  333. """
  334. ret = self.get_pillar(
  335. """\
  336. file_ignore_regex: []
  337. file_ignore_glob: []
  338. git_pillar_provider: gitpython
  339. git_pillar_includes: False
  340. cachedir: {cachedir}
  341. extension_modules: {extmods}
  342. ext_pillar:
  343. - git:
  344. - master {url}
  345. - top_only {url}:
  346. - env: base
  347. """
  348. )
  349. self.assertEqual(
  350. ret,
  351. {
  352. "branch": "master",
  353. "mylist": ["master"],
  354. "mydict": {
  355. "master": True,
  356. "nested_list": ["master"],
  357. "nested_dict": {"master": True},
  358. },
  359. "_errors": [
  360. "Specified SLS 'bar' in environment 'base' is not "
  361. "available on the salt master"
  362. ],
  363. },
  364. )
  365. def test_includes_enabled_solves___env___with_mountpoint(self):
  366. """
  367. Test with git_pillar_includes enabled and using "__env__" as the branch
  368. name for the configured repositories.
  369. The "gitinfo" repository contains top.sls file with a local reference
  370. and also referencing external "nowhere.foo" which is provided by "webinfo"
  371. repository mounted as "nowhere".
  372. """
  373. ret = self.get_pillar(
  374. """\
  375. file_ignore_regex: []
  376. file_ignore_glob: []
  377. git_pillar_provider: gitpython
  378. cachedir: {cachedir}
  379. extension_modules: {extmods}
  380. ext_pillar:
  381. - git:
  382. - __env__ {url_extra_repo}:
  383. - name: gitinfo
  384. - __env__ {url}:
  385. - name: webinfo
  386. - mountpoint: nowhere
  387. """
  388. )
  389. self.assertEqual(
  390. ret,
  391. {
  392. "branch": "master",
  393. "motd": "The force will be with you. Always.",
  394. "mylist": ["master"],
  395. "mydict": {
  396. "master": True,
  397. "nested_list": ["master"],
  398. "nested_dict": {"master": True},
  399. },
  400. },
  401. )
  402. def test_root_parameter(self):
  403. """
  404. Test root parameter
  405. """
  406. expected = {"from_subdir": True}
  407. ret = self.get_pillar(
  408. """\
  409. file_ignore_regex: []
  410. file_ignore_glob: []
  411. git_pillar_provider: gitpython
  412. cachedir: {cachedir}
  413. extension_modules: {extmods}
  414. ext_pillar:
  415. - git:
  416. - master {url}:
  417. - root: subdir
  418. - top_only {url}:
  419. - env: base
  420. """
  421. )
  422. self.assertEqual(ret, expected)
  423. def test_mountpoint_parameter(self):
  424. """
  425. Test mountpoint parameter
  426. """
  427. expected = {"included_pillar": True}
  428. ret = self.get_pillar(
  429. """\
  430. file_ignore_regex: []
  431. file_ignore_glob: []
  432. git_pillar_provider: gitpython
  433. cachedir: {cachedir}
  434. extension_modules: {extmods}
  435. ext_pillar:
  436. - git:
  437. - master {url}:
  438. - mountpoint: mounted
  439. - top_mounted {url}:
  440. - env: base
  441. """
  442. )
  443. self.assertEqual(ret, expected)
  444. def test_root_and_mountpoint_parameters(self):
  445. """
  446. Test root and mountpoint parameters
  447. """
  448. expected = {"from_subdir": True}
  449. ret = self.get_pillar(
  450. """\
  451. file_ignore_regex: []
  452. file_ignore_glob: []
  453. git_pillar_provider: gitpython
  454. cachedir: {cachedir}
  455. extension_modules: {extmods}
  456. ext_pillar:
  457. - git:
  458. - master {url}:
  459. - mountpoint: mounted
  460. - root: subdir
  461. - top_mounted {url}:
  462. - env: base
  463. """
  464. )
  465. self.assertEqual(ret, expected)
  466. def test_all_saltenvs(self):
  467. """
  468. Test all_saltenvs parameter.
  469. """
  470. ret = self.get_pillar(
  471. """\
  472. file_ignore_regex: []
  473. file_ignore_glob: []
  474. git_pillar_provider: gitpython
  475. cachedir: {cachedir}
  476. extension_modules: {extmods}
  477. pillarenv: dev
  478. ext_pillar:
  479. - git:
  480. - __env__ {url_extra_repo}:
  481. - all_saltenvs: master
  482. - __env__ {url}:
  483. - mountpoint: nowhere
  484. """
  485. )
  486. self.assertEqual(
  487. ret,
  488. {
  489. "branch": "dev",
  490. "motd": "The force will be with you. Always.",
  491. "mylist": ["dev"],
  492. "mydict": {
  493. "dev": True,
  494. "nested_list": ["dev"],
  495. "nested_dict": {"dev": True},
  496. },
  497. },
  498. )
  499. def test_all_saltenvs_base(self):
  500. """
  501. Test all_saltenvs parameter with base pillarenv.
  502. """
  503. ret = self.get_pillar(
  504. """\
  505. file_ignore_regex: []
  506. file_ignore_glob: []
  507. git_pillar_provider: gitpython
  508. cachedir: {cachedir}
  509. extension_modules: {extmods}
  510. ext_pillar:
  511. - git:
  512. - __env__ {url_extra_repo}:
  513. - all_saltenvs: master
  514. - __env__ {url}:
  515. - mountpoint: nowhere
  516. """
  517. )
  518. self.assertEqual(
  519. ret,
  520. {
  521. "branch": "master",
  522. "motd": "The force will be with you. Always.",
  523. "mylist": ["master"],
  524. "mydict": {
  525. "master": True,
  526. "nested_list": ["master"],
  527. "nested_dict": {"master": True},
  528. },
  529. },
  530. )
  531. def test_fallback(self):
  532. """
  533. Test fallback parameter.
  534. """
  535. ret = self.get_pillar(
  536. """\
  537. file_ignore_regex: []
  538. file_ignore_glob: []
  539. git_pillar_provider: gitpython
  540. cachedir: {cachedir}
  541. extension_modules: {extmods}
  542. pillarenv: nonexisting
  543. ext_pillar:
  544. - git:
  545. - __env__ {url_extra_repo}:
  546. - fallback: master
  547. - __env__ {url}:
  548. - mountpoint: nowhere
  549. - fallback: dev
  550. """
  551. )
  552. self.assertEqual(
  553. ret,
  554. {
  555. "branch": "dev",
  556. "motd": "The force will be with you. Always.",
  557. "mylist": ["dev"],
  558. "mydict": {
  559. "dev": True,
  560. "nested_list": ["dev"],
  561. "nested_dict": {"dev": True},
  562. },
  563. },
  564. )
  565. @skipIf(_windows_or_mac(), "minion is windows or mac")
  566. @pytest.mark.skip_if_not_root
  567. @pytest.mark.destructive_test
  568. @skipIf(not HAS_GITPYTHON, "GitPython >= {0} required".format(GITPYTHON_MINVER))
  569. @skipIf(not HAS_SSHD, "sshd not present")
  570. class TestGitPythonSSH(GitPillarSSHTestBase, GitPythonMixin):
  571. """
  572. Test git_pillar with GitPython using SSH authentication
  573. """
  574. id_rsa_nopass = _rand_key_name(8)
  575. id_rsa_withpass = _rand_key_name(8)
  576. username = USERNAME
  577. passphrase = PASSWORD
  578. @skipIf(_windows_or_mac(), "minion is windows or mac")
  579. @pytest.mark.skip_if_not_root
  580. @skipIf(not HAS_GITPYTHON, "GitPython >= {0} required".format(GITPYTHON_MINVER))
  581. @skipIf(not HAS_NGINX, "nginx not present")
  582. @skipIf(not HAS_VIRTUALENV, "virtualenv not present")
  583. class TestGitPythonHTTP(GitPillarHTTPTestBase, GitPythonMixin):
  584. """
  585. Test git_pillar with GitPython using unauthenticated HTTP
  586. """
  587. @skipIf(_windows_or_mac(), "minion is windows or mac")
  588. @pytest.mark.skip_if_not_root
  589. @skipIf(not HAS_GITPYTHON, "GitPython >= {0} required".format(GITPYTHON_MINVER))
  590. @skipIf(not HAS_NGINX, "nginx not present")
  591. @skipIf(not HAS_VIRTUALENV, "virtualenv not present")
  592. class TestGitPythonAuthenticatedHTTP(TestGitPythonHTTP, GitPythonMixin):
  593. """
  594. Test git_pillar with GitPython using authenticated HTTP
  595. """
  596. username = USERNAME
  597. password = PASSWORD
  598. @classmethod
  599. def setUpClass(cls):
  600. """
  601. Create start the webserver
  602. """
  603. super(TestGitPythonAuthenticatedHTTP, cls).setUpClass()
  604. # Override the URL set up in the parent class to encode the
  605. # username/password into it.
  606. cls.url = "http://{username}:{password}@127.0.0.1:{port}/repo.git".format(
  607. username=cls.username, password=cls.password, port=cls.nginx_port
  608. )
  609. cls.url_extra_repo = "http://{username}:{password}@127.0.0.1:{port}/extra_repo.git".format(
  610. username=cls.username, password=cls.password, port=cls.nginx_port
  611. )
  612. cls.ext_opts["url"] = cls.url
  613. cls.ext_opts["url_extra_repo"] = cls.url_extra_repo
  614. cls.ext_opts["username"] = cls.username
  615. cls.ext_opts["password"] = cls.password
  616. @skipIf(_windows_or_mac(), "minion is windows or mac")
  617. @pytest.mark.skip_if_not_root
  618. @pytest.mark.destructive_test
  619. @skipIf(
  620. not HAS_PYGIT2,
  621. "pygit2 >= {0} and libgit2 >= {1} required".format(PYGIT2_MINVER, LIBGIT2_MINVER),
  622. )
  623. @skipIf(not HAS_SSHD, "sshd not present")
  624. class TestPygit2SSH(GitPillarSSHTestBase):
  625. """
  626. Test git_pillar with pygit2 using SSH authentication
  627. NOTE: Any tests added to this test class should have equivalent tests (if
  628. possible) in the TestGitPythonSSH class.
  629. """
  630. id_rsa_nopass = _rand_key_name(8)
  631. id_rsa_withpass = _rand_key_name(8)
  632. username = USERNAME
  633. passphrase = PASSWORD
  634. @requires_system_grains
  635. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  636. def test_single_source(self, grains):
  637. """
  638. Test using a single ext_pillar repo
  639. """
  640. expected = {
  641. "branch": "master",
  642. "mylist": ["master"],
  643. "mydict": {
  644. "master": True,
  645. "nested_list": ["master"],
  646. "nested_dict": {"master": True},
  647. },
  648. }
  649. # Test with passphraseless key and global credential options
  650. ret = self.get_pillar(
  651. """\
  652. file_ignore_regex: []
  653. file_ignore_glob: []
  654. git_pillar_provider: pygit2
  655. git_pillar_pubkey: {pubkey_nopass}
  656. git_pillar_privkey: {privkey_nopass}
  657. cachedir: {cachedir}
  658. extension_modules: {extmods}
  659. ext_pillar:
  660. - git:
  661. - master {url}
  662. """
  663. )
  664. self.assertEqual(ret, expected)
  665. # Test with passphraseless key and per-repo credential options
  666. ret = self.get_pillar(
  667. """\
  668. file_ignore_regex: []
  669. file_ignore_glob: []
  670. git_pillar_provider: pygit2
  671. cachedir: {cachedir}
  672. extension_modules: {extmods}
  673. ext_pillar:
  674. - git:
  675. - master {url}:
  676. - pubkey: {pubkey_nopass}
  677. - privkey: {privkey_nopass}
  678. """
  679. )
  680. self.assertEqual(ret, expected)
  681. if grains["os_family"] == "Debian":
  682. # passphrase-protected currently does not work here
  683. return
  684. # Test with passphrase-protected key and global credential options
  685. ret = self.get_pillar(
  686. """\
  687. file_ignore_regex: []
  688. file_ignore_glob: []
  689. git_pillar_provider: pygit2
  690. git_pillar_pubkey: {pubkey_withpass}
  691. git_pillar_privkey: {privkey_withpass}
  692. git_pillar_passphrase: {passphrase}
  693. cachedir: {cachedir}
  694. extension_modules: {extmods}
  695. ext_pillar:
  696. - git:
  697. - master {url}
  698. """
  699. )
  700. self.assertEqual(ret, expected)
  701. # Test with passphrase-protected key and per-repo credential options
  702. ret = self.get_pillar(
  703. """\
  704. file_ignore_regex: []
  705. file_ignore_glob: []
  706. git_pillar_provider: pygit2
  707. cachedir: {cachedir}
  708. extension_modules: {extmods}
  709. ext_pillar:
  710. - git:
  711. - master {url}:
  712. - pubkey: {pubkey_withpass}
  713. - privkey: {privkey_withpass}
  714. - passphrase: {passphrase}
  715. """
  716. )
  717. self.assertEqual(ret, expected)
  718. @requires_system_grains
  719. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  720. def test_multiple_sources_master_dev_no_merge_lists(self, grains):
  721. """
  722. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  723. into a single dictionary, ordering matters.
  724. This tests with the master branch followed by dev, and with
  725. pillar_merge_lists disabled.
  726. """
  727. expected = {
  728. "branch": "dev",
  729. "mylist": ["dev"],
  730. "mydict": {
  731. "master": True,
  732. "dev": True,
  733. "nested_list": ["dev"],
  734. "nested_dict": {"master": True, "dev": True},
  735. },
  736. }
  737. # Test with passphraseless key and global credential options
  738. ret = self.get_pillar(
  739. """\
  740. file_ignore_regex: []
  741. file_ignore_glob: []
  742. git_pillar_provider: pygit2
  743. git_pillar_pubkey: {pubkey_nopass}
  744. git_pillar_privkey: {privkey_nopass}
  745. cachedir: {cachedir}
  746. extension_modules: {extmods}
  747. pillar_merge_lists: False
  748. ext_pillar:
  749. - git:
  750. - master {url}
  751. - dev {url}
  752. """
  753. )
  754. self.assertEqual(ret, expected)
  755. # Test with passphraseless key and per-repo credential options
  756. ret = self.get_pillar(
  757. """\
  758. file_ignore_regex: []
  759. file_ignore_glob: []
  760. git_pillar_provider: pygit2
  761. cachedir: {cachedir}
  762. extension_modules: {extmods}
  763. pillar_merge_lists: False
  764. ext_pillar:
  765. - git:
  766. - master {url}:
  767. - pubkey: {pubkey_nopass}
  768. - privkey: {privkey_nopass}
  769. - dev {url}:
  770. - pubkey: {pubkey_nopass}
  771. - privkey: {privkey_nopass}
  772. """
  773. )
  774. self.assertEqual(ret, expected)
  775. if grains["os_family"] == "Debian":
  776. # passphrase-protected currently does not work here
  777. return
  778. # Test with passphrase-protected key and global credential options
  779. ret = self.get_pillar(
  780. """\
  781. file_ignore_regex: []
  782. file_ignore_glob: []
  783. git_pillar_provider: pygit2
  784. git_pillar_pubkey: {pubkey_withpass}
  785. git_pillar_privkey: {privkey_withpass}
  786. git_pillar_passphrase: {passphrase}
  787. cachedir: {cachedir}
  788. extension_modules: {extmods}
  789. pillar_merge_lists: False
  790. ext_pillar:
  791. - git:
  792. - master {url}
  793. - dev {url}
  794. """
  795. )
  796. self.assertEqual(ret, expected)
  797. # Test with passphrase-protected key and per-repo credential options
  798. ret = self.get_pillar(
  799. """\
  800. file_ignore_regex: []
  801. file_ignore_glob: []
  802. git_pillar_provider: pygit2
  803. cachedir: {cachedir}
  804. extension_modules: {extmods}
  805. pillar_merge_lists: False
  806. ext_pillar:
  807. - git:
  808. - master {url}:
  809. - pubkey: {pubkey_withpass}
  810. - privkey: {privkey_withpass}
  811. - passphrase: {passphrase}
  812. - dev {url}:
  813. - pubkey: {pubkey_withpass}
  814. - privkey: {privkey_withpass}
  815. - passphrase: {passphrase}
  816. """
  817. )
  818. self.assertEqual(ret, expected)
  819. @requires_system_grains
  820. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  821. def test_multiple_sources_dev_master_no_merge_lists(self, grains):
  822. """
  823. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  824. into a single dictionary, ordering matters.
  825. This tests with the dev branch followed by master, and with
  826. pillar_merge_lists disabled.
  827. """
  828. expected = {
  829. "branch": "master",
  830. "mylist": ["master"],
  831. "mydict": {
  832. "master": True,
  833. "dev": True,
  834. "nested_list": ["master"],
  835. "nested_dict": {"master": True, "dev": True},
  836. },
  837. }
  838. # Test with passphraseless key and global credential options
  839. ret = self.get_pillar(
  840. """\
  841. file_ignore_regex: []
  842. file_ignore_glob: []
  843. git_pillar_provider: pygit2
  844. git_pillar_pubkey: {pubkey_nopass}
  845. git_pillar_privkey: {privkey_nopass}
  846. cachedir: {cachedir}
  847. extension_modules: {extmods}
  848. pillar_merge_lists: False
  849. ext_pillar:
  850. - git:
  851. - dev {url}
  852. - master {url}
  853. """
  854. )
  855. self.assertEqual(ret, expected)
  856. # Test with passphraseless key and per-repo credential options
  857. ret = self.get_pillar(
  858. """\
  859. file_ignore_regex: []
  860. file_ignore_glob: []
  861. git_pillar_provider: pygit2
  862. cachedir: {cachedir}
  863. extension_modules: {extmods}
  864. pillar_merge_lists: False
  865. ext_pillar:
  866. - git:
  867. - dev {url}:
  868. - pubkey: {pubkey_nopass}
  869. - privkey: {privkey_nopass}
  870. - master {url}:
  871. - pubkey: {pubkey_nopass}
  872. - privkey: {privkey_nopass}
  873. """
  874. )
  875. self.assertEqual(ret, expected)
  876. if grains["os_family"] == "Debian":
  877. # passphrase-protected currently does not work here
  878. return
  879. # Test with passphrase-protected key and global credential options
  880. ret = self.get_pillar(
  881. """\
  882. file_ignore_regex: []
  883. file_ignore_glob: []
  884. git_pillar_provider: pygit2
  885. git_pillar_pubkey: {pubkey_withpass}
  886. git_pillar_privkey: {privkey_withpass}
  887. git_pillar_passphrase: {passphrase}
  888. cachedir: {cachedir}
  889. extension_modules: {extmods}
  890. pillar_merge_lists: False
  891. ext_pillar:
  892. - git:
  893. - dev {url}
  894. - master {url}
  895. """
  896. )
  897. self.assertEqual(ret, expected)
  898. # Test with passphrase-protected key and per-repo credential options
  899. ret = self.get_pillar(
  900. """\
  901. file_ignore_regex: []
  902. file_ignore_glob: []
  903. git_pillar_provider: pygit2
  904. cachedir: {cachedir}
  905. extension_modules: {extmods}
  906. pillar_merge_lists: False
  907. ext_pillar:
  908. - git:
  909. - dev {url}:
  910. - pubkey: {pubkey_withpass}
  911. - privkey: {privkey_withpass}
  912. - passphrase: {passphrase}
  913. - master {url}:
  914. - pubkey: {pubkey_withpass}
  915. - privkey: {privkey_withpass}
  916. - passphrase: {passphrase}
  917. """
  918. )
  919. self.assertEqual(ret, expected)
  920. @requires_system_grains
  921. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  922. def test_multiple_sources_master_dev_merge_lists(self, grains):
  923. """
  924. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  925. into a single dictionary, ordering matters.
  926. This tests with the master branch followed by dev, and with
  927. pillar_merge_lists enabled.
  928. """
  929. expected = {
  930. "branch": "dev",
  931. "mylist": ["master", "dev"],
  932. "mydict": {
  933. "master": True,
  934. "dev": True,
  935. "nested_list": ["master", "dev"],
  936. "nested_dict": {"master": True, "dev": True},
  937. },
  938. }
  939. # Test with passphraseless key and global credential options
  940. ret = self.get_pillar(
  941. """\
  942. file_ignore_regex: []
  943. file_ignore_glob: []
  944. git_pillar_provider: pygit2
  945. git_pillar_pubkey: {pubkey_nopass}
  946. git_pillar_privkey: {privkey_nopass}
  947. cachedir: {cachedir}
  948. extension_modules: {extmods}
  949. pillar_merge_lists: True
  950. ext_pillar:
  951. - git:
  952. - master {url}
  953. - dev {url}
  954. """
  955. )
  956. self.assertEqual(ret, expected)
  957. # Test with passphraseless key and per-repo credential options
  958. ret = self.get_pillar(
  959. """\
  960. file_ignore_regex: []
  961. file_ignore_glob: []
  962. git_pillar_provider: pygit2
  963. cachedir: {cachedir}
  964. extension_modules: {extmods}
  965. pillar_merge_lists: True
  966. ext_pillar:
  967. - git:
  968. - master {url}:
  969. - pubkey: {pubkey_nopass}
  970. - privkey: {privkey_nopass}
  971. - dev {url}:
  972. - pubkey: {pubkey_nopass}
  973. - privkey: {privkey_nopass}
  974. """
  975. )
  976. self.assertEqual(ret, expected)
  977. if grains["os_family"] == "Debian":
  978. # passphrase-protected currently does not work here
  979. return
  980. # Test with passphrase-protected key and global credential options
  981. ret = self.get_pillar(
  982. """\
  983. file_ignore_regex: []
  984. file_ignore_glob: []
  985. git_pillar_provider: pygit2
  986. git_pillar_pubkey: {pubkey_withpass}
  987. git_pillar_privkey: {privkey_withpass}
  988. git_pillar_passphrase: {passphrase}
  989. cachedir: {cachedir}
  990. extension_modules: {extmods}
  991. pillar_merge_lists: True
  992. ext_pillar:
  993. - git:
  994. - master {url}
  995. - dev {url}
  996. """
  997. )
  998. self.assertEqual(ret, expected)
  999. # Test with passphrase-protected key and per-repo credential options
  1000. ret = self.get_pillar(
  1001. """\
  1002. file_ignore_regex: []
  1003. file_ignore_glob: []
  1004. git_pillar_provider: pygit2
  1005. cachedir: {cachedir}
  1006. extension_modules: {extmods}
  1007. pillar_merge_lists: True
  1008. ext_pillar:
  1009. - git:
  1010. - master {url}:
  1011. - pubkey: {pubkey_withpass}
  1012. - privkey: {privkey_withpass}
  1013. - passphrase: {passphrase}
  1014. - dev {url}:
  1015. - pubkey: {pubkey_withpass}
  1016. - privkey: {privkey_withpass}
  1017. - passphrase: {passphrase}
  1018. """
  1019. )
  1020. self.assertEqual(ret, expected)
  1021. @requires_system_grains
  1022. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  1023. def test_multiple_sources_dev_master_merge_lists(self, grains):
  1024. """
  1025. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  1026. into a single dictionary, ordering matters.
  1027. This tests with the dev branch followed by master, and with
  1028. pillar_merge_lists enabled.
  1029. """
  1030. expected = {
  1031. "branch": "master",
  1032. "mylist": ["dev", "master"],
  1033. "mydict": {
  1034. "master": True,
  1035. "dev": True,
  1036. "nested_list": ["dev", "master"],
  1037. "nested_dict": {"master": True, "dev": True},
  1038. },
  1039. }
  1040. # Test with passphraseless key and global credential options
  1041. ret = self.get_pillar(
  1042. """\
  1043. file_ignore_regex: []
  1044. file_ignore_glob: []
  1045. git_pillar_provider: pygit2
  1046. git_pillar_pubkey: {pubkey_nopass}
  1047. git_pillar_privkey: {privkey_nopass}
  1048. cachedir: {cachedir}
  1049. extension_modules: {extmods}
  1050. pillar_merge_lists: True
  1051. ext_pillar:
  1052. - git:
  1053. - dev {url}
  1054. - master {url}
  1055. """
  1056. )
  1057. self.assertEqual(ret, expected)
  1058. # Test with passphraseless key and per-repo credential options
  1059. ret = self.get_pillar(
  1060. """\
  1061. file_ignore_regex: []
  1062. file_ignore_glob: []
  1063. git_pillar_provider: pygit2
  1064. cachedir: {cachedir}
  1065. extension_modules: {extmods}
  1066. pillar_merge_lists: True
  1067. ext_pillar:
  1068. - git:
  1069. - dev {url}:
  1070. - pubkey: {pubkey_nopass}
  1071. - privkey: {privkey_nopass}
  1072. - master {url}:
  1073. - pubkey: {pubkey_nopass}
  1074. - privkey: {privkey_nopass}
  1075. """
  1076. )
  1077. self.assertEqual(ret, expected)
  1078. if grains["os_family"] == "Debian":
  1079. # passphrase-protected currently does not work here
  1080. return
  1081. # Test with passphrase-protected key and global credential options
  1082. ret = self.get_pillar(
  1083. """\
  1084. file_ignore_regex: []
  1085. file_ignore_glob: []
  1086. git_pillar_provider: pygit2
  1087. git_pillar_pubkey: {pubkey_withpass}
  1088. git_pillar_privkey: {privkey_withpass}
  1089. git_pillar_passphrase: {passphrase}
  1090. cachedir: {cachedir}
  1091. extension_modules: {extmods}
  1092. pillar_merge_lists: True
  1093. ext_pillar:
  1094. - git:
  1095. - dev {url}
  1096. - master {url}
  1097. """
  1098. )
  1099. self.assertEqual(ret, expected)
  1100. # Test with passphrase-protected key and per-repo credential options
  1101. ret = self.get_pillar(
  1102. """\
  1103. file_ignore_regex: []
  1104. file_ignore_glob: []
  1105. git_pillar_provider: pygit2
  1106. cachedir: {cachedir}
  1107. extension_modules: {extmods}
  1108. pillar_merge_lists: True
  1109. ext_pillar:
  1110. - git:
  1111. - dev {url}:
  1112. - pubkey: {pubkey_withpass}
  1113. - privkey: {privkey_withpass}
  1114. - passphrase: {passphrase}
  1115. - master {url}:
  1116. - pubkey: {pubkey_withpass}
  1117. - privkey: {privkey_withpass}
  1118. - passphrase: {passphrase}
  1119. """
  1120. )
  1121. self.assertEqual(ret, expected)
  1122. @requires_system_grains
  1123. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  1124. def test_multiple_sources_with_pillarenv(self, grains):
  1125. """
  1126. Test using pillarenv to restrict results to those from a single branch
  1127. """
  1128. expected = {
  1129. "branch": "master",
  1130. "mylist": ["master"],
  1131. "mydict": {
  1132. "master": True,
  1133. "nested_list": ["master"],
  1134. "nested_dict": {"master": True},
  1135. },
  1136. }
  1137. # Test with passphraseless key and global credential options
  1138. ret = self.get_pillar(
  1139. """\
  1140. file_ignore_regex: []
  1141. file_ignore_glob: []
  1142. git_pillar_provider: pygit2
  1143. git_pillar_pubkey: {pubkey_nopass}
  1144. git_pillar_privkey: {privkey_nopass}
  1145. cachedir: {cachedir}
  1146. extension_modules: {extmods}
  1147. pillarenv: base
  1148. ext_pillar:
  1149. - git:
  1150. - master {url}
  1151. - dev {url}
  1152. """
  1153. )
  1154. self.assertEqual(ret, expected)
  1155. # Test with passphraseless key and per-repo credential options
  1156. ret = self.get_pillar(
  1157. """\
  1158. file_ignore_regex: []
  1159. file_ignore_glob: []
  1160. git_pillar_provider: pygit2
  1161. cachedir: {cachedir}
  1162. extension_modules: {extmods}
  1163. pillarenv: base
  1164. ext_pillar:
  1165. - git:
  1166. - master {url}:
  1167. - pubkey: {pubkey_nopass}
  1168. - privkey: {privkey_nopass}
  1169. - dev {url}:
  1170. - pubkey: {pubkey_nopass}
  1171. - privkey: {privkey_nopass}
  1172. """
  1173. )
  1174. self.assertEqual(ret, expected)
  1175. if grains["os_family"] == "Debian":
  1176. # passphrase-protected currently does not work here
  1177. return
  1178. # Test with passphrase-protected key and global credential options
  1179. ret = self.get_pillar(
  1180. """\
  1181. file_ignore_regex: []
  1182. file_ignore_glob: []
  1183. git_pillar_provider: pygit2
  1184. git_pillar_pubkey: {pubkey_withpass}
  1185. git_pillar_privkey: {privkey_withpass}
  1186. git_pillar_passphrase: {passphrase}
  1187. cachedir: {cachedir}
  1188. extension_modules: {extmods}
  1189. pillarenv: base
  1190. ext_pillar:
  1191. - git:
  1192. - master {url}
  1193. - dev {url}
  1194. """
  1195. )
  1196. self.assertEqual(ret, expected)
  1197. # Test with passphrase-protected key and per-repo credential options
  1198. ret = self.get_pillar(
  1199. """\
  1200. file_ignore_regex: []
  1201. file_ignore_glob: []
  1202. git_pillar_provider: pygit2
  1203. cachedir: {cachedir}
  1204. extension_modules: {extmods}
  1205. pillarenv: base
  1206. ext_pillar:
  1207. - git:
  1208. - master {url}:
  1209. - pubkey: {pubkey_withpass}
  1210. - privkey: {privkey_withpass}
  1211. - passphrase: {passphrase}
  1212. - dev {url}:
  1213. - pubkey: {pubkey_nopass}
  1214. - privkey: {privkey_nopass}
  1215. - passphrase: {passphrase}
  1216. """
  1217. )
  1218. self.assertEqual(ret, expected)
  1219. @requires_system_grains
  1220. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  1221. def test_includes_enabled(self, grains):
  1222. """
  1223. Test with git_pillar_includes enabled. The top_only branch references
  1224. an SLS file from the master branch, so we should see the
  1225. "included_pillar" key from that SLS file in the compiled pillar data.
  1226. """
  1227. expected = {
  1228. "branch": "master",
  1229. "mylist": ["master"],
  1230. "mydict": {
  1231. "master": True,
  1232. "nested_list": ["master"],
  1233. "nested_dict": {"master": True},
  1234. },
  1235. "included_pillar": True,
  1236. }
  1237. # Test with passphraseless key and global credential options
  1238. ret = self.get_pillar(
  1239. """\
  1240. file_ignore_regex: []
  1241. file_ignore_glob: []
  1242. git_pillar_provider: pygit2
  1243. git_pillar_pubkey: {pubkey_nopass}
  1244. git_pillar_privkey: {privkey_nopass}
  1245. cachedir: {cachedir}
  1246. extension_modules: {extmods}
  1247. ext_pillar:
  1248. - git:
  1249. - master {url}
  1250. - top_only {url}:
  1251. - env: base
  1252. """
  1253. )
  1254. self.assertEqual(ret, expected)
  1255. # Test with passphraseless key and per-repo credential options
  1256. ret = self.get_pillar(
  1257. """\
  1258. file_ignore_regex: []
  1259. file_ignore_glob: []
  1260. git_pillar_provider: pygit2
  1261. cachedir: {cachedir}
  1262. extension_modules: {extmods}
  1263. ext_pillar:
  1264. - git:
  1265. - master {url}:
  1266. - pubkey: {pubkey_nopass}
  1267. - privkey: {privkey_nopass}
  1268. - top_only {url}:
  1269. - pubkey: {pubkey_nopass}
  1270. - privkey: {privkey_nopass}
  1271. - env: base
  1272. """
  1273. )
  1274. self.assertEqual(ret, expected)
  1275. if grains["os_family"] == "Debian":
  1276. # passphrase-protected currently does not work here
  1277. return
  1278. # Test with passphrase-protected key and global credential options
  1279. ret = self.get_pillar(
  1280. """\
  1281. file_ignore_regex: []
  1282. file_ignore_glob: []
  1283. git_pillar_provider: pygit2
  1284. git_pillar_pubkey: {pubkey_withpass}
  1285. git_pillar_privkey: {privkey_withpass}
  1286. git_pillar_passphrase: {passphrase}
  1287. cachedir: {cachedir}
  1288. extension_modules: {extmods}
  1289. ext_pillar:
  1290. - git:
  1291. - master {url}
  1292. - top_only {url}:
  1293. - env: base
  1294. """
  1295. )
  1296. self.assertEqual(ret, expected)
  1297. # Test with passphrase-protected key and per-repo credential options
  1298. ret = self.get_pillar(
  1299. """\
  1300. file_ignore_regex: []
  1301. file_ignore_glob: []
  1302. git_pillar_provider: pygit2
  1303. cachedir: {cachedir}
  1304. extension_modules: {extmods}
  1305. ext_pillar:
  1306. - git:
  1307. - master {url}:
  1308. - pubkey: {pubkey_withpass}
  1309. - privkey: {privkey_withpass}
  1310. - passphrase: {passphrase}
  1311. - top_only {url}:
  1312. - pubkey: {pubkey_withpass}
  1313. - privkey: {privkey_withpass}
  1314. - passphrase: {passphrase}
  1315. - env: base
  1316. """
  1317. )
  1318. self.assertEqual(ret, expected)
  1319. @requires_system_grains
  1320. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  1321. def test_includes_disabled(self, grains):
  1322. """
  1323. Test with git_pillar_includes enabled. The top_only branch references
  1324. an SLS file from the master branch, but since includes are disabled it
  1325. will not find the SLS file and the "included_pillar" key should not be
  1326. present in the compiled pillar data. We should instead see an error
  1327. message in the compiled data.
  1328. """
  1329. expected = {
  1330. "branch": "master",
  1331. "mylist": ["master"],
  1332. "mydict": {
  1333. "master": True,
  1334. "nested_list": ["master"],
  1335. "nested_dict": {"master": True},
  1336. },
  1337. "_errors": [
  1338. "Specified SLS 'bar' in environment 'base' is not "
  1339. "available on the salt master"
  1340. ],
  1341. }
  1342. # Test with passphraseless key and global credential options
  1343. ret = self.get_pillar(
  1344. """\
  1345. file_ignore_regex: []
  1346. file_ignore_glob: []
  1347. git_pillar_provider: pygit2
  1348. git_pillar_includes: False
  1349. git_pillar_pubkey: {pubkey_nopass}
  1350. git_pillar_privkey: {privkey_nopass}
  1351. cachedir: {cachedir}
  1352. extension_modules: {extmods}
  1353. ext_pillar:
  1354. - git:
  1355. - master {url}
  1356. - top_only {url}:
  1357. - env: base
  1358. """
  1359. )
  1360. self.assertEqual(ret, expected)
  1361. # Test with passphraseless key and per-repo credential options
  1362. ret = self.get_pillar(
  1363. """\
  1364. file_ignore_regex: []
  1365. file_ignore_glob: []
  1366. git_pillar_provider: pygit2
  1367. git_pillar_includes: False
  1368. cachedir: {cachedir}
  1369. extension_modules: {extmods}
  1370. ext_pillar:
  1371. - git:
  1372. - master {url}:
  1373. - pubkey: {pubkey_nopass}
  1374. - privkey: {privkey_nopass}
  1375. - top_only {url}:
  1376. - pubkey: {pubkey_nopass}
  1377. - privkey: {privkey_nopass}
  1378. - env: base
  1379. """
  1380. )
  1381. self.assertEqual(ret, expected)
  1382. if grains["os_family"] == "Debian":
  1383. # passphrase-protected currently does not work here
  1384. return
  1385. # Test with passphrase-protected key and global credential options
  1386. ret = self.get_pillar(
  1387. """\
  1388. file_ignore_regex: []
  1389. file_ignore_glob: []
  1390. git_pillar_provider: pygit2
  1391. git_pillar_includes: False
  1392. git_pillar_pubkey: {pubkey_withpass}
  1393. git_pillar_privkey: {privkey_withpass}
  1394. git_pillar_passphrase: {passphrase}
  1395. cachedir: {cachedir}
  1396. extension_modules: {extmods}
  1397. ext_pillar:
  1398. - git:
  1399. - master {url}
  1400. - top_only {url}:
  1401. - env: base
  1402. """
  1403. )
  1404. self.assertEqual(ret, expected)
  1405. # Test with passphrase-protected key and per-repo credential options
  1406. ret = self.get_pillar(
  1407. """\
  1408. file_ignore_regex: []
  1409. file_ignore_glob: []
  1410. git_pillar_provider: pygit2
  1411. git_pillar_includes: False
  1412. cachedir: {cachedir}
  1413. extension_modules: {extmods}
  1414. ext_pillar:
  1415. - git:
  1416. - master {url}:
  1417. - pubkey: {pubkey_withpass}
  1418. - privkey: {privkey_withpass}
  1419. - passphrase: {passphrase}
  1420. - top_only {url}:
  1421. - pubkey: {pubkey_withpass}
  1422. - privkey: {privkey_withpass}
  1423. - passphrase: {passphrase}
  1424. - env: base
  1425. """
  1426. )
  1427. self.assertEqual(ret, expected)
  1428. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  1429. def test_includes_enabled_solves___env___with_mountpoint(self):
  1430. """
  1431. Test with git_pillar_includes enabled and using "__env__" as the branch
  1432. name for the configured repositories.
  1433. The "gitinfo" repository contains top.sls file with a local reference
  1434. and also referencing external "nowhere.foo" which is provided by "webinfo"
  1435. repository mounted as "nowhere".
  1436. """
  1437. ret = self.get_pillar(
  1438. """\
  1439. file_ignore_regex: []
  1440. file_ignore_glob: []
  1441. git_pillar_provider: pygit2
  1442. git_pillar_pubkey: {pubkey_nopass}
  1443. git_pillar_privkey: {privkey_nopass}
  1444. cachedir: {cachedir}
  1445. extension_modules: {extmods}
  1446. ext_pillar:
  1447. - git:
  1448. - __env__ {url_extra_repo}:
  1449. - name: gitinfo
  1450. - __env__ {url}:
  1451. - name: webinfo
  1452. - mountpoint: nowhere
  1453. """
  1454. )
  1455. self.assertEqual(
  1456. ret,
  1457. {
  1458. "branch": "master",
  1459. "motd": "The force will be with you. Always.",
  1460. "mylist": ["master"],
  1461. "mydict": {
  1462. "master": True,
  1463. "nested_list": ["master"],
  1464. "nested_dict": {"master": True},
  1465. },
  1466. },
  1467. )
  1468. @requires_system_grains
  1469. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  1470. def test_root_parameter(self, grains):
  1471. """
  1472. Test root parameter
  1473. """
  1474. expected = {"from_subdir": True}
  1475. # Test with passphraseless key and global credential options
  1476. ret = self.get_pillar(
  1477. """\
  1478. file_ignore_regex: []
  1479. file_ignore_glob: []
  1480. git_pillar_provider: pygit2
  1481. git_pillar_pubkey: {pubkey_nopass}
  1482. git_pillar_privkey: {privkey_nopass}
  1483. cachedir: {cachedir}
  1484. extension_modules: {extmods}
  1485. ext_pillar:
  1486. - git:
  1487. - master {url}:
  1488. - root: subdir
  1489. - top_only {url}:
  1490. - env: base
  1491. """
  1492. )
  1493. self.assertEqual(ret, expected)
  1494. # Test with passphraseless key and per-repo credential options
  1495. ret = self.get_pillar(
  1496. """\
  1497. file_ignore_regex: []
  1498. file_ignore_glob: []
  1499. git_pillar_provider: pygit2
  1500. cachedir: {cachedir}
  1501. extension_modules: {extmods}
  1502. ext_pillar:
  1503. - git:
  1504. - master {url}:
  1505. - root: subdir
  1506. - pubkey: {pubkey_nopass}
  1507. - privkey: {privkey_nopass}
  1508. - top_only {url}:
  1509. - pubkey: {pubkey_nopass}
  1510. - privkey: {privkey_nopass}
  1511. - env: base
  1512. """
  1513. )
  1514. self.assertEqual(ret, expected)
  1515. if grains["os_family"] == "Debian":
  1516. # passphrase-protected currently does not work here
  1517. return
  1518. # Test with passphrase-protected key and global credential options
  1519. ret = self.get_pillar(
  1520. """\
  1521. file_ignore_regex: []
  1522. file_ignore_glob: []
  1523. git_pillar_provider: pygit2
  1524. git_pillar_pubkey: {pubkey_withpass}
  1525. git_pillar_privkey: {privkey_withpass}
  1526. git_pillar_passphrase: {passphrase}
  1527. cachedir: {cachedir}
  1528. extension_modules: {extmods}
  1529. ext_pillar:
  1530. - git:
  1531. - master {url}:
  1532. - root: subdir
  1533. - top_only {url}:
  1534. - env: base
  1535. """
  1536. )
  1537. self.assertEqual(ret, expected)
  1538. # Test with passphrase-protected key and per-repo credential options
  1539. ret = self.get_pillar(
  1540. """\
  1541. file_ignore_regex: []
  1542. file_ignore_glob: []
  1543. git_pillar_provider: pygit2
  1544. cachedir: {cachedir}
  1545. extension_modules: {extmods}
  1546. ext_pillar:
  1547. - git:
  1548. - master {url}:
  1549. - root: subdir
  1550. - pubkey: {pubkey_withpass}
  1551. - privkey: {privkey_withpass}
  1552. - passphrase: {passphrase}
  1553. - top_only {url}:
  1554. - pubkey: {pubkey_withpass}
  1555. - privkey: {privkey_withpass}
  1556. - passphrase: {passphrase}
  1557. - env: base
  1558. """
  1559. )
  1560. self.assertEqual(ret, expected)
  1561. @requires_system_grains
  1562. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  1563. def test_mountpoint_parameter(self, grains):
  1564. """
  1565. Test mountpoint parameter
  1566. """
  1567. expected = {"included_pillar": True}
  1568. # Test with passphraseless key and global credential options
  1569. ret = self.get_pillar(
  1570. """\
  1571. file_ignore_regex: []
  1572. file_ignore_glob: []
  1573. git_pillar_provider: pygit2
  1574. git_pillar_pubkey: {pubkey_nopass}
  1575. git_pillar_privkey: {privkey_nopass}
  1576. cachedir: {cachedir}
  1577. extension_modules: {extmods}
  1578. ext_pillar:
  1579. - git:
  1580. - master {url}:
  1581. - mountpoint: mounted
  1582. - top_mounted {url}:
  1583. - env: base
  1584. """
  1585. )
  1586. self.assertEqual(ret, expected)
  1587. # Test with passphraseless key and per-repo credential options
  1588. ret = self.get_pillar(
  1589. """\
  1590. file_ignore_regex: []
  1591. file_ignore_glob: []
  1592. git_pillar_provider: pygit2
  1593. cachedir: {cachedir}
  1594. extension_modules: {extmods}
  1595. ext_pillar:
  1596. - git:
  1597. - master {url}:
  1598. - mountpoint: mounted
  1599. - pubkey: {pubkey_nopass}
  1600. - privkey: {privkey_nopass}
  1601. - top_mounted {url}:
  1602. - pubkey: {pubkey_nopass}
  1603. - privkey: {privkey_nopass}
  1604. - env: base
  1605. """
  1606. )
  1607. self.assertEqual(ret, expected)
  1608. if grains["os_family"] == "Debian":
  1609. # passphrase-protected currently does not work here
  1610. return
  1611. # Test with passphrase-protected key and global credential options
  1612. ret = self.get_pillar(
  1613. """\
  1614. file_ignore_regex: []
  1615. file_ignore_glob: []
  1616. git_pillar_provider: pygit2
  1617. git_pillar_pubkey: {pubkey_withpass}
  1618. git_pillar_privkey: {privkey_withpass}
  1619. git_pillar_passphrase: {passphrase}
  1620. cachedir: {cachedir}
  1621. extension_modules: {extmods}
  1622. ext_pillar:
  1623. - git:
  1624. - master {url}:
  1625. - mountpoint: mounted
  1626. - top_mounted {url}:
  1627. - env: base
  1628. """
  1629. )
  1630. self.assertEqual(ret, expected)
  1631. # Test with passphrase-protected key and per-repo credential options
  1632. ret = self.get_pillar(
  1633. """\
  1634. file_ignore_regex: []
  1635. file_ignore_glob: []
  1636. git_pillar_provider: pygit2
  1637. cachedir: {cachedir}
  1638. extension_modules: {extmods}
  1639. ext_pillar:
  1640. - git:
  1641. - master {url}:
  1642. - mountpoint: mounted
  1643. - pubkey: {pubkey_withpass}
  1644. - privkey: {privkey_withpass}
  1645. - passphrase: {passphrase}
  1646. - top_mounted {url}:
  1647. - pubkey: {pubkey_withpass}
  1648. - privkey: {privkey_withpass}
  1649. - passphrase: {passphrase}
  1650. - env: base
  1651. """
  1652. )
  1653. self.assertEqual(ret, expected)
  1654. @requires_system_grains
  1655. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  1656. def test_root_and_mountpoint_parameters(self, grains):
  1657. """
  1658. Test root and mountpoint parameters
  1659. """
  1660. expected = {"from_subdir": True}
  1661. # Test with passphraseless key and global credential options
  1662. ret = self.get_pillar(
  1663. """\
  1664. file_ignore_regex: []
  1665. file_ignore_glob: []
  1666. git_pillar_provider: pygit2
  1667. git_pillar_pubkey: {pubkey_nopass}
  1668. git_pillar_privkey: {privkey_nopass}
  1669. cachedir: {cachedir}
  1670. extension_modules: {extmods}
  1671. ext_pillar:
  1672. - git:
  1673. - master {url}:
  1674. - mountpoint: mounted
  1675. - root: subdir
  1676. - top_mounted {url}:
  1677. - env: base
  1678. """
  1679. )
  1680. self.assertEqual(ret, expected)
  1681. # Test with passphraseless key and per-repo credential options
  1682. ret = self.get_pillar(
  1683. """\
  1684. file_ignore_regex: []
  1685. file_ignore_glob: []
  1686. git_pillar_provider: pygit2
  1687. cachedir: {cachedir}
  1688. extension_modules: {extmods}
  1689. ext_pillar:
  1690. - git:
  1691. - master {url}:
  1692. - mountpoint: mounted
  1693. - root: subdir
  1694. - pubkey: {pubkey_nopass}
  1695. - privkey: {privkey_nopass}
  1696. - top_mounted {url}:
  1697. - pubkey: {pubkey_nopass}
  1698. - privkey: {privkey_nopass}
  1699. - env: base
  1700. """
  1701. )
  1702. self.assertEqual(ret, expected)
  1703. if grains["os_family"] == "Debian":
  1704. # passphrase-protected currently does not work here
  1705. return
  1706. # Test with passphrase-protected key and global credential options
  1707. ret = self.get_pillar(
  1708. """\
  1709. file_ignore_regex: []
  1710. file_ignore_glob: []
  1711. git_pillar_provider: pygit2
  1712. git_pillar_pubkey: {pubkey_withpass}
  1713. git_pillar_privkey: {privkey_withpass}
  1714. git_pillar_passphrase: {passphrase}
  1715. cachedir: {cachedir}
  1716. extension_modules: {extmods}
  1717. ext_pillar:
  1718. - git:
  1719. - master {url}:
  1720. - mountpoint: mounted
  1721. - root: subdir
  1722. - top_mounted {url}:
  1723. - env: base
  1724. """
  1725. )
  1726. self.assertEqual(ret, expected)
  1727. # Test with passphrase-protected key and per-repo credential options
  1728. ret = self.get_pillar(
  1729. """\
  1730. file_ignore_regex: []
  1731. file_ignore_glob: []
  1732. git_pillar_provider: pygit2
  1733. cachedir: {cachedir}
  1734. extension_modules: {extmods}
  1735. ext_pillar:
  1736. - git:
  1737. - master {url}:
  1738. - mountpoint: mounted
  1739. - root: subdir
  1740. - pubkey: {pubkey_withpass}
  1741. - privkey: {privkey_withpass}
  1742. - passphrase: {passphrase}
  1743. - top_mounted {url}:
  1744. - pubkey: {pubkey_withpass}
  1745. - privkey: {privkey_withpass}
  1746. - passphrase: {passphrase}
  1747. - env: base
  1748. """
  1749. )
  1750. self.assertEqual(ret, expected)
  1751. @requires_system_grains
  1752. @pytest.mark.slow_test(seconds=30) # Test takes >10 and <=30 seconds
  1753. def test_all_saltenvs(self, grains):
  1754. """
  1755. Test all_saltenvs parameter.
  1756. """
  1757. expected = {
  1758. "branch": "dev",
  1759. "motd": "The force will be with you. Always.",
  1760. "mylist": ["dev"],
  1761. "mydict": {
  1762. "dev": True,
  1763. "nested_list": ["dev"],
  1764. "nested_dict": {"dev": True},
  1765. },
  1766. }
  1767. # Test with passphraseless key and global credential options
  1768. ret = self.get_pillar(
  1769. """\
  1770. file_ignore_regex: []
  1771. file_ignore_glob: []
  1772. git_pillar_provider: pygit2
  1773. git_pillar_pubkey: {pubkey_nopass}
  1774. git_pillar_privkey: {privkey_nopass}
  1775. cachedir: {cachedir}
  1776. extension_modules: {extmods}
  1777. pillarenv: dev
  1778. ext_pillar:
  1779. - git:
  1780. - __env__ {url_extra_repo}:
  1781. - all_saltenvs: master
  1782. - __env__ {url}:
  1783. - mountpoint: nowhere
  1784. """
  1785. )
  1786. self.assertEqual(ret, expected)
  1787. # Test with passphraseless key and per-repo credential options
  1788. ret = self.get_pillar(
  1789. """\
  1790. file_ignore_regex: []
  1791. file_ignore_glob: []
  1792. git_pillar_provider: pygit2
  1793. cachedir: {cachedir}
  1794. extension_modules: {extmods}
  1795. pillarenv: dev
  1796. ext_pillar:
  1797. - git:
  1798. - __env__ {url_extra_repo}:
  1799. - all_saltenvs: master
  1800. - pubkey: {pubkey_nopass}
  1801. - privkey: {privkey_nopass}
  1802. - __env__ {url}:
  1803. - mountpoint: nowhere
  1804. - pubkey: {pubkey_nopass}
  1805. - privkey: {privkey_nopass}
  1806. """
  1807. )
  1808. self.assertEqual(ret, expected)
  1809. if grains["os_family"] == "Debian":
  1810. # passphrase-protected currently does not work here
  1811. return
  1812. # Test with passphrase-protected key and global credential options
  1813. ret = self.get_pillar(
  1814. """\
  1815. file_ignore_regex: []
  1816. file_ignore_glob: []
  1817. git_pillar_provider: pygit2
  1818. git_pillar_pubkey: {pubkey_withpass}
  1819. git_pillar_privkey: {privkey_withpass}
  1820. git_pillar_passphrase: {passphrase}
  1821. cachedir: {cachedir}
  1822. extension_modules: {extmods}
  1823. pillarenv: dev
  1824. ext_pillar:
  1825. - git:
  1826. - __env__ {url_extra_repo}:
  1827. - all_saltenvs: master
  1828. - __env__ {url}:
  1829. - mountpoint: nowhere
  1830. """
  1831. )
  1832. self.assertEqual(ret, expected)
  1833. # Test with passphrase-protected key and per-repo credential options
  1834. ret = self.get_pillar(
  1835. """\
  1836. file_ignore_regex: []
  1837. file_ignore_glob: []
  1838. git_pillar_provider: pygit2
  1839. cachedir: {cachedir}
  1840. extension_modules: {extmods}
  1841. pillarenv: dev
  1842. ext_pillar:
  1843. - git:
  1844. - __env__ {url_extra_repo}:
  1845. - all_saltenvs: master
  1846. - pubkey: {pubkey_nopass}
  1847. - privkey: {privkey_nopass}
  1848. - passphrase: {passphrase}
  1849. - __env__ {url}:
  1850. - mountpoint: nowhere
  1851. - pubkey: {pubkey_nopass}
  1852. - privkey: {privkey_nopass}
  1853. - passphrase: {passphrase}
  1854. """
  1855. )
  1856. self.assertEqual(ret, expected)
  1857. @requires_system_grains
  1858. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  1859. def test_all_saltenvs_base(self, grains):
  1860. """
  1861. Test all_saltenvs parameter.
  1862. """
  1863. expected = {
  1864. "branch": "master",
  1865. "motd": "The force will be with you. Always.",
  1866. "mylist": ["master"],
  1867. "mydict": {
  1868. "master": True,
  1869. "nested_list": ["master"],
  1870. "nested_dict": {"master": True},
  1871. },
  1872. }
  1873. # Test with passphraseless key and global credential options
  1874. ret = self.get_pillar(
  1875. """\
  1876. file_ignore_regex: []
  1877. file_ignore_glob: []
  1878. git_pillar_provider: pygit2
  1879. git_pillar_pubkey: {pubkey_nopass}
  1880. git_pillar_privkey: {privkey_nopass}
  1881. cachedir: {cachedir}
  1882. extension_modules: {extmods}
  1883. ext_pillar:
  1884. - git:
  1885. - __env__ {url_extra_repo}:
  1886. - all_saltenvs: master
  1887. - __env__ {url}:
  1888. - mountpoint: nowhere
  1889. """
  1890. )
  1891. self.assertEqual(ret, expected)
  1892. # Test with passphraseless key and per-repo credential options
  1893. ret = self.get_pillar(
  1894. """\
  1895. file_ignore_regex: []
  1896. file_ignore_glob: []
  1897. git_pillar_provider: pygit2
  1898. cachedir: {cachedir}
  1899. extension_modules: {extmods}
  1900. ext_pillar:
  1901. - git:
  1902. - __env__ {url_extra_repo}:
  1903. - all_saltenvs: master
  1904. - pubkey: {pubkey_nopass}
  1905. - privkey: {privkey_nopass}
  1906. - __env__ {url}:
  1907. - mountpoint: nowhere
  1908. - pubkey: {pubkey_nopass}
  1909. - privkey: {privkey_nopass}
  1910. """
  1911. )
  1912. self.assertEqual(ret, expected)
  1913. if grains["os_family"] == "Debian":
  1914. # passphrase-protected currently does not work here
  1915. return
  1916. # Test with passphrase-protected key and global credential options
  1917. ret = self.get_pillar(
  1918. """\
  1919. file_ignore_regex: []
  1920. file_ignore_glob: []
  1921. git_pillar_provider: pygit2
  1922. git_pillar_pubkey: {pubkey_withpass}
  1923. git_pillar_privkey: {privkey_withpass}
  1924. git_pillar_passphrase: {passphrase}
  1925. cachedir: {cachedir}
  1926. extension_modules: {extmods}
  1927. ext_pillar:
  1928. - git:
  1929. - __env__ {url_extra_repo}:
  1930. - all_saltenvs: master
  1931. - __env__ {url}:
  1932. - mountpoint: nowhere
  1933. """
  1934. )
  1935. self.assertEqual(ret, expected)
  1936. # Test with passphrase-protected key and per-repo credential options
  1937. ret = self.get_pillar(
  1938. """\
  1939. file_ignore_regex: []
  1940. file_ignore_glob: []
  1941. git_pillar_provider: pygit2
  1942. cachedir: {cachedir}
  1943. extension_modules: {extmods}
  1944. ext_pillar:
  1945. - git:
  1946. - __env__ {url_extra_repo}:
  1947. - all_saltenvs: master
  1948. - pubkey: {pubkey_nopass}
  1949. - privkey: {privkey_nopass}
  1950. - passphrase: {passphrase}
  1951. - __env__ {url}:
  1952. - mountpoint: nowhere
  1953. - pubkey: {pubkey_nopass}
  1954. - privkey: {privkey_nopass}
  1955. - passphrase: {passphrase}
  1956. """
  1957. )
  1958. self.assertEqual(ret, expected)
  1959. @requires_system_grains
  1960. def test_fallback(self, grains):
  1961. """
  1962. Test fallback parameter.
  1963. """
  1964. expected = {
  1965. "branch": "dev",
  1966. "motd": "The force will be with you. Always.",
  1967. "mylist": ["dev"],
  1968. "mydict": {
  1969. "dev": True,
  1970. "nested_list": ["dev"],
  1971. "nested_dict": {"dev": True},
  1972. },
  1973. }
  1974. # Test with passphraseless key and global credential options
  1975. ret = self.get_pillar(
  1976. """\
  1977. file_ignore_regex: []
  1978. file_ignore_glob: []
  1979. git_pillar_provider: pygit2
  1980. git_pillar_pubkey: {pubkey_nopass}
  1981. git_pillar_privkey: {privkey_nopass}
  1982. cachedir: {cachedir}
  1983. extension_modules: {extmods}
  1984. pillarenv: nonexisting
  1985. ext_pillar:
  1986. - git:
  1987. - __env__ {url_extra_repo}:
  1988. - fallback: master
  1989. - __env__ {url}:
  1990. - mountpoint: nowhere
  1991. - fallback: dev
  1992. """
  1993. )
  1994. self.assertEqual(ret, expected)
  1995. # Test with passphraseless key and per-repo credential options
  1996. ret = self.get_pillar(
  1997. """\
  1998. file_ignore_regex: []
  1999. file_ignore_glob: []
  2000. git_pillar_provider: pygit2
  2001. cachedir: {cachedir}
  2002. extension_modules: {extmods}
  2003. pillarenv: nonexisting
  2004. ext_pillar:
  2005. - git:
  2006. - __env__ {url_extra_repo}:
  2007. - fallback: master
  2008. - pubkey: {pubkey_nopass}
  2009. - privkey: {privkey_nopass}
  2010. - __env__ {url}:
  2011. - mountpoint: nowhere
  2012. - fallback: dev
  2013. - pubkey: {pubkey_nopass}
  2014. - privkey: {privkey_nopass}
  2015. """
  2016. )
  2017. self.assertEqual(ret, expected)
  2018. if grains["os_family"] == "Debian":
  2019. # passphrase-protected currently does not work here
  2020. return
  2021. # Test with passphrase-protected key and global credential options
  2022. ret = self.get_pillar(
  2023. """\
  2024. file_ignore_regex: []
  2025. file_ignore_glob: []
  2026. git_pillar_provider: pygit2
  2027. git_pillar_pubkey: {pubkey_withpass}
  2028. git_pillar_privkey: {privkey_withpass}
  2029. git_pillar_passphrase: {passphrase}
  2030. cachedir: {cachedir}
  2031. extension_modules: {extmods}
  2032. pillarenv: nonexisting
  2033. ext_pillar:
  2034. - git:
  2035. - __env__ {url_extra_repo}:
  2036. - fallback: master
  2037. - __env__ {url}:
  2038. - mountpoint: nowhere
  2039. - fallback: dev
  2040. """
  2041. )
  2042. self.assertEqual(ret, expected)
  2043. # Test with passphrase-protected key and per-repo credential options
  2044. ret = self.get_pillar(
  2045. """\
  2046. file_ignore_regex: []
  2047. file_ignore_glob: []
  2048. git_pillar_provider: pygit2
  2049. cachedir: {cachedir}
  2050. extension_modules: {extmods}
  2051. pillarenv: nonexisting
  2052. ext_pillar:
  2053. - git:
  2054. - __env__ {url_extra_repo}:
  2055. - fallback: master
  2056. - pubkey: {pubkey_nopass}
  2057. - privkey: {privkey_nopass}
  2058. - passphrase: {passphrase}
  2059. - __env__ {url}:
  2060. - mountpoint: nowhere
  2061. - fallback: dev
  2062. - pubkey: {pubkey_nopass}
  2063. - privkey: {privkey_nopass}
  2064. - passphrase: {passphrase}
  2065. """
  2066. )
  2067. self.assertEqual(ret, expected)
  2068. @skipIf(_windows_or_mac(), "minion is windows or mac")
  2069. @pytest.mark.skip_if_not_root
  2070. @skipIf(
  2071. not HAS_PYGIT2,
  2072. "pygit2 >= {0} and libgit2 >= {1} required".format(PYGIT2_MINVER, LIBGIT2_MINVER),
  2073. )
  2074. @skipIf(not HAS_NGINX, "nginx not present")
  2075. @skipIf(not HAS_VIRTUALENV, "virtualenv not present")
  2076. class TestPygit2HTTP(GitPillarHTTPTestBase):
  2077. """
  2078. Test git_pillar with pygit2 using SSH authentication
  2079. """
  2080. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2081. def test_single_source(self):
  2082. """
  2083. Test using a single ext_pillar repo
  2084. """
  2085. expected = {
  2086. "branch": "master",
  2087. "mylist": ["master"],
  2088. "mydict": {
  2089. "master": True,
  2090. "nested_list": ["master"],
  2091. "nested_dict": {"master": True},
  2092. },
  2093. }
  2094. ret = self.get_pillar(
  2095. """\
  2096. file_ignore_regex: []
  2097. file_ignore_glob: []
  2098. git_pillar_provider: pygit2
  2099. cachedir: {cachedir}
  2100. extension_modules: {extmods}
  2101. ext_pillar:
  2102. - git:
  2103. - master {url}
  2104. """
  2105. )
  2106. self.assertEqual(ret, expected)
  2107. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2108. def test_multiple_sources_master_dev_no_merge_lists(self):
  2109. """
  2110. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  2111. into a single dictionary, ordering matters.
  2112. This tests with the master branch followed by dev, and with
  2113. pillar_merge_lists disabled.
  2114. """
  2115. expected = {
  2116. "branch": "dev",
  2117. "mylist": ["dev"],
  2118. "mydict": {
  2119. "master": True,
  2120. "dev": True,
  2121. "nested_list": ["dev"],
  2122. "nested_dict": {"master": True, "dev": True},
  2123. },
  2124. }
  2125. ret = self.get_pillar(
  2126. """\
  2127. file_ignore_regex: []
  2128. file_ignore_glob: []
  2129. git_pillar_provider: pygit2
  2130. cachedir: {cachedir}
  2131. extension_modules: {extmods}
  2132. pillar_merge_lists: False
  2133. ext_pillar:
  2134. - git:
  2135. - master {url}
  2136. - dev {url}
  2137. """
  2138. )
  2139. self.assertEqual(ret, expected)
  2140. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2141. def test_multiple_sources_dev_master_no_merge_lists(self):
  2142. """
  2143. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  2144. into a single dictionary, ordering matters.
  2145. This tests with the dev branch followed by master, and with
  2146. pillar_merge_lists disabled.
  2147. """
  2148. expected = {
  2149. "branch": "master",
  2150. "mylist": ["master"],
  2151. "mydict": {
  2152. "master": True,
  2153. "dev": True,
  2154. "nested_list": ["master"],
  2155. "nested_dict": {"master": True, "dev": True},
  2156. },
  2157. }
  2158. ret = self.get_pillar(
  2159. """\
  2160. file_ignore_regex: []
  2161. file_ignore_glob: []
  2162. git_pillar_provider: pygit2
  2163. cachedir: {cachedir}
  2164. extension_modules: {extmods}
  2165. pillar_merge_lists: False
  2166. ext_pillar:
  2167. - git:
  2168. - dev {url}
  2169. - master {url}
  2170. """
  2171. )
  2172. self.assertEqual(ret, expected)
  2173. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2174. def test_multiple_sources_master_dev_merge_lists(self):
  2175. """
  2176. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  2177. into a single dictionary, ordering matters.
  2178. This tests with the master branch followed by dev, and with
  2179. pillar_merge_lists enabled.
  2180. """
  2181. expected = {
  2182. "branch": "dev",
  2183. "mylist": ["master", "dev"],
  2184. "mydict": {
  2185. "master": True,
  2186. "dev": True,
  2187. "nested_list": ["master", "dev"],
  2188. "nested_dict": {"master": True, "dev": True},
  2189. },
  2190. }
  2191. ret = self.get_pillar(
  2192. """\
  2193. file_ignore_regex: []
  2194. file_ignore_glob: []
  2195. git_pillar_provider: pygit2
  2196. cachedir: {cachedir}
  2197. extension_modules: {extmods}
  2198. pillar_merge_lists: True
  2199. ext_pillar:
  2200. - git:
  2201. - master {url}
  2202. - dev {url}
  2203. """
  2204. )
  2205. self.assertEqual(ret, expected)
  2206. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2207. def test_multiple_sources_dev_master_merge_lists(self):
  2208. """
  2209. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  2210. into a single dictionary, ordering matters.
  2211. This tests with the dev branch followed by master, and with
  2212. pillar_merge_lists enabled.
  2213. """
  2214. expected = {
  2215. "branch": "master",
  2216. "mylist": ["dev", "master"],
  2217. "mydict": {
  2218. "master": True,
  2219. "dev": True,
  2220. "nested_list": ["dev", "master"],
  2221. "nested_dict": {"master": True, "dev": True},
  2222. },
  2223. }
  2224. ret = self.get_pillar(
  2225. """\
  2226. file_ignore_regex: []
  2227. file_ignore_glob: []
  2228. git_pillar_provider: pygit2
  2229. cachedir: {cachedir}
  2230. extension_modules: {extmods}
  2231. pillar_merge_lists: True
  2232. ext_pillar:
  2233. - git:
  2234. - dev {url}
  2235. - master {url}
  2236. """
  2237. )
  2238. self.assertEqual(ret, expected)
  2239. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2240. def test_multiple_sources_with_pillarenv(self):
  2241. """
  2242. Test using pillarenv to restrict results to those from a single branch
  2243. """
  2244. expected = {
  2245. "branch": "master",
  2246. "mylist": ["master"],
  2247. "mydict": {
  2248. "master": True,
  2249. "nested_list": ["master"],
  2250. "nested_dict": {"master": True},
  2251. },
  2252. }
  2253. ret = self.get_pillar(
  2254. """\
  2255. file_ignore_regex: []
  2256. file_ignore_glob: []
  2257. git_pillar_provider: pygit2
  2258. cachedir: {cachedir}
  2259. extension_modules: {extmods}
  2260. pillarenv: base
  2261. ext_pillar:
  2262. - git:
  2263. - master {url}
  2264. - dev {url}
  2265. """
  2266. )
  2267. self.assertEqual(ret, expected)
  2268. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2269. def test_includes_enabled(self):
  2270. """
  2271. Test with git_pillar_includes enabled. The top_only branch references
  2272. an SLS file from the master branch, so we should see the
  2273. "included_pillar" key from that SLS file in the compiled pillar data.
  2274. """
  2275. expected = {
  2276. "branch": "master",
  2277. "mylist": ["master"],
  2278. "mydict": {
  2279. "master": True,
  2280. "nested_list": ["master"],
  2281. "nested_dict": {"master": True},
  2282. },
  2283. "included_pillar": True,
  2284. }
  2285. ret = self.get_pillar(
  2286. """\
  2287. file_ignore_regex: []
  2288. file_ignore_glob: []
  2289. git_pillar_provider: pygit2
  2290. cachedir: {cachedir}
  2291. extension_modules: {extmods}
  2292. ext_pillar:
  2293. - git:
  2294. - master {url}
  2295. - top_only {url}:
  2296. - env: base
  2297. """
  2298. )
  2299. self.assertEqual(ret, expected)
  2300. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2301. def test_includes_disabled(self):
  2302. """
  2303. Test with git_pillar_includes enabled. The top_only branch references
  2304. an SLS file from the master branch, but since includes are disabled it
  2305. will not find the SLS file and the "included_pillar" key should not be
  2306. present in the compiled pillar data. We should instead see an error
  2307. message in the compiled data.
  2308. """
  2309. expected = {
  2310. "branch": "master",
  2311. "mylist": ["master"],
  2312. "mydict": {
  2313. "master": True,
  2314. "nested_list": ["master"],
  2315. "nested_dict": {"master": True},
  2316. },
  2317. "_errors": [
  2318. "Specified SLS 'bar' in environment 'base' is not "
  2319. "available on the salt master"
  2320. ],
  2321. }
  2322. ret = self.get_pillar(
  2323. """\
  2324. file_ignore_regex: []
  2325. file_ignore_glob: []
  2326. git_pillar_provider: pygit2
  2327. git_pillar_includes: False
  2328. cachedir: {cachedir}
  2329. extension_modules: {extmods}
  2330. ext_pillar:
  2331. - git:
  2332. - master {url}
  2333. - top_only {url}:
  2334. - env: base
  2335. """
  2336. )
  2337. self.assertEqual(ret, expected)
  2338. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2339. def test_includes_enabled_solves___env___with_mountpoint(self):
  2340. """
  2341. Test with git_pillar_includes enabled and using "__env__" as the branch
  2342. name for the configured repositories.
  2343. The "gitinfo" repository contains top.sls file with a local reference
  2344. and also referencing external "nowhere.foo" which is provided by "webinfo"
  2345. repository mounted as "nowhere".
  2346. """
  2347. ret = self.get_pillar(
  2348. """\
  2349. file_ignore_regex: []
  2350. file_ignore_glob: []
  2351. git_pillar_provider: pygit2
  2352. cachedir: {cachedir}
  2353. extension_modules: {extmods}
  2354. ext_pillar:
  2355. - git:
  2356. - __env__ {url_extra_repo}:
  2357. - name: gitinfo
  2358. - __env__ {url}:
  2359. - name: webinfo
  2360. - mountpoint: nowhere
  2361. """
  2362. )
  2363. self.assertEqual(
  2364. ret,
  2365. {
  2366. "branch": "master",
  2367. "motd": "The force will be with you. Always.",
  2368. "mylist": ["master"],
  2369. "mydict": {
  2370. "master": True,
  2371. "nested_list": ["master"],
  2372. "nested_dict": {"master": True},
  2373. },
  2374. },
  2375. )
  2376. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2377. def test_root_parameter(self):
  2378. """
  2379. Test root parameter
  2380. """
  2381. expected = {"from_subdir": True}
  2382. ret = self.get_pillar(
  2383. """\
  2384. file_ignore_regex: []
  2385. file_ignore_glob: []
  2386. git_pillar_provider: pygit2
  2387. cachedir: {cachedir}
  2388. extension_modules: {extmods}
  2389. ext_pillar:
  2390. - git:
  2391. - master {url}:
  2392. - root: subdir
  2393. - top_only {url}:
  2394. - env: base
  2395. """
  2396. )
  2397. self.assertEqual(ret, expected)
  2398. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2399. def test_mountpoint_parameter(self):
  2400. """
  2401. Test mountpoint parameter
  2402. """
  2403. expected = {"included_pillar": True}
  2404. ret = self.get_pillar(
  2405. """\
  2406. file_ignore_regex: []
  2407. file_ignore_glob: []
  2408. git_pillar_provider: pygit2
  2409. cachedir: {cachedir}
  2410. extension_modules: {extmods}
  2411. ext_pillar:
  2412. - git:
  2413. - master {url}:
  2414. - mountpoint: mounted
  2415. - top_mounted {url}:
  2416. - env: base
  2417. """
  2418. )
  2419. self.assertEqual(ret, expected)
  2420. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2421. def test_root_and_mountpoint_parameters(self):
  2422. """
  2423. Test root and mountpoint parameters
  2424. """
  2425. expected = {"from_subdir": True}
  2426. ret = self.get_pillar(
  2427. """\
  2428. file_ignore_regex: []
  2429. file_ignore_glob: []
  2430. git_pillar_provider: pygit2
  2431. cachedir: {cachedir}
  2432. extension_modules: {extmods}
  2433. ext_pillar:
  2434. - git:
  2435. - master {url}:
  2436. - mountpoint: mounted
  2437. - root: subdir
  2438. - top_mounted {url}:
  2439. - env: base
  2440. """
  2441. )
  2442. self.assertEqual(ret, expected)
  2443. @pytest.mark.slow_test(seconds=30) # Test takes >10 and <=30 seconds
  2444. def test_all_saltenvs(self):
  2445. """
  2446. Test all_saltenvs parameter.
  2447. """
  2448. ret = self.get_pillar(
  2449. """\
  2450. file_ignore_regex: []
  2451. file_ignore_glob: []
  2452. git_pillar_provider: pygit2
  2453. cachedir: {cachedir}
  2454. extension_modules: {extmods}
  2455. pillarenv: dev
  2456. ext_pillar:
  2457. - git:
  2458. - __env__ {url_extra_repo}:
  2459. - all_saltenvs: master
  2460. - __env__ {url}:
  2461. - mountpoint: nowhere
  2462. """
  2463. )
  2464. self.assertEqual(
  2465. ret,
  2466. {
  2467. "branch": "dev",
  2468. "motd": "The force will be with you. Always.",
  2469. "mylist": ["dev"],
  2470. "mydict": {
  2471. "dev": True,
  2472. "nested_list": ["dev"],
  2473. "nested_dict": {"dev": True},
  2474. },
  2475. },
  2476. )
  2477. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2478. def test_all_saltenvs_base(self):
  2479. """
  2480. Test all_saltenvs parameter with base pillarenv.
  2481. """
  2482. ret = self.get_pillar(
  2483. """\
  2484. file_ignore_regex: []
  2485. file_ignore_glob: []
  2486. git_pillar_provider: pygit2
  2487. cachedir: {cachedir}
  2488. extension_modules: {extmods}
  2489. ext_pillar:
  2490. - git:
  2491. - __env__ {url_extra_repo}:
  2492. - all_saltenvs: master
  2493. - __env__ {url}:
  2494. - mountpoint: nowhere
  2495. """
  2496. )
  2497. self.assertEqual(
  2498. ret,
  2499. {
  2500. "branch": "master",
  2501. "motd": "The force will be with you. Always.",
  2502. "mylist": ["master"],
  2503. "mydict": {
  2504. "master": True,
  2505. "nested_list": ["master"],
  2506. "nested_dict": {"master": True},
  2507. },
  2508. },
  2509. )
  2510. def test_fallback(self):
  2511. """
  2512. Test fallback parameter.
  2513. """
  2514. ret = self.get_pillar(
  2515. """\
  2516. file_ignore_regex: []
  2517. file_ignore_glob: []
  2518. git_pillar_provider: pygit2
  2519. cachedir: {cachedir}
  2520. extension_modules: {extmods}
  2521. pillarenv: nonexisting
  2522. ext_pillar:
  2523. - git:
  2524. - __env__ {url_extra_repo}:
  2525. - fallback: master
  2526. - __env__ {url}:
  2527. - mountpoint: nowhere
  2528. - fallback: dev
  2529. """
  2530. )
  2531. self.assertEqual(
  2532. ret,
  2533. {
  2534. "branch": "dev",
  2535. "motd": "The force will be with you. Always.",
  2536. "mylist": ["dev"],
  2537. "mydict": {
  2538. "dev": True,
  2539. "nested_list": ["dev"],
  2540. "nested_dict": {"dev": True},
  2541. },
  2542. },
  2543. )
  2544. @skipIf(_windows_or_mac(), "minion is windows or mac")
  2545. @pytest.mark.skip_if_not_root
  2546. @skipIf(
  2547. not HAS_PYGIT2,
  2548. "pygit2 >= {0} and libgit2 >= {1} required".format(PYGIT2_MINVER, LIBGIT2_MINVER),
  2549. )
  2550. @skipIf(not HAS_NGINX, "nginx not present")
  2551. @skipIf(not HAS_VIRTUALENV, "virtualenv not present")
  2552. class TestPygit2AuthenticatedHTTP(GitPillarHTTPTestBase):
  2553. """
  2554. Test git_pillar with pygit2 using SSH authentication
  2555. NOTE: Any tests added to this test class should have equivalent tests (if
  2556. possible) in the TestGitPythonSSH class.
  2557. """
  2558. user = USERNAME
  2559. password = PASSWORD
  2560. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2561. def test_single_source(self):
  2562. """
  2563. Test using a single ext_pillar repo
  2564. """
  2565. expected = {
  2566. "branch": "master",
  2567. "mylist": ["master"],
  2568. "mydict": {
  2569. "master": True,
  2570. "nested_list": ["master"],
  2571. "nested_dict": {"master": True},
  2572. },
  2573. }
  2574. # Test with global credential options
  2575. ret = self.get_pillar(
  2576. """\
  2577. file_ignore_regex: []
  2578. file_ignore_glob: []
  2579. git_pillar_provider: pygit2
  2580. git_pillar_user: {user}
  2581. git_pillar_password: {password}
  2582. git_pillar_insecure_auth: True
  2583. cachedir: {cachedir}
  2584. extension_modules: {extmods}
  2585. ext_pillar:
  2586. - git:
  2587. - master {url}
  2588. """
  2589. )
  2590. self.assertEqual(ret, expected)
  2591. # Test with per-repo credential options
  2592. ret = self.get_pillar(
  2593. """\
  2594. file_ignore_regex: []
  2595. file_ignore_glob: []
  2596. git_pillar_provider: pygit2
  2597. cachedir: {cachedir}
  2598. extension_modules: {extmods}
  2599. ext_pillar:
  2600. - git:
  2601. - master {url}:
  2602. - user: {user}
  2603. - password: {password}
  2604. - insecure_auth: True
  2605. """
  2606. )
  2607. self.assertEqual(ret, expected)
  2608. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  2609. def test_multiple_sources_master_dev_no_merge_lists(self):
  2610. """
  2611. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  2612. into a single dictionary, ordering matters.
  2613. This tests with the master branch followed by dev, and with
  2614. pillar_merge_lists disabled.
  2615. """
  2616. expected = {
  2617. "branch": "dev",
  2618. "mylist": ["dev"],
  2619. "mydict": {
  2620. "master": True,
  2621. "dev": True,
  2622. "nested_list": ["dev"],
  2623. "nested_dict": {"master": True, "dev": True},
  2624. },
  2625. }
  2626. # Test with global credential options
  2627. ret = self.get_pillar(
  2628. """\
  2629. file_ignore_regex: []
  2630. file_ignore_glob: []
  2631. git_pillar_provider: pygit2
  2632. git_pillar_user: {user}
  2633. git_pillar_password: {password}
  2634. git_pillar_insecure_auth: True
  2635. cachedir: {cachedir}
  2636. extension_modules: {extmods}
  2637. pillar_merge_lists: False
  2638. ext_pillar:
  2639. - git:
  2640. - master {url}
  2641. - dev {url}
  2642. """
  2643. )
  2644. self.assertEqual(ret, expected)
  2645. # Test with per-repo credential options
  2646. ret = self.get_pillar(
  2647. """\
  2648. file_ignore_regex: []
  2649. file_ignore_glob: []
  2650. git_pillar_provider: pygit2
  2651. cachedir: {cachedir}
  2652. extension_modules: {extmods}
  2653. pillar_merge_lists: False
  2654. ext_pillar:
  2655. - git:
  2656. - master {url}:
  2657. - user: {user}
  2658. - password: {password}
  2659. - insecure_auth: True
  2660. - dev {url}:
  2661. - user: {user}
  2662. - password: {password}
  2663. - insecure_auth: True
  2664. """
  2665. )
  2666. self.assertEqual(ret, expected)
  2667. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  2668. def test_multiple_sources_dev_master_no_merge_lists(self):
  2669. """
  2670. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  2671. into a single dictionary, ordering matters.
  2672. This tests with the dev branch followed by master, and with
  2673. pillar_merge_lists disabled.
  2674. """
  2675. expected = {
  2676. "branch": "master",
  2677. "mylist": ["master"],
  2678. "mydict": {
  2679. "master": True,
  2680. "dev": True,
  2681. "nested_list": ["master"],
  2682. "nested_dict": {"master": True, "dev": True},
  2683. },
  2684. }
  2685. # Test with global credential options
  2686. ret = self.get_pillar(
  2687. """\
  2688. file_ignore_regex: []
  2689. file_ignore_glob: []
  2690. git_pillar_provider: pygit2
  2691. git_pillar_user: {user}
  2692. git_pillar_password: {password}
  2693. git_pillar_insecure_auth: True
  2694. cachedir: {cachedir}
  2695. extension_modules: {extmods}
  2696. pillar_merge_lists: False
  2697. ext_pillar:
  2698. - git:
  2699. - dev {url}
  2700. - master {url}
  2701. """
  2702. )
  2703. self.assertEqual(ret, expected)
  2704. # Test with per-repo credential options
  2705. ret = self.get_pillar(
  2706. """\
  2707. file_ignore_regex: []
  2708. file_ignore_glob: []
  2709. git_pillar_provider: pygit2
  2710. cachedir: {cachedir}
  2711. extension_modules: {extmods}
  2712. pillar_merge_lists: False
  2713. ext_pillar:
  2714. - git:
  2715. - dev {url}:
  2716. - user: {user}
  2717. - password: {password}
  2718. - insecure_auth: True
  2719. - master {url}:
  2720. - user: {user}
  2721. - password: {password}
  2722. - insecure_auth: True
  2723. """
  2724. )
  2725. self.assertEqual(ret, expected)
  2726. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  2727. def test_multiple_sources_master_dev_merge_lists(self):
  2728. """
  2729. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  2730. into a single dictionary, ordering matters.
  2731. This tests with the master branch followed by dev, and with
  2732. pillar_merge_lists enabled.
  2733. """
  2734. expected = {
  2735. "branch": "dev",
  2736. "mylist": ["master", "dev"],
  2737. "mydict": {
  2738. "master": True,
  2739. "dev": True,
  2740. "nested_list": ["master", "dev"],
  2741. "nested_dict": {"master": True, "dev": True},
  2742. },
  2743. }
  2744. # Test with global credential options
  2745. ret = self.get_pillar(
  2746. """\
  2747. file_ignore_regex: []
  2748. file_ignore_glob: []
  2749. git_pillar_provider: pygit2
  2750. git_pillar_user: {user}
  2751. git_pillar_password: {password}
  2752. git_pillar_insecure_auth: True
  2753. cachedir: {cachedir}
  2754. extension_modules: {extmods}
  2755. pillar_merge_lists: True
  2756. ext_pillar:
  2757. - git:
  2758. - master {url}
  2759. - dev {url}
  2760. """
  2761. )
  2762. self.assertEqual(ret, expected)
  2763. # Test with per-repo credential options
  2764. ret = self.get_pillar(
  2765. """\
  2766. file_ignore_regex: []
  2767. file_ignore_glob: []
  2768. git_pillar_provider: pygit2
  2769. cachedir: {cachedir}
  2770. extension_modules: {extmods}
  2771. pillar_merge_lists: True
  2772. ext_pillar:
  2773. - git:
  2774. - master {url}:
  2775. - user: {user}
  2776. - password: {password}
  2777. - insecure_auth: True
  2778. - dev {url}:
  2779. - user: {user}
  2780. - password: {password}
  2781. - insecure_auth: True
  2782. """
  2783. )
  2784. self.assertEqual(ret, expected)
  2785. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  2786. def test_multiple_sources_dev_master_merge_lists(self):
  2787. """
  2788. Test using two ext_pillar dirs. Since all git_pillar repos are merged
  2789. into a single dictionary, ordering matters.
  2790. This tests with the dev branch followed by master, and with
  2791. pillar_merge_lists enabled.
  2792. """
  2793. expected = {
  2794. "branch": "master",
  2795. "mylist": ["dev", "master"],
  2796. "mydict": {
  2797. "master": True,
  2798. "dev": True,
  2799. "nested_list": ["dev", "master"],
  2800. "nested_dict": {"master": True, "dev": True},
  2801. },
  2802. }
  2803. # Test with global credential options
  2804. ret = self.get_pillar(
  2805. """\
  2806. file_ignore_regex: []
  2807. file_ignore_glob: []
  2808. git_pillar_provider: pygit2
  2809. git_pillar_user: {user}
  2810. git_pillar_password: {password}
  2811. git_pillar_insecure_auth: True
  2812. cachedir: {cachedir}
  2813. extension_modules: {extmods}
  2814. pillar_merge_lists: True
  2815. ext_pillar:
  2816. - git:
  2817. - dev {url}
  2818. - master {url}
  2819. """
  2820. )
  2821. self.assertEqual(ret, expected)
  2822. # Test with per-repo credential options
  2823. ret = self.get_pillar(
  2824. """\
  2825. file_ignore_regex: []
  2826. file_ignore_glob: []
  2827. git_pillar_provider: pygit2
  2828. cachedir: {cachedir}
  2829. extension_modules: {extmods}
  2830. pillar_merge_lists: True
  2831. ext_pillar:
  2832. - git:
  2833. - dev {url}:
  2834. - user: {user}
  2835. - password: {password}
  2836. - insecure_auth: True
  2837. - master {url}:
  2838. - user: {user}
  2839. - password: {password}
  2840. - insecure_auth: True
  2841. """
  2842. )
  2843. self.assertEqual(ret, expected)
  2844. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  2845. def test_multiple_sources_with_pillarenv(self):
  2846. """
  2847. Test using pillarenv to restrict results to those from a single branch
  2848. """
  2849. expected = {
  2850. "branch": "master",
  2851. "mylist": ["master"],
  2852. "mydict": {
  2853. "master": True,
  2854. "nested_list": ["master"],
  2855. "nested_dict": {"master": True},
  2856. },
  2857. }
  2858. # Test with global credential options
  2859. ret = self.get_pillar(
  2860. """\
  2861. file_ignore_regex: []
  2862. file_ignore_glob: []
  2863. git_pillar_provider: pygit2
  2864. git_pillar_user: {user}
  2865. git_pillar_password: {password}
  2866. git_pillar_insecure_auth: True
  2867. cachedir: {cachedir}
  2868. extension_modules: {extmods}
  2869. pillarenv: base
  2870. ext_pillar:
  2871. - git:
  2872. - master {url}
  2873. - dev {url}
  2874. """
  2875. )
  2876. self.assertEqual(ret, expected)
  2877. # Test with per-repo credential options
  2878. ret = self.get_pillar(
  2879. """\
  2880. file_ignore_regex: []
  2881. file_ignore_glob: []
  2882. git_pillar_provider: pygit2
  2883. cachedir: {cachedir}
  2884. extension_modules: {extmods}
  2885. pillarenv: base
  2886. ext_pillar:
  2887. - git:
  2888. - master {url}:
  2889. - user: {user}
  2890. - password: {password}
  2891. - insecure_auth: True
  2892. - dev {url}:
  2893. - user: {user}
  2894. - password: {password}
  2895. - insecure_auth: True
  2896. """
  2897. )
  2898. self.assertEqual(ret, expected)
  2899. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2900. def test_includes_enabled(self):
  2901. """
  2902. Test with git_pillar_includes enabled. The top_only branch references
  2903. an SLS file from the master branch, so we should see the
  2904. "included_pillar" key from that SLS file in the compiled pillar data.
  2905. """
  2906. expected = {
  2907. "branch": "master",
  2908. "mylist": ["master"],
  2909. "mydict": {
  2910. "master": True,
  2911. "nested_list": ["master"],
  2912. "nested_dict": {"master": True},
  2913. },
  2914. "included_pillar": True,
  2915. }
  2916. # Test with global credential options
  2917. ret = self.get_pillar(
  2918. """\
  2919. file_ignore_regex: []
  2920. file_ignore_glob: []
  2921. git_pillar_provider: pygit2
  2922. git_pillar_user: {user}
  2923. git_pillar_password: {password}
  2924. git_pillar_insecure_auth: True
  2925. cachedir: {cachedir}
  2926. extension_modules: {extmods}
  2927. ext_pillar:
  2928. - git:
  2929. - master {url}
  2930. - top_only {url}:
  2931. - env: base
  2932. """
  2933. )
  2934. self.assertEqual(ret, expected)
  2935. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  2936. def test_mountpoint_parameter(self):
  2937. """
  2938. Test mountpoint parameter
  2939. """
  2940. expected = {"included_pillar": True}
  2941. ret = self.get_pillar(
  2942. """\
  2943. file_ignore_regex: []
  2944. file_ignore_glob: []
  2945. git_pillar_provider: pygit2
  2946. git_pillar_user: {user}
  2947. git_pillar_password: {password}
  2948. git_pillar_insecure_auth: True
  2949. cachedir: {cachedir}
  2950. extension_modules: {extmods}
  2951. ext_pillar:
  2952. - git:
  2953. - master {url}:
  2954. - mountpoint: mounted
  2955. - top_mounted {url}:
  2956. - env: base
  2957. """
  2958. )
  2959. self.assertEqual(ret, expected)
  2960. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  2961. def test_root_parameter(self):
  2962. """
  2963. Test root parameter
  2964. """
  2965. expected = {"from_subdir": True}
  2966. ret = self.get_pillar(
  2967. """\
  2968. file_ignore_regex: []
  2969. file_ignore_glob: []
  2970. git_pillar_provider: pygit2
  2971. git_pillar_user: {user}
  2972. git_pillar_password: {password}
  2973. git_pillar_insecure_auth: True
  2974. cachedir: {cachedir}
  2975. extension_modules: {extmods}
  2976. ext_pillar:
  2977. - git:
  2978. - master {url}:
  2979. - root: subdir
  2980. - top_only {url}:
  2981. - env: base
  2982. """
  2983. )
  2984. self.assertEqual(ret, expected)
  2985. # Test with per-repo credential options
  2986. ret = self.get_pillar(
  2987. """\
  2988. file_ignore_regex: []
  2989. file_ignore_glob: []
  2990. git_pillar_provider: pygit2
  2991. cachedir: {cachedir}
  2992. extension_modules: {extmods}
  2993. ext_pillar:
  2994. - git:
  2995. - master {url}:
  2996. - root: subdir
  2997. - user: {user}
  2998. - password: {password}
  2999. - insecure_auth: True
  3000. - top_only {url}:
  3001. - user: {user}
  3002. - password: {password}
  3003. - insecure_auth: True
  3004. - env: base
  3005. """
  3006. )
  3007. self.assertEqual(ret, expected)
  3008. @pytest.mark.slow_test(seconds=10) # Test takes >5 and <=10 seconds
  3009. def test_includes_disabled(self):
  3010. """
  3011. Test with git_pillar_includes enabled. The top_only branch references
  3012. an SLS file from the master branch, but since includes are disabled it
  3013. will not find the SLS file and the "included_pillar" key should not be
  3014. present in the compiled pillar data. We should instead see an error
  3015. message in the compiled data.
  3016. """
  3017. expected = {
  3018. "branch": "master",
  3019. "mylist": ["master"],
  3020. "mydict": {
  3021. "master": True,
  3022. "nested_list": ["master"],
  3023. "nested_dict": {"master": True},
  3024. },
  3025. "_errors": [
  3026. "Specified SLS 'bar' in environment 'base' is not "
  3027. "available on the salt master"
  3028. ],
  3029. }
  3030. # Test with global credential options
  3031. ret = self.get_pillar(
  3032. """\
  3033. file_ignore_regex: []
  3034. file_ignore_glob: []
  3035. git_pillar_provider: pygit2
  3036. git_pillar_includes: False
  3037. git_pillar_user: {user}
  3038. git_pillar_password: {password}
  3039. git_pillar_insecure_auth: True
  3040. cachedir: {cachedir}
  3041. extension_modules: {extmods}
  3042. ext_pillar:
  3043. - git:
  3044. - master {url}
  3045. - top_only {url}:
  3046. - env: base
  3047. """
  3048. )
  3049. self.assertEqual(ret, expected)
  3050. # Test with per-repo credential options
  3051. ret = self.get_pillar(
  3052. """\
  3053. file_ignore_regex: []
  3054. file_ignore_glob: []
  3055. git_pillar_provider: pygit2
  3056. git_pillar_includes: False
  3057. cachedir: {cachedir}
  3058. extension_modules: {extmods}
  3059. ext_pillar:
  3060. - git:
  3061. - master {url}:
  3062. - user: {user}
  3063. - password: {password}
  3064. - insecure_auth: True
  3065. - top_only {url}:
  3066. - user: {user}
  3067. - password: {password}
  3068. - insecure_auth: True
  3069. - env: base
  3070. """
  3071. )
  3072. self.assertEqual(ret, expected)
  3073. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  3074. def test_includes_enabled_solves___env___with_mountpoint(self):
  3075. """
  3076. Test with git_pillar_includes enabled and using "__env__" as the branch
  3077. name for the configured repositories.
  3078. The "gitinfo" repository contains top.sls file with a local reference
  3079. and also referencing external "nowhere.foo" which is provided by "webinfo"
  3080. repository mounted as "nowhere".
  3081. """
  3082. ret = self.get_pillar(
  3083. """\
  3084. file_ignore_regex: []
  3085. file_ignore_glob: []
  3086. git_pillar_provider: pygit2
  3087. git_pillar_user: {user}
  3088. git_pillar_password: {password}
  3089. git_pillar_insecure_auth: True
  3090. cachedir: {cachedir}
  3091. extension_modules: {extmods}
  3092. ext_pillar:
  3093. - git:
  3094. - __env__ {url_extra_repo}:
  3095. - name: gitinfo
  3096. - user: {user}
  3097. - password: {password}
  3098. - insecure_auth: True
  3099. - __env__ {url}:
  3100. - name: webinfo
  3101. - mountpoint: nowhere
  3102. - user: {user}
  3103. - password: {password}
  3104. - insecure_auth: True
  3105. """
  3106. )
  3107. self.assertEqual(
  3108. ret,
  3109. {
  3110. "branch": "master",
  3111. "motd": "The force will be with you. Always.",
  3112. "mylist": ["master"],
  3113. "mydict": {
  3114. "master": True,
  3115. "nested_list": ["master"],
  3116. "nested_dict": {"master": True},
  3117. },
  3118. },
  3119. )
  3120. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  3121. def test_root_and_mountpoint_parameters(self):
  3122. """
  3123. Test root and mountpoint parameters
  3124. """
  3125. expected = {"from_subdir": True}
  3126. ret = self.get_pillar(
  3127. """\
  3128. file_ignore_regex: []
  3129. file_ignore_glob: []
  3130. git_pillar_provider: pygit2
  3131. git_pillar_user: {user}
  3132. git_pillar_password: {password}
  3133. git_pillar_insecure_auth: True
  3134. cachedir: {cachedir}
  3135. extension_modules: {extmods}
  3136. ext_pillar:
  3137. - git:
  3138. - master {url}:
  3139. - mountpoint: mounted
  3140. - root: subdir
  3141. - top_mounted {url}:
  3142. - env: base
  3143. """
  3144. )
  3145. self.assertEqual(ret, expected)
  3146. @pytest.mark.slow_test(seconds=30) # Test takes >10 and <=30 seconds
  3147. def test_all_saltenvs(self):
  3148. """
  3149. Test all_saltenvs parameter.
  3150. """
  3151. ret = self.get_pillar(
  3152. """\
  3153. file_ignore_regex: []
  3154. file_ignore_glob: []
  3155. git_pillar_provider: pygit2
  3156. git_pillar_user: {user}
  3157. git_pillar_password: {password}
  3158. git_pillar_insecure_auth: True
  3159. cachedir: {cachedir}
  3160. extension_modules: {extmods}
  3161. pillarenv: dev
  3162. ext_pillar:
  3163. - git:
  3164. - __env__ {url_extra_repo}:
  3165. - all_saltenvs: master
  3166. - __env__ {url}:
  3167. - mountpoint: nowhere
  3168. """
  3169. )
  3170. self.assertEqual(
  3171. ret,
  3172. {
  3173. "branch": "dev",
  3174. "motd": "The force will be with you. Always.",
  3175. "mylist": ["dev"],
  3176. "mydict": {
  3177. "dev": True,
  3178. "nested_list": ["dev"],
  3179. "nested_dict": {"dev": True},
  3180. },
  3181. },
  3182. )
  3183. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  3184. def test_all_saltenvs_base(self):
  3185. """
  3186. Test all_saltenvs parameter with base pillarenv.
  3187. """
  3188. ret = self.get_pillar(
  3189. """\
  3190. file_ignore_regex: []
  3191. file_ignore_glob: []
  3192. git_pillar_provider: pygit2
  3193. git_pillar_user: {user}
  3194. git_pillar_password: {password}
  3195. git_pillar_insecure_auth: True
  3196. cachedir: {cachedir}
  3197. extension_modules: {extmods}
  3198. ext_pillar:
  3199. - git:
  3200. - __env__ {url_extra_repo}:
  3201. - all_saltenvs: master
  3202. - __env__ {url}:
  3203. - mountpoint: nowhere
  3204. """
  3205. )
  3206. self.assertEqual(
  3207. ret,
  3208. {
  3209. "branch": "master",
  3210. "motd": "The force will be with you. Always.",
  3211. "mylist": ["master"],
  3212. "mydict": {
  3213. "master": True,
  3214. "nested_list": ["master"],
  3215. "nested_dict": {"master": True},
  3216. },
  3217. },
  3218. )
  3219. def test_fallback(self):
  3220. """
  3221. Test fallback parameter.
  3222. """
  3223. ret = self.get_pillar(
  3224. """\
  3225. file_ignore_regex: []
  3226. file_ignore_glob: []
  3227. git_pillar_provider: pygit2
  3228. git_pillar_user: {user}
  3229. git_pillar_password: {password}
  3230. git_pillar_insecure_auth: True
  3231. cachedir: {cachedir}
  3232. extension_modules: {extmods}
  3233. pillarenv: nonexisting
  3234. ext_pillar:
  3235. - git:
  3236. - __env__ {url_extra_repo}:
  3237. - fallback: master
  3238. - __env__ {url}:
  3239. - mountpoint: nowhere
  3240. - fallback: dev
  3241. """
  3242. )
  3243. self.assertEqual(
  3244. ret,
  3245. {
  3246. "branch": "dev",
  3247. "motd": "The force will be with you. Always.",
  3248. "mylist": ["dev"],
  3249. "mydict": {
  3250. "dev": True,
  3251. "nested_list": ["dev"],
  3252. "nested_dict": {"dev": True},
  3253. },
  3254. },
  3255. )