私はPythonスクリプトに以下の機能を提供して、それができるようにする方法を理解しようとしています:
ansible.cfg
とvault_password_file
変数vault_password_file
とPython変数に一時的に保存します私は google経由のこのコード を見つけましたが、試したときに機能していないようです:
import ansible.utils
bar = dict()
bar = ansible.utils._load_vars_from_path("secrets.yml", results=bar, vault_password="password")
print bar
このエラーをスローします:
$ python ansible-vault-ex.py
Traceback (most recent call last):
File "ansible-vault-ex.py", line 5, in <module>
bar = ansible.utils._load_vars_from_path("credentials.vault", results=bar, vault_password="password")
AttributeError: 'module' object has no attribute '_load_vars_from_path'
これを調査したところ、Ansibleの関連ファイルにこの関数の兆候が見られなかったため、このメソッドが一部の新しいバージョンのAnsibleでは機能しなくなったと思いました。
結論としては、PythonスクリプトからAnsibleライブラリ/モジュールをインポートするためのいくつかの方法が欲しいので、ansible-vault
Pythonからプログラムで管理されたファイル。
Kubaの答えを拡張して、ansible-vaultはVaultLibのラッパーです。これは、Ansible 2.4より前のバージョンのVaultlibと、2.4より後のバージョンをうまく処理します。
Ansible-vault load()メソッドはファイルを復号化するだけでなく、ファイルを解析して内容をdictとして返します。解析せずにコンテンツが必要な場合は、おそらく次のようなものでansible-vaultを拡張するのが最も簡単です。
from ansible_vault import Vault
class MyVault(Vault):
def load_raw(self, stream):
return self.vault.decrypt(stream)
def dump_raw(self, text, stream=None):
encrypted = self.vault.encrypt(text)
if stream:
stream.write(encrypted)
else:
return encrypted
ansible-vaultパッケージ の使用を検討してください
次の方法でインストールします。
$ pip install ansible-vault
そしてそれは次のように簡単です:
from ansible_vault import Vault
vault = Vault('password')
print vault.load(open('/path/to/your/vault.yml').read())
Ansibleコードを使用するには、そのパッケージの source を直接調べます。最も簡単なのは:
Ansible<= 2.3
from ansible.parsing.vault import VaultLib
vault = VaultLib('password')
print vault.decrypt(open('/path/to/vault.yml').read())
Ansible> = 2.4
from ansible.constants import DEFAULT_VAULT_ID_MATCH
from ansible.parsing.vault import VaultLib
from ansible.parsing.vault import VaultSecret
vault = VaultLib([(DEFAULT_VAULT_ID_MATCH, VaultSecret('password'))])
print vault.decrypt(open('/path/to/vault.yml').read())
ソースコードの量は同じですが、パッケージは両方のAnsibleバージョンの自動yaml解析+処理を提供します。
Ansible.cfgでvault_password_fileを設定している場合、次のようにパスワードをVaultLibに渡すことができます
インポート:
from ansible import constants as C
from ansible.parsing.vault import VaultLib
from ansible.cli import CLI
from ansible.parsing.dataloader import DataLoader
そして、あなたは呼び出すことができます:
loader = DataLoader()
vault_secret = CLI.setup_vault_secrets(
loader=loader,
vault_ids=C.DEFAULT_VAULT_IDENTITY_LIST
)
vault = VaultLib(vault_secret)
vault.decrypt(open('/path/to/vault.yml').read())
上記の回答で復号化を機能させることはできませんでしたが、サブプロセスを使用して適切に機能する関数がここにあります。
def vault_decrypt(text, vault_password_file):
"""
Calls ansible vault and pass the payload via stdin
:param text: str, text to decode
:param vault_password_file: str, vault password
:return: str, decoded text
"""
cmd = ['ansible-vault', 'decrypt', '--vault-password-file={}'.format(vault_password_file)]
p = Popen(cmd,
stdout=PIPE, stdin=PIPE, stderr=PIPE)
output = p.communicate(input=str.encode(text))
return output[0].decode("utf-8")
Ansible pythonモジュールを直接使用するように更新した場合、直接更新します。乾杯。
暗号化されたファイルをAnsible Python API、よろしいですか?
Ansible 2.0以降:
def execute_ansible_command(play_source, stdout_callback):
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.inventory import Inventory
from ansible.parsing.dataloader import DataLoader
from ansible.playbook import Play
from ansible.vars import VariableManager
Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'remote_user',
'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args',
'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity',
'check'])
variable_manager = VariableManager()
loader = DataLoader()
loader.set_vault_password(ANSIBLE_VAULT_PASS)
options = Options(connection='smart', module_path=None, forks=100,
remote_user=None, private_key_file=None, ssh_common_args="-o StrictHostKeyChecking=no",
ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=None,
become_method=None, become_user=None, verbosity=None, check=False)
passwords = dict()
inventory = Inventory(loader=loader, variable_manager=variable_manager, Host_list=ANSIBLE_INVENTORY)
variable_manager.set_inventory(inventory)
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
tqm = None
try:
tqm = TaskQueueManager(
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
options=options,
passwords=passwords,
stdout_callback=stdout_callback,
)
tqm.run(play)
finally:
if tqm is not None:
tqm.cleanup()
DataLoaderクラスは、YAMLまたはJSONコンテンツの読み込みと解析に使用され、set_vault_password
関数、ボールトのパスワードを送信して、ボールトで暗号化されたファイルを復号化できます
yaferファイル全体が暗号化されている場合、broferekの答えは機能します。 yamlファイルが暗号化されていないが暗号化された変数が含まれている場合、文句を言うでしょう。これはどちらの方法でも機能するはずです。
インポート:
from ansible import constants as C
from ansible.cli import CLI
from ansible.parsing.vault import VaultLib
from ansible.parsing.dataloader import DataLoader
次に、DataLoaderクラスを使用してファイルをdictに読み込みます
cfgfile = "/path/to/yaml/file.yml"
loader = DataLoader()
vault_secrets = CLI.setup_vault_secrets(loader=loader,
vault_ids=C.DEFAULT_VAULT_IDENTITY_LIST)
loader.set_vault_secrets(vault_secrets)
data = loader.load_from_file(cfgfile)
pprint.pprint(data)
これは正確には私が望んでいることではありませんが、subprocess
を介してansible view <vaultfile>
コマンドを実行することにより、上記の問題を回避しました。
import subprocess
import yaml
def getCreds():
cmd = "ansible-vault view credentials.vault"
process = subprocess.Popen(cmd, Shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(result, error) = process.communicate()
resultYaml = yaml.load(result)
accesskey = resultYaml['accesskey']
secretkey = resultYaml['secretkey']
return(accesskey, secretkey)
Pythonで直接Ansibleメソッドを直接呼び出すことは、依然として最善でしょう。