feat(kinesis): add new service Kinesis (#5228)

Co-authored-by: Sergio Garcia <38561120+sergargar@users.noreply.github.com>
This commit is contained in:
Hugo Pereira Brito
2024-10-02 16:59:59 +02:00
committed by GitHub
parent ab4190c215
commit 260cdf575a
2 changed files with 144 additions and 0 deletions
@@ -0,0 +1,70 @@
from enum import Enum
from typing import Optional
from pydantic import BaseModel
from prowler.lib.logger import logger
from prowler.lib.scan_filters.scan_filters import is_resource_filtered
from prowler.providers.aws.lib.service.service import AWSService
class Kinesis(AWSService):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, provider)
self.streams = {}
self.__threading_call__(self._list_streams)
self.__threading_call__(self._list_tags_for_stream, self.streams.values())
def _list_streams(self, regional_client):
logger.info("Kinesis - Listing Kinesis Streams...")
try:
list_streams_paginator = regional_client.get_paginator("list_streams")
for page in list_streams_paginator.paginate():
for stream in page["StreamSummaries"]:
arn = stream["StreamARN"]
if not self.audit_resources or (
is_resource_filtered(arn, self.audit_resources)
):
self.streams[arn] = Stream(
arn=arn,
name=stream["StreamName"],
region=regional_client.region,
status=StreamStatus(stream.get("StreamStatus", "ACTIVE")),
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def _list_tags_for_stream(self, stream):
logger.info(f"Kinesis - Listing tags for Stream {stream.name}...")
try:
stream.tags = (
self.regional_clients[stream.region]
.list_tags_for_stream(StreamName=stream.name)
.get("Tags", [])
)
except Exception as error:
logger.error(
f"{stream.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
class StreamStatus(Enum):
"""Enum for Kinesis Stream Status"""
ACTIVE = "ACTIVE"
CREATING = "CREATING"
DELETING = "DELETING"
UPDATING = "UPDATING"
class Stream(BaseModel):
"""Model for Kinesis Stream"""
arn: str
region: str
name: str
status: StreamStatus
tags: Optional[list]
@@ -0,0 +1,74 @@
from unittest.mock import patch
import botocore
from moto import mock_aws
from prowler.providers.aws.services.kinesis.kinesis_service import Kinesis, StreamStatus
from tests.providers.aws.utils import AWS_REGION_US_EAST_1, set_mocked_aws_provider
make_api_call = botocore.client.BaseClient._make_api_call
def mock_make_api_call(self, operation_name, kwarg):
if operation_name == "ListStreams":
return {
"StreamNames": ["test-stream"],
"StreamSummaries": [
{
"StreamName": "test-stream",
"StreamARN": "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream",
"StreamStatus": "ACTIVE",
}
],
}
if operation_name == "DescribeStream":
return {
"StreamDescription": {
"StreamName": "test-stream",
"StreamARN": "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream",
"StreamStatus": "ACTIVE",
"Tags": [{"Key": "test_tag", "Value": "test_value"}],
}
}
if operation_name == "ListTagsForStream":
return {"Tags": [{"Key": "test_tag", "Value": "test_value"}]}
return make_api_call(self, operation_name, kwarg)
# Patch every AWS call using Boto3
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
class Test_Kinesis_Service:
# Test Kinesis Client
@mock_aws
def test_get_client(self):
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
kinesis = Kinesis(aws_provider)
assert (
kinesis.regional_clients[AWS_REGION_US_EAST_1].__class__.__name__
== "Kinesis"
)
# Test Kinesis Session
def test__get_session__(self):
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
kinesis = Kinesis(aws_provider)
assert kinesis.session.__class__.__name__ == "Session"
# Test Kinesis Service
@mock_aws
def test__get_service__(self):
kinesis = Kinesis(set_mocked_aws_provider())
assert kinesis.service == "kinesis"
@mock_aws
def test_list_streamscomplete(self):
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
kinesis = Kinesis(aws_provider)
arn = "arn:aws:kinesis:us-east-1:123456789012:stream/test-stream"
assert len(kinesis.streams) == 1
assert kinesis.streams[arn].name == "test-stream"
assert kinesis.streams[arn].status == StreamStatus.ACTIVE
assert kinesis.streams[arn].tags == [{"Key": "test_tag", "Value": "test_value"}]
assert kinesis.streams[arn].region == AWS_REGION_US_EAST_1
assert kinesis.streams[arn].arn == arn