Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.
Empty file.
33 changes: 33 additions & 0 deletions localstack-core/localstack/feature_catalog/api_limitation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from functools import wraps


class ApiLimitation:
"""
Alternative approach to track specific api-operation limitations
This may be useful if service owners prefer to track limitation on operation level rather than on feature level
Could also be used as an input for the coverage-docs in the future

The ApiLimitation can be used as decorator for the specific operation, and adds a string with a description.
In the scripts/feature_catalog_playground/playground.py we created a first PoC that also parses the decorated operations
and adds the information to the final json output
"""

def __init__(self, limitation: str):
"""
Initialize the decorator with the message that will be stored for future retrieval.
"""
self.limitation = limitation

def __call__(self, func):
"""
Decorate the function or method, storing the message as an attribute on the function.
"""

@wraps(func)
def wrapper(*args, **kwargs):
# Call the original function
return func(*args, **kwargs)

# Attach the message to the function as an attribute for later retrieval
wrapper.api_limitation_message = self.limitation
return wrapper
84 changes: 84 additions & 0 deletions localstack-core/localstack/feature_catalog/service_feature.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from enum import Enum
from functools import wraps


class SupportStatus(Enum):
"""
Indicates the support on LocalStack in regard to the actual implementation
E.g.
SUPPORTED means that everything is behaving as on AWS
SUPPORTED_MOCKED_ONLY means that the response is the same as on AWS, but there is no actual behavior behind it (e.g. no database created)
SUPPORTED_PARTIALLY_EMULATED means that there is some kind of emulation, but there may be parts missing
NOT_SUPPORTED means this is not implemented at all on LS
"""

SUPPORTED = 1
SUPPORTED_MOCKED_ONLY = 2
SUPPORTED_PARTIALLY_EMULATED = 3
NOT_SUPPORTED = 4


class ImplementationStatus(Enum):
"""
Indicates implementation status on LS
E.g.
FULLY_IMPLEMENTED means that all (important?) operations are implemented
PARTIALLY_IMPLEMENTED means some selected operations are implemented
EXPERIMENTAL means that there is some implementation, but this feature is still higly experimental
"""

FULLY_IMPLEMENTED = 1
PARTIALLY_IMPLEMENTED = 2
EXPERIMENTAL = 3

Comment on lines +5 to +33

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was mainly for testing purpose, I don't think this is the best classification as it seems a bit confusing


class ServiceFeature:
"""
The base class for all service features
For each service there should be separate file in ./services that defines further features and sub features
The concrete features (or sub features) can then be used as decorator for api-operations or functions

With the script in scripts/feature_catalog_playground/playground.py we can create a first PoC that outputs the
details of all ServiceFeature subclasses in a json-format, including attributes;
also detecting all operations/functions that use the feature as decorator and map those accordingly
"""

implementation_status: ImplementationStatus

def __init__(self, func):
self.feature = self.__class__.__name__
self.func = func
wraps(func)(self)

def __get__(self, instance, owner):
"""
This makes the decorator work with bound methods inside classes.
It is called when the method is accessed on an instance.
"""
# Return a bound method by wrapping the function and passing the instance (`self`)
if instance is None:
return self # Return the unbound function when accessed via the class
# Bind the function to the instance by returning a wrapper
return lambda *args, **kwargs: self(instance, *args, **kwargs)

def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)


class ApiCoverage:
"""
One suggestions on how to track specific api-operation limitations:
This is the base class for limitations that we want to track on an api-operation level, instead of a feature-level

Alternative solution would be using the ApiLimitation (file api_limitation.py), which provides a more generic way
of doing so
"""

implementation_status: ImplementationStatus

def __init__(self, func):
self.func = func
wraps(func)(self)

def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from localstack.feature_catalog.service_feature import (
ImplementationStatus,
ServiceFeature,
SupportStatus,
)

"""
This is only a PoC on how features could be divided
For CloudWatch the features are not yet complete, only experimented with a couple of features and hierarchies

Attributes are subject to discussion as well
"""


class CloudWatchFeature(ServiceFeature):
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED


class Metric(CloudWatchFeature):
general_docs: str = "Collect metrics from AWS services, or generate custom metrics"
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
limitations: str = "AWS service metrics are only reported for selected services and metrics"
aws_docs_link: str = (
"https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/working_with_metrics.html"
)


class AWSMetric(Metric):
general_docs: str = "Collects application metrics from AWS services"
supported_services: list[str] = ["Lambda", "SQS"]
supported_details: dict[str] = {
"Lambda": "Supports Invocations and Errors metrics.",
"SQS": "Supports Approximate* metrics, NumberOfMessagesSent, and other metrics triggered by events such as message received or sending.",
}


class Alarm(CloudWatchFeature):
general_docs: str = "Alarms are used to set thresholds for metrics and trigger actions"
supported: SupportStatus = SupportStatus.SUPPORTED_PARTIALLY_EMULATED
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
aws_docs_link: str = (
"https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html"
)


class CompositeAlarm(Alarm):
supported: SupportStatus = SupportStatus.SUPPORTED_MOCKED_ONLY
aws_docs_link: str = (
"https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Create_Composite_Alarm.html"
)


