Skip to content

Conversation

osmman
Copy link

@osmman osmman commented Aug 1, 2025

  • removes operator.openshift.io/v1 Console
  • remove route.openshift.io Route and use static internal OCP service
  • load client config from in-cluster and kubeconfig
  • get bearer token via client api
  • mandatory BASE_DOMAIN env variable

Summary by Sourcery

Reduce required OpenShift cluster roles by removing operator and route API dependencies, consolidate config loading and token retrieval, mandate BASE_DOMAIN, and switch to HTTP health checks for Thanos Querier.

Enhancements:

  • Load Kubernetes client configuration from either in-cluster or kubeconfig.
  • Use client.ApiClient configuration for retrieving the bearer token instead of reading the serviceaccount file.
  • Replace Console operator and Route resource checks with HTTP-based Thanos Querier API calls.
  • Require BASE_DOMAIN environment variable for both nightly and installation modes.
  • Allow customizing the Thanos Querier URL via an environment variable with a sensible default.
  • Remove deprecated operator.openshift.io/v1 Console and route.openshift.io/v1 Route dependencies.

- removes operator.openshift.io/v1 Console
- remove route.openshift.io Route and use static internal OCP service
- load client config from in-cluster and kubeconfig
- get bearer token via client api
- mandatory BASE_DOMAIN env variable

Signed-off-by: Tomas Turek <[email protected]>
Copy link

sourcery-ai bot commented Aug 1, 2025

Reviewer's Guide

This PR refactors script.py to eliminate direct use of OpenShift Console and Route APIs by loading configuration more flexibly, retrieving the bearer token via the client API, and using static/internal services accessed over HTTP; it also enforces BASE_DOMAIN as a required environment variable and streamlines the nightly execution flow.

Class diagram for updated authentication and configuration loading

classDiagram
    class Script {
        +openshift_setup()
        +get_bearer_token()
    }
    class client {
        +ApiClient
        +Configuration
    }
    Script ..> client : uses
    Script : +openshift_setup() loads config from in-cluster or kubeconfig
    Script : +get_bearer_token() retrieves token from client.ApiClient
Loading

Flow diagram for new Thanos Querier status check

flowchart TD
    A[Start] --> B[Get THANOS_QUERIER_URL from env or default]
    B --> C[Get bearer token via client API]
    C --> D[Check Thanos Querier API status]
    D -->|Success| E[Proceed with nightly metrics]
    D -->|Failure| F[Fail job]
Loading

File-Level Changes

Change Details Files
Flexible client configuration loading
  • Wrap in-cluster config load in try/catch, fall back to kubeconfig
  • Raise clear error if neither config is available
src/script.py
Remove Console and Route resource queries
  • Delete check_console_operator function and related operator.openshift.io logic
  • Eliminate get_sanitized_cluster_domain and direct Route API calls
  • Replace Thanos Querier route lookup with HTTP status checks
src/script.py
Retrieve bearer token via client API
  • Remove manual file read of serviceaccount token
  • Use client.ApiClient().configuration.api_key to fetch authorization header
  • Error if bearer token is missing
src/script.py
Introduce BASE_DOMAIN environment variable
  • Replace sanitized cluster domain extraction with mandatory BASE_DOMAIN env check
  • Fail early if BASE_DOMAIN is not set
src/script.py
Restructure nightly run logic and parameters
  • Add THANOS_QUERIER_URL env var with default internal service URL
  • Parameterize requests CA bundle env vars
  • Reorder and consolidate checks: user workload monitoring, bearer token, Thanos status
src/script.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@osmman osmman marked this pull request as draft August 1, 2025 14:39
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @osmman - I've reviewed your changes - here's some feedback:

Blocking issues:

  • time.sleep() call; did you mean to leave this in? (link)

