- 
                Notifications
    You must be signed in to change notification settings 
- Fork 27
TLS on Patroni REST API #33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4a0399e
              37c0639
              d05d991
              52226c7
              13c5aa9
              aa61f60
              991de5f
              db18ba6
              61946da
              5f01c6e
              aa14718
              9e7fdfd
              12a4a7b
              bc723d1
              3e22732
              2d90e03
              3fab9c6
              82a9a68
              3f259d5
              56ff42a
              62cc604
              63004b4
              e188259
              42a5b13
              79d885b
              3b04265
              1560781
              ee43a39
              7764cb0
              7c1c74e
              0bce570
              5121002
              9d761b7
              00bd1e8
              f25f7b0
              dbfb7a6
              79b1447
              35a83dd
              30a1484
              03cc4f3
              91a1f26
              c472047
              a5c9226
              154df25
              1a8c7a2
              24ac60e
              abc324f
              d9ec362
              bdca5d4
              5bc6ae1
              7c860b7
              334a50d
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -2,6 +2,7 @@ | |
| # Copyright 2022 Canonical Ltd. | ||
| # See LICENSE file for licensing details. | ||
| import itertools | ||
| import json | ||
| import tempfile | ||
| import zipfile | ||
| from datetime import datetime | ||
|  | @@ -412,6 +413,32 @@ async def get_primary(ops_test: OpsTest, unit_name: str) -> str: | |
| return action.results["primary"] | ||
|  | ||
|  | ||
| async def get_tls_ca( | ||
| ops_test: OpsTest, | ||
| unit_name: str, | ||
| ) -> str: | ||
| """Returns the TLS CA used by the unit. | ||
|  | ||
| Args: | ||
| ops_test: The ops test framework instance | ||
| unit_name: The name of the unit | ||
|  | ||
| Returns: | ||
| TLS CA or an empty string if there is no CA. | ||
| """ | ||
| raw_data = (await ops_test.juju("show-unit", unit_name))[1] | ||
| if not raw_data: | ||
| raise ValueError(f"no unit info could be grabbed for {unit_name}") | ||
| data = yaml.safe_load(raw_data) | ||
| # Filter the data based on the relation name. | ||
| relation_data = [ | ||
| v for v in data[unit_name]["relation-info"] if v["endpoint"] == "certificates" | ||
| ] | ||
| if len(relation_data) == 0: | ||
| return "" | ||
| return json.loads(relation_data[0]["application-data"]["certificates"])[0].get("ca") | ||
|  | ||
|  | ||
| def get_unit_address(ops_test: OpsTest, unit_name: str) -> str: | ||
| """Get unit IP address. | ||
|  | ||
|  | @@ -490,6 +517,47 @@ async def check_tls(ops_test: OpsTest, unit_name: str, enabled: bool) -> bool: | |
| return False | ||
|  | ||
|  | ||
| async def check_tls_patroni_api(ops_test: OpsTest, unit_name: str, enabled: bool) -> bool: | ||
| """Returns whether TLS is enabled on Patroni REST API. | ||
|  | ||
| Args: | ||
| ops_test: The ops test framework instance. | ||
| unit_name: The name of the unit where Patroni is running. | ||
| enabled: check if TLS is enabled/disabled | ||
|  | ||
| Returns: | ||
| Whether TLS is enabled/disabled on Patroni REST API. | ||
| """ | ||
| unit_address = get_unit_address(ops_test, unit_name) | ||
| tls_ca = await get_tls_ca(ops_test, unit_name) | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you return False here  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I'll add it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added on 334a50d. | ||
|  | ||
| # If there is no TLS CA in the relation, something is wrong in | ||
| # the relation between the TLS Certificates Operator and PostgreSQL. | ||
| if enabled and not tls_ca: | ||
| return False | ||
|  | ||
| try: | ||
| for attempt in Retrying( | ||
| stop=stop_after_attempt(10), wait=wait_exponential(multiplier=1, min=2, max=30) | ||
| ): | ||
| with attempt, tempfile.NamedTemporaryFile() as temp_ca_file: | ||
| # Write the TLS CA to a temporary file to use it in a request. | ||
| temp_ca_file.write(tls_ca.encode("utf-8")) | ||
| temp_ca_file.seek(0) | ||
|  | ||
| # The CA bundle file is used to validate the server certificate when | ||
| # TLS is enabled, otherwise True is set because it's the default value | ||
| # for the verify parameter. | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. excellent commenting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks Mia! | ||
| health_info = requests.get( | ||
| f"{'https' if enabled else 'http'}://{unit_address}:8008/health", | ||
| verify=temp_ca_file.name if enabled else True, | ||
| ) | ||
| return health_info.status_code == 200 | ||
| except RetryError: | ||
| return False | ||
| return False | ||
|  | ||
|  | ||
| async def scale_application(ops_test: OpsTest, application_name: str, count: int) -> None: | ||
| """Scale a given application to a specific unit count. | ||
|  | ||
|  | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit add verify
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This specific parameter is related to whether TLS is already enabled or not, different from the tests, where we have parameters related to verify whether TLS is enabled.