2323import os
2424import os .path
2525import signal
26+ import socket
2627import sys
2728import threading
2829import time
@@ -444,7 +445,7 @@ def _update_gtm(self, config):
444445 partition = "Common"
445446 try :
446447 allConfig = get_gtm_config (config )
447- if not bool (allConfig ):
448+ if bool (allConfig ):
448449 newGtmConfig = allConfig ["config" ]
449450 self ._deleted_tenants = allConfig ["deletedTenants" ]
450451 mgr ._gtm .pre_process_gtm (newGtmConfig )
@@ -1631,23 +1632,121 @@ def _handle_global_config(config):
16311632 # level only is needed for unit tests
16321633 return verify_interval , level , vxlan_partition
16331634
1635+ def get_credentials ():
1636+ """
1637+ Unified function to retrieve credentials.
1638+ First tries Unix socket, then falls back to environment variables.
1639+ Returns:
1640+ dict: {'username': '...', 'password': '...'}
1641+ """
1642+ # First check credentials over Unix Socket
1643+ credentials = get_credentials_from_socket ()
1644+ if credentials :
1645+ return credentials
1646+
1647+ # Check Environment Variables
1648+ credential_sources = tuple ()
1649+ if not credentials or not credentials ["bigip_username" ]:
1650+ credential_sources = credential_sources + (('bigip' , get_credentials_from_env ),)
1651+
1652+ if not credentials or not credentials ["gtm_username" ]:
1653+ credential_sources = credential_sources + (('gtm' , get_gtm_credentials_from_env ),)
1654+
1655+ credentials = {}
1656+ for prefix , fetch_func in credential_sources :
1657+ env_credentials = fetch_func ()
1658+ if env_credentials :
1659+ username , password = env_credentials
1660+ credentials [f'{ prefix } _username' ] = username
1661+ credentials [f'{ prefix } _password' ] = password
1662+
1663+ if not credentials ["gtm_username" ] or credentials ["gtm_username" ] == "" :
1664+ credentials ["gtm_username" ] = credentials ["bigip_username" ]
1665+ if not credentials ["gtm_password" ] or credentials ["gtm_password" ] == "" :
1666+ credentials ["gtm_password" ] = credentials ["bigip_password" ]
1667+
1668+ return credentials
1669+
1670+
1671+ def get_credentials_from_env ():
1672+ """
1673+ Retrieve credentials from environment variables.
1674+ Returns:
1675+ tuple: (username, password) if found, else None.
1676+ """
1677+ log .debug ("Checking for credentials in environment variables..." )
1678+ username = os .getenv ("BIGIP_USERNAME" )
1679+ password = os .getenv ("BIGIP_PASSWORD" )
1680+
1681+ if username and password :
1682+ log .info ("successfully fetched BIGIP credentials from environment variables." )
1683+ return username , password
1684+ else :
1685+ log .error ("Failed to get BIGIP credentials from environment variables." )
1686+ return None
1687+
1688+ def get_gtm_credentials_from_env ():
1689+ """
1690+ Retrieve credentials from environment variables.
1691+ Returns:
1692+ tuple: (username, password) if found, else None.
1693+ """
1694+ log .debug ("Checking for GTM credentials in environment variables..." )
1695+ username = os .getenv ("GTM_BIGIP_USERNAME" )
1696+ password = os .getenv ("GTM_BIGIP_PASSWORD" )
1697+
1698+ if username and password :
1699+ log .info ("successfully fetched GTM credentials from environment variables." )
1700+ return username , password
1701+ else :
1702+ log .error ("Failed to get GTM credentials from environment variables." )
1703+ return None
1704+
1705+ def get_credentials_from_socket ():
1706+ socket_path = "/tmp/secure_cis.sock"
1707+ client = None
1708+
1709+ if not os .path .exists (socket_path ):
1710+ log .error (f"Socket file not found: { socket_path } " )
1711+ return None
1712+ try :
1713+ client = socket .socket (socket .AF_UNIX , socket .SOCK_STREAM )
1714+ client .connect (socket_path )
1715+ log .info ("Connected to server." )
1716+
1717+ data = client .recv (4096 ).decode ('utf-8' )
1718+ credentials = json .loads (data )
1719+ if credentials :
1720+ if credentials .get ('bigip_username' , '' ) != "" and credentials .get ('bigip_password' , '' ) != "" :
1721+ log .info ("successfully fetched BIGIP credentials from socket." )
1722+ if credentials .get ('gtm_username' , '' ) != "" and credentials .get ('gtm_password' , '' ) != "" :
1723+ log .info ("successfully fetched GTM credentials from socket." )
1724+ return credentials
1725+
1726+ except ConnectionError as e :
1727+ log .error (f"Connection failed: { e } " )
1728+ finally :
1729+ client .close ()
1730+
1731+
16341732
16351733def _handle_bigip_config (config ):
16361734 if (not config ) or ('bigip' not in config ):
16371735 raise ConfigError ('Configuration file missing "bigip" section' )
16381736 bigip = config ['bigip' ]
1639- if 'username' not in bigip :
1640- raise ConfigError ('Configuration file missing '
1641- '"bigip:username" section' )
1642- if 'password' not in bigip :
1643- raise ConfigError ('Configuration file missing '
1644- '"bigip:password" section' )
16451737 if 'url' not in bigip :
16461738 raise ConfigError ('Configuration file missing "bigip:url" section' )
16471739 if ('partitions' not in bigip ) or (len (bigip ['partitions' ]) == 0 ):
16481740 raise ConfigError ('Configuration file must specify at least one '
16491741 'partition in the "bigip:partitions" section' )
16501742
1743+ if 'username' not in config ['bigip' ]:
1744+ raise ConfigError ('missing config '
1745+ '"bigip:username" section' )
1746+ if 'password' not in config ['bigip' ]:
1747+ raise ConfigError ('missing config '
1748+ '"bigip:password" section' )
1749+
16511750 url = urlparse (bigip ['url' ])
16521751 host = url .hostname
16531752 port = url .port
@@ -1656,6 +1755,18 @@ def _handle_bigip_config(config):
16561755
16571756 return host , port
16581757
1758+ def _handle_credentials (config ):
1759+ credentials = get_credentials ()
1760+ if credentials :
1761+ config ['bigip' ]['username' ] = credentials .get ('bigip_username' , '' )
1762+ config ['bigip' ]['password' ] = credentials .get ('bigip_password' , '' )
1763+ if 'gtm_bigip' in config :
1764+ config ['gtm_bigip' ]['username' ] = credentials .get ('gtm_username' , '' )
1765+ config ['gtm_bigip' ]['password' ] = credentials .get ('gtm_password' , '' )
1766+ else :
1767+ log .error ("Failed to retrieve credentials." )
1768+ return config
1769+
16591770
16601771def _handle_vxlan_config (config ):
16611772 if config and 'vxlan-fdb' in config :
@@ -1768,6 +1879,7 @@ def main():
17681879
17691880 config = _parse_config (args .config_file )
17701881 verify_interval , _ , vxlan_partition = _handle_global_config (config )
1882+ config = _handle_credentials (config )
17711883 host , port = _handle_bigip_config (config )
17721884
17731885 # FIXME (kenr): Big-IP settings are currently static (we ignore any
0 commit comments