Repository: open-telemetry/opentelemetry-python-contrib

Issue:
`remove_url_credentials` drops brackets from IPv6 hostnames
**Describe your environment** 

Python 3.11.9, `opentelemetry-instrumentation` is auto-injected via the OpenTelemetry operator, `opentelemetry_util_http` is `0.44b0`

**Steps to reproduce**
```python

from opentelemetry.util.http import remove_url_credentials

literal_ipv6_url = "https://[::1]/somepath?query=foo"
remove_url_credentials(literal_ipv6_url)
# 'https://::1/somepath?query=foo' -- should be 'https://[::1]/somepath?query=foo'

literal_ipv6_url_with_port = "https://[::1]:12345/somepath?query=foo"
remove_url_credentials(literal_ipv6_url_with_port)
# 'https://::1:12345/somepath?query=foo -- should be 'https://[::1]:12345/somepath?query=foo'

literal_ipv6_url_with_auth = "https://someuser:somepass@[::1]:12345/somepath?query=foo"
remove_url_credentials(literal_ipv6_url_with_auth)
# 'https://::1:12345/somepath?query=foo' -- should be https://[::1]:12345/somepath?query=foo

```

**What is the expected behavior?**
The ipv6 host should remain inside `[]` 

**What is the actual behavior?**
`[]` are stripped from the host

**Additional context**
https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py#L169 is the causing line. The `hostname` result on `urlparse` does not contain the brackets


```python
from urllib.parse import urlparse

parsed = urlparse(literal_ipv6_url_with_auth)

parsed
# ParseResult(scheme='https', netloc='someuser:somepass@[::1]:12345', path='/somepath', params='', query='query=foo', fragment='')

parsed.hostname
# '::1'
```



Discussion:

Resolving patch:
diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py
--- a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py
+++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py
@@ -166,11 +166,7 @@ def remove_url_credentials(url: str) -> str:
         parsed = urlparse(url)
         if all([parsed.scheme, parsed.netloc]):  # checks for valid url
             parsed_url = urlparse(url)
-            netloc = (
-                (":".join(((parsed_url.hostname or ""), str(parsed_url.port))))
-                if parsed_url.port
-                else (parsed_url.hostname or "")
-            )
+            _, _, netloc = parsed.netloc.rpartition("@")
             return urlunparse(
                 (
                     parsed_url.scheme,


Test patch:
diff --git a/util/opentelemetry-util-http/tests/test_remove_credentials.py b/util/opentelemetry-util-http/tests/test_remove_credentials.py
new file mode 100644
--- /dev/null
+++ b/util/opentelemetry-util-http/tests/test_remove_credentials.py
@@ -0,0 +1,27 @@
+import unittest
+
+from opentelemetry.util.http import remove_url_credentials
+
+
+class TestRemoveUrlCredentials(unittest.TestCase):
+    def test_remove_no_credentials(self):
+        url = "http://opentelemetry.io:8080/test/path?query=value"
+        cleaned_url = remove_url_credentials(url)
+        self.assertEqual(cleaned_url, url)
+
+    def test_remove_credentials(self):
+        url = "http://someuser:somepass@opentelemetry.io:8080/test/path?query=value"
+        cleaned_url = remove_url_credentials(url)
+        self.assertEqual(
+            cleaned_url, "http://opentelemetry.io:8080/test/path?query=value"
+        )
+
+    def test_remove_credentials_ipv4_literal(self):
+        url = "http://someuser:somepass@127.0.0.1:8080/test/path?query=value"
+        cleaned_url = remove_url_credentials(url)
+        self.assertEqual(cleaned_url, "http://127.0.0.1:8080/test/path?query=value")
+
+    def test_remove_credentials_ipv6_literal(self):
+        url = "http://someuser:somepass@[::1]:8080/test/path?query=value"
+        cleaned_url = remove_url_credentials(url)
+        self.assertEqual(cleaned_url, "http://[::1]:8080/test/path?query=value")