Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1602,7 +1602,7 @@ Apache License


anyio
4.10.0
4.11.0
UNKNOWN
The MIT License (MIT)

Expand Down
2 changes: 1 addition & 1 deletion connectors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
import os

with open(os.path.join(os.path.dirname(__file__), "VERSION")) as f:
__version__ = f.read().strip()
__version__: str = f.read().strip()
10 changes: 8 additions & 2 deletions connectors/access_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# you may not use this file except in compliance with the Elastic License 2.0.
#

from typing import Dict, List, Optional, Union

ACCESS_CONTROL = "_allow_access_control"
DLS_QUERY = """{
"bool": {
Expand All @@ -27,14 +29,18 @@
}"""


def prefix_identity(prefix, identity):
def prefix_identity(
prefix: Optional[str], identity: Optional[Union[str, int]]
) -> Optional[str]:
if prefix is None or identity is None:
return None

return f"{prefix}:{identity}"


def es_access_control_query(access_control):
def es_access_control_query(
access_control: List[Optional[str]],
) -> Dict[str, Dict[str, Dict[str, Union[Dict[str, List[str]], str]]]]:
# filter out 'None' values
filtered_access_control = list(
filter(
Expand Down
5 changes: 3 additions & 2 deletions connectors/agent/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import asyncio
import functools
import signal
from logging import Logger

from elastic_agent_client.util.async_tools import (
sleeps_for_retryable,
Expand All @@ -14,10 +15,10 @@
from connectors.agent.component import ConnectorsAgentComponent
from connectors.agent.logger import get_logger

logger = get_logger("cli")
logger: Logger = get_logger("cli")


def main(args=None):
def main(args=None) -> None:
"""Script entry point into running Connectors Service on Agent.

It initialises an event loop, creates a component and runs the component.
Expand Down
9 changes: 5 additions & 4 deletions connectors/agent/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# you may not use this file except in compliance with the Elastic License 2.0.
#
import sys
from logging import Logger

from elastic_agent_client.client import V2Options, VersionInfo
from elastic_agent_client.reader import new_v2_from_reader
Expand All @@ -16,7 +17,7 @@
from connectors.agent.service_manager import ConnectorServiceManager
from connectors.services.base import MultiService

logger = get_logger("component")
logger: Logger = get_logger("component")

CONNECTOR_SERVICE = "connector-service"

Expand All @@ -30,7 +31,7 @@ class ConnectorsAgentComponent:
and provides applied interface to be able to run it in 2 simple methods: run and stop.
"""

def __init__(self):
def __init__(self) -> None:
"""Inits the class.

Init should be safe to call without expectations of side effects (connections to Agent, blocking or anything).
Expand All @@ -42,7 +43,7 @@ def __init__(self):
self.buffer = sys.stdin.buffer
self.config_wrapper = ConnectorsAgentConfigurationWrapper()

async def run(self):
async def run(self) -> None:
"""Start reading from Agent protocol and run Connectors Service with settings reported by agent.

This method can block if it's not running from Agent - it expects the client to be able to read messages
Expand Down Expand Up @@ -72,7 +73,7 @@ async def run(self):

await self.multi_service.run()

def stop(self, sig):
def stop(self, sig) -> None:
"""Shutdown everything running in the component.

Attempts to gracefully shutdown the services that are running under the component.
Expand Down
21 changes: 15 additions & 6 deletions connectors/agent/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@
# you may not use this file except in compliance with the Elastic License 2.0.
#
import base64
from logging import Logger
from typing import Any, Dict, List, Union
from unittest.mock import Mock

from elastic_agent_client.client import Unit

from connectors.agent.logger import get_logger
from connectors.config import add_defaults
from connectors.utils import nested_get_from_dict

logger = get_logger("config")
logger: Logger = get_logger("config")


class ConnectorsAgentConfigurationWrapper:
Expand All @@ -21,7 +26,7 @@ class ConnectorsAgentConfigurationWrapper:
- Indicating that configuration has changed so that the user of the class can trigger the restart
"""

def __init__(self):
def __init__(self) -> None:
"""Inits the class.

There's default config that allows us to run connectors service. When final
Expand All @@ -37,7 +42,9 @@ def __init__(self):

self.specific_config = {}

def try_update(self, connector_id, service_type, output_unit):
def try_update(
self, connector_id: str, service_type: str, output_unit: Union[Mock, Unit]
) -> bool:
"""Try update the configuration and see if it changed.

This method takes the check-in event data (connector_id, service_type and output) coming
Expand Down Expand Up @@ -103,7 +110,7 @@ def try_update(self, connector_id, service_type, output_unit):
logger.debug("No changes detected for connectors-relevant configurations")
return False

def config_changed(self, new_config):
def config_changed(self, new_config: Dict[str, Any]) -> bool:
"""See if configuration passed in new_config will update currently stored configuration

This method takes the new configuration received from the agent and see if there are any changes
Expand Down Expand Up @@ -175,7 +182,7 @@ def _connectors_config_changes():

return False

def get(self):
def get(self) -> Dict[str, Any]:
"""Get current Connectors Service configuration.

This method combines three configs with higher ones taking precedence:
Expand All @@ -194,5 +201,7 @@ def get(self):

return configuration

def get_specific_config(self):
def get_specific_config(
self,
) -> Dict[str, Union[List[Dict[str, str]], Dict[str, int]]]:
return self.specific_config
13 changes: 9 additions & 4 deletions connectors/agent/connector_record_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
# you may not use this file except in compliance with the Elastic License 2.0.
#

from logging import Logger
from typing import Optional, Tuple

from connectors.agent.logger import get_logger
from connectors.protocol import ConnectorIndex
from connectors.utils import generate_random_id

logger = get_logger("agent_connector_record_manager")
logger: Logger = get_logger("agent_connector_record_manager")


class ConnectorRecordManager:
Expand All @@ -17,10 +20,12 @@ class ConnectorRecordManager:
exist in the connector index. It creates the connector record if necessary.
"""

def __init__(self):
def __init__(self) -> None:
self.connector_index = None

async def ensure_connector_records_exist(self, agent_config, connector_name=None):
async def ensure_connector_records_exist(
self, agent_config, connector_name: Optional[str] = None
) -> None:
"""
Ensure that connector records exist for all connectors specified in the agent configuration.

Expand Down Expand Up @@ -71,7 +76,7 @@ async def ensure_connector_records_exist(self, agent_config, connector_name=None
f"Skipping connector creation. Connector record for {connector_id} already exists."
)

def _check_agent_config_ready(self, agent_config):
def _check_agent_config_ready(self, agent_config) -> Tuple[bool, Optional[str]]:
"""
Validates the agent configuration to check if all info is present to create a connector record.

Expand Down
9 changes: 5 additions & 4 deletions connectors/agent/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
# you may not use this file except in compliance with the Elastic License 2.0.
#
import logging
from typing import TextIO, Union

import ecs_logging

root_logger = logging.getLogger("agent_component")
handler = logging.StreamHandler()
root_logger: logging.Logger = logging.getLogger("agent_component")
handler: logging.StreamHandler[TextIO] = logging.StreamHandler()
handler.setFormatter(ecs_logging.StdlibFormatter())
root_logger.addHandler(handler)
root_logger.setLevel(logging.INFO)


def get_logger(module):
def get_logger(module: str) -> logging.Logger:
logger = root_logger.getChild(module)

if logger.hasHandlers():
Expand All @@ -25,5 +26,5 @@ def get_logger(module):
return logger


def update_logger_level(log_level):
def update_logger_level(log_level: Union[int, str]) -> None:
root_logger.setLevel(log_level)
11 changes: 7 additions & 4 deletions connectors/agent/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
# you may not use this file except in compliance with the Elastic License 2.0.
#

from logging import Logger

from elastic_agent_client.client import V2
from elastic_agent_client.generated import elastic_agent_client_pb2 as proto
from elastic_agent_client.handler.action import BaseActionHandler
from elastic_agent_client.handler.checkin import BaseCheckinHandler

from connectors.agent.connector_record_manager import ConnectorRecordManager
from connectors.agent.logger import get_logger

logger = get_logger("protocol")
logger: Logger = get_logger("protocol")


CONNECTORS_INPUT_TYPE = "connectors-py"
Expand Down Expand Up @@ -49,10 +52,10 @@ class ConnectorCheckinHandler(BaseCheckinHandler):

def __init__(
self,
client,
client: V2,
agent_connectors_config_wrapper,
service_manager,
):
) -> None:
"""Inits the class.

Initing this class should not produce side-effects.
Expand All @@ -62,7 +65,7 @@ def __init__(
self.service_manager = service_manager
self.connector_record_manager = ConnectorRecordManager()

async def apply_from_client(self):
async def apply_from_client(self) -> None:
"""Implementation of BaseCheckinHandler.apply_from_client

This method is called by the Agent Protocol handlers when there's a check-in event
Expand Down
10 changes: 5 additions & 5 deletions connectors/agent/service_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
)
from connectors.utils import CancellableSleeps

logger = get_logger("service_manager")
logger: logging.Logger = get_logger("service_manager")


class ConnectorServiceManager:
Expand All @@ -28,7 +28,7 @@ class ConnectorServiceManager:

"""

def __init__(self, configuration):
def __init__(self, configuration) -> None:
"""Inits ConnectorServiceManager with shared ConnectorsAgentConfigurationWrapper.

This service is supposed to be ran once, and after it's stopped or finished running it's not
Expand All @@ -41,7 +41,7 @@ def __init__(self, configuration):
self._running = False
self._sleeps = CancellableSleeps()

async def run(self):
async def run(self) -> None:
"""Starts the running loop of the service.

Once started, the service attempts to run all needed connector subservices
Expand Down Expand Up @@ -81,7 +81,7 @@ async def run(self):
finally:
logger.info("Finished running, exiting")

def stop(self):
def stop(self) -> None:
"""Stop the service manager and all running subservices.

Running stop attempts to gracefully shutdown all subservices currently running.
Expand All @@ -92,7 +92,7 @@ def stop(self):
if self._multi_service:
self._multi_service.shutdown(None)

def restart(self):
def restart(self) -> None:
"""Restart the service manager and all running subservices.

Running restart attempts to gracefully shutdown all subservices currently running.
Expand Down
2 changes: 1 addition & 1 deletion connectors/build_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

# This references a file that's built in .buildkite/publish/publish-common.sh
# See https://github.com/elastic/connectors/pull/3154 for more info
yaml_path = os.path.join(os.path.dirname(__file__), "build.yaml")
yaml_path: str = os.path.join(os.path.dirname(__file__), "build.yaml")
if os.path.exists(yaml_path):
__build_info__ = ""
with open(yaml_path) as f:
Expand Down
13 changes: 10 additions & 3 deletions connectors/cli/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#
import asyncio
import os
from typing import Optional

import yaml
from elasticsearch import ApiError
Expand All @@ -15,7 +16,13 @@


class Auth:
def __init__(self, host, username=None, password=None, api_key=None):
def __init__(
self,
host: str,
username: Optional[str] = None,
password: Optional[str] = None,
api_key: Optional[str] = None,
) -> None:
elastic_config = {
"host": host,
"username": username,
Expand All @@ -28,14 +35,14 @@ def __init__(self, host, username=None, password=None, api_key=None):

self.cli_client = CLIClient(self.elastic_config)

def authenticate(self):
def authenticate(self) -> bool:
if asyncio.run(self.__ping_es_client()):
self.__save_config()
return True
else:
return False

def is_config_present(self):
def is_config_present(self) -> bool:
return os.path.isfile(CONFIG_FILE_PATH)

async def __ping_es_client(self):
Expand Down
Loading