diff --git a/src/spaceone/inventory/connector/aws_elasticache_connector/connector.py b/src/spaceone/inventory/connector/aws_elasticache_connector/connector.py
index 2d1fefb5..eb097b50 100644
--- a/src/spaceone/inventory/connector/aws_elasticache_connector/connector.py
+++ b/src/spaceone/inventory/connector/aws_elasticache_connector/connector.py
@@ -1,9 +1,9 @@
import logging
from spaceone.core.utils import *
-from spaceone.inventory.connector.aws_elasticache_connector.schema.data import Redis, Memcached
+from spaceone.inventory.connector.aws_elasticache_connector.schema.data import Redis, Memcached, Valkey
from spaceone.inventory.connector.aws_elasticache_connector.schema.resource import RedisResource, RedisResponse, \
- MemcachedResource, MemcachedResponse
+ MemcachedResource, MemcachedResponse, ValkeyResponse, ValkeyResource
from spaceone.inventory.connector.aws_elasticache_connector.schema.service_type import CLOUD_SERVICE_TYPES
from spaceone.inventory.libs.connector import SchematicAWSConnector
from spaceone.inventory.libs.schema.resource import ReferenceModel, CloudWatchModel
@@ -39,7 +39,9 @@ def get_resources(self):
resources.append(MemcachedResponse({'resource': memcached_vo}))
- for redis_vo in self.get_redis_data(region_name, cache_clusters):
+ replication_groups = cache_clusters = [cluster for cluster in self.describe_replication_groups()]
+
+ for redis_vo in self.get_redis_data(region_name, replication_groups, cache_clusters):
if getattr(redis_vo, 'resource_type', None) and redis_vo.resource_type == 'inventory.ErrorResource':
# Error Resource
resources.append(redis_vo)
@@ -48,6 +50,16 @@ def get_resources(self):
redis_vo.cloudwatch = CloudWatchModel(redis_vo.set_cloudwatch(region_name))
resources.append(RedisResponse({'resource': redis_vo}))
+
+ for valkey_vo in self.get_valkey_data(region_name, replication_groups, cache_clusters):
+ if getattr(valkey_vo, 'resource_type', None) and valkey_vo.resource_type == 'inventory.ErrorResource':
+ # Error Resource
+ resources.append(valkey_vo)
+ else:
+ if getattr(valkey_vo, 'set_cloudwatch', None):
+ valkey_vo.cloudwatch = CloudWatchModel(valkey_vo.set_cloudwatch(region_name))
+
+ resources.append(ValkeyResponse({'resource': valkey_vo}))
except Exception as e:
error_resource_response = self.generate_error(region_name, '', e)
resources.append(error_resource_response)
@@ -87,47 +99,97 @@ def get_memcached_data(self, region_name, cache_clusters):
error_resource_response = self.generate_error(region_name, resource_id, e)
yield {'data': error_resource_response}
- def get_redis_data(self, region_name, cache_clusters):
+ def get_redis_data(self, region_name, replication_groups, cache_clusters):
self.cloud_service_type = 'Redis'
cloudtrail_resource_type = None
- for replication_group in self.describe_replication_groups():
+ for replication_group in replication_groups:
try:
- replication_group.update({
- 'mode': self.set_redis_mode(replication_group.get('ClusterEnabled')),
- 'engine': 'redis',
- 'engine_version': self.get_engine_version(replication_group, cache_clusters),
- 'shard_count': self.get_shard_count(replication_group.get('NodeGroups', [])),
- 'availability_zones': self.get_redis_availability_zones(replication_group.get('NodeGroups', [])),
- 'subnet_group_name': self.get_redis_subnet_group_name(replication_group, cache_clusters),
- 'parameter_group_name': self.get_redis_parameter_group_name(replication_group, cache_clusters),
- 'node_count': self.get_node_count(replication_group.get('MemberClusters', [])),
- 'cloudtrail': self.set_cloudtrail(region_name, cloudtrail_resource_type,
- replication_group['ReplicationGroupId']),
- 'nodes': self.get_redis_nodes_info(replication_group, cache_clusters),
- })
-
- if replication_group.get('mode') == 'Redis':
+ if replication_group.get('Engine') == 'redis':
replication_group.update({
- 'primary_endpoint': self.get_redis_primary_endpoint(replication_group),
- 'reader_endpoint': self.get_redis_reader_endpoint(replication_group)
+ 'mode': self.set_redis_mode(replication_group.get('ClusterEnabled')),
+ 'engine': 'redis',
+ 'engine_version': self.get_engine_version(replication_group, cache_clusters),
+ 'shard_count': self.get_shard_count(replication_group.get('NodeGroups', [])),
+ 'availability_zones': self.get_availability_zones(replication_group.get('NodeGroups', [])),
+ 'subnet_group_name': self.get_subnet_group_name(replication_group, cache_clusters),
+ 'parameter_group_name': self.get_parameter_group_name(replication_group, cache_clusters),
+ 'node_count': self.get_node_count(replication_group.get('MemberClusters', [])),
+ 'cloudtrail': self.set_cloudtrail(region_name, cloudtrail_resource_type,
+ replication_group['ReplicationGroupId']),
+ 'nodes': self.get_nodes_info(replication_group, cache_clusters),
})
- elif replication_group.get('mode') == 'Clustered Redis':
- replication_group.update({
- 'shards': self.get_redis_shards_info(replication_group)
+
+ if replication_group.get('mode') == 'Redis':
+ replication_group.update({
+ 'primary_endpoint': self.get_primary_endpoint(replication_group),
+ 'reader_endpoint': self.get_reader_endpoint(replication_group)
+ })
+ elif replication_group.get('mode') == 'Clustered Redis':
+ replication_group.update({
+ 'shards': self.get_shards_info(replication_group)
+ })
+
+ redis_vo = Redis(replication_group, strict=False)
+
+ yield RedisResource({
+ 'data': redis_vo,
+ 'name': redis_vo.replication_group_id,
+ 'instance_type': redis_vo.cache_node_type,
+ 'account': self.account_id,
+ 'region_code': region_name,
+ 'tags': self.list_tags(redis_vo.arn),
+ 'reference': ReferenceModel(redis_vo.reference(region_name))
})
- redis_vo = Redis(replication_group, strict=False)
+ except Exception as e:
+ resource_id = replication_group.get('ARN', '')
+ error_resource_response = self.generate_error(region_name, resource_id, e)
+ yield {'data': error_resource_response}
+
+ def get_valkey_data(self, region_name, replication_groups, cache_clusters):
+ self.cloud_service_type = 'Valkey'
+ cloudtrail_resource_type = None
+
+ for replication_group in replication_groups:
+ try:
+ if replication_group.get('Engine') == 'valkey':
+ replication_group.update({
+ 'mode': self.set_valkey_mode(replication_group.get('ClusterEnabled')),
+ 'engine': 'valkey',
+ 'engine_version': self.get_engine_version(replication_group, cache_clusters),
+ 'shard_count': self.get_shard_count(replication_group.get('NodeGroups', [])),
+ 'availability_zones': self.get_availability_zones(
+ replication_group.get('NodeGroups', [])),
+ 'subnet_group_name': self.get_subnet_group_name(replication_group, cache_clusters),
+ 'parameter_group_name': self.get_parameter_group_name(replication_group, cache_clusters),
+ 'node_count': self.get_node_count(replication_group.get('MemberClusters', [])),
+ 'cloudtrail': self.set_cloudtrail(region_name, cloudtrail_resource_type,
+ replication_group['ReplicationGroupId']),
+ 'nodes': self.get_nodes_info(replication_group, cache_clusters),
+ })
- yield RedisResource({
- 'data': redis_vo,
- 'name': redis_vo.replication_group_id,
- 'instance_type': redis_vo.cache_node_type,
- 'account': self.account_id,
- 'region_code': region_name,
- 'tags': self.list_tags(redis_vo.arn),
- 'reference': ReferenceModel(redis_vo.reference(region_name))
- })
+ if replication_group.get('mode') == 'Valkey':
+ replication_group.update({
+ 'primary_endpoint': self.get_primary_endpoint(replication_group),
+ 'reader_endpoint': self.get_reader_endpoint(replication_group)
+ })
+ elif replication_group.get('mode') == 'Clustered Valkey':
+ replication_group.update({
+ 'shards': self.get_shards_info(replication_group)
+ })
+
+ valkey_vo = Valkey(replication_group, strict=False)
+
+ yield ValkeyResource({
+ 'data': valkey_vo,
+ 'name': valkey_vo.replication_group_id,
+ 'instance_type': valkey_vo.cache_node_type,
+ 'account': self.account_id,
+ 'region_code': region_name,
+ 'tags': self.list_tags(valkey_vo.arn),
+ 'reference': ReferenceModel(valkey_vo.reference(region_name))
+ })
except Exception as e:
resource_id = replication_group.get('ARN', '')
@@ -195,6 +257,13 @@ def set_redis_mode(cluster_enabled):
else:
return 'Redis'
+ @staticmethod
+ def set_valkey_mode(cluster_enabled):
+ if cluster_enabled:
+ return 'Clustered Valkey'
+ else:
+ return 'Valkey'
+
@staticmethod
def get_node_count(member_clusters):
return len(member_clusters)
@@ -204,13 +273,13 @@ def get_shard_count(node_groups):
return len(node_groups)
@staticmethod
- def get_redis_primary_endpoint(replication_group):
+ def get_primary_endpoint(replication_group):
for node_group in replication_group.get('NodeGroups', []):
primary_endpoint = node_group.get("PrimaryEndpoint", {})
return f'{primary_endpoint.get("Address", "")}:{primary_endpoint.get("Port", "")}'
@staticmethod
- def get_redis_reader_endpoint(replication_group):
+ def get_reader_endpoint(replication_group):
for node_group in replication_group.get('NodeGroups', []):
reader_endpoint = node_group.get("ReaderEndpoint", {})
return f'{reader_endpoint.get("Address", "")}:{reader_endpoint.get("Port", "")}'
@@ -225,7 +294,7 @@ def get_engine_version(replication_group, cache_clusters):
return ''
@staticmethod
- def get_redis_availability_zones(node_groups):
+ def get_availability_zones(node_groups):
azs = []
for node_group in node_groups:
@@ -237,7 +306,7 @@ def get_redis_availability_zones(node_groups):
return list(set(azs))
@staticmethod
- def get_redis_subnet_group_name(replication_group, cache_clusters):
+ def get_subnet_group_name(replication_group, cache_clusters):
for member in replication_group.get('MemberClusters', []):
for cache_cluster in cache_clusters:
if cache_cluster.get('CacheClusterId') == member:
@@ -246,7 +315,7 @@ def get_redis_subnet_group_name(replication_group, cache_clusters):
return ''
@staticmethod
- def get_redis_parameter_group_name(replication_group, cache_clusters):
+ def get_parameter_group_name(replication_group, cache_clusters):
for member in replication_group.get('MemberClusters', []):
for cache_cluster in cache_clusters:
if cache_cluster.get('CacheClusterId') == member:
@@ -254,7 +323,7 @@ def get_redis_parameter_group_name(replication_group, cache_clusters):
return ''
- def get_redis_nodes_info(self, replication_group, cache_clusters):
+ def get_nodes_info(self, replication_group, cache_clusters):
nodes = []
for member in replication_group.get('MemberClusters', []):
@@ -282,7 +351,7 @@ def get_redis_nodes_info(self, replication_group, cache_clusters):
})
else:
node_dic.update({
- 'endpoint': self.set_redis_cluster_node_endpoint(member, replication_group.get('ConfigurationEndpoint', {}).get('Address')),
+ 'endpoint': self.set_cluster_node_endpoint(member, replication_group.get('ConfigurationEndpoint', {}).get('Address')),
'port': replication_group.get('ConfigurationEndpoint', {}).get('Port', ''),
'zone': node_group_member.get('PreferredAvailabilityZone', ''),
})
@@ -292,7 +361,7 @@ def get_redis_nodes_info(self, replication_group, cache_clusters):
return nodes
@staticmethod
- def get_redis_shards_info(replication_group):
+ def get_shards_info(replication_group):
shards = []
for node_group in replication_group.get('NodeGroups', []):
@@ -306,7 +375,7 @@ def get_redis_shards_info(replication_group):
return shards
@staticmethod
- def set_redis_cluster_node_endpoint(member, address):
+ def set_cluster_node_endpoint(member, address):
if address:
address_split = address.split('.')[1:]
address_split.insert(0, member)
diff --git a/src/spaceone/inventory/connector/aws_elasticache_connector/schema/data.py b/src/spaceone/inventory/connector/aws_elasticache_connector/schema/data.py
index 961facd5..0ec7627b 100644
--- a/src/spaceone/inventory/connector/aws_elasticache_connector/schema/data.py
+++ b/src/spaceone/inventory/connector/aws_elasticache_connector/schema/data.py
@@ -32,7 +32,7 @@ class NodeGroupMembers(Model):
current_role = StringType(deserialize_from='CurrentRole', serialize_when_none=False)
-class RedisNodeGroups(Model):
+class NodeGroups(Model):
node_group_id = StringType(deserialize_from='NodeGroupId', serialize_when_none=False)
status = StringType(deserialize_from='Status', serialize_when_none=False)
primary_endpoint = ModelType(Endpoint, deserialize_from='PrimaryEndpoint', serialize_when_none=False)
@@ -41,7 +41,7 @@ class RedisNodeGroups(Model):
node_group_members = ListType(ModelType(NodeGroupMembers), deserialize_from='NodeGroupMembers', default=[])
-class RedisUserGroups(Model):
+class UserGroups(Model):
user_group_ids_to_add = ListType(StringType, deserialize_from='UserGroupIdsToAdd', default=[])
user_group_ids_to_remove = ListType(StringType, deserialize_from='UserGroupIdsToRemove', default=[])
@@ -50,21 +50,21 @@ class ReshardingSlotMigration(Model):
progress_percentage = FloatType(deserialize_from='ProgressPercentage', serialize_when_none=False)
-class RedisResharding(Model):
+class Resharding(Model):
slot_migration = ModelType(ReshardingSlotMigration, deserialize_from='SlotMigration', serialize_when_none=False)
-class RedisPendingModifiedValues(Model):
+class PendingModifiedValues(Model):
primary_cluster_id = StringType(deserialize_from='PrimaryClusterId', serialize_when_none=False)
automatic_failover_status = StringType(deserialize_from='AutomaticFailoverStatus', choices=('enabled', 'disabled'),
serialize_when_none=False)
- resharding = ModelType(RedisResharding, deserialize_from='Resharding', serialize_when_none=False)
+ resharding = ModelType(Resharding, deserialize_from='Resharding', serialize_when_none=False)
auth_token_status = StringType(deserialize_from='AuthTokenStatus', choices=('SETTING', 'ROTATING'),
serialize_when_none=False)
- user_groups = ModelType(RedisUserGroups, deserialize_from='RedisUserGroups', serialize_when_none=False)
+ user_groups = ModelType(UserGroups, deserialize_from='UserGroups', serialize_when_none=False)
-class RedisGlobalReplicationGroupInfo(Model):
+class GlobalReplicationGroupInfo(Model):
global_replication_group_id = StringType(deserialize_from='GlobalReplicationGroupId', serialize_when_none=False)
global_replication_group_member_role = StringType(deserialize_from='GlobalReplicationGroupMemberRole',
serialize_when_none=False)
@@ -99,14 +99,14 @@ class MemcachedPendingModifiedValues(Model):
serialize_when_none=False)
-class RedisShard(Model):
+class Shard(Model):
shard_name = StringType()
nodes = IntType()
status = StringType()
slots = StringType()
-class RedisNode(Model):
+class Node(Model):
node_name = StringType()
status = StringType()
current_role = StringType(serialize_when_none=False)
@@ -118,6 +118,55 @@ class RedisNode(Model):
created_on = DateTimeType()
+class Valkey(AWSCloudService):
+ arn = StringType(deserialize_from='ARN', serialize_when_none=False)
+ replication_group_id = StringType(deserialize_from="ReplicationGroupId", serialize_when_none=False)
+ mode = StringType(choices=('Clustered Valkey', 'Valkey'))
+ engine = StringType(deserialize_from="Engine", serialize_when_none=False)
+ engine_version = StringType(deserialize_from="EngineVersion", serialize_when_none=False)
+ shard_count = IntType()
+ node_count = IntType()
+ cache_node_type = StringType(deserialize_from="CacheNodeType", serialize_when_none=False)
+ description = StringType(deserialize_from="Description", serialize_when_none=False)
+ global_replication_group_info = ModelType(GlobalReplicationGroupInfo,
+ deserialize_from="GlobalReplicationGroupInfo", serialize_when_none=False)
+ status = StringType(deserialize_from='Status')
+ pending_modified_values = ModelType(PendingModifiedValues, deserialize_from='PendingModifiedValues',
+ serialize_when_none=False)
+ member_clusters = ListType(StringType, deserialize_from='MemberClusters', default=[])
+ node_groups = ListType(ModelType(NodeGroups), deserialize_from='NodeGroups', default=[])
+ availability_zones = ListType(StringType, default=[])
+ snapshotting_cluster_id = StringType(deserialize_from='SnapshottingClusterId', serialize_when_none=False)
+ automatic_failover = StringType(deserialize_from='AutomaticFailover',
+ choices=('enabled', 'disabled', 'enabling', 'disabling'),
+ serialize_when_none=False)
+ parameter_group_name = StringType(serialize_when_none=False)
+ subnet_group_name = StringType(serialize_when_none=False)
+ multi_az = StringType(deserialize_from='MultiAZ', choices=('enabled', 'disabled'), serialize_when_none=False)
+ configuration_endpoint = ModelType(Endpoint, deserialize_from='ConfigurationEndpoint', serialize_when_none=False)
+ primary_endpoint = StringType(serialize_when_none=False)
+ reader_endpoint = StringType(serialize_when_none=False)
+ snapshot_retention_limit = IntType(deserialize_from='SnapshotRetentionLimit', serialize_when_none=False)
+ snapshot_window = StringType(deserialize_from='SnapshotWindow', serialize_when_none=False)
+ cluster_enabled = BooleanType(deserialize_from='ClusterEnabled', serialize_when_none=False)
+ cluster_node_type = StringType(deserialize_from='CacheNodeType', serialize_when_none=False)
+ auth_token_enabled = BooleanType(deserialize_from='AuthTokenEnabled', serialize_when_none=False)
+ auth_token_last_modified_date = DateTimeType(deserialize_from='AuthTokenLastModifiedDate', serialize_when_none=False)
+ transit_encryption_enabled = BooleanType(deserialize_from='TransitEncryptionEnabled', serialize_when_none=False)
+ at_rest_encryption_enabled = BooleanType(deserialize_from='AtRestEncryptionEnabled', serialize_when_none=False)
+ member_clusters_outpost_arns = ListType(StringType, deserialize_from='MemberClustersOutpostArns', default=[])
+ kms_key_id = StringType(deserialize_from='KmsKeyId', serialize_when_none=False)
+ user_group_ids = ListType(StringType, deserialize_from='UserGroupIds', default=[])
+ shards = ListType(ModelType(Shard), default=[])
+ nodes = ListType(ModelType(Node), default=[])
+
+ def reference(self, region_code):
+ return {
+ "resource_id": self.arn,
+ "external_link": f"https://console.aws.amazon.com/elasticache/home?region={region_code}#redis-group-detail:id={self.replication_group_id}"
+ }
+
+
class Redis(AWSCloudService):
arn = StringType(deserialize_from='ARN', serialize_when_none=False)
replication_group_id = StringType(deserialize_from="ReplicationGroupId", serialize_when_none=False)
@@ -128,13 +177,13 @@ class Redis(AWSCloudService):
node_count = IntType()
cache_node_type = StringType(deserialize_from="CacheNodeType", serialize_when_none=False)
description = StringType(deserialize_from="Description", serialize_when_none=False)
- global_replication_group_info = ModelType(RedisGlobalReplicationGroupInfo,
+ global_replication_group_info = ModelType(GlobalReplicationGroupInfo,
deserialize_from="GlobalReplicationGroupInfo", serialize_when_none=False)
status = StringType(deserialize_from='Status')
- pending_modified_values = ModelType(RedisPendingModifiedValues, deserialize_from='PendingModifiedValues',
+ pending_modified_values = ModelType(PendingModifiedValues, deserialize_from='PendingModifiedValues',
serialize_when_none=False)
member_clusters = ListType(StringType, deserialize_from='MemberClusters', default=[])
- node_groups = ListType(ModelType(RedisNodeGroups), deserialize_from='NodeGroups', default=[])
+ node_groups = ListType(ModelType(NodeGroups), deserialize_from='NodeGroups', default=[])
availability_zones = ListType(StringType, default=[])
snapshotting_cluster_id = StringType(deserialize_from='SnapshottingClusterId', serialize_when_none=False)
automatic_failover = StringType(deserialize_from='AutomaticFailover',
@@ -157,8 +206,8 @@ class Redis(AWSCloudService):
member_clusters_outpost_arns = ListType(StringType, deserialize_from='MemberClustersOutpostArns', default=[])
kms_key_id = StringType(deserialize_from='KmsKeyId', serialize_when_none=False)
user_group_ids = ListType(StringType, deserialize_from='UserGroupIds', default=[])
- shards = ListType(ModelType(RedisShard), default=[])
- nodes = ListType(ModelType(RedisNode), default=[])
+ shards = ListType(ModelType(Shard), default=[])
+ nodes = ListType(ModelType(Node), default=[])
def reference(self, region_code):
return {
diff --git a/src/spaceone/inventory/connector/aws_elasticache_connector/schema/resource.py b/src/spaceone/inventory/connector/aws_elasticache_connector/schema/resource.py
index 153ecc39..32b7b943 100644
--- a/src/spaceone/inventory/connector/aws_elasticache_connector/schema/resource.py
+++ b/src/spaceone/inventory/connector/aws_elasticache_connector/schema/resource.py
@@ -2,7 +2,7 @@
from schematics.types import ModelType, StringType, PolyModelType
-from spaceone.inventory.connector.aws_elasticache_connector.schema.data import Redis, Memcached
+from spaceone.inventory.connector.aws_elasticache_connector.schema.data import Redis, Memcached, Valkey
from spaceone.inventory.libs.schema.resource import CloudServiceResource, CloudServiceResponse, CloudServiceMeta
from spaceone.inventory.libs.schema.dynamic_field import TextDyField, ListDyField, DateTimeDyField, EnumDyField
from spaceone.inventory.libs.schema.dynamic_layout import ItemDynamicLayout, TableDynamicLayout, SimpleTableDynamicLayout
@@ -124,6 +124,76 @@
redis_metadata = CloudServiceMeta.set_layouts(layouts=[redis_base, redis_shards, redis_nodes])
+'''
+Valkey
+'''
+valkey_base = ItemDynamicLayout.set_fields('Description', fields=[
+ TextDyField.data_source('Name', 'data.replication_group_id'),
+ TextDyField.data_source('ARN', 'data.arn'),
+ TextDyField.data_source('Mode', 'data.mode'),
+ EnumDyField.data_source('Status', 'data.status', default_state={
+ 'safe': ['available'],
+ 'warning': ['creating', 'modifying', 'deleting', 'snapshotting'],
+ 'alert': ['create-failed']
+ }),
+ TextDyField.data_source('Configuration Endpoint Address', 'data.configuration_endpoint.address'),
+ TextDyField.data_source('Configuration Endpoint Port', 'data.configuration_endpoint.port'),
+ TextDyField.data_source('Primary Endpoint', 'data.primary_endpoint'),
+ TextDyField.data_source('Reader Endpoint', 'data.reader_endpoint'),
+ TextDyField.data_source('Engine', 'data.engine'),
+ TextDyField.data_source('Engine Version Compatibility', 'data.engine_version'),
+ TextDyField.data_source('Multi-AZ', 'data.multi_az'),
+ ListDyField.data_source('Availability Zones', 'data.availability_zones', options={
+ 'delimiter': '
'
+ }),
+ TextDyField.data_source('Auto Fail-over', 'data.automatic_failover'),
+ TextDyField.data_source('Description', 'data.description'),
+ TextDyField.data_source('Parameter Group ', 'data.parameter_group_name'),
+ TextDyField.data_source('Subnet Group ', 'data.subnet_group_name'),
+ TextDyField.data_source('Description', 'data.description'),
+ TextDyField.data_source('Backup Retention Period', 'data.snapshot_retention_limit'),
+ TextDyField.data_source('Encryption in-transit', 'data.transit_encryption_enabled'),
+ TextDyField.data_source('Backup Window', 'data.snapshot_window'),
+ TextDyField.data_source('Encryption at-rest', 'data.at_rest_encryption_enabled'),
+ TextDyField.data_source('Redis AUTH Default User Access', 'data.auth_token_enabled'),
+ TextDyField.data_source('Custom Managed CMK', 'data.kms_key_id'),
+ ListDyField.data_source('User Group', 'data.user_group_ids', options={
+ 'delimiter': '
'
+ }),
+ DateTimeDyField.data_source('AUTH token last modified date', 'data.auth_token_last_modified_date'),
+ ListDyField.data_source('Outpost ARN', 'data.member_clusters_outpost_arns', options={
+ 'delimiter': '
'
+ })
+])
+
+valkey_shards = TableDynamicLayout.set_fields('Shards', 'data.shards', fields=[
+ TextDyField.data_source('Shard Name', 'shard_name'),
+ EnumDyField.data_source('Status', 'status', default_state={
+ 'safe': ['available'],
+ }),
+ TextDyField.data_source('Node Counts', 'nodes'),
+ TextDyField.data_source('Slots', 'slots')
+])
+
+valkey_nodes = TableDynamicLayout.set_fields('Nodes', 'data.nodes', fields=[
+ TextDyField.data_source('Node Name', 'node_name'),
+ EnumDyField.data_source('Status', 'status', default_state={
+ 'safe': ['available'],
+ }),
+ TextDyField.data_source('Current Role', 'current_role'),
+ TextDyField.data_source('Port', 'port'),
+ TextDyField.data_source('Endpoint', 'endpoint'),
+ EnumDyField.data_source('Parameter Group Status', 'parameter_group_status', default_state={
+ 'safe': ['in-sync'],
+ }),
+ TextDyField.data_source('Zone', 'zone'),
+ TextDyField.data_source('ARN', 'arn'),
+ DateTimeDyField.data_source('Created On', 'created_on')
+])
+
+valkey_metadata = CloudServiceMeta.set_layouts(layouts=[valkey_base, valkey_shards, valkey_nodes])
+
+
# Memcached
class ElasticCacheResource(CloudServiceResource):
cloud_service_group = StringType(default='ElastiCache')
@@ -150,3 +220,10 @@ class RedisResponse(CloudServiceResponse):
resource = PolyModelType(RedisResource)
+class ValkeyResource(ElasticCacheResource):
+ cloud_service_type = StringType(default='Valkey')
+ data = ModelType(Valkey)
+ _metadata = ModelType(CloudServiceMeta, default=valkey_metadata, serialized_name='metadata')
+
+class ValkeyResponse(CloudServiceResponse):
+ resource = PolyModelType(ValkeyResource)
diff --git a/src/spaceone/inventory/connector/aws_elasticache_connector/schema/service_type.py b/src/spaceone/inventory/connector/aws_elasticache_connector/schema/service_type.py
index 0f650184..1e11a724 100644
--- a/src/spaceone/inventory/connector/aws_elasticache_connector/schema/service_type.py
+++ b/src/spaceone/inventory/connector/aws_elasticache_connector/schema/service_type.py
@@ -169,7 +169,98 @@
)
+cst_valkey = CloudServiceTypeResource()
+cst_valkey.name = 'Valkey'
+cst_valkey.provider = 'aws'
+cst_valkey.group = 'ElastiCache'
+cst_valkey.labels = ['Database']
+cst_valkey.is_primary = True
+cst_valkey.is_major = True
+cst_valkey.service_code = 'AmazonElastiCache'
+cst_valkey.tags = {
+ 'spaceone:icon': f'{ASSET_URL}/Amazon-ElastiCache.svg',
+}
+
+cst_valkey._metadata = CloudServiceTypeMeta.set_meta(
+ fields=[
+ TextDyField.data_source('Mode', 'data.mode'),
+ EnumDyField.data_source('Status', 'data.status', default_state={
+ 'safe': ['available'],
+ 'warning': ['creating', 'modifying', 'deleting', 'snapshotting'],
+ 'alert': ['create-failed', 'restore-failed']
+ }),
+ TextDyField.data_source('Shard', 'data.shard_count'),
+ TextDyField.data_source('Nodes', 'data.node_count'),
+ TextDyField.data_source('Node Type', 'instance_type'),
+ TextDyField.data_source('Encryption in-transit', 'data.transit_encryption_enabled'),
+ TextDyField.data_source('Encryption at-rest', 'data.at_rest_encryption_enabled'),
+ TextDyField.data_source('ARN', 'data.arn', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Cache Node Type', 'data.cache_node_type', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Engine Version', 'data.engine_version', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Description', 'data.description', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Automatic Failover', 'data.automatic_failover', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Endpoint Address', 'data.configuration_endpoint.address', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Port', 'data.configuration_endpoint.port', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Snapshot Retention Limit', 'data.snapshot_retention_limit', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Parameter Group Name', 'data.parameter_group_name', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Replication Group ID', 'data.replication_group_id', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Snapshot Window', 'data.snapshot_window', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Multi AZ', 'data.multi_az', options={
+ 'is_optional': True
+ }),
+ ListDyField.data_source('Availability Zones', 'data.availability_zones', options={
+ 'delimiter': '
',
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Subnet Group Name', 'data.subnet_group_name', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('Auth Token Enabled', 'data.auth_token_enabled', options={
+ 'is_optional': True
+ }),
+ TextDyField.data_source('AWS Account ID', 'account', options={
+ 'is_optional': True
+ })
+ ],
+ search=[
+ SearchField.set(name='ARN', key='data.arn'),
+ SearchField.set(name='Mode', key='data.mode'),
+ SearchField.set(name='Status', key='data.status'),
+ SearchField.set(name='Shard Count', key='data.shard_count', data_type='integer'),
+ SearchField.set(name='Node Count', key='data.node_count', data_type='integer'),
+ SearchField.set(name='Node Type', key='instance_type'),
+ SearchField.set(name='Multi AZ', key='data.multi_az'),
+ SearchField.set(name='Configuration Endpoint Address', key='data.configuration_endpoint.address'),
+ SearchField.set(name='Configuration Endpoint Port', key='data.configuration_endpoint.port'),
+ SearchField.set(name='AWS Account ID', key='account')
+ ]
+)
+
+
CLOUD_SERVICE_TYPES = [
CloudServiceTypeResponse({'resource': cst_memcached}),
CloudServiceTypeResponse({'resource': cst_redis}),
+ CloudServiceTypeResponse({'resource': cst_valkey})
]