Skip to content

Commit 81d101e

Browse files
authored
Merge branch 'main' into add-explicit-forward-proxy
2 parents d68fbf6 + a03f7cf commit 81d101e

File tree

14 files changed

+334
-171
lines changed

14 files changed

+334
-171
lines changed

.github/workflows/ci.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ env:
2323
GOPROXY: "https://${{ secrets.ARTIFACTORY_USER }}:${{ secrets.ARTIFACTORY_TOKEN }}@azr.artifactory.f5net.com/artifactory/api/go/f5-nginx-go-dev"
2424

2525
jobs:
26+
set-vars:
27+
runs-on: ubuntu-22.04
28+
steps:
29+
- name: Set Variables
30+
run: |
31+
if [[ -z ${{ secrets.ARTIFACTORY_USER }} ]] ||
32+
[[ -z ${{ secrets.ARTIFACTORY_TOKEN }} ]] ||
33+
${{ github.event.pull_request.head.repo.fork }}; then
34+
echo "GOPROXY=direct" >> $GITHUB_ENV
35+
fi
36+
2637
lint:
2738
name: Lint
2839
runs-on: ubuntu-22.04

.github/workflows/release-branch.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ on:
4242

4343
env:
4444
NFPM_VERSION: 'v2.35.3'
45-
GOPROXY: "https://${{ secrets.ARTIFACTORY_USER }}:${{ secrets.ARTIFACTORY_TOKEN }}@azr.artifactory.f5net.com/artifactory/api/go/f5-nginx-go-local-approved-dependency"
45+
GOPROXY: "https://${{ secrets.ARTIFACTORY_USER }}:${{ secrets.ARTIFACTORY_TOKEN }}@azr.artifactory.f5net.com/artifactory/api/go/f5-nginx-go-dev"
4646