General comments:

  • Standardize return types and error handling in the status-check functions so callers can unambiguously distinguish success, failure, and exceptions (e.g., avoid mixing bools and ints and catch specific exception types rather than using bare except).
  • Switch from print statements to the logging module to provide configurable log levels and better observability in cluster environments.
  • Ensure service URLs always include the protocol (https://) when formatting the query endpoints to prevent intermittent connection failures.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Standardize return types and error handling in the status-check functions so callers can unambiguously distinguish success, failure, and exceptions (e.g., avoid mixing bools and ints and catch specific exception types rather than using bare except).
- Switch from print statements to the logging module to provide configurable log levels and better observability in cluster environments.
- Ensure service URLs always include the protocol (https://) when formatting the query endpoints to prevent intermittent connection failures.

## Individual Comments

### Comment 1
<location> `src/script.py:60` </location>
<code_context>
-    route_up = False
-    thanos_quierier_host = ''

+    headers = {'Authorization': '{bearer_token}'.format(bearer_token=bearer_token)}
     while attempt < attempts:
         try:
</code_context>

<issue_to_address>
Authorization header may be missing 'Bearer' prefix.

Omitting the 'Bearer' prefix may cause authentication failures. Update the header to include 'Bearer' if required by the API: {'Authorization': 'Bearer {bearer_token}'}.
</issue_to_address>

### Comment 2
<location> `src/script.py:126` </location>
<code_context>
+    fulcio_new_certs_query_URL = '{thanos_quierier_host}/api/v1/query?&{fulcio_new_certs_query_data}'.format(thanos_quierier_host=thanos_quierier_host, fulcio_new_certs_query_data=fulcio_new_certs_query_data)
</code_context>

<issue_to_address>
Protocol removed from query URLs may cause issues if host is not a full URL.

The new code relies on thanos_quierier_host including the protocol. Please validate or document this requirement to prevent request failures.
</issue_to_address>

### Comment 3
<location> `src/script.py:102` </location>
<code_context>
-        return 1
+    bearer_token = configuration.api_key.get('authorization')
+
+    if not bearer_token:
+        raise RuntimeError("Bearer token not found in the loaded configuration.")
+
</code_context>

<issue_to_address>
Raising RuntimeError may not be handled upstream.

If abrupt termination is not desired, consider returning a sentinel value or handling the error more gracefully.
</issue_to_address>

## Security Issues

### Issue 1
<location> `src/script.py:74` </location>

<issue_to_address>
**security (python.lang.best-practice.arbitrary-sleep):** time.sleep() call; did you mean to leave this in?

*Source: opengrep*
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.


headers = {'Authorization': '{bearer_token}'.format(bearer_token=bearer_token)}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Protocol removed from query URLs may cause issues if host is not a full URL.

The new code relies on thanos_quierier_host including the protocol. Please validate or document this requirement to prevent request failures.

from nightly import main_nightly
from installation import main_installation

def openshift_setup():
config.load_incluster_config()
try:
config.load_incluster_config()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): We've found these issues:

Comment on lines +63 to 73
response = fetch_response_data(query_url+"/api/v1/status/buildinfo", headers, REQUESTS_CA_BUNDLE, REQUESTS_CA_BUNDLE_INTERNAL)
print(response)
if response.status_code == 200 or response.status_code == 201:
return True
else:
print('API is not accessible yet. Retrying in ', sleep_interval, ' seconds...')
attempt = attempt + 1
time.sleep(sleep_interval)
except requests.exceptions.RequestException as e:
print(f"Request failed with error: {e}")
attempt = attempt + 1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): We've found these issues:

Comment on lines +100 to +103
bearer_token = configuration.api_key.get('authorization')

if not bearer_token:
raise RuntimeError("Bearer token not found in the loaded configuration.")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): We've found these issues:

rekor_qps_by_api_query_URL='https://{thanos_quierier_host}/api/v1/query?&{rekor_qps_by_api_query_data}'.format(thanos_quierier_host=thanos_quierier_host, rekor_qps_by_api_query_data=rekor_qps_by_api_query_data)
headers = {'Authorization': 'Bearer {bearer_token}'.format(bearer_token=bearer_token)}
rekor_qps_by_api_query_URL='{thanos_quierier_host}/api/v1/query?&{rekor_qps_by_api_query_data}'.format(thanos_quierier_host=thanos_quierier_host, rekor_qps_by_api_query_data=rekor_qps_by_api_query_data)
headers = {'Authorization': '{bearer_token}'.format(bearer_token=bearer_token)}

fulcio_new_certs_response_data = fetch_response_data(fulcio_new_certs_query_URL, headers, REQUESTS_CA_BUNDLE, REQUESTS_CA_BUNDLE_INTERNAL)
if fulcio_new_certs_response_data.status_code == 200 or fulcio_new_certs_response_data.status_code == 201:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): We've found these issues:

Suggested change
if fulcio_new_certs_response_data.status_code == 200 or fulcio_new_certs_response_data.status_code == 201:
if fulcio_new_certs_response_data.status_code in [200, 201]:


Explanation
The quality score for this function is below the quality threshold of 25%.
This score is a combination of the method length, cognitive complexity and working memory.

How can you solve this?

It might be worth refactoring this function to make it shorter and more readable.

  • Reduce the function length by extracting pieces of functionality out into
    their own functions. This is the most important thing you can do - ideally a
    function should be less than 10 lines.
  • Reduce nesting, perhaps by introducing guard clauses to return early.
  • Ensure that variables are tightly scoped, so that code using related concepts
    sits together within the function rather than being scattered.

REQUESTS_CA_BUNDLE_INTERNAL = os.environ.get('REQUESTS_CA_BUNDLE_INTERNAL')
REQUESTS_CA_BUNDLE = os.environ.get('REQUESTS_CA_BUNDLE')
query_nightly_metrics(openshift_client, thanos_quierier_host, bearer_token, base_domain, REQUESTS_CA_BUNDLE, REQUESTS_CA_BUNDLE_INTERNAL)
requests_ca_bundle_internal = os.environ.get('REQUESTS_CA_BUNDLE_INTERNAL')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): Extract code out into function (extract-method)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant