Skip to content

Fix cost over usage resource file path and Jenkins exit handling.#1008

Merged
pragya811 merged 1 commit into
mainfrom
jenkins_fix8
Jul 3, 2026
Merged

Fix cost over usage resource file path and Jenkins exit handling.#1008
pragya811 merged 1 commit into
mainfrom
jenkins_fix8

Conversation

@pragya811

Copy link
Copy Markdown
Member

Type of change

Note: Fill x in []

  • bug
  • enhancement
  • documentation
  • dependencies

Description

Write the user resource JSON to /tmp before S3 upload and fail the weekly Jenkins job when podman runs return a non-zero exit code.

For security reasons, all pull requests need to be approved first before running any automated CI

Assisted-by: Cursor

Write the user resource JSON to /tmp before S3 upload and fail the weekly Jenkins job when podman runs return a non-zero exit code.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved cost alert handling so emails only include an attachment when instance details are available, avoiding invalid file references.
    • Cost calculations now handle instance-related usage more reliably when summarizing user spending.
    • Upload jobs now stop immediately if any container run command fails, helping prevent partial or inconsistent results.

Walkthrough

This PR modifies cost_over_usage.py to fix Cost field aggregation, guard instance file creation, and conditionally attach email files, and updates run_upload_es.py to run podman commands in a loop that exits on failure.

Changes

Cost usage report and alerting fixes

Layer / File(s) Summary
Cost aggregation and threshold email flow
cloud_governance/policy/aws/cost_over_usage.py
Cost aggregation switches to pandas string aggregation, file_name is initialized to None and only set when Instances data exists, and email sending conditionally includes filename via email_kwargs.

Podman command execution hardening

Layer / File(s) Summary
Command loop with failure exit
jenkins/clouds/aws/weekly/cost_over_usage/run_upload_es.py
Podman commands are collected into a list and executed in a loop, exiting with status 1 if any command fails.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant aws_user_usage
  participant FileSystem
  participant send_email_postfix
  aws_user_usage->>aws_user_usage: check cost_usage exceeded
  aws_user_usage->>aws_user_usage: evaluate ignore_user_mails
  alt Instances present
    aws_user_usage->>FileSystem: write /tmp/<to>_resource.json
    aws_user_usage->>aws_user_usage: set file_name
  end
  aws_user_usage->>send_email_postfix: send_email_postfix(**email_kwargs)
Loading

Related issues: None specified

Related PRs: None specified

Suggested labels: bug, enhancement

Suggested reviewers: None specified

🐰 A hop, a fix, a JSON file's fate,
Only written when Instances await,
Podman commands march in a row,
Exit at the first sign of woe.
Cost sums summed the pandas way—
Carrots for a cleaner day! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the two main fixes: resource file handling and Jenkins exit handling.
Description check ✅ Passed The description matches the implemented changes by describing the /tmp JSON write and Jenkins failure behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@pragya811 pragya811 self-assigned this Jul 2, 2026
@pragya811 pragya811 added the bug Something isn't working label Jul 2, 2026
@pragya811 pragya811 requested a review from ebattat July 2, 2026 10:56

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
cloud_governance/policy/aws/cost_over_usage.py (2)

96-96: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Loop-invariant literal_eval call.

self.__ignore_mails is decoded on every iteration of the for user_usage in user_data loop even though it doesn't depend on the loop variable. Hoist it outside the loop.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cloud_governance/policy/aws/cost_over_usage.py` at line 96, The
`literal_eval` on `self.__ignore_mails` inside the `for user_usage in user_data`
loop is loop-invariant and should be moved out of the loop. Update the logic in
`CostOverUsage` so the decoded `ignore_user_mails` value is computed once before
iterating over `user_data`, then reused within the loop; use the existing
`self._elastic_upload.literal_eval` and `user_usage` flow to place the hoisted
assignment correctly.

103-108: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Hardcoded /tmp path with no cleanup; consider tempfile module.

Static analysis flags this as insecure temp-file usage (S108/CWE-377). The file is written under a fixed /tmp directory keyed by to (user-controlled/ES-derived value) and never cleaned up after the email is sent, risking accumulation and potential collisions/predictable paths across runs.

♻️ Suggested fix using tempfile
-                    file_name = None
+                    file_name = None
                     if user_usage.get('Instances'):
                         used_instances = self.get_user_used_instances(user_used_list=user_usage.get('Instances'))
-                        file_name = os.path.join('/tmp', f'{to}_resource.json')
+                        file_name = os.path.join(tempfile.gettempdir(), f'{to}_resource.json')
                         with open(file_name, 'w') as file:
                             json.dump(used_instances, file, indent=4)

