Azure/azure-sdk-for-python

Wrong request build when validating EASM discovery groups

amocsub opened this issue · 1 comments

  • Package Name: azure-defender-easm
  • Package Version: 1.0.0b1
  • Operating System: macOS 14.4.1 (23E224)
  • Python Version: Python 3.10.13

Describe the bug
There is an error in the url the SDK construction at the method build_discovery_groups_validate_request . According to the docs the correspondent path should be {endpoint}/discoGroups:validate but the implementation is like the following {endpoint}/discoGroups/{groupName}:validate. Please not that the groupName is being sent in the request path.

To Reproduce
Steps to reproduce the behavior, fill in with your environment variables:

from azure.defender.easm import EasmClient
from azure.identity import DefaultAzureCredential
subscription_id = "<SUBSCRIPTION_ID>"
resource_group = "<RESOURCE_GROUP>"
discovery_group = {'name': 'test', 'frequencyMilliseconds': 604800000, 'seeds': [{'name': 'thisisatest.microsoft.com', 'kind': 'host'}], 'tier': 'advanced', 'description': 'This is a disco group'}
endpoint = '<LOCATION>.easm.defender.microsoft.com'
client = EasmClient(endpoint, resource_group, subscription_id, workspace["name"], credential=DefaultAzureCredential())
response = client.discovery_groups.validate("test", discovery_group)

Expected behavior
Whenever someone validates a discovery group it should do what the API specifies, validate it.

Curl command working
image

Screenshots
SDK Failing
image

Curl command failing:
image

API Failing when there is no name in the body with internal server error, code 500
image

Additional context
The following code works to solve this but since the code seems to be autogenerated I will only create an issue here.

  def build_discovery_groups_validate_request(
      group_name: str, subscription_id: str, resource_group_name: str, workspace_name: str, **kwargs: Any
  ) -> HttpRequest:
      _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
      _params = case_insensitive_dict(kwargs.pop("params", {}) or {})
  
      content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
      api_version: Literal["2023-03-01-preview"] = kwargs.pop(
          "api_version", _params.pop("api-version", "2023-03-01-preview")
      )
      accept = _headers.pop("Accept", "application/json")
  
      # Construct URL
      _url = "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/workspaces/{workspaceName}/discoGroups:validate"  # pylint: disable=line-too-long
      path_format_arguments = {
          "subscriptionId": _SERIALIZER.url("subscription_id", subscription_id, "str"),
          "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, "str"),
          "workspaceName": _SERIALIZER.url("workspace_name", workspace_name, "str"),
      }
  
      _url: str = _format_url_section(_url, **path_format_arguments)  # type: ignore
  
      # Construct parameters
      _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str")
  
      # Construct headers
      if content_type is not None:
          _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str")
      _headers["Accept"] = _SERIALIZER.header("accept", accept, "str")
  
      return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs)

Thanks for the feedback, we’ll investigate asap.