66import os
77import re
88
9- from ansible .errors import AnsibleError
10- from ansible .plugins .lookup import LookupBase
11- from ansible .utils .display import Display
12-
139try :
1410 from ansible_collections .devolutions .dvls .plugins .module_utils .auth import (
1511 login ,
1915 get_vault_entry ,
2016 get_vault_entry_from_name ,
2117 )
22- except ImportError as e :
23- raise AnsibleError (f"Failed to import DVLS module_utils: { e } " )
24-
25- display = Display ()
18+ except ImportError :
19+ # Will be caught by lookup plugins
20+ pass
2621
2722UUID_PATTERN = re .compile (
2823 r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" ,
4540}
4641
4742
48- class BaseDVLSLookup (LookupBase ):
49- """Base class for DVLS lookup plugins with shared authentication and retrieval logic."""
43+ class DVLSLookupHelper :
44+ """Helper class for DVLS lookup plugins with shared authentication and retrieval logic."""
45+
46+ def __init__ (self , display_instance , ansible_error_class ):
47+ """
48+ Initialize the helper.
5049
51- def __init__ (self , * args , ** kwargs ):
52- super (BaseDVLSLookup , self ).__init__ (* args , ** kwargs )
50+ Args:
51+ display_instance: Display instance for logging
52+ ansible_error_class: AnsibleError class for raising exceptions
53+ """
5354 self ._token = None
5455 self ._server_base_url = None
5556 self ._cleanup_registered = False
57+ self ._display = display_instance
58+ self ._ansible_error = ansible_error_class
5659
5760 def _cleanup (self ):
5861 """Cleanup method called at interpreter exit"""
5962 if self ._token and self ._server_base_url :
6063 try :
61- display .vvv ("Logging out from DVLS" )
64+ self . _display .vvv ("Logging out from DVLS" )
6265 logout (self ._server_base_url , self ._token )
6366 except Exception as e :
64- display .warning (f"Failed to logout from DVLS during cleanup: { e } " )
67+ self . _display .warning (f"Failed to logout from DVLS during cleanup: { e } " )
6568
6669 def _is_uuid (self , value ):
6770 """Check if a string matches UUID format"""
6871 return UUID_PATTERN .match (value ) is not None
6972
70- def _get_config (self , variables ):
73+ def get_config (self , get_option , variables ):
7174 """Extract configuration from options and environment variables"""
72- server_base_url = self . get_option ("server_base_url" ) or os .environ .get (
75+ server_base_url = get_option ("server_base_url" ) or os .environ .get (
7376 "DVLS_SERVER_BASE_URL"
7477 )
75- app_key = self . get_option ("app_key" ) or os .environ .get ("DVLS_APP_KEY" )
76- app_secret = self . get_option ("app_secret" ) or os .environ .get ("DVLS_APP_SECRET" )
77- vault_id = self . get_option ("vault_id" ) or os .environ .get ("DVLS_VAULT_ID" )
78+ app_key = get_option ("app_key" ) or os .environ .get ("DVLS_APP_KEY" )
79+ app_secret = get_option ("app_secret" ) or os .environ .get ("DVLS_APP_SECRET" )
80+ vault_id = get_option ("vault_id" ) or os .environ .get ("DVLS_VAULT_ID" )
7881
7982 if not all ([server_base_url , app_key , app_secret , vault_id ]):
80- raise AnsibleError (
83+ raise self . _ansible_error (
8184 "Missing required configuration. Set DVLS_SERVER_BASE_URL, DVLS_APP_KEY, "
8285 "DVLS_APP_SECRET, and DVLS_VAULT_ID environment variables or pass as parameters."
8386 )
@@ -89,21 +92,21 @@ def _get_config(self, variables):
8992 "vault_id" : vault_id ,
9093 }
9194
92- def _authenticate (self , server_base_url , app_key , app_secret ):
95+ def authenticate (self , server_base_url , app_key , app_secret ):
9396 """Authenticate to DVLS and cache the token"""
9497 if not self ._token :
9598 try :
96- display .vvv (f"Authenticating to DVLS at { server_base_url } " )
99+ self . _display .vvv (f"Authenticating to DVLS at { server_base_url } " )
97100 self ._token = login (server_base_url , app_key , app_secret )
98101 self ._server_base_url = server_base_url
99102
100103 if not self ._cleanup_registered :
101104 atexit .register (self ._cleanup )
102105 self ._cleanup_registered = True
103106 except Exception as e :
104- raise AnsibleError (f"DVLS authentication failed: { e } " ) from e
107+ raise self . _ansible_error (f"DVLS authentication failed: { e } " ) from e
105108
106- def _get_credential (self , server_base_url , vault_id , term ):
109+ def get_credential (self , server_base_url , vault_id , term ):
107110 """
108111 Retrieve a credential from DVLS by name or UUID.
109112
@@ -115,70 +118,26 @@ def _get_credential(self, server_base_url, vault_id, term):
115118 Returns:
116119 dict: Complete credential object
117120 """
118- display .vvv (f"Looking up credential: { term } " )
121+ self . _display .vvv (f"Looking up credential: { term } " )
119122
120123 if self ._is_uuid (term ):
121- display .vvv (f"Using ID lookup for { term } " )
124+ self . _display .vvv (f"Using ID lookup for { term } " )
122125 response = get_vault_entry (server_base_url , self ._token , vault_id , term )
123126 credential = response .get ("data" , {})
124127 else :
125- display .vvv (f"Using name lookup for { term } " )
128+ self . _display .vvv (f"Using name lookup for { term } " )
126129 response = get_vault_entry_from_name (
127130 server_base_url , self ._token , vault_id , term
128131 )
129132 entries = response .get ("data" , [])
130133 if not entries :
131- raise AnsibleError (f"Credential '{ term } ' not found in vault { vault_id } " )
134+ raise self ._ansible_error (
135+ f"Credential '{ term } ' not found in vault { vault_id } "
136+ )
132137 entry_id = entries [0 ].get ("id" )
133138 full_response = get_vault_entry (
134139 server_base_url , self ._token , vault_id , entry_id
135140 )
136141 credential = full_response .get ("data" , {})
137142
138143 return credential
139-
140- def transform_result (self , credential , term ):
141- """
142- Transform the credential into the desired output format.
143-
144- This method must be implemented by subclasses.
145-
146- Args:
147- credential: Complete credential object from DVLS
148- term: Original lookup term
149-
150- Returns:
151- The transformed result (field value, full object, etc.)
152- """
153- raise NotImplementedError ("Subclasses must implement transform_result()" )
154-
155- def run (self , terms , variables = None , ** kwargs ):
156- """
157- Main lookup execution method.
158-
159- Handles authentication, credential retrieval, and result transformation.
160- """
161- self .set_options (var_options = variables , direct = kwargs )
162-
163- config = self ._get_config (variables )
164- self ._authenticate (
165- config ["server_base_url" ], config ["app_key" ], config ["app_secret" ]
166- )
167-
168- results = []
169- for term in terms :
170- try :
171- credential = self ._get_credential (
172- config ["server_base_url" ], config ["vault_id" ], term
173- )
174- result = self .transform_result (credential , term )
175- results .append (result )
176-
177- except AnsibleError :
178- raise
179- except Exception as e :
180- raise AnsibleError (
181- f"Failed to retrieve credential '{ term } ': { e } "
182- ) from e
183-
184- return results
0 commit comments