diff --git a/.gitignore b/.gitignore index 2d2b4a1..d07af72 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ inventory test.yml __pycache__ infisical-vault-1.0.0.tar.gz + +.vscode \ No newline at end of file diff --git a/README.md b/README.md index d4c24da..952777a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ You can install the Infisical collection with the Ansible Galaxy CLI: The python module dependencies are not installed by `ansible-galaxy`. They can be manually installed using pip: - pip install infisical-python + pip install infisicalsdk ## Using this collection @@ -38,6 +38,6 @@ vars: # {"SECRET_KEY_1": "secret-value-1", "SECRET_KEY_2": "secret-value-2"} -> Can be accessed as secrets.SECRET_KEY_1 read_secret_by_name_within_scope: "{{ lookup('infisical.vault.read_secrets', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', secret_name='HOST', url='https://spotify.infisical.com') }}" - # [{ "key": "HOST", "value": "google.com" }] + # { "key": "HOST", "value": "google.com" } ``` diff --git a/plugins/lookup/read_secrets.py b/plugins/lookup/read_secrets.py index e843530..080c26b 100644 --- a/plugins/lookup/read_secrets.py +++ b/plugins/lookup/read_secrets.py @@ -23,6 +23,7 @@ options: description: The Machine Identity Client ID used to authenticate env: - name: UNIVERSAL_AUTH_MACHINE_IDENTITY_CLIENT_ID + - name: INFISICAL_UNIVERSAL_AUTH_CLIENT_ID required: True type: string version_added: 1.0.0 @@ -30,6 +31,7 @@ options: description: The Machine Identity Client Secret used to authenticate env: - name: UNIVERSAL_AUTH_MACHINE_IDENTITY_CLIENT_SECRET + - name: INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET required: True type: string version_added: 1.0.0 @@ -57,10 +59,15 @@ options: type: string version_added: 1.0.0 secret_name: - description: The name of the secret that should be fetched. The name should be exactly as it appears in Infisical + description: The name of the secret that should be fetched. The name should be exactly as it appears in Infisical. required: False type: string version_added: 1.0.0 + as_dict: + description: "Return the listed secrets as a dictionary within a list instead of a list of key-value pairs (defaults to False). When True, returns [{'SECRET_KEY': 'secret_value', ...}] instead of [{'key': 'SECRET_KEY', 'value': 'secret_value'}, ...]. This only applies when reading all secrets within a scope, not when reading a single secret by name." + required: False + type: bool + version_added: 1.0.0 """ EXAMPLES = r""" @@ -68,6 +75,9 @@ vars: read_all_secrets_within_scope: "{{ lookup('infisical_vault', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', url='https://spotify.infisical.com') }}" # [{ "key": "HOST", "value": "google.com" }, { "key": "SMTP", "value": "gmail.smtp.edu" }] + read_all_secrets_as_dict: "{{ lookup('infisical_vault', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', as_dict=True, url='https://spotify.infisical.com') }}" + # {"HOST": "google.com", "SMTP": "gmail.smtp.edu"} + read_secret_by_name_within_scope: "{{ lookup('infisical_vault', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', secret_name='HOST', url='https://spotify.infisical.com') }}" # [{ "key": "HOST", "value": "google.com" }] """ @@ -75,6 +85,7 @@ vars: class LookupModule(LookupBase): def run(self, terms, variables=None, **kwargs): + self.set_options(var_options=variables, direct=kwargs) if not HAS_INFISICAL: raise AnsibleError("Please pip install infisicalsdk to use the infisical_vault lookup module.") @@ -95,6 +106,7 @@ class LookupModule(LookupBase): ) secretName = kwargs.get('secret_name') + asDict = kwargs.get('as_dict') envSlug = kwargs.get('env_slug') path = kwargs.get('path') project_id = kwargs.get('project_id') @@ -105,10 +117,10 @@ class LookupModule(LookupBase): project_id, secretName, envSlug, - path + path, ) else: - return self.get_all_secrets(client, project_id, envSlug, path) + return self.get_all_secrets(client, project_id, envSlug, path, asDict) def get_single_secret( self, @@ -128,10 +140,9 @@ class LookupModule(LookupBase): return [{"value": secret.secretValue, "key": secret.secretKey}] except Exception as e: - print(e) raise AnsibleError(f"Error fetching single secret {e}") - def get_all_secrets(self, client, project_id, environment="dev", path="/"): + def get_all_secrets(self, client, project_id, environment="dev", path="/", asDict=False): try: secrets = client.secrets.list_secrets( project_id=project_id, @@ -139,7 +150,10 @@ class LookupModule(LookupBase): secret_path=path ) - return [{"value": s.secretValue, "key": s.secretKey} for s in secrets.secrets] + if asDict: + return [{s.secretKey: s.secretValue for s in secrets.secrets}] + else: + return [{"value": s.secretValue, "key": s.secretKey} for s in secrets.secrets] except Exception as e: raise AnsibleError(f"Error fetching all secrets {e}")