diff --git a/Libraries/Libraries.sln b/Libraries/Libraries.sln
index b2a87e830..c0e00084d 100644
--- a/Libraries/Libraries.sln
+++ b/Libraries/Libraries.sln
@@ -77,6 +77,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerShellTests", "test\Pow
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerShellScriptsAsFunctions", "test\TestPowerShellFunctions\PowerShellScriptsAsFunctions\PowerShellScriptsAsFunctions.csproj", "{0AD1E5D6-AC23-47C1-97BF-227007021B6F}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Amazon.Lambda.CloudWatchEvents", "src\Amazon.Lambda.CloudWatchEvents\Amazon.Lambda.CloudWatchEvents.csproj", "{AD96AA48-2E1A-4BBB-9329-E1E484172FE3}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -203,6 +205,10 @@ Global
{0AD1E5D6-AC23-47C1-97BF-227007021B6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0AD1E5D6-AC23-47C1-97BF-227007021B6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0AD1E5D6-AC23-47C1-97BF-227007021B6F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AD96AA48-2E1A-4BBB-9329-E1E484172FE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AD96AA48-2E1A-4BBB-9329-E1E484172FE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AD96AA48-2E1A-4BBB-9329-E1E484172FE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AD96AA48-2E1A-4BBB-9329-E1E484172FE3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -240,6 +246,7 @@ Global
{ADEC039D-0C34-4DA7-802B-6204FFE3F1F5} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69}
{997B1047-4361-4E6D-9850-F130EC188141} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69}
{0AD1E5D6-AC23-47C1-97BF-227007021B6F} = {ADEC039D-0C34-4DA7-802B-6204FFE3F1F5}
+ {AD96AA48-2E1A-4BBB-9329-E1E484172FE3} = {AAB54E74-20B1-42ED-BC3D-CE9F7BC7FD12}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {503678A4-B8D1-4486-8915-405A3E9CF0EB}
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/Amazon.Lambda.CloudWatchEvents.csproj b/Libraries/src/Amazon.Lambda.CloudWatchEvents/Amazon.Lambda.CloudWatchEvents.csproj
new file mode 100644
index 000000000..d60a4a60f
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/Amazon.Lambda.CloudWatchEvents.csproj
@@ -0,0 +1,20 @@
+
+
+
+
+
+ netstandard1.3
+ 1.6.0
+ Amazon Lambda .NET Core support - CloudWatchEvents package.
+ Amazon.Lambda.CloudWatchEvents
+ 1.0.0
+ Amazon.Lambda.CloudWatchEvents
+ Amazon.Lambda.CloudWatchEvents
+ AWS;Amazon;Lambda
+
+
+
+
+
+
+
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/CloudWatchEvent.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/CloudWatchEvent.cs
new file mode 100644
index 000000000..55968369e
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/CloudWatchEvent.cs
@@ -0,0 +1,77 @@
+namespace Amazon.Lambda.CloudWatchEvents
+{
+ using System;
+ using System.Collections.Generic;
+
+ ///
+ /// AWS CloudWatch event
+ /// The contents of the detail top-level field are different depending on which service generated the event and what the event is.
+ /// The combination of the source and detail-type fields serves to identify the fields and values found in the detail field.
+ /// Complete list of events that inherit this interface: https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/EventTypes.html
+ /// https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CloudWatchEventsandEventPatterns.html
+ /// https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/EventTypes.html
+ ///
+ public class CloudWatchEvent
+ {
+ ///
+ /// By default, this is set to 0 (zero) in all events.
+ ///
+ public string Version { get; set; }
+
+ ///
+ /// The 12-digit number identifying an AWS account.
+ ///
+ public string Account { get; set; }
+
+ ///
+ /// Identifies the AWS region where the event originated.
+ ///
+ public string Region { get; set; }
+
+ ///
+ /// A JSON object, whose content is at the discretion of the service originating the event.
+ /// The detail content in the example above is very simple, just two fields.
+ /// AWS API call events have detail objects with around 50 fields nested several levels deep.
+ ///
+ public T Detail { get; set; }
+
+ ///
+ /// Identifies, in combination with the source field, the fields and values that appear in the detail field.
+ /// For example, ScheduledEvent will be null
+ /// For example, ECSEvent could be "ECS Container Instance State Change" or "ECS Task State Change"
+ ///
+ public string DetailType { get; set; }
+
+ ///
+ /// Identifies the service that sourced the event.
+ /// All events sourced from within AWS begin with "aws."
+ /// Customer-generated events can have any value here, as long as it doesn't begin with "aws."
+ /// We recommend the use of Java package-name style reverse domain-name strings.
+ /// For example, ScheduledEvent will be "aws.events"
+ /// For example, ECSEvent will be "aws.ecs"
+ ///
+ public string Source { get; set; }
+
+ ///
+ /// The event timestamp, which can be specified by the service originating the event.
+ /// If the event spans a time interval, the service might choose to report the start time,
+ /// so this value can be noticeably before the time the event is actually received.
+ ///
+ public DateTime Time { get; set; }
+
+ ///
+ /// A unique value is generated for every event.
+ /// This can be helpful in tracing events as they move through rules to targets, and are processed.
+ ///
+ public string Id { get; set; }
+
+ ///
+ /// This JSON array contains ARNs that identify resources that are involved in the event.
+ /// Inclusion of these ARNs is at the discretion of the service.
+ /// For example, Amazon EC2 instance state-changes include Amazon EC2 instance ARNs, Auto Scaling events
+ /// include ARNs for both instances and Auto Scaling groups, but API calls with AWS CloudTrail do not
+ /// include resource ARNs.
+ ///
+ public List Resources { get; set; }
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Attachment.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Attachment.cs
new file mode 100644
index 000000000..27074c940
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Attachment.cs
@@ -0,0 +1,33 @@
+using System.Collections.Generic;
+
+namespace Amazon.Lambda.CloudWatchEvents.ECSEvents
+{
+ ///
+ /// An object representing a container instance or task attachment.
+ /// https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_Attachment.html
+ ///
+ public class Attachment
+ {
+ ///
+ /// Details of the attachment. For elastic network interfaces, this includes the
+ /// network interface ID, the MAC address, the subnet ID, and the private IPv4 address.
+ ///
+ public List> Details { get; set; }
+
+ ///
+ /// The unique identifier for the attachment.
+ ///
+ public string Id { get; set; }
+
+ ///
+ /// The status of the attachment. Valid values are PRECREATED, CREATED, ATTACHING,
+ /// ATTACHED, DETACHING, DETACHED, and DELETED.
+ ///
+ public string Status { get; set; }
+
+ ///
+ /// The type of the attachment, such as ElasticNetworkInterface.
+ ///
+ public string Type { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Attribute.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Attribute.cs
new file mode 100644
index 000000000..7eae7d505
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Attribute.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Amazon.Lambda.CloudWatchEvents.ECSEvents
+{
+ ///
+ /// https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerInstance.html
+ ///
+ public class Attribute
+ {
+ ///
+ /// The attributes set for the container instance, either by the Amazon ECS container agent at instance
+ /// registration or manually with the PutAttributes operation.
+ ///
+ public string Name { get; set; }
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Container.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Container.cs
new file mode 100644
index 000000000..30262f41c
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Container.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Amazon.Lambda.CloudWatchEvents.ECSEvents
+{
+ ///
+ /// A Docker container that is part of a task.
+ /// https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_Container.html
+ ///
+ public class Container
+ {
+ ///
+ /// The Amazon Resource Name (ARN) of the container.
+ ///
+ public string ContainerArn { get; set; }
+
+ ///
+ /// The exit code returned from the container.
+ ///
+ public int ExitCode { get; set; }
+
+ ///
+ /// The last known status of the container.
+ ///
+ public string LastStatus { get; set; }
+
+ ///
+ /// The name of the container.
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// The ARN of the task.
+ ///
+ public string TaskArn { get; set; }
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/ContainerInstance.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/ContainerInstance.cs
new file mode 100644
index 000000000..beba77bce
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/ContainerInstance.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Collections.Generic;
+
+namespace Amazon.Lambda.CloudWatchEvents.ECSEvents
+{
+ ///
+ /// An EC2 instance that is running the Amazon ECS agent and has been registered with a cluster.
+ /// https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerInstance.html
+ ///
+ public class ContainerInstance
+ {
+ ///
+ /// This parameter returns true if the agent is connected to Amazon ECS.
+ /// Registered instances with an agent that may be unhealthy or stopped return false. Instances without
+ /// a connected agent can't accept placement requests.
+ ///
+ public bool AgentConnected { get; set; }
+
+ ///
+ /// The status of the most recent agent update. If an update has never been requested, this value is NULL.
+ ///
+ public string AgentUpdateStatus { get; set; }
+
+ ///
+ /// The elastic network interfaces associated with the container instance.
+ ///
+ public List Attachments { get; set; }
+
+ ///
+ /// The attributes set for the container instance, either by the Amazon ECS container agent at instance
+ /// registration or manually with the PutAttributes operation.
+ ///
+ public List Attributes { get; set; }
+
+ ///
+ /// The Amazon Resource Name (ARN) of the container instance.
+ /// The ARN contains the arn:aws:ecs namespace, followed by the region of the container instance,
+ /// the AWS account ID of the container instance owner, the container-instance namespace,
+ /// and then the container instance ID.
+ ///
+ public string ContainerInstanceArn { get; set; }
+
+ ///
+ /// The EC2 instance ID of the container instance.
+ ///
+ public string Ec2InstanceId { get; set; }
+
+ ///
+ /// The number of tasks on the container instance that are in the PENDING status.
+ ///
+ public int PendingTasksCount { get; set; }
+
+ ///
+ /// The Unix time stamp for when the container instance was registered.
+ ///
+ public DateTime RegisteredAt { get; set; }
+
+ ///
+ /// For CPU and memory resource types, this parameter describes the amount of each resource that was available
+ /// on the container instance when the container agent registered it with Amazon ECS; this value represents
+ /// the total amount of CPU and memory that can be allocated on this container instance to tasks.
+ /// For port resource types, this parameter describes the ports that were reserved by the Amazon ECS container
+ /// agent when it registered the container instance with Amazon ECS.
+ ///
+ public List RegisteredResources { get; set; }
+
+ ///
+ /// For CPU and memory resource types, this parameter describes the remaining CPU and memory that has not
+ /// already been allocated to tasks and is therefore available for new tasks.
+ /// For port resource types, this parameter describes the ports that were reserved by the Amazon ECS
+ /// container agent (at instance registration time) and any task containers that have reserved port mappings
+ /// on the host (with the host or bridge network mode).
+ /// Any port that is not specified here is available for new tasks.
+ ///
+ public List RemainingResources { get; set; }
+
+ ///
+ /// The number of tasks on the container instance that are in the RUNNING status.
+ ///
+ public int RunningTasksCount { get; set; }
+
+ ///
+ /// The status of the container instance.
+ /// The valid values are ACTIVE, INACTIVE, or DRAINING. ACTIVE indicates that the container instance
+ /// can accept tasks.
+ /// DRAINING indicates that new tasks are not placed on the container instance and any service tasks
+ /// running on the container instance are removed if possible.
+ ///
+ public string Status { get; set; }
+
+ ///
+ /// The version counter for the container instance.
+ /// Every time a container instance experiences a change that triggers a CloudWatch event,
+ /// the version counter is incremented. If you are replicating your Amazon ECS container instance
+ /// state with CloudWatch Events, you can compare the version of a container instance reported by
+ /// the Amazon ECS APIs with the version reported in CloudWatch Events for the container instance
+ /// (inside the detail object) to verify that the version in your event stream is current.
+ ///
+ public long Version { get; set; }
+
+ ///
+ /// The version information for the Amazon ECS container agent and Docker daemon running on the container instance.
+ ///
+ public VersionInfo VersionInfo { get; set; }
+
+ // NOTE: The following properties are not present in the ContainerInstance object documentation but have
+ // been added here for convenience.
+
+ ///
+ /// The Amazon Resource Name (ARN) of the cluster that hosts the service.
+ ///
+ public string ClusterArn { get; set; }
+
+ ///
+ /// The Unix time stamp for when the service was last updated.
+ ///
+ public DateTime UpdatedAt { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/ContainerOverride.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/ContainerOverride.cs
new file mode 100644
index 000000000..e4862ec58
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/ContainerOverride.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Amazon.Lambda.CloudWatchEvents.ECSEvents
+{
+ ///
+ /// The overrides that should be sent to a container.
+ /// https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerOverride.html
+ ///
+ public class ContainerOverride
+ {
+ ///
+ /// The command to send to the container that overrides the default command from
+ /// the Docker image or the task definition. You must also specify a container name.
+ ///
+ public List Command { get; set; }
+
+ ///
+ /// The number of cpu units reserved for the container, instead of the default value
+ /// from the task definition. You must also specify a container name.
+ ///
+ public int Cpu { get; set; }
+
+ ///
+ /// The environment variables to send to the container. You can add new environment variables,
+ /// which are added to the container at launch, or you can override the existing environment
+ /// variables from the Docker image or the task definition. You must also specify a container name.
+ ///
+ public List> Environment { get; set; }
+
+ ///
+ /// The hard limit (in MiB) of memory to present to the container, instead of the default value
+ /// from the task definition. If your container attempts to exceed the memory specified here,
+ /// the container is killed. You must also specify a container name.
+ ///
+ public int Memory { get; set; }
+
+ ///
+ /// The soft limit (in MiB) of memory to reserve for the container, instead of the default value
+ /// from the task definition. You must also specify a container name.
+ ///
+ public int MemoryReservation { get; set; }
+
+ ///
+ /// The name of the container that receives the override.
+ /// This parameter is required if any override is specified.
+ ///
+ public string Name { get; set; }
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/ECSContainerInstanceStateChangeEvent.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/ECSContainerInstanceStateChangeEvent.cs
new file mode 100644
index 000000000..467acefa7
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/ECSContainerInstanceStateChangeEvent.cs
@@ -0,0 +1,17 @@
+using System;
+using Amazon.Lambda.CloudWatchEvents;
+
+namespace Amazon.Lambda.CloudWatchEvents.ECSEvents
+{
+
+ ///
+ /// AWS ECS event
+ /// http://docs.aws.amazon.com/config/latest/developerguide/evaluate-config_develop-rules.html
+ /// http://docs.aws.amazon.com/config/latest/developerguide/evaluate-config_develop-rules_example-events.html
+ /// https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_cwe_events.html
+ ///
+ public class ECSContainerInstanceStateChangeEvent : CloudWatchEvent
+ {
+
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/ECSTaskStateChangeEvent.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/ECSTaskStateChangeEvent.cs
new file mode 100644
index 000000000..26e526607
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/ECSTaskStateChangeEvent.cs
@@ -0,0 +1,16 @@
+using System;
+using Amazon.Lambda.CloudWatchEvents;
+
+namespace Amazon.Lambda.CloudWatchEvents.ECSEvents
+{
+ ///
+ /// /// AWS ECS task state change event
+ /// http://docs.aws.amazon.com/config/latest/developerguide/evaluate-config_develop-rules.html
+ /// http://docs.aws.amazon.com/config/latest/developerguide/evaluate-config_develop-rules_example-events.html
+ /// https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_cwe_events.html
+ ///
+ public class ECSTaskStateChangeEvent : CloudWatchEvent
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Resource.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Resource.cs
new file mode 100644
index 000000000..c72f1f399
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Resource.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Amazon.Lambda.CloudWatchEvents.ECSEvents
+{
+ using System.Collections.Generic;
+
+ ///
+ /// Describes the resources available for a container instance.
+ /// https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_Resource.html
+ ///
+ public class Resource
+ {
+ ///
+ /// The name of the resource, such as CPU, MEMORY, PORTS, PORTS_UDP, or a user-defined resource.
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// The type of the resource, such as INTEGER, DOUBLE, LONG, or STRINGSET.
+ ///
+ public string Type { get; set; }
+
+ ///
+ /// When the integerValue type is set, the value of the resource must be an integer.
+ ///
+ public int IntegerValue { get; set; }
+
+ ///
+ /// When the stringSetValue type is set, the value of the resource must be a string type.
+ ///
+ public List StringSetValue { get; set; }
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Task.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Task.cs
new file mode 100644
index 000000000..8503322a0
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/Task.cs
@@ -0,0 +1,165 @@
+using System;
+using System.Collections.Generic;
+
+namespace Amazon.Lambda.CloudWatchEvents.ECSEvents
+{
+ ///
+ /// Details on a task in a cluster.
+ /// https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_Task.html
+ ///
+ public class Task
+ {
+ ///
+ /// The elastic network adapter associated with the task if the task uses the awsvpc network mode.
+ ///
+ public List Attachments { get; set; }
+
+ ///
+ /// The ARN of the cluster that hosts the task.
+ ///
+ public string ClusterArn { get; set; }
+
+ ///
+ /// The connectivity status of a task.
+ ///
+ public string Connectivity { get; set; }
+
+ ///
+ /// The Unix time stamp for when the task last went into CONNECTED status.
+ ///
+ public DateTime ConnectivityAt { get; set; }
+
+ ///
+ /// The ARN of the container instances that host the task.
+ ///
+ public string ContainerInstanceArn { get; set; }
+
+ ///
+ /// The containers associated with the task.
+ ///
+ public List Containers { get; set; }
+
+ ///
+ /// The number of CPU units used by the task. It can be expressed as an integer using CPU units,
+ /// for example 1024, or as a string using vCPUs, for example 1 vCPU or 1 vcpu, in a task definition.
+ /// String values are converted to an integer indicating the CPU units when the task definition is registered.
+ /// See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_Task.html for extra info.
+ ///
+ public string Cpu { get; set; }
+
+ ///
+ /// The Unix time stamp for when the task was created (the task entered the PENDING state).
+ ///
+ public DateTime CreatedAt { get; set; }
+
+ ///
+ /// The desired status of the task. For more information,
+ /// see Task Lifecycle: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_life_cycle.html.
+ ///
+ public string DesiredStatus { get; set; }
+
+ ///
+ /// The Unix time stamp for when the task execution stopped.
+ ///
+ public DateTime ExecutionStoppedAt { get; set; }
+
+ ///
+ /// The name of the task group associated with the task.
+ ///
+ public string Group { get; set; }
+
+ ///
+ /// The health status for the task, which is determined by the health of the essential containers in the task.
+ /// If all essential containers in the task are reporting as HEALTHY, then the task status also
+ /// reports as HEALTHY. If any essential containers in the task are reporting as UNHEALTHY or UNKNOWN,
+ /// then the task status also reports as UNHEALTHY or UNKNOWN, accordingly.
+ /// See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_Task.html for extra info.
+ ///
+ public string HealthStatus { get; set; }
+
+ ///
+ /// The last known status of the task. For more information,
+ /// see Task Lifecycle: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_life_cycle.html.
+ ///
+ public string LastStatus { get; set; }
+
+ ///
+ /// The launch type on which your task is running.
+ ///
+ public string LaunchType { get; set; }
+
+ ///
+ /// The amount of memory (in MiB) used by the task. It can be expressed as an integer using MiB,
+ /// for example 1024, or as a string using GB, for example 1GB or 1 GB, in a task definition.
+ /// String values are converted to an integer indicating the MiB when the task definition is registered.
+ /// See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_Task.html for extra info.
+ ///
+ public string Memory { get; set; }
+
+ ///
+ /// One or more container overrides.
+ ///
+ public TaskOverride Overrides { get; set; }
+
+ ///
+ /// The platform version on which your task is running. For more information,
+ /// see AWS Fargate Platform Versions in the Amazon Elastic Container Service Developer Guide.
+ /// https://docs.aws.amazon.com/AmazonECS/latest/developerguide/platform_versions.html
+ ///
+ public string PlatformVersion { get; set; }
+
+ ///
+ /// The Unix time stamp for when the container image pull began.
+ ///
+ public DateTime PullStartedAt { get; set; }
+
+ ///
+ /// The Unix time stamp for when the container image pull completed.
+ ///
+ public DateTime PullStoppedAt { get; set; }
+
+ ///
+ /// The Unix time stamp for when the task started (the task
+ /// transitioned from the PENDING state to the RUNNING state).
+ ///
+ public DateTime StartedAt { get; set; }
+
+ ///
+ /// The tag specified when a task is started. If the task is started by an Amazon ECS service,
+ /// then the startedBy parameter contains the deployment ID of the service that starts it.
+ ///
+ public string StartedBy { get; set; }
+
+ ///
+ /// The Unix time stamp for when the task stops (transitions from the RUNNING state to STOPPED).
+ ///
+ public DateTime StoppedAt { get; set; }
+
+ ///
+ /// The Amazon Resource Name (ARN) of the task.
+ ///
+ public string TaskArn { get; set; }
+
+ ///
+ /// The ARN of the task definition that creates the task.
+ ///
+ public string TaskDefinitionArn { get; set; }
+
+ ///
+ /// The version counter for the task. Every time a task experiences a change that triggers a CloudWatch event,
+ /// the version counter is incremented. If you are replicating your Amazon ECS task state with
+ /// CloudWatch Events, you can compare the version of a task reported by the Amazon ECS APIs with
+ /// the version reported in CloudWatch Events for the task (inside the detail object) to verify that
+ /// the version in your event stream is current.
+ ///
+ public long Version { get; set; }
+
+ // NOTE: The UpdatedAt property is not present in the Task object documentation but has been
+ // added here for convenience.
+
+ ///
+ /// The Unix time stamp for when the service was last updated.
+ ///
+ public DateTime UpdatedAt { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/TaskOverride.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/TaskOverride.cs
new file mode 100644
index 000000000..fb14a5a41
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/TaskOverride.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Amazon.Lambda.CloudWatchEvents.ECSEvents
+{
+ ///
+ /// The overrides associated with a task.
+ /// https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_TaskOverride.html
+ ///
+ public class TaskOverride
+ {
+ ///
+ /// One or more container overrides sent to a task.
+ ///
+ public List ContainerOverrides { get; set; }
+
+ ///
+ /// The Amazon Resource Name (ARN) of the task execution role that the
+ /// Amazon ECS container agent and the Docker daemon can assume.
+ ///
+ public string ExecutionRoleArn { get; set; }
+
+ ///
+ /// The Amazon Resource Name (ARN) of the IAM role that containers in this task can assume.
+ /// All containers in this task are granted the permissions that are specified in this role.
+ ///
+ public string TaskRoleArn { get; set; }
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/VersionInfo.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/VersionInfo.cs
new file mode 100644
index 000000000..6b5b6922d
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/ECSEvents/VersionInfo.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Amazon.Lambda.CloudWatchEvents.ECSEvents
+{
+ ///
+ /// The Docker and Amazon ECS container agent version information about a container instance.
+ /// https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_VersionInfo.html
+ ///
+ public class VersionInfo
+ {
+ ///
+ /// The Git commit hash for the Amazon ECS container agent build on the amazon-ecs-agent GitHub repository.
+ ///
+ public string AgentHash { get; set; }
+ ///
+ /// The version number of the Amazon ECS container agent.
+ ///
+ public string AgentVersion { get; set; }
+ ///
+ /// The Docker version running on the container instance.
+ ///
+ public string DockerVersion { get; set; }
+ }
+}
diff --git a/Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs b/Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs
index e5bb32558..586f485a4 100644
--- a/Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs
+++ b/Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs
@@ -2,6 +2,7 @@
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
+using System.Reflection;
namespace Amazon.Lambda.Serialization.Json
{
@@ -80,6 +81,18 @@ protected override IList CreateProperties(Type type, MemberSeriali
}
}
}
+ else if (type.FullName.StartsWith("Amazon.Lambda.CloudWatchEvents.")
+ && (type.GetTypeInfo().BaseType?.FullName?.StartsWith("Amazon.Lambda.CloudWatchEvents.CloudWatchEvent`",
+ StringComparison.Ordinal) ?? false))
+ {
+ foreach (JsonProperty property in properties)
+ {
+ if (property.PropertyName.Equals("DetailType", StringComparison.Ordinal))
+ {
+ property.PropertyName = "detail-type";
+ }
+ }
+ }
return properties;
}
diff --git a/Libraries/test/EventsTests/EventTests.cs b/Libraries/test/EventsTests/EventTests.cs
index 36b7a7ef8..52edc2d69 100644
--- a/Libraries/test/EventsTests/EventTests.cs
+++ b/Libraries/test/EventsTests/EventTests.cs
@@ -14,6 +14,8 @@ namespace Amazon.Lambda.Tests
using Amazon.Lambda.LexEvents;
using Amazon.Lambda.KinesisFirehoseEvents;
using Amazon.Lambda.KinesisAnalyticsEvents;
+ using Amazon.Lambda.CloudWatchLogsEvents;
+ using Amazon.Lambda.CloudWatchEvents.ECSEvents;
using Newtonsoft.Json.Linq;
@@ -23,11 +25,11 @@ namespace Amazon.Lambda.Tests
using System.Text;
using Xunit;
using System.Linq;
- using Amazon.Lambda.CloudWatchLogsEvents;
using Newtonsoft.Json;
using JsonSerializer = Amazon.Lambda.Serialization.Json.JsonSerializer;
+
public class EventTest
{
[Fact]
@@ -181,7 +183,7 @@ public void CognitoTest()
private static void Handle(CognitoEvent cognitoEvent)
{
- foreach(var datasetKVP in cognitoEvent.DatasetRecords)
+ foreach (var datasetKVP in cognitoEvent.DatasetRecords)
{
var datasetName = datasetKVP.Key;
var datasetRecord = datasetKVP.Value;
@@ -351,7 +353,7 @@ public void SQSTest()
Assert.Equal("MessageID", record.MessageId);
Assert.Equal("MessageReceiptHandle", record.ReceiptHandle);
Assert.Equal("Message Body", record.Body);
- Assert.Equal("fce0ea8dd236ccb3ed9b37dae260836f", record.Md5OfBody );
+ Assert.Equal("fce0ea8dd236ccb3ed9b37dae260836f", record.Md5OfBody);
Assert.Equal("582c92c5c5b6ac403040a4f3ab3115c9", record.Md5OfMessageAttributes);
Assert.Equal("arn:aws:sqs:us-west-2:123456789012:SQSQueue", record.EventSourceArn);
Assert.Equal("aws:sqs", record.EventSource);
@@ -617,7 +619,7 @@ public void LexResponse()
Assert.Equal("button-text", lexResponse.DialogAction.ResponseCard.GenericAttachments[0].Buttons[0].Text);
Assert.Equal("value sent to server on button click", lexResponse.DialogAction.ResponseCard.GenericAttachments[0].Buttons[0].Value);
- MemoryStream ms = new MemoryStream();
+ MemoryStream ms = new MemoryStream();
serializer.Serialize(lexResponse, ms);
ms.Position = 0;
var json = new StreamReader(ms).ReadToEnd();
@@ -781,5 +783,104 @@ private string MemoryStreamToBase64String(MemoryStream ms)
var data = ms.ToArray();
return Convert.ToBase64String(data);
}
+
+ [Fact]
+ public void ECSContainerInstanceStateChangeEventTest()
+ {
+ using (var fileStream = File.OpenRead("ecs-container-state-change-event.json"))
+ {
+ var serializer = new JsonSerializer();
+ var ecsEvent = serializer.Deserialize(fileStream);
+
+ Assert.Equal(ecsEvent.Version, "0");
+ Assert.Equal(ecsEvent.Id, "8952ba83-7be2-4ab5-9c32-6687532d15a2");
+ Assert.Equal(ecsEvent.DetailType, "ECS Container Instance State Change");
+ Assert.Equal(ecsEvent.Source, "aws.ecs");
+ Assert.Equal(ecsEvent.Account, "111122223333");
+ Assert.Equal(ecsEvent.Time.ToUniversalTime(), DateTime.Parse("2016-12-06T16:41:06Z").ToUniversalTime());
+ Assert.Equal(ecsEvent.Region, "us-east-1");
+ Assert.Equal(ecsEvent.Resources.Count, 1);
+ Assert.Equal(ecsEvent.Resources[0], "arn:aws:ecs:us-east-1:111122223333:container-instance/b54a2a04-046f-4331-9d74-3f6d7f6ca315");
+ Assert.IsType(typeof(ContainerInstance), ecsEvent.Detail);
+ Assert.Equal(ecsEvent.Detail.AgentConnected, true);
+ Assert.Equal(ecsEvent.Detail.Attributes.Count, 14);
+ Assert.Equal(ecsEvent.Detail.Attributes[0].Name, "com.amazonaws.ecs.capability.logging-driver.syslog");
+ Assert.Equal(ecsEvent.Detail.ClusterArn, "arn:aws:ecs:us-east-1:111122223333:cluster/default");
+ Assert.Equal(ecsEvent.Detail.ContainerInstanceArn, "arn:aws:ecs:us-east-1:111122223333:container-instance/b54a2a04-046f-4331-9d74-3f6d7f6ca315");
+ Assert.Equal(ecsEvent.Detail.Ec2InstanceId, "i-f3a8506b");
+ Assert.Equal(ecsEvent.Detail.RegisteredResources.Count, 4);
+ Assert.Equal(ecsEvent.Detail.RegisteredResources[0].Name, "CPU");
+ Assert.Equal(ecsEvent.Detail.RegisteredResources[0].Type, "INTEGER");
+ Assert.Equal(ecsEvent.Detail.RegisteredResources[0].IntegerValue, 2048);
+ Assert.Equal(ecsEvent.Detail.RegisteredResources[2].StringSetValue[0], "22");
+ Assert.Equal(ecsEvent.Detail.RemainingResources.Count, 4);
+ Assert.Equal(ecsEvent.Detail.RemainingResources[0].Name, "CPU");
+ Assert.Equal(ecsEvent.Detail.RemainingResources[0].Type, "INTEGER");
+ Assert.Equal(ecsEvent.Detail.RemainingResources[0].IntegerValue, 1988);
+ Assert.Equal(ecsEvent.Detail.RemainingResources[2].StringSetValue[0], "22");
+ Assert.Equal(ecsEvent.Detail.Status, "ACTIVE");
+ Assert.Equal(ecsEvent.Detail.Version, 14801);
+ Assert.Equal(ecsEvent.Detail.VersionInfo.AgentHash, "aebcbca");
+ Assert.Equal(ecsEvent.Detail.VersionInfo.AgentVersion, "1.13.0");
+ Assert.Equal(ecsEvent.Detail.VersionInfo.DockerVersion, "DockerVersion: 1.11.2");
+ Assert.Equal(ecsEvent.Detail.UpdatedAt.ToUniversalTime(), DateTime.Parse("2016-12-06T16:41:06.991Z").ToUniversalTime());
+
+ Handle(ecsEvent);
+ }
+ }
+
+ [Fact]
+ public void ECSTaskStateChangeEventTest()
+ {
+ using (var fileStream = File.OpenRead("ecs-task-state-change-event.json"))
+ {
+ var serializer = new JsonSerializer();
+ var ecsEvent = serializer.Deserialize(fileStream);
+
+ Assert.Equal(ecsEvent.Version, "0");
+ Assert.Equal(ecsEvent.Id, "9bcdac79-b31f-4d3d-9410-fbd727c29fab");
+ Assert.Equal(ecsEvent.DetailType, "ECS Task State Change");
+ Assert.Equal(ecsEvent.Source, "aws.ecs");
+ Assert.Equal(ecsEvent.Account, "111122223333");
+ Assert.Equal(ecsEvent.Time.ToUniversalTime(), DateTime.Parse("2016-12-06T16:41:06Z").ToUniversalTime());
+ Assert.Equal(ecsEvent.Region, "us-east-1");
+ Assert.Equal(ecsEvent.Resources.Count, 1);
+ Assert.Equal(ecsEvent.Resources[0], "arn:aws:ecs:us-east-1:111122223333:task/b99d40b3-5176-4f71-9a52-9dbd6f1cebef");
+ Assert.IsType(typeof(Task), ecsEvent.Detail);
+ Assert.Equal(ecsEvent.Detail.ClusterArn, "arn:aws:ecs:us-east-1:111122223333:cluster/default");
+ Assert.Equal(ecsEvent.Detail.ContainerInstanceArn, "arn:aws:ecs:us-east-1:111122223333:container-instance/b54a2a04-046f-4331-9d74-3f6d7f6ca315");
+ Assert.Equal(ecsEvent.Detail.Containers.Count, 1);
+ Assert.Equal(ecsEvent.Detail.Containers[0].ContainerArn, "arn:aws:ecs:us-east-1:111122223333:container/3305bea1-bd16-4217-803d-3e0482170a17");
+ Assert.Equal(ecsEvent.Detail.Containers[0].ExitCode, 0);
+ Assert.Equal(ecsEvent.Detail.Containers[0].LastStatus, "STOPPED");
+ Assert.Equal(ecsEvent.Detail.Containers[0].Name, "xray");
+ Assert.Equal(ecsEvent.Detail.Containers[0].TaskArn, "arn:aws:ecs:us-east-1:111122223333:task/b99d40b3-5176-4f71-9a52-9dbd6f1cebef");
+ Assert.Equal(ecsEvent.Detail.CreatedAt.ToUniversalTime(), DateTime.Parse("2016-12-06T16:41:05.702Z").ToUniversalTime());
+ Assert.Equal(ecsEvent.Detail.DesiredStatus, "RUNNING");
+ Assert.Equal(ecsEvent.Detail.Group, "task-group");
+ Assert.Equal(ecsEvent.Detail.LastStatus, "RUNNING");
+ Assert.Equal(ecsEvent.Detail.Overrides.ContainerOverrides.Count, 1);
+ Assert.Equal(ecsEvent.Detail.Overrides.ContainerOverrides[0].Name, "xray");
+ Assert.Equal(ecsEvent.Detail.StartedAt.ToUniversalTime(), DateTime.Parse("2016-12-06T16:41:06.8Z").ToUniversalTime());
+ Assert.Equal(ecsEvent.Detail.StartedBy, "ecs-svc/9223370556150183303");
+ Assert.Equal(ecsEvent.Detail.UpdatedAt.ToUniversalTime(), DateTime.Parse("2016-12-06T16:41:06.975Z").ToUniversalTime());
+ Assert.Equal(ecsEvent.Detail.TaskArn, "arn:aws:ecs:us-east-1:111122223333:task/b99d40b3-5176-4f71-9a52-9dbd6f1cebef");
+ Assert.Equal(ecsEvent.Detail.TaskDefinitionArn, "arn:aws:ecs:us-east-1:111122223333:task-definition/xray:2");
+ Assert.Equal(ecsEvent.Detail.Version, 4);
+
+ Handle(ecsEvent);
+ }
+ }
+
+ private void Handle(ECSContainerInstanceStateChangeEvent ecsEvent)
+ {
+ Console.WriteLine($"[{ecsEvent.Source} {ecsEvent.Time}] {ecsEvent.DetailType}");
+ }
+
+ private void Handle(ECSTaskStateChangeEvent ecsEvent)
+ {
+ Console.WriteLine($"[{ecsEvent.Source} {ecsEvent.Time}] {ecsEvent.DetailType}");
+ }
+
}
}
diff --git a/Libraries/test/EventsTests/EventsTests.csproj b/Libraries/test/EventsTests/EventsTests.csproj
index 15fe53575..95b98dccf 100644
--- a/Libraries/test/EventsTests/EventsTests.csproj
+++ b/Libraries/test/EventsTests/EventsTests.csproj
@@ -16,6 +16,8 @@
+
+
@@ -23,6 +25,7 @@
+
diff --git a/Libraries/test/EventsTests/ecs-container-state-change-event.json b/Libraries/test/EventsTests/ecs-container-state-change-event.json
new file mode 100644
index 000000000..aaf6365f8
--- /dev/null
+++ b/Libraries/test/EventsTests/ecs-container-state-change-event.json
@@ -0,0 +1,126 @@
+{
+ "version": "0",
+ "id": "8952ba83-7be2-4ab5-9c32-6687532d15a2",
+ "detail-type": "ECS Container Instance State Change",
+ "source": "aws.ecs",
+ "account": "111122223333",
+ "time": "2016-12-06T16:41:06Z",
+ "region": "us-east-1",
+ "resources": [
+ "arn:aws:ecs:us-east-1:111122223333:container-instance/b54a2a04-046f-4331-9d74-3f6d7f6ca315"
+ ],
+ "detail": {
+ "agentConnected": true,
+ "attributes": [
+ {
+ "name": "com.amazonaws.ecs.capability.logging-driver.syslog"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.task-iam-role-network-host"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.logging-driver.json-file"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.docker-remote-api.1.17"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.privileged-container"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.ecr-auth"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.docker-remote-api.1.20"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.docker-remote-api.1.21"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.docker-remote-api.1.22"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.docker-remote-api.1.23"
+ },
+ {
+ "name": "com.amazonaws.ecs.capability.task-iam-role"
+ }
+ ],
+ "clusterArn": "arn:aws:ecs:us-east-1:111122223333:cluster/default",
+ "containerInstanceArn": "arn:aws:ecs:us-east-1:111122223333:container-instance/b54a2a04-046f-4331-9d74-3f6d7f6ca315",
+ "ec2InstanceId": "i-f3a8506b",
+ "registeredResources": [
+ {
+ "name": "CPU",
+ "type": "INTEGER",
+ "integerValue": 2048
+ },
+ {
+ "name": "MEMORY",
+ "type": "INTEGER",
+ "integerValue": 3767
+ },
+ {
+ "name": "PORTS",
+ "type": "STRINGSET",
+ "stringSetValue": [
+ "22",
+ "2376",
+ "2375",
+ "51678",
+ "51679"
+ ]
+ },
+ {
+ "name": "PORTS_UDP",
+ "type": "STRINGSET",
+ "stringSetValue": []
+ }
+ ],
+ "remainingResources": [
+ {
+ "name": "CPU",
+ "type": "INTEGER",
+ "integerValue": 1988
+ },
+ {
+ "name": "MEMORY",
+ "type": "INTEGER",
+ "integerValue": 767
+ },
+ {
+ "name": "PORTS",
+ "type": "STRINGSET",
+ "stringSetValue": [
+ "22",
+ "2376",
+ "2375",
+ "51678",
+ "51679"
+ ]
+ },
+ {
+ "name": "PORTS_UDP",
+ "type": "STRINGSET",
+ "stringSetValue": []
+ }
+ ],
+ "status": "ACTIVE",
+ "version": 14801,
+ "versionInfo": {
+ "agentHash": "aebcbca",
+ "agentVersion": "1.13.0",
+ "dockerVersion": "DockerVersion: 1.11.2"
+ },
+ "updatedAt": "2016-12-06T16:41:06.991Z"
+ }
+}
\ No newline at end of file
diff --git a/Libraries/test/EventsTests/ecs-task-state-change-event.json b/Libraries/test/EventsTests/ecs-task-state-change-event.json
new file mode 100644
index 000000000..fa36a1ade
--- /dev/null
+++ b/Libraries/test/EventsTests/ecs-task-state-change-event.json
@@ -0,0 +1,42 @@
+{
+ "version": "0",
+ "id": "9bcdac79-b31f-4d3d-9410-fbd727c29fab",
+ "detail-type": "ECS Task State Change",
+ "source": "aws.ecs",
+ "account": "111122223333",
+ "time": "2016-12-06T16:41:06Z",
+ "region": "us-east-1",
+ "resources": [
+ "arn:aws:ecs:us-east-1:111122223333:task/b99d40b3-5176-4f71-9a52-9dbd6f1cebef"
+ ],
+ "detail": {
+ "clusterArn": "arn:aws:ecs:us-east-1:111122223333:cluster/default",
+ "containerInstanceArn": "arn:aws:ecs:us-east-1:111122223333:container-instance/b54a2a04-046f-4331-9d74-3f6d7f6ca315",
+ "containers": [
+ {
+ "containerArn": "arn:aws:ecs:us-east-1:111122223333:container/3305bea1-bd16-4217-803d-3e0482170a17",
+ "exitCode": 0,
+ "lastStatus": "STOPPED",
+ "name": "xray",
+ "taskArn": "arn:aws:ecs:us-east-1:111122223333:task/b99d40b3-5176-4f71-9a52-9dbd6f1cebef"
+ }
+ ],
+ "createdAt": "2016-12-06T16:41:05.702Z",
+ "desiredStatus": "RUNNING",
+ "group": "task-group",
+ "lastStatus": "RUNNING",
+ "overrides": {
+ "containerOverrides": [
+ {
+ "name": "xray"
+ }
+ ]
+ },
+ "startedAt": "2016-12-06T16:41:06.8Z",
+ "startedBy": "ecs-svc/9223370556150183303",
+ "updatedAt": "2016-12-06T16:41:06.975Z",
+ "taskArn": "arn:aws:ecs:us-east-1:111122223333:task/b99d40b3-5176-4f71-9a52-9dbd6f1cebef",
+ "taskDefinitionArn": "arn:aws:ecs:us-east-1:111122223333:task-definition/xray:2",
+ "version": 4
+ }
+}
\ No newline at end of file