Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
78a6502
OSN-1145. Fix other cloud type flavors in ri_breakdown
nk-hystax Dec 9, 2025
0b0cd54
Pull request update/251209
stanfra Dec 9, 2025
ee2cdd7
OSN-1226. Export chart download error
DoRightt Dec 10, 2025
0841e29
OSN-1194. Add TypeScript typings for WrapperCard component
ka-hystax Dec 10, 2025
785b8e4
OSS-203. The name of resources is missing from the links in the top r…
ka-hystax Dec 10, 2025
0e3011d
Pull request update/251211
stanfra Dec 11, 2025
c79fcc2
Feature/mpt 15116/udate assumed role connect form
dwolosz Dec 11, 2025
f85c5c5
OSN-1205. Optimized raw expenses query
sd-hystax Dec 11, 2025
10d7260
Pull request update/251216
stanfra Dec 16, 2025
57ba330
Allow cloud accounts to switch to assumed role
bdjilka Dec 16, 2025
ebcba87
OSN-1225. Fixed bumi module hanging
sd-hystax Dec 18, 2025
620f60f
OSN-1249. Fixed recommendation error on empty region candidates
sd-hystax Dec 19, 2025
2be4e65
Pull request update/251219
stanfra Dec 19, 2025
75e29b0
OSN-1245. Fixed expense anomaly not hit
nk-hystax Dec 22, 2025
76f5569
OSN-1242. Default recommendations limit removed
DoRightt Dec 23, 2025
8f0ba4c
Pull request update/251223
stanfra Dec 23, 2025
2cbd948
OSN-1234. Skip email by regex filter on template parameter value
nk-hystax Dec 23, 2025
e5bab41
Feature/billing
nk-hystax Dec 23, 2025
1e9bc94
Fixed subspector build
sd-hystax Dec 23, 2025
1182932
OSN-1234. Fix email filters doesn't work on some emails
nk-hystax Dec 24, 2025
80004ef
OSN-1252. Introduced a new environment variable for billing integration
ek-hystax Dec 24, 2025
9b1402d
Fixed error format
sd-hystax Dec 24, 2025
81a7579
OSN-1255: added cloudwatch:GetMetricData
nexusriot Dec 25, 2025
a68194f
OSN-1257. Add ability to suppress api error alerts
ek-hystax Dec 25, 2025
17881d8
OSN-1258. Ignore environment CA for billing summary
sd-hystax Dec 26, 2025
6a8bcc7
Pull request update/251229
stanfra Dec 29, 2025
f797130
OSN-1142. Replace ObsoleteImages recommendation with SnapshotsWithNon…
nk-hystax Dec 29, 2025
8a15006
OSN-1174. Replace “Obsolete Images” recommendation with “Snapshots wi…
ka-hystax Dec 29, 2025
257be67
OSN-1262. Archive page is unavailable
ka-hystax Dec 30, 2025
e7c81ac
OSN-1247: Respect disabled regions for assumed roles
nexusriot Jan 7, 2026
9bd9ebd
OSN-1270. Fix missing report files on buckets with 1000+ files
nk-hystax Jan 8, 2026
f9be403
Pull request update/260108
stanfra Jan 8, 2026
6377288
Create Type and Tag model in rest api service
bdjilka Jan 13, 2026
2940a01
Implement theme resolver plugin for Vite to support theme-specific
dwolosz Jan 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: Build deactivatorg test image and run tests on it
run-name: Build deactivatorg test image and run tests on it - started by ${{ github.actor }}
name: Build bailiff test image and run tests on it
run-name: Build bailiff test image and run tests on it - started by ${{ github.actor }}
permissions: read-all
on:
pull_request:
types: [opened, synchronize]
paths:
- 'docker_images/deactivatorg/**'
- 'docker_images/bailiff/**'
workflow_dispatch:


Expand All @@ -25,6 +25,6 @@ jobs:
username: ${{ env.username }}
password: ${{ env.password }}
- name: Build image
run: bash -x build.sh deactivatorg build
run: bash -x build.sh bailiff build
- name: Build test image and run tests
run: bash -x docker_images/run_test.sh deactivatorg
run: bash -x docker_images/run_test.sh bailiff
30 changes: 30 additions & 0 deletions .github/workflows/test_subspector.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Build subspector test image and run tests on it
run-name: Build subspector test image and run tests on it - started by ${{ github.actor }}
permissions: read-all
on:
pull_request:
types: [opened, synchronize]
paths:
- 'subspector/**'
workflow_dispatch:


jobs:
build_image:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Login to Docker Hub (optional)
env:
username: ${{ secrets.EXT_DOCKER_LOGIN }}
password: ${{ secrets.EXT_DOCKER_TOKEN }}
if: ${{ env.username != '' && env.password != ''}}
uses: docker/login-action@v3
with:
username: ${{ env.username }}
password: ${{ env.password }}
- name: Build image
run: bash -x build.sh subspector build
- name: Build test image and run tests
run: bash -x subspector/run_test.sh
30 changes: 30 additions & 0 deletions .github/workflows/test_subsyncer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Build subsyncer test image and run tests on it
run-name: Build subsyncer test image and run tests on it - started by ${{ github.actor }}
permissions: read-all
on:
pull_request:
types: [opened, synchronize]
paths:
- 'docker_images/subsyncer/**'
workflow_dispatch:


