From d7798060a2e3f468f87920e73a697c3081c890f0 Mon Sep 17 00:00:00 2001 From: Anika Maskara Date: Thu, 3 Oct 2024 16:02:28 -0400 Subject: [PATCH 1/3] mult form parameter support --- .generator/src/generator/templates/api_client.j2 | 3 ++- features/step_definitions/request.rb | 5 +++-- features/support/env.rb | 9 ++++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.generator/src/generator/templates/api_client.j2 b/.generator/src/generator/templates/api_client.j2 index c2a8db8f6227..00d2f8a8ccfc 100644 --- a/.generator/src/generator/templates/api_client.j2 +++ b/.generator/src/generator/templates/api_client.j2 @@ -183,7 +183,8 @@ module {{ module_name }} :http_proxyaddr => @config.http_proxyaddr, :http_proxyport => @config.http_proxyport, :http_proxyuser => @config.http_proxyuser, - :http_proxypass => @config.http_proxypass + :http_proxypass => @config.http_proxypass, + :query_string_normalizer => HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER } req_opts[:pem] = File.read(@config.cert_file) if @config.cert_file diff --git a/features/step_definitions/request.rb b/features/step_definitions/request.rb index bdfb33f12e62..e911dbe0dfaf 100644 --- a/features/step_definitions/request.rb +++ b/features/step_definitions/request.rb @@ -6,6 +6,7 @@ require_relative '../scenarios_model_mapping' SLEEP_AFTER_REQUEST = ENV.has_key?("SLEEP_AFTER_REQUEST") ? ENV["SLEEP_AFTER_REQUEST"].to_i : 0 +WebMock::Config.instance.query_values_notation = :flat_array module APIWorld def api @@ -100,7 +101,7 @@ def relative_time(iso) return ret.rfc3339(3) if iso return ret.to_i end - return nil + nil } end @@ -221,7 +222,7 @@ def build_given(api_version, operation) def model_builder(param, obj) model = ScenariosModelMappings["v#{@api_version}.#{@operation_id}"][param] if model == 'File' - return File.open(File.join(__dir__, "..", "v" + @api_version, obj)) + return File.open(File.join(__dir__, "..", "v" + @api_version, obj)) end @api_client.convert_to_type(obj, model, "V#{@api_version}") end diff --git a/features/support/env.rb b/features/support/env.rb index 10f4f67f6f63..1a28d543447f 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -51,9 +51,16 @@ def use_real_time? c.register_request_matcher :safe_headers do |r1, r2| r1.headers.slice(*filtered_headers) == r2.headers.slice(*filtered_headers) end + c.register_request_matcher :ignore_query_param_ordering do |r1, r2| + uri1 = URI(r1.uri) + uri2 = URI(r2.uri) + query1 = CGI.parse(uri1.query || '').transform_values(&:sort) + query2 = CGI.parse(uri2.query || '').transform_values(&:sort) + query1 == query2 + end c.default_cassette_options = { :record_on_error => false, - :match_requests_on => [:method, :host, :safe_path, :query, :body_as_json, :safe_headers], + :match_requests_on => [:method, :host, :safe_path, :ignore_query_param_ordering, :body_as_json, :safe_headers], } c.allow_http_connections_when_no_cassette = true RecordMode.send(ENV["RECORD"] || "false", c) From 5169ced1c12d2d315840ffa149784cbf3dbf5aa5 Mon Sep 17 00:00:00 2001 From: Anika Maskara Date: Tue, 29 Oct 2024 10:54:44 -0400 Subject: [PATCH 2/3] only add non rails for some apis --- .generator/src/generator/templates/api.j2 | 4 ++++ .generator/src/generator/templates/api_client.j2 | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.generator/src/generator/templates/api.j2 b/.generator/src/generator/templates/api.j2 index 3225b2f6cc73..246723345f3c 100644 --- a/.generator/src/generator/templates/api.j2 +++ b/.generator/src/generator/templates/api.j2 @@ -207,6 +207,10 @@ module {{ module_name }}::{{ version|upper }} :return_type => return_type, :api_version => "{{ version|upper }}" ) + {%- set query_multi_params = operation|parameters | map(attribute=1) | selectattr("in", "equalto", "query")| map("collection_format")| select("eq", "multi") | first-%} + {%- if query_multi_params %} + new_options[:query_string_normalizer] = HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER + {%- endif %} data, status_code, headers = @api_client.call_api(Net::HTTP::{{ httpMethod|camel_case }}, local_var_path, new_options) if @api_client.config.debugging diff --git a/.generator/src/generator/templates/api_client.j2 b/.generator/src/generator/templates/api_client.j2 index 00d2f8a8ccfc..61d6ee4152fb 100644 --- a/.generator/src/generator/templates/api_client.j2 +++ b/.generator/src/generator/templates/api_client.j2 @@ -183,12 +183,12 @@ module {{ module_name }} :http_proxyaddr => @config.http_proxyaddr, :http_proxyport => @config.http_proxyport, :http_proxyuser => @config.http_proxyuser, - :http_proxypass => @config.http_proxypass, - :query_string_normalizer => HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER + :http_proxypass => @config.http_proxypass } req_opts[:pem] = File.read(@config.cert_file) if @config.cert_file req_opts[:pem_password] = File.read(@config.key_file) if @config.key_file + req_opts[:query_string_normalizer] = opts[:query_string_normalizer] if opts[:query_string_normalizer] opts[:stream_body] = true if opts[:return_type] == 'File' From d02808456b52ce8186649201af4e46d199e49e35 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Mon, 4 Nov 2024 18:34:58 +0000 Subject: [PATCH 3/3] Regenerate client from commit aeb956c4 of spec repo --- .apigentools-info | 8 ++++---- ...ype-query-param-returns-OK-response.frozen | 1 + ...n-type-query-param-returns-OK-response.yml | 20 +++++++++++++++++++ .../ListFindings_1668290866.rb | 14 +++++++++++++ features/v2/security_monitoring.feature | 8 ++++++++ lib/datadog_api_client/api_client.rb | 1 + .../v1/api/synthetics_api.rb | 2 ++ .../v1/api/usage_metering_api.rb | 2 ++ .../v2/api/security_monitoring_api.rb | 1 + lib/datadog_api_client/v2/api/teams_api.rb | 1 + 10 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 cassettes/features/v2/security_monitoring/List-findings-with-detection-type-query-param-returns-OK-response.frozen create mode 100644 cassettes/features/v2/security_monitoring/List-findings-with-detection-type-query-param-returns-OK-response.yml create mode 100644 examples/v2/security-monitoring/ListFindings_1668290866.rb diff --git a/.apigentools-info b/.apigentools-info index 30ee28af8935..08f1536dc31d 100644 --- a/.apigentools-info +++ b/.apigentools-info @@ -4,13 +4,13 @@ "spec_versions": { "v1": { "apigentools_version": "1.6.6", - "regenerated": "2024-11-04 17:58:13.167732", - "spec_repo_commit": "6ffe013b" + "regenerated": "2024-11-04 18:34:33.238993", + "spec_repo_commit": "aeb956c4" }, "v2": { "apigentools_version": "1.6.6", - "regenerated": "2024-11-04 17:58:13.187613", - "spec_repo_commit": "6ffe013b" + "regenerated": "2024-11-04 18:34:33.257596", + "spec_repo_commit": "aeb956c4" } } } \ No newline at end of file diff --git a/cassettes/features/v2/security_monitoring/List-findings-with-detection-type-query-param-returns-OK-response.frozen b/cassettes/features/v2/security_monitoring/List-findings-with-detection-type-query-param-returns-OK-response.frozen new file mode 100644 index 000000000000..fc4c1120f10f --- /dev/null +++ b/cassettes/features/v2/security_monitoring/List-findings-with-detection-type-query-param-returns-OK-response.frozen @@ -0,0 +1 @@ +2024-10-21T20:05:58.636Z \ No newline at end of file diff --git a/cassettes/features/v2/security_monitoring/List-findings-with-detection-type-query-param-returns-OK-response.yml b/cassettes/features/v2/security_monitoring/List-findings-with-detection-type-query-param-returns-OK-response.yml new file mode 100644 index 000000000000..78a8e9029427 --- /dev/null +++ b/cassettes/features/v2/security_monitoring/List-findings-with-detection-type-query-param-returns-OK-response.yml @@ -0,0 +1,20 @@ +http_interactions: +- recorded_at: Mon, 21 Oct 2024 20:05:58 GMT + request: + body: null + headers: + Accept: + - application/json + method: GET + uri: https://api.datadoghq.com/api/v2/posture_management/findings?filter%5Bvulnerability_type%5D=misconfiguration&filter%5Bvulnerability_type%5D=attack_path + response: + body: + encoding: UTF-8 + string: '{"data":[],"meta":{"page":{"total_filtered_count":0},"snapshot_timestamp":1729541158755}}' + headers: + Content-Type: + - application/vnd.api+json + status: + code: 200 + message: OK +recorded_with: VCR 6.0.0 diff --git a/examples/v2/security-monitoring/ListFindings_1668290866.rb b/examples/v2/security-monitoring/ListFindings_1668290866.rb new file mode 100644 index 000000000000..2fbceb00350f --- /dev/null +++ b/examples/v2/security-monitoring/ListFindings_1668290866.rb @@ -0,0 +1,14 @@ +# List findings with detection_type query param returns "OK" response + +require "datadog_api_client" +DatadogAPIClient.configure do |config| + config.unstable_operations["v2.list_findings".to_sym] = true +end +api_instance = DatadogAPIClient::V2::SecurityMonitoringAPI.new +opts = { + filter_vulnerability_type: [ + FindingVulnerabilityType::MISCONFIGURATION, + FindingVulnerabilityType::ATTACK_PATH, + ], +} +p api_instance.list_findings(opts) diff --git a/features/v2/security_monitoring.feature b/features/v2/security_monitoring.feature index 27e45dd3c2b3..901edb86b494 100644 --- a/features/v2/security_monitoring.feature +++ b/features/v2/security_monitoring.feature @@ -485,6 +485,14 @@ Feature: Security Monitoring When the request with pagination is sent Then the response status is 200 OK + @skip-terraform-config @team:DataDog/cloud-security-posture-management + Scenario: List findings with detection_type query param returns "OK" response + Given operation "ListFindings" enabled + And new "ListFindings" request + And request contains "filter[vulnerability_type]" parameter with value ["misconfiguration", "attack_path"] + When the request is sent + Then the response status is 200 OK + @generated @skip @team:DataDog/k9-cloud-security-platform Scenario: List rules returns "Bad Request" response Given new "ListSecurityMonitoringRules" request diff --git a/lib/datadog_api_client/api_client.rb b/lib/datadog_api_client/api_client.rb index e21d2b320410..86b4f6dad628 100644 --- a/lib/datadog_api_client/api_client.rb +++ b/lib/datadog_api_client/api_client.rb @@ -199,6 +199,7 @@ def build_request(http_method, path, opts = {}) req_opts[:pem] = File.read(@config.cert_file) if @config.cert_file req_opts[:pem_password] = File.read(@config.key_file) if @config.key_file + req_opts[:query_string_normalizer] = opts[:query_string_normalizer] if opts[:query_string_normalizer] opts[:stream_body] = true if opts[:return_type] == 'File' diff --git a/lib/datadog_api_client/v1/api/synthetics_api.rb b/lib/datadog_api_client/v1/api/synthetics_api.rb index c81d9f3beb59..b4935365e7f5 100644 --- a/lib/datadog_api_client/v1/api/synthetics_api.rb +++ b/lib/datadog_api_client/v1/api/synthetics_api.rb @@ -823,6 +823,7 @@ def get_api_test_latest_results_with_http_info(public_id, opts = {}) :return_type => return_type, :api_version => "V1" ) + new_options[:query_string_normalizer] = HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER data, status_code, headers = @api_client.call_api(Net::HTTP::Get, local_var_path, new_options) if @api_client.config.debugging @@ -1030,6 +1031,7 @@ def get_browser_test_latest_results_with_http_info(public_id, opts = {}) :return_type => return_type, :api_version => "V1" ) + new_options[:query_string_normalizer] = HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER data, status_code, headers = @api_client.call_api(Net::HTTP::Get, local_var_path, new_options) if @api_client.config.debugging diff --git a/lib/datadog_api_client/v1/api/usage_metering_api.rb b/lib/datadog_api_client/v1/api/usage_metering_api.rb index f0efe6de4749..57d66c756042 100644 --- a/lib/datadog_api_client/v1/api/usage_metering_api.rb +++ b/lib/datadog_api_client/v1/api/usage_metering_api.rb @@ -1671,6 +1671,7 @@ def get_usage_logs_by_index_with_http_info(start_hr, opts = {}) :return_type => return_type, :api_version => "V1" ) + new_options[:query_string_normalizer] = HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER data, status_code, headers = @api_client.call_api(Net::HTTP::Get, local_var_path, new_options) if @api_client.config.debugging @@ -2759,6 +2760,7 @@ def get_usage_top_avg_metrics_with_http_info(opts = {}) :return_type => return_type, :api_version => "V1" ) + new_options[:query_string_normalizer] = HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER data, status_code, headers = @api_client.call_api(Net::HTTP::Get, local_var_path, new_options) if @api_client.config.debugging diff --git a/lib/datadog_api_client/v2/api/security_monitoring_api.rb b/lib/datadog_api_client/v2/api/security_monitoring_api.rb index 55704b2a6e40..d58f4ad638a6 100644 --- a/lib/datadog_api_client/v2/api/security_monitoring_api.rb +++ b/lib/datadog_api_client/v2/api/security_monitoring_api.rb @@ -1242,6 +1242,7 @@ def list_findings_with_http_info(opts = {}) :return_type => return_type, :api_version => "V2" ) + new_options[:query_string_normalizer] = HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER data, status_code, headers = @api_client.call_api(Net::HTTP::Get, local_var_path, new_options) if @api_client.config.debugging diff --git a/lib/datadog_api_client/v2/api/teams_api.rb b/lib/datadog_api_client/v2/api/teams_api.rb index c96a50c610b5..637c22b5a8f0 100644 --- a/lib/datadog_api_client/v2/api/teams_api.rb +++ b/lib/datadog_api_client/v2/api/teams_api.rb @@ -940,6 +940,7 @@ def list_teams_with_http_info(opts = {}) :return_type => return_type, :api_version => "V2" ) + new_options[:query_string_normalizer] = HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER data, status_code, headers = @api_client.call_api(Net::HTTP::Get, local_var_path, new_options) if @api_client.config.debugging