diff --git a/CODING_STANDARDS.md b/CODING_STANDARDS.md index df402caf2..c863aa64f 100644 --- a/CODING_STANDARDS.md +++ b/CODING_STANDARDS.md @@ -36,6 +36,7 @@ This document outlines the coding standards and conventions used in the terrafor - Prefer using existing util functions over longer form, duplicated code: - `utils.IsKnown(val)` instead of `!val.IsNull() && !val.IsUnknown()` - `utils.ListTypeAs` instead of `val.ElementsAs` or similar for other collection types +- The final state for a resource should be derived from a read request following a mutative request (eg create or update). We should not use the response from a mutative request to build the final resource state. ## Schema Definitions diff --git a/docs/resources/kibana_security_exception_item.md b/docs/resources/kibana_security_exception_item.md new file mode 100644 index 000000000..2289a6ddf --- /dev/null +++ b/docs/resources/kibana_security_exception_item.md @@ -0,0 +1,173 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "elasticstack_kibana_security_exception_item Resource - terraform-provider-elasticstack" +subcategory: "Kibana" +description: |- + Manages a Kibana Exception Item. Exception items define the specific query conditions used to prevent rules from generating alerts. + See the Kibana Exceptions API documentation https://www.elastic.co/docs/api/doc/kibana/group/endpoint-security-exceptions-api for more details. +--- + +# elasticstack_kibana_security_exception_item (Resource) + +Manages a Kibana Exception Item. Exception items define the specific query conditions used to prevent rules from generating alerts. + +See the [Kibana Exceptions API documentation](https://www.elastic.co/docs/api/doc/kibana/group/endpoint-security-exceptions-api) for more details. + +## Example Usage + +### Basic exception item + +```terraform +resource "elasticstack_kibana_security_exception_list" "example" { + list_id = "my-exception-list" + name = "My Exception List" + description = "List of exceptions for security rules" + type = "detection" + namespace_type = "single" + + tags = ["security", "detections"] +} + +resource "elasticstack_kibana_security_exception_item" "example" { + list_id = elasticstack_kibana_security_exception_list.example.list_id + item_id = "my-exception-item" + name = "My Exception Item" + description = "Exclude specific processes from alerts" + type = "simple" + namespace_type = "single" + + entries = [ + { + type = "match" + field = "process.name" + operator = "included" + value = "trusted-process" + } + ] + + tags = ["trusted", "whitelisted"] +} +``` + +### Complex exception item with multiple entries + +```terraform +resource "elasticstack_kibana_security_exception_list" "example" { + list_id = "my-exception-list" + name = "My Exception List" + description = "List of exceptions" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "complex_entry" { + list_id = elasticstack_kibana_security_exception_list.example.list_id + item_id = "complex-exception" + name = "Complex Exception with Multiple Entries" + description = "Exception with multiple conditions" + type = "simple" + namespace_type = "single" + + # Multiple entries with different operators + entries = [ + { + type = "match" + field = "host.name" + operator = "included" + value = "trusted-host" + }, + { + type = "match_any" + field = "user.name" + operator = "excluded" + values = ["admin", "root"] + } + ] + + os_types = ["linux"] + tags = ["complex", "multi-condition"] +} +``` + + +## Schema + +### Required + +- `description` (String) Describes the exception item. +- `entries` (Attributes List) The exception item entries. This defines the conditions under which the exception applies. (see [below for nested schema](#nestedatt--entries)) +- `list_id` (String) The exception list's identifier that this item belongs to. +- `name` (String) The name of the exception item. +- `type` (String) The type of exception item. Must be `simple`. + +### Optional + +- `comments` (Attributes List) Array of comments about the exception item. (see [below for nested schema](#nestedatt--comments)) +- `expire_time` (String) The exception item's expiration date in RFC3339 format. This field is only available for regular exception items, not endpoint exceptions. +- `item_id` (String) The exception item's human readable string identifier. +- `meta` (String) Placeholder for metadata about the exception item as JSON string. +- `namespace_type` (String) Determines whether the exception item is available in all Kibana spaces or just the space in which it is created. Can be `single` (default) or `agnostic`. +- `os_types` (List of String) Array of OS types for which the exceptions apply. Valid values: `linux`, `macos`, `windows`. +- `space_id` (String) An identifier for the space. If space_id is not provided, the default space is used. +- `tags` (List of String) String array containing words and phrases to help categorize exception items. + +### Read-Only + +- `created_at` (String) The timestamp of when the exception item was created. +- `created_by` (String) The user who created the exception item. +- `id` (String) The unique identifier of the exception item (auto-generated by Kibana). +- `tie_breaker_id` (String) Field used in search to ensure all items are sorted and returned correctly. +- `updated_at` (String) The timestamp of when the exception item was last updated. +- `updated_by` (String) The user who last updated the exception item. + + +### Nested Schema for `entries` + +Required: + +- `field` (String) The field name. Required for all entry types. +- `type` (String) The type of entry. Valid values: `match`, `match_any`, `list`, `exists`, `nested`, `wildcard`. + +Optional: + +- `entries` (Attributes List) Nested entries (for `nested` type). Only `match`, `match_any`, and `exists` entry types are allowed as nested entries. (see [below for nested schema](#nestedatt--entries--entries)) +- `list` (Attributes) Value list reference (for `list` type). (see [below for nested schema](#nestedatt--entries--list)) +- `operator` (String) The operator to use. Valid values: `included`, `excluded`. Note: The operator field is not supported for nested entry types and will be ignored if specified. +- `value` (String) The value to match (for `match` and `wildcard` types). +- `values` (List of String) Array of values to match (for `match_any` type). + + +### Nested Schema for `entries.entries` + +Required: + +- `field` (String) The field name. +- `operator` (String) The operator to use. Valid values: `included`, `excluded`. +- `type` (String) The type of nested entry. Valid values: `match`, `match_any`, `exists`. + +Optional: + +- `value` (String) The value to match (for `match` type). +- `values` (List of String) Array of values to match (for `match_any` type). + + + +### Nested Schema for `entries.list` + +Required: + +- `id` (String) The value list ID. +- `type` (String) The value list type (e.g., `keyword`, `ip`, `ip_range`). + + + + +### Nested Schema for `comments` + +Required: + +- `comment` (String) The comment text. + +Read-Only: + +- `id` (String) The unique identifier of the comment (auto-generated by Kibana). diff --git a/docs/resources/kibana_security_exception_list.md b/docs/resources/kibana_security_exception_list.md new file mode 100644 index 000000000..974f92fac --- /dev/null +++ b/docs/resources/kibana_security_exception_list.md @@ -0,0 +1,73 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "elasticstack_kibana_security_exception_list Resource - terraform-provider-elasticstack" +subcategory: "Kibana" +description: |- + Manages a Kibana Exception List. Exception lists are containers for exception items used to prevent security rules from generating alerts. + See the Kibana Exceptions API documentation https://www.elastic.co/docs/api/doc/kibana/group/endpoint-security-exceptions-api for more details. +--- + +# elasticstack_kibana_security_exception_list (Resource) + +Manages a Kibana Exception List. Exception lists are containers for exception items used to prevent security rules from generating alerts. + +See the [Kibana Exceptions API documentation](https://www.elastic.co/docs/api/doc/kibana/group/endpoint-security-exceptions-api) for more details. + +## Example Usage + +### Basic exception list + +```terraform +resource "elasticstack_kibana_security_exception_list" "example" { + list_id = "my-detection-exception-list" + name = "My Detection Exception List" + description = "List of exceptions for security detection rules" + type = "detection" + namespace_type = "single" + + tags = ["security", "detections"] +} +``` + +### Endpoint exception list with OS types + +```terraform +resource "elasticstack_kibana_security_exception_list" "endpoint" { + list_id = "my-endpoint-exception-list" + name = "My Endpoint Exception List" + description = "List of endpoint exceptions" + type = "endpoint" + namespace_type = "agnostic" + + os_types = ["linux", "windows", "macos"] + tags = ["endpoint", "security"] +} +``` + + +## Schema + +### Required + +- `description` (String) Describes the exception list. +- `list_id` (String) The exception list's human readable string identifier. +- `name` (String) The name of the exception list. +- `type` (String) The type of exception list. Can be one of: `detection`, `endpoint`, `endpoint_trusted_apps`, `endpoint_events`, `endpoint_host_isolation_exceptions`, `endpoint_blocklists`. + +### Optional + +- `meta` (String) Placeholder for metadata about the list container as JSON string. +- `namespace_type` (String) Determines whether the exception list is available in all Kibana spaces or just the space in which it is created. Can be `single` (default) or `agnostic`. +- `os_types` (List of String) Array of OS types for which the exceptions apply. Valid values: `linux`, `macos`, `windows`. +- `space_id` (String) An identifier for the space. If space_id is not provided, the default space is used. +- `tags` (List of String) String array containing words and phrases to help categorize exception containers. + +### Read-Only + +- `created_at` (String) The timestamp of when the exception list was created. +- `created_by` (String) The user who created the exception list. +- `id` (String) The unique identifier of the exception list (auto-generated by Kibana). +- `immutable` (Boolean) Whether the exception list is immutable. +- `tie_breaker_id` (String) Field used in search to ensure all containers are sorted and returned correctly. +- `updated_at` (String) The timestamp of when the exception list was last updated. +- `updated_by` (String) The user who last updated the exception list. diff --git a/docs/resources/kibana_security_list.md b/docs/resources/kibana_security_list.md new file mode 100644 index 000000000..52299ff2f --- /dev/null +++ b/docs/resources/kibana_security_list.md @@ -0,0 +1,110 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "elasticstack_kibana_security_list Resource - terraform-provider-elasticstack" +subcategory: "Kibana" +description: |- + Manages Kibana security lists (also known as value lists). Security lists are used by exception items to define sets of values for matching or excluding in security rules. + Example Usage + + resource "elasticstack_kibana_security_list" "ip_list" { + space_id = "default" + name = "Trusted IP Addresses" + description = "List of trusted IP addresses for security rules" + type = "ip" + } + + resource "elasticstack_kibana_security_list" "keyword_list" { + space_id = "security" + list_id = "custom-keywords" + name = "Custom Keywords" + description = "Custom keyword list for detection rules" + type = "keyword" + } + + Notes + Security lists define the type of data they can contain via the type attributeOnce created, the type of a list cannot be changedLists can be referenced by exception items to create more sophisticated matching rulesThe list_id is auto-generated if not provided +--- + +# elasticstack_kibana_security_list (Resource) + +Manages Kibana security lists (also known as value lists). Security lists are used by exception items to define sets of values for matching or excluding in security rules. + +## Example Usage + +```terraform +resource "elasticstack_kibana_security_list" "ip_list" { + space_id = "default" + name = "Trusted IP Addresses" + description = "List of trusted IP addresses for security rules" + type = "ip" +} + +resource "elasticstack_kibana_security_list" "keyword_list" { + space_id = "security" + list_id = "custom-keywords" + name = "Custom Keywords" + description = "Custom keyword list for detection rules" + type = "keyword" +} +``` + +## Notes + +- Security lists define the type of data they can contain via the `type` attribute +- Once created, the `type` of a list cannot be changed +- Lists can be referenced by exception items to create more sophisticated matching rules +- The `list_id` is auto-generated if not provided + +## Example Usage + +### IP address list + +```terraform +resource "elasticstack_kibana_security_list" "ip_list" { + space_id = "default" + name = "Trusted IP Addresses" + description = "List of trusted IP addresses for security rules" + type = "ip" +} +``` + +### Keyword list with custom list_id + +```terraform +resource "elasticstack_kibana_security_list" "keyword_list" { + space_id = "security" + list_id = "custom-keywords" + name = "Custom Keywords" + description = "Custom keyword list for detection rules" + type = "keyword" +} +``` + + +## Schema + +### Required + +- `description` (String) Describes the security list. +- `name` (String) The name of the security list. +- `type` (String) Specifies the Elasticsearch data type of values the list contains. Valid values include: `binary`, `boolean`, `byte`, `date`, `date_nanos`, `date_range`, `double`, `double_range`, `float`, `float_range`, `geo_point`, `geo_shape`, `half_float`, `integer`, `integer_range`, `ip`, `ip_range`, `keyword`, `long`, `long_range`, `shape`, `short`, `text`. + +### Optional + +- `deserializer` (String) Determines how retrieved list item values are presented. By default, list items are presented using Handlebars expressions based on the type. +- `id` (String) The unique identifier of the security list (auto-generated by Kibana if not specified). +- `list_id` (String) The value list's human-readable identifier. +- `meta` (String) Placeholder for metadata about the value list as JSON string. +- `serializer` (String) Determines how uploaded list item values are parsed. By default, list items are parsed using named regex groups based on the type. +- `space_id` (String) An identifier for the space. If space_id is not provided, the default space is used. +- `version` (Number) The document version number. + +### Read-Only + +- `created_at` (String) The timestamp of when the list was created. +- `created_by` (String) The user who created the list. +- `immutable` (Boolean) Whether the list is immutable. +- `tie_breaker_id` (String) Field used in search to ensure all containers are sorted and returned correctly. +- `updated_at` (String) The timestamp of when the list was last updated. +- `updated_by` (String) The user who last updated the list. +- `version_id` (String) The version id, normally returned by the API when the document is retrieved. diff --git a/docs/resources/kibana_security_list_item.md b/docs/resources/kibana_security_list_item.md new file mode 100644 index 000000000..14645968f --- /dev/null +++ b/docs/resources/kibana_security_list_item.md @@ -0,0 +1,197 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "elasticstack_kibana_security_list_item Resource - terraform-provider-elasticstack" +subcategory: "Kibana" +description: |- + subcategory: "Kibana" + layout: "" + page_title: "Elasticstack: elasticstack_kibana_security_list_item Resource" + description: |- + Manages items within Kibana security value lists. + Resource: elasticstack_kibana_security_list_item + Manages items within Kibana security value lists. Value lists are containers for values that can be used within exception lists to define conditions. This resource allows you to add, update, and remove individual values (items) in those lists. + Value list items are used to store data values that match the type of their parent security list (e.g., IP addresses, keywords, etc.). These items can then be referenced in exception list entries to define exception conditions. + Example Usage + + # First create a security list + resource "elasticstack_kibana_security_list" "ip_list" { + list_id = "allowed_ips" + name = "Allowed IP Addresses" + description = "List of IP addresses that are allowed" + type = "ip" + } + + # Add an IP address to the list + resource "elasticstack_kibana_security_list_item" "ip_item_1" { + list_id = elasticstack_kibana_security_list.ip_list.list_id + value = "192.168.1.1" + } + + # Add another IP address + resource "elasticstack_kibana_security_list_item" "ip_item_2" { + list_id = elasticstack_kibana_security_list.ip_list.list_id + value = "10.0.0.1" + } + + # Add a keyword item with metadata + resource "elasticstack_kibana_security_list" "keyword_list" { + list_id = "allowed_domains" + name = "Allowed Domains" + description = "List of domains that are allowed" + type = "keyword" + } + + resource "elasticstack_kibana_security_list_item" "domain_item" { + list_id = elasticstack_kibana_security_list.keyword_list.list_id + value = "example.com" + meta = jsonencode({ + note = "Primary corporate domain" + }) + } + + Note on Space Support + Important: The generated Kibana API client does not currently support space_id for list item operations. While the space_id attribute is available in the schema for future compatibility, list items currently operate in the default space only. This is a known limitation that will be addressed in a future update when the API client is regenerated with proper space support. +--- + +# elasticstack_kibana_security_list_item (Resource) + +--- +subcategory: "Kibana" +layout: "" +page_title: "Elasticstack: elasticstack_kibana_security_list_item Resource" +description: |- + Manages items within Kibana security value lists. +--- + +# Resource: elasticstack_kibana_security_list_item + +Manages items within Kibana security value lists. Value lists are containers for values that can be used within exception lists to define conditions. This resource allows you to add, update, and remove individual values (items) in those lists. + +Value list items are used to store data values that match the type of their parent security list (e.g., IP addresses, keywords, etc.). These items can then be referenced in exception list entries to define exception conditions. + +## Example Usage + +```terraform +# First create a security list +resource "elasticstack_kibana_security_list" "ip_list" { + list_id = "allowed_ips" + name = "Allowed IP Addresses" + description = "List of IP addresses that are allowed" + type = "ip" +} + +# Add an IP address to the list +resource "elasticstack_kibana_security_list_item" "ip_item_1" { + list_id = elasticstack_kibana_security_list.ip_list.list_id + value = "192.168.1.1" +} + +# Add another IP address +resource "elasticstack_kibana_security_list_item" "ip_item_2" { + list_id = elasticstack_kibana_security_list.ip_list.list_id + value = "10.0.0.1" +} + +# Add a keyword item with metadata +resource "elasticstack_kibana_security_list" "keyword_list" { + list_id = "allowed_domains" + name = "Allowed Domains" + description = "List of domains that are allowed" + type = "keyword" +} + +resource "elasticstack_kibana_security_list_item" "domain_item" { + list_id = elasticstack_kibana_security_list.keyword_list.list_id + value = "example.com" + meta = jsonencode({ + note = "Primary corporate domain" + }) +} +``` + +## Note on Space Support + +**Important**: The generated Kibana API client does not currently support space_id for list item operations. While the `space_id` attribute is available in the schema for future compatibility, list items currently operate in the default space only. This is a known limitation that will be addressed in a future update when the API client is regenerated with proper space support. + +## Example Usage + +### Basic keyword value + +```terraform +# First create a security list +resource "elasticstack_kibana_security_list" "my_list" { + list_id = "allowed_domains" + name = "Allowed Domains" + description = "List of allowed domains" + type = "keyword" +} + +# Add an item to the list +resource "elasticstack_kibana_security_list_item" "domain_example" { + list_id = elasticstack_kibana_security_list.my_list.list_id + value = "example.com" +} +``` + +### IP address value + +```terraform +# First create an IP address list +resource "elasticstack_kibana_security_list" "ip_list" { + list_id = "allowed_ips" + name = "Allowed IP Addresses" + description = "List of allowed IP addresses" + type = "ip" +} + +# Add an IP address to the list +resource "elasticstack_kibana_security_list_item" "ip_example" { + list_id = elasticstack_kibana_security_list.ip_list.list_id + value = "192.168.1.1" +} +``` + +### Value with metadata + +```terraform +# First create a security list +resource "elasticstack_kibana_security_list" "tagged_domains" { + list_id = "tagged_domains" + name = "Tagged Domains" + description = "Domains with associated metadata" + type = "keyword" +} + +# Add an item with metadata +resource "elasticstack_kibana_security_list_item" "domain_with_meta" { + list_id = elasticstack_kibana_security_list.tagged_domains.list_id + value = "internal.example.com" + meta = jsonencode({ + category = "internal" + owner = "infrastructure-team" + note = "Primary internal domain" + }) +} +``` + + +## Schema + +### Required + +- `list_id` (String) The value list's identifier that this item belongs to. +- `value` (String) The value used to evaluate exceptions. The value's data type must match the list's type. + +### Optional + +- `id` (String) The value list item's identifier (auto-generated by Kibana if not specified). +- `meta` (String) Placeholder for metadata about the value list item as JSON string. +- `space_id` (String) An identifier for the space. If space_id is not provided, the default space is used. + +### Read-Only + +- `created_at` (String) The timestamp of when the list item was created. +- `created_by` (String) The user who created the list item. +- `updated_at` (String) The timestamp of when the list item was last updated. +- `updated_by` (String) The user who last updated the list item. +- `version` (String) The version id, normally returned by the API when the document is retrieved. Used to ensure updates are done against the latest version. diff --git a/examples/resources/elasticstack_kibana_security_exception_item/resource.tf b/examples/resources/elasticstack_kibana_security_exception_item/resource.tf new file mode 100644 index 000000000..22d1bea09 --- /dev/null +++ b/examples/resources/elasticstack_kibana_security_exception_item/resource.tf @@ -0,0 +1,29 @@ +resource "elasticstack_kibana_security_exception_list" "example" { + list_id = "my-exception-list" + name = "My Exception List" + description = "List of exceptions for security rules" + type = "detection" + namespace_type = "single" + + tags = ["security", "detections"] +} + +resource "elasticstack_kibana_security_exception_item" "example" { + list_id = elasticstack_kibana_security_exception_list.example.list_id + item_id = "my-exception-item" + name = "My Exception Item" + description = "Exclude specific processes from alerts" + type = "simple" + namespace_type = "single" + + entries = [ + { + type = "match" + field = "process.name" + operator = "included" + value = "trusted-process" + } + ] + + tags = ["trusted", "whitelisted"] +} diff --git a/examples/resources/elasticstack_kibana_security_exception_item/resource_complex.tf b/examples/resources/elasticstack_kibana_security_exception_item/resource_complex.tf new file mode 100644 index 000000000..6955e5245 --- /dev/null +++ b/examples/resources/elasticstack_kibana_security_exception_item/resource_complex.tf @@ -0,0 +1,35 @@ +resource "elasticstack_kibana_security_exception_list" "example" { + list_id = "my-exception-list" + name = "My Exception List" + description = "List of exceptions" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "complex_entry" { + list_id = elasticstack_kibana_security_exception_list.example.list_id + item_id = "complex-exception" + name = "Complex Exception with Multiple Entries" + description = "Exception with multiple conditions" + type = "simple" + namespace_type = "single" + + # Multiple entries with different operators + entries = [ + { + type = "match" + field = "host.name" + operator = "included" + value = "trusted-host" + }, + { + type = "match_any" + field = "user.name" + operator = "excluded" + values = ["admin", "root"] + } + ] + + os_types = ["linux"] + tags = ["complex", "multi-condition"] +} diff --git a/examples/resources/elasticstack_kibana_security_exception_list/resource.tf b/examples/resources/elasticstack_kibana_security_exception_list/resource.tf new file mode 100644 index 000000000..70c9805f0 --- /dev/null +++ b/examples/resources/elasticstack_kibana_security_exception_list/resource.tf @@ -0,0 +1,9 @@ +resource "elasticstack_kibana_security_exception_list" "example" { + list_id = "my-detection-exception-list" + name = "My Detection Exception List" + description = "List of exceptions for security detection rules" + type = "detection" + namespace_type = "single" + + tags = ["security", "detections"] +} diff --git a/examples/resources/elasticstack_kibana_security_exception_list/resource_endpoint.tf b/examples/resources/elasticstack_kibana_security_exception_list/resource_endpoint.tf new file mode 100644 index 000000000..2aaa604f3 --- /dev/null +++ b/examples/resources/elasticstack_kibana_security_exception_list/resource_endpoint.tf @@ -0,0 +1,10 @@ +resource "elasticstack_kibana_security_exception_list" "endpoint" { + list_id = "my-endpoint-exception-list" + name = "My Endpoint Exception List" + description = "List of endpoint exceptions" + type = "endpoint" + namespace_type = "agnostic" + + os_types = ["linux", "windows", "macos"] + tags = ["endpoint", "security"] +} diff --git a/examples/resources/elasticstack_kibana_security_list/resource.tf b/examples/resources/elasticstack_kibana_security_list/resource.tf new file mode 100644 index 000000000..b8d89eb50 --- /dev/null +++ b/examples/resources/elasticstack_kibana_security_list/resource.tf @@ -0,0 +1,6 @@ +resource "elasticstack_kibana_security_list" "ip_list" { + space_id = "default" + name = "Trusted IP Addresses" + description = "List of trusted IP addresses for security rules" + type = "ip" +} diff --git a/examples/resources/elasticstack_kibana_security_list/resource_keyword.tf b/examples/resources/elasticstack_kibana_security_list/resource_keyword.tf new file mode 100644 index 000000000..e8aa1e811 --- /dev/null +++ b/examples/resources/elasticstack_kibana_security_list/resource_keyword.tf @@ -0,0 +1,7 @@ +resource "elasticstack_kibana_security_list" "keyword_list" { + space_id = "security" + list_id = "custom-keywords" + name = "Custom Keywords" + description = "Custom keyword list for detection rules" + type = "keyword" +} diff --git a/examples/resources/elasticstack_kibana_security_list_item/resource.tf b/examples/resources/elasticstack_kibana_security_list_item/resource.tf new file mode 100644 index 000000000..705311869 --- /dev/null +++ b/examples/resources/elasticstack_kibana_security_list_item/resource.tf @@ -0,0 +1,13 @@ +# First create a security list +resource "elasticstack_kibana_security_list" "my_list" { + list_id = "allowed_domains" + name = "Allowed Domains" + description = "List of allowed domains" + type = "keyword" +} + +# Add an item to the list +resource "elasticstack_kibana_security_list_item" "domain_example" { + list_id = elasticstack_kibana_security_list.my_list.list_id + value = "example.com" +} diff --git a/examples/resources/elasticstack_kibana_security_list_item/resource_ip.tf b/examples/resources/elasticstack_kibana_security_list_item/resource_ip.tf new file mode 100644 index 000000000..d306ef013 --- /dev/null +++ b/examples/resources/elasticstack_kibana_security_list_item/resource_ip.tf @@ -0,0 +1,13 @@ +# First create an IP address list +resource "elasticstack_kibana_security_list" "ip_list" { + list_id = "allowed_ips" + name = "Allowed IP Addresses" + description = "List of allowed IP addresses" + type = "ip" +} + +# Add an IP address to the list +resource "elasticstack_kibana_security_list_item" "ip_example" { + list_id = elasticstack_kibana_security_list.ip_list.list_id + value = "192.168.1.1" +} diff --git a/examples/resources/elasticstack_kibana_security_list_item/resource_with_meta.tf b/examples/resources/elasticstack_kibana_security_list_item/resource_with_meta.tf new file mode 100644 index 000000000..03131f882 --- /dev/null +++ b/examples/resources/elasticstack_kibana_security_list_item/resource_with_meta.tf @@ -0,0 +1,18 @@ +# First create a security list +resource "elasticstack_kibana_security_list" "tagged_domains" { + list_id = "tagged_domains" + name = "Tagged Domains" + description = "Domains with associated metadata" + type = "keyword" +} + +# Add an item with metadata +resource "elasticstack_kibana_security_list_item" "domain_with_meta" { + list_id = elasticstack_kibana_security_list.tagged_domains.list_id + value = "internal.example.com" + meta = jsonencode({ + category = "internal" + owner = "infrastructure-team" + note = "Primary internal domain" + }) +} diff --git a/generated/kbapi/kibana.gen.go b/generated/kbapi/kibana.gen.go index 57dd6b0b3..ae79993af 100644 --- a/generated/kbapi/kibana.gen.go +++ b/generated/kbapi/kibana.gen.go @@ -28988,100 +28988,6 @@ type GetEntityStoreStatusParams struct { IncludeComponents *bool `form:"include_components,omitempty" json:"include_components,omitempty"` } -// DeleteExceptionListParams defines parameters for DeleteExceptionList. -type DeleteExceptionListParams struct { - // Id Exception list's identifier. Either `id` or `list_id` must be specified. - Id *SecurityExceptionsAPIExceptionListId `form:"id,omitempty" json:"id,omitempty"` - - // ListId Human readable exception list string identifier, e.g. `trusted-linux-processes`. Either `id` or `list_id` must be specified. - ListId *SecurityExceptionsAPIExceptionListHumanId `form:"list_id,omitempty" json:"list_id,omitempty"` - NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `form:"namespace_type,omitempty" json:"namespace_type,omitempty"` -} - -// ReadExceptionListParams defines parameters for ReadExceptionList. -type ReadExceptionListParams struct { - // Id Exception list's identifier. Either `id` or `list_id` must be specified. - Id *SecurityExceptionsAPIExceptionListId `form:"id,omitempty" json:"id,omitempty"` - - // ListId Human readable exception list string identifier, e.g. `trusted-linux-processes`. Either `id` or `list_id` must be specified. - ListId *SecurityExceptionsAPIExceptionListHumanId `form:"list_id,omitempty" json:"list_id,omitempty"` - NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `form:"namespace_type,omitempty" json:"namespace_type,omitempty"` -} - -// CreateExceptionListJSONBody defines parameters for CreateExceptionList. -type CreateExceptionListJSONBody struct { - // Description Describes the exception list. - Description SecurityExceptionsAPIExceptionListDescription `json:"description"` - - // ListId The exception list's human readable string identifier, `endpoint_list`. - ListId *SecurityExceptionsAPIExceptionListHumanId `json:"list_id,omitempty"` - - // Meta Placeholder for metadata about the list container. - Meta *SecurityExceptionsAPIExceptionListMeta `json:"meta,omitempty"` - - // Name The name of the exception list. - Name SecurityExceptionsAPIExceptionListName `json:"name"` - - // NamespaceType Determines whether the exception container is available in all Kibana spaces or just the space - // in which it is created, where: - // - // - `single`: Only available in the Kibana space in which it is created. - // - `agnostic`: Available in all Kibana spaces. - NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `json:"namespace_type,omitempty"` - - // OsTypes Use this field to specify the operating system. Only enter one value. - OsTypes *SecurityExceptionsAPIExceptionListOsTypeArray `json:"os_types,omitempty"` - - // Tags String array containing words and phrases to help categorize exception containers. - Tags *SecurityExceptionsAPIExceptionListTags `json:"tags,omitempty"` - - // Type The type of exception list to be created. Different list types may denote where they can be utilized. - Type SecurityExceptionsAPIExceptionListType `json:"type"` - - // Version The document version, automatically increasd on updates. - Version *SecurityExceptionsAPIExceptionListVersion `json:"version,omitempty"` -} - -// UpdateExceptionListJSONBody defines parameters for UpdateExceptionList. -type UpdateExceptionListJSONBody struct { - // UnderscoreVersion The version id, normally returned by the API when the item was retrieved. Use it ensure updates are done against the latest version. - UnderscoreVersion *string `json:"_version,omitempty"` - - // Description Describes the exception list. - Description SecurityExceptionsAPIExceptionListDescription `json:"description"` - - // Id Exception list's identifier. - Id *SecurityExceptionsAPIExceptionListId `json:"id,omitempty"` - - // ListId The exception list's human readable string identifier, `endpoint_list`. - ListId *SecurityExceptionsAPIExceptionListHumanId `json:"list_id,omitempty"` - - // Meta Placeholder for metadata about the list container. - Meta *SecurityExceptionsAPIExceptionListMeta `json:"meta,omitempty"` - - // Name The name of the exception list. - Name SecurityExceptionsAPIExceptionListName `json:"name"` - - // NamespaceType Determines whether the exception container is available in all Kibana spaces or just the space - // in which it is created, where: - // - // - `single`: Only available in the Kibana space in which it is created. - // - `agnostic`: Available in all Kibana spaces. - NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `json:"namespace_type,omitempty"` - - // OsTypes Use this field to specify the operating system. Only enter one value. - OsTypes *SecurityExceptionsAPIExceptionListOsTypeArray `json:"os_types,omitempty"` - - // Tags String array containing words and phrases to help categorize exception containers. - Tags *SecurityExceptionsAPIExceptionListTags `json:"tags,omitempty"` - - // Type The type of exception list to be created. Different list types may denote where they can be utilized. - Type SecurityExceptionsAPIExceptionListType `json:"type"` - - // Version The document version, automatically increasd on updates. - Version *SecurityExceptionsAPIExceptionListVersion `json:"version,omitempty"` -} - // DuplicateExceptionListParams defines parameters for DuplicateExceptionList. type DuplicateExceptionListParams struct { ListId SecurityExceptionsAPIExceptionListHumanId `form:"list_id" json:"list_id"` @@ -29155,95 +29061,6 @@ type ImportExceptionListParams struct { AsNewList *bool `form:"as_new_list,omitempty" json:"as_new_list,omitempty"` } -// DeleteExceptionListItemParams defines parameters for DeleteExceptionListItem. -type DeleteExceptionListItemParams struct { - // Id Exception item's identifier. Either `id` or `item_id` must be specified - Id *SecurityExceptionsAPIExceptionListItemId `form:"id,omitempty" json:"id,omitempty"` - - // ItemId Human readable exception item string identifier, e.g. `trusted-linux-processes`. Either `id` or `item_id` must be specified - ItemId *SecurityExceptionsAPIExceptionListItemHumanId `form:"item_id,omitempty" json:"item_id,omitempty"` - NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `form:"namespace_type,omitempty" json:"namespace_type,omitempty"` -} - -// ReadExceptionListItemParams defines parameters for ReadExceptionListItem. -type ReadExceptionListItemParams struct { - // Id Exception list item's identifier. Either `id` or `item_id` must be specified. - Id *SecurityExceptionsAPIExceptionListItemId `form:"id,omitempty" json:"id,omitempty"` - - // ItemId Human readable exception item string identifier, e.g. `trusted-linux-processes`. Either `id` or `item_id` must be specified. - ItemId *SecurityExceptionsAPIExceptionListItemHumanId `form:"item_id,omitempty" json:"item_id,omitempty"` - NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `form:"namespace_type,omitempty" json:"namespace_type,omitempty"` -} - -// CreateExceptionListItemJSONBody defines parameters for CreateExceptionListItem. -type CreateExceptionListItemJSONBody struct { - Comments *SecurityExceptionsAPICreateExceptionListItemCommentArray `json:"comments,omitempty"` - - // Description Describes the exception list. - Description SecurityExceptionsAPIExceptionListItemDescription `json:"description"` - Entries SecurityExceptionsAPIExceptionListItemEntryArray `json:"entries"` - - // ExpireTime The exception item’s expiration date, in ISO format. This field is only available for regular exception items, not endpoint exceptions. - ExpireTime *SecurityExceptionsAPIExceptionListItemExpireTime `json:"expire_time,omitempty"` - - // ItemId Human readable string identifier, e.g. `trusted-linux-processes` - ItemId *SecurityExceptionsAPIExceptionListItemHumanId `json:"item_id,omitempty"` - - // ListId The exception list's human readable string identifier, `endpoint_list`. - ListId SecurityExceptionsAPIExceptionListHumanId `json:"list_id"` - Meta *SecurityExceptionsAPIExceptionListItemMeta `json:"meta,omitempty"` - - // Name Exception list name. - Name SecurityExceptionsAPIExceptionListItemName `json:"name"` - - // NamespaceType Determines whether the exception container is available in all Kibana spaces or just the space - // in which it is created, where: - // - // - `single`: Only available in the Kibana space in which it is created. - // - `agnostic`: Available in all Kibana spaces. - NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `json:"namespace_type,omitempty"` - OsTypes *SecurityExceptionsAPIExceptionListItemOsTypeArray `json:"os_types,omitempty"` - Tags *SecurityExceptionsAPIExceptionListItemTags `json:"tags,omitempty"` - Type SecurityExceptionsAPIExceptionListItemType `json:"type"` -} - -// UpdateExceptionListItemJSONBody defines parameters for UpdateExceptionListItem. -type UpdateExceptionListItemJSONBody struct { - // UnderscoreVersion The version id, normally returned by the API when the item was retrieved. Use it ensure updates are done against the latest version. - UnderscoreVersion *string `json:"_version,omitempty"` - Comments *SecurityExceptionsAPIUpdateExceptionListItemCommentArray `json:"comments,omitempty"` - - // Description Describes the exception list. - Description SecurityExceptionsAPIExceptionListItemDescription `json:"description"` - Entries SecurityExceptionsAPIExceptionListItemEntryArray `json:"entries"` - - // ExpireTime The exception item’s expiration date, in ISO format. This field is only available for regular exception items, not endpoint exceptions. - ExpireTime *SecurityExceptionsAPIExceptionListItemExpireTime `json:"expire_time,omitempty"` - - // Id Exception's identifier. - Id *SecurityExceptionsAPIExceptionListItemId `json:"id,omitempty"` - - // ItemId Human readable string identifier, e.g. `trusted-linux-processes` - ItemId *SecurityExceptionsAPIExceptionListItemHumanId `json:"item_id,omitempty"` - - // ListId The exception list's human readable string identifier, `endpoint_list`. - ListId *SecurityExceptionsAPIExceptionListHumanId `json:"list_id,omitempty"` - Meta *SecurityExceptionsAPIExceptionListItemMeta `json:"meta,omitempty"` - - // Name Exception list name. - Name SecurityExceptionsAPIExceptionListItemName `json:"name"` - - // NamespaceType Determines whether the exception container is available in all Kibana spaces or just the space - // in which it is created, where: - // - // - `single`: Only available in the Kibana space in which it is created. - // - `agnostic`: Available in all Kibana spaces. - NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `json:"namespace_type,omitempty"` - OsTypes *SecurityExceptionsAPIExceptionListItemOsTypeArray `json:"os_types,omitempty"` - Tags *SecurityExceptionsAPIExceptionListItemTags `json:"tags,omitempty"` - Type SecurityExceptionsAPIExceptionListItemType `json:"type"` -} - // FindExceptionListItemsParams defines parameters for FindExceptionListItems. type FindExceptionListItemsParams struct { // ListId The `list_id`s of the items to fetch. @@ -30792,100 +30609,6 @@ type GetFleetUninstallTokensParams struct { Page *float32 `form:"page,omitempty" json:"page,omitempty"` } -// DeleteListParams defines parameters for DeleteList. -type DeleteListParams struct { - Id SecurityListsAPIListId `form:"id" json:"id"` - - // DeleteReferences Determines whether exception items referencing this value list should be deleted. - DeleteReferences *bool `form:"deleteReferences,omitempty" json:"deleteReferences,omitempty"` - - // IgnoreReferences Determines whether to delete value list without performing any additional checks of where this list may be utilized. - IgnoreReferences *bool `form:"ignoreReferences,omitempty" json:"ignoreReferences,omitempty"` -} - -// ReadListParams defines parameters for ReadList. -type ReadListParams struct { - Id SecurityListsAPIListId `form:"id" json:"id"` -} - -// PatchListJSONBody defines parameters for PatchList. -type PatchListJSONBody struct { - // UnderscoreVersion The version id, normally returned by the API when the document is retrieved. Use it ensure updates are done against the latest version. - UnderscoreVersion *SecurityListsAPIListVersionId `json:"_version,omitempty"` - - // Description Describes the value list. - Description *SecurityListsAPIListDescription `json:"description,omitempty"` - - // Id Value list's identifier. - Id SecurityListsAPIListId `json:"id"` - - // Meta Placeholder for metadata about the value list. - Meta *SecurityListsAPIListMetadata `json:"meta,omitempty"` - - // Name Value list's name. - Name *SecurityListsAPIListName `json:"name,omitempty"` - - // Version The document version number. - Version *SecurityListsAPIListVersion `json:"version,omitempty"` -} - -// CreateListJSONBody defines parameters for CreateList. -type CreateListJSONBody struct { - // Description Describes the value list. - Description SecurityListsAPIListDescription `json:"description"` - - // Deserializer Determines how retrieved list item values are presented. By default list items are presented using these Handelbar expressions: - // - // - `{{{value}}}` - Single value item types, such as `ip`, `long`, `date`, `keyword`, and `text`. - // - `{{{gte}}}-{{{lte}}}` - Range value item types, such as `ip_range`, `double_range`, `float_range`, `integer_range`, and `long_range`. - // - `{{{gte}}},{{{lte}}}` - Date range values. - Deserializer *SecurityListsAPIListDeserializer `json:"deserializer,omitempty"` - - // Id Value list's identifier. - Id *SecurityListsAPIListId `json:"id,omitempty"` - - // Meta Placeholder for metadata about the value list. - Meta *SecurityListsAPIListMetadata `json:"meta,omitempty"` - - // Name Value list's name. - Name SecurityListsAPIListName `json:"name"` - - // Serializer Determines how uploaded list item values are parsed. By default, list items are parsed using these named regex groups: - // - // - `(?.+)` - Single value item types, such as ip, long, date, keyword, and text. - // - `(?.+)-(?.+)|(?.+)` - Range value item types, such as `date_range`, `ip_range`, `double_range`, `float_range`, `integer_range`, and `long_range`. - Serializer *SecurityListsAPIListSerializer `json:"serializer,omitempty"` - - // Type Specifies the Elasticsearch data type of excludes the list container holds. Some common examples: - // - // - `keyword`: Many ECS fields are Elasticsearch keywords - // - `ip`: IP addresses - // - `ip_range`: Range of IP addresses (supports IPv4, IPv6, and CIDR notation) - Type SecurityListsAPIListType `json:"type"` - Version *int `json:"version,omitempty"` -} - -// UpdateListJSONBody defines parameters for UpdateList. -type UpdateListJSONBody struct { - // UnderscoreVersion The version id, normally returned by the API when the document is retrieved. Use it ensure updates are done against the latest version. - UnderscoreVersion *SecurityListsAPIListVersionId `json:"_version,omitempty"` - - // Description Describes the value list. - Description SecurityListsAPIListDescription `json:"description"` - - // Id Value list's identifier. - Id SecurityListsAPIListId `json:"id"` - - // Meta Placeholder for metadata about the value list. - Meta *SecurityListsAPIListMetadata `json:"meta,omitempty"` - - // Name Value list's name. - Name SecurityListsAPIListName `json:"name"` - - // Version The document version number. - Version *SecurityListsAPIListVersion `json:"version,omitempty"` -} - // FindListsParams defines parameters for FindLists. type FindListsParams struct { // Page The page number to return. @@ -46057,6 +45780,283 @@ type ReadRuleParams struct { RuleId *SecurityDetectionsAPIRuleSignatureId `form:"rule_id,omitempty" json:"rule_id,omitempty"` } +// DeleteExceptionListParams defines parameters for DeleteExceptionList. +type DeleteExceptionListParams struct { + // Id Exception list's identifier. Either `id` or `list_id` must be specified. + Id *SecurityExceptionsAPIExceptionListId `form:"id,omitempty" json:"id,omitempty"` + + // ListId Human readable exception list string identifier, e.g. `trusted-linux-processes`. Either `id` or `list_id` must be specified. + ListId *SecurityExceptionsAPIExceptionListHumanId `form:"list_id,omitempty" json:"list_id,omitempty"` + NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `form:"namespace_type,omitempty" json:"namespace_type,omitempty"` +} + +// ReadExceptionListParams defines parameters for ReadExceptionList. +type ReadExceptionListParams struct { + // Id Exception list's identifier. Either `id` or `list_id` must be specified. + Id *SecurityExceptionsAPIExceptionListId `form:"id,omitempty" json:"id,omitempty"` + + // ListId Human readable exception list string identifier, e.g. `trusted-linux-processes`. Either `id` or `list_id` must be specified. + ListId *SecurityExceptionsAPIExceptionListHumanId `form:"list_id,omitempty" json:"list_id,omitempty"` + NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `form:"namespace_type,omitempty" json:"namespace_type,omitempty"` +} + +// CreateExceptionListJSONBody defines parameters for CreateExceptionList. +type CreateExceptionListJSONBody struct { + // Description Describes the exception list. + Description SecurityExceptionsAPIExceptionListDescription `json:"description"` + + // ListId The exception list's human readable string identifier, `endpoint_list`. + ListId *SecurityExceptionsAPIExceptionListHumanId `json:"list_id,omitempty"` + + // Meta Placeholder for metadata about the list container. + Meta *SecurityExceptionsAPIExceptionListMeta `json:"meta,omitempty"` + + // Name The name of the exception list. + Name SecurityExceptionsAPIExceptionListName `json:"name"` + + // NamespaceType Determines whether the exception container is available in all Kibana spaces or just the space + // in which it is created, where: + // + // - `single`: Only available in the Kibana space in which it is created. + // - `agnostic`: Available in all Kibana spaces. + NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `json:"namespace_type,omitempty"` + + // OsTypes Use this field to specify the operating system. Only enter one value. + OsTypes *SecurityExceptionsAPIExceptionListOsTypeArray `json:"os_types,omitempty"` + + // Tags String array containing words and phrases to help categorize exception containers. + Tags *SecurityExceptionsAPIExceptionListTags `json:"tags,omitempty"` + + // Type The type of exception list to be created. Different list types may denote where they can be utilized. + Type SecurityExceptionsAPIExceptionListType `json:"type"` + + // Version The document version, automatically increasd on updates. + Version *SecurityExceptionsAPIExceptionListVersion `json:"version,omitempty"` +} + +// UpdateExceptionListJSONBody defines parameters for UpdateExceptionList. +type UpdateExceptionListJSONBody struct { + // UnderscoreVersion The version id, normally returned by the API when the item was retrieved. Use it ensure updates are done against the latest version. + UnderscoreVersion *string `json:"_version,omitempty"` + + // Description Describes the exception list. + Description SecurityExceptionsAPIExceptionListDescription `json:"description"` + + // Id Exception list's identifier. + Id *SecurityExceptionsAPIExceptionListId `json:"id,omitempty"` + + // ListId The exception list's human readable string identifier, `endpoint_list`. + ListId *SecurityExceptionsAPIExceptionListHumanId `json:"list_id,omitempty"` + + // Meta Placeholder for metadata about the list container. + Meta *SecurityExceptionsAPIExceptionListMeta `json:"meta,omitempty"` + + // Name The name of the exception list. + Name SecurityExceptionsAPIExceptionListName `json:"name"` + + // NamespaceType Determines whether the exception container is available in all Kibana spaces or just the space + // in which it is created, where: + // + // - `single`: Only available in the Kibana space in which it is created. + // - `agnostic`: Available in all Kibana spaces. + NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `json:"namespace_type,omitempty"` + + // OsTypes Use this field to specify the operating system. Only enter one value. + OsTypes *SecurityExceptionsAPIExceptionListOsTypeArray `json:"os_types,omitempty"` + + // Tags String array containing words and phrases to help categorize exception containers. + Tags *SecurityExceptionsAPIExceptionListTags `json:"tags,omitempty"` + + // Type The type of exception list to be created. Different list types may denote where they can be utilized. + Type SecurityExceptionsAPIExceptionListType `json:"type"` + + // Version The document version, automatically increasd on updates. + Version *SecurityExceptionsAPIExceptionListVersion `json:"version,omitempty"` +} + +// DeleteExceptionListItemParams defines parameters for DeleteExceptionListItem. +type DeleteExceptionListItemParams struct { + // Id Exception item's identifier. Either `id` or `item_id` must be specified + Id *SecurityExceptionsAPIExceptionListItemId `form:"id,omitempty" json:"id,omitempty"` + + // ItemId Human readable exception item string identifier, e.g. `trusted-linux-processes`. Either `id` or `item_id` must be specified + ItemId *SecurityExceptionsAPIExceptionListItemHumanId `form:"item_id,omitempty" json:"item_id,omitempty"` + NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `form:"namespace_type,omitempty" json:"namespace_type,omitempty"` +} + +// ReadExceptionListItemParams defines parameters for ReadExceptionListItem. +type ReadExceptionListItemParams struct { + // Id Exception list item's identifier. Either `id` or `item_id` must be specified. + Id *SecurityExceptionsAPIExceptionListItemId `form:"id,omitempty" json:"id,omitempty"` + + // ItemId Human readable exception item string identifier, e.g. `trusted-linux-processes`. Either `id` or `item_id` must be specified. + ItemId *SecurityExceptionsAPIExceptionListItemHumanId `form:"item_id,omitempty" json:"item_id,omitempty"` + NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `form:"namespace_type,omitempty" json:"namespace_type,omitempty"` +} + +// CreateExceptionListItemJSONBody defines parameters for CreateExceptionListItem. +type CreateExceptionListItemJSONBody struct { + Comments *SecurityExceptionsAPICreateExceptionListItemCommentArray `json:"comments,omitempty"` + + // Description Describes the exception list. + Description SecurityExceptionsAPIExceptionListItemDescription `json:"description"` + Entries SecurityExceptionsAPIExceptionListItemEntryArray `json:"entries"` + + // ExpireTime The exception item’s expiration date, in ISO format. This field is only available for regular exception items, not endpoint exceptions. + ExpireTime *SecurityExceptionsAPIExceptionListItemExpireTime `json:"expire_time,omitempty"` + + // ItemId Human readable string identifier, e.g. `trusted-linux-processes` + ItemId *SecurityExceptionsAPIExceptionListItemHumanId `json:"item_id,omitempty"` + + // ListId The exception list's human readable string identifier, `endpoint_list`. + ListId SecurityExceptionsAPIExceptionListHumanId `json:"list_id"` + Meta *SecurityExceptionsAPIExceptionListItemMeta `json:"meta,omitempty"` + + // Name Exception list name. + Name SecurityExceptionsAPIExceptionListItemName `json:"name"` + + // NamespaceType Determines whether the exception container is available in all Kibana spaces or just the space + // in which it is created, where: + // + // - `single`: Only available in the Kibana space in which it is created. + // - `agnostic`: Available in all Kibana spaces. + NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `json:"namespace_type,omitempty"` + OsTypes *SecurityExceptionsAPIExceptionListItemOsTypeArray `json:"os_types,omitempty"` + Tags *SecurityExceptionsAPIExceptionListItemTags `json:"tags,omitempty"` + Type SecurityExceptionsAPIExceptionListItemType `json:"type"` +} + +// UpdateExceptionListItemJSONBody defines parameters for UpdateExceptionListItem. +type UpdateExceptionListItemJSONBody struct { + // UnderscoreVersion The version id, normally returned by the API when the item was retrieved. Use it ensure updates are done against the latest version. + UnderscoreVersion *string `json:"_version,omitempty"` + Comments *SecurityExceptionsAPIUpdateExceptionListItemCommentArray `json:"comments,omitempty"` + + // Description Describes the exception list. + Description SecurityExceptionsAPIExceptionListItemDescription `json:"description"` + Entries SecurityExceptionsAPIExceptionListItemEntryArray `json:"entries"` + + // ExpireTime The exception item’s expiration date, in ISO format. This field is only available for regular exception items, not endpoint exceptions. + ExpireTime *SecurityExceptionsAPIExceptionListItemExpireTime `json:"expire_time,omitempty"` + + // Id Exception's identifier. + Id *SecurityExceptionsAPIExceptionListItemId `json:"id,omitempty"` + + // ItemId Human readable string identifier, e.g. `trusted-linux-processes` + ItemId *SecurityExceptionsAPIExceptionListItemHumanId `json:"item_id,omitempty"` + + // ListId The exception list's human readable string identifier, `endpoint_list`. + ListId *SecurityExceptionsAPIExceptionListHumanId `json:"list_id,omitempty"` + Meta *SecurityExceptionsAPIExceptionListItemMeta `json:"meta,omitempty"` + + // Name Exception list name. + Name SecurityExceptionsAPIExceptionListItemName `json:"name"` + + // NamespaceType Determines whether the exception container is available in all Kibana spaces or just the space + // in which it is created, where: + // + // - `single`: Only available in the Kibana space in which it is created. + // - `agnostic`: Available in all Kibana spaces. + NamespaceType *SecurityExceptionsAPIExceptionNamespaceType `json:"namespace_type,omitempty"` + OsTypes *SecurityExceptionsAPIExceptionListItemOsTypeArray `json:"os_types,omitempty"` + Tags *SecurityExceptionsAPIExceptionListItemTags `json:"tags,omitempty"` + Type SecurityExceptionsAPIExceptionListItemType `json:"type"` +} + +// DeleteListParams defines parameters for DeleteList. +type DeleteListParams struct { + Id SecurityListsAPIListId `form:"id" json:"id"` + + // DeleteReferences Determines whether exception items referencing this value list should be deleted. + DeleteReferences *bool `form:"deleteReferences,omitempty" json:"deleteReferences,omitempty"` + + // IgnoreReferences Determines whether to delete value list without performing any additional checks of where this list may be utilized. + IgnoreReferences *bool `form:"ignoreReferences,omitempty" json:"ignoreReferences,omitempty"` +} + +// ReadListParams defines parameters for ReadList. +type ReadListParams struct { + Id SecurityListsAPIListId `form:"id" json:"id"` +} + +// PatchListJSONBody defines parameters for PatchList. +type PatchListJSONBody struct { + // UnderscoreVersion The version id, normally returned by the API when the document is retrieved. Use it ensure updates are done against the latest version. + UnderscoreVersion *SecurityListsAPIListVersionId `json:"_version,omitempty"` + + // Description Describes the value list. + Description *SecurityListsAPIListDescription `json:"description,omitempty"` + + // Id Value list's identifier. + Id SecurityListsAPIListId `json:"id"` + + // Meta Placeholder for metadata about the value list. + Meta *SecurityListsAPIListMetadata `json:"meta,omitempty"` + + // Name Value list's name. + Name *SecurityListsAPIListName `json:"name,omitempty"` + + // Version The document version number. + Version *SecurityListsAPIListVersion `json:"version,omitempty"` +} + +// CreateListJSONBody defines parameters for CreateList. +type CreateListJSONBody struct { + // Description Describes the value list. + Description SecurityListsAPIListDescription `json:"description"` + + // Deserializer Determines how retrieved list item values are presented. By default list items are presented using these Handelbar expressions: + // + // - `{{{value}}}` - Single value item types, such as `ip`, `long`, `date`, `keyword`, and `text`. + // - `{{{gte}}}-{{{lte}}}` - Range value item types, such as `ip_range`, `double_range`, `float_range`, `integer_range`, and `long_range`. + // - `{{{gte}}},{{{lte}}}` - Date range values. + Deserializer *SecurityListsAPIListDeserializer `json:"deserializer,omitempty"` + + // Id Value list's identifier. + Id *SecurityListsAPIListId `json:"id,omitempty"` + + // Meta Placeholder for metadata about the value list. + Meta *SecurityListsAPIListMetadata `json:"meta,omitempty"` + + // Name Value list's name. + Name SecurityListsAPIListName `json:"name"` + + // Serializer Determines how uploaded list item values are parsed. By default, list items are parsed using these named regex groups: + // + // - `(?.+)` - Single value item types, such as ip, long, date, keyword, and text. + // - `(?.+)-(?.+)|(?.+)` - Range value item types, such as `date_range`, `ip_range`, `double_range`, `float_range`, `integer_range`, and `long_range`. + Serializer *SecurityListsAPIListSerializer `json:"serializer,omitempty"` + + // Type Specifies the Elasticsearch data type of excludes the list container holds. Some common examples: + // + // - `keyword`: Many ECS fields are Elasticsearch keywords + // - `ip`: IP addresses + // - `ip_range`: Range of IP addresses (supports IPv4, IPv6, and CIDR notation) + Type SecurityListsAPIListType `json:"type"` + Version *int `json:"version,omitempty"` +} + +// UpdateListJSONBody defines parameters for UpdateList. +type UpdateListJSONBody struct { + // UnderscoreVersion The version id, normally returned by the API when the document is retrieved. Use it ensure updates are done against the latest version. + UnderscoreVersion *SecurityListsAPIListVersionId `json:"_version,omitempty"` + + // Description Describes the value list. + Description SecurityListsAPIListDescription `json:"description"` + + // Id Value list's identifier. + Id SecurityListsAPIListId `json:"id"` + + // Meta Placeholder for metadata about the value list. + Meta *SecurityListsAPIListMetadata `json:"meta,omitempty"` + + // Name Value list's name. + Name SecurityListsAPIListName `json:"name"` + + // Version The document version number. + Version *SecurityListsAPIListVersion `json:"version,omitempty"` +} + // PostMaintenanceWindowJSONBody defines parameters for PostMaintenanceWindow. type PostMaintenanceWindowJSONBody struct { // Enabled Whether the current maintenance window is enabled. Disabled maintenance windows do not suppress notifications. @@ -46441,21 +46441,9 @@ type DeleteSingleEntityJSONRequestBody DeleteSingleEntityJSONBody // UpsertEntityJSONRequestBody defines body for UpsertEntity for application/json ContentType. type UpsertEntityJSONRequestBody = SecurityEntityAnalyticsAPIEntity -// CreateExceptionListJSONRequestBody defines body for CreateExceptionList for application/json ContentType. -type CreateExceptionListJSONRequestBody CreateExceptionListJSONBody - -// UpdateExceptionListJSONRequestBody defines body for UpdateExceptionList for application/json ContentType. -type UpdateExceptionListJSONRequestBody UpdateExceptionListJSONBody - // ImportExceptionListMultipartRequestBody defines body for ImportExceptionList for multipart/form-data ContentType. type ImportExceptionListMultipartRequestBody ImportExceptionListMultipartBody -// CreateExceptionListItemJSONRequestBody defines body for CreateExceptionListItem for application/json ContentType. -type CreateExceptionListItemJSONRequestBody CreateExceptionListItemJSONBody - -// UpdateExceptionListItemJSONRequestBody defines body for UpdateExceptionListItem for application/json ContentType. -type UpdateExceptionListItemJSONRequestBody UpdateExceptionListItemJSONBody - // CreateSharedExceptionListJSONRequestBody defines body for CreateSharedExceptionList for application/json ContentType. type CreateSharedExceptionListJSONRequestBody CreateSharedExceptionListJSONBody @@ -46621,15 +46609,6 @@ type PutFleetSettingsJSONRequestBody PutFleetSettingsJSONBody // PutFleetSpaceSettingsJSONRequestBody defines body for PutFleetSpaceSettings for application/json ContentType. type PutFleetSpaceSettingsJSONRequestBody PutFleetSpaceSettingsJSONBody -// PatchListJSONRequestBody defines body for PatchList for application/json ContentType. -type PatchListJSONRequestBody PatchListJSONBody - -// CreateListJSONRequestBody defines body for CreateList for application/json ContentType. -type CreateListJSONRequestBody CreateListJSONBody - -// UpdateListJSONRequestBody defines body for UpdateList for application/json ContentType. -type UpdateListJSONRequestBody UpdateListJSONBody - // PatchListItemJSONRequestBody defines body for PatchListItem for application/json ContentType. type PatchListItemJSONRequestBody PatchListItemJSONBody @@ -46933,6 +46912,27 @@ type CreateRuleJSONRequestBody = SecurityDetectionsAPIRuleCreateProps // UpdateRuleJSONRequestBody defines body for UpdateRule for application/json ContentType. type UpdateRuleJSONRequestBody = SecurityDetectionsAPIRuleUpdateProps +// CreateExceptionListJSONRequestBody defines body for CreateExceptionList for application/json ContentType. +type CreateExceptionListJSONRequestBody CreateExceptionListJSONBody + +// UpdateExceptionListJSONRequestBody defines body for UpdateExceptionList for application/json ContentType. +type UpdateExceptionListJSONRequestBody UpdateExceptionListJSONBody + +// CreateExceptionListItemJSONRequestBody defines body for CreateExceptionListItem for application/json ContentType. +type CreateExceptionListItemJSONRequestBody CreateExceptionListItemJSONBody + +// UpdateExceptionListItemJSONRequestBody defines body for UpdateExceptionListItem for application/json ContentType. +type UpdateExceptionListItemJSONRequestBody UpdateExceptionListItemJSONBody + +// PatchListJSONRequestBody defines body for PatchList for application/json ContentType. +type PatchListJSONRequestBody PatchListJSONBody + +// CreateListJSONRequestBody defines body for CreateList for application/json ContentType. +type CreateListJSONRequestBody CreateListJSONBody + +// UpdateListJSONRequestBody defines body for UpdateList for application/json ContentType. +type UpdateListJSONRequestBody UpdateListJSONBody + // PostMaintenanceWindowJSONRequestBody defines body for PostMaintenanceWindow for application/json ContentType. type PostMaintenanceWindowJSONRequestBody PostMaintenanceWindowJSONBody @@ -59445,7 +59445,7 @@ func (t SLOsIndicatorPropertiesTimesliceMetric_Params_Metric_Metrics_Item) AsSLO // FromSLOsTimesliceMetricBasicMetricWithField overwrites any union data inside the SLOsIndicatorPropertiesTimesliceMetric_Params_Metric_Metrics_Item as the provided SLOsTimesliceMetricBasicMetricWithField func (t *SLOsIndicatorPropertiesTimesliceMetric_Params_Metric_Metrics_Item) FromSLOsTimesliceMetricBasicMetricWithField(v SLOsTimesliceMetricBasicMetricWithField) error { - v.Aggregation = "avg" + v.Aggregation = "cardinality" b, err := json.Marshal(v) t.union = b return err @@ -59453,7 +59453,7 @@ func (t *SLOsIndicatorPropertiesTimesliceMetric_Params_Metric_Metrics_Item) From // MergeSLOsTimesliceMetricBasicMetricWithField performs a merge with any union data inside the SLOsIndicatorPropertiesTimesliceMetric_Params_Metric_Metrics_Item, using the provided SLOsTimesliceMetricBasicMetricWithField func (t *SLOsIndicatorPropertiesTimesliceMetric_Params_Metric_Metrics_Item) MergeSLOsTimesliceMetricBasicMetricWithField(v SLOsTimesliceMetricBasicMetricWithField) error { - v.Aggregation = "avg" + v.Aggregation = "cardinality" b, err := json.Marshal(v) if err != nil { return err @@ -59534,7 +59534,7 @@ func (t SLOsIndicatorPropertiesTimesliceMetric_Params_Metric_Metrics_Item) Value return nil, err } switch discriminator { - case "avg": + case "cardinality": return t.AsSLOsTimesliceMetricBasicMetricWithField() case "doc_count": return t.AsSLOsTimesliceMetricDocCountMetric() @@ -74101,22 +74101,6 @@ type ClientInterface interface { // GetEntityStoreStatus request GetEntityStoreStatus(ctx context.Context, params *GetEntityStoreStatusParams, reqEditors ...RequestEditorFn) (*http.Response, error) - // DeleteExceptionList request - DeleteExceptionList(ctx context.Context, params *DeleteExceptionListParams, reqEditors ...RequestEditorFn) (*http.Response, error) - - // ReadExceptionList request - ReadExceptionList(ctx context.Context, params *ReadExceptionListParams, reqEditors ...RequestEditorFn) (*http.Response, error) - - // CreateExceptionListWithBody request with any body - CreateExceptionListWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - CreateExceptionList(ctx context.Context, body CreateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - - // UpdateExceptionListWithBody request with any body - UpdateExceptionListWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - UpdateExceptionList(ctx context.Context, body UpdateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - // DuplicateExceptionList request DuplicateExceptionList(ctx context.Context, params *DuplicateExceptionListParams, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -74129,22 +74113,6 @@ type ClientInterface interface { // ImportExceptionListWithBody request with any body ImportExceptionListWithBody(ctx context.Context, params *ImportExceptionListParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - // DeleteExceptionListItem request - DeleteExceptionListItem(ctx context.Context, params *DeleteExceptionListItemParams, reqEditors ...RequestEditorFn) (*http.Response, error) - - // ReadExceptionListItem request - ReadExceptionListItem(ctx context.Context, params *ReadExceptionListItemParams, reqEditors ...RequestEditorFn) (*http.Response, error) - - // CreateExceptionListItemWithBody request with any body - CreateExceptionListItemWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - CreateExceptionListItem(ctx context.Context, body CreateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - - // UpdateExceptionListItemWithBody request with any body - UpdateExceptionListItemWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - UpdateExceptionListItem(ctx context.Context, body UpdateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - // FindExceptionListItems request FindExceptionListItems(ctx context.Context, params *FindExceptionListItemsParams, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -74651,39 +74619,9 @@ type ClientInterface interface { // GetFleetUninstallTokensUninstalltokenid request GetFleetUninstallTokensUninstalltokenid(ctx context.Context, uninstallTokenId string, reqEditors ...RequestEditorFn) (*http.Response, error) - // DeleteList request - DeleteList(ctx context.Context, params *DeleteListParams, reqEditors ...RequestEditorFn) (*http.Response, error) - - // ReadList request - ReadList(ctx context.Context, params *ReadListParams, reqEditors ...RequestEditorFn) (*http.Response, error) - - // PatchListWithBody request with any body - PatchListWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - PatchList(ctx context.Context, body PatchListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - - // CreateListWithBody request with any body - CreateListWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - CreateList(ctx context.Context, body CreateListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - - // UpdateListWithBody request with any body - UpdateListWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - UpdateList(ctx context.Context, body UpdateListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - // FindLists request FindLists(ctx context.Context, params *FindListsParams, reqEditors ...RequestEditorFn) (*http.Response, error) - // DeleteListIndex request - DeleteListIndex(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) - - // ReadListIndex request - ReadListIndex(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) - - // CreateListIndex request - CreateListIndex(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) - // DeleteListItem request DeleteListItem(ctx context.Context, params *DeleteListItemParams, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -75394,6 +75332,68 @@ type ClientInterface interface { UpdateRule(ctx context.Context, spaceId SpaceId, body UpdateRuleJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // DeleteExceptionList request + DeleteExceptionList(ctx context.Context, spaceId SpaceId, params *DeleteExceptionListParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // ReadExceptionList request + ReadExceptionList(ctx context.Context, spaceId SpaceId, params *ReadExceptionListParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateExceptionListWithBody request with any body + CreateExceptionListWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateExceptionList(ctx context.Context, spaceId SpaceId, body CreateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // UpdateExceptionListWithBody request with any body + UpdateExceptionListWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + UpdateExceptionList(ctx context.Context, spaceId SpaceId, body UpdateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteExceptionListItem request + DeleteExceptionListItem(ctx context.Context, spaceId SpaceId, params *DeleteExceptionListItemParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // ReadExceptionListItem request + ReadExceptionListItem(ctx context.Context, spaceId SpaceId, params *ReadExceptionListItemParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateExceptionListItemWithBody request with any body + CreateExceptionListItemWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateExceptionListItem(ctx context.Context, spaceId SpaceId, body CreateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // UpdateExceptionListItemWithBody request with any body + UpdateExceptionListItemWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + UpdateExceptionListItem(ctx context.Context, spaceId SpaceId, body UpdateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteList request + DeleteList(ctx context.Context, spaceId SpaceId, params *DeleteListParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // ReadList request + ReadList(ctx context.Context, spaceId SpaceId, params *ReadListParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // PatchListWithBody request with any body + PatchListWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PatchList(ctx context.Context, spaceId SpaceId, body PatchListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateListWithBody request with any body + CreateListWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + CreateList(ctx context.Context, spaceId SpaceId, body CreateListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // UpdateListWithBody request with any body + UpdateListWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + UpdateList(ctx context.Context, spaceId SpaceId, body UpdateListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DeleteListIndex request + DeleteListIndex(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*http.Response, error) + + // ReadListIndex request + ReadListIndex(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*http.Response, error) + + // CreateListIndex request + CreateListIndex(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*http.Response, error) + // PostMaintenanceWindowWithBody request with any body PostMaintenanceWindowWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -78436,78 +78436,6 @@ func (c *Client) GetEntityStoreStatus(ctx context.Context, params *GetEntityStor return c.Client.Do(req) } -func (c *Client) DeleteExceptionList(ctx context.Context, params *DeleteExceptionListParams, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDeleteExceptionListRequest(c.Server, params) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) ReadExceptionList(ctx context.Context, params *ReadExceptionListParams, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewReadExceptionListRequest(c.Server, params) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) CreateExceptionListWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewCreateExceptionListRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) CreateExceptionList(ctx context.Context, body CreateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewCreateExceptionListRequest(c.Server, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) UpdateExceptionListWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewUpdateExceptionListRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) UpdateExceptionList(ctx context.Context, body UpdateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewUpdateExceptionListRequest(c.Server, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - func (c *Client) DuplicateExceptionList(ctx context.Context, params *DuplicateExceptionListParams, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewDuplicateExceptionListRequest(c.Server, params) if err != nil { @@ -78556,78 +78484,6 @@ func (c *Client) ImportExceptionListWithBody(ctx context.Context, params *Import return c.Client.Do(req) } -func (c *Client) DeleteExceptionListItem(ctx context.Context, params *DeleteExceptionListItemParams, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDeleteExceptionListItemRequest(c.Server, params) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) ReadExceptionListItem(ctx context.Context, params *ReadExceptionListItemParams, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewReadExceptionListItemRequest(c.Server, params) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) CreateExceptionListItemWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewCreateExceptionListItemRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) CreateExceptionListItem(ctx context.Context, body CreateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewCreateExceptionListItemRequest(c.Server, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) UpdateExceptionListItemWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewUpdateExceptionListItemRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) UpdateExceptionListItem(ctx context.Context, body UpdateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewUpdateExceptionListItemRequest(c.Server, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - func (c *Client) FindExceptionListItems(ctx context.Context, params *FindExceptionListItemsParams, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewFindExceptionListItemsRequest(c.Server, params) if err != nil { @@ -80872,102 +80728,6 @@ func (c *Client) GetFleetUninstallTokensUninstalltokenid(ctx context.Context, un return c.Client.Do(req) } -func (c *Client) DeleteList(ctx context.Context, params *DeleteListParams, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDeleteListRequest(c.Server, params) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) ReadList(ctx context.Context, params *ReadListParams, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewReadListRequest(c.Server, params) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) PatchListWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewPatchListRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) PatchList(ctx context.Context, body PatchListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewPatchListRequest(c.Server, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) CreateListWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewCreateListRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) CreateList(ctx context.Context, body CreateListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewCreateListRequest(c.Server, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) UpdateListWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewUpdateListRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) UpdateList(ctx context.Context, body UpdateListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewUpdateListRequest(c.Server, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - func (c *Client) FindLists(ctx context.Context, params *FindListsParams, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewFindListsRequest(c.Server, params) if err != nil { @@ -80980,42 +80740,6 @@ func (c *Client) FindLists(ctx context.Context, params *FindListsParams, reqEdit return c.Client.Do(req) } -func (c *Client) DeleteListIndex(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDeleteListIndexRequest(c.Server) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) ReadListIndex(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewReadListIndexRequest(c.Server) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) CreateListIndex(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewCreateListIndexRequest(c.Server) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - func (c *Client) DeleteListItem(ctx context.Context, params *DeleteListItemParams, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewDeleteListItemRequest(c.Server, params) if err != nil { @@ -84244,6 +83968,282 @@ func (c *Client) UpdateRule(ctx context.Context, spaceId SpaceId, body UpdateRul return c.Client.Do(req) } +func (c *Client) DeleteExceptionList(ctx context.Context, spaceId SpaceId, params *DeleteExceptionListParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteExceptionListRequest(c.Server, spaceId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) ReadExceptionList(ctx context.Context, spaceId SpaceId, params *ReadExceptionListParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewReadExceptionListRequest(c.Server, spaceId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateExceptionListWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateExceptionListRequestWithBody(c.Server, spaceId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateExceptionList(ctx context.Context, spaceId SpaceId, body CreateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateExceptionListRequest(c.Server, spaceId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateExceptionListWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateExceptionListRequestWithBody(c.Server, spaceId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateExceptionList(ctx context.Context, spaceId SpaceId, body UpdateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateExceptionListRequest(c.Server, spaceId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteExceptionListItem(ctx context.Context, spaceId SpaceId, params *DeleteExceptionListItemParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteExceptionListItemRequest(c.Server, spaceId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) ReadExceptionListItem(ctx context.Context, spaceId SpaceId, params *ReadExceptionListItemParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewReadExceptionListItemRequest(c.Server, spaceId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateExceptionListItemWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateExceptionListItemRequestWithBody(c.Server, spaceId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateExceptionListItem(ctx context.Context, spaceId SpaceId, body CreateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateExceptionListItemRequest(c.Server, spaceId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateExceptionListItemWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateExceptionListItemRequestWithBody(c.Server, spaceId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateExceptionListItem(ctx context.Context, spaceId SpaceId, body UpdateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateExceptionListItemRequest(c.Server, spaceId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteList(ctx context.Context, spaceId SpaceId, params *DeleteListParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteListRequest(c.Server, spaceId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) ReadList(ctx context.Context, spaceId SpaceId, params *ReadListParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewReadListRequest(c.Server, spaceId, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) PatchListWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPatchListRequestWithBody(c.Server, spaceId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) PatchList(ctx context.Context, spaceId SpaceId, body PatchListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPatchListRequest(c.Server, spaceId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateListWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateListRequestWithBody(c.Server, spaceId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateList(ctx context.Context, spaceId SpaceId, body CreateListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateListRequest(c.Server, spaceId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateListWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateListRequestWithBody(c.Server, spaceId, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) UpdateList(ctx context.Context, spaceId SpaceId, body UpdateListJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewUpdateListRequest(c.Server, spaceId, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) DeleteListIndex(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDeleteListIndexRequest(c.Server, spaceId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) ReadListIndex(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewReadListIndexRequest(c.Server, spaceId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) CreateListIndex(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewCreateListIndexRequest(c.Server, spaceId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) PostMaintenanceWindowWithBody(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewPostMaintenanceWindowRequestWithBody(c.Server, spaceId, contentType, body) if err != nil { @@ -93500,8 +93500,8 @@ func NewGetEntityStoreStatusRequest(server string, params *GetEntityStoreStatusP return req, nil } -// NewDeleteExceptionListRequest generates requests for DeleteExceptionList -func NewDeleteExceptionListRequest(server string, params *DeleteExceptionListParams) (*http.Request, error) { +// NewDuplicateExceptionListRequest generates requests for DuplicateExceptionList +func NewDuplicateExceptionListRequest(server string, params *DuplicateExceptionListParams) (*http.Request, error) { var err error serverURL, err := url.Parse(server) @@ -93509,7 +93509,7 @@ func NewDeleteExceptionListRequest(server string, params *DeleteExceptionListPar return nil, err } - operationPath := fmt.Sprintf("/api/exception_lists") + operationPath := fmt.Sprintf("/api/exception_lists/_duplicate") if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -93522,58 +93522,46 @@ func NewDeleteExceptionListRequest(server string, params *DeleteExceptionListPar if params != nil { queryValues := queryURL.Query() - if params.Id != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, *params.Id); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "list_id", runtime.ParamLocationQuery, params.ListId); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) } } - } - if params.ListId != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "list_id", runtime.ParamLocationQuery, *params.ListId); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "namespace_type", runtime.ParamLocationQuery, params.NamespaceType); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) } } - } - if params.NamespaceType != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "namespace_type", runtime.ParamLocationQuery, *params.NamespaceType); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "include_expired_exceptions", runtime.ParamLocationQuery, params.IncludeExpiredExceptions); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) } } - } queryURL.RawQuery = queryValues.Encode() } - req, err := http.NewRequest("DELETE", queryURL.String(), nil) + req, err := http.NewRequest("POST", queryURL.String(), nil) if err != nil { return nil, err } @@ -93581,8 +93569,8 @@ func NewDeleteExceptionListRequest(server string, params *DeleteExceptionListPar return req, nil } -// NewReadExceptionListRequest generates requests for ReadExceptionList -func NewReadExceptionListRequest(server string, params *ReadExceptionListParams) (*http.Request, error) { +// NewExportExceptionListRequest generates requests for ExportExceptionList +func NewExportExceptionListRequest(server string, params *ExportExceptionListParams) (*http.Request, error) { var err error serverURL, err := url.Parse(server) @@ -93590,7 +93578,7 @@ func NewReadExceptionListRequest(server string, params *ReadExceptionListParams) return nil, err } - operationPath := fmt.Sprintf("/api/exception_lists") + operationPath := fmt.Sprintf("/api/exception_lists/_export") if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -93603,320 +93591,90 @@ func NewReadExceptionListRequest(server string, params *ReadExceptionListParams) if params != nil { queryValues := queryURL.Query() - if params.Id != nil { + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, params.Id); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, *params.Id); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "list_id", runtime.ParamLocationQuery, params.ListId); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) } } + } + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "namespace_type", runtime.ParamLocationQuery, params.NamespaceType); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } } - if params.ListId != nil { + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "include_expired_exceptions", runtime.ParamLocationQuery, params.IncludeExpiredExceptions); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "list_id", runtime.ParamLocationQuery, *params.ListId); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - } - - if params.NamespaceType != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "namespace_type", runtime.ParamLocationQuery, *params.NamespaceType); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - } - - queryURL.RawQuery = queryValues.Encode() - } - - req, err := http.NewRequest("GET", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewCreateExceptionListRequest calls the generic CreateExceptionList builder with application/json body -func NewCreateExceptionListRequest(server string, body CreateExceptionListJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewCreateExceptionListRequestWithBody(server, "application/json", bodyReader) -} - -// NewCreateExceptionListRequestWithBody generates requests for CreateExceptionList with any type of body -func NewCreateExceptionListRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/exception_lists") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewUpdateExceptionListRequest calls the generic UpdateExceptionList builder with application/json body -func NewUpdateExceptionListRequest(server string, body UpdateExceptionListJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewUpdateExceptionListRequestWithBody(server, "application/json", bodyReader) -} - -// NewUpdateExceptionListRequestWithBody generates requests for UpdateExceptionList with any type of body -func NewUpdateExceptionListRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/exception_lists") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("PUT", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewDuplicateExceptionListRequest generates requests for DuplicateExceptionList -func NewDuplicateExceptionListRequest(server string, params *DuplicateExceptionListParams) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/exception_lists/_duplicate") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - if params != nil { - queryValues := queryURL.Query() - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "list_id", runtime.ParamLocationQuery, params.ListId); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "namespace_type", runtime.ParamLocationQuery, params.NamespaceType); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "include_expired_exceptions", runtime.ParamLocationQuery, params.IncludeExpiredExceptions); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - queryURL.RawQuery = queryValues.Encode() - } - - req, err := http.NewRequest("POST", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewExportExceptionListRequest generates requests for ExportExceptionList -func NewExportExceptionListRequest(server string, params *ExportExceptionListParams) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/exception_lists/_export") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - if params != nil { - queryValues := queryURL.Query() - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, params.Id); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "list_id", runtime.ParamLocationQuery, params.ListId); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "namespace_type", runtime.ParamLocationQuery, params.NamespaceType); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "include_expired_exceptions", runtime.ParamLocationQuery, params.IncludeExpiredExceptions); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - queryURL.RawQuery = queryValues.Encode() - } - - req, err := http.NewRequest("POST", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewFindExceptionListsRequest generates requests for FindExceptionLists -func NewFindExceptionListsRequest(server string, params *FindExceptionListsParams) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/exception_lists/_find") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - if params != nil { - queryValues := queryURL.Query() - - if params.Filter != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "filter", runtime.ParamLocationQuery, *params.Filter); err != nil { + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("POST", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewFindExceptionListsRequest generates requests for FindExceptionLists +func NewFindExceptionListsRequest(server string, params *FindExceptionListsParams) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/api/exception_lists/_find") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Filter != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "filter", runtime.ParamLocationQuery, *params.Filter); err != nil { return nil, err } else if parsed, err := url.ParseQuery(queryFrag); err != nil { return nil, err @@ -94088,248 +93846,6 @@ func NewImportExceptionListRequestWithBody(server string, params *ImportExceptio return req, nil } -// NewDeleteExceptionListItemRequest generates requests for DeleteExceptionListItem -func NewDeleteExceptionListItemRequest(server string, params *DeleteExceptionListItemParams) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/exception_lists/items") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - if params != nil { - queryValues := queryURL.Query() - - if params.Id != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, *params.Id); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - } - - if params.ItemId != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "item_id", runtime.ParamLocationQuery, *params.ItemId); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - } - - if params.NamespaceType != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "namespace_type", runtime.ParamLocationQuery, *params.NamespaceType); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - } - - queryURL.RawQuery = queryValues.Encode() - } - - req, err := http.NewRequest("DELETE", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewReadExceptionListItemRequest generates requests for ReadExceptionListItem -func NewReadExceptionListItemRequest(server string, params *ReadExceptionListItemParams) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/exception_lists/items") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - if params != nil { - queryValues := queryURL.Query() - - if params.Id != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, *params.Id); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - } - - if params.ItemId != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "item_id", runtime.ParamLocationQuery, *params.ItemId); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - } - - if params.NamespaceType != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "namespace_type", runtime.ParamLocationQuery, *params.NamespaceType); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - } - - queryURL.RawQuery = queryValues.Encode() - } - - req, err := http.NewRequest("GET", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewCreateExceptionListItemRequest calls the generic CreateExceptionListItem builder with application/json body -func NewCreateExceptionListItemRequest(server string, body CreateExceptionListItemJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewCreateExceptionListItemRequestWithBody(server, "application/json", bodyReader) -} - -// NewCreateExceptionListItemRequestWithBody generates requests for CreateExceptionListItem with any type of body -func NewCreateExceptionListItemRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/exception_lists/items") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewUpdateExceptionListItemRequest calls the generic UpdateExceptionListItem builder with application/json body -func NewUpdateExceptionListItemRequest(server string, body UpdateExceptionListItemJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewUpdateExceptionListItemRequestWithBody(server, "application/json", bodyReader) -} - -// NewUpdateExceptionListItemRequestWithBody generates requests for UpdateExceptionListItem with any type of body -func NewUpdateExceptionListItemRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/exception_lists/items") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("PUT", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - // NewFindExceptionListItemsRequest generates requests for FindExceptionListItems func NewFindExceptionListItemsRequest(server string, params *FindExceptionListItemsParams) (*http.Request, error) { var err error @@ -101429,248 +100945,6 @@ func NewGetFleetUninstallTokensUninstalltokenidRequest(server string, uninstallT return req, nil } -// NewDeleteListRequest generates requests for DeleteList -func NewDeleteListRequest(server string, params *DeleteListParams) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/lists") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - if params != nil { - queryValues := queryURL.Query() - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, params.Id); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - if params.DeleteReferences != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "deleteReferences", runtime.ParamLocationQuery, *params.DeleteReferences); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - } - - if params.IgnoreReferences != nil { - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "ignoreReferences", runtime.ParamLocationQuery, *params.IgnoreReferences); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - } - - queryURL.RawQuery = queryValues.Encode() - } - - req, err := http.NewRequest("DELETE", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewReadListRequest generates requests for ReadList -func NewReadListRequest(server string, params *ReadListParams) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/lists") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - if params != nil { - queryValues := queryURL.Query() - - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, params.Id); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - - queryURL.RawQuery = queryValues.Encode() - } - - req, err := http.NewRequest("GET", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewPatchListRequest calls the generic PatchList builder with application/json body -func NewPatchListRequest(server string, body PatchListJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewPatchListRequestWithBody(server, "application/json", bodyReader) -} - -// NewPatchListRequestWithBody generates requests for PatchList with any type of body -func NewPatchListRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/lists") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("PATCH", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewCreateListRequest calls the generic CreateList builder with application/json body -func NewCreateListRequest(server string, body CreateListJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewCreateListRequestWithBody(server, "application/json", bodyReader) -} - -// NewCreateListRequestWithBody generates requests for CreateList with any type of body -func NewCreateListRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/lists") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewUpdateListRequest calls the generic UpdateList builder with application/json body -func NewUpdateListRequest(server string, body UpdateListJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewUpdateListRequestWithBody(server, "application/json", bodyReader) -} - -// NewUpdateListRequestWithBody generates requests for UpdateList with any type of body -func NewUpdateListRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/lists") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("PUT", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - // NewFindListsRequest generates requests for FindLists func NewFindListsRequest(server string, params *FindListsParams) (*http.Request, error) { var err error @@ -101800,87 +101074,6 @@ func NewFindListsRequest(server string, params *FindListsParams) (*http.Request, return req, nil } -// NewDeleteListIndexRequest generates requests for DeleteListIndex -func NewDeleteListIndexRequest(server string) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/lists/index") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("DELETE", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewReadListIndexRequest generates requests for ReadListIndex -func NewReadListIndexRequest(server string) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/lists/index") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("GET", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewCreateListIndexRequest generates requests for CreateListIndex -func NewCreateListIndexRequest(server string) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/api/lists/index") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - // NewDeleteListItemRequest generates requests for DeleteListItem func NewDeleteListItemRequest(server string, params *DeleteListItemParams) (*http.Request, error) { var err error @@ -111158,6 +110351,925 @@ func NewUpdateRuleRequestWithBody(server string, spaceId SpaceId, contentType st return req, nil } +// NewDeleteExceptionListRequest generates requests for DeleteExceptionList +func NewDeleteExceptionListRequest(server string, spaceId SpaceId, params *DeleteExceptionListParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/exception_lists", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Id != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, *params.Id); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.ListId != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "list_id", runtime.ParamLocationQuery, *params.ListId); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.NamespaceType != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "namespace_type", runtime.ParamLocationQuery, *params.NamespaceType); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewReadExceptionListRequest generates requests for ReadExceptionList +func NewReadExceptionListRequest(server string, spaceId SpaceId, params *ReadExceptionListParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/exception_lists", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Id != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, *params.Id); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.ListId != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "list_id", runtime.ParamLocationQuery, *params.ListId); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.NamespaceType != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "namespace_type", runtime.ParamLocationQuery, *params.NamespaceType); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateExceptionListRequest calls the generic CreateExceptionList builder with application/json body +func NewCreateExceptionListRequest(server string, spaceId SpaceId, body CreateExceptionListJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateExceptionListRequestWithBody(server, spaceId, "application/json", bodyReader) +} + +// NewCreateExceptionListRequestWithBody generates requests for CreateExceptionList with any type of body +func NewCreateExceptionListRequestWithBody(server string, spaceId SpaceId, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/exception_lists", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewUpdateExceptionListRequest calls the generic UpdateExceptionList builder with application/json body +func NewUpdateExceptionListRequest(server string, spaceId SpaceId, body UpdateExceptionListJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewUpdateExceptionListRequestWithBody(server, spaceId, "application/json", bodyReader) +} + +// NewUpdateExceptionListRequestWithBody generates requests for UpdateExceptionList with any type of body +func NewUpdateExceptionListRequestWithBody(server string, spaceId SpaceId, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/exception_lists", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewDeleteExceptionListItemRequest generates requests for DeleteExceptionListItem +func NewDeleteExceptionListItemRequest(server string, spaceId SpaceId, params *DeleteExceptionListItemParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/exception_lists/items", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Id != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, *params.Id); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.ItemId != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "item_id", runtime.ParamLocationQuery, *params.ItemId); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.NamespaceType != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "namespace_type", runtime.ParamLocationQuery, *params.NamespaceType); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewReadExceptionListItemRequest generates requests for ReadExceptionListItem +func NewReadExceptionListItemRequest(server string, spaceId SpaceId, params *ReadExceptionListItemParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/exception_lists/items", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Id != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, *params.Id); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.ItemId != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "item_id", runtime.ParamLocationQuery, *params.ItemId); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.NamespaceType != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "namespace_type", runtime.ParamLocationQuery, *params.NamespaceType); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateExceptionListItemRequest calls the generic CreateExceptionListItem builder with application/json body +func NewCreateExceptionListItemRequest(server string, spaceId SpaceId, body CreateExceptionListItemJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateExceptionListItemRequestWithBody(server, spaceId, "application/json", bodyReader) +} + +// NewCreateExceptionListItemRequestWithBody generates requests for CreateExceptionListItem with any type of body +func NewCreateExceptionListItemRequestWithBody(server string, spaceId SpaceId, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/exception_lists/items", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewUpdateExceptionListItemRequest calls the generic UpdateExceptionListItem builder with application/json body +func NewUpdateExceptionListItemRequest(server string, spaceId SpaceId, body UpdateExceptionListItemJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewUpdateExceptionListItemRequestWithBody(server, spaceId, "application/json", bodyReader) +} + +// NewUpdateExceptionListItemRequestWithBody generates requests for UpdateExceptionListItem with any type of body +func NewUpdateExceptionListItemRequestWithBody(server string, spaceId SpaceId, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/exception_lists/items", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewDeleteListRequest generates requests for DeleteList +func NewDeleteListRequest(server string, spaceId SpaceId, params *DeleteListParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/lists", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, params.Id); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + if params.DeleteReferences != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "deleteReferences", runtime.ParamLocationQuery, *params.DeleteReferences); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.IgnoreReferences != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "ignoreReferences", runtime.ParamLocationQuery, *params.IgnoreReferences); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewReadListRequest generates requests for ReadList +func NewReadListRequest(server string, spaceId SpaceId, params *ReadListParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/lists", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "id", runtime.ParamLocationQuery, params.Id); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewPatchListRequest calls the generic PatchList builder with application/json body +func NewPatchListRequest(server string, spaceId SpaceId, body PatchListJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPatchListRequestWithBody(server, spaceId, "application/json", bodyReader) +} + +// NewPatchListRequestWithBody generates requests for PatchList with any type of body +func NewPatchListRequestWithBody(server string, spaceId SpaceId, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/lists", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PATCH", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewCreateListRequest calls the generic CreateList builder with application/json body +func NewCreateListRequest(server string, spaceId SpaceId, body CreateListJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewCreateListRequestWithBody(server, spaceId, "application/json", bodyReader) +} + +// NewCreateListRequestWithBody generates requests for CreateList with any type of body +func NewCreateListRequestWithBody(server string, spaceId SpaceId, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/lists", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewUpdateListRequest calls the generic UpdateList builder with application/json body +func NewUpdateListRequest(server string, spaceId SpaceId, body UpdateListJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewUpdateListRequestWithBody(server, spaceId, "application/json", bodyReader) +} + +// NewUpdateListRequestWithBody generates requests for UpdateList with any type of body +func NewUpdateListRequestWithBody(server string, spaceId SpaceId, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/lists", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewDeleteListIndexRequest generates requests for DeleteListIndex +func NewDeleteListIndexRequest(server string, spaceId SpaceId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/lists/index", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewReadListIndexRequest generates requests for ReadListIndex +func NewReadListIndexRequest(server string, spaceId SpaceId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/lists/index", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewCreateListIndexRequest generates requests for CreateListIndex +func NewCreateListIndexRequest(server string, spaceId SpaceId) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "spaceId", runtime.ParamLocationPath, spaceId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/s/%s/api/lists/index", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + // NewPostMaintenanceWindowRequest calls the generic PostMaintenanceWindow builder with application/json body func NewPostMaintenanceWindowRequest(server string, spaceId SpaceId, body PostMaintenanceWindowJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader @@ -112871,22 +112983,6 @@ type ClientWithResponsesInterface interface { // GetEntityStoreStatusWithResponse request GetEntityStoreStatusWithResponse(ctx context.Context, params *GetEntityStoreStatusParams, reqEditors ...RequestEditorFn) (*GetEntityStoreStatusResponse, error) - // DeleteExceptionListWithResponse request - DeleteExceptionListWithResponse(ctx context.Context, params *DeleteExceptionListParams, reqEditors ...RequestEditorFn) (*DeleteExceptionListResponse, error) - - // ReadExceptionListWithResponse request - ReadExceptionListWithResponse(ctx context.Context, params *ReadExceptionListParams, reqEditors ...RequestEditorFn) (*ReadExceptionListResponse, error) - - // CreateExceptionListWithBodyWithResponse request with any body - CreateExceptionListWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateExceptionListResponse, error) - - CreateExceptionListWithResponse(ctx context.Context, body CreateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateExceptionListResponse, error) - - // UpdateExceptionListWithBodyWithResponse request with any body - UpdateExceptionListWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateExceptionListResponse, error) - - UpdateExceptionListWithResponse(ctx context.Context, body UpdateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateExceptionListResponse, error) - // DuplicateExceptionListWithResponse request DuplicateExceptionListWithResponse(ctx context.Context, params *DuplicateExceptionListParams, reqEditors ...RequestEditorFn) (*DuplicateExceptionListResponse, error) @@ -112899,22 +112995,6 @@ type ClientWithResponsesInterface interface { // ImportExceptionListWithBodyWithResponse request with any body ImportExceptionListWithBodyWithResponse(ctx context.Context, params *ImportExceptionListParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ImportExceptionListResponse, error) - // DeleteExceptionListItemWithResponse request - DeleteExceptionListItemWithResponse(ctx context.Context, params *DeleteExceptionListItemParams, reqEditors ...RequestEditorFn) (*DeleteExceptionListItemResponse, error) - - // ReadExceptionListItemWithResponse request - ReadExceptionListItemWithResponse(ctx context.Context, params *ReadExceptionListItemParams, reqEditors ...RequestEditorFn) (*ReadExceptionListItemResponse, error) - - // CreateExceptionListItemWithBodyWithResponse request with any body - CreateExceptionListItemWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateExceptionListItemResponse, error) - - CreateExceptionListItemWithResponse(ctx context.Context, body CreateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateExceptionListItemResponse, error) - - // UpdateExceptionListItemWithBodyWithResponse request with any body - UpdateExceptionListItemWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateExceptionListItemResponse, error) - - UpdateExceptionListItemWithResponse(ctx context.Context, body UpdateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateExceptionListItemResponse, error) - // FindExceptionListItemsWithResponse request FindExceptionListItemsWithResponse(ctx context.Context, params *FindExceptionListItemsParams, reqEditors ...RequestEditorFn) (*FindExceptionListItemsResponse, error) @@ -113421,39 +113501,9 @@ type ClientWithResponsesInterface interface { // GetFleetUninstallTokensUninstalltokenidWithResponse request GetFleetUninstallTokensUninstalltokenidWithResponse(ctx context.Context, uninstallTokenId string, reqEditors ...RequestEditorFn) (*GetFleetUninstallTokensUninstalltokenidResponse, error) - // DeleteListWithResponse request - DeleteListWithResponse(ctx context.Context, params *DeleteListParams, reqEditors ...RequestEditorFn) (*DeleteListResponse, error) - - // ReadListWithResponse request - ReadListWithResponse(ctx context.Context, params *ReadListParams, reqEditors ...RequestEditorFn) (*ReadListResponse, error) - - // PatchListWithBodyWithResponse request with any body - PatchListWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PatchListResponse, error) - - PatchListWithResponse(ctx context.Context, body PatchListJSONRequestBody, reqEditors ...RequestEditorFn) (*PatchListResponse, error) - - // CreateListWithBodyWithResponse request with any body - CreateListWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateListResponse, error) - - CreateListWithResponse(ctx context.Context, body CreateListJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateListResponse, error) - - // UpdateListWithBodyWithResponse request with any body - UpdateListWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateListResponse, error) - - UpdateListWithResponse(ctx context.Context, body UpdateListJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateListResponse, error) - // FindListsWithResponse request FindListsWithResponse(ctx context.Context, params *FindListsParams, reqEditors ...RequestEditorFn) (*FindListsResponse, error) - // DeleteListIndexWithResponse request - DeleteListIndexWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*DeleteListIndexResponse, error) - - // ReadListIndexWithResponse request - ReadListIndexWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ReadListIndexResponse, error) - - // CreateListIndexWithResponse request - CreateListIndexWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*CreateListIndexResponse, error) - // DeleteListItemWithResponse request DeleteListItemWithResponse(ctx context.Context, params *DeleteListItemParams, reqEditors ...RequestEditorFn) (*DeleteListItemResponse, error) @@ -114164,6 +114214,68 @@ type ClientWithResponsesInterface interface { UpdateRuleWithResponse(ctx context.Context, spaceId SpaceId, body UpdateRuleJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateRuleResponse, error) + // DeleteExceptionListWithResponse request + DeleteExceptionListWithResponse(ctx context.Context, spaceId SpaceId, params *DeleteExceptionListParams, reqEditors ...RequestEditorFn) (*DeleteExceptionListResponse, error) + + // ReadExceptionListWithResponse request + ReadExceptionListWithResponse(ctx context.Context, spaceId SpaceId, params *ReadExceptionListParams, reqEditors ...RequestEditorFn) (*ReadExceptionListResponse, error) + + // CreateExceptionListWithBodyWithResponse request with any body + CreateExceptionListWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateExceptionListResponse, error) + + CreateExceptionListWithResponse(ctx context.Context, spaceId SpaceId, body CreateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateExceptionListResponse, error) + + // UpdateExceptionListWithBodyWithResponse request with any body + UpdateExceptionListWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateExceptionListResponse, error) + + UpdateExceptionListWithResponse(ctx context.Context, spaceId SpaceId, body UpdateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateExceptionListResponse, error) + + // DeleteExceptionListItemWithResponse request + DeleteExceptionListItemWithResponse(ctx context.Context, spaceId SpaceId, params *DeleteExceptionListItemParams, reqEditors ...RequestEditorFn) (*DeleteExceptionListItemResponse, error) + + // ReadExceptionListItemWithResponse request + ReadExceptionListItemWithResponse(ctx context.Context, spaceId SpaceId, params *ReadExceptionListItemParams, reqEditors ...RequestEditorFn) (*ReadExceptionListItemResponse, error) + + // CreateExceptionListItemWithBodyWithResponse request with any body + CreateExceptionListItemWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateExceptionListItemResponse, error) + + CreateExceptionListItemWithResponse(ctx context.Context, spaceId SpaceId, body CreateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateExceptionListItemResponse, error) + + // UpdateExceptionListItemWithBodyWithResponse request with any body + UpdateExceptionListItemWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateExceptionListItemResponse, error) + + UpdateExceptionListItemWithResponse(ctx context.Context, spaceId SpaceId, body UpdateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateExceptionListItemResponse, error) + + // DeleteListWithResponse request + DeleteListWithResponse(ctx context.Context, spaceId SpaceId, params *DeleteListParams, reqEditors ...RequestEditorFn) (*DeleteListResponse, error) + + // ReadListWithResponse request + ReadListWithResponse(ctx context.Context, spaceId SpaceId, params *ReadListParams, reqEditors ...RequestEditorFn) (*ReadListResponse, error) + + // PatchListWithBodyWithResponse request with any body + PatchListWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PatchListResponse, error) + + PatchListWithResponse(ctx context.Context, spaceId SpaceId, body PatchListJSONRequestBody, reqEditors ...RequestEditorFn) (*PatchListResponse, error) + + // CreateListWithBodyWithResponse request with any body + CreateListWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateListResponse, error) + + CreateListWithResponse(ctx context.Context, spaceId SpaceId, body CreateListJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateListResponse, error) + + // UpdateListWithBodyWithResponse request with any body + UpdateListWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateListResponse, error) + + UpdateListWithResponse(ctx context.Context, spaceId SpaceId, body UpdateListJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateListResponse, error) + + // DeleteListIndexWithResponse request + DeleteListIndexWithResponse(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*DeleteListIndexResponse, error) + + // ReadListIndexWithResponse request + ReadListIndexWithResponse(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*ReadListIndexResponse, error) + + // CreateListIndexWithResponse request + CreateListIndexWithResponse(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*CreateListIndexResponse, error) + // PostMaintenanceWindowWithBodyWithResponse request with any body PostMaintenanceWindowWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostMaintenanceWindowResponse, error) @@ -120471,122 +120583,6 @@ func (r GetEntityStoreStatusResponse) StatusCode() int { return 0 } -type DeleteExceptionListResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityExceptionsAPIExceptionList - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityExceptionsAPIPlatformErrorResponse - JSON403 *SecurityExceptionsAPIPlatformErrorResponse - JSON404 *SecurityExceptionsAPISiemErrorResponse - JSON500 *SecurityExceptionsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r DeleteExceptionListResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r DeleteExceptionListResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type ReadExceptionListResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityExceptionsAPIExceptionList - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityExceptionsAPIPlatformErrorResponse - JSON403 *SecurityExceptionsAPIPlatformErrorResponse - JSON404 *SecurityExceptionsAPISiemErrorResponse - JSON500 *SecurityExceptionsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r ReadExceptionListResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r ReadExceptionListResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type CreateExceptionListResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityExceptionsAPIExceptionList - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityExceptionsAPIPlatformErrorResponse - JSON403 *SecurityExceptionsAPIPlatformErrorResponse - JSON409 *SecurityExceptionsAPISiemErrorResponse - JSON500 *SecurityExceptionsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r CreateExceptionListResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r CreateExceptionListResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type UpdateExceptionListResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityExceptionsAPIExceptionList - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityExceptionsAPIPlatformErrorResponse - JSON403 *SecurityExceptionsAPIPlatformErrorResponse - JSON404 *SecurityExceptionsAPISiemErrorResponse - JSON500 *SecurityExceptionsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r UpdateExceptionListResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r UpdateExceptionListResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - type DuplicateExceptionListResponse struct { Body []byte HTTPResponse *http.Response @@ -120714,122 +120710,6 @@ func (r ImportExceptionListResponse) StatusCode() int { return 0 } -type DeleteExceptionListItemResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityExceptionsAPIExceptionListItem - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityExceptionsAPIPlatformErrorResponse - JSON403 *SecurityExceptionsAPIPlatformErrorResponse - JSON404 *SecurityExceptionsAPISiemErrorResponse - JSON500 *SecurityExceptionsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r DeleteExceptionListItemResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r DeleteExceptionListItemResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type ReadExceptionListItemResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityExceptionsAPIExceptionListItem - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityExceptionsAPIPlatformErrorResponse - JSON403 *SecurityExceptionsAPIPlatformErrorResponse - JSON404 *SecurityExceptionsAPISiemErrorResponse - JSON500 *SecurityExceptionsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r ReadExceptionListItemResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r ReadExceptionListItemResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type CreateExceptionListItemResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityExceptionsAPIExceptionListItem - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityExceptionsAPIPlatformErrorResponse - JSON403 *SecurityExceptionsAPIPlatformErrorResponse - JSON409 *SecurityExceptionsAPISiemErrorResponse - JSON500 *SecurityExceptionsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r CreateExceptionListItemResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r CreateExceptionListItemResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type UpdateExceptionListItemResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityExceptionsAPIExceptionListItem - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityExceptionsAPIPlatformErrorResponse - JSON403 *SecurityExceptionsAPIPlatformErrorResponse - JSON404 *SecurityExceptionsAPISiemErrorResponse - JSON500 *SecurityExceptionsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r UpdateExceptionListItemResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r UpdateExceptionListItemResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - type FindExceptionListItemsResponse struct { Body []byte HTTPResponse *http.Response @@ -127941,151 +127821,6 @@ func (r GetFleetUninstallTokensUninstalltokenidResponse) StatusCode() int { return 0 } -type DeleteListResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityListsAPIList - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityListsAPIPlatformErrorResponse - JSON403 *SecurityListsAPIPlatformErrorResponse - JSON404 *SecurityListsAPISiemErrorResponse - JSON500 *SecurityListsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r DeleteListResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r DeleteListResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type ReadListResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityListsAPIList - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityListsAPIPlatformErrorResponse - JSON403 *SecurityListsAPIPlatformErrorResponse - JSON404 *SecurityListsAPISiemErrorResponse - JSON500 *SecurityListsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r ReadListResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r ReadListResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type PatchListResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityListsAPIList - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityListsAPIPlatformErrorResponse - JSON403 *SecurityListsAPIPlatformErrorResponse - JSON404 *SecurityListsAPISiemErrorResponse - JSON500 *SecurityListsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r PatchListResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r PatchListResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type CreateListResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityListsAPIList - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityListsAPIPlatformErrorResponse - JSON403 *SecurityListsAPIPlatformErrorResponse - JSON409 *SecurityListsAPISiemErrorResponse - JSON500 *SecurityListsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r CreateListResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r CreateListResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type UpdateListResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *SecurityListsAPIList - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityListsAPIPlatformErrorResponse - JSON403 *SecurityListsAPIPlatformErrorResponse - JSON404 *SecurityListsAPISiemErrorResponse - JSON500 *SecurityListsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r UpdateListResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r UpdateListResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - type FindListsResponse struct { Body []byte HTTPResponse *http.Response @@ -128120,100 +127855,6 @@ func (r FindListsResponse) StatusCode() int { return 0 } -type DeleteListIndexResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *struct { - Acknowledged bool `json:"acknowledged"` - } - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityListsAPIPlatformErrorResponse - JSON403 *SecurityListsAPIPlatformErrorResponse - JSON404 *SecurityListsAPISiemErrorResponse - JSON500 *SecurityListsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r DeleteListIndexResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r DeleteListIndexResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type ReadListIndexResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *struct { - ListIndex bool `json:"list_index"` - ListItemIndex bool `json:"list_item_index"` - } - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityListsAPIPlatformErrorResponse - JSON403 *SecurityListsAPIPlatformErrorResponse - JSON404 *SecurityListsAPISiemErrorResponse - JSON500 *SecurityListsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r ReadListIndexResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r ReadListIndexResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type CreateListIndexResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *struct { - Acknowledged bool `json:"acknowledged"` - } - JSON400 *struct { - union json.RawMessage - } - JSON401 *SecurityListsAPIPlatformErrorResponse - JSON403 *SecurityListsAPIPlatformErrorResponse - JSON409 *SecurityListsAPISiemErrorResponse - JSON500 *SecurityListsAPISiemErrorResponse -} - -// Status returns HTTPResponse.Status -func (r CreateListIndexResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r CreateListIndexResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - type DeleteListItemResponse struct { Body []byte HTTPResponse *http.Response @@ -132639,6 +132280,477 @@ func (r UpdateRuleResponse) StatusCode() int { return 0 } +type DeleteExceptionListResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityExceptionsAPIExceptionList + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityExceptionsAPIPlatformErrorResponse + JSON403 *SecurityExceptionsAPIPlatformErrorResponse + JSON404 *SecurityExceptionsAPISiemErrorResponse + JSON500 *SecurityExceptionsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r DeleteExceptionListResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteExceptionListResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type ReadExceptionListResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityExceptionsAPIExceptionList + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityExceptionsAPIPlatformErrorResponse + JSON403 *SecurityExceptionsAPIPlatformErrorResponse + JSON404 *SecurityExceptionsAPISiemErrorResponse + JSON500 *SecurityExceptionsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r ReadExceptionListResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ReadExceptionListResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateExceptionListResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityExceptionsAPIExceptionList + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityExceptionsAPIPlatformErrorResponse + JSON403 *SecurityExceptionsAPIPlatformErrorResponse + JSON409 *SecurityExceptionsAPISiemErrorResponse + JSON500 *SecurityExceptionsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r CreateExceptionListResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateExceptionListResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type UpdateExceptionListResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityExceptionsAPIExceptionList + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityExceptionsAPIPlatformErrorResponse + JSON403 *SecurityExceptionsAPIPlatformErrorResponse + JSON404 *SecurityExceptionsAPISiemErrorResponse + JSON500 *SecurityExceptionsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r UpdateExceptionListResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r UpdateExceptionListResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteExceptionListItemResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityExceptionsAPIExceptionListItem + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityExceptionsAPIPlatformErrorResponse + JSON403 *SecurityExceptionsAPIPlatformErrorResponse + JSON404 *SecurityExceptionsAPISiemErrorResponse + JSON500 *SecurityExceptionsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r DeleteExceptionListItemResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteExceptionListItemResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type ReadExceptionListItemResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityExceptionsAPIExceptionListItem + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityExceptionsAPIPlatformErrorResponse + JSON403 *SecurityExceptionsAPIPlatformErrorResponse + JSON404 *SecurityExceptionsAPISiemErrorResponse + JSON500 *SecurityExceptionsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r ReadExceptionListItemResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ReadExceptionListItemResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateExceptionListItemResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityExceptionsAPIExceptionListItem + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityExceptionsAPIPlatformErrorResponse + JSON403 *SecurityExceptionsAPIPlatformErrorResponse + JSON409 *SecurityExceptionsAPISiemErrorResponse + JSON500 *SecurityExceptionsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r CreateExceptionListItemResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateExceptionListItemResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type UpdateExceptionListItemResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityExceptionsAPIExceptionListItem + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityExceptionsAPIPlatformErrorResponse + JSON403 *SecurityExceptionsAPIPlatformErrorResponse + JSON404 *SecurityExceptionsAPISiemErrorResponse + JSON500 *SecurityExceptionsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r UpdateExceptionListItemResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r UpdateExceptionListItemResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteListResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityListsAPIList + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityListsAPIPlatformErrorResponse + JSON403 *SecurityListsAPIPlatformErrorResponse + JSON404 *SecurityListsAPISiemErrorResponse + JSON500 *SecurityListsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r DeleteListResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteListResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type ReadListResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityListsAPIList + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityListsAPIPlatformErrorResponse + JSON403 *SecurityListsAPIPlatformErrorResponse + JSON404 *SecurityListsAPISiemErrorResponse + JSON500 *SecurityListsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r ReadListResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ReadListResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type PatchListResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityListsAPIList + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityListsAPIPlatformErrorResponse + JSON403 *SecurityListsAPIPlatformErrorResponse + JSON404 *SecurityListsAPISiemErrorResponse + JSON500 *SecurityListsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r PatchListResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PatchListResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateListResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityListsAPIList + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityListsAPIPlatformErrorResponse + JSON403 *SecurityListsAPIPlatformErrorResponse + JSON409 *SecurityListsAPISiemErrorResponse + JSON500 *SecurityListsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r CreateListResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateListResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type UpdateListResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *SecurityListsAPIList + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityListsAPIPlatformErrorResponse + JSON403 *SecurityListsAPIPlatformErrorResponse + JSON404 *SecurityListsAPISiemErrorResponse + JSON500 *SecurityListsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r UpdateListResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r UpdateListResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type DeleteListIndexResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *struct { + Acknowledged bool `json:"acknowledged"` + } + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityListsAPIPlatformErrorResponse + JSON403 *SecurityListsAPIPlatformErrorResponse + JSON404 *SecurityListsAPISiemErrorResponse + JSON500 *SecurityListsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r DeleteListIndexResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r DeleteListIndexResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type ReadListIndexResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *struct { + ListIndex bool `json:"list_index"` + ListItemIndex bool `json:"list_item_index"` + } + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityListsAPIPlatformErrorResponse + JSON403 *SecurityListsAPIPlatformErrorResponse + JSON404 *SecurityListsAPISiemErrorResponse + JSON500 *SecurityListsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r ReadListIndexResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ReadListIndexResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type CreateListIndexResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *struct { + Acknowledged bool `json:"acknowledged"` + } + JSON400 *struct { + union json.RawMessage + } + JSON401 *SecurityListsAPIPlatformErrorResponse + JSON403 *SecurityListsAPIPlatformErrorResponse + JSON409 *SecurityListsAPISiemErrorResponse + JSON500 *SecurityListsAPISiemErrorResponse +} + +// Status returns HTTPResponse.Status +func (r CreateListIndexResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r CreateListIndexResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type PostMaintenanceWindowResponse struct { Body []byte HTTPResponse *http.Response @@ -135408,58 +135520,6 @@ func (c *ClientWithResponses) GetEntityStoreStatusWithResponse(ctx context.Conte return ParseGetEntityStoreStatusResponse(rsp) } -// DeleteExceptionListWithResponse request returning *DeleteExceptionListResponse -func (c *ClientWithResponses) DeleteExceptionListWithResponse(ctx context.Context, params *DeleteExceptionListParams, reqEditors ...RequestEditorFn) (*DeleteExceptionListResponse, error) { - rsp, err := c.DeleteExceptionList(ctx, params, reqEditors...) - if err != nil { - return nil, err - } - return ParseDeleteExceptionListResponse(rsp) -} - -// ReadExceptionListWithResponse request returning *ReadExceptionListResponse -func (c *ClientWithResponses) ReadExceptionListWithResponse(ctx context.Context, params *ReadExceptionListParams, reqEditors ...RequestEditorFn) (*ReadExceptionListResponse, error) { - rsp, err := c.ReadExceptionList(ctx, params, reqEditors...) - if err != nil { - return nil, err - } - return ParseReadExceptionListResponse(rsp) -} - -// CreateExceptionListWithBodyWithResponse request with arbitrary body returning *CreateExceptionListResponse -func (c *ClientWithResponses) CreateExceptionListWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateExceptionListResponse, error) { - rsp, err := c.CreateExceptionListWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseCreateExceptionListResponse(rsp) -} - -func (c *ClientWithResponses) CreateExceptionListWithResponse(ctx context.Context, body CreateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateExceptionListResponse, error) { - rsp, err := c.CreateExceptionList(ctx, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseCreateExceptionListResponse(rsp) -} - -// UpdateExceptionListWithBodyWithResponse request with arbitrary body returning *UpdateExceptionListResponse -func (c *ClientWithResponses) UpdateExceptionListWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateExceptionListResponse, error) { - rsp, err := c.UpdateExceptionListWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseUpdateExceptionListResponse(rsp) -} - -func (c *ClientWithResponses) UpdateExceptionListWithResponse(ctx context.Context, body UpdateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateExceptionListResponse, error) { - rsp, err := c.UpdateExceptionList(ctx, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseUpdateExceptionListResponse(rsp) -} - // DuplicateExceptionListWithResponse request returning *DuplicateExceptionListResponse func (c *ClientWithResponses) DuplicateExceptionListWithResponse(ctx context.Context, params *DuplicateExceptionListParams, reqEditors ...RequestEditorFn) (*DuplicateExceptionListResponse, error) { rsp, err := c.DuplicateExceptionList(ctx, params, reqEditors...) @@ -135496,58 +135556,6 @@ func (c *ClientWithResponses) ImportExceptionListWithBodyWithResponse(ctx contex return ParseImportExceptionListResponse(rsp) } -// DeleteExceptionListItemWithResponse request returning *DeleteExceptionListItemResponse -func (c *ClientWithResponses) DeleteExceptionListItemWithResponse(ctx context.Context, params *DeleteExceptionListItemParams, reqEditors ...RequestEditorFn) (*DeleteExceptionListItemResponse, error) { - rsp, err := c.DeleteExceptionListItem(ctx, params, reqEditors...) - if err != nil { - return nil, err - } - return ParseDeleteExceptionListItemResponse(rsp) -} - -// ReadExceptionListItemWithResponse request returning *ReadExceptionListItemResponse -func (c *ClientWithResponses) ReadExceptionListItemWithResponse(ctx context.Context, params *ReadExceptionListItemParams, reqEditors ...RequestEditorFn) (*ReadExceptionListItemResponse, error) { - rsp, err := c.ReadExceptionListItem(ctx, params, reqEditors...) - if err != nil { - return nil, err - } - return ParseReadExceptionListItemResponse(rsp) -} - -// CreateExceptionListItemWithBodyWithResponse request with arbitrary body returning *CreateExceptionListItemResponse -func (c *ClientWithResponses) CreateExceptionListItemWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateExceptionListItemResponse, error) { - rsp, err := c.CreateExceptionListItemWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseCreateExceptionListItemResponse(rsp) -} - -func (c *ClientWithResponses) CreateExceptionListItemWithResponse(ctx context.Context, body CreateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateExceptionListItemResponse, error) { - rsp, err := c.CreateExceptionListItem(ctx, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseCreateExceptionListItemResponse(rsp) -} - -// UpdateExceptionListItemWithBodyWithResponse request with arbitrary body returning *UpdateExceptionListItemResponse -func (c *ClientWithResponses) UpdateExceptionListItemWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateExceptionListItemResponse, error) { - rsp, err := c.UpdateExceptionListItemWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseUpdateExceptionListItemResponse(rsp) -} - -func (c *ClientWithResponses) UpdateExceptionListItemWithResponse(ctx context.Context, body UpdateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateExceptionListItemResponse, error) { - rsp, err := c.UpdateExceptionListItem(ctx, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseUpdateExceptionListItemResponse(rsp) -} - // FindExceptionListItemsWithResponse request returning *FindExceptionListItemsResponse func (c *ClientWithResponses) FindExceptionListItemsWithResponse(ctx context.Context, params *FindExceptionListItemsParams, reqEditors ...RequestEditorFn) (*FindExceptionListItemsResponse, error) { rsp, err := c.FindExceptionListItems(ctx, params, reqEditors...) @@ -137176,75 +137184,6 @@ func (c *ClientWithResponses) GetFleetUninstallTokensUninstalltokenidWithRespons return ParseGetFleetUninstallTokensUninstalltokenidResponse(rsp) } -// DeleteListWithResponse request returning *DeleteListResponse -func (c *ClientWithResponses) DeleteListWithResponse(ctx context.Context, params *DeleteListParams, reqEditors ...RequestEditorFn) (*DeleteListResponse, error) { - rsp, err := c.DeleteList(ctx, params, reqEditors...) - if err != nil { - return nil, err - } - return ParseDeleteListResponse(rsp) -} - -// ReadListWithResponse request returning *ReadListResponse -func (c *ClientWithResponses) ReadListWithResponse(ctx context.Context, params *ReadListParams, reqEditors ...RequestEditorFn) (*ReadListResponse, error) { - rsp, err := c.ReadList(ctx, params, reqEditors...) - if err != nil { - return nil, err - } - return ParseReadListResponse(rsp) -} - -// PatchListWithBodyWithResponse request with arbitrary body returning *PatchListResponse -func (c *ClientWithResponses) PatchListWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PatchListResponse, error) { - rsp, err := c.PatchListWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParsePatchListResponse(rsp) -} - -func (c *ClientWithResponses) PatchListWithResponse(ctx context.Context, body PatchListJSONRequestBody, reqEditors ...RequestEditorFn) (*PatchListResponse, error) { - rsp, err := c.PatchList(ctx, body, reqEditors...) - if err != nil { - return nil, err - } - return ParsePatchListResponse(rsp) -} - -// CreateListWithBodyWithResponse request with arbitrary body returning *CreateListResponse -func (c *ClientWithResponses) CreateListWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateListResponse, error) { - rsp, err := c.CreateListWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseCreateListResponse(rsp) -} - -func (c *ClientWithResponses) CreateListWithResponse(ctx context.Context, body CreateListJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateListResponse, error) { - rsp, err := c.CreateList(ctx, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseCreateListResponse(rsp) -} - -// UpdateListWithBodyWithResponse request with arbitrary body returning *UpdateListResponse -func (c *ClientWithResponses) UpdateListWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateListResponse, error) { - rsp, err := c.UpdateListWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseUpdateListResponse(rsp) -} - -func (c *ClientWithResponses) UpdateListWithResponse(ctx context.Context, body UpdateListJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateListResponse, error) { - rsp, err := c.UpdateList(ctx, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseUpdateListResponse(rsp) -} - // FindListsWithResponse request returning *FindListsResponse func (c *ClientWithResponses) FindListsWithResponse(ctx context.Context, params *FindListsParams, reqEditors ...RequestEditorFn) (*FindListsResponse, error) { rsp, err := c.FindLists(ctx, params, reqEditors...) @@ -137254,33 +137193,6 @@ func (c *ClientWithResponses) FindListsWithResponse(ctx context.Context, params return ParseFindListsResponse(rsp) } -// DeleteListIndexWithResponse request returning *DeleteListIndexResponse -func (c *ClientWithResponses) DeleteListIndexWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*DeleteListIndexResponse, error) { - rsp, err := c.DeleteListIndex(ctx, reqEditors...) - if err != nil { - return nil, err - } - return ParseDeleteListIndexResponse(rsp) -} - -// ReadListIndexWithResponse request returning *ReadListIndexResponse -func (c *ClientWithResponses) ReadListIndexWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ReadListIndexResponse, error) { - rsp, err := c.ReadListIndex(ctx, reqEditors...) - if err != nil { - return nil, err - } - return ParseReadListIndexResponse(rsp) -} - -// CreateListIndexWithResponse request returning *CreateListIndexResponse -func (c *ClientWithResponses) CreateListIndexWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*CreateListIndexResponse, error) { - rsp, err := c.CreateListIndex(ctx, reqEditors...) - if err != nil { - return nil, err - } - return ParseCreateListIndexResponse(rsp) -} - // DeleteListItemWithResponse request returning *DeleteListItemResponse func (c *ClientWithResponses) DeleteListItemWithResponse(ctx context.Context, params *DeleteListItemParams, reqEditors ...RequestEditorFn) (*DeleteListItemResponse, error) { rsp, err := c.DeleteListItem(ctx, params, reqEditors...) @@ -139605,6 +139517,206 @@ func (c *ClientWithResponses) UpdateRuleWithResponse(ctx context.Context, spaceI return ParseUpdateRuleResponse(rsp) } +// DeleteExceptionListWithResponse request returning *DeleteExceptionListResponse +func (c *ClientWithResponses) DeleteExceptionListWithResponse(ctx context.Context, spaceId SpaceId, params *DeleteExceptionListParams, reqEditors ...RequestEditorFn) (*DeleteExceptionListResponse, error) { + rsp, err := c.DeleteExceptionList(ctx, spaceId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteExceptionListResponse(rsp) +} + +// ReadExceptionListWithResponse request returning *ReadExceptionListResponse +func (c *ClientWithResponses) ReadExceptionListWithResponse(ctx context.Context, spaceId SpaceId, params *ReadExceptionListParams, reqEditors ...RequestEditorFn) (*ReadExceptionListResponse, error) { + rsp, err := c.ReadExceptionList(ctx, spaceId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseReadExceptionListResponse(rsp) +} + +// CreateExceptionListWithBodyWithResponse request with arbitrary body returning *CreateExceptionListResponse +func (c *ClientWithResponses) CreateExceptionListWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateExceptionListResponse, error) { + rsp, err := c.CreateExceptionListWithBody(ctx, spaceId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateExceptionListResponse(rsp) +} + +func (c *ClientWithResponses) CreateExceptionListWithResponse(ctx context.Context, spaceId SpaceId, body CreateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateExceptionListResponse, error) { + rsp, err := c.CreateExceptionList(ctx, spaceId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateExceptionListResponse(rsp) +} + +// UpdateExceptionListWithBodyWithResponse request with arbitrary body returning *UpdateExceptionListResponse +func (c *ClientWithResponses) UpdateExceptionListWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateExceptionListResponse, error) { + rsp, err := c.UpdateExceptionListWithBody(ctx, spaceId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateExceptionListResponse(rsp) +} + +func (c *ClientWithResponses) UpdateExceptionListWithResponse(ctx context.Context, spaceId SpaceId, body UpdateExceptionListJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateExceptionListResponse, error) { + rsp, err := c.UpdateExceptionList(ctx, spaceId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateExceptionListResponse(rsp) +} + +// DeleteExceptionListItemWithResponse request returning *DeleteExceptionListItemResponse +func (c *ClientWithResponses) DeleteExceptionListItemWithResponse(ctx context.Context, spaceId SpaceId, params *DeleteExceptionListItemParams, reqEditors ...RequestEditorFn) (*DeleteExceptionListItemResponse, error) { + rsp, err := c.DeleteExceptionListItem(ctx, spaceId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteExceptionListItemResponse(rsp) +} + +// ReadExceptionListItemWithResponse request returning *ReadExceptionListItemResponse +func (c *ClientWithResponses) ReadExceptionListItemWithResponse(ctx context.Context, spaceId SpaceId, params *ReadExceptionListItemParams, reqEditors ...RequestEditorFn) (*ReadExceptionListItemResponse, error) { + rsp, err := c.ReadExceptionListItem(ctx, spaceId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseReadExceptionListItemResponse(rsp) +} + +// CreateExceptionListItemWithBodyWithResponse request with arbitrary body returning *CreateExceptionListItemResponse +func (c *ClientWithResponses) CreateExceptionListItemWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateExceptionListItemResponse, error) { + rsp, err := c.CreateExceptionListItemWithBody(ctx, spaceId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateExceptionListItemResponse(rsp) +} + +func (c *ClientWithResponses) CreateExceptionListItemWithResponse(ctx context.Context, spaceId SpaceId, body CreateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateExceptionListItemResponse, error) { + rsp, err := c.CreateExceptionListItem(ctx, spaceId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateExceptionListItemResponse(rsp) +} + +// UpdateExceptionListItemWithBodyWithResponse request with arbitrary body returning *UpdateExceptionListItemResponse +func (c *ClientWithResponses) UpdateExceptionListItemWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateExceptionListItemResponse, error) { + rsp, err := c.UpdateExceptionListItemWithBody(ctx, spaceId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateExceptionListItemResponse(rsp) +} + +func (c *ClientWithResponses) UpdateExceptionListItemWithResponse(ctx context.Context, spaceId SpaceId, body UpdateExceptionListItemJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateExceptionListItemResponse, error) { + rsp, err := c.UpdateExceptionListItem(ctx, spaceId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateExceptionListItemResponse(rsp) +} + +// DeleteListWithResponse request returning *DeleteListResponse +func (c *ClientWithResponses) DeleteListWithResponse(ctx context.Context, spaceId SpaceId, params *DeleteListParams, reqEditors ...RequestEditorFn) (*DeleteListResponse, error) { + rsp, err := c.DeleteList(ctx, spaceId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteListResponse(rsp) +} + +// ReadListWithResponse request returning *ReadListResponse +func (c *ClientWithResponses) ReadListWithResponse(ctx context.Context, spaceId SpaceId, params *ReadListParams, reqEditors ...RequestEditorFn) (*ReadListResponse, error) { + rsp, err := c.ReadList(ctx, spaceId, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseReadListResponse(rsp) +} + +// PatchListWithBodyWithResponse request with arbitrary body returning *PatchListResponse +func (c *ClientWithResponses) PatchListWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PatchListResponse, error) { + rsp, err := c.PatchListWithBody(ctx, spaceId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePatchListResponse(rsp) +} + +func (c *ClientWithResponses) PatchListWithResponse(ctx context.Context, spaceId SpaceId, body PatchListJSONRequestBody, reqEditors ...RequestEditorFn) (*PatchListResponse, error) { + rsp, err := c.PatchList(ctx, spaceId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePatchListResponse(rsp) +} + +// CreateListWithBodyWithResponse request with arbitrary body returning *CreateListResponse +func (c *ClientWithResponses) CreateListWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateListResponse, error) { + rsp, err := c.CreateListWithBody(ctx, spaceId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateListResponse(rsp) +} + +func (c *ClientWithResponses) CreateListWithResponse(ctx context.Context, spaceId SpaceId, body CreateListJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateListResponse, error) { + rsp, err := c.CreateList(ctx, spaceId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateListResponse(rsp) +} + +// UpdateListWithBodyWithResponse request with arbitrary body returning *UpdateListResponse +func (c *ClientWithResponses) UpdateListWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateListResponse, error) { + rsp, err := c.UpdateListWithBody(ctx, spaceId, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateListResponse(rsp) +} + +func (c *ClientWithResponses) UpdateListWithResponse(ctx context.Context, spaceId SpaceId, body UpdateListJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateListResponse, error) { + rsp, err := c.UpdateList(ctx, spaceId, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseUpdateListResponse(rsp) +} + +// DeleteListIndexWithResponse request returning *DeleteListIndexResponse +func (c *ClientWithResponses) DeleteListIndexWithResponse(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*DeleteListIndexResponse, error) { + rsp, err := c.DeleteListIndex(ctx, spaceId, reqEditors...) + if err != nil { + return nil, err + } + return ParseDeleteListIndexResponse(rsp) +} + +// ReadListIndexWithResponse request returning *ReadListIndexResponse +func (c *ClientWithResponses) ReadListIndexWithResponse(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*ReadListIndexResponse, error) { + rsp, err := c.ReadListIndex(ctx, spaceId, reqEditors...) + if err != nil { + return nil, err + } + return ParseReadListIndexResponse(rsp) +} + +// CreateListIndexWithResponse request returning *CreateListIndexResponse +func (c *ClientWithResponses) CreateListIndexWithResponse(ctx context.Context, spaceId SpaceId, reqEditors ...RequestEditorFn) (*CreateListIndexResponse, error) { + rsp, err := c.CreateListIndex(ctx, spaceId, reqEditors...) + if err != nil { + return nil, err + } + return ParseCreateListIndexResponse(rsp) +} + // PostMaintenanceWindowWithBodyWithResponse request with arbitrary body returning *PostMaintenanceWindowResponse func (c *ClientWithResponses) PostMaintenanceWindowWithBodyWithResponse(ctx context.Context, spaceId SpaceId, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostMaintenanceWindowResponse, error) { rsp, err := c.PostMaintenanceWindowWithBody(ctx, spaceId, contentType, body, reqEditors...) @@ -147368,258 +147480,6 @@ func ParseGetEntityStoreStatusResponse(rsp *http.Response) (*GetEntityStoreStatu return response, nil } -// ParseDeleteExceptionListResponse parses an HTTP response from a DeleteExceptionListWithResponse call -func ParseDeleteExceptionListResponse(rsp *http.Response) (*DeleteExceptionListResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &DeleteExceptionListResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityExceptionsAPIExceptionList - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseReadExceptionListResponse parses an HTTP response from a ReadExceptionListWithResponse call -func ParseReadExceptionListResponse(rsp *http.Response) (*ReadExceptionListResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &ReadExceptionListResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityExceptionsAPIExceptionList - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseCreateExceptionListResponse parses an HTTP response from a CreateExceptionListWithResponse call -func ParseCreateExceptionListResponse(rsp *http.Response) (*CreateExceptionListResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &CreateExceptionListResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityExceptionsAPIExceptionList - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON409 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseUpdateExceptionListResponse parses an HTTP response from a UpdateExceptionListWithResponse call -func ParseUpdateExceptionListResponse(rsp *http.Response) (*UpdateExceptionListResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &UpdateExceptionListResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityExceptionsAPIExceptionList - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - // ParseDuplicateExceptionListResponse parses an HTTP response from a DuplicateExceptionListWithResponse call func ParseDuplicateExceptionListResponse(rsp *http.Response) (*DuplicateExceptionListResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -147871,258 +147731,6 @@ func ParseImportExceptionListResponse(rsp *http.Response) (*ImportExceptionListR return response, nil } -// ParseDeleteExceptionListItemResponse parses an HTTP response from a DeleteExceptionListItemWithResponse call -func ParseDeleteExceptionListItemResponse(rsp *http.Response) (*DeleteExceptionListItemResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &DeleteExceptionListItemResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityExceptionsAPIExceptionListItem - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseReadExceptionListItemResponse parses an HTTP response from a ReadExceptionListItemWithResponse call -func ParseReadExceptionListItemResponse(rsp *http.Response) (*ReadExceptionListItemResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &ReadExceptionListItemResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityExceptionsAPIExceptionListItem - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseCreateExceptionListItemResponse parses an HTTP response from a CreateExceptionListItemWithResponse call -func ParseCreateExceptionListItemResponse(rsp *http.Response) (*CreateExceptionListItemResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &CreateExceptionListItemResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityExceptionsAPIExceptionListItem - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON409 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseUpdateExceptionListItemResponse parses an HTTP response from a UpdateExceptionListItemWithResponse call -func ParseUpdateExceptionListItemResponse(rsp *http.Response) (*UpdateExceptionListItemResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &UpdateExceptionListItemResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityExceptionsAPIExceptionListItem - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityExceptionsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityExceptionsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - // ParseFindExceptionListItemsResponse parses an HTTP response from a FindExceptionListItemsWithResponse call func ParseFindExceptionListItemsResponse(rsp *http.Response) (*FindExceptionListItemsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -154909,321 +154517,6 @@ func ParseGetFleetUninstallTokensUninstalltokenidResponse(rsp *http.Response) (* return response, nil } -// ParseDeleteListResponse parses an HTTP response from a DeleteListWithResponse call -func ParseDeleteListResponse(rsp *http.Response) (*DeleteListResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &DeleteListResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityListsAPIList - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseReadListResponse parses an HTTP response from a ReadListWithResponse call -func ParseReadListResponse(rsp *http.Response) (*ReadListResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &ReadListResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityListsAPIList - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParsePatchListResponse parses an HTTP response from a PatchListWithResponse call -func ParsePatchListResponse(rsp *http.Response) (*PatchListResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &PatchListResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityListsAPIList - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseCreateListResponse parses an HTTP response from a CreateListWithResponse call -func ParseCreateListResponse(rsp *http.Response) (*CreateListResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &CreateListResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityListsAPIList - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON409 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseUpdateListResponse parses an HTTP response from a UpdateListWithResponse call -func ParseUpdateListResponse(rsp *http.Response) (*UpdateListResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &UpdateListResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest SecurityListsAPIList - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - // ParseFindListsResponse parses an HTTP response from a FindListsWithResponse call func ParseFindListsResponse(rsp *http.Response) (*FindListsResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -155286,202 +154579,6 @@ func ParseFindListsResponse(rsp *http.Response) (*FindListsResponse, error) { return response, nil } -// ParseDeleteListIndexResponse parses an HTTP response from a DeleteListIndexWithResponse call -func ParseDeleteListIndexResponse(rsp *http.Response) (*DeleteListIndexResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &DeleteListIndexResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest struct { - Acknowledged bool `json:"acknowledged"` - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseReadListIndexResponse parses an HTTP response from a ReadListIndexWithResponse call -func ParseReadListIndexResponse(rsp *http.Response) (*ReadListIndexResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &ReadListIndexResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest struct { - ListIndex bool `json:"list_index"` - ListItemIndex bool `json:"list_item_index"` - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON404 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseCreateListIndexResponse parses an HTTP response from a CreateListIndexWithResponse call -func ParseCreateListIndexResponse(rsp *http.Response) (*CreateListIndexResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &CreateListIndexResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest struct { - Acknowledged bool `json:"acknowledged"` - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest struct { - union json.RawMessage - } - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: - var dest SecurityListsAPIPlatformErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON403 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON409 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest SecurityListsAPISiemErrorResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - // ParseDeleteListItemResponse parses an HTTP response from a DeleteListItemWithResponse call func ParseDeleteListItemResponse(rsp *http.Response) (*DeleteListItemResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -160669,6 +159766,1021 @@ func ParseUpdateRuleResponse(rsp *http.Response) (*UpdateRuleResponse, error) { return response, nil } +// ParseDeleteExceptionListResponse parses an HTTP response from a DeleteExceptionListWithResponse call +func ParseDeleteExceptionListResponse(rsp *http.Response) (*DeleteExceptionListResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteExceptionListResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityExceptionsAPIExceptionList + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseReadExceptionListResponse parses an HTTP response from a ReadExceptionListWithResponse call +func ParseReadExceptionListResponse(rsp *http.Response) (*ReadExceptionListResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ReadExceptionListResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityExceptionsAPIExceptionList + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseCreateExceptionListResponse parses an HTTP response from a CreateExceptionListWithResponse call +func ParseCreateExceptionListResponse(rsp *http.Response) (*CreateExceptionListResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateExceptionListResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityExceptionsAPIExceptionList + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON409 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseUpdateExceptionListResponse parses an HTTP response from a UpdateExceptionListWithResponse call +func ParseUpdateExceptionListResponse(rsp *http.Response) (*UpdateExceptionListResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &UpdateExceptionListResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityExceptionsAPIExceptionList + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseDeleteExceptionListItemResponse parses an HTTP response from a DeleteExceptionListItemWithResponse call +func ParseDeleteExceptionListItemResponse(rsp *http.Response) (*DeleteExceptionListItemResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteExceptionListItemResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityExceptionsAPIExceptionListItem + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseReadExceptionListItemResponse parses an HTTP response from a ReadExceptionListItemWithResponse call +func ParseReadExceptionListItemResponse(rsp *http.Response) (*ReadExceptionListItemResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ReadExceptionListItemResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityExceptionsAPIExceptionListItem + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseCreateExceptionListItemResponse parses an HTTP response from a CreateExceptionListItemWithResponse call +func ParseCreateExceptionListItemResponse(rsp *http.Response) (*CreateExceptionListItemResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateExceptionListItemResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityExceptionsAPIExceptionListItem + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON409 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseUpdateExceptionListItemResponse parses an HTTP response from a UpdateExceptionListItemWithResponse call +func ParseUpdateExceptionListItemResponse(rsp *http.Response) (*UpdateExceptionListItemResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &UpdateExceptionListItemResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityExceptionsAPIExceptionListItem + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityExceptionsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityExceptionsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseDeleteListResponse parses an HTTP response from a DeleteListWithResponse call +func ParseDeleteListResponse(rsp *http.Response) (*DeleteListResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteListResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityListsAPIList + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseReadListResponse parses an HTTP response from a ReadListWithResponse call +func ParseReadListResponse(rsp *http.Response) (*ReadListResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ReadListResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityListsAPIList + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParsePatchListResponse parses an HTTP response from a PatchListWithResponse call +func ParsePatchListResponse(rsp *http.Response) (*PatchListResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PatchListResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityListsAPIList + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseCreateListResponse parses an HTTP response from a CreateListWithResponse call +func ParseCreateListResponse(rsp *http.Response) (*CreateListResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateListResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityListsAPIList + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON409 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseUpdateListResponse parses an HTTP response from a UpdateListWithResponse call +func ParseUpdateListResponse(rsp *http.Response) (*UpdateListResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &UpdateListResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest SecurityListsAPIList + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseDeleteListIndexResponse parses an HTTP response from a DeleteListIndexWithResponse call +func ParseDeleteListIndexResponse(rsp *http.Response) (*DeleteListIndexResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &DeleteListIndexResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest struct { + Acknowledged bool `json:"acknowledged"` + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseReadListIndexResponse parses an HTTP response from a ReadListIndexWithResponse call +func ParseReadListIndexResponse(rsp *http.Response) (*ReadListIndexResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ReadListIndexResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest struct { + ListIndex bool `json:"list_index"` + ListItemIndex bool `json:"list_item_index"` + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseCreateListIndexResponse parses an HTTP response from a CreateListIndexWithResponse call +func ParseCreateListIndexResponse(rsp *http.Response) (*CreateListIndexResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &CreateListIndexResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest struct { + Acknowledged bool `json:"acknowledged"` + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest struct { + union json.RawMessage + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest SecurityListsAPIPlatformErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 409: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON409 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest SecurityListsAPISiemErrorResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + // ParsePostMaintenanceWindowResponse parses an HTTP response from a PostMaintenanceWindowWithResponse call func ParsePostMaintenanceWindowResponse(rsp *http.Response) (*PostMaintenanceWindowResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) diff --git a/generated/kbapi/transform_schema.go b/generated/kbapi/transform_schema.go index a377cfe9b..888341188 100644 --- a/generated/kbapi/transform_schema.go +++ b/generated/kbapi/transform_schema.go @@ -691,6 +691,10 @@ func transformKibanaPaths(schema *Schema) { "/api/actions/connector/{id}", "/api/actions/connectors", "/api/detection_engine/rules", + "/api/exception_lists", + "/api/exception_lists/items", + "/api/lists", + "/api/lists/index", } // Add a spaceId parameter if not already present diff --git a/internal/clients/kibana_oapi/exceptions.go b/internal/clients/kibana_oapi/exceptions.go new file mode 100644 index 000000000..8c1d39464 --- /dev/null +++ b/internal/clients/kibana_oapi/exceptions.go @@ -0,0 +1,138 @@ +package kibana_oapi + +import ( + "context" + "net/http" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/diagutil" + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +// GetExceptionList reads an exception list from the API by ID or list_id +func GetExceptionList(ctx context.Context, client *Client, spaceId string, params *kbapi.ReadExceptionListParams) (*kbapi.ReadExceptionListResponse, diag.Diagnostics) { + resp, err := client.API.ReadExceptionListWithResponse(ctx, kbapi.SpaceId(spaceId), params) + if err != nil { + return nil, diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return resp, nil + case http.StatusNotFound: + return nil, nil + default: + return nil, reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// CreateExceptionList creates a new exception list. +func CreateExceptionList(ctx context.Context, client *Client, spaceId string, body kbapi.CreateExceptionListJSONRequestBody) (*kbapi.CreateExceptionListResponse, diag.Diagnostics) { + resp, err := client.API.CreateExceptionListWithResponse(ctx, kbapi.SpaceId(spaceId), body) + if err != nil { + return nil, diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return resp, nil + default: + return nil, reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// UpdateExceptionList updates an existing exception list. +func UpdateExceptionList(ctx context.Context, client *Client, spaceId string, body kbapi.UpdateExceptionListJSONRequestBody) (*kbapi.UpdateExceptionListResponse, diag.Diagnostics) { + resp, err := client.API.UpdateExceptionListWithResponse(ctx, kbapi.SpaceId(spaceId), body) + if err != nil { + return nil, diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return resp, nil + default: + return nil, reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// DeleteExceptionList deletes an existing exception list. +func DeleteExceptionList(ctx context.Context, client *Client, spaceId string, params *kbapi.DeleteExceptionListParams) diag.Diagnostics { + resp, err := client.API.DeleteExceptionListWithResponse(ctx, kbapi.SpaceId(spaceId), params) + if err != nil { + return diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return nil + case http.StatusNotFound: + return nil + default: + return reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// GetExceptionListItem reads an exception list item from the API by ID or item_id +func GetExceptionListItem(ctx context.Context, client *Client, spaceId string, params *kbapi.ReadExceptionListItemParams) (*kbapi.ReadExceptionListItemResponse, diag.Diagnostics) { + resp, err := client.API.ReadExceptionListItemWithResponse(ctx, kbapi.SpaceId(spaceId), params) + if err != nil { + return nil, diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return resp, nil + case http.StatusNotFound: + return nil, nil + default: + return nil, reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// CreateExceptionListItem creates a new exception list item. +func CreateExceptionListItem(ctx context.Context, client *Client, spaceId string, body kbapi.CreateExceptionListItemJSONRequestBody) (*kbapi.CreateExceptionListItemResponse, diag.Diagnostics) { + resp, err := client.API.CreateExceptionListItemWithResponse(ctx, kbapi.SpaceId(spaceId), body) + if err != nil { + return nil, diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return resp, nil + default: + return nil, reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// UpdateExceptionListItem updates an existing exception list item. +func UpdateExceptionListItem(ctx context.Context, client *Client, spaceId string, body kbapi.UpdateExceptionListItemJSONRequestBody) (*kbapi.UpdateExceptionListItemResponse, diag.Diagnostics) { + resp, err := client.API.UpdateExceptionListItemWithResponse(ctx, kbapi.SpaceId(spaceId), body) + if err != nil { + return nil, diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return resp, nil + default: + return nil, reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// DeleteExceptionListItem deletes an existing exception list item. +func DeleteExceptionListItem(ctx context.Context, client *Client, spaceId string, params *kbapi.DeleteExceptionListItemParams) diag.Diagnostics { + resp, err := client.API.DeleteExceptionListItemWithResponse(ctx, kbapi.SpaceId(spaceId), params) + if err != nil { + return diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return nil + case http.StatusNotFound: + return nil + default: + return reportUnknownError(resp.StatusCode(), resp.Body) + } +} diff --git a/internal/clients/kibana_oapi/security_lists.go b/internal/clients/kibana_oapi/security_lists.go new file mode 100644 index 000000000..f6f09f133 --- /dev/null +++ b/internal/clients/kibana_oapi/security_lists.go @@ -0,0 +1,162 @@ +package kibana_oapi + +import ( + "context" + "net/http" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/diagutil" + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +// CreateListIndex creates the .lists and .items data streams for a space if they don't exist. +// This is required before any list operations can be performed. +func CreateListIndex(ctx context.Context, client *Client, spaceId string) diag.Diagnostics { + resp, err := client.API.CreateListIndexWithResponse(ctx, kbapi.SpaceId(spaceId)) + if err != nil { + return diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return nil + default: + return reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// GetList reads a security list from the API by ID +func GetList(ctx context.Context, client *Client, spaceId string, params *kbapi.ReadListParams) (*kbapi.ReadListResponse, diag.Diagnostics) { + resp, err := client.API.ReadListWithResponse(ctx, kbapi.SpaceId(spaceId), params) + if err != nil { + return nil, diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return resp, nil + case http.StatusNotFound: + return nil, nil + default: + return nil, reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// CreateList creates a new security list. +func CreateList(ctx context.Context, client *Client, spaceId string, body kbapi.CreateListJSONRequestBody) (*kbapi.CreateListResponse, diag.Diagnostics) { + resp, err := client.API.CreateListWithResponse(ctx, kbapi.SpaceId(spaceId), body) + if err != nil { + return nil, diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return resp, nil + default: + return nil, reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// UpdateList updates an existing security list. +func UpdateList(ctx context.Context, client *Client, spaceId string, body kbapi.UpdateListJSONRequestBody) (*kbapi.UpdateListResponse, diag.Diagnostics) { + resp, err := client.API.UpdateListWithResponse(ctx, kbapi.SpaceId(spaceId), body) + if err != nil { + return nil, diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return resp, nil + default: + return nil, reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// DeleteList deletes an existing security list. +func DeleteList(ctx context.Context, client *Client, spaceId string, params *kbapi.DeleteListParams) diag.Diagnostics { + resp, err := client.API.DeleteListWithResponse(ctx, kbapi.SpaceId(spaceId), params) + if err != nil { + return diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return nil + case http.StatusNotFound: + return nil + default: + return reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// GetListItem reads a security list item from the API by ID or list_id and value +// Note: The generated Kibana API client does not support space_id for list items yet, +// so this function operates in the default space only. +func GetListItem(ctx context.Context, client *Client, params *kbapi.ReadListItemParams) (*kbapi.ReadListItemResponse, diag.Diagnostics) { + resp, err := client.API.ReadListItemWithResponse(ctx, params) + if err != nil { + return nil, diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return resp, nil + case http.StatusNotFound: + return nil, nil + default: + return nil, reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// CreateListItem creates a new security list item. +// Note: The generated Kibana API client does not support space_id for list items yet, +// so this function operates in the default space only. +func CreateListItem(ctx context.Context, client *Client, body kbapi.CreateListItemJSONRequestBody) (*kbapi.CreateListItemResponse, diag.Diagnostics) { + resp, err := client.API.CreateListItemWithResponse(ctx, body) + if err != nil { + return nil, diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return resp, nil + default: + return nil, reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// UpdateListItem updates an existing security list item. +// Note: The generated Kibana API client does not support space_id for list items yet, +// so this function operates in the default space only. +func UpdateListItem(ctx context.Context, client *Client, body kbapi.UpdateListItemJSONRequestBody) (*kbapi.UpdateListItemResponse, diag.Diagnostics) { + resp, err := client.API.UpdateListItemWithResponse(ctx, body) + if err != nil { + return nil, diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return resp, nil + default: + return nil, reportUnknownError(resp.StatusCode(), resp.Body) + } +} + +// DeleteListItem deletes an existing security list item. +// Note: The generated Kibana API client does not support space_id for list items yet, +// so this function operates in the default space only. +func DeleteListItem(ctx context.Context, client *Client, params *kbapi.DeleteListItemParams) diag.Diagnostics { + resp, err := client.API.DeleteListItemWithResponse(ctx, params) + if err != nil { + return diagutil.FrameworkDiagFromError(err) + } + + switch resp.StatusCode() { + case http.StatusOK: + return nil + case http.StatusNotFound: + return nil + default: + return reportUnknownError(resp.StatusCode(), resp.Body) + } +} diff --git a/internal/kibana/security_detection_rule/schema.go b/internal/kibana/security_detection_rule/schema.go index 0dab25047..8ea3c75b9 100644 --- a/internal/kibana/security_detection_rule/schema.go +++ b/internal/kibana/security_detection_rule/schema.go @@ -970,6 +970,7 @@ func (r securityDetectionRuleResource) ValidateConfig(ctx context.Context, req r } + // TODO unknown is allowed if we are referencing values that are not yet known if !utils.IsKnown(data.Index) && !utils.IsKnown(data.DataViewId) { resp.Diagnostics.AddError( "Invalid Configuration", diff --git a/internal/kibana/security_exception_item/acc_test.go b/internal/kibana/security_exception_item/acc_test.go new file mode 100644 index 000000000..d5ad643ac --- /dev/null +++ b/internal/kibana/security_exception_item/acc_test.go @@ -0,0 +1,474 @@ +package security_exception_item_test + +import ( + "fmt" + "regexp" + "testing" + + "github.com/elastic/terraform-provider-elasticstack/internal/acctest" + "github.com/elastic/terraform-provider-elasticstack/internal/versionutils" + "github.com/google/uuid" + "github.com/hashicorp/go-version" + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +var minExceptionItemAPISupport = version.Must(version.NewVersion("7.9.0")) + +func TestAccResourceExceptionItem(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("create"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable("test-exception-list-for-item"), + "item_id": config.StringVariable("test-exception-item"), + "name": config.StringVariable("Test Exception Item"), + "description": config.StringVariable("Test exception item for acceptance tests"), + "type": config.StringVariable("simple"), + "namespace_type": config.StringVariable("single"), + "tags": config.ListVariable(config.StringVariable("test")), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "item_id", "test-exception-item"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "name", "Test Exception Item"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "description", "Test exception item for acceptance tests"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "type", "simple"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "namespace_type", "single"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "tags.0", "test"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_exception_item.test", "id"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_exception_item.test", "entries.#"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_exception_item.test", "created_at"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_exception_item.test", "created_by"), + ), + }, + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("update"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable("test-exception-list-for-item"), + "item_id": config.StringVariable("test-exception-item"), + "name": config.StringVariable("Test Exception Item Updated"), + "description": config.StringVariable("Updated description"), + "type": config.StringVariable("simple"), + "namespace_type": config.StringVariable("single"), + "tags": config.ListVariable(config.StringVariable("test"), config.StringVariable("updated")), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "name", "Test Exception Item Updated"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "description", "Updated description"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "tags.0", "test"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "tags.1", "updated"), + ), + }, + }, + }) +} + +func TestAccResourceExceptionItemWithSpace(t *testing.T) { + resourceName := "elasticstack_kibana_security_exception_item.test" + spaceResourceName := "elasticstack_kibana_space.test" + spaceID := fmt.Sprintf("test-space-%s", uuid.New().String()[:8]) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProtoV6ProviderFactories: acctest.Providers, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ConfigDirectory: acctest.NamedTestCaseDirectory("create"), + ConfigVariables: config.Variables{ + "space_id": config.StringVariable(spaceID), + "list_id": config.StringVariable("test-exception-list-for-item-space"), + "item_id": config.StringVariable("test-exception-item-space"), + "name": config.StringVariable("Test Exception Item in Space"), + "description": config.StringVariable("Test exception item in custom space"), + "type": config.StringVariable("simple"), + "namespace_type": config.StringVariable("single"), + "tags": config.ListVariable(config.StringVariable("test"), config.StringVariable("space")), + }, + Check: resource.ComposeTestCheckFunc( + // Check space attributes + resource.TestCheckResourceAttr(spaceResourceName, "space_id", spaceID), + resource.TestCheckResourceAttr(spaceResourceName, "name", "Test Space for Exception Items"), + + // Check exception item attributes + resource.TestCheckResourceAttr(resourceName, "space_id", spaceID), + resource.TestCheckResourceAttr(resourceName, "item_id", "test-exception-item-space"), + resource.TestCheckResourceAttr(resourceName, "name", "Test Exception Item in Space"), + resource.TestCheckResourceAttr(resourceName, "description", "Test exception item in custom space"), + resource.TestCheckResourceAttr(resourceName, "type", "simple"), + resource.TestCheckResourceAttr(resourceName, "namespace_type", "single"), + resource.TestCheckResourceAttr(resourceName, "tags.0", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.1", "space"), + resource.TestCheckResourceAttrSet(resourceName, "id"), + resource.TestCheckResourceAttrSet(resourceName, "entries.#"), + resource.TestCheckResourceAttrSet(resourceName, "created_at"), + resource.TestCheckResourceAttrSet(resourceName, "created_by"), + ), + }, + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ConfigDirectory: acctest.NamedTestCaseDirectory("update"), + ConfigVariables: config.Variables{ + "space_id": config.StringVariable(spaceID), + "list_id": config.StringVariable("test-exception-list-for-item-space"), + "item_id": config.StringVariable("test-exception-item-space"), + "name": config.StringVariable("Test Exception Item in Space Updated"), + "description": config.StringVariable("Updated description in space"), + "type": config.StringVariable("simple"), + "namespace_type": config.StringVariable("single"), + "tags": config.ListVariable(config.StringVariable("test"), config.StringVariable("space"), config.StringVariable("updated")), + }, + Check: resource.ComposeTestCheckFunc( + // Check space attributes remain the same + resource.TestCheckResourceAttr(spaceResourceName, "space_id", spaceID), + resource.TestCheckResourceAttr(spaceResourceName, "name", "Test Space for Exception Items"), + + // Check updated exception item attributes + resource.TestCheckResourceAttr(resourceName, "space_id", spaceID), + resource.TestCheckResourceAttr(resourceName, "name", "Test Exception Item in Space Updated"), + resource.TestCheckResourceAttr(resourceName, "description", "Updated description in space"), + resource.TestCheckResourceAttr(resourceName, "tags.0", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.1", "space"), + resource.TestCheckResourceAttr(resourceName, "tags.2", "updated"), + ), + }, + }, + }) +} + +func TestAccResourceExceptionItemEntryType_Match(t *testing.T) { + listID := fmt.Sprintf("test-exception-list-match-%s", uuid.New().String()[:8]) + itemID := fmt.Sprintf("test-exception-item-match-%s", uuid.New().String()[:8]) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("match"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.type", "match"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.field", "process.name"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.operator", "included"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.value", "test-process"), + ), + }, + }, + }) +} + +func TestAccResourceExceptionItemEntryType_MatchAny(t *testing.T) { + listID := fmt.Sprintf("test-exception-list-match-any-%s", uuid.New().String()[:8]) + itemID := fmt.Sprintf("test-exception-item-match-any-%s", uuid.New().String()[:8]) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("match_any"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.type", "match_any"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.field", "process.name"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.operator", "included"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.values.0", "process1"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.values.1", "process2"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.values.2", "process3"), + ), + }, + }, + }) +} + +func TestAccResourceExceptionItemEntryType_List(t *testing.T) { + exceptionListID := fmt.Sprintf("test-exception-list-list-entry-%s", uuid.New().String()[:8]) + itemID := fmt.Sprintf("test-exception-item-list-entry-%s", uuid.New().String()[:8]) + valueListID := fmt.Sprintf("test-value-list-%s", uuid.New().String()[:8]) + valueListValue := "192.168.1.1" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("list"), + ConfigVariables: config.Variables{ + "exception_list_id": config.StringVariable(exceptionListID), + "item_id": config.StringVariable(itemID), + "value_list_id": config.StringVariable(valueListID), + "value_list_value": config.StringVariable(valueListValue), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.type", "list"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.field", "source.ip"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.operator", "included"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.list.id", valueListID), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.list.type", "ip"), + ), + }, + }, + }) +} + +func TestAccResourceExceptionItemEntryType_Exists(t *testing.T) { + listID := fmt.Sprintf("test-exception-list-exists-%s", uuid.New().String()[:8]) + itemID := fmt.Sprintf("test-exception-item-exists-%s", uuid.New().String()[:8]) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("exists"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.type", "exists"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.field", "file.hash.sha256"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.operator", "included"), + ), + }, + }, + }) +} + +func TestAccResourceExceptionItemEntryType_Nested(t *testing.T) { + listID := fmt.Sprintf("test-exception-list-nested-%s", uuid.New().String()[:8]) + itemID := fmt.Sprintf("test-exception-item-nested-%s", uuid.New().String()[:8]) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("nested"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.type", "nested"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.field", "parent.field"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.entries.0.type", "match"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.entries.0.field", "nested.field"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.entries.0.operator", "included"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.entries.0.value", "nested-value"), + ), + }, + }, + }) +} + +func TestAccResourceExceptionItemEntryType_Wildcard(t *testing.T) { + listID := fmt.Sprintf("test-exception-list-wildcard-%s", uuid.New().String()[:8]) + itemID := fmt.Sprintf("test-exception-item-wildcard-%s", uuid.New().String()[:8]) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("wildcard"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.type", "wildcard"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.field", "file.path"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.operator", "included"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_item.test", "entries.0.value", "/tmp/*.tmp"), + ), + }, + }, + }) +} + +func TestAccResourceExceptionItemValidation(t *testing.T) { + listID := fmt.Sprintf("test-exception-list-validation-%s", uuid.New().String()[:8]) + itemID := fmt.Sprintf("test-exception-item-validation-%s", uuid.New().String()[:8]) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + Steps: []resource.TestStep{ + // Test 1: Match entry missing value + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_match_missing_value"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile("Entry type 'match' requires 'value' to be set"), + PlanOnly: true, + }, + // Test 2: Match entry missing operator + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_match_missing_operator"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile("Entry type 'match' requires 'operator' to be set"), + PlanOnly: true, + }, + // Test 3: Wildcard entry missing value + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_wildcard_missing_value"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile("Entry type 'wildcard' requires 'value' to be set"), + PlanOnly: true, + }, + // Test 4: MatchAny entry missing values + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_match_any_missing_values"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile("Entry type 'match_any' requires 'values' to be set"), + PlanOnly: true, + }, + // Test 5: MatchAny entry missing operator + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_match_any_missing_operator"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile("Entry type 'match_any' requires 'operator' to be set"), + PlanOnly: true, + }, + // Test 6: List entry missing list object + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_list_missing_list_object"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile("Entry type 'list' requires 'list' object to be set"), + PlanOnly: true, + }, + // Test 7: List entry missing list.id + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_list_missing_list_id"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile(`attribute "id" is required`), + PlanOnly: true, + }, + // Test 8: List entry missing list.type + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_list_missing_list_type"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile(`attribute "type" is required`), + PlanOnly: true, + }, + // Test 9: Exists entry missing operator + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_exists_missing_operator"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile("Entry type 'exists' requires 'operator' to be set"), + PlanOnly: true, + }, + // Test 10: Nested entry missing entries + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_nested_missing_entries"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile("Entry type 'nested' requires 'entries' to be set"), + PlanOnly: true, + }, + // Test 11: Nested entry with invalid entry type + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_nested_invalid_entry_type"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile(`(Nested entry .* has invalid type|value must be one of:.*"match".*"match_any".*"exists")`), + PlanOnly: true, + }, + // Test 12: Nested match entry missing value + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_nested_entry_missing_value"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile("Nested entry type 'match' requires 'value' to be set"), + PlanOnly: true, + }, + // Test 13: Nested entry missing operator + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionItemAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("validation_nested_entry_missing_operator"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "item_id": config.StringVariable(itemID), + }, + ExpectError: regexp.MustCompile(`(Nested entry requires 'operator' to be set|attribute "operator" is required)`), + PlanOnly: true, + }, + }, + }) +} diff --git a/internal/kibana/security_exception_item/create.go b/internal/kibana/security_exception_item/create.go new file mode 100644 index 000000000..d826f2732 --- /dev/null +++ b/internal/kibana/security_exception_item/create.go @@ -0,0 +1,263 @@ +package security_exception_item + +import ( + "context" + "encoding/json" + "time" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/elastic/terraform-provider-elasticstack/internal/utils" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func (r *ExceptionItemResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var plan ExceptionItemModel + + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Convert entries from Terraform model to API model + entries, diags := convertEntriesToAPI(ctx, plan.Entries) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + // Build the request body + body := kbapi.CreateExceptionListItemJSONRequestBody{ + ListId: kbapi.SecurityExceptionsAPIExceptionListHumanId(plan.ListID.ValueString()), + Name: kbapi.SecurityExceptionsAPIExceptionListItemName(plan.Name.ValueString()), + Description: kbapi.SecurityExceptionsAPIExceptionListItemDescription(plan.Description.ValueString()), + Type: kbapi.SecurityExceptionsAPIExceptionListItemType(plan.Type.ValueString()), + Entries: entries, + } + + // Set optional item_id + if utils.IsKnown(plan.ItemID) && !plan.ItemID.IsNull() { + itemID := kbapi.SecurityExceptionsAPIExceptionListItemHumanId(plan.ItemID.ValueString()) + body.ItemId = &itemID + } + + // Set optional namespace_type + if utils.IsKnown(plan.NamespaceType) { + nsType := kbapi.SecurityExceptionsAPIExceptionNamespaceType(plan.NamespaceType.ValueString()) + body.NamespaceType = &nsType + } + + // Set optional os_types + if utils.IsKnown(plan.OsTypes) && !plan.OsTypes.IsNull() { + var osTypes []string + diags := plan.OsTypes.ElementsAs(ctx, &osTypes, false) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + if len(osTypes) > 0 { + osTypesArray := make(kbapi.SecurityExceptionsAPIExceptionListItemOsTypeArray, len(osTypes)) + for i, osType := range osTypes { + osTypesArray[i] = kbapi.SecurityExceptionsAPIExceptionListOsType(osType) + } + body.OsTypes = &osTypesArray + } + } + + // Set optional tags + if utils.IsKnown(plan.Tags) && !plan.Tags.IsNull() { + var tags []string + diags := plan.Tags.ElementsAs(ctx, &tags, false) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + if len(tags) > 0 { + tagsArray := kbapi.SecurityExceptionsAPIExceptionListItemTags(tags) + body.Tags = &tagsArray + } + } + + // Set optional meta + if utils.IsKnown(plan.Meta) && !plan.Meta.IsNull() { + var meta kbapi.SecurityExceptionsAPIExceptionListItemMeta + if err := json.Unmarshal([]byte(plan.Meta.ValueString()), &meta); err != nil { + resp.Diagnostics.AddError("Failed to parse meta JSON", err.Error()) + return + } + body.Meta = &meta + } + + // Set optional comments + if utils.IsKnown(plan.Comments) && !plan.Comments.IsNull() { + var comments []CommentModel + diags := plan.Comments.ElementsAs(ctx, &comments, false) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + if len(comments) > 0 { + commentsArray := make(kbapi.SecurityExceptionsAPICreateExceptionListItemCommentArray, len(comments)) + for i, comment := range comments { + commentsArray[i] = kbapi.SecurityExceptionsAPICreateExceptionListItemComment{ + Comment: kbapi.SecurityExceptionsAPINonEmptyString(comment.Comment.ValueString()), + } + } + body.Comments = &commentsArray + } + } + + // Set optional expire_time + if utils.IsKnown(plan.ExpireTime) && !plan.ExpireTime.IsNull() { + expireTime, err := time.Parse(time.RFC3339, plan.ExpireTime.ValueString()) + if err != nil { + resp.Diagnostics.AddError("Failed to parse expire_time", err.Error()) + return + } + expireTimeAPI := kbapi.SecurityExceptionsAPIExceptionListItemExpireTime(expireTime) + body.ExpireTime = &expireTimeAPI + } + + // Create the exception item + createResp, diags := kibana_oapi.CreateExceptionListItem(ctx, client, plan.SpaceID.ValueString(), body) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if createResp == nil || createResp.JSON200 == nil { + resp.Diagnostics.AddError("Failed to create exception item", "API returned empty response") + return + } + + /* + * In create/update paths we typically follow the write operation with a read, and then set the state from the read. + * We want to avoid a dirty plan immediately after an apply. + */ + // Read back the created resource to get the final state + readParams := &kbapi.ReadExceptionListItemParams{ + Id: (*kbapi.SecurityExceptionsAPIExceptionListItemId)(&createResp.JSON200.Id), + } + + readResp, diags := kibana_oapi.GetExceptionListItem(ctx, client, plan.SpaceID.ValueString(), readParams) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if readResp == nil || readResp.JSON200 == nil { + resp.State.RemoveResource(ctx) + return + } + + // Update state with read response + diags = r.updateStateFromAPIResponse(ctx, &plan, readResp.JSON200) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + diags = resp.State.Set(ctx, plan) + resp.Diagnostics.Append(diags...) +} + +func (r *ExceptionItemResource) updateStateFromAPIResponse(ctx context.Context, model *ExceptionItemModel, apiResp *kbapi.SecurityExceptionsAPIExceptionListItem) diag.Diagnostics { + var diags diag.Diagnostics + + model.ID = types.StringValue(string(apiResp.Id)) + model.ItemID = types.StringValue(string(apiResp.ItemId)) + model.ListID = types.StringValue(string(apiResp.ListId)) + model.Name = types.StringValue(string(apiResp.Name)) + model.Description = types.StringValue(string(apiResp.Description)) + model.Type = types.StringValue(string(apiResp.Type)) + model.NamespaceType = types.StringValue(string(apiResp.NamespaceType)) + model.CreatedAt = types.StringValue(apiResp.CreatedAt.Format("2006-01-02T15:04:05.000Z")) + model.CreatedBy = types.StringValue(apiResp.CreatedBy) + model.UpdatedAt = types.StringValue(apiResp.UpdatedAt.Format("2006-01-02T15:04:05.000Z")) + model.UpdatedBy = types.StringValue(apiResp.UpdatedBy) + model.TieBreakerID = types.StringValue(apiResp.TieBreakerId) + + // Set optional expire_time + if apiResp.ExpireTime != nil { + model.ExpireTime = types.StringValue(time.Time(*apiResp.ExpireTime).Format(time.RFC3339)) + } else { + model.ExpireTime = types.StringNull() + } + + // Set optional os_types + if apiResp.OsTypes != nil && len(*apiResp.OsTypes) > 0 { + osTypes := make([]string, len(*apiResp.OsTypes)) + for i, osType := range *apiResp.OsTypes { + osTypes[i] = string(osType) + } + list, d := types.ListValueFrom(ctx, types.StringType, osTypes) + diags.Append(d...) + model.OsTypes = list + } else { + model.OsTypes = types.ListNull(types.StringType) + } + + // Set optional tags + if apiResp.Tags != nil && len(*apiResp.Tags) > 0 { + list, d := types.ListValueFrom(ctx, types.StringType, *apiResp.Tags) + diags.Append(d...) + model.Tags = list + } else { + model.Tags = types.ListNull(types.StringType) + } + + // Set optional meta + if apiResp.Meta != nil { + metaJSON, err := json.Marshal(apiResp.Meta) + if err != nil { + diags.AddError("Failed to serialize meta", err.Error()) + return diags + } + model.Meta = types.StringValue(string(metaJSON)) + } else { + model.Meta = types.StringNull() + } + + // Set entries (convert from API model to Terraform model) + entriesList, d := convertEntriesFromAPI(ctx, apiResp.Entries) + diags.Append(d...) + model.Entries = entriesList + + // Set optional comments + if len(apiResp.Comments) > 0 { + comments := make([]CommentModel, len(apiResp.Comments)) + for i, comment := range apiResp.Comments { + comments[i] = CommentModel{ + ID: types.StringValue(string(comment.Id)), + Comment: types.StringValue(string(comment.Comment)), + } + } + list, d := types.ListValueFrom(ctx, types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "id": types.StringType, + "comment": types.StringType, + }, + }, comments) + diags.Append(d...) + model.Comments = list + } else { + model.Comments = types.ListNull(types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "id": types.StringType, + "comment": types.StringType, + }, + }) + } + + return diags +} diff --git a/internal/kibana/security_exception_item/delete.go b/internal/kibana/security_exception_item/delete.go new file mode 100644 index 000000000..3b834b756 --- /dev/null +++ b/internal/kibana/security_exception_item/delete.go @@ -0,0 +1,34 @@ +package security_exception_item + +import ( + "context" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *ExceptionItemResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state ExceptionItemModel + + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Delete by ID + id := kbapi.SecurityExceptionsAPIExceptionListItemId(state.ID.ValueString()) + params := &kbapi.DeleteExceptionListItemParams{ + Id: &id, + } + + diags = kibana_oapi.DeleteExceptionListItem(ctx, client, state.SpaceID.ValueString(), params) + resp.Diagnostics.Append(diags...) +} diff --git a/internal/kibana/security_exception_item/models.go b/internal/kibana/security_exception_item/models.go new file mode 100644 index 000000000..5e4ab2499 --- /dev/null +++ b/internal/kibana/security_exception_item/models.go @@ -0,0 +1,539 @@ +package security_exception_item + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type ExceptionItemModel struct { + ID types.String `tfsdk:"id"` + SpaceID types.String `tfsdk:"space_id"` + ItemID types.String `tfsdk:"item_id"` + ListID types.String `tfsdk:"list_id"` + Name types.String `tfsdk:"name"` + Description types.String `tfsdk:"description"` + Type types.String `tfsdk:"type"` + NamespaceType types.String `tfsdk:"namespace_type"` + OsTypes types.List `tfsdk:"os_types"` + Tags types.List `tfsdk:"tags"` + Meta types.String `tfsdk:"meta"` + Entries types.List `tfsdk:"entries"` + Comments types.List `tfsdk:"comments"` + ExpireTime types.String `tfsdk:"expire_time"` + CreatedAt types.String `tfsdk:"created_at"` + CreatedBy types.String `tfsdk:"created_by"` + UpdatedAt types.String `tfsdk:"updated_at"` + UpdatedBy types.String `tfsdk:"updated_by"` + TieBreakerID types.String `tfsdk:"tie_breaker_id"` +} + +type CommentModel struct { + ID types.String `tfsdk:"id"` + Comment types.String `tfsdk:"comment"` +} + +type EntryModel struct { + Type types.String `tfsdk:"type"` + Field types.String `tfsdk:"field"` + Operator types.String `tfsdk:"operator"` + Value types.String `tfsdk:"value"` + Values types.List `tfsdk:"values"` + List types.Object `tfsdk:"list"` + Entries types.List `tfsdk:"entries"` +} + +type EntryListModel struct { + ID types.String `tfsdk:"id"` + Type types.String `tfsdk:"type"` +} + +type NestedEntryModel struct { + Type types.String `tfsdk:"type"` + Field types.String `tfsdk:"field"` + Operator types.String `tfsdk:"operator"` + Value types.String `tfsdk:"value"` + Values types.List `tfsdk:"values"` +} + +// convertEntriesToAPI converts Terraform entry models to API entry models +func convertEntriesToAPI(ctx context.Context, entries types.List) (kbapi.SecurityExceptionsAPIExceptionListItemEntryArray, diag.Diagnostics) { + var diags diag.Diagnostics + + if entries.IsNull() || entries.IsUnknown() { + return nil, diags + } + + var entryModels []EntryModel + diags.Append(entries.ElementsAs(ctx, &entryModels, false)...) + if diags.HasError() { + return nil, diags + } + + apiEntries := make(kbapi.SecurityExceptionsAPIExceptionListItemEntryArray, 0, len(entryModels)) + for _, entry := range entryModels { + apiEntry, d := convertEntryToAPI(ctx, entry) + diags.Append(d...) + if d.HasError() { + continue + } + apiEntries = append(apiEntries, apiEntry) + } + + return apiEntries, diags +} + +// convertEntryToAPI converts a single Terraform entry model to an API entry model +func convertEntryToAPI(ctx context.Context, entry EntryModel) (kbapi.SecurityExceptionsAPIExceptionListItemEntry, diag.Diagnostics) { + var diags diag.Diagnostics + var result kbapi.SecurityExceptionsAPIExceptionListItemEntry + + entryType := entry.Type.ValueString() + operator := kbapi.SecurityExceptionsAPIExceptionListItemEntryOperator(entry.Operator.ValueString()) + field := kbapi.SecurityExceptionsAPINonEmptyString(entry.Field.ValueString()) + + switch entryType { + case "match": + // Validate required field + if entry.Value.IsNull() || entry.Value.IsUnknown() || entry.Value.ValueString() == "" { + diags.AddError("Invalid Configuration", "Attribute 'value' is required when type is 'match'") + return result, diags + } + + apiEntry := kbapi.SecurityExceptionsAPIExceptionListItemEntryMatch{ + Type: "match", + Field: field, + Operator: operator, + Value: kbapi.SecurityExceptionsAPINonEmptyString(entry.Value.ValueString()), + } + if err := result.FromSecurityExceptionsAPIExceptionListItemEntryMatch(apiEntry); err != nil { + diags.AddError("Failed to create match entry", err.Error()) + } + + case "match_any": + // Validate required field + if entry.Values.IsNull() || entry.Values.IsUnknown() { + diags.AddError("Invalid Configuration", "Attribute 'values' is required when type is 'match_any'") + return result, diags + } + + var values []string + diags.Append(entry.Values.ElementsAs(ctx, &values, false)...) + if diags.HasError() { + return result, diags + } + + if len(values) == 0 { + diags.AddError("Invalid Configuration", "Attribute 'values' must contain at least one value when type is 'match_any'") + return result, diags + } + + apiValues := make([]kbapi.SecurityExceptionsAPINonEmptyString, len(values)) + for i, v := range values { + apiValues[i] = kbapi.SecurityExceptionsAPINonEmptyString(v) + } + apiEntry := kbapi.SecurityExceptionsAPIExceptionListItemEntryMatchAny{ + Type: "match_any", + Field: field, + Operator: operator, + Value: apiValues, + } + if err := result.FromSecurityExceptionsAPIExceptionListItemEntryMatchAny(apiEntry); err != nil { + diags.AddError("Failed to create match_any entry", err.Error()) + } + + case "list": + // Validate required field + if entry.List.IsNull() || entry.List.IsUnknown() { + diags.AddError("Invalid Configuration", "Attribute 'list' is required when type is 'list'") + return result, diags + } + + var listModel EntryListModel + diags.Append(entry.List.As(ctx, &listModel, basetypes.ObjectAsOptions{})...) + if diags.HasError() { + return result, diags + } + apiEntry := kbapi.SecurityExceptionsAPIExceptionListItemEntryList{ + Type: "list", + Field: field, + Operator: operator, + } + apiEntry.List.Id = kbapi.SecurityExceptionsAPIListId(listModel.ID.ValueString()) + apiEntry.List.Type = kbapi.SecurityExceptionsAPIListType(listModel.Type.ValueString()) + if err := result.FromSecurityExceptionsAPIExceptionListItemEntryList(apiEntry); err != nil { + diags.AddError("Failed to create list entry", err.Error()) + } + + case "exists": + apiEntry := kbapi.SecurityExceptionsAPIExceptionListItemEntryExists{ + Type: "exists", + Field: field, + Operator: operator, + } + if err := result.FromSecurityExceptionsAPIExceptionListItemEntryExists(apiEntry); err != nil { + diags.AddError("Failed to create exists entry", err.Error()) + } + + case "wildcard": + // Validate required field + if entry.Value.IsNull() || entry.Value.IsUnknown() || entry.Value.ValueString() == "" { + diags.AddError("Invalid Configuration", "Attribute 'value' is required when type is 'wildcard'") + return result, diags + } + + apiEntry := kbapi.SecurityExceptionsAPIExceptionListItemEntryMatchWildcard{ + Type: "wildcard", + Field: field, + Operator: operator, + Value: kbapi.SecurityExceptionsAPINonEmptyString(entry.Value.ValueString()), + } + if err := result.FromSecurityExceptionsAPIExceptionListItemEntryMatchWildcard(apiEntry); err != nil { + diags.AddError("Failed to create wildcard entry", err.Error()) + } + + case "nested": + // Validate required field + if entry.Entries.IsNull() || entry.Entries.IsUnknown() { + diags.AddError("Invalid Configuration", "Attribute 'entries' is required when type is 'nested'") + return result, diags + } + + var nestedEntries []NestedEntryModel + diags.Append(entry.Entries.ElementsAs(ctx, &nestedEntries, false)...) + if diags.HasError() { + return result, diags + } + + if len(nestedEntries) == 0 { + diags.AddError("Invalid Configuration", "Attribute 'entries' must contain at least one entry when type is 'nested'") + return result, diags + } + + apiNestedEntries := make([]kbapi.SecurityExceptionsAPIExceptionListItemEntryNestedEntryItem, 0, len(nestedEntries)) + for _, ne := range nestedEntries { + nestedAPIEntry, d := convertNestedEntryToAPI(ctx, ne) + diags.Append(d...) + if d.HasError() { + continue + } + apiNestedEntries = append(apiNestedEntries, nestedAPIEntry) + } + + apiEntry := kbapi.SecurityExceptionsAPIExceptionListItemEntryNested{ + Type: "nested", + Field: field, + Entries: apiNestedEntries, + } + if err := result.FromSecurityExceptionsAPIExceptionListItemEntryNested(apiEntry); err != nil { + diags.AddError("Failed to create nested entry", err.Error()) + } + + default: + diags.AddError("Invalid entry type", fmt.Sprintf("Unknown entry type: %s", entryType)) + } + + return result, diags +} + +// convertNestedEntryToAPI converts a nested entry model to an API nested entry model +func convertNestedEntryToAPI(ctx context.Context, entry NestedEntryModel) (kbapi.SecurityExceptionsAPIExceptionListItemEntryNestedEntryItem, diag.Diagnostics) { + var diags diag.Diagnostics + var result kbapi.SecurityExceptionsAPIExceptionListItemEntryNestedEntryItem + + entryType := entry.Type.ValueString() + operator := kbapi.SecurityExceptionsAPIExceptionListItemEntryOperator(entry.Operator.ValueString()) + field := kbapi.SecurityExceptionsAPINonEmptyString(entry.Field.ValueString()) + + switch entryType { + case "match": + // Validate required field + if entry.Value.IsNull() || entry.Value.IsUnknown() || entry.Value.ValueString() == "" { + diags.AddError("Invalid Configuration", "Attribute 'value' is required for nested entry when type is 'match'") + return result, diags + } + + apiEntry := kbapi.SecurityExceptionsAPIExceptionListItemEntryMatch{ + Type: "match", + Field: field, + Operator: operator, + Value: kbapi.SecurityExceptionsAPINonEmptyString(entry.Value.ValueString()), + } + if err := result.FromSecurityExceptionsAPIExceptionListItemEntryMatch(apiEntry); err != nil { + diags.AddError("Failed to create nested match entry", err.Error()) + } + + case "match_any": + // Validate required field + if entry.Values.IsNull() || entry.Values.IsUnknown() { + diags.AddError("Invalid Configuration", "Attribute 'values' is required for nested entry when type is 'match_any'") + return result, diags + } + + var values []string + diags.Append(entry.Values.ElementsAs(ctx, &values, false)...) + if diags.HasError() { + return result, diags + } + + if len(values) == 0 { + diags.AddError("Invalid Configuration", "Attribute 'values' must contain at least one value for nested entry when type is 'match_any'") + return result, diags + } + + apiValues := make([]kbapi.SecurityExceptionsAPINonEmptyString, len(values)) + for i, v := range values { + apiValues[i] = kbapi.SecurityExceptionsAPINonEmptyString(v) + } + apiEntry := kbapi.SecurityExceptionsAPIExceptionListItemEntryMatchAny{ + Type: "match_any", + Field: field, + Operator: operator, + Value: apiValues, + } + if err := result.FromSecurityExceptionsAPIExceptionListItemEntryMatchAny(apiEntry); err != nil { + diags.AddError("Failed to create nested match_any entry", err.Error()) + } + + case "exists": + apiEntry := kbapi.SecurityExceptionsAPIExceptionListItemEntryExists{ + Type: "exists", + Field: field, + Operator: operator, + } + if err := result.FromSecurityExceptionsAPIExceptionListItemEntryExists(apiEntry); err != nil { + diags.AddError("Failed to create nested exists entry", err.Error()) + } + + default: + diags.AddError("Invalid nested entry type", fmt.Sprintf("Unknown nested entry type: %s. Only 'match', 'match_any', and 'exists' are allowed.", entryType)) + } + + return result, diags +} + +// convertEntriesFromAPI converts API entry models to Terraform entry models +func convertEntriesFromAPI(ctx context.Context, apiEntries kbapi.SecurityExceptionsAPIExceptionListItemEntryArray) (types.List, diag.Diagnostics) { + var diags diag.Diagnostics + + if len(apiEntries) == 0 { + return types.ListNull(types.ObjectType{ + AttrTypes: getEntryAttrTypes(), + }), diags + } + + entries := make([]EntryModel, 0, len(apiEntries)) + for _, apiEntry := range apiEntries { + entry, d := convertEntryFromAPI(ctx, apiEntry) + diags.Append(d...) + if d.HasError() { + continue + } + entries = append(entries, entry) + } + + list, d := types.ListValueFrom(ctx, types.ObjectType{ + AttrTypes: getEntryAttrTypes(), + }, entries) + diags.Append(d...) + return list, diags +} + +// convertEntryFromAPI converts a single API entry to a Terraform entry model +func convertEntryFromAPI(ctx context.Context, apiEntry kbapi.SecurityExceptionsAPIExceptionListItemEntry) (EntryModel, diag.Diagnostics) { + var diags diag.Diagnostics + var entry EntryModel + + // Marshal the entry back to JSON to inspect its type + entryBytes, err := apiEntry.MarshalJSON() + if err != nil { + diags.AddError("Failed to marshal entry", err.Error()) + return entry, diags + } + + // Try to unmarshal into a map to determine the type + var entryMap map[string]interface{} + if err := json.Unmarshal(entryBytes, &entryMap); err != nil { + diags.AddError("Failed to unmarshal entry", err.Error()) + return entry, diags + } + + entryType, ok := entryMap["type"].(string) + if !ok { + diags.AddError("Invalid entry", "Entry is missing 'type' field") + return entry, diags + } + + entry.Type = types.StringValue(entryType) + if field, ok := entryMap["field"].(string); ok { + entry.Field = types.StringValue(field) + } + if operator, ok := entryMap["operator"].(string); ok { + entry.Operator = types.StringValue(operator) + } + + switch entryType { + case "match", "wildcard": + if value, ok := entryMap["value"].(string); ok { + entry.Value = types.StringValue(value) + } else { + entry.Value = types.StringNull() + } + entry.Values = types.ListNull(types.StringType) + entry.List = types.ObjectNull(getListAttrTypes()) + entry.Entries = types.ListNull(types.ObjectType{AttrTypes: getNestedEntryAttrTypes()}) + + case "match_any": + if values, ok := entryMap["value"].([]interface{}); ok { + strValues := make([]string, 0, len(values)) + for _, v := range values { + if str, ok := v.(string); ok { + strValues = append(strValues, str) + } + } + list, d := types.ListValueFrom(ctx, types.StringType, strValues) + diags.Append(d...) + entry.Values = list + } else { + entry.Values = types.ListNull(types.StringType) + } + entry.Value = types.StringNull() + entry.List = types.ObjectNull(getListAttrTypes()) + entry.Entries = types.ListNull(types.ObjectType{AttrTypes: getNestedEntryAttrTypes()}) + + case "list": + if listData, ok := entryMap["list"].(map[string]interface{}); ok { + listModel := EntryListModel{ + ID: types.StringValue(listData["id"].(string)), + Type: types.StringValue(listData["type"].(string)), + } + obj, d := types.ObjectValueFrom(ctx, getListAttrTypes(), listModel) + diags.Append(d...) + entry.List = obj + } else { + entry.List = types.ObjectNull(getListAttrTypes()) + } + entry.Value = types.StringNull() + entry.Values = types.ListNull(types.StringType) + entry.Entries = types.ListNull(types.ObjectType{AttrTypes: getNestedEntryAttrTypes()}) + + case "exists": + entry.Value = types.StringNull() + entry.Values = types.ListNull(types.StringType) + entry.List = types.ObjectNull(getListAttrTypes()) + entry.Entries = types.ListNull(types.ObjectType{AttrTypes: getNestedEntryAttrTypes()}) + + case "nested": + // Nested entries don't have an operator field in the API + entry.Operator = types.StringNull() + if entriesData, ok := entryMap["entries"].([]interface{}); ok { + nestedEntries := make([]NestedEntryModel, 0, len(entriesData)) + for _, neData := range entriesData { + if neMap, ok := neData.(map[string]interface{}); ok { + ne, d := convertNestedEntryFromMap(ctx, neMap) + diags.Append(d...) + if !d.HasError() { + nestedEntries = append(nestedEntries, ne) + } + } + } + list, d := types.ListValueFrom(ctx, types.ObjectType{AttrTypes: getNestedEntryAttrTypes()}, nestedEntries) + diags.Append(d...) + entry.Entries = list + } else { + entry.Entries = types.ListNull(types.ObjectType{AttrTypes: getNestedEntryAttrTypes()}) + } + entry.Value = types.StringNull() + entry.Values = types.ListNull(types.StringType) + entry.List = types.ObjectNull(getListAttrTypes()) + } + + return entry, diags +} + +// convertNestedEntryFromMap converts a map representation of nested entry to a model +func convertNestedEntryFromMap(ctx context.Context, entryMap map[string]interface{}) (NestedEntryModel, diag.Diagnostics) { + var diags diag.Diagnostics + var entry NestedEntryModel + + if entryType, ok := entryMap["type"].(string); ok { + entry.Type = types.StringValue(entryType) + } + if field, ok := entryMap["field"].(string); ok { + entry.Field = types.StringValue(field) + } + if operator, ok := entryMap["operator"].(string); ok { + entry.Operator = types.StringValue(operator) + } + + entryType := entry.Type.ValueString() + switch entryType { + case "match": + if value, ok := entryMap["value"].(string); ok { + entry.Value = types.StringValue(value) + } else { + entry.Value = types.StringNull() + } + entry.Values = types.ListNull(types.StringType) + + case "match_any": + if values, ok := entryMap["value"].([]interface{}); ok { + strValues := make([]string, 0, len(values)) + for _, v := range values { + if str, ok := v.(string); ok { + strValues = append(strValues, str) + } + } + list, d := types.ListValueFrom(ctx, types.StringType, strValues) + diags.Append(d...) + entry.Values = list + } else { + entry.Values = types.ListNull(types.StringType) + } + entry.Value = types.StringNull() + + case "exists": + entry.Value = types.StringNull() + entry.Values = types.ListNull(types.StringType) + } + + return entry, diags +} + +// getEntryAttrTypes returns the attribute types for entry objects +func getEntryAttrTypes() map[string]attr.Type { + return map[string]attr.Type{ + "type": types.StringType, + "field": types.StringType, + "operator": types.StringType, + "value": types.StringType, + "values": types.ListType{ElemType: types.StringType}, + "list": types.ObjectType{AttrTypes: getListAttrTypes()}, + "entries": types.ListType{ElemType: types.ObjectType{AttrTypes: getNestedEntryAttrTypes()}}, + } +} + +// getListAttrTypes returns the attribute types for list objects +func getListAttrTypes() map[string]attr.Type { + return map[string]attr.Type{ + "id": types.StringType, + "type": types.StringType, + } +} + +// getNestedEntryAttrTypes returns the attribute types for nested entry objects +func getNestedEntryAttrTypes() map[string]attr.Type { + return map[string]attr.Type{ + "type": types.StringType, + "field": types.StringType, + "operator": types.StringType, + "value": types.StringType, + "values": types.ListType{ElemType: types.StringType}, + } +} diff --git a/internal/kibana/security_exception_item/read.go b/internal/kibana/security_exception_item/read.go new file mode 100644 index 000000000..2f2b24880 --- /dev/null +++ b/internal/kibana/security_exception_item/read.go @@ -0,0 +1,52 @@ +package security_exception_item + +import ( + "context" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *ExceptionItemResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state ExceptionItemModel + + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Read by ID + id := kbapi.SecurityExceptionsAPIExceptionListItemId(state.ID.ValueString()) + params := &kbapi.ReadExceptionListItemParams{ + Id: &id, + } + + readResp, diags := kibana_oapi.GetExceptionListItem(ctx, client, state.SpaceID.ValueString(), params) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if readResp == nil || readResp.JSON200 == nil { + resp.State.RemoveResource(ctx) + return + } + + // Update state with response + diags = r.updateStateFromAPIResponse(ctx, &state, readResp.JSON200) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + diags = resp.State.Set(ctx, state) + resp.Diagnostics.Append(diags...) +} diff --git a/internal/kibana/security_exception_item/resource-description.md b/internal/kibana/security_exception_item/resource-description.md new file mode 100644 index 000000000..7ad7c0a47 --- /dev/null +++ b/internal/kibana/security_exception_item/resource-description.md @@ -0,0 +1,3 @@ +Manages a Kibana Exception Item. Exception items define the specific query conditions used to prevent rules from generating alerts. + +See the [Kibana Exceptions API documentation](https://www.elastic.co/docs/api/doc/kibana/group/endpoint-security-exceptions-api) for more details. diff --git a/internal/kibana/security_exception_item/resource.go b/internal/kibana/security_exception_item/resource.go new file mode 100644 index 000000000..c03b7f15e --- /dev/null +++ b/internal/kibana/security_exception_item/resource.go @@ -0,0 +1,41 @@ +package security_exception_item + +import ( + "context" + "fmt" + + "github.com/elastic/terraform-provider-elasticstack/internal/clients" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +var ( + _ resource.Resource = &ExceptionItemResource{} + _ resource.ResourceWithConfigure = &ExceptionItemResource{} + _ resource.ResourceWithImportState = &ExceptionItemResource{} + _ resource.ResourceWithValidateConfig = &ExceptionItemResource{} +) + +// NewResource is a helper function to simplify the provider implementation. +func NewResource() resource.Resource { + return &ExceptionItemResource{} +} + +type ExceptionItemResource struct { + client *clients.ApiClient +} + +func (r *ExceptionItemResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + client, diags := clients.ConvertProviderData(req.ProviderData) + resp.Diagnostics.Append(diags...) + r.client = client +} + +// Metadata returns the provider type name. +func (r *ExceptionItemResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = fmt.Sprintf("%s_%s", req.ProviderTypeName, "kibana_security_exception_item") +} + +func (r *ExceptionItemResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), request, response) +} diff --git a/internal/kibana/security_exception_item/schema.go b/internal/kibana/security_exception_item/schema.go new file mode 100644 index 000000000..86d5d81e0 --- /dev/null +++ b/internal/kibana/security_exception_item/schema.go @@ -0,0 +1,246 @@ +package security_exception_item + +import ( + "context" + _ "embed" + + "github.com/elastic/terraform-provider-elasticstack/internal/utils/validators" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +//go:embed resource-description.md +var exceptionItemResourceDescription string + +func (r *ExceptionItemResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: exceptionItemResourceDescription, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + MarkdownDescription: "The unique identifier of the exception item (auto-generated by Kibana).", + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "space_id": schema.StringAttribute{ + MarkdownDescription: "An identifier for the space. If space_id is not provided, the default space is used.", + Optional: true, + Computed: true, + Default: stringdefault.StaticString("default"), + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "item_id": schema.StringAttribute{ + MarkdownDescription: "The exception item's human readable string identifier.", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + stringplanmodifier.UseStateForUnknown(), + }, + }, + "list_id": schema.StringAttribute{ + MarkdownDescription: "The exception list's identifier that this item belongs to.", + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "name": schema.StringAttribute{ + MarkdownDescription: "The name of the exception item.", + Required: true, + }, + "description": schema.StringAttribute{ + MarkdownDescription: "Describes the exception item.", + Required: true, + }, + "type": schema.StringAttribute{ + MarkdownDescription: "The type of exception item. Must be `simple`.", + Required: true, + Validators: []validator.String{ + stringvalidator.OneOf("simple"), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "namespace_type": schema.StringAttribute{ + MarkdownDescription: "Determines whether the exception item is available in all Kibana spaces or just the space in which it is created. Can be `single` (default) or `agnostic`.", + Optional: true, + Computed: true, + Default: stringdefault.StaticString("single"), + Validators: []validator.String{ + stringvalidator.OneOf("single", "agnostic"), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "os_types": schema.ListAttribute{ + MarkdownDescription: "Array of OS types for which the exceptions apply. Valid values: `linux`, `macos`, `windows`.", + Optional: true, + ElementType: types.StringType, + }, + "tags": schema.ListAttribute{ + MarkdownDescription: "String array containing words and phrases to help categorize exception items.", + Optional: true, + ElementType: types.StringType, + }, + "meta": schema.StringAttribute{ + MarkdownDescription: "Placeholder for metadata about the exception item as JSON string.", + Optional: true, + }, + "entries": schema.ListNestedAttribute{ + MarkdownDescription: "The exception item entries. This defines the conditions under which the exception applies.", + Required: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "type": schema.StringAttribute{ + MarkdownDescription: "The type of entry. Valid values: `match`, `match_any`, `list`, `exists`, `nested`, `wildcard`.", + Required: true, + Validators: []validator.String{ + stringvalidator.OneOf("match", "match_any", "list", "exists", "nested", "wildcard"), + }, + }, + "field": schema.StringAttribute{ + MarkdownDescription: "The field name. Required for all entry types.", + Required: true, + }, + "operator": schema.StringAttribute{ + MarkdownDescription: "The operator to use. Valid values: `included`, `excluded`. Note: The operator field is not supported for nested entry types and will be ignored if specified.", + Optional: true, + Validators: []validator.String{ + stringvalidator.OneOf("included", "excluded"), + }, + }, + "value": schema.StringAttribute{ + MarkdownDescription: "The value to match (for `match` and `wildcard` types).", + Optional: true, + Validators: []validator.String{ + validators.RequiredIfDependentPathOneOf( + path.Root("type"), + []string{"match", "wildcard"}, + ), + }, + }, + "values": schema.ListAttribute{ + ElementType: types.StringType, + MarkdownDescription: "Array of values to match (for `match_any` type).", + Optional: true, + }, + "list": schema.SingleNestedAttribute{ + MarkdownDescription: "Value list reference (for `list` type).", + Optional: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + MarkdownDescription: "The value list ID.", + Required: true, + }, + "type": schema.StringAttribute{ + MarkdownDescription: "The value list type (e.g., `keyword`, `ip`, `ip_range`).", + Required: true, + }, + }, + }, + "entries": schema.ListNestedAttribute{ + MarkdownDescription: "Nested entries (for `nested` type). Only `match`, `match_any`, and `exists` entry types are allowed as nested entries.", + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "type": schema.StringAttribute{ + MarkdownDescription: "The type of nested entry. Valid values: `match`, `match_any`, `exists`.", + Required: true, + Validators: []validator.String{ + stringvalidator.OneOf("match", "match_any", "exists"), + }, + }, + "field": schema.StringAttribute{ + MarkdownDescription: "The field name.", + Required: true, + }, + "operator": schema.StringAttribute{ + MarkdownDescription: "The operator to use. Valid values: `included`, `excluded`.", + Required: true, + Validators: []validator.String{ + stringvalidator.OneOf("included", "excluded"), + }, + }, + "value": schema.StringAttribute{ + MarkdownDescription: "The value to match (for `match` type).", + Optional: true, + Validators: []validator.String{ + validators.RequiredIfDependentPathOneOf( + path.Root("type"), + []string{"match"}, + ), + }, + }, + "values": schema.ListAttribute{ + ElementType: types.StringType, + MarkdownDescription: "Array of values to match (for `match_any` type).", + Optional: true, + Validators: []validator.List{ + validators.RequiredIfDependentPathOneOf( + path.Root("type"), + []string{"match_any"}, + ), + }, + }, + }, + }, + }, + }, + }, + }, + "comments": schema.ListNestedAttribute{ + MarkdownDescription: "Array of comments about the exception item.", + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + MarkdownDescription: "The unique identifier of the comment (auto-generated by Kibana).", + Computed: true, + }, + "comment": schema.StringAttribute{ + MarkdownDescription: "The comment text.", + Required: true, + }, + }, + }, + }, + "expire_time": schema.StringAttribute{ + MarkdownDescription: "The exception item's expiration date in RFC3339 format. This field is only available for regular exception items, not endpoint exceptions.", + Optional: true, + }, + "created_at": schema.StringAttribute{ + MarkdownDescription: "The timestamp of when the exception item was created.", + Computed: true, + }, + "created_by": schema.StringAttribute{ + MarkdownDescription: "The user who created the exception item.", + Computed: true, + }, + "updated_at": schema.StringAttribute{ + MarkdownDescription: "The timestamp of when the exception item was last updated.", + Computed: true, + }, + "updated_by": schema.StringAttribute{ + MarkdownDescription: "The user who last updated the exception item.", + Computed: true, + }, + "tie_breaker_id": schema.StringAttribute{ + MarkdownDescription: "Field used in search to ensure all items are sorted and returned correctly.", + Computed: true, + }, + }, + } +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItem/create/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItem/create/exception_item.tf new file mode 100644 index 000000000..383f279ae --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItem/create/exception_item.tf @@ -0,0 +1,65 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +variable "name" { + description = "The exception item name" + type = string +} + +variable "description" { + description = "The exception item description" + type = string +} + +variable "type" { + description = "The exception item type" + type = string +} + +variable "namespace_type" { + description = "The namespace type" + type = string +} + +variable "tags" { + description = "Tags for the exception item" + type = list(string) +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List for Item" + description = "Test exception list" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = var.name + description = var.description + type = var.type + namespace_type = var.namespace_type + entries = [ + { + type = "match" + field = "process.name" + operator = "included" + value = "test-process" + } + ] + tags = var.tags +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItem/update/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItem/update/exception_item.tf new file mode 100644 index 000000000..c3423ad43 --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItem/update/exception_item.tf @@ -0,0 +1,65 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +variable "name" { + description = "The exception item name" + type = string +} + +variable "description" { + description = "The exception item description" + type = string +} + +variable "type" { + description = "The exception item type" + type = string +} + +variable "namespace_type" { + description = "The namespace type" + type = string +} + +variable "tags" { + description = "Tags for the exception item" + type = list(string) +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List for Item" + description = "Test exception list" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = var.name + description = var.description + type = var.type + namespace_type = var.namespace_type + entries = [ + { + type = "match" + field = "process.name" + operator = "included" + value = "test-process-updated" + } + ] + tags = var.tags +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_Exists/exists/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_Exists/exists/exception_item.tf new file mode 100644 index 000000000..566d0809f --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_Exists/exists/exception_item.tf @@ -0,0 +1,39 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List for Exists Entry" + description = "Test exception list for exists entry type" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Exists Entry" + description = "Test exception item with exists entry type" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "exists" + field = "file.hash.sha256" + operator = "included" + } + ] + tags = ["test", "exists"] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_List/list/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_List/list/exception_item.tf new file mode 100644 index 000000000..caed9f9d5 --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_List/list/exception_item.tf @@ -0,0 +1,64 @@ +variable "exception_list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +variable "value_list_id" { + description = "The value list ID" + type = string +} +variable "value_list_value" { + description = "The value list value" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.exception_list_id + name = "Test Exception List for List Entry" + description = "Test exception list for list entry type" + type = "detection" + namespace_type = "single" +} +resource "elasticstack_kibana_security_list_item" "test-item" { + list_id = elasticstack_kibana_security_list.test.list_id + value = var.value_list_value +} + +# Create a value list to reference in the exception item +resource "elasticstack_kibana_security_list" "test" { + list_id = var.value_list_id + name = "Test Value List" + description = "Test value list for list entry type" + type = "ip" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - List Entry" + description = "Test exception item with list entry type" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "list" + field = "source.ip" + operator = "included" + list = { + id = elasticstack_kibana_security_list.test.list_id + type = "ip" + } + } + ] + tags = ["test", "list"] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_Match/match/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_Match/match/exception_item.tf new file mode 100644 index 000000000..72106432b --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_Match/match/exception_item.tf @@ -0,0 +1,40 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List for Match Entry" + description = "Test exception list for match entry type" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Match Entry" + description = "Test exception item with match entry type" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "match" + field = "process.name" + operator = "included" + value = "test-process" + } + ] + tags = ["test", "match"] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_MatchAny/match_any/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_MatchAny/match_any/exception_item.tf new file mode 100644 index 000000000..7564996cb --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_MatchAny/match_any/exception_item.tf @@ -0,0 +1,40 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List for Match Any Entry" + description = "Test exception list for match_any entry type" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Match Any Entry" + description = "Test exception item with match_any entry type" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "match_any" + field = "process.name" + operator = "included" + values = ["process1", "process2", "process3"] + } + ] + tags = ["test", "match_any"] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_Nested/nested/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_Nested/nested/exception_item.tf new file mode 100644 index 000000000..e1ad82dd8 --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_Nested/nested/exception_item.tf @@ -0,0 +1,46 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List for Nested Entry" + description = "Test exception list for nested entry type" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Nested Entry" + description = "Test exception item with nested entry type" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "nested" + field = "parent.field" + entries = [ + { + type = "match" + field = "nested.field" + operator = "included" + value = "nested-value" + } + ] + } + ] + tags = ["test", "nested"] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_Wildcard/wildcard/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_Wildcard/wildcard/exception_item.tf new file mode 100644 index 000000000..ea49b6e3d --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemEntryType_Wildcard/wildcard/exception_item.tf @@ -0,0 +1,40 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List for Wildcard Entry" + description = "Test exception list for wildcard entry type" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Wildcard Entry" + description = "Test exception item with wildcard entry type" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "wildcard" + field = "file.path" + operator = "included" + value = "/tmp/*.tmp" + } + ] + tags = ["test", "wildcard"] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_exists_missing_operator/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_exists_missing_operator/exception_item.tf new file mode 100644 index 000000000..7567268fc --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_exists_missing_operator/exception_item.tf @@ -0,0 +1,38 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Exists Missing Operator" + description = "Test validation: exists entry without operator" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "exists" + field = "file.hash.sha256" + # Missing operator - should trigger validation error + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_list_missing_list_id/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_list_missing_list_id/exception_item.tf new file mode 100644 index 000000000..f7e0e0f0d --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_list_missing_list_id/exception_item.tf @@ -0,0 +1,42 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - List Missing List ID" + description = "Test validation: list entry without list.id" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "list" + field = "source.ip" + operator = "included" + list = { + type = "ip" + # Missing id - should trigger validation error + } + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_list_missing_list_object/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_list_missing_list_object/exception_item.tf new file mode 100644 index 000000000..009f9397d --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_list_missing_list_object/exception_item.tf @@ -0,0 +1,39 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - List Missing List Object" + description = "Test validation: list entry without list object" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "list" + field = "source.ip" + operator = "included" + # Missing list object - should trigger validation error + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_list_missing_list_type/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_list_missing_list_type/exception_item.tf new file mode 100644 index 000000000..4e5b32275 --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_list_missing_list_type/exception_item.tf @@ -0,0 +1,42 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - List Missing List Type" + description = "Test validation: list entry without list.type" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "list" + field = "source.ip" + operator = "included" + list = { + id = "test-value-list" + # Missing type - should trigger validation error + } + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_match_any_missing_operator/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_match_any_missing_operator/exception_item.tf new file mode 100644 index 000000000..268dc730f --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_match_any_missing_operator/exception_item.tf @@ -0,0 +1,39 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - MatchAny Missing Operator" + description = "Test validation: match_any entry without operator" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "match_any" + field = "process.name" + values = ["process1", "process2"] + # Missing operator - should trigger validation error + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_match_any_missing_values/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_match_any_missing_values/exception_item.tf new file mode 100644 index 000000000..1b9618eb4 --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_match_any_missing_values/exception_item.tf @@ -0,0 +1,39 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - MatchAny Missing Values" + description = "Test validation: match_any entry without values" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "match_any" + field = "process.name" + operator = "included" + # Missing values - should trigger validation error + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_match_missing_operator/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_match_missing_operator/exception_item.tf new file mode 100644 index 000000000..f7ffd3fde --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_match_missing_operator/exception_item.tf @@ -0,0 +1,39 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Match Missing Operator" + description = "Test validation: match entry without operator" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "match" + field = "process.name" + value = "test-process" + # Missing operator - should trigger validation error + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_match_missing_value/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_match_missing_value/exception_item.tf new file mode 100644 index 000000000..e21b8daae --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_match_missing_value/exception_item.tf @@ -0,0 +1,39 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Match Missing Value" + description = "Test validation: match entry without value" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "match" + field = "process.name" + operator = "included" + # Missing value - should trigger validation error + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_nested_entry_missing_operator/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_nested_entry_missing_operator/exception_item.tf new file mode 100644 index 000000000..0408f440c --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_nested_entry_missing_operator/exception_item.tf @@ -0,0 +1,45 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Nested Entry Missing Operator" + description = "Test validation: nested match entry without operator" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "nested" + field = "parent.field" + entries = [ + { + type = "match" + field = "nested.field" + value = "test-value" + # Missing operator - should trigger validation error + } + ] + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_nested_entry_missing_value/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_nested_entry_missing_value/exception_item.tf new file mode 100644 index 000000000..0a293ec6c --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_nested_entry_missing_value/exception_item.tf @@ -0,0 +1,45 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Nested Entry Missing Value" + description = "Test validation: nested match entry without value" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "nested" + field = "parent.field" + entries = [ + { + type = "match" + field = "nested.field" + operator = "included" + # Missing value - should trigger validation error + } + ] + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_nested_invalid_entry_type/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_nested_invalid_entry_type/exception_item.tf new file mode 100644 index 000000000..bcbbfaa94 --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_nested_invalid_entry_type/exception_item.tf @@ -0,0 +1,45 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Nested Invalid Entry Type" + description = "Test validation: nested entry with invalid nested entry type (wildcard)" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "nested" + field = "parent.field" + entries = [ + { + type = "wildcard" + field = "nested.field" + operator = "included" + value = "test*" + } + ] + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_nested_missing_entries/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_nested_missing_entries/exception_item.tf new file mode 100644 index 000000000..ce02051eb --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_nested_missing_entries/exception_item.tf @@ -0,0 +1,38 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Nested Missing Entries" + description = "Test validation: nested entry without entries" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "nested" + field = "parent.field" + # Missing entries - should trigger validation error + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_wildcard_missing_value/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_wildcard_missing_value/exception_item.tf new file mode 100644 index 000000000..de6fc230d --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemValidation/validation_wildcard_missing_value/exception_item.tf @@ -0,0 +1,39 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = "Test Exception List" + description = "Test exception list for validation" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = "Test Exception Item - Wildcard Missing Value" + description = "Test validation: wildcard entry without value" + type = "simple" + namespace_type = "single" + entries = [ + { + type = "wildcard" + field = "file.path" + operator = "included" + # Missing value - should trigger validation error + } + ] +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemWithSpace/create/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemWithSpace/create/exception_item.tf new file mode 100644 index 000000000..c5a4f0a32 --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemWithSpace/create/exception_item.tf @@ -0,0 +1,73 @@ +variable "space_id" { + description = "The Kibana space ID" + type = string +} + +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +variable "name" { + description = "The exception item name" + type = string +} + +variable "description" { + description = "The exception item description" + type = string +} + +variable "type" { + description = "The exception item type" + type = string +} + +variable "namespace_type" { + description = "The namespace type" + type = string +} + +variable "tags" { + description = "Tags for the exception item" + type = list(string) +} + +resource "elasticstack_kibana_space" "test" { + space_id = var.space_id + name = "Test Space for Exception Items" + description = "Space for testing exception items" +} + +resource "elasticstack_kibana_security_exception_list" "test" { + space_id = elasticstack_kibana_space.test.space_id + list_id = var.list_id + name = "Test Exception List for Item" + description = "Test exception list" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + space_id = elasticstack_kibana_space.test.space_id + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = var.name + description = var.description + type = var.type + namespace_type = var.namespace_type + entries = [ + { + type = "match" + field = "process.name" + operator = "included" + value = "test-process-space" + } + ] + tags = var.tags +} diff --git a/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemWithSpace/update/exception_item.tf b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemWithSpace/update/exception_item.tf new file mode 100644 index 000000000..e27275925 --- /dev/null +++ b/internal/kibana/security_exception_item/testdata/TestAccResourceExceptionItemWithSpace/update/exception_item.tf @@ -0,0 +1,73 @@ +variable "space_id" { + description = "The Kibana space ID" + type = string +} + +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "item_id" { + description = "The exception item ID" + type = string +} + +variable "name" { + description = "The exception item name" + type = string +} + +variable "description" { + description = "The exception item description" + type = string +} + +variable "type" { + description = "The exception item type" + type = string +} + +variable "namespace_type" { + description = "The namespace type" + type = string +} + +variable "tags" { + description = "Tags for the exception item" + type = list(string) +} + +resource "elasticstack_kibana_space" "test" { + space_id = var.space_id + name = "Test Space for Exception Items" + description = "Space for testing exception items" +} + +resource "elasticstack_kibana_security_exception_list" "test" { + space_id = elasticstack_kibana_space.test.space_id + list_id = var.list_id + name = "Test Exception List for Item" + description = "Test exception list" + type = "detection" + namespace_type = "single" +} + +resource "elasticstack_kibana_security_exception_item" "test" { + space_id = elasticstack_kibana_space.test.space_id + list_id = elasticstack_kibana_security_exception_list.test.list_id + item_id = var.item_id + name = var.name + description = var.description + type = var.type + namespace_type = var.namespace_type + entries = [ + { + type = "match" + field = "process.name" + operator = "included" + value = "test-process-space-updated" + } + ] + tags = var.tags +} diff --git a/internal/kibana/security_exception_item/update.go b/internal/kibana/security_exception_item/update.go new file mode 100644 index 000000000..abebae6c2 --- /dev/null +++ b/internal/kibana/security_exception_item/update.go @@ -0,0 +1,164 @@ +package security_exception_item + +import ( + "context" + "encoding/json" + "time" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/elastic/terraform-provider-elasticstack/internal/utils" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *ExceptionItemResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var plan ExceptionItemModel + + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Convert entries from Terraform model to API model + entries, diags := convertEntriesToAPI(ctx, plan.Entries) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + // Build the update request body + id := kbapi.SecurityExceptionsAPIExceptionListItemId(plan.ID.ValueString()) + body := kbapi.UpdateExceptionListItemJSONRequestBody{ + Id: &id, + Name: kbapi.SecurityExceptionsAPIExceptionListItemName(plan.Name.ValueString()), + Description: kbapi.SecurityExceptionsAPIExceptionListItemDescription(plan.Description.ValueString()), + Type: kbapi.SecurityExceptionsAPIExceptionListItemType(plan.Type.ValueString()), + Entries: entries, + } + + // Set optional namespace_type + if utils.IsKnown(plan.NamespaceType) { + nsType := kbapi.SecurityExceptionsAPIExceptionNamespaceType(plan.NamespaceType.ValueString()) + body.NamespaceType = &nsType + } + + // Set optional os_types + if utils.IsKnown(plan.OsTypes) && !plan.OsTypes.IsNull() { + var osTypes []string + diags := plan.OsTypes.ElementsAs(ctx, &osTypes, false) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + if len(osTypes) > 0 { + osTypesArray := make(kbapi.SecurityExceptionsAPIExceptionListItemOsTypeArray, len(osTypes)) + for i, osType := range osTypes { + osTypesArray[i] = kbapi.SecurityExceptionsAPIExceptionListOsType(osType) + } + body.OsTypes = &osTypesArray + } + } + + // Set optional tags + if utils.IsKnown(plan.Tags) && !plan.Tags.IsNull() { + var tags []string + diags := plan.Tags.ElementsAs(ctx, &tags, false) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + if len(tags) > 0 { + tagsArray := kbapi.SecurityExceptionsAPIExceptionListItemTags(tags) + body.Tags = &tagsArray + } + } + + // Set optional meta + if utils.IsKnown(plan.Meta) && !plan.Meta.IsNull() { + var meta kbapi.SecurityExceptionsAPIExceptionListItemMeta + if err := json.Unmarshal([]byte(plan.Meta.ValueString()), &meta); err != nil { + resp.Diagnostics.AddError("Failed to parse meta JSON", err.Error()) + return + } + body.Meta = &meta + } + + // Set optional comments + if utils.IsKnown(plan.Comments) && !plan.Comments.IsNull() { + var comments []CommentModel + diags := plan.Comments.ElementsAs(ctx, &comments, false) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + if len(comments) > 0 { + commentsArray := make(kbapi.SecurityExceptionsAPIUpdateExceptionListItemCommentArray, len(comments)) + for i, comment := range comments { + commentsArray[i] = kbapi.SecurityExceptionsAPIUpdateExceptionListItemComment{ + Comment: kbapi.SecurityExceptionsAPINonEmptyString(comment.Comment.ValueString()), + } + } + body.Comments = &commentsArray + } + } + + // Set optional expire_time + if utils.IsKnown(plan.ExpireTime) && !plan.ExpireTime.IsNull() { + expireTime, err := time.Parse(time.RFC3339, plan.ExpireTime.ValueString()) + if err != nil { + resp.Diagnostics.AddError("Failed to parse expire_time", err.Error()) + return + } + expireTimeAPI := kbapi.SecurityExceptionsAPIExceptionListItemExpireTime(expireTime) + body.ExpireTime = &expireTimeAPI + } + + // Update the exception item + updateResp, diags := kibana_oapi.UpdateExceptionListItem(ctx, client, plan.SpaceID.ValueString(), body) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if updateResp == nil || updateResp.JSON200 == nil { + resp.Diagnostics.AddError("Failed to update exception item", "API returned empty response") + return + } + + /* + * In create/update paths we typically follow the write operation with a read, and then set the state from the read. + * We want to avoid a dirty plan immediately after an apply. + */ + // Read back the updated resource to get the final state + readParams := &kbapi.ReadExceptionListItemParams{ + Id: (*kbapi.SecurityExceptionsAPIExceptionListItemId)(&updateResp.JSON200.Id), + } + + readResp, diags := kibana_oapi.GetExceptionListItem(ctx, client, plan.SpaceID.ValueString(), readParams) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if readResp == nil || readResp.JSON200 == nil { + resp.State.RemoveResource(ctx) + return + } + + // Update state with read response + diags = r.updateStateFromAPIResponse(ctx, &plan, readResp.JSON200) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + diags = resp.State.Set(ctx, plan) + resp.Diagnostics.Append(diags...) +} diff --git a/internal/kibana/security_exception_item/validate.go b/internal/kibana/security_exception_item/validate.go new file mode 100644 index 000000000..77d060e6a --- /dev/null +++ b/internal/kibana/security_exception_item/validate.go @@ -0,0 +1,226 @@ +package security_exception_item + +import ( + "context" + "fmt" + + "github.com/elastic/terraform-provider-elasticstack/internal/utils" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// ValidateConfig validates the configuration for an exception item resource. +// It ensures that entries are properly configured based on their type: +// +// - For "match" and "wildcard" types: 'value' must be set +// - For "match_any" type: 'values' must be set +// - For "list" type: 'list' object must be set with 'id' and 'type' +// - For "exists" type: only 'field' and 'operator' are required +// - For "nested" type: 'entries' must be set and validated recursively +// - The 'operator' field is required for all types except "nested" +// +// Validation only runs on known values. Values that are unknown (e.g., references to +// other resources that haven't been created yet) are skipped. +// +// The function adds appropriate error diagnostics if validation fails. +func (r *ExceptionItemResource) ValidateConfig(ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse) { + var data ExceptionItemModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Validate entries + if !utils.IsKnown(data.Entries) { + return + } + + var entries []EntryModel + resp.Diagnostics.Append(data.Entries.ElementsAs(ctx, &entries, false)...) + if resp.Diagnostics.HasError() { + return + } + + for i, entry := range entries { + validateEntry(ctx, entry, i, &resp.Diagnostics, "entries") + } +} + +// validateEntry validates a single entry based on its type +func validateEntry(ctx context.Context, entry EntryModel, index int, diags *diag.Diagnostics, path string) { + if !utils.IsKnown(entry.Type) { + return + } + + entryType := entry.Type.ValueString() + entryPath := fmt.Sprintf("%s[%d]", path, index) + + switch entryType { + case "match", "wildcard": + // 'value' is required (only validate if not unknown) + if entry.Value.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Entry type '%s' requires 'value' to be set at %s.", entryType, entryPath), + ) + } + // 'operator' is required (only validate if not unknown) + if entry.Operator.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Entry type '%s' requires 'operator' to be set at %s.", entryType, entryPath), + ) + } + + case "match_any": + // 'values' is required (only validate if not unknown) + if entry.Values.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Entry type 'match_any' requires 'values' to be set at %s.", entryPath), + ) + } + // 'operator' is required (only validate if not unknown) + if entry.Operator.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Entry type 'match_any' requires 'operator' to be set at %s.", entryPath), + ) + } + + case "list": + // 'list' object is required (only validate if not unknown) + if entry.List.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Entry type 'list' requires 'list' object to be set at %s.", entryPath), + ) + } else if !entry.List.IsUnknown() { + // Only validate list contents if the list object itself is known + var listModel EntryListModel + d := entry.List.As(ctx, &listModel, basetypes.ObjectAsOptions{}) + if d.HasError() { + diags.Append(d...) + } else { + // Only validate if the values are not unknown + if listModel.ID.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Entry type 'list' requires 'list.id' to be set at %s.", entryPath), + ) + } + + if listModel.Type.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Entry type 'list' requires 'list.type' to be set at %s.", entryPath), + ) + } + } + } + // 'operator' is required (only validate if not unknown) + if entry.Operator.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Entry type 'list' requires 'operator' to be set at %s.", entryPath), + ) + } + + case "exists": + // Only 'field' and 'operator' are required (already handled by schema) + // 'operator' is required (only validate if not unknown) + if entry.Operator.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Entry type 'exists' requires 'operator' to be set at %s.", entryPath), + ) + } + + case "nested": + // 'entries' is required for nested type (only validate if not unknown) + if entry.Entries.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Entry type 'nested' requires 'entries' to be set at %s.", entryPath), + ) + return + } + + // Skip validation if entries are unknown + if entry.Entries.IsUnknown() { + return + } + + // 'operator' should NOT be set for nested type + if utils.IsKnown(entry.Operator) { + diags.AddWarning( + "Ignored Field", + fmt.Sprintf("Entry type 'nested' does not support 'operator'. This field will be ignored at %s.", entryPath), + ) + } + + // Validate nested entries + var nestedEntries []NestedEntryModel + d := entry.Entries.ElementsAs(ctx, &nestedEntries, false) + if d.HasError() { + diags.Append(d...) + return + } + + for j, nestedEntry := range nestedEntries { + validateNestedEntry(ctx, nestedEntry, j, diags, fmt.Sprintf("%s.entries", entryPath)) + } + } +} + +// validateNestedEntry validates a nested entry within a "nested" type entry +func validateNestedEntry(ctx context.Context, entry NestedEntryModel, index int, diags *diag.Diagnostics, path string) { + if !utils.IsKnown(entry.Type) { + return + } + + entryType := entry.Type.ValueString() + entryPath := fmt.Sprintf("%s[%d]", path, index) + + // Nested entries can only be: match, match_any, or exists + switch entryType { + case "match": + // 'value' is required (only validate if not unknown) + if entry.Value.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Nested entry type 'match' requires 'value' to be set at %s.", entryPath), + ) + } + + case "match_any": + // 'values' is required (only validate if not unknown) + if entry.Values.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Nested entry type 'match_any' requires 'values' to be set at %s.", entryPath), + ) + } + + case "exists": + // Only 'field' and 'operator' are required (already handled by schema) + // Nothing additional to validate + + default: + diags.AddError( + "Invalid Entry Type", + fmt.Sprintf("Nested entry at %s has invalid type '%s'. Only 'match', 'match_any', and 'exists' are allowed for nested entries.", entryPath, entryType), + ) + } + + // 'operator' is always required for nested entries (only validate if not unknown) + if entry.Operator.IsNull() { + diags.AddError( + "Missing Required Field", + fmt.Sprintf("Nested entry requires 'operator' to be set at %s.", entryPath), + ) + } +} diff --git a/internal/kibana/security_exception_list/acc_test.go b/internal/kibana/security_exception_list/acc_test.go new file mode 100644 index 000000000..89059330d --- /dev/null +++ b/internal/kibana/security_exception_list/acc_test.go @@ -0,0 +1,136 @@ +package security_exception_list_test + +import ( + "fmt" + "testing" + + "github.com/elastic/terraform-provider-elasticstack/internal/acctest" + "github.com/elastic/terraform-provider-elasticstack/internal/versionutils" + "github.com/google/uuid" + "github.com/hashicorp/go-version" + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +var minExceptionListAPISupport = version.Must(version.NewVersion("7.9.0")) + +func TestAccResourceExceptionList(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionListAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("create"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable("test-exception-list"), + "name": config.StringVariable("Test Exception List"), + "description": config.StringVariable("Test exception list for acceptance tests"), + "type": config.StringVariable("detection"), + "namespace_type": config.StringVariable("single"), + "tags": config.ListVariable(config.StringVariable("test")), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_list.test", "list_id", "test-exception-list"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_list.test", "name", "Test Exception List"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_list.test", "description", "Test exception list for acceptance tests"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_list.test", "type", "detection"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_list.test", "namespace_type", "single"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_list.test", "tags.0", "test"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_exception_list.test", "id"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_exception_list.test", "created_at"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_exception_list.test", "created_by"), + ), + }, + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionListAPISupport), + ProtoV6ProviderFactories: acctest.Providers, + ConfigDirectory: acctest.NamedTestCaseDirectory("update"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable("test-exception-list"), + "name": config.StringVariable("Test Exception List Updated"), + "description": config.StringVariable("Updated description"), + "type": config.StringVariable("detection"), + "namespace_type": config.StringVariable("single"), + "tags": config.ListVariable(config.StringVariable("test"), config.StringVariable("updated")), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_list.test", "name", "Test Exception List Updated"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_list.test", "description", "Updated description"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_list.test", "tags.0", "test"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_exception_list.test", "tags.1", "updated"), + ), + }, + }, + }) +} + +func TestAccResourceExceptionListWithSpace(t *testing.T) { + resourceName := "elasticstack_kibana_security_exception_list.test" + spaceResourceName := "elasticstack_kibana_space.test" + spaceID := fmt.Sprintf("test-space-%s", uuid.New().String()[:8]) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProtoV6ProviderFactories: acctest.Providers, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionListAPISupport), + ConfigDirectory: acctest.NamedTestCaseDirectory("create"), + ConfigVariables: config.Variables{ + "space_id": config.StringVariable(spaceID), + "list_id": config.StringVariable("test-exception-list-space"), + "name": config.StringVariable("Test Exception List in Space"), + "description": config.StringVariable("Test exception list in custom space"), + "type": config.StringVariable("detection"), + "namespace_type": config.StringVariable("single"), + "tags": config.ListVariable(config.StringVariable("test"), config.StringVariable("space")), + }, + Check: resource.ComposeTestCheckFunc( + // Check space attributes + resource.TestCheckResourceAttr(spaceResourceName, "space_id", spaceID), + resource.TestCheckResourceAttr(spaceResourceName, "name", "Test Space for Exception Lists"), + + // Check exception list attributes + resource.TestCheckResourceAttr(resourceName, "space_id", spaceID), + resource.TestCheckResourceAttr(resourceName, "list_id", "test-exception-list-space"), + resource.TestCheckResourceAttr(resourceName, "name", "Test Exception List in Space"), + resource.TestCheckResourceAttr(resourceName, "description", "Test exception list in custom space"), + resource.TestCheckResourceAttr(resourceName, "type", "detection"), + resource.TestCheckResourceAttr(resourceName, "namespace_type", "single"), + resource.TestCheckResourceAttr(resourceName, "tags.0", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.1", "space"), + resource.TestCheckResourceAttrSet(resourceName, "id"), + resource.TestCheckResourceAttrSet(resourceName, "created_at"), + resource.TestCheckResourceAttrSet(resourceName, "created_by"), + ), + }, + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minExceptionListAPISupport), + ConfigDirectory: acctest.NamedTestCaseDirectory("update"), + ConfigVariables: config.Variables{ + "space_id": config.StringVariable(spaceID), + "list_id": config.StringVariable("test-exception-list-space"), + "name": config.StringVariable("Test Exception List in Space Updated"), + "description": config.StringVariable("Updated description in space"), + "type": config.StringVariable("detection"), + "namespace_type": config.StringVariable("single"), + "tags": config.ListVariable(config.StringVariable("test"), config.StringVariable("space"), config.StringVariable("updated")), + }, + Check: resource.ComposeTestCheckFunc( + // Check space attributes remain the same + resource.TestCheckResourceAttr(spaceResourceName, "space_id", spaceID), + resource.TestCheckResourceAttr(spaceResourceName, "name", "Test Space for Exception Lists"), + + // Check updated exception list attributes + resource.TestCheckResourceAttr(resourceName, "space_id", spaceID), + resource.TestCheckResourceAttr(resourceName, "name", "Test Exception List in Space Updated"), + resource.TestCheckResourceAttr(resourceName, "description", "Updated description in space"), + resource.TestCheckResourceAttr(resourceName, "tags.0", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.1", "space"), + resource.TestCheckResourceAttr(resourceName, "tags.2", "updated"), + ), + }, + }, + }) +} diff --git a/internal/kibana/security_exception_list/create.go b/internal/kibana/security_exception_list/create.go new file mode 100644 index 000000000..93a34a38c --- /dev/null +++ b/internal/kibana/security_exception_list/create.go @@ -0,0 +1,180 @@ +package security_exception_list + +import ( + "context" + "encoding/json" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/elastic/terraform-provider-elasticstack/internal/utils" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func (r *ExceptionListResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var plan ExceptionListModel + + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Build the request body + body := kbapi.CreateExceptionListJSONRequestBody{ + ListId: (*kbapi.SecurityExceptionsAPIExceptionListHumanId)(plan.ListID.ValueStringPointer()), + Name: kbapi.SecurityExceptionsAPIExceptionListName(plan.Name.ValueString()), + Description: kbapi.SecurityExceptionsAPIExceptionListDescription(plan.Description.ValueString()), + Type: kbapi.SecurityExceptionsAPIExceptionListType(plan.Type.ValueString()), + } + + // Set optional namespace_type + if utils.IsKnown(plan.NamespaceType) { + nsType := kbapi.SecurityExceptionsAPIExceptionNamespaceType(plan.NamespaceType.ValueString()) + body.NamespaceType = &nsType + } + + // Set optional os_types + if utils.IsKnown(plan.OsTypes) && !plan.OsTypes.IsNull() { + var osTypes []string + diags := plan.OsTypes.ElementsAs(ctx, &osTypes, false) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + if len(osTypes) > 0 { + osTypesArray := make(kbapi.SecurityExceptionsAPIExceptionListOsTypeArray, len(osTypes)) + for i, osType := range osTypes { + osTypesArray[i] = kbapi.SecurityExceptionsAPIExceptionListOsType(osType) + } + body.OsTypes = &osTypesArray + } + } + + // Set optional tags + if utils.IsKnown(plan.Tags) && !plan.Tags.IsNull() { + var tags []string + diags := plan.Tags.ElementsAs(ctx, &tags, false) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + if len(tags) > 0 { + tagsArray := kbapi.SecurityExceptionsAPIExceptionListTags(tags) + body.Tags = &tagsArray + } + } + + // Set optional meta + if utils.IsKnown(plan.Meta) && !plan.Meta.IsNull() { + var meta kbapi.SecurityExceptionsAPIExceptionListMeta + if err := json.Unmarshal([]byte(plan.Meta.ValueString()), &meta); err != nil { + resp.Diagnostics.AddError("Failed to parse meta JSON", err.Error()) + return + } + body.Meta = &meta + } + + // Create the exception list + createResp, diags := kibana_oapi.CreateExceptionList(ctx, client, plan.SpaceID.ValueString(), body) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if createResp == nil || createResp.JSON200 == nil { + resp.Diagnostics.AddError("Failed to create exception list", "API returned empty response") + return + } + + /* + * In create/update paths we typically follow the write operation with a read, and then set the state from the read. + * We want to avoid a dirty plan immediately after an apply. + */ + // Read back the created resource to get the final state + readParams := &kbapi.ReadExceptionListParams{ + Id: (*kbapi.SecurityExceptionsAPIExceptionListId)(&createResp.JSON200.Id), + } + + readResp, diags := kibana_oapi.GetExceptionList(ctx, client, plan.SpaceID.ValueString(), readParams) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if readResp == nil || readResp.JSON200 == nil { + resp.State.RemoveResource(ctx) + return + } + + // Update state with read response + diags = r.updateStateFromAPIResponse(ctx, &plan, readResp.JSON200) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + diags = resp.State.Set(ctx, plan) + resp.Diagnostics.Append(diags...) +} + +func (r *ExceptionListResource) updateStateFromAPIResponse(ctx context.Context, model *ExceptionListModel, apiResp *kbapi.SecurityExceptionsAPIExceptionList) diag.Diagnostics { + var diags diag.Diagnostics + + model.ID = types.StringValue(string(apiResp.Id)) + model.ListID = types.StringValue(string(apiResp.ListId)) + model.Name = types.StringValue(string(apiResp.Name)) + model.Description = types.StringValue(string(apiResp.Description)) + model.Type = types.StringValue(string(apiResp.Type)) + model.NamespaceType = types.StringValue(string(apiResp.NamespaceType)) + model.CreatedAt = types.StringValue(apiResp.CreatedAt.Format("2006-01-02T15:04:05.000Z")) + model.CreatedBy = types.StringValue(apiResp.CreatedBy) + model.UpdatedAt = types.StringValue(apiResp.UpdatedAt.Format("2006-01-02T15:04:05.000Z")) + model.UpdatedBy = types.StringValue(apiResp.UpdatedBy) + model.Immutable = types.BoolValue(apiResp.Immutable) + model.TieBreakerID = types.StringValue(apiResp.TieBreakerId) + + // Set optional os_types + if apiResp.OsTypes != nil && len(*apiResp.OsTypes) > 0 { + // osTypes := make([]string, len(*apiResp.OsTypes)) + // for i, osType := range *apiResp.OsTypes { + // osTypes[i] = string(osType) + // } + // list, d := types.ListValueFrom(ctx, types.StringType, osTypes) + list, d := types.ListValueFrom(ctx, types.StringType, apiResp.OsTypes) + diags.Append(d...) + model.OsTypes = list + } else { + model.OsTypes = types.ListNull(types.StringType) + } + + // Set optional tags + if apiResp.Tags != nil && len(*apiResp.Tags) > 0 { + list, d := types.ListValueFrom(ctx, types.StringType, *apiResp.Tags) + diags.Append(d...) + model.Tags = list + } else { + model.Tags = types.ListNull(types.StringType) + } + + // Set optional meta + if apiResp.Meta != nil { + metaJSON, err := json.Marshal(apiResp.Meta) + if err != nil { + diags.AddError("Failed to serialize meta", err.Error()) + return diags + } + model.Meta = types.StringValue(string(metaJSON)) + } else { + model.Meta = types.StringNull() + } + + return diags +} diff --git a/internal/kibana/security_exception_list/delete.go b/internal/kibana/security_exception_list/delete.go new file mode 100644 index 000000000..0c2b34b96 --- /dev/null +++ b/internal/kibana/security_exception_list/delete.go @@ -0,0 +1,34 @@ +package security_exception_list + +import ( + "context" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *ExceptionListResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state ExceptionListModel + + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Delete by ID + id := kbapi.SecurityExceptionsAPIExceptionListId(state.ID.ValueString()) + params := &kbapi.DeleteExceptionListParams{ + Id: &id, + } + + diags = kibana_oapi.DeleteExceptionList(ctx, client, state.SpaceID.ValueString(), params) + resp.Diagnostics.Append(diags...) +} diff --git a/internal/kibana/security_exception_list/models.go b/internal/kibana/security_exception_list/models.go new file mode 100644 index 000000000..5e97aa9f9 --- /dev/null +++ b/internal/kibana/security_exception_list/models.go @@ -0,0 +1,24 @@ +package security_exception_list + +import ( + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type ExceptionListModel struct { + ID types.String `tfsdk:"id"` + SpaceID types.String `tfsdk:"space_id"` + ListID types.String `tfsdk:"list_id"` + Name types.String `tfsdk:"name"` + Description types.String `tfsdk:"description"` + Type types.String `tfsdk:"type"` + NamespaceType types.String `tfsdk:"namespace_type"` + OsTypes types.List `tfsdk:"os_types"` + Tags types.List `tfsdk:"tags"` + Meta types.String `tfsdk:"meta"` + CreatedAt types.String `tfsdk:"created_at"` + CreatedBy types.String `tfsdk:"created_by"` + UpdatedAt types.String `tfsdk:"updated_at"` + UpdatedBy types.String `tfsdk:"updated_by"` + Immutable types.Bool `tfsdk:"immutable"` + TieBreakerID types.String `tfsdk:"tie_breaker_id"` +} diff --git a/internal/kibana/security_exception_list/read.go b/internal/kibana/security_exception_list/read.go new file mode 100644 index 000000000..1ace40cb5 --- /dev/null +++ b/internal/kibana/security_exception_list/read.go @@ -0,0 +1,52 @@ +package security_exception_list + +import ( + "context" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *ExceptionListResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state ExceptionListModel + + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Read by ID + id := kbapi.SecurityExceptionsAPIExceptionListId(state.ID.ValueString()) + params := &kbapi.ReadExceptionListParams{ + Id: &id, + } + + readResp, diags := kibana_oapi.GetExceptionList(ctx, client, state.SpaceID.ValueString(), params) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if readResp == nil || readResp.JSON200 == nil { + resp.State.RemoveResource(ctx) + return + } + + // Update state with response + diags = r.updateStateFromAPIResponse(ctx, &state, readResp.JSON200) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + diags = resp.State.Set(ctx, state) + resp.Diagnostics.Append(diags...) +} diff --git a/internal/kibana/security_exception_list/resource-description.md b/internal/kibana/security_exception_list/resource-description.md new file mode 100644 index 000000000..d773a038b --- /dev/null +++ b/internal/kibana/security_exception_list/resource-description.md @@ -0,0 +1,3 @@ +Manages a Kibana Exception List. Exception lists are containers for exception items used to prevent security rules from generating alerts. + +See the [Kibana Exceptions API documentation](https://www.elastic.co/docs/api/doc/kibana/group/endpoint-security-exceptions-api) for more details. diff --git a/internal/kibana/security_exception_list/resource.go b/internal/kibana/security_exception_list/resource.go new file mode 100644 index 000000000..03b5c3a71 --- /dev/null +++ b/internal/kibana/security_exception_list/resource.go @@ -0,0 +1,40 @@ +package security_exception_list + +import ( + "context" + "fmt" + + "github.com/elastic/terraform-provider-elasticstack/internal/clients" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +var ( + _ resource.Resource = &ExceptionListResource{} + _ resource.ResourceWithConfigure = &ExceptionListResource{} + _ resource.ResourceWithImportState = &ExceptionListResource{} +) + +// NewResource is a helper function to simplify the provider implementation. +func NewResource() resource.Resource { + return &ExceptionListResource{} +} + +type ExceptionListResource struct { + client *clients.ApiClient +} + +func (r *ExceptionListResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + client, diags := clients.ConvertProviderData(req.ProviderData) + resp.Diagnostics.Append(diags...) + r.client = client +} + +// Metadata returns the provider type name. +func (r *ExceptionListResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = fmt.Sprintf("%s_%s", req.ProviderTypeName, "kibana_security_exception_list") +} + +func (r *ExceptionListResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), request, response) +} diff --git a/internal/kibana/security_exception_list/schema.go b/internal/kibana/security_exception_list/schema.go new file mode 100644 index 000000000..8d1f934a6 --- /dev/null +++ b/internal/kibana/security_exception_list/schema.go @@ -0,0 +1,124 @@ +package security_exception_list + +import ( + "context" + _ "embed" + + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +//go:embed resource-description.md +var exceptionListResourceDescription string + +func (r *ExceptionListResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: exceptionListResourceDescription, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + MarkdownDescription: "The unique identifier of the exception list (auto-generated by Kibana).", + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "space_id": schema.StringAttribute{ + MarkdownDescription: "An identifier for the space. If space_id is not provided, the default space is used.", + Optional: true, + Computed: true, + Default: stringdefault.StaticString("default"), + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "list_id": schema.StringAttribute{ + MarkdownDescription: "The exception list's human readable string identifier.", + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "name": schema.StringAttribute{ + MarkdownDescription: "The name of the exception list.", + Required: true, + }, + "description": schema.StringAttribute{ + MarkdownDescription: "Describes the exception list.", + Required: true, + }, + "type": schema.StringAttribute{ + MarkdownDescription: "The type of exception list. Can be one of: `detection`, `endpoint`, `endpoint_trusted_apps`, `endpoint_events`, `endpoint_host_isolation_exceptions`, `endpoint_blocklists`.", + Required: true, + Validators: []validator.String{ + stringvalidator.OneOf( + "detection", + "endpoint", + "endpoint_trusted_apps", + "endpoint_events", + "endpoint_host_isolation_exceptions", + "endpoint_blocklists", + ), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "namespace_type": schema.StringAttribute{ + MarkdownDescription: "Determines whether the exception list is available in all Kibana spaces or just the space in which it is created. Can be `single` (default) or `agnostic`.", + Optional: true, + Computed: true, + Default: stringdefault.StaticString("single"), + Validators: []validator.String{ + stringvalidator.OneOf("single", "agnostic"), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "os_types": schema.ListAttribute{ + MarkdownDescription: "Array of OS types for which the exceptions apply. Valid values: `linux`, `macos`, `windows`.", + Optional: true, + ElementType: types.StringType, + }, + "tags": schema.ListAttribute{ + MarkdownDescription: "String array containing words and phrases to help categorize exception containers.", + Optional: true, + ElementType: types.StringType, + }, + "meta": schema.StringAttribute{ + MarkdownDescription: "Placeholder for metadata about the list container as JSON string.", + Optional: true, + }, + "created_at": schema.StringAttribute{ + MarkdownDescription: "The timestamp of when the exception list was created.", + Computed: true, + }, + "created_by": schema.StringAttribute{ + MarkdownDescription: "The user who created the exception list.", + Computed: true, + }, + "updated_at": schema.StringAttribute{ + MarkdownDescription: "The timestamp of when the exception list was last updated.", + Computed: true, + }, + "updated_by": schema.StringAttribute{ + MarkdownDescription: "The user who last updated the exception list.", + Computed: true, + }, + "immutable": schema.BoolAttribute{ + MarkdownDescription: "Whether the exception list is immutable.", + Computed: true, + }, + "tie_breaker_id": schema.StringAttribute{ + MarkdownDescription: "Field used in search to ensure all containers are sorted and returned correctly.", + Computed: true, + }, + }, + } +} diff --git a/internal/kibana/security_exception_list/testdata/TestAccResourceExceptionList/create/exception_list.tf b/internal/kibana/security_exception_list/testdata/TestAccResourceExceptionList/create/exception_list.tf new file mode 100644 index 000000000..06adaccef --- /dev/null +++ b/internal/kibana/security_exception_list/testdata/TestAccResourceExceptionList/create/exception_list.tf @@ -0,0 +1,43 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "name" { + description = "The exception list name" + type = string +} + +variable "description" { + description = "The exception list description" + type = string +} + +variable "type" { + description = "The exception list type" + type = string +} + +variable "namespace_type" { + description = "The namespace type" + type = string +} + +variable "tags" { + description = "Tags for the exception list" + type = list(string) +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = var.name + description = var.description + type = var.type + namespace_type = var.namespace_type + tags = var.tags +} diff --git a/internal/kibana/security_exception_list/testdata/TestAccResourceExceptionList/update/exception_list.tf b/internal/kibana/security_exception_list/testdata/TestAccResourceExceptionList/update/exception_list.tf new file mode 100644 index 000000000..06adaccef --- /dev/null +++ b/internal/kibana/security_exception_list/testdata/TestAccResourceExceptionList/update/exception_list.tf @@ -0,0 +1,43 @@ +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "name" { + description = "The exception list name" + type = string +} + +variable "description" { + description = "The exception list description" + type = string +} + +variable "type" { + description = "The exception list type" + type = string +} + +variable "namespace_type" { + description = "The namespace type" + type = string +} + +variable "tags" { + description = "Tags for the exception list" + type = list(string) +} + +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_kibana_security_exception_list" "test" { + list_id = var.list_id + name = var.name + description = var.description + type = var.type + namespace_type = var.namespace_type + tags = var.tags +} diff --git a/internal/kibana/security_exception_list/testdata/TestAccResourceExceptionListWithSpace/create/exception_list.tf b/internal/kibana/security_exception_list/testdata/TestAccResourceExceptionListWithSpace/create/exception_list.tf new file mode 100644 index 000000000..c9122eb0f --- /dev/null +++ b/internal/kibana/security_exception_list/testdata/TestAccResourceExceptionListWithSpace/create/exception_list.tf @@ -0,0 +1,50 @@ +variable "space_id" { + description = "The Kibana space ID" + type = string +} + +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "name" { + description = "The exception list name" + type = string +} + +variable "description" { + description = "The exception list description" + type = string +} + +variable "type" { + description = "The exception list type" + type = string +} + +variable "namespace_type" { + description = "The namespace type" + type = string +} + +variable "tags" { + description = "Tags for the exception list" + type = list(string) +} + +resource "elasticstack_kibana_space" "test" { + space_id = var.space_id + name = "Test Space for Exception Lists" + description = "Space for testing exception lists" +} + +resource "elasticstack_kibana_security_exception_list" "test" { + space_id = elasticstack_kibana_space.test.space_id + list_id = var.list_id + name = var.name + description = var.description + type = var.type + namespace_type = var.namespace_type + tags = var.tags +} diff --git a/internal/kibana/security_exception_list/testdata/TestAccResourceExceptionListWithSpace/update/exception_list.tf b/internal/kibana/security_exception_list/testdata/TestAccResourceExceptionListWithSpace/update/exception_list.tf new file mode 100644 index 000000000..c9122eb0f --- /dev/null +++ b/internal/kibana/security_exception_list/testdata/TestAccResourceExceptionListWithSpace/update/exception_list.tf @@ -0,0 +1,50 @@ +variable "space_id" { + description = "The Kibana space ID" + type = string +} + +variable "list_id" { + description = "The exception list ID" + type = string +} + +variable "name" { + description = "The exception list name" + type = string +} + +variable "description" { + description = "The exception list description" + type = string +} + +variable "type" { + description = "The exception list type" + type = string +} + +variable "namespace_type" { + description = "The namespace type" + type = string +} + +variable "tags" { + description = "Tags for the exception list" + type = list(string) +} + +resource "elasticstack_kibana_space" "test" { + space_id = var.space_id + name = "Test Space for Exception Lists" + description = "Space for testing exception lists" +} + +resource "elasticstack_kibana_security_exception_list" "test" { + space_id = elasticstack_kibana_space.test.space_id + list_id = var.list_id + name = var.name + description = var.description + type = var.type + namespace_type = var.namespace_type + tags = var.tags +} diff --git a/internal/kibana/security_exception_list/update.go b/internal/kibana/security_exception_list/update.go new file mode 100644 index 000000000..328e9c37f --- /dev/null +++ b/internal/kibana/security_exception_list/update.go @@ -0,0 +1,127 @@ +package security_exception_list + +import ( + "context" + "encoding/json" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/elastic/terraform-provider-elasticstack/internal/utils" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *ExceptionListResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var plan ExceptionListModel + + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Build the update request body + id := kbapi.SecurityExceptionsAPIExceptionListId(plan.ID.ValueString()) + body := kbapi.UpdateExceptionListJSONRequestBody{ + Id: &id, + Name: kbapi.SecurityExceptionsAPIExceptionListName(plan.Name.ValueString()), + Description: kbapi.SecurityExceptionsAPIExceptionListDescription(plan.Description.ValueString()), + // Type is required by the API even though it has RequiresReplace in the schema + // The API will reject updates without this field, even though the value cannot change + Type: kbapi.SecurityExceptionsAPIExceptionListType(plan.Type.ValueString()), + } + + // Set optional namespace_type (should not change, but include it) + if utils.IsKnown(plan.NamespaceType) { + nsType := kbapi.SecurityExceptionsAPIExceptionNamespaceType(plan.NamespaceType.ValueString()) + body.NamespaceType = &nsType + } + + // Set optional os_types + if utils.IsKnown(plan.OsTypes) && !plan.OsTypes.IsNull() { + var osTypes []string + diags := plan.OsTypes.ElementsAs(ctx, &osTypes, false) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + if len(osTypes) > 0 { + osTypesArray := make(kbapi.SecurityExceptionsAPIExceptionListOsTypeArray, len(osTypes)) + for i, osType := range osTypes { + osTypesArray[i] = kbapi.SecurityExceptionsAPIExceptionListOsType(osType) + } + body.OsTypes = &osTypesArray + } + } + + // Set optional tags + if utils.IsKnown(plan.Tags) && !plan.Tags.IsNull() { + var tags []string + diags := plan.Tags.ElementsAs(ctx, &tags, false) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + if len(tags) > 0 { + tagsArray := kbapi.SecurityExceptionsAPIExceptionListTags(tags) + body.Tags = &tagsArray + } + } + + // Set optional meta + if utils.IsKnown(plan.Meta) && !plan.Meta.IsNull() { + var meta kbapi.SecurityExceptionsAPIExceptionListMeta + if err := json.Unmarshal([]byte(plan.Meta.ValueString()), &meta); err != nil { + resp.Diagnostics.AddError("Failed to parse meta JSON", err.Error()) + return + } + body.Meta = &meta + } + + // Update the exception list + updateResp, diags := kibana_oapi.UpdateExceptionList(ctx, client, plan.SpaceID.ValueString(), body) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if updateResp == nil || updateResp.JSON200 == nil { + resp.Diagnostics.AddError("Failed to update exception list", "API returned empty response") + return + } + + /* + * In create/update paths we typically follow the write operation with a read, and then set the state from the read. + * We want to avoid a dirty plan immediately after an apply. + */ + // Read back the updated resource to get the final state + readParams := &kbapi.ReadExceptionListParams{ + Id: (*kbapi.SecurityExceptionsAPIExceptionListId)(&updateResp.JSON200.Id), + } + + readResp, diags := kibana_oapi.GetExceptionList(ctx, client, plan.SpaceID.ValueString(), readParams) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if readResp == nil || readResp.JSON200 == nil { + resp.State.RemoveResource(ctx) + return + } + + // Update state with read response + diags = r.updateStateFromAPIResponse(ctx, &plan, readResp.JSON200) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + diags = resp.State.Set(ctx, plan) + resp.Diagnostics.Append(diags...) +} diff --git a/internal/kibana/security_list/acc_test.go b/internal/kibana/security_list/acc_test.go new file mode 100644 index 000000000..e9dc7c1d7 --- /dev/null +++ b/internal/kibana/security_list/acc_test.go @@ -0,0 +1,105 @@ +package security_list_test + +import ( + "context" + "testing" + + "github.com/elastic/terraform-provider-elasticstack/internal/acctest" + "github.com/elastic/terraform-provider-elasticstack/internal/clients" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func ensureListIndexExists(t *testing.T) { + client, err := clients.NewAcceptanceTestingClient() + if err != nil { + t.Fatalf("Failed to create client: %v", err) + } + + kibanaClient, err := client.GetKibanaOapiClient() + if err != nil { + t.Fatalf("Failed to get Kibana client: %v", err) + } + + diags := kibana_oapi.CreateListIndex(context.Background(), kibanaClient, "default") + if diags.HasError() { + // It's OK if it already exists, we'll only fail on other errors + for _, d := range diags { + if d.Summary() != "Unexpected status code from server: got HTTP 409" { + t.Fatalf("Failed to create list index: %v", d.Detail()) + } + } + } +} + +func TestAccResourceSecurityList(t *testing.T) { + listID := "test-list-" + uuid.New().String() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + ensureListIndexExists(t) + }, + ProtoV6ProviderFactories: acctest.Providers, + Steps: []resource.TestStep{ + { // Create + ConfigDirectory: acctest.NamedTestCaseDirectory("create"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "name": config.StringVariable("Test Security List"), + "description": config.StringVariable("A test security list for IP addresses"), + "type": config.StringVariable("ip"), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list.test", "id"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_list.test", "name", "Test Security List"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_list.test", "description", "A test security list for IP addresses"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_list.test", "type", "ip"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list.test", "created_at"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list.test", "created_by"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list.test", "updated_at"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list.test", "updated_by"), + ), + }, + { // Update + ConfigDirectory: acctest.NamedTestCaseDirectory("update"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "name": config.StringVariable("Updated Security List"), + "description": config.StringVariable("An updated test security list"), + "type": config.StringVariable("ip"), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_list.test", "name", "Updated Security List"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_list.test", "description", "An updated test security list"), + ), + }, + }, + }) +} + +func TestAccResourceSecurityList_KeywordType(t *testing.T) { + listID := "keyword-list-" + uuid.New().String() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + ensureListIndexExists(t) + }, + ProtoV6ProviderFactories: acctest.Providers, + Steps: []resource.TestStep{ + { + ConfigDirectory: acctest.NamedTestCaseDirectory("keyword_type"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "name": config.StringVariable("Keyword Security List"), + "description": config.StringVariable("A test security list for keywords"), + "type": config.StringVariable("keyword"), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_list.test", "type", "keyword"), + ), + }, + }, + }) +} diff --git a/internal/kibana/security_list/create.go b/internal/kibana/security_list/create.go new file mode 100644 index 000000000..969e09567 --- /dev/null +++ b/internal/kibana/security_list/create.go @@ -0,0 +1,69 @@ +package security_list + +import ( + "context" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *securityListResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var plan SecurityListModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + // Get Kibana client + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Convert plan to API request + createReq, diags := plan.toCreateRequest() + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + // Create the list + spaceID := plan.SpaceID.ValueString() + createResp, diags := kibana_oapi.CreateList(ctx, client, spaceID, *createReq) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if createResp == nil || createResp.JSON200 == nil { + resp.Diagnostics.AddError("Failed to create security list", "API returned empty response") + return + } + + // Read the created list to populate state + readParams := &kbapi.ReadListParams{ + Id: createResp.JSON200.Id, + } + + readResp, diags := kibana_oapi.GetList(ctx, client, spaceID, readParams) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if readResp == nil || readResp.JSON200 == nil { + resp.State.RemoveResource(ctx) + return + } + + // Update state with read response + diags = plan.fromAPI(ctx, readResp.JSON200) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) +} diff --git a/internal/kibana/security_list/delete.go b/internal/kibana/security_list/delete.go new file mode 100644 index 000000000..a532b38f3 --- /dev/null +++ b/internal/kibana/security_list/delete.go @@ -0,0 +1,33 @@ +package security_list + +import ( + "context" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *securityListResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state SecurityListModel + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + spaceID := state.SpaceID.ValueString() + listID := state.ListID.ValueString() + + params := &kbapi.DeleteListParams{ + Id: kbapi.SecurityListsAPIListId(listID), + } + + diags := kibana_oapi.DeleteList(ctx, client, spaceID, params) + resp.Diagnostics.Append(diags...) +} diff --git a/internal/kibana/security_list/models.go b/internal/kibana/security_list/models.go new file mode 100644 index 000000000..f2524bd3c --- /dev/null +++ b/internal/kibana/security_list/models.go @@ -0,0 +1,154 @@ +package security_list + +import ( + "context" + "encoding/json" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type SecurityListModel struct { + ID types.String `tfsdk:"id"` + SpaceID types.String `tfsdk:"space_id"` + ListID types.String `tfsdk:"list_id"` + Name types.String `tfsdk:"name"` + Description types.String `tfsdk:"description"` + Type types.String `tfsdk:"type"` + Deserializer types.String `tfsdk:"deserializer"` + Serializer types.String `tfsdk:"serializer"` + Meta types.String `tfsdk:"meta"` + Version types.Int64 `tfsdk:"version"` + VersionID types.String `tfsdk:"version_id"` + Immutable types.Bool `tfsdk:"immutable"` + CreatedAt types.String `tfsdk:"created_at"` + CreatedBy types.String `tfsdk:"created_by"` + UpdatedAt types.String `tfsdk:"updated_at"` + UpdatedBy types.String `tfsdk:"updated_by"` + TieBreakerID types.String `tfsdk:"tie_breaker_id"` +} + +// toCreateRequest converts the Terraform model to API create request +func (m *SecurityListModel) toCreateRequest() (*kbapi.CreateListJSONRequestBody, diag.Diagnostics) { + var diags diag.Diagnostics + req := &kbapi.CreateListJSONRequestBody{ + Name: kbapi.SecurityListsAPIListName(m.Name.ValueString()), + Description: kbapi.SecurityListsAPIListDescription(m.Description.ValueString()), + Type: kbapi.SecurityListsAPIListType(m.Type.ValueString()), + } + + // Set optional fields + if !m.ListID.IsNull() && !m.ListID.IsUnknown() { + id := kbapi.SecurityListsAPIListId(m.ListID.ValueString()) + req.Id = &id + } + + if !m.Deserializer.IsNull() && !m.Deserializer.IsUnknown() { + deserializer := kbapi.SecurityListsAPIListDeserializer(m.Deserializer.ValueString()) + req.Deserializer = &deserializer + } + + if !m.Serializer.IsNull() && !m.Serializer.IsUnknown() { + serializer := kbapi.SecurityListsAPIListSerializer(m.Serializer.ValueString()) + req.Serializer = &serializer + } + + if !m.Meta.IsNull() && !m.Meta.IsUnknown() { + var metaMap kbapi.SecurityListsAPIListMetadata + if err := json.Unmarshal([]byte(m.Meta.ValueString()), &metaMap); err != nil { + diags.AddError("Invalid meta JSON", err.Error()) + return nil, diags + } + req.Meta = &metaMap + } + + if !m.Version.IsNull() && !m.Version.IsUnknown() { + version := int(m.Version.ValueInt64()) + req.Version = &version + } + + return req, diags +} + +// toUpdateRequest converts the Terraform model to API update request +func (m *SecurityListModel) toUpdateRequest() (*kbapi.UpdateListJSONRequestBody, diag.Diagnostics) { + var diags diag.Diagnostics + req := &kbapi.UpdateListJSONRequestBody{ + Id: kbapi.SecurityListsAPIListId(m.ListID.ValueString()), + Name: kbapi.SecurityListsAPIListName(m.Name.ValueString()), + Description: kbapi.SecurityListsAPIListDescription(m.Description.ValueString()), + } + + // Set optional fields + if !m.VersionID.IsNull() && !m.VersionID.IsUnknown() { + versionID := kbapi.SecurityListsAPIListVersionId(m.VersionID.ValueString()) + req.UnderscoreVersion = &versionID + } + + if !m.Meta.IsNull() && !m.Meta.IsUnknown() { + var metaMap kbapi.SecurityListsAPIListMetadata + if err := json.Unmarshal([]byte(m.Meta.ValueString()), &metaMap); err != nil { + diags.AddError("Invalid meta JSON", err.Error()) + return nil, diags + } + req.Meta = &metaMap + } + + if !m.Version.IsNull() && !m.Version.IsUnknown() { + version := kbapi.SecurityListsAPIListVersion(m.Version.ValueInt64()) + req.Version = &version + } + + return req, diags +} + +// fromAPI converts the API response to Terraform model +func (m *SecurityListModel) fromAPI(ctx context.Context, apiList *kbapi.SecurityListsAPIList) diag.Diagnostics { + var diags diag.Diagnostics + + m.ID = types.StringValue(string(apiList.Id)) + m.ListID = types.StringValue(string(apiList.Id)) + m.Name = types.StringValue(string(apiList.Name)) + m.Description = types.StringValue(string(apiList.Description)) + m.Type = types.StringValue(string(apiList.Type)) + m.Immutable = types.BoolValue(apiList.Immutable) + m.Version = types.Int64Value(int64(apiList.Version)) + m.TieBreakerID = types.StringValue(apiList.TieBreakerId) + m.CreatedAt = types.StringValue(apiList.CreatedAt.String()) + m.CreatedBy = types.StringValue(apiList.CreatedBy) + m.UpdatedAt = types.StringValue(apiList.UpdatedAt.String()) + m.UpdatedBy = types.StringValue(apiList.UpdatedBy) + + // Set optional _version field + if apiList.UnderscoreVersion != nil { + m.VersionID = types.StringValue(string(*apiList.UnderscoreVersion)) + } else { + m.VersionID = types.StringNull() + } + + if apiList.Deserializer != nil { + m.Deserializer = types.StringValue(string(*apiList.Deserializer)) + } else { + m.Deserializer = types.StringNull() + } + + if apiList.Serializer != nil { + m.Serializer = types.StringValue(string(*apiList.Serializer)) + } else { + m.Serializer = types.StringNull() + } + + if apiList.Meta != nil { + metaBytes, err := json.Marshal(apiList.Meta) + if err != nil { + diags.AddError("Failed to marshal meta", err.Error()) + return diags + } + m.Meta = types.StringValue(string(metaBytes)) + } else { + m.Meta = types.StringNull() + } + + return diags +} diff --git a/internal/kibana/security_list/read.go b/internal/kibana/security_list/read.go new file mode 100644 index 000000000..b5027401e --- /dev/null +++ b/internal/kibana/security_list/read.go @@ -0,0 +1,50 @@ +package security_list + +import ( + "context" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *securityListResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state SecurityListModel + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + spaceID := state.SpaceID.ValueString() + listID := state.ListID.ValueString() + + params := &kbapi.ReadListParams{ + Id: kbapi.SecurityListsAPIListId(listID), + } + + readResp, diags := kibana_oapi.GetList(ctx, client, spaceID, params) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if readResp == nil || readResp.JSON200 == nil { + resp.State.RemoveResource(ctx) + return + } + + // Convert API response to model + diags = state.fromAPI(ctx, readResp.JSON200) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, state)...) +} diff --git a/internal/kibana/security_list/resource-description.md b/internal/kibana/security_list/resource-description.md new file mode 100644 index 000000000..9b67b4e12 --- /dev/null +++ b/internal/kibana/security_list/resource-description.md @@ -0,0 +1,27 @@ +Manages Kibana security lists (also known as value lists). Security lists are used by exception items to define sets of values for matching or excluding in security rules. + +## Example Usage + +```terraform +resource "elasticstack_kibana_security_list" "ip_list" { + space_id = "default" + name = "Trusted IP Addresses" + description = "List of trusted IP addresses for security rules" + type = "ip" +} + +resource "elasticstack_kibana_security_list" "keyword_list" { + space_id = "security" + list_id = "custom-keywords" + name = "Custom Keywords" + description = "Custom keyword list for detection rules" + type = "keyword" +} +``` + +## Notes + +- Security lists define the type of data they can contain via the `type` attribute +- Once created, the `type` of a list cannot be changed +- Lists can be referenced by exception items to create more sophisticated matching rules +- The `list_id` is auto-generated if not provided diff --git a/internal/kibana/security_list/resource.go b/internal/kibana/security_list/resource.go new file mode 100644 index 000000000..51d6ad1a6 --- /dev/null +++ b/internal/kibana/security_list/resource.go @@ -0,0 +1,38 @@ +package security_list + +import ( + "context" + + "github.com/elastic/terraform-provider-elasticstack/internal/clients" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +// Ensure provider defined types fully satisfy framework interfaces +var ( + _ resource.Resource = &securityListResource{} + _ resource.ResourceWithConfigure = &securityListResource{} + _ resource.ResourceWithImportState = &securityListResource{} +) + +func NewResource() resource.Resource { + return &securityListResource{} +} + +type securityListResource struct { + client *clients.ApiClient +} + +func (r *securityListResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_kibana_security_list" +} + +func (r *securityListResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + client, diags := clients.ConvertProviderData(req.ProviderData) + resp.Diagnostics.Append(diags...) + r.client = client +} + +func (r *securityListResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), request, response) +} diff --git a/internal/kibana/security_list/schema.go b/internal/kibana/security_list/schema.go new file mode 100644 index 000000000..318dd87d8 --- /dev/null +++ b/internal/kibana/security_list/schema.go @@ -0,0 +1,122 @@ +package security_list + +import ( + "context" + _ "embed" + + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +//go:embed resource-description.md +var securityListResourceDescription string + +func (r *securityListResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: securityListResourceDescription, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + MarkdownDescription: "The unique identifier of the security list (auto-generated by Kibana if not specified).", + Computed: true, + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + stringplanmodifier.UseStateForUnknown(), + }, + }, + "space_id": schema.StringAttribute{ + MarkdownDescription: "An identifier for the space. If space_id is not provided, the default space is used.", + Optional: true, + Computed: true, + Default: stringdefault.StaticString("default"), + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "list_id": schema.StringAttribute{ + MarkdownDescription: "The value list's human-readable identifier.", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + stringplanmodifier.UseStateForUnknown(), + }, + }, + "name": schema.StringAttribute{ + MarkdownDescription: "The name of the security list.", + Required: true, + }, + "description": schema.StringAttribute{ + MarkdownDescription: "Describes the security list.", + Required: true, + }, + "type": schema.StringAttribute{ + MarkdownDescription: "Specifies the Elasticsearch data type of values the list contains. Valid values include: `binary`, `boolean`, `byte`, `date`, `date_nanos`, `date_range`, `double`, `double_range`, `float`, `float_range`, `geo_point`, `geo_shape`, `half_float`, `integer`, `integer_range`, `ip`, `ip_range`, `keyword`, `long`, `long_range`, `shape`, `short`, `text`.", + Required: true, + Validators: []validator.String{ + stringvalidator.OneOf( + "binary", "boolean", "byte", "date", "date_nanos", "date_range", + "double", "double_range", "float", "float_range", "geo_point", "geo_shape", + "half_float", "integer", "integer_range", "ip", "ip_range", "keyword", + "long", "long_range", "shape", "short", "text", + ), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "deserializer": schema.StringAttribute{ + MarkdownDescription: "Determines how retrieved list item values are presented. By default, list items are presented using Handlebars expressions based on the type.", + Optional: true, + Computed: true, + }, + "serializer": schema.StringAttribute{ + MarkdownDescription: "Determines how uploaded list item values are parsed. By default, list items are parsed using named regex groups based on the type.", + Optional: true, + Computed: true, + }, + "meta": schema.StringAttribute{ + MarkdownDescription: "Placeholder for metadata about the value list as JSON string.", + Optional: true, + }, + "version": schema.Int64Attribute{ + MarkdownDescription: "The document version number.", + Optional: true, + Computed: true, + }, + "version_id": schema.StringAttribute{ + MarkdownDescription: "The version id, normally returned by the API when the document is retrieved.", + Computed: true, + }, + "immutable": schema.BoolAttribute{ + MarkdownDescription: "Whether the list is immutable.", + Computed: true, + }, + "created_at": schema.StringAttribute{ + MarkdownDescription: "The timestamp of when the list was created.", + Computed: true, + }, + "created_by": schema.StringAttribute{ + MarkdownDescription: "The user who created the list.", + Computed: true, + }, + "updated_at": schema.StringAttribute{ + MarkdownDescription: "The timestamp of when the list was last updated.", + Computed: true, + }, + "updated_by": schema.StringAttribute{ + MarkdownDescription: "The user who last updated the list.", + Computed: true, + }, + "tie_breaker_id": schema.StringAttribute{ + MarkdownDescription: "Field used in search to ensure all containers are sorted and returned correctly.", + Computed: true, + }, + }, + } +} diff --git a/internal/kibana/security_list/testdata/TestAccResourceSecurityList/create/main.tf b/internal/kibana/security_list/testdata/TestAccResourceSecurityList/create/main.tf new file mode 100644 index 000000000..8d7acc2eb --- /dev/null +++ b/internal/kibana/security_list/testdata/TestAccResourceSecurityList/create/main.tf @@ -0,0 +1,22 @@ +variable "list_id" { + type = string +} + +variable "name" { + type = string +} + +variable "description" { + type = string +} + +variable "type" { + type = string +} + +resource "elasticstack_kibana_security_list" "test" { + list_id = var.list_id + name = var.name + description = var.description + type = var.type +} diff --git a/internal/kibana/security_list/testdata/TestAccResourceSecurityList/update/main.tf b/internal/kibana/security_list/testdata/TestAccResourceSecurityList/update/main.tf new file mode 100644 index 000000000..8d7acc2eb --- /dev/null +++ b/internal/kibana/security_list/testdata/TestAccResourceSecurityList/update/main.tf @@ -0,0 +1,22 @@ +variable "list_id" { + type = string +} + +variable "name" { + type = string +} + +variable "description" { + type = string +} + +variable "type" { + type = string +} + +resource "elasticstack_kibana_security_list" "test" { + list_id = var.list_id + name = var.name + description = var.description + type = var.type +} diff --git a/internal/kibana/security_list/testdata/TestAccResourceSecurityList_KeywordType/keyword_type/main.tf b/internal/kibana/security_list/testdata/TestAccResourceSecurityList_KeywordType/keyword_type/main.tf new file mode 100644 index 000000000..8d7acc2eb --- /dev/null +++ b/internal/kibana/security_list/testdata/TestAccResourceSecurityList_KeywordType/keyword_type/main.tf @@ -0,0 +1,22 @@ +variable "list_id" { + type = string +} + +variable "name" { + type = string +} + +variable "description" { + type = string +} + +variable "type" { + type = string +} + +resource "elasticstack_kibana_security_list" "test" { + list_id = var.list_id + name = var.name + description = var.description + type = var.type +} diff --git a/internal/kibana/security_list/update.go b/internal/kibana/security_list/update.go new file mode 100644 index 000000000..d545d92da --- /dev/null +++ b/internal/kibana/security_list/update.go @@ -0,0 +1,80 @@ +package security_list + +import ( + "context" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *securityListResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var plan SecurityListModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + var state SecurityListModel + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + // Preserve version_id from state for optimistic locking + if state.VersionID.ValueString() != "" { + plan.VersionID = state.VersionID + } + + // Convert plan to API request + updateReq, diags := plan.toUpdateRequest() + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + // Get Kibana client + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Update the list + spaceID := plan.SpaceID.ValueString() + updateResp, diags := kibana_oapi.UpdateList(ctx, client, spaceID, *updateReq) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if updateResp == nil || updateResp.JSON200 == nil { + resp.Diagnostics.AddError("Failed to update security list", "API returned empty response") + return + } + + // Read the updated list to populate state + readParams := &kbapi.ReadListParams{ + Id: updateResp.JSON200.Id, + } + + readResp, diags := kibana_oapi.GetList(ctx, client, spaceID, readParams) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if readResp == nil || readResp.JSON200 == nil { + resp.State.RemoveResource(ctx) + return + } + + // Update state with read response + diags = plan.fromAPI(ctx, readResp.JSON200) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) +} diff --git a/internal/kibana/security_list_item/acc_test.go b/internal/kibana/security_list_item/acc_test.go new file mode 100644 index 000000000..34168a453 --- /dev/null +++ b/internal/kibana/security_list_item/acc_test.go @@ -0,0 +1,73 @@ +package security_list_item_test + +import ( + "context" + "testing" + + "github.com/elastic/terraform-provider-elasticstack/internal/acctest" + "github.com/elastic/terraform-provider-elasticstack/internal/clients" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func ensureListIndexExists(t *testing.T) { + client, err := clients.NewAcceptanceTestingClient() + if err != nil { + t.Fatalf("Failed to create client: %v", err) + } + + kibanaClient, err := client.GetKibanaOapiClient() + if err != nil { + t.Fatalf("Failed to get Kibana client: %v", err) + } + + diags := kibana_oapi.CreateListIndex(context.Background(), kibanaClient, "default") + if diags.HasError() { + // It's OK if it already exists, we'll only fail on other errors + for _, d := range diags { + if d.Summary() != "Unexpected status code from server: got HTTP 409" { + t.Fatalf("Failed to create list index: %v", d.Detail()) + } + } + } +} + +func TestAccResourceSecurityListItem(t *testing.T) { + listID := "test-list-items-" + uuid.New().String() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + ensureListIndexExists(t) + }, + ProtoV6ProviderFactories: acctest.Providers, + Steps: []resource.TestStep{ + { // Create + ConfigDirectory: acctest.NamedTestCaseDirectory("create"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "value": config.StringVariable("test-value-1"), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list_item.test", "id"), + resource.TestCheckResourceAttr("elasticstack_kibana_security_list_item.test", "value", "test-value-1"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list_item.test", "created_at"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list_item.test", "created_by"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list_item.test", "updated_at"), + resource.TestCheckResourceAttrSet("elasticstack_kibana_security_list_item.test", "updated_by"), + ), + }, + { // Update + ConfigDirectory: acctest.NamedTestCaseDirectory("update"), + ConfigVariables: config.Variables{ + "list_id": config.StringVariable(listID), + "value": config.StringVariable("test-value-updated"), + }, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_kibana_security_list_item.test", "value", "test-value-updated"), + ), + }, + }, + }) +} diff --git a/internal/kibana/security_list_item/create.go b/internal/kibana/security_list_item/create.go new file mode 100644 index 000000000..59dc7a1e6 --- /dev/null +++ b/internal/kibana/security_list_item/create.go @@ -0,0 +1,77 @@ +package security_list_item + +import ( + "context" + "encoding/json" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *securityListItemResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var plan SecurityListItemModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + // Get Kibana client + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Convert plan to API request + createReq, diags := plan.toAPICreateModel(ctx) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + // Create the list item + createResp, diags := kibana_oapi.CreateListItem(ctx, client, *createReq) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if createResp == nil || createResp.JSON200 == nil { + resp.Diagnostics.AddError("Failed to create security list item", "API returned empty response") + return + } + + // Read the created list item to populate state + id := kbapi.SecurityListsAPIListId(createResp.JSON200.Id) + readParams := &kbapi.ReadListItemParams{ + Id: &id, + } + + readResp, diags := kibana_oapi.GetListItem(ctx, client, readParams) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if readResp == nil || readResp.JSON200 == nil { + resp.State.RemoveResource(ctx) + return + } + + // Unmarshal the response body to get the list item + var listItem kbapi.SecurityListsAPIListItem + if err := json.Unmarshal(readResp.Body, &listItem); err != nil { + resp.Diagnostics.AddError("Failed to parse list item response", err.Error()) + return + } + + // Update state with read response + diags = plan.fromAPIModel(ctx, &listItem) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) +} diff --git a/internal/kibana/security_list_item/delete.go b/internal/kibana/security_list_item/delete.go new file mode 100644 index 000000000..3feafbb54 --- /dev/null +++ b/internal/kibana/security_list_item/delete.go @@ -0,0 +1,33 @@ +package security_list_item + +import ( + "context" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *securityListItemResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state SecurityListItemModel + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + // Get Kibana client + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Delete by ID + id := kbapi.SecurityListsAPIListItemId(state.ID.ValueString()) + params := &kbapi.DeleteListItemParams{ + Id: &id, + } + + diags := kibana_oapi.DeleteListItem(ctx, client, params) + resp.Diagnostics.Append(diags...) +} diff --git a/internal/kibana/security_list_item/models.go b/internal/kibana/security_list_item/models.go new file mode 100644 index 000000000..cf2438f2b --- /dev/null +++ b/internal/kibana/security_list_item/models.go @@ -0,0 +1,113 @@ +package security_list_item + +import ( + "context" + "encoding/json" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type SecurityListItemModel struct { + ID types.String `tfsdk:"id"` + SpaceID types.String `tfsdk:"space_id"` + ListID types.String `tfsdk:"list_id"` + Value types.String `tfsdk:"value"` + Meta types.String `tfsdk:"meta"` + CreatedAt types.String `tfsdk:"created_at"` + CreatedBy types.String `tfsdk:"created_by"` + UpdatedAt types.String `tfsdk:"updated_at"` + UpdatedBy types.String `tfsdk:"updated_by"` + Version types.String `tfsdk:"version"` +} + +// toAPICreateModel converts the Terraform model to the API create request body +func (m *SecurityListItemModel) toAPICreateModel(ctx context.Context) (*kbapi.CreateListItemJSONRequestBody, diag.Diagnostics) { + var diags diag.Diagnostics + + body := &kbapi.CreateListItemJSONRequestBody{ + ListId: kbapi.SecurityListsAPIListId(m.ListID.ValueString()), + Value: kbapi.SecurityListsAPIListItemValue(m.Value.ValueString()), + } + + // Set optional ID if specified + if !m.ID.IsNull() && !m.ID.IsUnknown() { + id := kbapi.SecurityListsAPIListItemId(m.ID.ValueString()) + body.Id = &id + } + + // Set optional meta if specified + if !m.Meta.IsNull() && !m.Meta.IsUnknown() { + var meta kbapi.SecurityListsAPIListItemMetadata + if err := json.Unmarshal([]byte(m.Meta.ValueString()), &meta); err != nil { + diags.AddError("Failed to parse meta JSON", err.Error()) + return nil, diags + } + body.Meta = &meta + } + + return body, diags +} + +// toAPIUpdateModel converts the Terraform model to the API update request body +func (m *SecurityListItemModel) toAPIUpdateModel(ctx context.Context) (*kbapi.UpdateListItemJSONRequestBody, diag.Diagnostics) { + var diags diag.Diagnostics + + body := &kbapi.UpdateListItemJSONRequestBody{ + Id: kbapi.SecurityListsAPIListItemId(m.ID.ValueString()), + Value: kbapi.SecurityListsAPIListItemValue(m.Value.ValueString()), + } + + // Set optional version if available + if !m.Version.IsNull() && !m.Version.IsUnknown() { + version := kbapi.SecurityListsAPIListVersionId(m.Version.ValueString()) + body.UnderscoreVersion = &version + } + + // Set optional meta if specified + if !m.Meta.IsNull() && !m.Meta.IsUnknown() { + var meta kbapi.SecurityListsAPIListItemMetadata + if err := json.Unmarshal([]byte(m.Meta.ValueString()), &meta); err != nil { + diags.AddError("Failed to parse meta JSON", err.Error()) + return nil, diags + } + body.Meta = &meta + } + + return body, diags +} + +// fromAPIModel populates the Terraform model from an API response +func (m *SecurityListItemModel) fromAPIModel(ctx context.Context, apiItem *kbapi.SecurityListsAPIListItem) diag.Diagnostics { + var diags diag.Diagnostics + + m.ID = types.StringValue(string(apiItem.Id)) + m.ListID = types.StringValue(string(apiItem.ListId)) + m.Value = types.StringValue(string(apiItem.Value)) + m.CreatedAt = types.StringValue(apiItem.CreatedAt.Format("2006-01-02T15:04:05.000Z")) + m.CreatedBy = types.StringValue(apiItem.CreatedBy) + m.UpdatedAt = types.StringValue(apiItem.UpdatedAt.Format("2006-01-02T15:04:05.000Z")) + m.UpdatedBy = types.StringValue(apiItem.UpdatedBy) + + // Set version if available + if apiItem.UnderscoreVersion != nil { + m.Version = types.StringValue(string(*apiItem.UnderscoreVersion)) + } else { + m.Version = types.StringNull() + } + + // Set meta if available + if apiItem.Meta != nil { + metaJSON, err := json.Marshal(apiItem.Meta) + if err != nil { + diags.AddError("Failed to serialize meta", err.Error()) + return diags + } + m.Meta = types.StringValue(string(metaJSON)) + } else { + m.Meta = types.StringNull() + } + + return diags +} diff --git a/internal/kibana/security_list_item/read.go b/internal/kibana/security_list_item/read.go new file mode 100644 index 000000000..498b9ee04 --- /dev/null +++ b/internal/kibana/security_list_item/read.go @@ -0,0 +1,59 @@ +package security_list_item + +import ( + "context" + "encoding/json" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *securityListItemResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state SecurityListItemModel + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + // Get Kibana client + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Read by ID + id := kbapi.SecurityListsAPIListId(state.ID.ValueString()) + params := &kbapi.ReadListItemParams{ + Id: &id, + } + + readResp, diags := kibana_oapi.GetListItem(ctx, client, params) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if readResp == nil || readResp.JSON200 == nil { + resp.State.RemoveResource(ctx) + return + } + + // The response can be a single item or an array, so we need to unmarshal from the body + // When querying by ID, we expect a single item + var listItem kbapi.SecurityListsAPIListItem + if err := json.Unmarshal(readResp.Body, &listItem); err != nil { + resp.Diagnostics.AddError("Failed to parse list item response", err.Error()) + return + } + + // Update state with response + diags = state.fromAPIModel(ctx, &listItem) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, state)...) +} diff --git a/internal/kibana/security_list_item/resource-description.md b/internal/kibana/security_list_item/resource-description.md new file mode 100644 index 000000000..d00e14915 --- /dev/null +++ b/internal/kibana/security_list_item/resource-description.md @@ -0,0 +1,57 @@ +--- +subcategory: "Kibana" +layout: "" +page_title: "Elasticstack: elasticstack_kibana_security_list_item Resource" +description: |- + Manages items within Kibana security value lists. +--- + +# Resource: elasticstack_kibana_security_list_item + +Manages items within Kibana security value lists. Value lists are containers for values that can be used within exception lists to define conditions. This resource allows you to add, update, and remove individual values (items) in those lists. + +Value list items are used to store data values that match the type of their parent security list (e.g., IP addresses, keywords, etc.). These items can then be referenced in exception list entries to define exception conditions. + +## Example Usage + +```terraform +# First create a security list +resource "elasticstack_kibana_security_list" "ip_list" { + list_id = "allowed_ips" + name = "Allowed IP Addresses" + description = "List of IP addresses that are allowed" + type = "ip" +} + +# Add an IP address to the list +resource "elasticstack_kibana_security_list_item" "ip_item_1" { + list_id = elasticstack_kibana_security_list.ip_list.list_id + value = "192.168.1.1" +} + +# Add another IP address +resource "elasticstack_kibana_security_list_item" "ip_item_2" { + list_id = elasticstack_kibana_security_list.ip_list.list_id + value = "10.0.0.1" +} + +# Add a keyword item with metadata +resource "elasticstack_kibana_security_list" "keyword_list" { + list_id = "allowed_domains" + name = "Allowed Domains" + description = "List of domains that are allowed" + type = "keyword" +} + +resource "elasticstack_kibana_security_list_item" "domain_item" { + list_id = elasticstack_kibana_security_list.keyword_list.list_id + value = "example.com" + meta = jsonencode({ + note = "Primary corporate domain" + }) +} +``` + +## Note on Space Support + +**Important**: The generated Kibana API client does not currently support space_id for list item operations. While the `space_id` attribute is available in the schema for future compatibility, list items currently operate in the default space only. This is a known limitation that will be addressed in a future update when the API client is regenerated with proper space support. diff --git a/internal/kibana/security_list_item/resource.go b/internal/kibana/security_list_item/resource.go new file mode 100644 index 000000000..0f9402be3 --- /dev/null +++ b/internal/kibana/security_list_item/resource.go @@ -0,0 +1,38 @@ +package security_list_item + +import ( + "context" + + "github.com/elastic/terraform-provider-elasticstack/internal/clients" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +// Ensure provider defined types fully satisfy framework interfaces +var ( + _ resource.Resource = &securityListItemResource{} + _ resource.ResourceWithConfigure = &securityListItemResource{} + _ resource.ResourceWithImportState = &securityListItemResource{} +) + +func NewResource() resource.Resource { + return &securityListItemResource{} +} + +type securityListItemResource struct { + client *clients.ApiClient +} + +func (r *securityListItemResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_kibana_security_list_item" +} + +func (r *securityListItemResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + client, diags := clients.ConvertProviderData(req.ProviderData) + resp.Diagnostics.Append(diags...) + r.client = client +} + +func (r *securityListItemResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), request, response) +} diff --git a/internal/kibana/security_list_item/schema.go b/internal/kibana/security_list_item/schema.go new file mode 100644 index 000000000..3315e715f --- /dev/null +++ b/internal/kibana/security_list_item/schema.go @@ -0,0 +1,76 @@ +package security_list_item + +import ( + "context" + _ "embed" + + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" +) + +//go:embed resource-description.md +var securityListItemResourceDescription string + +func (r *securityListItemResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: securityListItemResourceDescription, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + MarkdownDescription: "The value list item's identifier (auto-generated by Kibana if not specified).", + Computed: true, + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + stringplanmodifier.UseStateForUnknown(), + }, + }, + "space_id": schema.StringAttribute{ + MarkdownDescription: "An identifier for the space. If space_id is not provided, the default space is used.", + Optional: true, + Computed: true, + Default: stringdefault.StaticString("default"), + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "list_id": schema.StringAttribute{ + MarkdownDescription: "The value list's identifier that this item belongs to.", + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "value": schema.StringAttribute{ + MarkdownDescription: "The value used to evaluate exceptions. The value's data type must match the list's type.", + Required: true, + }, + "meta": schema.StringAttribute{ + MarkdownDescription: "Placeholder for metadata about the value list item as JSON string.", + Optional: true, + }, + "version": schema.StringAttribute{ + MarkdownDescription: "The version id, normally returned by the API when the document is retrieved. Used to ensure updates are done against the latest version.", + Computed: true, + }, + "created_at": schema.StringAttribute{ + MarkdownDescription: "The timestamp of when the list item was created.", + Computed: true, + }, + "created_by": schema.StringAttribute{ + MarkdownDescription: "The user who created the list item.", + Computed: true, + }, + "updated_at": schema.StringAttribute{ + MarkdownDescription: "The timestamp of when the list item was last updated.", + Computed: true, + }, + "updated_by": schema.StringAttribute{ + MarkdownDescription: "The user who last updated the list item.", + Computed: true, + }, + }, + } +} diff --git a/internal/kibana/security_list_item/testdata/TestAccResourceSecurityListItem/create/main.tf b/internal/kibana/security_list_item/testdata/TestAccResourceSecurityListItem/create/main.tf new file mode 100644 index 000000000..246c973a6 --- /dev/null +++ b/internal/kibana/security_list_item/testdata/TestAccResourceSecurityListItem/create/main.tf @@ -0,0 +1,16 @@ +variable "list_id" {} +variable "value" {} + +# First create a security list to put items in +resource "elasticstack_kibana_security_list" "test" { + list_id = var.list_id + name = "Test List for Items" + description = "A test security list for IP addresses" + type = "keyword" +} + +# Create a list item +resource "elasticstack_kibana_security_list_item" "test" { + list_id = elasticstack_kibana_security_list.test.list_id + value = var.value +} diff --git a/internal/kibana/security_list_item/testdata/TestAccResourceSecurityListItem/update/main.tf b/internal/kibana/security_list_item/testdata/TestAccResourceSecurityListItem/update/main.tf new file mode 100644 index 000000000..df1d6c668 --- /dev/null +++ b/internal/kibana/security_list_item/testdata/TestAccResourceSecurityListItem/update/main.tf @@ -0,0 +1,16 @@ +variable "list_id" {} +variable "value" {} + +# First create a security list to put items in +resource "elasticstack_kibana_security_list" "test" { + list_id = var.list_id + name = "Test List for Items" + description = "A test security list for IP addresses" + type = "keyword" +} + +# Create a list item with updated value +resource "elasticstack_kibana_security_list_item" "test" { + list_id = elasticstack_kibana_security_list.test.list_id + value = var.value +} diff --git a/internal/kibana/security_list_item/update.go b/internal/kibana/security_list_item/update.go new file mode 100644 index 000000000..b8d6cbf62 --- /dev/null +++ b/internal/kibana/security_list_item/update.go @@ -0,0 +1,77 @@ +package security_list_item + +import ( + "context" + "encoding/json" + + "github.com/elastic/terraform-provider-elasticstack/generated/kbapi" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/kibana_oapi" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +func (r *securityListItemResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var plan SecurityListItemModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + // Get Kibana client + client, err := r.client.GetKibanaOapiClient() + if err != nil { + resp.Diagnostics.AddError("Failed to get Kibana client", err.Error()) + return + } + + // Convert plan to API request + updateReq, diags := plan.toAPIUpdateModel(ctx) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + // Update the list item + updateResp, diags := kibana_oapi.UpdateListItem(ctx, client, *updateReq) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if updateResp == nil || updateResp.JSON200 == nil { + resp.Diagnostics.AddError("Failed to update security list item", "API returned empty response") + return + } + + // Read the updated list item to populate state + id := kbapi.SecurityListsAPIListId(updateResp.JSON200.Id) + readParams := &kbapi.ReadListItemParams{ + Id: &id, + } + + readResp, diags := kibana_oapi.GetListItem(ctx, client, readParams) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if readResp == nil || readResp.JSON200 == nil { + resp.State.RemoveResource(ctx) + return + } + + // Unmarshal the response body to get the list item + var listItem kbapi.SecurityListsAPIListItem + if err := json.Unmarshal(readResp.Body, &listItem); err != nil { + resp.Diagnostics.AddError("Failed to parse list item response", err.Error()) + return + } + + // Update state with read response + diags = plan.fromAPIModel(ctx, &listItem) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) +} diff --git a/internal/utils/validators/conditional.go b/internal/utils/validators/conditional.go index df011533c..a1a10f2ea 100644 --- a/internal/utils/validators/conditional.go +++ b/internal/utils/validators/conditional.go @@ -93,6 +93,10 @@ func (v condition) ValidateInt64(ctx context.Context, request validator.Int64Req response.Diagnostics.Append(v.validate(ctx, request.Config, request.ConfigValue, request.Path)...) } +func (v condition) ValidateObject(ctx context.Context, request validator.ObjectRequest, response *validator.ObjectResponse) { + response.Diagnostics.Append(v.validate(ctx, request.Config, request.ConfigValue, request.Path)...) +} + // DependantPathOneOf creates a condition that validates a dependent path's value is one of the allowed values. // It returns a condition that checks if the value at dependentPath matches any of the provided allowedValues. // If the dependent field does not have an allowed value, it generates a diagnostic error indicating diff --git a/provider/plugin_framework.go b/provider/plugin_framework.go index 0685d4228..b24562863 100644 --- a/provider/plugin_framework.go +++ b/provider/plugin_framework.go @@ -31,6 +31,10 @@ import ( "github.com/elastic/terraform-provider-elasticstack/internal/kibana/import_saved_objects" "github.com/elastic/terraform-provider-elasticstack/internal/kibana/maintenance_window" "github.com/elastic/terraform-provider-elasticstack/internal/kibana/security_detection_rule" + "github.com/elastic/terraform-provider-elasticstack/internal/kibana/security_exception_item" + "github.com/elastic/terraform-provider-elasticstack/internal/kibana/security_exception_list" + "github.com/elastic/terraform-provider-elasticstack/internal/kibana/security_list" + "github.com/elastic/terraform-provider-elasticstack/internal/kibana/security_list_item" "github.com/elastic/terraform-provider-elasticstack/internal/kibana/spaces" "github.com/elastic/terraform-provider-elasticstack/internal/kibana/synthetics/monitor" "github.com/elastic/terraform-provider-elasticstack/internal/kibana/synthetics/parameter" @@ -128,6 +132,10 @@ func (p *Provider) Resources(ctx context.Context) []func() resource.Resource { datafeed.NewDatafeedResource, anomaly_detection_job.NewAnomalyDetectionJobResource, security_detection_rule.NewSecurityDetectionRuleResource, + security_exception_list.NewResource, + security_exception_item.NewResource, + security_list.NewResource, + security_list_item.NewResource, job_state.NewMLJobStateResource, datafeed_state.NewMLDatafeedStateResource, } diff --git a/templates/resources/kibana_security_exception_item.md.tmpl b/templates/resources/kibana_security_exception_item.md.tmpl new file mode 100644 index 000000000..a8ad6b6c0 --- /dev/null +++ b/templates/resources/kibana_security_exception_item.md.tmpl @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" +subcategory: "Kibana" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +### Basic exception item + +{{ tffile "examples/resources/elasticstack_kibana_security_exception_item/resource.tf" }} + +### Complex exception item with multiple entries + +{{ tffile "examples/resources/elasticstack_kibana_security_exception_item/resource_complex.tf" }} + +{{ .SchemaMarkdown | trimspace }} +{{- if or .HasImport .HasImportIDConfig .HasImportIdentityConfig }} + +## Import + +Import is supported using the following syntax: +{{- end }} +{{- if .HasImportIdentityConfig }} + +In Terraform v1.12.0 and later, the [`import` block](https://developer.hashicorp.com/terraform/language/import) can be used with the `identity` attribute, for example: + +{{tffile .ImportIdentityConfigFile }} + +{{ .IdentitySchemaMarkdown | trimspace }} +{{- end }} +{{- if .HasImportIDConfig }} + +In Terraform v1.5.0 and later, the [`import` block](https://developer.hashicorp.com/terraform/language/import) can be used with the `id` attribute, for example: + +{{tffile .ImportIDConfigFile }} +{{- end }} +{{- if .HasImport }} + +The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example: + +{{codefile "shell" .ImportFile }} +{{- end }} diff --git a/templates/resources/kibana_security_exception_list.md.tmpl b/templates/resources/kibana_security_exception_list.md.tmpl new file mode 100644 index 000000000..c6b737823 --- /dev/null +++ b/templates/resources/kibana_security_exception_list.md.tmpl @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" +subcategory: "Kibana" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +### Basic exception list + +{{ tffile "examples/resources/elasticstack_kibana_security_exception_list/resource.tf" }} + +### Endpoint exception list with OS types + +{{ tffile "examples/resources/elasticstack_kibana_security_exception_list/resource_endpoint.tf" }} + +{{ .SchemaMarkdown | trimspace }} +{{- if or .HasImport .HasImportIDConfig .HasImportIdentityConfig }} + +## Import + +Import is supported using the following syntax: +{{- end }} +{{- if .HasImportIdentityConfig }} + +In Terraform v1.12.0 and later, the [`import` block](https://developer.hashicorp.com/terraform/language/import) can be used with the `identity` attribute, for example: + +{{tffile .ImportIdentityConfigFile }} + +{{ .IdentitySchemaMarkdown | trimspace }} +{{- end }} +{{- if .HasImportIDConfig }} + +In Terraform v1.5.0 and later, the [`import` block](https://developer.hashicorp.com/terraform/language/import) can be used with the `id` attribute, for example: + +{{tffile .ImportIDConfigFile }} +{{- end }} +{{- if .HasImport }} + +The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example: + +{{codefile "shell" .ImportFile }} +{{- end }} diff --git a/templates/resources/kibana_security_list.md.tmpl b/templates/resources/kibana_security_list.md.tmpl new file mode 100644 index 000000000..1c8f1ea33 --- /dev/null +++ b/templates/resources/kibana_security_list.md.tmpl @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" +subcategory: "Kibana" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +### IP address list + +{{ tffile "examples/resources/elasticstack_kibana_security_list/resource.tf" }} + +### Keyword list with custom list_id + +{{ tffile "examples/resources/elasticstack_kibana_security_list/resource_keyword.tf" }} + +{{ .SchemaMarkdown | trimspace }} +{{- if or .HasImport .HasImportIDConfig .HasImportIdentityConfig }} + +## Import + +Import is supported using the following syntax: +{{- end }} +{{- if .HasImportIdentityConfig }} + +In Terraform v1.12.0 and later, the [`import` block](https://developer.hashicorp.com/terraform/language/import) can be used with the `identity` attribute, for example: + +{{tffile .ImportIdentityConfigFile }} + +{{ .IdentitySchemaMarkdown | trimspace }} +{{- end }} +{{- if .HasImportIDConfig }} + +In Terraform v1.5.0 and later, the [`import` block](https://developer.hashicorp.com/terraform/language/import) can be used with the `id` attribute, for example: + +{{tffile .ImportIDConfigFile }} +{{- end }} +{{- if .HasImport }} + +The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example: + +{{codefile "shell" .ImportFile }} +{{- end }} diff --git a/templates/resources/kibana_security_list_item.md.tmpl b/templates/resources/kibana_security_list_item.md.tmpl new file mode 100644 index 000000000..a69108d49 --- /dev/null +++ b/templates/resources/kibana_security_list_item.md.tmpl @@ -0,0 +1,48 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" +subcategory: "Kibana" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +### Basic keyword value + +{{ tffile "examples/resources/elasticstack_kibana_security_list_item/resource.tf" }} + +### IP address value + +{{ tffile "examples/resources/elasticstack_kibana_security_list_item/resource_ip.tf" }} + +### Value with metadata + +{{ tffile "examples/resources/elasticstack_kibana_security_list_item/resource_with_meta.tf" }} + +{{ .SchemaMarkdown | trimspace }} +{{- if or .HasImport .HasImportIDConfig .HasImportIdentityConfig }} + +## Import + +Import is supported using the following syntax: +{{- end }} +{{- if .HasImportIdentityConfig }} + +{{ codefile "sh" .ImportIdentityConfig }} + +{{- end }} +{{- if .HasImportIDConfig }} + +{{ codefile "sh" .ImportIDConfig }} + +{{- end }} +{{- if .HasImport }} + +{{ codefile "sh" .ImportFile }} + +{{- end }}