Cranspassword integration
parent
47c8f27682
commit
d425f154f5
|
@ -1 +1,3 @@
|
||||||
*.retry
|
*.retry
|
||||||
|
scripts/inventory_re2o.ini
|
||||||
|
__pycache__
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
# Do not create .retry files
|
# Do not create .retry files
|
||||||
retry_files_enabled = False
|
retry_files_enabled = False
|
||||||
|
|
||||||
# Use inventory
|
# Generate inventory
|
||||||
|
#inventory = ./scripts/inventory_re2o.py
|
||||||
inventory = ./hosts
|
inventory = ./hosts
|
||||||
|
|
||||||
# Custom header in templates
|
# 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