4747
defaults:
4848
run:
@@ -304,10 +304,10 @@ jobs:
304304
script: |
305305
const { repo, owner } = context.repo;
306306
const result = await github.rest.pulls.create({
307-
title: 'Merge ${{ github.ref_name }} back into main',
307+
title: 'Merge ${{ inputs.releaseBranch }} back into main',
308308
owner,
309309
repo,
310-
head: '${{ github.ref_name }}',
310+
head: '${{ inputs.releaseBranch }}',
311311
base: 'main',
312312
body: [
313313
'This PR is auto-generated by the release workflow.'

Makefile.packaging

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ AZURE_PACKAGES_DIR := ./build/azure/packages
99
BINARY_PATH := $(BUILD_DIR)/$(BINARY_NAME)
1010
GPG_PUBLIC_KEY := .key
1111
PACKAGE_BUILD ?= 1
12-
PACKAGE_VERSION := $(shell git describe --match "v[0-9]*" --abbrev=0 --tags)
12+
PACKAGE_VERSION ?= $(shell echo ${VERSION} | tr -d 'v')
1313
TARBALL_NAME := $(PACKAGE_PREFIX).tar.gz
1414

1515
DEB_DISTROS ?= ubuntu-plucky-25.04 ubuntu-noble-24.04 ubuntu-jammy-22.04 ubuntu-focal-20.04 debian-bookworm-12 debian-bullseye-11
@@ -35,7 +35,7 @@ $(PACKAGES_DIR):
3535
@mkdir -p $(PACKAGES_DIR)/deb && mkdir -p $(PACKAGES_DIR)/rpm && mkdir -p $(PACKAGES_DIR)/apk
3636

3737
.PHONY: package
38-
package: $(PACKAGES_DIR) #### Create final packages for all supported distros
38+
package: gpg-key $(PACKAGES_DIR) #### Create final packages for all supported distros
3939
# Create deb packages
4040
@for arch in $(DEB_ARCHS); do \
4141
GOWORK=off CGO_ENABLED=0 GOARCH=$${arch} GOOS=linux go build -pgo=auto -ldflags=${LDFLAGS} -o $(BINARY_PATH) $(PROJECT_DIR)/$(PROJECT_FILE); \
@@ -111,7 +111,7 @@ package: $(PACKAGES_DIR) #### Create final packages for all supported distros
111111
find $(PACKAGES_DIR)/apk ;\
112112

113113
# Create tarball containing all packages
114-
cd $(PACKAGES_DIR) && tar -czvf "./$(TARBALL_NAME)" * && cd ../.. && cp "${PACKAGES_DIR}/$(TARBALL_NAME)"; \
114+
cd $(PACKAGES_DIR) && tar -czvf "./$(TARBALL_NAME)" * && cd ../..; \
115115

116116
.PHONY: gpg-key
117117
gpg-key: ## Generate GPG public key

internal/collector/otel_collector_plugin.go

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"fmt"
1111
"log/slog"
1212
"net/url"
13+
"net"
1314
"os"
1415
"strings"
1516
"sync"
@@ -47,11 +48,12 @@ const (
4748
type (
4849
// Collector The OTel collector plugin start an embedded OTel collector for metrics collection in the OTel format.
4950
Collector struct {
50-
service types.CollectorInterface
51-
cancel context.CancelFunc
52-
config *config.Config
53-
mu *sync.Mutex
54-
stopped bool
51+
service types.CollectorInterface
52+
config *config.Config
53+
mu *sync.Mutex
54+
cancel context.CancelFunc
55+
previousNAPSysLogServer string
56+
stopped bool
5557
}
5658
)
5759

@@ -87,10 +89,11 @@ func NewCollector(conf *config.Config) (*Collector, error) {
8789
}
8890

8991
return &Collector{
90-
config: conf,
91-
service: oTelCollector,
92-
stopped: true,
93-
mu: &sync.Mutex{},
92+
config: conf,
93+
service: oTelCollector,
94+
stopped: true,
95+
mu: &sync.Mutex{},
96+
previousNAPSysLogServer: "",
9497
}, nil
9598
}
9699

@@ -586,10 +589,12 @@ func (oc *Collector) updateNginxAppProtectTcplogReceivers(nginxConfigContext *mo
586589
oc.config.Collector.Receivers.TcplogReceivers = make(map[string]*config.TcplogReceiver)
587590
}
588591

589-
if nginxConfigContext.NAPSysLogServer != "" {
590-
if !oc.doesTcplogReceiverAlreadyExist(nginxConfigContext.NAPSysLogServer) {
592+
napSysLogServer := oc.findAvailableSyslogServers(nginxConfigContext.NAPSysLogServers)
593+
594+
if napSysLogServer != "" {
595+
if !oc.doesTcplogReceiverAlreadyExist(napSysLogServer) {
591596
oc.config.Collector.Receivers.TcplogReceivers["nginx_app_protect"] = &config.TcplogReceiver{
592-
ListenAddress: nginxConfigContext.NAPSysLogServer,
597+
ListenAddress: napSysLogServer,
593598
Operators: []config.Operator{
594599
// regex captures the priority number from the log line
595600
{
@@ -642,13 +647,13 @@ func (oc *Collector) updateNginxAppProtectTcplogReceivers(nginxConfigContext *mo
642647
}
643648
}
644649

645-
tcplogReceiverDeleted := oc.areNapReceiversDeleted(nginxConfigContext)
650+
tcplogReceiverDeleted := oc.areNapReceiversDeleted(napSysLogServer)
646651

647652
return newTcplogReceiverAdded || tcplogReceiverDeleted
648653
}
649654

650-
func (oc *Collector) areNapReceiversDeleted(nginxConfigContext *model.NginxConfigContext) bool {
651-
listenAddressesToBeDeleted := oc.configDeletedNapReceivers(nginxConfigContext)
655+
func (oc *Collector) areNapReceiversDeleted(napSysLogServer string) bool {
656+
listenAddressesToBeDeleted := oc.configDeletedNapReceivers(napSysLogServer)
652657
if len(listenAddressesToBeDeleted) != 0 {
653658
delete(oc.config.Collector.Receivers.TcplogReceivers, "nginx_app_protect")
654659
return true
@@ -657,17 +662,17 @@ func (oc *Collector) areNapReceiversDeleted(nginxConfigContext *model.NginxConfi
657662
return false
658663
}
659664

660-
func (oc *Collector) configDeletedNapReceivers(nginxConfigContext *model.NginxConfigContext) map[string]bool {
665+
func (oc *Collector) configDeletedNapReceivers(napSysLogServer string) map[string]bool {
661666
elements := make(map[string]bool)
662667

663668
for _, tcplogReceiver := range oc.config.Collector.Receivers.TcplogReceivers {
664669
elements[tcplogReceiver.ListenAddress] = true
665670
}
666671

667-
if nginxConfigContext.NAPSysLogServer != "" {
672+
if napSysLogServer != "" {
668673
addressesToDelete := make(map[string]bool)
669-
if !elements[nginxConfigContext.NAPSysLogServer] {
670-
addressesToDelete[nginxConfigContext.NAPSysLogServer] = true
674+
if !elements[napSysLogServer] {
675+
addressesToDelete[napSysLogServer] = true
671676
}
672677

673678
return addressesToDelete
@@ -711,6 +716,39 @@ func (oc *Collector) updateResourceAttributes(
711716
return actionUpdated
712717
}
713718

719+
func (oc *Collector) findAvailableSyslogServers(napSyslogServers []string) string {
720+
napSyslogServersMap := make(map[string]bool)
721+
for _, server := range napSyslogServers {
722+
napSyslogServersMap[server] = true
723+
}
724+
725+
if oc.previousNAPSysLogServer != "" {
726+
if _, ok := napSyslogServersMap[oc.previousNAPSysLogServer]; ok {
727+
return oc.previousNAPSysLogServer
728+
}
729+
}
730+
731+
for _, napSyslogServer := range napSyslogServers {
732+
ln, err := net.Listen("tcp", napSyslogServer)
733+
if err != nil {
734+
slog.Debug("NAP syslog server is not reachable", "address", napSyslogServer,
735+
"error", err)
736+
737+
continue
738+
}
739+
closeError := ln.Close()
740+
if closeError != nil {
741+
slog.Debug("Failed to close syslog server", "address", napSyslogServer, "error", closeError)
742+
}
743+
744+
slog.Debug("Found valid NAP syslog server", "address", napSyslogServer)
745+
746+
return napSyslogServer
747+
}
748+
749+
return ""
750+
}
751+
714752
func isOSSReceiverChanged(nginxReceiver config.NginxReceiver, nginxConfigContext *model.NginxConfigContext) bool {
715753
return nginxReceiver.StubStatus.URL != nginxConfigContext.StubStatus.URL ||
716754
len(nginxReceiver.AccessLogs) != len(nginxConfigContext.AccessLogs)

internal/collector/otel_collector_plugin_test.go

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"errors"
1111
"net/url"
1212
"os"
13+
"net"
1314
"path/filepath"
1415
"testing"
1516

@@ -740,7 +741,7 @@ func TestCollector_updateNginxAppProtectTcplogReceivers(t *testing.T) {
740741
require.NoError(t, err)
741742

742743
nginxConfigContext := &model.NginxConfigContext{
743-
NAPSysLogServer: "localhost:151",
744+
NAPSysLogServers: []string{"localhost:15632"},
744745
}
745746

746747
assert.Empty(t, conf.Collector.Receivers.TcplogReceivers)
@@ -750,7 +751,7 @@ func TestCollector_updateNginxAppProtectTcplogReceivers(t *testing.T) {
750751

751752
assert.True(tt, tcplogReceiverAdded)
752753
assert.Len(tt, conf.Collector.Receivers.TcplogReceivers, 1)
753-
assert.Equal(tt, "localhost:151", conf.Collector.Receivers.TcplogReceivers["nginx_app_protect"].ListenAddress)
754+
assert.Equal(tt, "localhost:15632", conf.Collector.Receivers.TcplogReceivers["nginx_app_protect"].ListenAddress)
754755
assert.Len(tt, conf.Collector.Receivers.TcplogReceivers["nginx_app_protect"].Operators, 6)
755756
})
756757

@@ -760,7 +761,7 @@ func TestCollector_updateNginxAppProtectTcplogReceivers(t *testing.T) {
760761
tcplogReceiverAdded := collector.updateNginxAppProtectTcplogReceivers(nginxConfigContext)
761762
assert.False(t, tcplogReceiverAdded)
762763
assert.Len(t, conf.Collector.Receivers.TcplogReceivers, 1)
763-
assert.Equal(t, "localhost:151", conf.Collector.Receivers.TcplogReceivers["nginx_app_protect"].ListenAddress)
764+
assert.Equal(t, "localhost:15632", conf.Collector.Receivers.TcplogReceivers["nginx_app_protect"].ListenAddress)
764765
assert.Len(t, conf.Collector.Receivers.TcplogReceivers["nginx_app_protect"].Operators, 6)
765766
})
766767

@@ -773,13 +774,13 @@ func TestCollector_updateNginxAppProtectTcplogReceivers(t *testing.T) {
773774
t.Run("Test 4: NewCollector tcplogReceiver added and deleted another", func(tt *testing.T) {
774775
tcplogReceiverDeleted := collector.updateNginxAppProtectTcplogReceivers(
775776
&model.NginxConfigContext{
776-
NAPSysLogServer: "localhost:152",
777+
NAPSysLogServers: []string{"localhost:1555"},
777778
},
778779
)
779780

780781
assert.True(t, tcplogReceiverDeleted)
781782
assert.Len(t, conf.Collector.Receivers.TcplogReceivers, 1)
782-
assert.Equal(t, "localhost:152", conf.Collector.Receivers.TcplogReceivers["nginx_app_protect"].ListenAddress)
783+
assert.Equal(t, "localhost:1555", conf.Collector.Receivers.TcplogReceivers["nginx_app_protect"].ListenAddress)
783784
assert.Len(t, conf.Collector.Receivers.TcplogReceivers["nginx_app_protect"].Operators, 6)
784785
})
785786
}
@@ -903,6 +904,74 @@ func TestSetExporterProxyEnvVars(t *testing.T) {
903904
os.Unsetenv("HTTP_PROXY")
904905
os.Unsetenv("HTTPS_PROXY")
905906
}
907+
}
908+
}
909+
}
910+
911+
func TestCollector_findAvailableSyslogServers(t *testing.T) {
912+
conf := types.OTelConfig(t)
913+
conf.Collector.Log.Path = ""
914+
conf.Collector.Processors.Batch = nil
915+
conf.Collector.Processors.Attribute = nil
916+
conf.Collector.Processors.Resource = nil
917+
conf.Collector.Processors.LogsGzip = nil
918+
collector, err := NewCollector(conf)
919+
require.NoError(t, err)
920+
921+
tests := []struct {
922+
name string
923+
expectedSyslogServer string
924+
previousNAPSysLogServer string
925+
syslogServers []string
926+
portInUse bool
927+
}{
928+
{
929+
name: "Test 1: port available",
930+
expectedSyslogServer: "localhost:15632",
931+
previousNAPSysLogServer: "",
932+
syslogServers: []string{"localhost:15632"},
933+
portInUse: false,
934+
},
935+
{
936+
name: "Test 2: port in use",
937+
expectedSyslogServer: "",
938+
previousNAPSysLogServer: "",
939+
syslogServers: []string{"localhost:15632"},
940+
portInUse: true,
941+
},
942+
{
943+
name: "Test 3: syslog server already configured",
944+
expectedSyslogServer: "localhost:15632",
945+
previousNAPSysLogServer: "localhost:15632",
946+
syslogServers: []string{"localhost:15632"},
947+
portInUse: false,
948+
},
949+
{
950+
name: "Test 4: new syslog server",
951+
expectedSyslogServer: "localhost:15632",
952+
previousNAPSysLogServer: "localhost:1122",
953+
syslogServers: []string{"localhost:15632"},
954+
portInUse: false,
955+
},
956+
{
957+
name: "Test 5: port in use find next server",
958+
expectedSyslogServer: "localhost:1122",
959+
previousNAPSysLogServer: "",
960+
syslogServers: []string{"localhost:15632", "localhost:1122"},
961+
portInUse: true,
962+
},
963+
}
964+
965+
for _, test := range tests {
966+
t.Run(test.name, func(tt *testing.T) {
967+
if test.portInUse {
968+
ln, listenError := net.Listen("tcp", "localhost:15632")
969+
require.NoError(t, listenError)
970+
defer ln.Close()
971+
}
972+
973+
actual := collector.findAvailableSyslogServers(test.syslogServers)
974+
assert.Equal(tt, test.expectedSyslogServer, actual)
906975
})
907976
}
908977
}

internal/config/config.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,14 @@ func normalizeFunc(f *flag.FlagSet, name string) flag.NormalizedName {
848848
}
849849

850850
func resolveLog() *Log {
851+
logLevel := strings.ToLower(viperInstance.GetString(LogLevelKey))
852+
validLevels := []string{"debug", "info", "warn", "error"}
853+
854+
if !slices.Contains(validLevels, logLevel) {
855+
slog.Warn("Invalid log level set, defaulting to 'info'", "log_level", logLevel)
856+
viperInstance.Set(LogLevelKey, "info")
857+
}
858+
851859
return &Log{
852860
Level: viperInstance.GetString(LogLevelKey),
853861
Path: viperInstance.GetString(LogPathKey),
@@ -1227,6 +1235,10 @@ func isHealthExtensionSet() bool {
12271235
}
12281236

12291237
func resolveCollectorLog() *Log {
1238+
if !viperInstance.IsSet(CollectorLogLevelKey) {
1239+
viperInstance.Set(CollectorLogLevelKey, strings.ToUpper(viperInstance.GetString(LogLevelKey)))
1240+
}
1241+
12301242
return &Log{
12311243
Level: viperInstance.GetString(CollectorLogLevelKey),
12321244
Path: viperInstance.GetString(CollectorLogPathKey),

0 commit comments

Comments
 (0)