55#
66import base64
77
8+ from connectors .agent .logger import get_logger
89from connectors .config import add_defaults
10+ from connectors .utils import nested_get_from_dict
11+
12+ logger = get_logger ("config" )
913
1014
1115class ConnectorsAgentConfigurationWrapper :
@@ -25,10 +29,11 @@ def __init__(self):
2529 Service config and specific config coming from Agent.
2630 """
2731 self ._default_config = {
28- "_force_allow_native" : True ,
2932 "service" : {
33+ "log_level" : "INFO" ,
3034 "_use_native_connector_api_keys" : False ,
3135 },
36+ "_force_allow_native" : True ,
3237 "native_service_types" : [
3338 "azure_blob_storage" ,
3439 "box" ,
@@ -60,7 +65,7 @@ def __init__(self):
6065
6166 self .specific_config = {}
6267
63- def try_update (self , source ):
68+ def try_update (self , unit ):
6469 """Try update the configuration and see if it changed.
6570
6671 This method takes the check-in event coming from Agent and checks if config needs an update.
@@ -69,33 +74,92 @@ def try_update(self, source):
6974 the method returns False.
7075 """
7176
77+ source = unit .config .source
78+
7279 # TODO: find a good link to what this object is.
7380 has_hosts = source .fields .get ("hosts" )
7481 has_api_key = source .fields .get ("api_key" )
7582 has_basic_auth = source .fields .get ("username" ) and source .fields .get ("password" )
83+
84+ assumed_configuration = {}
85+
86+ # Log-related
87+ assumed_configuration ["service" ] = {}
88+ assumed_configuration ["service" ]["log_level" ] = unit .log_level
89+
90+ # Auth-related
7691 if has_hosts and (has_api_key or has_basic_auth ):
77- es_creds = {
78- "host" : source ["hosts" ][0 ],
79- }
92+ es_creds = {"host" : source ["hosts" ][0 ]}
8093
8194 if source .fields .get ("api_key" ):
95+ logger .debug ("Found api_key" )
8296 api_key = source ["api_key" ]
8397 # if beats_logstash_format we need to base64 the key
8498 if ":" in api_key :
8599 api_key = base64 .b64encode (api_key .encode ()).decode ()
86100
87101 es_creds ["api_key" ] = api_key
88102 elif source .fields .get ("username" ) and source .fields .get ("password" ):
103+ logger .debug ("Found username and passowrd" )
89104 es_creds ["username" ] = source ["username" ]
90105 es_creds ["password" ] = source ["password" ]
91106 else :
92107 msg = "Invalid Elasticsearch credentials"
93108 raise ValueError (msg )
94109
95- new_config = {
96- "elasticsearch" : es_creds ,
97- }
98- self .specific_config = new_config
110+ assumed_configuration ["elasticsearch" ] = es_creds
111+
112+ if self .config_changed (assumed_configuration ):
113+ logger .debug ("Changes detected for connectors-relevant configurations" )
114+ # This is a partial update.
115+ # Agent can send different data in updates.
116+ # For example, updating only log_level will not send credentials.
117+ # Thus we don't overwrite configuration, we only update fields that
118+ # were received
119+ self .specific_config .update (assumed_configuration )
120+ return True
121+
122+ logger .debug ("No changes detected for connectors-relevant configurations" )
123+ return False
124+
125+ def config_changed (self , new_config ):
126+ """See if configuration passed in new_config will update currently stored configuration
127+
128+ This method takes the new configuration received from the agent and see if there are any changes
129+ to existing configuration.
130+
131+ If new_config contains new values for relevant fields, then True is returned, otherwise it returns False.
132+ """
133+ # TODO: For now manually check, need to think of a better way?
134+ # Not super proud of this function, but hey it's tested
135+ logger .debug ("Checking if config changed" )
136+ current_config = self ._default_config .copy ()
137+ current_config .update (self .specific_config )
138+
139+ def _log_level_changed ():
140+ new_config_log_level = nested_get_from_dict (
141+ new_config , ("service" , "log_level" )
142+ )
143+ current_config_log_level = nested_get_from_dict (
144+ current_config , ("service" , "log_level" )
145+ )
146+
147+ if new_config_log_level is None :
148+ return False
149+
150+ return current_config_log_level != new_config_log_level
151+
152+ def _elasticsearch_config_changed ():
153+ return current_config .get ("elasticsearch" ) != new_config .get (
154+ "elasticsearch"
155+ )
156+
157+ if _log_level_changed ():
158+ logger .debug ("log_level changed" )
159+ return True
160+
161+ if _elasticsearch_config_changed ():
162+ logger .debug ("elasticsearch changed" )
99163 return True
100164
101165 return False
@@ -112,8 +176,8 @@ def get(self):
112176 """
113177 # First take "default config"
114178 config = self ._default_config .copy ()
115- # Then override with what we get from Agent
116- config . update ( self .specific_config )
179+ # Then merge with what we get from Agent
180+ config = dict ( add_defaults ( self .specific_config , default_config = config ) )
117181 # Then merge with default connectors config
118182 configuration = dict (add_defaults (config ))
119183
0 commit comments