jobs:
build_image:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Login to Docker Hub (optional)
env:
username: ${{ secrets.EXT_DOCKER_LOGIN }}
password: ${{ secrets.EXT_DOCKER_TOKEN }}
if: ${{ env.username != '' && env.password != ''}}
uses: docker/login-action@v3
with:
username: ${{ env.username }}
password: ${{ env.password }}
- name: Build image
run: bash -x build.sh subsyncer build
- name: Build test image and run tests
run: bash -x docker_images/run_test.sh subsyncer
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@

from bumiworker.bumiworker.consts import ArchiveReason
from bumiworker.bumiworker.modules.base import ArchiveBase
from bumiworker.bumiworker.modules.recommendations.obsolete_images import (
ObsoleteImages as ObsoleteImagesRecommendation, SUPPORTED_CLOUD_TYPES)
from bumiworker.bumiworker.modules.recommendations.snapshots_with_non_used_images import (
SnapshotsWithNonUsedImages as SnapshotsWithNonUsedImagesRecommendation,
SUPPORTED_CLOUD_TYPES
)

LOG = logging.getLogger(__name__)


class ObsoleteImages(ArchiveBase, ObsoleteImagesRecommendation):
class SnapshotsWithNonUsedImages(ArchiveBase,
SnapshotsWithNonUsedImagesRecommendation):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.reason_description_map[ArchiveReason.RECOMMENDATION_APPLIED] = (
'image deleted')
'snapshot deleted')

@property
def supported_cloud_types(self):
Expand All @@ -35,15 +38,14 @@ def _get(self, previous_options, optimizations, cloud_accounts_map,
starting_point = datetime.now(timezone.utc) - timedelta(
days=days_threshold)

images_map = self._get_images_map(cloud_accounts_map.values(), starting_point)
images_map = self._get_images_map(cloud_accounts_map.values())
used_image_ids = self.mongo_client.restapi.resources.distinct(
'meta.image_id', {
'cloud_account_id': {'$in': list(cloud_accounts_map.keys())},
'resource_type': 'Instance',
'meta.image_id': {'$in': list(images_map.keys())},
'_last_seen_date': {'$gte': self.timestamp_to_day_start(
starting_point.timestamp())},
'first_seen': {'$gte': starting_point.timestamp()}
starting_point.timestamp())}
}
)
for cloud_account_id, optimizations_ in account_optimizations_map.items():
Expand All @@ -53,12 +55,24 @@ def _get(self, previous_options, optimizations, cloud_accounts_map,
optimization, ArchiveReason.CLOUD_ACCOUNT_DELETED)
result.append(optimization)
continue
resource_ids = [x['resource_id'] for x in optimizations_]
snapshots = [
x['_id'] for x in self.mongo_client.restapi.resources.find(
{'_id': {'$in': resource_ids}, 'active': True})
]
for optimization in optimizations_:
resource_id = optimization['cloud_resource_id']
if resource_id not in images_map:
resource_id = optimization['resource_id']
images = optimization['images']
if resource_id not in snapshots:
# snapshot deleted
self._set_reason_properties(
optimization, ArchiveReason.RECOMMENDATION_APPLIED)
elif resource_id in used_image_ids:
elif any(x in used_image_ids for x in images):
# image used for instance
self._set_reason_properties(
optimization, ArchiveReason.RECOMMENDATION_IRRELEVANT)
elif all(x not in images_map for x in images):
# image deleted
self._set_reason_properties(
optimization, ArchiveReason.RECOMMENDATION_IRRELEVANT)
else:
Expand All @@ -69,5 +83,5 @@ def _get(self, previous_options, optimizations, cloud_accounts_map,


def main(organization_id, config_client, created_at, **kwargs):
return ObsoleteImages(
return SnapshotsWithNonUsedImages(
organization_id, config_client, created_at).get()
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
from collections import defaultdict
from concurrent.futures.thread import ThreadPoolExecutor
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import Any, Dict, List, Tuple
from datetime import datetime, date, timedelta

Expand Down Expand Up @@ -205,7 +205,7 @@ def _display_name(storage_type):
})
metrics = aws.get_cloud_watch_metric_data(
region, metric_queries, today,
today - timedelta(days=7))
today - timedelta(days=2))
for md in metrics.get("MetricDataResults", []):
values = md.get("Values") or []
if not values:
Expand All @@ -228,14 +228,21 @@ def _candidates_and_savings(self,
"""
buckets_data = {}
result = []
with ThreadPoolExecutor(max_workers=50) as executor:
if not region_candidates:
return result
cw_clients = {
region: aws.session.client("cloudwatch", region_name=region)
for region in region_candidates
}
max_workers = min(20, sum(len(v) for v in region_candidates.values()))
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = []
for region, candidates in region_candidates.items():
s3_client = aws.session.client("s3", region_name=region)
for cand in candidates:
for region, buckets in region_candidates.items():
cloudwatch = cw_clients[region]
for bucket in buckets:
futures.append(executor.submit(
aws.get_bucket_storage_info, s3_client, cand, ))
for f in futures:
aws.get_bucket_storage_info, cloudwatch, bucket, ))
for f in as_completed(futures):
res = f.result()
if res:
buckets_data.update(res)
Expand Down
Loading