lex-cost-scanner 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/legion/extensions/cost_scanner/actors/weekly_scan.rb +1 -1
- data/lib/legion/extensions/cost_scanner/helpers/classifier.rb +4 -4
- data/lib/legion/extensions/cost_scanner/helpers/findings_store.rb +3 -3
- data/lib/legion/extensions/cost_scanner/runners/reporter.rb +7 -5
- data/lib/legion/extensions/cost_scanner/runners/scanner.rb +15 -13
- data/lib/legion/extensions/cost_scanner/version.rb +1 -1
- data/lib/legion/extensions/cost_scanner.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 505897e6d0311a9e6d695a1f391fa80e34e923de745f03af6f2de11354b56ce3
|
|
4
|
+
data.tar.gz: 3df5cf94e94894598b0d5fe0afaac3e441d6a3e18ee195c1d945bd91eb660806
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 70ad1bedc0e2236f159e38423657b03583706e31292567a5f36afdf0f3de0e7836980c70bf9721f5ef844335dcc0f8bec1e2c6bad3685556f6622f5dc2fd6f63
|
|
7
|
+
data.tar.gz: 43cddabb87240fabbf4240b920eea240cabe6eaca4198166a39d3a571bec12fc0f6bd3288baa860565b90be6ed347348f18fc141c791bb15f6deda16d5d45d0f
|
data/CHANGELOG.md
CHANGED
|
@@ -53,15 +53,15 @@ module Legion
|
|
|
53
53
|
def llm_classify(resource_id:, resource_type:, monthly_cost:, utilization:)
|
|
54
54
|
prompt = format(CLASSIFY_PROMPT, resource_type: resource_type, resource_id: resource_id,
|
|
55
55
|
monthly_cost: monthly_cost, utilization: utilization.inspect)
|
|
56
|
-
response = Legion::LLM.chat(
|
|
56
|
+
response = Legion::LLM.chat( # rubocop:disable Legion/HelperMigration/DirectLlm
|
|
57
57
|
message: prompt,
|
|
58
|
-
caller:
|
|
58
|
+
caller: { extension: 'lex-cost-scanner', function: 'classify' }
|
|
59
59
|
)
|
|
60
|
-
parsed = Legion::JSON.load(response)
|
|
60
|
+
parsed = Legion::JSON.load(response) # rubocop:disable Legion/HelperMigration/DirectJson
|
|
61
61
|
parsed[:finding_type] = parsed[:finding_type].to_sym
|
|
62
62
|
parsed[:severity] = parsed[:severity].to_sym
|
|
63
63
|
parsed.merge(resource_id: resource_id, resource_type: resource_type, method: :llm)
|
|
64
|
-
rescue StandardError
|
|
64
|
+
rescue StandardError => _e
|
|
65
65
|
result = rule_based_classify(utilization: utilization, monthly_cost: monthly_cost)
|
|
66
66
|
result.merge(resource_id: resource_id, resource_type: resource_type, method: :rule_based_fallback)
|
|
67
67
|
end
|
|
@@ -6,7 +6,7 @@ module Legion
|
|
|
6
6
|
module Helpers
|
|
7
7
|
module FindingsStore
|
|
8
8
|
@mutex = Mutex.new
|
|
9
|
-
@findings = {}
|
|
9
|
+
@findings = {} # rubocop:disable ThreadSafety/MutableClassInstanceVariable
|
|
10
10
|
|
|
11
11
|
module_function
|
|
12
12
|
|
|
@@ -55,9 +55,9 @@ module Legion
|
|
|
55
55
|
|
|
56
56
|
def stats
|
|
57
57
|
@mutex.synchronize do
|
|
58
|
-
{ total:
|
|
58
|
+
{ total: @findings.size,
|
|
59
59
|
total_savings: @findings.values.sum { |f| f[:estimated_monthly_savings] || 0.0 },
|
|
60
|
-
by_type:
|
|
60
|
+
by_type: @findings.values.group_by { |f| f[:finding_type] }.transform_values(&:size) }
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
|
|
@@ -5,15 +5,17 @@ module Legion
|
|
|
5
5
|
module CostScanner
|
|
6
6
|
module Runners
|
|
7
7
|
module Reporter
|
|
8
|
+
extend self
|
|
9
|
+
|
|
8
10
|
def generate_report(limit: 10)
|
|
9
11
|
top = Helpers::FindingsStore.top_by_savings(limit: limit)
|
|
10
12
|
stats = Helpers::FindingsStore.stats
|
|
11
13
|
|
|
12
|
-
{ total_savings:
|
|
14
|
+
{ total_savings: stats[:total_savings],
|
|
13
15
|
findings_count: stats[:total],
|
|
14
|
-
by_type:
|
|
15
|
-
top_findings:
|
|
16
|
-
generated_at:
|
|
16
|
+
by_type: stats[:by_type],
|
|
17
|
+
top_findings: top,
|
|
18
|
+
generated_at: Time.now }
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def format_slack_blocks(report:)
|
|
@@ -55,7 +57,7 @@ module Legion
|
|
|
55
57
|
private
|
|
56
58
|
|
|
57
59
|
def report_webhook
|
|
58
|
-
return nil unless defined?(Legion::Settings)
|
|
60
|
+
return nil unless defined?(Legion::Settings) # rubocop:disable Legion/Extension/RunnerReturnHash
|
|
59
61
|
|
|
60
62
|
config = Legion::Settings[:cost_scanner] || {}
|
|
61
63
|
config[:slack_webhook]
|
|
@@ -5,6 +5,8 @@ module Legion
|
|
|
5
5
|
module CostScanner
|
|
6
6
|
module Runners
|
|
7
7
|
module Scanner
|
|
8
|
+
extend self
|
|
9
|
+
|
|
8
10
|
def scan_all
|
|
9
11
|
accounts = scanner_config[:accounts] || []
|
|
10
12
|
results = accounts.map { |acct| scan_account(account_id: acct[:id], cloud: acct[:cloud]) }
|
|
@@ -38,31 +40,31 @@ module Legion
|
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
def process_resource(account_id:, resource:)
|
|
41
|
-
return false if (resource[:monthly_cost] || 0) < Helpers::Constants::MIN_MONTHLY_COST
|
|
43
|
+
return false if (resource[:monthly_cost] || 0) < Helpers::Constants::MIN_MONTHLY_COST # rubocop:disable Legion/Extension/RunnerReturnHash
|
|
42
44
|
|
|
43
45
|
classification = Helpers::Classifier.classify(
|
|
44
|
-
resource_id:
|
|
46
|
+
resource_id: resource[:resource_id],
|
|
45
47
|
resource_type: resource[:resource_type],
|
|
46
|
-
monthly_cost:
|
|
47
|
-
utilization:
|
|
48
|
+
monthly_cost: resource[:monthly_cost],
|
|
49
|
+
utilization: resource[:utilization] || {}
|
|
48
50
|
)
|
|
49
|
-
return false if classification[:finding_type] == :none
|
|
51
|
+
return false if classification[:finding_type] == :none # rubocop:disable Legion/Extension/RunnerReturnHash
|
|
50
52
|
|
|
51
53
|
result = Helpers::FindingsStore.record(
|
|
52
|
-
account_id:
|
|
53
|
-
resource_id:
|
|
54
|
-
resource_type:
|
|
55
|
-
finding_type:
|
|
56
|
-
severity:
|
|
57
|
-
monthly_cost:
|
|
54
|
+
account_id: account_id,
|
|
55
|
+
resource_id: resource[:resource_id],
|
|
56
|
+
resource_type: resource[:resource_type],
|
|
57
|
+
finding_type: classification[:finding_type],
|
|
58
|
+
severity: classification[:severity],
|
|
59
|
+
monthly_cost: resource[:monthly_cost],
|
|
58
60
|
estimated_monthly_savings: classification[:estimated_monthly_savings],
|
|
59
|
-
recommendation:
|
|
61
|
+
recommendation: classification[:recommendation]
|
|
60
62
|
)
|
|
61
63
|
result[:new]
|
|
62
64
|
end
|
|
63
65
|
|
|
64
66
|
def fetch_resources(_account_id:, _cloud: 'aws')
|
|
65
|
-
return [] unless defined?(Legion::Extensions::Http::Client)
|
|
67
|
+
return [] unless defined?(Legion::Extensions::Http::Client) # rubocop:disable Legion/Extension/RunnerReturnHash
|
|
66
68
|
|
|
67
69
|
[]
|
|
68
70
|
end
|
|
@@ -7,7 +7,7 @@ require_relative 'cost_scanner/helpers/findings_store'
|
|
|
7
7
|
require_relative 'cost_scanner/runners/scanner'
|
|
8
8
|
require_relative 'cost_scanner/runners/reporter'
|
|
9
9
|
|
|
10
|
-
require_relative 'cost_scanner/actors/weekly_scan'
|
|
10
|
+
require_relative 'cost_scanner/actors/weekly_scan'
|
|
11
11
|
|
|
12
12
|
module Legion
|
|
13
13
|
module Extensions
|