Repository: juju/python-libjuju
Issue: [Bug]: is_subordinate() returns wrong result if `subordinate:false` is explicitly specified in charm's metadata

### Description

Currently, [`is_subordinate()`](https://github.com/juju/python-libjuju/blob/master/juju/charmhub.py#L34) function determines if a charm is subordinate by retrieving information from Charmhub API and checking if a `subordinate` key exists. 

```python
return 'subordinate' in response['default-release']['revision']
```

However, for charms that explicitly specify `subordinate:false` in their metadata, e.g. [mysql-innodb-cluster](https://opendev.org/openstack/charm-mysql-innodb-cluster/src/branch/master/src/metadata.yaml#L9), the `subordinate` key would exist in the Charmhuib API response with a value of `false`.

```
{"default-release":{"channel":{"base":{"architecture":"s390x","channel":"22.04","name":"ubuntu"},"name":"8.0/stable","released-at":"2022-08-05T19:05:33.053108+00:00","risk":"stable","track":"8.0"},"revision":{"subordinate":false}},"id":"i5HWuKoEat09854Sz0qXHOjmr4wwHLfP","name":"mysql-innodb-cluster","type":"charm"}
```

In such a case, the `is_subordinate()` function would return wrong result because it only checks the existence of the `subordinate` key but not its value. 

### Urgency

Blocker for our release

### Python-libjuju version

3.0.2

### Juju version

2.9

### Reproduce / Test

```python
from juju.model import Model
import asyncio

async def deploy_mysql():
    model = Model()
    await model.connect("test")
    mysql_innodb_app = await model.deploy(
        "mysql-innodb-cluster", application_name="mysql", series="focal", channel="stable", num_units=3
    )
    return mysql_innodb_app

asyncio.run(deploy_mysql())
```


Changed files:
juju/charmhub.py, tests/integration/test_charmhub.py

diff --git a/juju/charmhub.py b/juju/charmhub.py
index e3f6807..c5d573b 100644
--- a/juju/charmhub.py
+++ b/juju/charmhub.py
@@ -38,7 +38,8 @@ class CharmHub:
         url = "{}/v2/charms/info/{}?fields=default-release.revision.subordinate".format(charmhub_url.value, charm_name)
         _response = await self.request_charmhub_with_retry(url, 5)
         response = json.loads(_response.text)
-        return 'subordinate' in response['default-release']['revision']
+        rev_response = response['default-release']['revision']
+        return 'subordinate' in rev_response and rev_response['subordinate']
 
     # TODO (caner) : we should be able to recreate the channel-map through the
     #  api call without needing the CharmHub facade
diff --git a/tests/integration/test_charmhub.py b/tests/integration/test_charmhub.py
index 2bbd1cd..e95123a 100644
--- a/tests/integration/test_charmhub.py
+++ b/tests/integration/test_charmhub.py
@@ -121,6 +121,14 @@ async def test_subordinate_charm_zero_units(event_loop):
         assert len(app2.units) == 0
 
 
+@base.bootstrapped
+@pytest.mark.asyncio
+async def test_subordinate_false_field_exists(event_loop):
+    async with base.CleanModel() as model:
+        assert await model.charmhub.is_subordinate("rsyslog-forwarder-ha")
+        assert not await model.charmhub.is_subordinate("mysql-innodb-cluster")
+
+
 @base.bootstrapped
 @pytest.mark.asyncio
 async def test_list_resources(event_loop):