class MetricAlarm(Alarm):
supported: SupportStatus = SupportStatus.SUPPORTED
supported_triggers: list[str] = ["SNS", "Lambda"]
21 changes: 21 additions & 0 deletions localstack-core/localstack/feature_catalog/services/kms_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from localstack.feature_catalog.service_feature import (
ApiCoverage,
ImplementationStatus,
SupportStatus,
)


class CreateKey(ApiCoverage):

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this approach was suggested by @sannya-singal to document additional limitations.
However, we also iterated over it, and came up with a ApiLimitation decorator that could take the limitation as input, which may be more practical solution as we don't need to setup subclasses.

"""
One suggestions on how to track specific api-operation limitations:

Alternative solution would be using the ApiLimitation (file feature_catalog/api_limitation.py), which provides a more generic way
of doing so
"""

general_docs: str = "Creates an AWS KMS key."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
limitations: list = [
"Status 'Updating' is not supported.",
]
195 changes: 195 additions & 0 deletions localstack-core/localstack/feature_catalog/services/kms_feature.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
from localstack.feature_catalog.service_feature import (
ImplementationStatus,
ServiceFeature,
SupportStatus,
)


class KMSFeature(ServiceFeature):
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED


# Key Management


class KeyManagement(KMSFeature):
general_docs: str = "Manages the creation and lifecycle of the cryptographic keys"
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = (
"https://docs.aws.amazon.com/kms/latest/developerguide/getting-started.html"
)


class Provisioning(KeyManagement):
general_docs: str = "Manage the creation and modification of the keys."
implementation_status: ImplementationStatus = ImplementationStatus.FULLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html"
api_operations: list = ["CreateKey"]

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is just one suggestion on how to include api_operations.
With the usage as decorators, however, we have shown that we can also link the decorated functions back to the feature-catalog-mapping, which makes this information redundant.



class Alias(KeyManagement):
general_docs: str = "Manage the aliases for referring to a KMS key."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/kms-alias.html"


class StateControl(KeyManagement):
general_docs: str = "Control the activation and deactivation of keys."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/enabling-keys.html"


class Deletion(KeyManagement):
general_docs: str = "Manage the deletion of the keys."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/deleting-keys.html"


class Viewing(KeyManagement):
general_docs: str = "View the details of the keys."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html"


class Tagging(KeyManagement):
general_docs = "Manage the tags of the keys."
implementation_status: ImplementationStatus = ImplementationStatus.FULLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/tagging-keys.html"


class Rotation(KeyManagement):
general_docs: str = "Manage the rotation of the keys."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html"


# CryptographicOperations


class CryptographicOperations(KMSFeature):
general_docs: str = "Perform cryptographic operations using the keys for data protecttion."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
limitations: list = ["Limited support for offline encryption and decryption"]
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#cryptographic-operations"


class Symmetric(CryptographicOperations):
general_docs: str = "Manage the symmetric keys for crytographic operations."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = (
"https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#symmetric-cmks"
)


class Asymmetric(CryptographicOperations):
general_docs: str = "Manage the asymmetric keys for crytographic operations."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
limitations: list = ["No support for SM2 key spec"]
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#asymmetric-keys-concept"


class HMAC(CryptographicOperations):
general_docs: str = "Manage the HMAC keys for crytographic operations."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/hmac.html"


class Data(CryptographicOperations):
general_docs: str = "Manage the data keys for crytographic operations."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = (
"https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#data-keys"
)


class Random(CryptographicOperations):
general_docs = "Generate random data for cryptographic operations."
implementation_status = ImplementationStatus.FULLY_IMPLEMENTED
support_type = SupportStatus.SUPPORTED
aws_docs_link = "https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateRandom.html"


# PolicyAndPermissions


class AccessControl(KMSFeature):
general_docs: str = "Define and manage permissions and access control for the keys."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/control-access.html"


class Policy(AccessControl):
general_docs: str = "Manage the key policies for the keys."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html"


class Grant(AccessControl):
general_docs: str = "Manage the grants for the keys."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/grants.html"


# Custom KeyStores


class CustomKeyStores(KMSFeature):
general_docs: str = "Store the keys in custom key stores."
support_type: SupportStatus = SupportStatus.NOT_SUPPORTED
aws_docs_link: str = (
"https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html"
)


class StoreManagement(CustomKeyStores):
general_docs: str = "Manage the custom key stores."
support_type: SupportStatus = SupportStatus.NOT_SUPPORTED
aws_docs_link: str = (
"https://docs.aws.amazon.com/kms/latest/developerguide/keystore-cloudhsm.html"
)


# Multi-Region


class MultiRegion(KMSFeature):
general_docs: str = "Manage the keys across multiple regions."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
limitations: list = [
"Key replication is not automatically synchronized with the corresponding primary key"
]
aws_docs_link: str = (
"https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html"
)


# Import


class Import(KMSFeature):
general_docs: str = "Import your own cryptographic key material to AWS KMS."
implementation_status: ImplementationStatus = ImplementationStatus.PARTIALLY_IMPLEMENTED
support_type: SupportStatus = SupportStatus.SUPPORTED
aws_docs_link: str = "https://docs.aws.amazon.com/kms/latest/developerguide/importing-keys.html"


# TODO:
# "FULLY_IMPLEMENTED" -> definition? how to measure this? parity issues tracker usage?
# - feature support vs api support
Loading