Also consider deleting file_name after send_email_postfix completes to avoid stale files accumulating in the temp directory.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cloud_governance/policy/aws/cost_over_usage.py` around lines 103 - 108, The
temporary resource file creation in the cost_over_usage flow uses a hardcoded
/tmp path and leaves stale files behind. Update the logic around
get_user_used_instances and the send_email_postfix path to create the JSON file
via tempfile (using a secure, unique location/name instead of
f"{to}_resource.json"), and ensure it is removed after the email is sent. Keep
the fix localized to the block that writes file_name and passes it to
send_email_postfix.

Source: Linters/SAST tools

jenkins/clouds/aws/weekly/cost_over_usage/run_upload_es.py (1)

26-34: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Exit-on-failure loop is correct; consider subprocess over os.system.

Loop logic correctly matches the PR goal of failing when podman returns non-zero. Static analysis flags os.system(command) with interpolated env vars as command-injection risk (Ruff S605, OpenGrep, ast-grep). Since inputs here come from Jenkins environment variables rather than untrusted external input, actual exploitability is low, but migrating to subprocess.run(shlex.split(command)) or a list-of-args form would remove the flagged pattern and give you captured stdout/stderr for better failure diagnostics.

♻️ Suggested refactor
-for command in commands:
-    if os.system(command) != 0:
-        sys.exit(1)
+for command in commands:
+    result = subprocess.run(command, shell=True)
+    if result.returncode != 0:
+        sys.exit(1)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jenkins/clouds/aws/weekly/cost_over_usage/run_upload_es.py` around lines 26 -
34, The loop in run_upload_es.py currently uses os.system(command), which
triggers command-injection/static-analysis warnings even though the values come
from Jenkins env vars. Replace the os.system call with subprocess-based
execution in the command loop, using a safe argument form (or shlex.split if you
keep the command string) so the podman invocation is preserved while avoiding
the flagged pattern and allowing stdout/stderr capture. Keep the existing
failure-on-nonzero behavior in the loop and update the command construction
around commands/command accordingly.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cloud_governance/policy/aws/cost_over_usage.py`:
- Around line 76-79: The aggregation in aggregate_user_sum is using the builtin
sum for the Instances field, which crashes when the column contains list values.
Update the groupby/agg logic in aggregate_user_sum so Instances uses a list-safe
reducer (for example, collecting or combining lists) while keeping the Cost sum
unchanged, and make sure the conditional branch that checks for Instances still
routes through the same aggregation path.

---

Nitpick comments:
In `@cloud_governance/policy/aws/cost_over_usage.py`:
- Line 96: The `literal_eval` on `self.__ignore_mails` inside the `for
user_usage in user_data` loop is loop-invariant and should be moved out of the
loop. Update the logic in `CostOverUsage` so the decoded `ignore_user_mails`
value is computed once before iterating over `user_data`, then reused within the
loop; use the existing `self._elastic_upload.literal_eval` and `user_usage` flow
to place the hoisted assignment correctly.
- Around line 103-108: The temporary resource file creation in the
cost_over_usage flow uses a hardcoded /tmp path and leaves stale files behind.
Update the logic around get_user_used_instances and the send_email_postfix path
to create the JSON file via tempfile (using a secure, unique location/name
instead of f"{to}_resource.json"), and ensure it is removed after the email is
sent. Keep the fix localized to the block that writes file_name and passes it to
send_email_postfix.

In `@jenkins/clouds/aws/weekly/cost_over_usage/run_upload_es.py`:
- Around line 26-34: The loop in run_upload_es.py currently uses
os.system(command), which triggers command-injection/static-analysis warnings
even though the values come from Jenkins env vars. Replace the os.system call
with subprocess-based execution in the command loop, using a safe argument form
(or shlex.split if you keep the command string) so the podman invocation is
preserved while avoiding the flagged pattern and allowing stdout/stderr capture.
Keep the existing failure-on-nonzero behavior in the loop and update the command
construction around commands/command accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 174804e7-dade-462a-b66e-3aa4baed9835

📥 Commits

Reviewing files that changed from the base of the PR and between b4bcb9b and cb4d4e0.

📒 Files selected for processing (2)
  • cloud_governance/policy/aws/cost_over_usage.py
  • jenkins/clouds/aws/weekly/cost_over_usage/run_upload_es.py

Comment thread cloud_governance/policy/aws/cost_over_usage.py

@ebattat ebattat left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/approve

@ebattat ebattat left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/approve

@pragya811 pragya811 merged commit ce5ea46 into main Jul 3, 2026
34 checks passed
@github-project-automation github-project-automation Bot moved this from In progress to Done in Cloud-Governance project Jul 3, 2026
@pragya811 pragya811 deleted the jenkins_fix8 branch July 3, 2026 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Development

Successfully merging this pull request may close these issues.

2 participants