diff --git a/apis/v1alpha1/ack-generate-metadata.yaml b/apis/v1alpha1/ack-generate-metadata.yaml index fc065da..9fb4760 100755 --- a/apis/v1alpha1/ack-generate-metadata.yaml +++ b/apis/v1alpha1/ack-generate-metadata.yaml @@ -1,13 +1,13 @@ ack_generate_info: - build_date: "2026-03-11T18:55:26Z" + build_date: "2026-03-12T00:53:11Z" build_hash: 5ac6c79fbc941c426d8b70cba768820fc9296542 - go_version: go1.25.7 + go_version: go1.25.0 version: v0.58.0 -api_directory_checksum: 1f4208ba97caf6e9f52dc317cdc9ed1925d1fe6b +api_directory_checksum: 25647e3e28fbe0ec776e6388c646474c13d23346 api_version: v1alpha1 aws_sdk_go_version: 1.32.6 generator_config_info: - file_checksum: 2d9c00d169bf62141d55f1ca924c39b669bbaa13 + file_checksum: f2582d062d9ee453c38a058c0e98edb7734c7814 original_file_name: generator.yaml last_modification: reason: API generation diff --git a/apis/v1alpha1/enums.go b/apis/v1alpha1/enums.go index 9c267ee..0352e91 100644 --- a/apis/v1alpha1/enums.go +++ b/apis/v1alpha1/enums.go @@ -18,47 +18,47 @@ package v1alpha1 type AnomalyDetectorStatus string const ( - AnomalyDetectorStatus_ANALYZING AnomalyDetectorStatus = "ANALYZING" - AnomalyDetectorStatus_DELETED AnomalyDetectorStatus = "DELETED" - AnomalyDetectorStatus_FAILED AnomalyDetectorStatus = "FAILED" + AnomalyDetectorStatus_ANALYZING AnomalyDetectorStatus = "ANALYZING" + AnomalyDetectorStatus_DELETED AnomalyDetectorStatus = "DELETED" + AnomalyDetectorStatus_FAILED AnomalyDetectorStatus = "FAILED" AnomalyDetectorStatus_INITIALIZING AnomalyDetectorStatus = "INITIALIZING" - AnomalyDetectorStatus_PAUSED AnomalyDetectorStatus = "PAUSED" - AnomalyDetectorStatus_TRAINING AnomalyDetectorStatus = "TRAINING" + AnomalyDetectorStatus_PAUSED AnomalyDetectorStatus = "PAUSED" + AnomalyDetectorStatus_TRAINING AnomalyDetectorStatus = "TRAINING" ) type DataProtectionStatus string const ( DataProtectionStatus_ACTIVATED DataProtectionStatus = "ACTIVATED" - DataProtectionStatus_ARCHIVED DataProtectionStatus = "ARCHIVED" - DataProtectionStatus_DELETED DataProtectionStatus = "DELETED" - DataProtectionStatus_DISABLED DataProtectionStatus = "DISABLED" + DataProtectionStatus_ARCHIVED DataProtectionStatus = "ARCHIVED" + DataProtectionStatus_DELETED DataProtectionStatus = "DELETED" + DataProtectionStatus_DISABLED DataProtectionStatus = "DISABLED" ) type DeliveryDestinationType string const ( DeliveryDestinationType_CWL DeliveryDestinationType = "CWL" - DeliveryDestinationType_FH DeliveryDestinationType = "FH" - DeliveryDestinationType_S3 DeliveryDestinationType = "S3" + DeliveryDestinationType_FH DeliveryDestinationType = "FH" + DeliveryDestinationType_S3 DeliveryDestinationType = "S3" ) type Distribution string const ( Distribution_ByLogStream Distribution = "ByLogStream" - Distribution_Random Distribution = "Random" + Distribution_Random Distribution = "Random" ) type EntityRejectionErrorType string const ( - EntityRejectionErrorType_EntitySizeTooLarge EntityRejectionErrorType = "EntitySizeTooLarge" - EntityRejectionErrorType_InvalidAttributes EntityRejectionErrorType = "InvalidAttributes" - EntityRejectionErrorType_InvalidEntity EntityRejectionErrorType = "InvalidEntity" - EntityRejectionErrorType_InvalidKeyAttributes EntityRejectionErrorType = "InvalidKeyAttributes" - EntityRejectionErrorType_InvalidTypeValue EntityRejectionErrorType = "InvalidTypeValue" - EntityRejectionErrorType_MissingRequiredFields EntityRejectionErrorType = "MissingRequiredFields" + EntityRejectionErrorType_EntitySizeTooLarge EntityRejectionErrorType = "EntitySizeTooLarge" + EntityRejectionErrorType_InvalidAttributes EntityRejectionErrorType = "InvalidAttributes" + EntityRejectionErrorType_InvalidEntity EntityRejectionErrorType = "InvalidEntity" + EntityRejectionErrorType_InvalidKeyAttributes EntityRejectionErrorType = "InvalidKeyAttributes" + EntityRejectionErrorType_InvalidTypeValue EntityRejectionErrorType = "InvalidTypeValue" + EntityRejectionErrorType_MissingRequiredFields EntityRejectionErrorType = "MissingRequiredFields" EntityRejectionErrorType_UnsupportedLogGroupType EntityRejectionErrorType = "UnsupportedLogGroupType" ) @@ -66,35 +66,35 @@ type EvaluationFrequency string const ( EvaluationFrequency_FIFTEEN_MIN EvaluationFrequency = "FIFTEEN_MIN" - EvaluationFrequency_FIVE_MIN EvaluationFrequency = "FIVE_MIN" - EvaluationFrequency_ONE_HOUR EvaluationFrequency = "ONE_HOUR" - EvaluationFrequency_ONE_MIN EvaluationFrequency = "ONE_MIN" - EvaluationFrequency_TEN_MIN EvaluationFrequency = "TEN_MIN" - EvaluationFrequency_THIRTY_MIN EvaluationFrequency = "THIRTY_MIN" + EvaluationFrequency_FIVE_MIN EvaluationFrequency = "FIVE_MIN" + EvaluationFrequency_ONE_HOUR EvaluationFrequency = "ONE_HOUR" + EvaluationFrequency_ONE_MIN EvaluationFrequency = "ONE_MIN" + EvaluationFrequency_TEN_MIN EvaluationFrequency = "TEN_MIN" + EvaluationFrequency_THIRTY_MIN EvaluationFrequency = "THIRTY_MIN" ) type ExportTaskStatusCode string const ( - ExportTaskStatusCode_CANCELLED ExportTaskStatusCode = "CANCELLED" - ExportTaskStatusCode_COMPLETED ExportTaskStatusCode = "COMPLETED" - ExportTaskStatusCode_FAILED ExportTaskStatusCode = "FAILED" - ExportTaskStatusCode_PENDING ExportTaskStatusCode = "PENDING" + ExportTaskStatusCode_CANCELLED ExportTaskStatusCode = "CANCELLED" + ExportTaskStatusCode_COMPLETED ExportTaskStatusCode = "COMPLETED" + ExportTaskStatusCode_FAILED ExportTaskStatusCode = "FAILED" + ExportTaskStatusCode_PENDING ExportTaskStatusCode = "PENDING" ExportTaskStatusCode_PENDING_CANCEL ExportTaskStatusCode = "PENDING_CANCEL" - ExportTaskStatusCode_RUNNING ExportTaskStatusCode = "RUNNING" + ExportTaskStatusCode_RUNNING ExportTaskStatusCode = "RUNNING" ) type FlattenedElement string const ( FlattenedElement_first FlattenedElement = "first" - FlattenedElement_last FlattenedElement = "last" + FlattenedElement_last FlattenedElement = "last" ) type IndexSource string const ( - IndexSource_ACCOUNT IndexSource = "ACCOUNT" + IndexSource_ACCOUNT IndexSource = "ACCOUNT" IndexSource_LOG_GROUP IndexSource = "LOG_GROUP" ) @@ -107,8 +107,8 @@ const ( type IntegrationStatus string const ( - IntegrationStatus_ACTIVE IntegrationStatus = "ACTIVE" - IntegrationStatus_FAILED IntegrationStatus = "FAILED" + IntegrationStatus_ACTIVE IntegrationStatus = "ACTIVE" + IntegrationStatus_FAILED IntegrationStatus = "FAILED" IntegrationStatus_PROVISIONING IntegrationStatus = "PROVISIONING" ) @@ -122,14 +122,14 @@ type LogGroupClass string const ( LogGroupClass_INFREQUENT_ACCESS LogGroupClass = "INFREQUENT_ACCESS" - LogGroupClass_STANDARD LogGroupClass = "STANDARD" + LogGroupClass_STANDARD LogGroupClass = "STANDARD" ) type OpenSearchResourceStatusType string const ( - OpenSearchResourceStatusType_ACTIVE OpenSearchResourceStatusType = "ACTIVE" - OpenSearchResourceStatusType_ERROR OpenSearchResourceStatusType = "ERROR" + OpenSearchResourceStatusType_ACTIVE OpenSearchResourceStatusType = "ACTIVE" + OpenSearchResourceStatusType_ERROR OpenSearchResourceStatusType = "ERROR" OpenSearchResourceStatusType_NOT_FOUND OpenSearchResourceStatusType = "NOT_FOUND" ) @@ -143,40 +143,40 @@ const ( type OutputFormat string const ( - OutputFormat_json OutputFormat = "json" + OutputFormat_json OutputFormat = "json" OutputFormat_parquet OutputFormat = "parquet" - OutputFormat_plain OutputFormat = "plain" - OutputFormat_raw OutputFormat = "raw" - OutputFormat_w3c OutputFormat = "w3c" + OutputFormat_plain OutputFormat = "plain" + OutputFormat_raw OutputFormat = "raw" + OutputFormat_w3c OutputFormat = "w3c" ) type PolicyType string const ( - PolicyType_DATA_PROTECTION_POLICY PolicyType = "DATA_PROTECTION_POLICY" - PolicyType_FIELD_INDEX_POLICY PolicyType = "FIELD_INDEX_POLICY" + PolicyType_DATA_PROTECTION_POLICY PolicyType = "DATA_PROTECTION_POLICY" + PolicyType_FIELD_INDEX_POLICY PolicyType = "FIELD_INDEX_POLICY" PolicyType_SUBSCRIPTION_FILTER_POLICY PolicyType = "SUBSCRIPTION_FILTER_POLICY" - PolicyType_TRANSFORMER_POLICY PolicyType = "TRANSFORMER_POLICY" + PolicyType_TRANSFORMER_POLICY PolicyType = "TRANSFORMER_POLICY" ) type QueryLanguage string const ( QueryLanguage_CWLI QueryLanguage = "CWLI" - QueryLanguage_PPL QueryLanguage = "PPL" - QueryLanguage_SQL QueryLanguage = "SQL" + QueryLanguage_PPL QueryLanguage = "PPL" + QueryLanguage_SQL QueryLanguage = "SQL" ) type QueryStatus string const ( QueryStatus_Cancelled QueryStatus = "Cancelled" - QueryStatus_Complete QueryStatus = "Complete" - QueryStatus_Failed QueryStatus = "Failed" - QueryStatus_Running QueryStatus = "Running" + QueryStatus_Complete QueryStatus = "Complete" + QueryStatus_Failed QueryStatus = "Failed" + QueryStatus_Running QueryStatus = "Running" QueryStatus_Scheduled QueryStatus = "Scheduled" - QueryStatus_Timeout QueryStatus = "Timeout" - QueryStatus_Unknown QueryStatus = "Unknown" + QueryStatus_Timeout QueryStatus = "Timeout" + QueryStatus_Unknown QueryStatus = "Unknown" ) type Scope string @@ -188,47 +188,47 @@ const ( type StandardUnit string const ( - StandardUnit_Bits StandardUnit = "Bits" - StandardUnit_Bits_Second StandardUnit = "Bits/Second" - StandardUnit_Bytes StandardUnit = "Bytes" - StandardUnit_Bytes_Second StandardUnit = "Bytes/Second" - StandardUnit_Count StandardUnit = "Count" - StandardUnit_Count_Second StandardUnit = "Count/Second" - StandardUnit_Gigabits StandardUnit = "Gigabits" - StandardUnit_Gigabits_Second StandardUnit = "Gigabits/Second" - StandardUnit_Gigabytes StandardUnit = "Gigabytes" + StandardUnit_Bits StandardUnit = "Bits" + StandardUnit_Bits_Second StandardUnit = "Bits/Second" + StandardUnit_Bytes StandardUnit = "Bytes" + StandardUnit_Bytes_Second StandardUnit = "Bytes/Second" + StandardUnit_Count StandardUnit = "Count" + StandardUnit_Count_Second StandardUnit = "Count/Second" + StandardUnit_Gigabits StandardUnit = "Gigabits" + StandardUnit_Gigabits_Second StandardUnit = "Gigabits/Second" + StandardUnit_Gigabytes StandardUnit = "Gigabytes" StandardUnit_Gigabytes_Second StandardUnit = "Gigabytes/Second" - StandardUnit_Kilobits StandardUnit = "Kilobits" - StandardUnit_Kilobits_Second StandardUnit = "Kilobits/Second" - StandardUnit_Kilobytes StandardUnit = "Kilobytes" + StandardUnit_Kilobits StandardUnit = "Kilobits" + StandardUnit_Kilobits_Second StandardUnit = "Kilobits/Second" + StandardUnit_Kilobytes StandardUnit = "Kilobytes" StandardUnit_Kilobytes_Second StandardUnit = "Kilobytes/Second" - StandardUnit_Megabits StandardUnit = "Megabits" - StandardUnit_Megabits_Second StandardUnit = "Megabits/Second" - StandardUnit_Megabytes StandardUnit = "Megabytes" + StandardUnit_Megabits StandardUnit = "Megabits" + StandardUnit_Megabits_Second StandardUnit = "Megabits/Second" + StandardUnit_Megabytes StandardUnit = "Megabytes" StandardUnit_Megabytes_Second StandardUnit = "Megabytes/Second" - StandardUnit_Microseconds StandardUnit = "Microseconds" - StandardUnit_Milliseconds StandardUnit = "Milliseconds" - StandardUnit_None StandardUnit = "None" - StandardUnit_Percent StandardUnit = "Percent" - StandardUnit_Seconds StandardUnit = "Seconds" - StandardUnit_Terabits StandardUnit = "Terabits" - StandardUnit_Terabits_Second StandardUnit = "Terabits/Second" - StandardUnit_Terabytes StandardUnit = "Terabytes" + StandardUnit_Microseconds StandardUnit = "Microseconds" + StandardUnit_Milliseconds StandardUnit = "Milliseconds" + StandardUnit_None StandardUnit = "None" + StandardUnit_Percent StandardUnit = "Percent" + StandardUnit_Seconds StandardUnit = "Seconds" + StandardUnit_Terabits StandardUnit = "Terabits" + StandardUnit_Terabits_Second StandardUnit = "Terabits/Second" + StandardUnit_Terabytes StandardUnit = "Terabytes" StandardUnit_Terabytes_Second StandardUnit = "Terabytes/Second" ) type State string const ( - State_Active State = "Active" - State_Baseline State = "Baseline" + State_Active State = "Active" + State_Baseline State = "Baseline" State_Suppressed State = "Suppressed" ) type SuppressionState string const ( - SuppressionState_SUPPRESSED SuppressionState = "SUPPRESSED" + SuppressionState_SUPPRESSED SuppressionState = "SUPPRESSED" SuppressionState_UNSUPPRESSED SuppressionState = "UNSUPPRESSED" ) @@ -236,13 +236,13 @@ type SuppressionType string const ( SuppressionType_INFINITE SuppressionType = "INFINITE" - SuppressionType_LIMITED SuppressionType = "LIMITED" + SuppressionType_LIMITED SuppressionType = "LIMITED" ) type SuppressionUnit string const ( - SuppressionUnit_HOURS SuppressionUnit = "HOURS" + SuppressionUnit_HOURS SuppressionUnit = "HOURS" SuppressionUnit_MINUTES SuppressionUnit = "MINUTES" SuppressionUnit_SECONDS SuppressionUnit = "SECONDS" ) @@ -251,7 +251,7 @@ type Type string const ( Type_boolean Type = "boolean" - Type_double Type = "double" + Type_double Type = "double" Type_integer Type = "integer" - Type_string Type = "string" -) + Type_string Type = "string" +) \ No newline at end of file diff --git a/apis/v1alpha1/generator.yaml b/apis/v1alpha1/generator.yaml index 9461082..aa11b78 100644 --- a/apis/v1alpha1/generator.yaml +++ b/apis/v1alpha1/generator.yaml @@ -13,6 +13,7 @@ ignore: - PutSubscriptionFilterInput.LogGroupName - CreateLogGroupInput.LogGroupClass - PutSubscriptionFilterInput.ApplyOnTransformedLogs + - PutMetricFilterInput.LogGroupName resources: LogGroup: exceptions: @@ -30,6 +31,9 @@ resources: SubscriptionFilters: custom_field: list_of: PutSubscriptionFilterInput + MetricFilters: + custom_field: + list_of: PutMetricFilterInput RetentionDays: from: operation: PutRetentionPolicy diff --git a/apis/v1alpha1/groupversion_info.go b/apis/v1alpha1/groupversion_info.go index 14fb2bf..4799a40 100644 --- a/apis/v1alpha1/groupversion_info.go +++ b/apis/v1alpha1/groupversion_info.go @@ -16,17 +16,17 @@ package v1alpha1 import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" ) var ( - // GroupVersion is the API Group Version used to register the objects - GroupVersion = schema.GroupVersion{Group: "cloudwatchlogs.services.k8s.aws", Version: "v1alpha1"} + // GroupVersion is the API Group Version used to register the objects + GroupVersion = schema.GroupVersion{Group: "cloudwatchlogs.services.k8s.aws", Version: "v1alpha1"} - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} - // AddToScheme adds the types in this group-version to the given scheme. - AddToScheme = SchemeBuilder.AddToScheme + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme ) diff --git a/apis/v1alpha1/log_group.go b/apis/v1alpha1/log_group.go index 9bd6ee6..5aa2118 100644 --- a/apis/v1alpha1/log_group.go +++ b/apis/v1alpha1/log_group.go @@ -25,25 +25,26 @@ import ( // Represents a log group. type LogGroupSpec struct { - // The Amazon Resource Name (ARN) of the KMS key to use when encrypting log - // data. For more information, see Amazon Resource Names (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-kms). - KMSKeyID *string `json:"kmsKeyID,omitempty"` - KMSKeyRef *ackv1alpha1.AWSResourceReferenceWrapper `json:"kmsKeyRef,omitempty"` - // +kubebuilder:validation:Required - Name *string `json:"name"` - RetentionDays *int64 `json:"retentionDays,omitempty"` - SubscriptionFilters []*PutSubscriptionFilterInput `json:"subscriptionFilters,omitempty"` - // The key-value pairs to use for the tags. - // - // You can grant users access to certain log groups while preventing them from - // accessing other log groups. To do so, tag your groups and use IAM policies - // that refer to those tags. To assign tags when you create a log group, you - // must have either the logs:TagResource or logs:TagLogGroup permission. For - // more information about tagging, see Tagging Amazon Web Services resources - // (https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html). For more - // information about using tags to control access, see Controlling access to - // Amazon Web Services resources using tags (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_tags.html). - Tags map[string]*string `json:"tags,omitempty"` +// The Amazon Resource Name (ARN) of the KMS key to use when encrypting log +// data. For more information, see Amazon Resource Names (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-kms). +KMSKeyID *string `json:"kmsKeyID,omitempty"` +KMSKeyRef *ackv1alpha1.AWSResourceReferenceWrapper `json:"kmsKeyRef,omitempty"` +MetricFilters []*PutMetricFilterInput `json:"metricFilters,omitempty"` +// +kubebuilder:validation:Required +Name *string `json:"name"` +RetentionDays *int64 `json:"retentionDays,omitempty"` +SubscriptionFilters []*PutSubscriptionFilterInput `json:"subscriptionFilters,omitempty"` +// The key-value pairs to use for the tags. +// +// You can grant users access to certain log groups while preventing them from +// accessing other log groups. To do so, tag your groups and use IAM policies +// that refer to those tags. To assign tags when you create a log group, you +// must have either the logs:TagResource or logs:TagLogGroup permission. For +// more information about tagging, see Tagging Amazon Web Services resources +// (https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html). For more +// information about using tags to control access, see Controlling access to +// Amazon Web Services resources using tags (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_tags.html). +Tags map[string]*string `json:"tags,omitempty"` } // LogGroupStatus defines the observed state of LogGroup @@ -60,11 +61,11 @@ type LogGroupStatus struct { // +kubebuilder:validation:Optional Conditions []*ackv1alpha1.Condition `json:"conditions"` // The creation time of the log group, expressed as the number of milliseconds - // after Jan 1, 1970 00:00:00 UTC. +// after Jan 1, 1970 00:00:00 UTC. // +kubebuilder:validation:Optional CreationTime *int64 `json:"creationTime,omitempty"` // Displays whether this log group has a protection policy, or whether it had - // one in the past. For more information, see PutDataProtectionPolicy (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDataProtectionPolicy.html). +// one in the past. For more information, see PutDataProtectionPolicy (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDataProtectionPolicy.html). // +kubebuilder:validation:Optional DataProtectionStatus *string `json:"dataProtectionStatus,omitempty"` // The number of metric filters. @@ -83,8 +84,8 @@ type LogGroupStatus struct { type LogGroup struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec LogGroupSpec `json:"spec,omitempty"` - Status LogGroupStatus `json:"status,omitempty"` + Spec LogGroupSpec `json:"spec,omitempty"` + Status LogGroupStatus `json:"status,omitempty"` } // LogGroupList contains a list of LogGroup @@ -92,9 +93,9 @@ type LogGroup struct { type LogGroupList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` - Items []LogGroup `json:"items"` + Items []LogGroup `json:"items"` } func init() { SchemeBuilder.Register(&LogGroup{}, &LogGroupList{}) -} +} \ No newline at end of file diff --git a/apis/v1alpha1/types.go b/apis/v1alpha1/types.go index 6f2cd00..99f2c27 100644 --- a/apis/v1alpha1/types.go +++ b/apis/v1alpha1/types.go @@ -28,226 +28,266 @@ var ( _ = ackv1alpha1.AWSAccountID("") ) + // A structure that contains information about one CloudWatch Logs account policy. type AccountPolicy struct { - AccountID *string `json:"accountID,omitempty"` - LastUpdatedTime *int64 `json:"lastUpdatedTime,omitempty"` + AccountID *string `json:"accountID,omitempty"` + LastUpdatedTime *int64 `json:"lastUpdatedTime,omitempty"` } + // Contains information about one anomaly detector in the account. type AnomalyDetector struct { // A symbolic description of how CloudWatch Logs should interpret the data in - // each log event. For example, a log event can contain timestamps, IP addresses, - // strings, and so on. You use the filter pattern to specify what to look for - // in the log event message. +// each log event. For example, a log event can contain timestamps, IP addresses, +// strings, and so on. You use the filter pattern to specify what to look for +// in the log event message. FilterPattern *string `json:"filterPattern,omitempty"` - KMSKeyID *string `json:"kmsKeyID,omitempty"` + KMSKeyID *string `json:"kmsKeyID,omitempty"` } + // This structure contains information about one delivery in your account. -// +// // A delivery is a connection between a logical delivery source and a logical // delivery destination. -// +// // For more information, see CreateDelivery (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateDelivery.html). -// +// // To update an existing delivery configuration, use UpdateDeliveryConfiguration // (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_UpdateDeliveryConfiguration.html). type Delivery struct { - ARN *string `json:"arn,omitempty"` - DeliveryDestinationARN *string `json:"deliveryDestinationARN,omitempty"` - Tags map[string]*string `json:"tags,omitempty"` + ARN *string `json:"arn,omitempty"` + DeliveryDestinationARN *string `json:"deliveryDestinationARN,omitempty"` + Tags map[string]*string `json:"tags,omitempty"` } + // This structure contains information about one delivery destination in your // account. A delivery destination is an Amazon Web Services resource that represents // an Amazon Web Services service that logs can be sent to. CloudWatch Logs, // Amazon S3, are supported as Firehose delivery destinations. -// +// // To configure logs delivery between a supported Amazon Web Services service // and a destination, you must do the following: -// -// - Create a delivery source, which is a logical object that represents -// the resource that is actually sending the logs. For more information, -// see PutDeliverySource (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDeliverySource.html). -// -// - Create a delivery destination, which is a logical object that represents -// the actual delivery destination. -// -// - If you are delivering logs cross-account, you must use PutDeliveryDestinationPolicy -// (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDeliveryDestinationPolicy.html) -// in the destination account to assign an IAM policy to the destination. -// This policy allows delivery to that destination. -// -// - Create a delivery by pairing exactly one delivery source and one delivery -// destination. For more information, see CreateDelivery (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateDelivery.html). -// +// +// * Create a delivery source, which is a logical object that represents +// the resource that is actually sending the logs. For more information, +// see PutDeliverySource (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDeliverySource.html). +// +// * Create a delivery destination, which is a logical object that represents +// the actual delivery destination. +// +// * If you are delivering logs cross-account, you must use PutDeliveryDestinationPolicy +// (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDeliveryDestinationPolicy.html) +// in the destination account to assign an IAM policy to the destination. +// This policy allows delivery to that destination. +// +// * Create a delivery by pairing exactly one delivery source and one delivery +// destination. For more information, see CreateDelivery (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateDelivery.html). +// // You can configure a single delivery source to send logs to multiple destinations // by creating multiple deliveries. You can also create multiple deliveries // to configure multiple delivery sources to send logs to the same delivery // destination. type DeliveryDestination struct { - ARN *string `json:"arn,omitempty"` + ARN *string `json:"arn,omitempty"` Tags map[string]*string `json:"tags,omitempty"` } + // A structure that contains information about one logs delivery destination. type DeliveryDestinationConfiguration struct { DestinationResourceARN *string `json:"destinationResourceARN,omitempty"` } + // This structure contains information about one delivery source in your account. // A delivery source is an Amazon Web Services resource that sends logs to an // Amazon Web Services destination. The destination can be CloudWatch Logs, // Amazon S3, or Firehose. -// +// // Only some Amazon Web Services services support being configured as a delivery // source. These services are listed as Supported [V2 Permissions] in the table // at Enabling logging from Amazon Web Services services. (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AWS-logs-and-resource-policy.html) -// +// // To configure logs delivery between a supported Amazon Web Services service // and a destination, you must do the following: -// -// - Create a delivery source, which is a logical object that represents -// the resource that is actually sending the logs. For more information, -// see PutDeliverySource (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDeliverySource.html). -// -// - Create a delivery destination, which is a logical object that represents -// the actual delivery destination. For more information, see PutDeliveryDestination -// (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDeliveryDestination.html). -// -// - If you are delivering logs cross-account, you must use PutDeliveryDestinationPolicy -// (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDeliveryDestinationPolicy.html) -// in the destination account to assign an IAM policy to the destination. -// This policy allows delivery to that destination. -// -// - Create a delivery by pairing exactly one delivery source and one delivery -// destination. For more information, see CreateDelivery (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateDelivery.html). -// +// +// * Create a delivery source, which is a logical object that represents +// the resource that is actually sending the logs. For more information, +// see PutDeliverySource (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDeliverySource.html). +// +// * Create a delivery destination, which is a logical object that represents +// the actual delivery destination. For more information, see PutDeliveryDestination +// (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDeliveryDestination.html). +// +// * If you are delivering logs cross-account, you must use PutDeliveryDestinationPolicy +// (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDeliveryDestinationPolicy.html) +// in the destination account to assign an IAM policy to the destination. +// This policy allows delivery to that destination. +// +// * Create a delivery by pairing exactly one delivery source and one delivery +// destination. For more information, see CreateDelivery (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateDelivery.html). +// // You can configure a single delivery source to send logs to multiple destinations // by creating multiple deliveries. You can also create multiple deliveries // to configure multiple delivery sources to send logs to the same delivery // destination. type DeliverySource struct { - ARN *string `json:"arn,omitempty"` + ARN *string `json:"arn,omitempty"` Tags map[string]*string `json:"tags,omitempty"` } + // Represents a cross-account destination that receives subscription log events. type Destination struct { - ARN *string `json:"arn,omitempty"` - CreationTime *int64 `json:"creationTime,omitempty"` - RoleARN *string `json:"roleARN,omitempty"` + ARN *string `json:"arn,omitempty"` + CreationTime *int64 `json:"creationTime,omitempty"` + RoleARN *string `json:"roleARN,omitempty"` } + // Represents an export task. type ExportTask struct { - From *int64 `json:"from,omitempty"` + From *int64 `json:"from,omitempty"` LogGroupName *string `json:"logGroupName,omitempty"` - To *int64 `json:"to,omitempty"` + To *int64 `json:"to,omitempty"` } + // Represents the status of an export task. type ExportTaskExecutionInfo struct { CompletionTime *int64 `json:"completionTime,omitempty"` - CreationTime *int64 `json:"creationTime,omitempty"` + CreationTime *int64 `json:"creationTime,omitempty"` } + // This structure describes one log event field that is used as an index in // at least one index policy in this account. type FieldIndex struct { FirstEventTime *int64 `json:"firstEventTime,omitempty"` - LastEventTime *int64 `json:"lastEventTime,omitempty"` - LastScanTime *int64 `json:"lastScanTime,omitempty"` + LastEventTime *int64 `json:"lastEventTime,omitempty"` + LastScanTime *int64 `json:"lastScanTime,omitempty"` } + // Represents a matched event. type FilteredLogEvent struct { IngestionTime *int64 `json:"ingestionTime,omitempty"` - Timestamp *int64 `json:"timestamp,omitempty"` + Timestamp *int64 `json:"timestamp,omitempty"` } + // This structure contains information about one field index policy in this // account. type IndexPolicy struct { LastUpdateTime *int64 `json:"lastUpdateTime,omitempty"` } + // Represents a log event, which is a record of activity that was recorded by // the application or resource being monitored. type InputLogEvent struct { Timestamp *int64 `json:"timestamp,omitempty"` } + // This object contains the information for one log event returned in a Live // Tail stream. type LiveTailSessionLogEvent struct { IngestionTime *int64 `json:"ingestionTime,omitempty"` - Timestamp *int64 `json:"timestamp,omitempty"` + Timestamp *int64 `json:"timestamp,omitempty"` } + // This object contains information about this Live Tail session, including // the log groups included and the log stream filters, if any. type LiveTailSessionStart struct { // A symbolic description of how CloudWatch Logs should interpret the data in - // each log event. For example, a log event can contain timestamps, IP addresses, - // strings, and so on. You use the filter pattern to specify what to look for - // in the log event message. +// each log event. For example, a log event can contain timestamps, IP addresses, +// strings, and so on. You use the filter pattern to specify what to look for +// in the log event message. LogEventFilterPattern *string `json:"logEventFilterPattern,omitempty"` } + // This structure contains the information for one sample log event that is // associated with an anomaly found by a log anomaly detector. type LogEvent struct { Timestamp *int64 `json:"timestamp,omitempty"` } + // Represents a log group. type LogGroup_SDK struct { - ARN *string `json:"arn,omitempty"` - CreationTime *int64 `json:"creationTime,omitempty"` - DataProtectionStatus *string `json:"dataProtectionStatus,omitempty"` - InheritedProperties []*string `json:"inheritedProperties,omitempty"` - KMSKeyID *string `json:"kmsKeyID,omitempty"` - LogGroupARN *string `json:"logGroupARN,omitempty"` - LogGroupClass *string `json:"logGroupClass,omitempty"` - LogGroupName *string `json:"logGroupName,omitempty"` - MetricFilterCount *int64 `json:"metricFilterCount,omitempty"` + ARN *string `json:"arn,omitempty"` + CreationTime *int64 `json:"creationTime,omitempty"` + DataProtectionStatus *string `json:"dataProtectionStatus,omitempty"` + InheritedProperties []*string `json:"inheritedProperties,omitempty"` + KMSKeyID *string `json:"kmsKeyID,omitempty"` + LogGroupARN *string `json:"logGroupARN,omitempty"` + LogGroupClass *string `json:"logGroupClass,omitempty"` + LogGroupName *string `json:"logGroupName,omitempty"` + MetricFilterCount *int64 `json:"metricFilterCount,omitempty"` // The number of days to retain the log events in the specified log group. Possible - // values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, - // 1096, 1827, 2192, 2557, 2922, 3288, and 3653. - // - // To set a log group so that its log events do not expire, use DeleteRetentionPolicy - // (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DeleteRetentionPolicy.html). +// values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, +// 1096, 1827, 2192, 2557, 2922, 3288, and 3653. +// +// To set a log group so that its log events do not expire, use DeleteRetentionPolicy +// (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DeleteRetentionPolicy.html). RetentionInDays *int64 `json:"retentionInDays,omitempty"` - StoredBytes *int64 `json:"storedBytes,omitempty"` + StoredBytes *int64 `json:"storedBytes,omitempty"` } + // Represents a log stream, which is a sequence of log events from a single // emitter of logs. type LogStream struct { - ARN *string `json:"arn,omitempty"` - CreationTime *int64 `json:"creationTime,omitempty"` - FirstEventTimestamp *int64 `json:"firstEventTimestamp,omitempty"` - LastEventTimestamp *int64 `json:"lastEventTimestamp,omitempty"` - LastIngestionTime *int64 `json:"lastIngestionTime,omitempty"` - StoredBytes *int64 `json:"storedBytes,omitempty"` + ARN *string `json:"arn,omitempty"` + CreationTime *int64 `json:"creationTime,omitempty"` + FirstEventTimestamp *int64 `json:"firstEventTimestamp,omitempty"` + LastEventTimestamp *int64 `json:"lastEventTimestamp,omitempty"` + LastIngestionTime *int64 `json:"lastIngestionTime,omitempty"` + StoredBytes *int64 `json:"storedBytes,omitempty"` } + // Metric filters express how CloudWatch Logs would extract metric observations // from ingested log events and transform them into metric data in a CloudWatch // metric. type MetricFilter struct { - CreationTime *int64 `json:"creationTime,omitempty"` - FilterName *string `json:"filterName,omitempty"` + ApplyOnTransformedLogs *bool `json:"applyOnTransformedLogs,omitempty"` + CreationTime *int64 `json:"creationTime,omitempty"` + FilterName *string `json:"filterName,omitempty"` // A symbolic description of how CloudWatch Logs should interpret the data in - // each log event. For example, a log event can contain timestamps, IP addresses, - // strings, and so on. You use the filter pattern to specify what to look for - // in the log event message. +// each log event. For example, a log event can contain timestamps, IP addresses, +// strings, and so on. You use the filter pattern to specify what to look for +// in the log event message. FilterPattern *string `json:"filterPattern,omitempty"` - LogGroupName *string `json:"logGroupName,omitempty"` + LogGroupName *string `json:"logGroupName,omitempty"` + MetricTransformations []*MetricTransformation `json:"metricTransformations,omitempty"` +} + + +// Indicates how to transform ingested log events to metric data in a CloudWatch +// metric. +type MetricTransformation struct { + DefaultValue *float64 `json:"defaultValue,omitempty"` + Dimensions map[string]*string `json:"dimensions,omitempty"` + // The name of the CloudWatch metric to which the monitored log information +// should be published. For example, you might publish to a metric named ErrorCount. + MetricName *string `json:"metricName,omitempty"` + MetricNamespace *string `json:"metricNamespace,omitempty"` + // The value to publish to the CloudWatch metric. For example, if you're counting +// the occurrences of a term like Error, the value is 1 for each occurrence. +// If you're counting the bytes transferred, the value is the value in the log +// event. + MetricValue *string `json:"metricValue,omitempty"` + Unit *string `json:"unit,omitempty"` } + // This structure contains information about the OpenSearch Service application // used for this integration. An OpenSearch Service application is the web application // created by the integration with CloudWatch Logs. It hosts the vended logs @@ -256,6 +296,7 @@ type OpenSearchApplication struct { ApplicationARN *string `json:"applicationARN,omitempty"` } + // This structure contains information about the OpenSearch Service collection // used for this integration. An OpenSearch Service collection is a logical // grouping of one or more indexes that represent an analytics workload. For @@ -265,66 +306,86 @@ type OpenSearchCollection struct { CollectionARN *string `json:"collectionARN,omitempty"` } + // This structure contains configuration details about an integration between // CloudWatch Logs and OpenSearch Service. type OpenSearchResourceConfig struct { - ApplicationARN *string `json:"applicationARN,omitempty"` + ApplicationARN *string `json:"applicationARN,omitempty"` DataSourceRoleARN *string `json:"dataSourceRoleARN,omitempty"` - KMSKeyARN *string `json:"kmsKeyARN,omitempty"` + KMSKeyARN *string `json:"kmsKeyARN,omitempty"` } + // Represents a log event. type OutputLogEvent struct { IngestionTime *int64 `json:"ingestionTime,omitempty"` - Timestamp *int64 `json:"timestamp,omitempty"` + Timestamp *int64 `json:"timestamp,omitempty"` +} + + +type PutMetricFilterInput struct { + ApplyOnTransformedLogs *bool `json:"applyOnTransformedLogs,omitempty"` + FilterName *string `json:"filterName,omitempty"` + // A symbolic description of how CloudWatch Logs should interpret the data in +// each log event. For example, a log event can contain timestamps, IP addresses, +// strings, and so on. You use the filter pattern to specify what to look for +// in the log event message. + FilterPattern *string `json:"filterPattern,omitempty"` + MetricTransformations []*MetricTransformation `json:"metricTransformations,omitempty"` } + type PutSubscriptionFilterInput struct { DestinationARN *string `json:"destinationARN,omitempty"` // The method used to distribute log data to the destination, which can be either - // random or grouped by log stream. +// random or grouped by log stream. Distribution *string `json:"distribution,omitempty"` - FilterName *string `json:"filterName,omitempty"` + FilterName *string `json:"filterName,omitempty"` // A symbolic description of how CloudWatch Logs should interpret the data in - // each log event. For example, a log event can contain timestamps, IP addresses, - // strings, and so on. You use the filter pattern to specify what to look for - // in the log event message. +// each log event. For example, a log event can contain timestamps, IP addresses, +// strings, and so on. You use the filter pattern to specify what to look for +// in the log event message. FilterPattern *string `json:"filterPattern,omitempty"` - RoleARN *string `json:"roleARN,omitempty"` + RoleARN *string `json:"roleARN,omitempty"` } + // This structure contains details about a saved CloudWatch Logs Insights query // definition. type QueryDefinition struct { LastModified *int64 `json:"lastModified,omitempty"` } + // Information about one CloudWatch Logs Insights query that matches the request // in a DescribeQueries operation. type QueryInfo struct { - CreateTime *int64 `json:"createTime,omitempty"` + CreateTime *int64 `json:"createTime,omitempty"` LogGroupName *string `json:"logGroupName,omitempty"` } + // A policy enabling one or more entities to put logs to a log group in this // account. type ResourcePolicy struct { LastUpdatedTime *int64 `json:"lastUpdatedTime,omitempty"` } + // Represents a subscription filter. type SubscriptionFilter struct { - CreationTime *int64 `json:"creationTime,omitempty"` + ApplyOnTransformedLogs *bool `json:"applyOnTransformedLogs,omitempty"` + CreationTime *int64 `json:"creationTime,omitempty"` DestinationARN *string `json:"destinationARN,omitempty"` // The method used to distribute log data to the destination, which can be either - // random or grouped by log stream. +// random or grouped by log stream. Distribution *string `json:"distribution,omitempty"` - FilterName *string `json:"filterName,omitempty"` + FilterName *string `json:"filterName,omitempty"` // A symbolic description of how CloudWatch Logs should interpret the data in - // each log event. For example, a log event can contain timestamps, IP addresses, - // strings, and so on. You use the filter pattern to specify what to look for - // in the log event message. +// each log event. For example, a log event can contain timestamps, IP addresses, +// strings, and so on. You use the filter pattern to specify what to look for +// in the log event message. FilterPattern *string `json:"filterPattern,omitempty"` - LogGroupName *string `json:"logGroupName,omitempty"` - RoleARN *string `json:"roleARN,omitempty"` -} + LogGroupName *string `json:"logGroupName,omitempty"` + RoleARN *string `json:"roleARN,omitempty"` +} \ No newline at end of file diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go index a3e0dff..301a825 100644 --- a/apis/v1alpha1/zz_generated.deepcopy.go +++ b/apis/v1alpha1/zz_generated.deepcopy.go @@ -524,6 +524,17 @@ func (in *LogGroupSpec) DeepCopyInto(out *LogGroupSpec) { *out = new(corev1alpha1.AWSResourceReferenceWrapper) (*in).DeepCopyInto(*out) } + if in.MetricFilters != nil { + in, out := &in.MetricFilters, &out.MetricFilters + *out = make([]*PutMetricFilterInput, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(PutMetricFilterInput) + (*in).DeepCopyInto(*out) + } + } + } if in.Name != nil { in, out := &in.Name, &out.Name *out = new(string) @@ -753,6 +764,11 @@ func (in *LogStream) DeepCopy() *LogStream { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MetricFilter) DeepCopyInto(out *MetricFilter) { *out = *in + if in.ApplyOnTransformedLogs != nil { + in, out := &in.ApplyOnTransformedLogs, &out.ApplyOnTransformedLogs + *out = new(bool) + **out = **in + } if in.CreationTime != nil { in, out := &in.CreationTime, &out.CreationTime *out = new(int64) @@ -773,6 +789,17 @@ func (in *MetricFilter) DeepCopyInto(out *MetricFilter) { *out = new(string) **out = **in } + if in.MetricTransformations != nil { + in, out := &in.MetricTransformations, &out.MetricTransformations + *out = make([]*MetricTransformation, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(MetricTransformation) + (*in).DeepCopyInto(*out) + } + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricFilter. @@ -785,6 +812,62 @@ func (in *MetricFilter) DeepCopy() *MetricFilter { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MetricTransformation) DeepCopyInto(out *MetricTransformation) { + *out = *in + if in.DefaultValue != nil { + in, out := &in.DefaultValue, &out.DefaultValue + *out = new(float64) + **out = **in + } + if in.Dimensions != nil { + in, out := &in.Dimensions, &out.Dimensions + *out = make(map[string]*string, len(*in)) + for key, val := range *in { + var outVal *string + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = new(string) + **out = **in + } + (*out)[key] = outVal + } + } + if in.MetricName != nil { + in, out := &in.MetricName, &out.MetricName + *out = new(string) + **out = **in + } + if in.MetricNamespace != nil { + in, out := &in.MetricNamespace, &out.MetricNamespace + *out = new(string) + **out = **in + } + if in.MetricValue != nil { + in, out := &in.MetricValue, &out.MetricValue + *out = new(string) + **out = **in + } + if in.Unit != nil { + in, out := &in.Unit, &out.Unit + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTransformation. +func (in *MetricTransformation) DeepCopy() *MetricTransformation { + if in == nil { + return nil + } + out := new(MetricTransformation) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpenSearchApplication) DeepCopyInto(out *OpenSearchApplication) { *out = *in @@ -880,6 +963,47 @@ func (in *OutputLogEvent) DeepCopy() *OutputLogEvent { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PutMetricFilterInput) DeepCopyInto(out *PutMetricFilterInput) { + *out = *in + if in.ApplyOnTransformedLogs != nil { + in, out := &in.ApplyOnTransformedLogs, &out.ApplyOnTransformedLogs + *out = new(bool) + **out = **in + } + if in.FilterName != nil { + in, out := &in.FilterName, &out.FilterName + *out = new(string) + **out = **in + } + if in.FilterPattern != nil { + in, out := &in.FilterPattern, &out.FilterPattern + *out = new(string) + **out = **in + } + if in.MetricTransformations != nil { + in, out := &in.MetricTransformations, &out.MetricTransformations + *out = make([]*MetricTransformation, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(MetricTransformation) + (*in).DeepCopyInto(*out) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PutMetricFilterInput. +func (in *PutMetricFilterInput) DeepCopy() *PutMetricFilterInput { + if in == nil { + return nil + } + out := new(PutMetricFilterInput) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PutSubscriptionFilterInput) DeepCopyInto(out *PutSubscriptionFilterInput) { *out = *in @@ -988,6 +1112,11 @@ func (in *ResourcePolicy) DeepCopy() *ResourcePolicy { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SubscriptionFilter) DeepCopyInto(out *SubscriptionFilter) { *out = *in + if in.ApplyOnTransformedLogs != nil { + in, out := &in.ApplyOnTransformedLogs, &out.ApplyOnTransformedLogs + *out = new(bool) + **out = **in + } if in.CreationTime != nil { in, out := &in.CreationTime, &out.CreationTime *out = new(int64) diff --git a/cmd/controller/main.go b/cmd/controller/main.go index 522f30a..d9bb2e0 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -16,10 +16,9 @@ package main import ( - "context" "os" + "context" - kmsapitypes "github.com/aws-controllers-k8s/kms-controller/apis/v1alpha1" ackv1alpha1 "github.com/aws-controllers-k8s/runtime/apis/core/v1alpha1" ackcfg "github.com/aws-controllers-k8s/runtime/pkg/config" ackrt "github.com/aws-controllers-k8s/runtime/pkg/runtime" @@ -27,8 +26,8 @@ import ( ackrtutil "github.com/aws-controllers-k8s/runtime/pkg/util" ackrtwebhook "github.com/aws-controllers-k8s/runtime/pkg/webhook" flag "github.com/spf13/pflag" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" ctrlrt "sigs.k8s.io/controller-runtime" ctrlrtcache "sigs.k8s.io/controller-runtime/pkg/cache" @@ -36,25 +35,27 @@ import ( ctrlrtmetrics "sigs.k8s.io/controller-runtime/pkg/metrics" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" ctrlrtwebhook "sigs.k8s.io/controller-runtime/pkg/webhook" + kmsapitypes "github.com/aws-controllers-k8s/kms-controller/apis/v1alpha1" - svctypes "github.com/aws-controllers-k8s/cloudwatchlogs-controller/apis/v1alpha1" svcresource "github.com/aws-controllers-k8s/cloudwatchlogs-controller/pkg/resource" + svctypes "github.com/aws-controllers-k8s/cloudwatchlogs-controller/apis/v1alpha1" + _ "github.com/aws-controllers-k8s/cloudwatchlogs-controller/pkg/resource/log_group" - + "github.com/aws-controllers-k8s/cloudwatchlogs-controller/pkg/version" ) var ( - awsServiceAPIGroup = "cloudwatchlogs.services.k8s.aws" - awsServiceAlias = "cloudwatchlogs" - scheme = runtime.NewScheme() - setupLog = ctrlrt.Log.WithName("setup") + awsServiceAPIGroup = "cloudwatchlogs.services.k8s.aws" + awsServiceAlias = "cloudwatchlogs" + scheme = runtime.NewScheme() + setupLog = ctrlrt.Log.WithName("setup") ) func init() { _ = clientgoscheme.AddToScheme(scheme) - + _ = svctypes.AddToScheme(scheme) _ = ackv1alpha1.AddToScheme(scheme) _ = kmsapitypes.AddToScheme(scheme) @@ -99,7 +100,8 @@ func main() { ) os.Exit(1) } - + + for _, namespace := range namespaces { watchNamespaces[namespace] = ctrlrtcache.Config{} } diff --git a/config/controller/kustomization.yaml b/config/controller/kustomization.yaml index 1d52f34..5333f3f 100644 --- a/config/controller/kustomization.yaml +++ b/config/controller/kustomization.yaml @@ -6,4 +6,4 @@ kind: Kustomization images: - name: controller newName: public.ecr.aws/aws-controllers-k8s/cloudwatchlogs-controller - newTag: 1.2.2 + newTag: 0.0.0-non-release-version diff --git a/config/crd/bases/cloudwatchlogs.services.k8s.aws_loggroups.yaml b/config/crd/bases/cloudwatchlogs.services.k8s.aws_loggroups.yaml index 9e4d02c..1f3f329 100644 --- a/config/crd/bases/cloudwatchlogs.services.k8s.aws_loggroups.yaml +++ b/config/crd/bases/cloudwatchlogs.services.k8s.aws_loggroups.yaml @@ -64,6 +64,52 @@ spec: type: string type: object type: object + metricFilters: + items: + properties: + applyOnTransformedLogs: + type: boolean + filterName: + type: string + filterPattern: + description: |- + A symbolic description of how CloudWatch Logs should interpret the data in + each log event. For example, a log event can contain timestamps, IP addresses, + strings, and so on. You use the filter pattern to specify what to look for + in the log event message. + type: string + metricTransformations: + items: + description: |- + Indicates how to transform ingested log events to metric data in a CloudWatch + metric. + properties: + defaultValue: + type: number + dimensions: + additionalProperties: + type: string + type: object + metricName: + description: |- + The name of the CloudWatch metric to which the monitored log information + should be published. For example, you might publish to a metric named ErrorCount. + type: string + metricNamespace: + type: string + metricValue: + description: |- + The value to publish to the CloudWatch metric. For example, if you're counting + the occurrences of a term like Error, the value is 1 for each occurrence. + If you're counting the bytes transferred, the value is the value in the log + event. + type: string + unit: + type: string + type: object + type: array + type: object + type: array name: type: string retentionDays: diff --git a/generator.yaml b/generator.yaml index 9461082..aa11b78 100644 --- a/generator.yaml +++ b/generator.yaml @@ -13,6 +13,7 @@ ignore: - PutSubscriptionFilterInput.LogGroupName - CreateLogGroupInput.LogGroupClass - PutSubscriptionFilterInput.ApplyOnTransformedLogs + - PutMetricFilterInput.LogGroupName resources: LogGroup: exceptions: @@ -30,6 +31,9 @@ resources: SubscriptionFilters: custom_field: list_of: PutSubscriptionFilterInput + MetricFilters: + custom_field: + list_of: PutMetricFilterInput RetentionDays: from: operation: PutRetentionPolicy diff --git a/helm/Chart.yaml b/helm/Chart.yaml index ead63ae..cf936b9 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 name: cloudwatchlogs-chart description: A Helm chart for the ACK service controller for Amazon CloudWatch Logs (CloudWatch Logs) -version: 1.2.2 -appVersion: 1.2.2 +version: 0.0.0-non-release-version +appVersion: 0.0.0-non-release-version home: https://github.com/aws-controllers-k8s/cloudwatchlogs-controller icon: https://raw.githubusercontent.com/aws/eks-charts/master/docs/logo/aws.png sources: diff --git a/helm/crds/cloudwatchlogs.services.k8s.aws_loggroups.yaml b/helm/crds/cloudwatchlogs.services.k8s.aws_loggroups.yaml index 9e4d02c..1f3f329 100644 --- a/helm/crds/cloudwatchlogs.services.k8s.aws_loggroups.yaml +++ b/helm/crds/cloudwatchlogs.services.k8s.aws_loggroups.yaml @@ -64,6 +64,52 @@ spec: type: string type: object type: object + metricFilters: + items: + properties: + applyOnTransformedLogs: + type: boolean + filterName: + type: string + filterPattern: + description: |- + A symbolic description of how CloudWatch Logs should interpret the data in + each log event. For example, a log event can contain timestamps, IP addresses, + strings, and so on. You use the filter pattern to specify what to look for + in the log event message. + type: string + metricTransformations: + items: + description: |- + Indicates how to transform ingested log events to metric data in a CloudWatch + metric. + properties: + defaultValue: + type: number + dimensions: + additionalProperties: + type: string + type: object + metricName: + description: |- + The name of the CloudWatch metric to which the monitored log information + should be published. For example, you might publish to a metric named ErrorCount. + type: string + metricNamespace: + type: string + metricValue: + description: |- + The value to publish to the CloudWatch metric. For example, if you're counting + the occurrences of a term like Error, the value is 1 for each occurrence. + If you're counting the bytes transferred, the value is the value in the log + event. + type: string + unit: + type: string + type: object + type: array + type: object + type: array name: type: string retentionDays: diff --git a/helm/templates/NOTES.txt b/helm/templates/NOTES.txt index 8fdbe44..beb9efd 100644 --- a/helm/templates/NOTES.txt +++ b/helm/templates/NOTES.txt @@ -1,5 +1,5 @@ {{ .Chart.Name }} has been installed. -This chart deploys "public.ecr.aws/aws-controllers-k8s/cloudwatchlogs-controller:1.2.2". +This chart deploys "public.ecr.aws/aws-controllers-k8s/cloudwatchlogs-controller:0.0.0-non-release-version". Check its status by running: kubectl --namespace {{ .Release.Namespace }} get pods -l "app.kubernetes.io/instance={{ .Release.Name }}" diff --git a/helm/values.yaml b/helm/values.yaml index 9626b1f..36df5a1 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -4,7 +4,7 @@ image: repository: public.ecr.aws/aws-controllers-k8s/cloudwatchlogs-controller - tag: 1.2.2 + tag: 0.0.0-non-release-version pullPolicy: IfNotPresent pullSecrets: [] diff --git a/pkg/resource/log_group/delta.go b/pkg/resource/log_group/delta.go index be0afc0..3001182 100644 --- a/pkg/resource/log_group/delta.go +++ b/pkg/resource/log_group/delta.go @@ -53,6 +53,13 @@ func newResourceDelta( if !equality.Semantic.Equalities.DeepEqual(a.ko.Spec.KMSKeyRef, b.ko.Spec.KMSKeyRef) { delta.Add("Spec.KMSKeyRef", a.ko.Spec.KMSKeyRef, b.ko.Spec.KMSKeyRef) } + if len(a.ko.Spec.MetricFilters) != len(b.ko.Spec.MetricFilters) { + delta.Add("Spec.MetricFilters", a.ko.Spec.MetricFilters, b.ko.Spec.MetricFilters) + } else if len(a.ko.Spec.MetricFilters) > 0 { + if !equality.Semantic.Equalities.DeepEqual(a.ko.Spec.MetricFilters, b.ko.Spec.MetricFilters) { + delta.Add("Spec.MetricFilters", a.ko.Spec.MetricFilters, b.ko.Spec.MetricFilters) + } + } if ackcompare.HasNilDifference(a.ko.Spec.Name, b.ko.Spec.Name) { delta.Add("Spec.Name", a.ko.Spec.Name, b.ko.Spec.Name) } else if a.ko.Spec.Name != nil && b.ko.Spec.Name != nil { diff --git a/pkg/resource/log_group/hook.go b/pkg/resource/log_group/hook.go index 20032a2..2b32f08 100644 --- a/pkg/resource/log_group/hook.go +++ b/pkg/resource/log_group/hook.go @@ -174,6 +174,11 @@ func (rm *resourceManager) customUpdateLogGroup( return &resource{ko}, err } } + if delta.DifferentAt("Spec.MetricFilters") { + if err := rm.updateMetricFilters(ctx, desired, latest); err != nil { + return &resource{ko}, err + } + } if desired.ko.Spec.RetentionDays != nil { ko.Status.RetentionInDays = desired.ko.Spec.RetentionDays @@ -320,3 +325,248 @@ func equalStrings(a, b *string) bool { return (*a == "" && b == nil) || *a == *b } + +func (rm *resourceManager) updateMetricFilters( + ctx context.Context, + desired, latest *resource, +) (err error) { + rlog := ackrtlog.FromContext(ctx) + exit := rlog.Trace("rm.updateMetricFilters") + defer func(err error) { + exit(err) + }(err) + + toAdd, toRemove := compareMetricFilters(desired.ko.Spec.MetricFilters, latest.ko.Spec.MetricFilters) + for _, metricFilter := range toRemove { + _, err = rm.removeMetricFilter(ctx, desired, metricFilter.FilterName) + if err != nil { + return err + } + } + for _, metricFilter := range toAdd { + _, err = rm.addMetricFilter(ctx, desired, metricFilter) + if err != nil { + return err + } + } + return nil +} + +// addMetricFilter calls the AWS API to add a metric filter. +func (rm *resourceManager) addMetricFilter( + ctx context.Context, + desired *resource, + metricFilter *svcapitypes.PutMetricFilterInput, +) (output *svcsdk.PutMetricFilterOutput, err error) { + rlog := ackrtlog.FromContext(ctx) + exit := rlog.Trace("rm.addMetricFilter") + defer func(err error) { exit(err) }(err) + + input := &svcsdk.PutMetricFilterInput{ + LogGroupName: desired.ko.Spec.Name, + FilterName: metricFilter.FilterName, + FilterPattern: metricFilter.FilterPattern, + } + if metricFilter.MetricTransformations != nil { + transformations := make([]svcsdktypes.MetricTransformation, 0, len(metricFilter.MetricTransformations)) + for _, mt := range metricFilter.MetricTransformations { + t := svcsdktypes.MetricTransformation{} + if mt.MetricName != nil { + t.MetricName = mt.MetricName + } + if mt.MetricNamespace != nil { + t.MetricNamespace = mt.MetricNamespace + } + if mt.MetricValue != nil { + t.MetricValue = mt.MetricValue + } + if mt.DefaultValue != nil { + t.DefaultValue = mt.DefaultValue + } + if mt.Unit != nil { + t.Unit = svcsdktypes.StandardUnit(*mt.Unit) + } + if mt.Dimensions != nil { + dims := make(map[string]string, len(mt.Dimensions)) + for k, v := range mt.Dimensions { + if v != nil { + dims[k] = *v + } + } + t.Dimensions = dims + } + transformations = append(transformations, t) + } + input.MetricTransformations = transformations + } + + output, err = rm.sdkapi.PutMetricFilter(ctx, input) + rm.metrics.RecordAPICall("UPDATE", "PutMetricFilter", err) + if err != nil { + return nil, err + } + return output, nil +} + +// removeMetricFilter calls the AWS API to delete a metric filter. +func (rm *resourceManager) removeMetricFilter( + ctx context.Context, + desired *resource, + filterName *string, +) (output *svcsdk.DeleteMetricFilterOutput, err error) { + rlog := ackrtlog.FromContext(ctx) + exit := rlog.Trace("rm.removeMetricFilter") + defer func(err error) { exit(err) }(err) + + input := &svcsdk.DeleteMetricFilterInput{ + FilterName: filterName, + LogGroupName: desired.ko.Spec.Name, + } + + output, err = rm.sdkapi.DeleteMetricFilter(ctx, input) + rm.metrics.RecordAPICall("UPDATE", "DeleteMetricFilter", err) + if err != nil { + return nil, err + } + return output, nil +} + +func (rm *resourceManager) getMetricFilters(ctx context.Context, name *string) ([]*svcapitypes.PutMetricFilterInput, error) { + var err error + rlog := ackrtlog.FromContext(ctx) + exit := rlog.Trace("rm.getMetricFilters") + defer func(err error) { exit(err) }(err) + + metricFilters := make([]*svcapitypes.PutMetricFilterInput, 0) + input := &svcsdk.DescribeMetricFiltersInput{ + LogGroupName: name, + } + + for { + var resp *svcsdk.DescribeMetricFiltersOutput + resp, err = rm.sdkapi.DescribeMetricFilters(ctx, input) + rm.metrics.RecordAPICall("READ_MANY", "DescribeMetricFilters", err) + if err != nil { + return nil, err + } + + for _, mf := range resp.MetricFilters { + pmfi := &svcapitypes.PutMetricFilterInput{ + FilterName: mf.FilterName, + FilterPattern: mf.FilterPattern, + } + if mf.MetricTransformations != nil { + transformations := make([]*svcapitypes.MetricTransformation, 0, len(mf.MetricTransformations)) + for _, mt := range mf.MetricTransformations { + t := &svcapitypes.MetricTransformation{ + MetricName: mt.MetricName, + MetricNamespace: mt.MetricNamespace, + MetricValue: mt.MetricValue, + DefaultValue: mt.DefaultValue, + } + if mt.Unit != "" { + unit := string(mt.Unit) + t.Unit = &unit + } + if mt.Dimensions != nil { + dims := make(map[string]*string, len(mt.Dimensions)) + for k, v := range mt.Dimensions { + vCopy := v + dims[k] = &vCopy + } + t.Dimensions = dims + } + transformations = append(transformations, t) + } + pmfi.MetricTransformations = transformations + } + metricFilters = append(metricFilters, pmfi) + } + if resp.NextToken == nil { + break + } + input.NextToken = resp.NextToken + } + + return metricFilters, nil +} + +func compareMetricFilters( + desired, observed []*svcapitypes.PutMetricFilterInput, +) (toAdd, toRemove []*svcapitypes.PutMetricFilterInput) { + for _, d := range desired { + found := false + for _, o := range observed { + if *d.FilterName == *o.FilterName { + if !equalMetricFilters(*d, *o) { + break + } + found = true + break + } + } + if !found { + toAdd = append(toAdd, d) + } + } + for _, o := range observed { + found := false + for _, d := range desired { + if *o.FilterName == *d.FilterName { + found = true + break + } + } + if !found { + toRemove = append(toRemove, o) + } + } + return +} + +func equalMetricFilters(a, b svcapitypes.PutMetricFilterInput) bool { + if !equalStrings(a.FilterName, b.FilterName) { + return false + } + if !equalStrings(a.FilterPattern, b.FilterPattern) { + return false + } + if len(a.MetricTransformations) != len(b.MetricTransformations) { + return false + } + for i := range a.MetricTransformations { + if !equalMetricTransformations(a.MetricTransformations[i], b.MetricTransformations[i]) { + return false + } + } + return true +} + +func equalMetricTransformations(a, b *svcapitypes.MetricTransformation) bool { + if a == nil && b == nil { + return true + } + if a == nil || b == nil { + return false + } + if !equalStrings(a.MetricName, b.MetricName) { + return false + } + if !equalStrings(a.MetricNamespace, b.MetricNamespace) { + return false + } + if !equalStrings(a.MetricValue, b.MetricValue) { + return false + } + if !equalStrings(a.Unit, b.Unit) { + return false + } + // Compare DefaultValue + if (a.DefaultValue == nil) != (b.DefaultValue == nil) { + return false + } + if a.DefaultValue != nil && *a.DefaultValue != *b.DefaultValue { + return false + } + return true +} diff --git a/pkg/resource/log_group/sdk.go b/pkg/resource/log_group/sdk.go index 58fa9d5..4b5c669 100644 --- a/pkg/resource/log_group/sdk.go +++ b/pkg/resource/log_group/sdk.go @@ -151,6 +151,10 @@ func (rm *resourceManager) sdkFind( if err != nil { return nil, err } + ko.Spec.MetricFilters, err = rm.getMetricFilters(ctx, r.ko.Spec.Name) + if err != nil { + return nil, err + } ko.Spec.Tags, err = getTags(ctx, rm.sdkapi, rm.metrics, string(*ko.Status.ACKResourceMetadata.ARN)) if err != nil { return nil, err @@ -228,7 +232,7 @@ func (rm *resourceManager) sdkCreate( // // It's the first we see this issue. @a-hilaly to investigate and determine // whether this is a bug everywhere or something specific to cloudwatch. - if len(desired.ko.Spec.SubscriptionFilters) > 0 { + if len(desired.ko.Spec.SubscriptionFilters) > 0 || len(desired.ko.Spec.MetricFilters) > 0 { return &resource{ko}, &ackrequeue.RequeueNeeded{} } diff --git a/pkg/version/version.go b/pkg/version/version.go index de0f243..30662cd 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -19,4 +19,4 @@ var ( GitVersion string GitCommit string BuildDate string -) +) \ No newline at end of file diff --git a/templates/hooks/log_group/sdk_create_post_set_output.go.tpl b/templates/hooks/log_group/sdk_create_post_set_output.go.tpl index 42ea7aa..a4217c6 100644 --- a/templates/hooks/log_group/sdk_create_post_set_output.go.tpl +++ b/templates/hooks/log_group/sdk_create_post_set_output.go.tpl @@ -14,6 +14,6 @@ // // It's the first we see this issue. @a-hilaly to investigate and determine // whether this is a bug everywhere or something specific to cloudwatch. - if len(desired.ko.Spec.SubscriptionFilters) > 0 { + if len(desired.ko.Spec.SubscriptionFilters) > 0 || len(desired.ko.Spec.MetricFilters) > 0 { return &resource{ko}, &ackrequeue.RequeueNeeded{} } diff --git a/templates/hooks/log_group/sdk_read_many_post_set_output.go.tpl b/templates/hooks/log_group/sdk_read_many_post_set_output.go.tpl index 1624494..24ce9a7 100644 --- a/templates/hooks/log_group/sdk_read_many_post_set_output.go.tpl +++ b/templates/hooks/log_group/sdk_read_many_post_set_output.go.tpl @@ -5,6 +5,10 @@ if err != nil { return nil, err } + ko.Spec.MetricFilters, err = rm.getMetricFilters(ctx, r.ko.Spec.Name) + if err != nil { + return nil, err + } ko.Spec.Tags, err = getTags(ctx, rm.sdkapi, rm.metrics, string(*ko.Status.ACKResourceMetadata.ARN)) if err != nil { return nil, err