-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Playground feature catalog #11592
Playground feature catalog #11592
Changes from all commits
8470485
a261c96
e415039
c0eef52
c3ada09
7cca6b5
ad6f1a5
4153784
61df19a
9609dc3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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 |
| 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 | ||
|
|
||
|
|
||
| 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"] |
| 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): | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this approach was suggested by @sannya-singal to document additional limitations. |
||
| """ | ||
| 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.", | ||
| ] | ||
| 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"] | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is just one suggestion on how to include api_operations. |
||
|
|
||
|
|
||
| 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 | ||
There was a problem hiding this comment.
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