Skip to content

Commit 0ed77fa

Browse files
committed
Merge remote-tracking branch 'origin/release/v11.2.2' into release/v11.2.2
2 parents 75dc4c4 + e446278 commit 0ed77fa

File tree

15 files changed

+143
-72
lines changed

15 files changed

+143
-72
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ installer/installer
1111
geolocation/
1212
installer/public_key.crt
1313
.github/scripts/golang-updater/go-updater
14+
15+
16+
qodana.yaml

agent-manager/updates/updates.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import (
44
"crypto/tls"
55
"net/http"
66
"os"
7+
"time"
78

8-
"github.com/gin-contrib/gzip"
99
"github.com/threatwinds/go-sdk/catcher"
1010

1111
"github.com/gin-gonic/gin"
@@ -23,7 +23,6 @@ func ServeDependencies() {
2323
r := gin.New()
2424
r.Use(
2525
gin.Recovery(),
26-
gzip.Gzip(gzip.DefaultCompression),
2726
)
2827

2928
r.NoRoute(notFound)
@@ -33,20 +32,31 @@ func ServeDependencies() {
3332

3433
loadedCert, err := tls.LoadX509KeyPair(config.CertPath, config.CertKeyPath)
3534
if err != nil {
36-
catcher.Error("failed to load TLS credentials", err, map[string]any{"process": "agent-manager"})
35+
_ = catcher.Error("failed to load TLS credentials", err, map[string]any{"process": "agent-manager"})
36+
time.Sleep(5 * time.Second)
3737
os.Exit(1)
3838
}
3939

4040
tlsConfig := &tls.Config{
41-
MinVersion: tls.VersionTLS12,
4241
Certificates: []tls.Certificate{loadedCert},
42+
MinVersion: tls.VersionTLS12,
43+
MaxVersion: tls.VersionTLS13,
4344
CipherSuites: []uint16{
44-
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
45+
// TLS 1.2 secure cipher suites - RSA key exchange
4546
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
4647
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
48+
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
49+
// TLS 1.2 secure cipher suites - ECDSA key exchange (for ECDSA certificates)
50+
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
51+
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
52+
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
53+
},
54+
CurvePreferences: []tls.CurveID{
55+
tls.X25519, // Modern and fast
56+
tls.CurveP256, // NIST P-256
57+
tls.CurveP384, // NIST P-384
58+
tls.CurveP521, // NIST P-521
4759
},
48-
49-
PreferServerCipherSuites: true,
5060
}
5161

5262
server := &http.Server{
@@ -57,7 +67,7 @@ func ServeDependencies() {
5767

5868
catcher.Info("Starting HTTP server on port 8080", map[string]any{"process": "agent-manager"})
5969
if err := server.ListenAndServeTLS("", ""); err != nil {
60-
catcher.Error("error starting HTTP server", err, map[string]any{"process": "agent-manager"})
70+
_ = catcher.Error("error starting HTTP server", err, map[string]any{"process": "agent-manager"})
6171
return
6272
}
6373
}

agent/updater/utils/download.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ func DownloadFile(url string, headers map[string]string, fileName string, path s
2020

2121
client := &http.Client{}
2222
client.Transport = &http.Transport{
23-
TLSClientConfig: &tls.Config{InsecureSkipVerify: skipTlsVerification},
23+
TLSClientConfig: &tls.Config{InsecureSkipVerify: skipTlsVerification},
24+
DisableCompression: true,
2425
}
2526

2627
resp, err := client.Do(req)

agent/utils/download.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func DownloadFile(url string, headers map[string]string, fileName string, path s
2121
client := &http.Client{}
2222
client.Transport = &http.Transport{
2323
TLSClientConfig: &tls.Config{InsecureSkipVerify: skipTlsVerification},
24+
DisableCompression: true,
2425
}
2526

2627
resp, err := client.Do(req)

agent/utils/files.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"io"
99
"os"
1010
"path/filepath"
11+
"reflect"
1112

1213
"gopkg.in/yaml.v2"
1314
)
@@ -22,6 +23,15 @@ func GetMyPath() string {
2223
}
2324

2425
func ReadYAML(path string, result interface{}) error {
26+
if result == nil {
27+
return fmt.Errorf("result interface is nil")
28+
}
29+
30+
rv := reflect.ValueOf(result)
31+
if rv.Kind() != reflect.Ptr || rv.IsNil() {
32+
return fmt.Errorf("result must be a non-nil pointer")
33+
}
34+
2535
file, err := os.Open(path)
2636
if err != nil {
2737
return err
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<databaseChangeLog
3+
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
6+
7+
<changeSet id="20260126001" author="Manuel Abascal">
8+
9+
<update tableName="utm_configuration_parameter">
10+
<column name="conf_param_regexp" value="^(?:https?:\/\/)?(?:\d{1,3}(?:\.\d{1,3}){3}|(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,})(?:\/[^\s]*)?$"/>
11+
<where> conf_param_short = 'utmstack.mail.baseUrl' </where>
12+
</update>
13+
14+
</changeSet>
15+
16+
</databaseChangeLog>

backend/src/main/resources/config/liquibase/master.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,4 +319,6 @@
319319

320320
<include file="/config/liquibase/changelog/20260122004_update_azure_visualizations.xml" relativeToChangelogFile="false"/>
321321

322+
<include file="/config/liquibase/changelog/20260126001_update_regex_for_configuration_parameter_base_url.xml" relativeToChangelogFile="false"/>
323+
322324
</databaseChangeLog>

filters/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
# UTMStack Filters
2+
3+
Documentation on how to create and maintain custom filters can be found in: https://github.com/utmstack/UTMStack/wiki

installer/utils/os.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"os"
88
"os/exec"
99
"path/filepath"
10+
"reflect"
1011

1112
"gopkg.in/yaml.v3"
1213
)
@@ -51,12 +52,12 @@ func RunCmd(command string, arg ...string) error {
5152

5253
func RunCmdWithOutput(command string, arg ...string) ([]string, error) {
5354
cmd := exec.Command(command, arg...)
54-
55+
5556
output, err := cmd.Output()
5657
if err != nil {
5758
return nil, fmt.Errorf("error running command: %v", err)
5859
}
59-
60+
6061
lines := bytes.Split(output, []byte("\n"))
6162
result := make([]string, 0, len(lines))
6263
for _, line := range lines {
@@ -65,7 +66,7 @@ func RunCmdWithOutput(command string, arg ...string) ([]string, error) {
6566
result = append(result, string(trimmed))
6667
}
6768
}
68-
69+
6970
return result, nil
7071
}
7172

@@ -127,6 +128,15 @@ func WriteYAML(url string, data any) error {
127128
}
128129

129130
func ReadYAML(path string, result any) error {
131+
if result == nil {
132+
return fmt.Errorf("result interface is nil")
133+
}
134+
135+
rv := reflect.ValueOf(result)
136+
if rv.Kind() != reflect.Ptr || rv.IsNil() {
137+
return fmt.Errorf("result must be a non-nil pointer")
138+
}
139+
130140
file, err := os.Open(path)
131141
if err != nil {
132142
return err

plugins/alerts/main.go

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package main
22

33
import (
44
"context"
5-
"fmt"
65
"os"
76
"regexp"
87
"strings"
@@ -86,22 +85,13 @@ func correlate(ctx context.Context,
8685
}
8786
}()
8887

89-
parentId := getPreviousAlertId(alert)
90-
91-
if parentId != nil {
92-
if isDuplicate(alert) {
93-
return nil, nil
94-
}
95-
return nil, newAlert(alert, parentId)
88+
if isDuplicate(alert) {
89+
return nil, nil
9690
}
9791

98-
if len(alert.DeduplicateBy) > 0 {
99-
if isDuplicate(alert) {
100-
return nil, nil
101-
}
102-
}
92+
parentId := getPreviousAlertId(alert)
10393

104-
return nil, newAlert(alert, nil)
94+
return nil, newAlert(alert, parentId)
10595
}
10696

10797
func isDuplicate(alert *plugins.Alert) bool {
@@ -116,6 +106,10 @@ func isDuplicate(alert *plugins.Alert) bool {
116106
}
117107
}()
118108

109+
if len(alert.DeduplicateBy) == 0 {
110+
return false
111+
}
112+
119113
alertString, err := utils.ProtoMessageToString(alert)
120114
if err != nil {
121115
_ = catcher.Error("cannot convert alert to string", err, map[string]any{"alert": alert.Name, "process": "plugin_com.utmstack.alerts"})
@@ -129,7 +123,7 @@ func isDuplicate(alert *plugins.Alert) bool {
129123
bb := sdkos.NewBoolBuilder(ctx, indices, "plugin_com.utmstack.alerts")
130124

131125
// 1. Filter by Name (always)
132-
bb.FilterTerm("name.keyword", alert.Name)
126+
bb.FilterTerm("name", alert.Name)
133127

134128
// Compile regex for array index stripping
135129
reArrayIndex := regexp.MustCompile(`\.[0-9]+(\.|$)`)
@@ -139,7 +133,7 @@ func isDuplicate(alert *plugins.Alert) bool {
139133

140134
value := gjson.Get(*alertString, d)
141135
if value.Type == gjson.Null {
142-
continue
136+
return false
143137
}
144138

145139
// Calculate OpenSearch field name by removing array indices
@@ -151,7 +145,7 @@ func isDuplicate(alert *plugins.Alert) bool {
151145
})
152146

153147
if value.Type == gjson.String {
154-
bb.FilterTerm(fmt.Sprintf("%s.keyword", searchField), value.String())
148+
bb.FilterTerm(searchField, value.String())
155149
} else if value.Type == gjson.Number {
156150
bb.FilterTerm(searchField, value.Float())
157151
} else if value.IsBool() {
@@ -196,12 +190,7 @@ func getPreviousAlertId(alert *plugins.Alert) *string {
196190
}
197191
}()
198192

199-
searchFields := alert.GroupBy
200-
if len(searchFields) == 0 {
201-
searchFields = alert.DeduplicateBy
202-
}
203-
204-
if len(searchFields) == 0 {
193+
if len(alert.GroupBy) == 0 {
205194
return nil
206195
}
207196

@@ -218,7 +207,7 @@ func getPreviousAlertId(alert *plugins.Alert) *string {
218207
bb := sdkos.NewBoolBuilder(ctx, indices, "plugin_com.utmstack.alerts")
219208

220209
// 1. Filter by Name (always)
221-
bb.FilterTerm("name.keyword", alert.Name)
210+
bb.FilterTerm("name", alert.Name)
222211

223212
// 2. Must NOT match existing ParentId (we want strictly the parent, or another orphan, not a child)
224213
// Original logic: MustNot exists field "parentId"
@@ -227,12 +216,12 @@ func getPreviousAlertId(alert *plugins.Alert) *string {
227216
// Compile regex for array index stripping
228217
reArrayIndex := regexp.MustCompile(`\.[0-9]+(\.|$)`)
229218

230-
for _, d := range searchFields {
219+
for _, d := range alert.GroupBy {
231220
d = strings.TrimSuffix(d, ".keyword")
232221

233222
value := gjson.Get(*alertString, d)
234223
if value.Type == gjson.Null {
235-
continue
224+
return nil
236225
}
237226

238227
// Calculate OpenSearch field name by removing array indices
@@ -244,7 +233,7 @@ func getPreviousAlertId(alert *plugins.Alert) *string {
244233
})
245234

246235
if value.Type == gjson.String {
247-
bb.FilterTerm(fmt.Sprintf("%s.keyword", searchField), value.String())
236+
bb.FilterTerm(searchField, value.String())
248237
} else if value.Type == gjson.Number {
249238
bb.FilterTerm(searchField, value.Float())
250239
} else if value.IsBool() {

0 commit comments

Comments
 (0)