Cranspassword integration
parent
47c8f27682
commit
d425f154f5
|
@ -1 +1,3 @@
|
|||
*.retry
|
||||
scripts/inventory_re2o.ini
|
||||
__pycache__
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
# Do not create .retry files
|
||||
retry_files_enabled = False
|
||||
|
||||
# Use inventory
|
||||
# Generate inventory
|
||||
#inventory = ./scripts/inventory_re2o.py
|
||||
inventory = ./hosts
|
||||
|
||||
# Custom header in templates
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
$ANSIBLE_VAULT;1.1;AES256
|
||||
37373933363563303566623732633165343839663164663535316638633462626636326135316534
|
||||
3839346634623331363336663863353363376665613764390a383866613635363238323637386235
|
||||
61623963366463636561346162616532626133306165343161393333616363656339643933393531
|
||||
6662343239653361320a633064306238363836346166653931356334376537636266646237323438
|
||||
65316261636463336261643831653661383863346633323764346339373834363433373730383861
|
||||
64613139366566653035656531363933313234343265653535636464323839336165653637323432
|
||||
61386236383830663230613335303437633737346232316135353262396433376439643562353438
|
||||
62393431396262383965303436663431326239626666353735636465656530333236326137313062
|
||||
38323866346433646261633633373031346334396561323536376563363035633565643137346137
|
||||
33393930326166303439623463623631333339383566383565363536333036626630303130633432
|
||||
32646364336665363966626665323465346363346137636536303362663935643831326536633739
|
||||
34353361656635623965383332643936336663373330653563353837353230326531366238353035
|
||||
32356465653966643831633963623239666136393436663932353366633231343534626234336539
|
||||
32663133616162366238323635616531373335383535653732373432613938396535343339383037
|
||||
37376461646438383434633364373339303137333134333138323630633731366533633061373634
|
||||
38353034356332373134373833393431346539306265313965623663343433343361613634646563
|
||||
35383234623362633935383362393763363938643864373266336339373265353933336232303965
|
||||
61666133356430663764323437373632643533333066616232336236633164363965356339326161
|
||||
63626437663736666536373965316230303239653764356338613638623233643835383637386661
|
||||
38616330623739306338396639323739383661363431396531613963393732396433346363616438
|
||||
33303030663231313263616163346563336631643563316465373866383162356562653165333766
|
||||
33333966303932396336393263363039383930353334313061316335313238363564313639646637
|
||||
34316562386366306238376465326631336539643936663264306631303335346131343939663965
|
||||
62316566393236643938633731356465373435646238646661333935323563333231363361663638
|
||||
31313832613032636466316263386561363665333432653931393835346535653837303937363764
|
||||
65353561326162313831303865393665353732346536653262316131643863373039636336616132
|
||||
38666362363137663266306634346438636430353036616536613332376535633662326432383431
|
||||
66353539376132373165633634376230393738393831313831663535613430633937383732356163
|
||||
32356639626237303861336364376663306465393130373136366461666233626333346437316563
|
||||
65616132326637313134656665323439366362613634376536373631656234343934396532333539
|
||||
62306163313062393365613338326464633136376562383130303638616364366139373734346236
|
||||
36333665306666633465396437633161356664643235326665633537666366316662643339626430
|
||||
66393335343463663662363561626534386435373636626131393263626664336164633062393239
|
||||
39613737383834363661343662323436326236326464343732326232316264303135613035323039
|
||||
62313539363532333738343664663830373163346436636533663164333438623338623332303136
|
||||
37633065336162326361333430363464656662626237366530343765643937333866373831666336
|
||||
36333363633830343836383235613562633435663166386264343936666264323561343938393232
|
||||
38323235636266616266333535376661663063363562376461336437376661633734633165326661
|
||||
326437613235333261643465663663343838
|
|
@ -0,0 +1,7 @@
|
|||
# Ansible Re2o Inventory settings
|
||||
#
|
||||
|
||||
[Re2o]
|
||||
hostname = re2o.example.net
|
||||
username = my_api_username
|
||||
password = my_api_password
|
|
@ -0,0 +1,6 @@
|
|||
# Ansible Vault CransPassword settings
|
||||
#
|
||||
|
||||
[cranspassword]
|
||||
#: Commande exécutée sur le client pour appeler le script sur le serveur distant.
|
||||
server_cmd=/usr/bin/ssh odlyd.crans.org sudo -n /usr/local/bin/cranspasswords-server
|
|
@ -0,0 +1,112 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# (c) 2019 Cr@ns <roots@crans.org>
|
||||
# Authors : Alexandre IOOSS <erdnaxe@crans.org>
|
||||
# Based on cranspasswords by : Daniel Stan <daniel.stan@crans.org>
|
||||
# Vincent Le Gallic <legallic@crans.org>
|
||||
#
|
||||
# This file is part of Cr@ns ansible deploiement
|
||||
|
||||
"""
|
||||
Ansible Vault CransPassword script.
|
||||
========================================
|
||||
|
||||
Returns Ansible vault from CransPassword.
|
||||
|
||||
Configuration is read from `vault_cranspassword.ini`.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from ansible.module_utils.six.moves import configparser
|
||||
from ansible.plugins.vars import BaseVarsPlugin
|
||||
|
||||
|
||||
class VarsModule(BaseVarsPlugin):
|
||||
@staticmethod
|
||||
def gpg_decrypt(crypt_text):
|
||||
full_command = ['gpg', '-d']
|
||||
proc = subprocess.Popen(full_command,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=sys.stderr,
|
||||
close_fds=True)
|
||||
proc.stdin.write(crypt_text.encode())
|
||||
proc.stdin.close()
|
||||
clear_text = proc.stdout.read().decode()
|
||||
return clear_text
|
||||
|
||||
def getfile_command(self, filename):
|
||||
"""Exécute la commande distante, et retourne la sortie de cette
|
||||
commande"""
|
||||
# Get full command from settings file
|
||||
command = self.config.get('cranspassword', 'server_cmd').split(" ")
|
||||
command.append("getfiles")
|
||||
proc = subprocess.Popen(
|
||||
command,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=sys.stderr,
|
||||
close_fds=True
|
||||
)
|
||||
proc.stdin.write(json.dumps([filename]).encode())
|
||||
proc.stdin.flush()
|
||||
|
||||
raw_out, raw_err = proc.communicate()
|
||||
ret = proc.returncode
|
||||
|
||||
if ret != 0:
|
||||
print("Mauvais code retour côté serveur", file=sys.stderr)
|
||||
sys.exit(ret)
|
||||
|
||||
try:
|
||||
answer = json.loads(raw_out.strip())
|
||||
except ValueError:
|
||||
print("Impossible de parser le résultat", file=sys.stderr)
|
||||
sys.exit(42)
|
||||
|
||||
return answer[0]
|
||||
|
||||
def get_encrypted(self, filename):
|
||||
"""
|
||||
Get encrypted content of a cranspassword file
|
||||
"""
|
||||
gotit, value = self.getfile_command(filename)
|
||||
if not gotit:
|
||||
print(value, file=sys.stderr) # value contient le message d'erreur
|
||||
else:
|
||||
crypt_text = value['contents']
|
||||
return crypt_text
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
# Load config
|
||||
self.config = configparser.ConfigParser()
|
||||
self.config.read(os.path.dirname(os.path.realpath(__file__))
|
||||
+ '/vault_cranspassword.ini')
|
||||
|
||||
def get_vars(self, loader, path, entities, cache=True):
|
||||
"""
|
||||
Get all vars for entities, called by Ansible
|
||||
"""
|
||||
super().get_vars(loader, path, entities)
|
||||
|
||||
# We do not want to request N time the same file from cranspassword
|
||||
# But VarsModule object get instanced each time
|
||||
# So the hack is to use loader._FILE_CACHE that *should* be private
|
||||
# Sorry for this, don't judge me on this please <3
|
||||
|
||||
if 'cranspassword' not in loader._FILE_CACHE:
|
||||
# Get text then decrypt and return
|
||||
crypt_text = self.get_encrypted('ansible_vault')
|
||||
clear_text = self.gpg_decrypt(crypt_text)
|
||||
data = loader.load(clear_text)
|
||||
loader._FILE_CACHE['cranspassword'] = data
|
||||
else:
|
||||
data = loader._FILE_CACHE['cranspassword']
|
||||
|
||||
return data
|
Loading…
Reference in New Issue