Skip to content

Commit f44d561

Browse files
Latest updates
- certs: restore cert checking metrics - datapower: opentelemetry collector stats - manager: fix bugs with org metrics - consumption: ibm-cloud consumption metrics - improve error handling - move to ubi9 for builds Signed-off-by: Ricky Moorhouse <[email protected]>
1 parent 771ee33 commit f44d561

File tree

19 files changed

+827
-275
lines changed

19 files changed

+827
-275
lines changed

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
cover.out
2+
exporter
3+
*/coverage.html
14
coverage.xml
25
.coverage
36
.pytest_cache/
47
__pycache__/
58
local/
69
*.pyc
7-
secrets/
10+
secrets/
11+
.vscode/settings.json
12+
config.yaml

.pre-commit-config.yaml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
# See https://pre-commit.com for more information
22
# See https://pre-commit.com/hooks.html for more hooks
33
repos:
4-
- repo: https://gitlab.com/pycqa/flake8
5-
rev: 'master' # Use the sha / tag you want to point at
4+
- repo: https://github.com/ibm/detect-secrets
5+
rev: 0.13.1+ibm.61.dss
66
hooks:
7-
- id: flake8
8-
args: []
7+
- id: detect-secrets
8+
args: [--baseline, .secrets.baseline, --use-all-plugins]
9+
- repo: https://github.com/dnephin/pre-commit-golang
10+
rev: v0.5.1
11+
hooks:
12+
- id: go-fmt
13+
- id: validate-toml
14+
- id: no-go-testing
15+
- id: go-unit-tests
16+
- id: go-build
17+
- id: go-mod-tidy
18+

Dockerfile

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,32 @@
1-
FROM registry.access.redhat.com/ubi9/ubi-minimal AS build
2-
RUN microdnf update -y --refresh --best --nodocs --noplugins --setopt=install_weak_deps=0 && \
3-
microdnf install -y --refresh --best --nodocs --noplugins --setopt=install_weak_deps=0 zip unzip make git gcc && \
4-
microdnf install -y --refresh --best --nodocs --noplugins --setopt=install_weak_deps=0 go-toolset ca-certificates && \
5-
microdnf clean all && \
6-
rm -rf /var/cache/yum
1+
FROM registry.access.redhat.com/ubi9/ubi:latest AS build
2+
73
WORKDIR /app/
84

9-
ENV GOPATH /tmp/go
10-
ENV PATH $PATH:$GOPATH/bin
5+
RUN dnf upgrade --assumeyes
6+
RUN dnf install -y curl jq tar --allowerasing
7+
8+
# Set the Go version dynamically by fetching the latest version
9+
RUN GOVERSION=$(curl -s 'https://go.dev/dl/?mode=json' | jq -r '.[0].version' | sed 's/^go//') && \
10+
echo "Installing Go version: $GOVERSION" && \
11+
curl -sSL "https://golang.org/dl/go$GOVERSION.linux-amd64.tar.gz" | tar -C /usr/local -xzf - && \
12+
ln -s /usr/local/go/bin/go /usr/bin/go
1113

1214
COPY . .
1315
RUN go mod download
1416

1517
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./out/trawler .
18+
RUN dnf install ca-certificates --assumeyes
19+
RUN groupadd -r app && useradd -r -g app app
1620

17-
FROM registry.access.redhat.com/ubi9/ubi-minimal
18-
19-
ARG USER_UID
20-
ARG USER_NAME
21-
22-
ENV USER_UID ${USER_UID:-1001}
23-
ENV USER_NAME ${USER_NAME:-apic}
24-
RUN mkdir -p ${HOME} && chown ${USER_UID}:0 ${HOME} && chmod ug+rwx ${HOME}
21+
FROM scratch
2522

2623
COPY --from=build /app/out/trawler /app/trawler
2724
COPY base-config.yaml /app/config/config.yaml
25+
COPY --from=build /etc/pki/tls/certs/ca-bundle.crt /etc/ssl/certs/ca-certificates.crt
26+
COPY --from=build /etc/passwd /etc/passwd
2827

29-
USER root
30-
RUN microdnf upgrade -y --refresh --best --nodocs --noplugins --setopt=install_weak_deps=0 \
31-
&& microdnf clean all
32-
USER 1001:0
28+
USER app
3329

3430
EXPOSE 63512
35-
ENV CONFIG_PATH=/app/config/config.yaml
3631

37-
CMD ["/app/trawler"]
32+
CMD ["/app/trawler", "-c", "/app/config/config.yaml"]

README.md

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -67,36 +67,75 @@ Feature requests and issue reports are welcome as [github issues](https://github
6767

6868
## Development tips
6969

70-
### Setting up your development environment
70+
## Running locally for development
71+
72+
### Secret set up
73+
74+
secrets/
75+
datapower/ <-- datapower login credentials (DP_CREDS)
76+
password
77+
management/ <-- client credentials for accessing APIC platform api (MGMT_CREDS)
78+
client_id
79+
client_secret
80+
analytics/ <-- client certificate to connect to analytics (ANALYTICS_CERTS)
81+
ca.crt
82+
tls.crt
83+
tls.key
84+
cert/ <-- server certificates for trawler (CERT_PATH if using SECURE)
85+
ca.crt
86+
tls.crt
87+
tls.key
88+
89+
Then ensure the following environment variables are set:
7190

72-
Install the pre-reqs for trawler from requirements.txt and development and testing requirements from requirements-dev.txt
91+
```
92+
export MGMT_CREDS=secrets/management
93+
export DP_CREDS=secrets/datapower
94+
export ANALYTICS_CERTS=secrets/analytics
95+
# if testing using https and mtls
96+
export SECURE=true
97+
export CERT_PATH=secrets/cert
98+
```
99+
100+
101+
### DataPower
102+
103+
- Log into your cluster.
104+
- Ensure you have the password available in the secrets directory and the username set in your config
105+
106+
```
107+
kubectl get secret gateway-admin-secret -o yaml | grep " password" | awk '{print $2}' | base64 -d > secrets/datapower/password
108+
```
73109
74-
pip install -r requirements.txt
75-
pip install -r requirements-dev.txt
110+
- Open port-forward to both ports 5554 (for REST Management) and 9443 (for API Invoke)
111+
112+
```
113+
kubectl port-forward $(kubectl get pods -l app.kubernetes.io/name=datapower -o name | head -1) 9443 5554
114+
```
76115
77-
Initialise the pre-commit checks for Trawler using [pre-commit](https://pre-commit.com/)
116+
By default trawler will look for all the gateway pods in the cluster by label - this can also be restricted by namespace through the config. Typically running in the cluster, trawler will communicate directly with each pod to retrieve metrics. For local testing or running outside of the cluster you may wish to override the host it uses to retrieve metrics in the config (nets.datapower.host) - this will then be used instead of each pods individual IP address - getting metrics from a single place but reporting as if it spoke to each in turn.
78117
79-
pre-commit install
80118
81-
### Running test cases locally
82119
83-
Trawler uses py.test for test cases and the test suite is intended to be run with the test-assets directory as the secrets path.
84120
85-
SECRETS=test-assets coverage run --source . -m py.test
86121
87122
88-
### Running locally
89123
90-
To run locally point the config parameter to a local config file
124+
### Analytics
91125
92-
python3 trawler.py --config local/config.yaml
126+
- Log into your cluster.
127+
- Ensure you have the certificates available in the secrets directory
93128
94-
You can view the data that is being exposed to prometheus at [localhost:63512](http://localhost:63512) (or the custom port value if it's been changed)
129+
```
130+
kubectl get secret analytics-client -o yaml > /tmp/analytics-client
131+
cat /tmp/analytics-client | grep " tls.crt" | awk '{print $2}' | base64 -d > secrets/analytics/tls.crt
132+
cat /tmp/analytics-client | grep " tls.key" | awk '{print $2}' | base64 -d > secrets/analytics/tls.key
133+
```
95134
135+
- Open port-forward to port 3009 on one of the analytics director pods
96136
137+
```
138+
kubectl port-forward $(kubectl get deployment -l app.kubernetes.io/name=director -o name) 3009
139+
```
97140
98-
Notes on developing with a running k8s pod:
99141
100-
kubectl cp datapower_trawl.py {trawler_pod}:/app/datapower_trawl.py
101-
kubectl cp newconfig.yaml {trawler_pod}:/app/newconfig.yaml
102-
kubectl exec {trawler_pod} -- sh -c 'cd /app;python3 trawler.py -c newconfig.yaml'

exporter.go

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ import (
88
"nets"
99
"nets/analytics"
1010
"nets/apiconnect"
11+
"nets/certs"
1112
"nets/consumption"
1213
"nets/datapower"
1314
"nets/manager"
1415
"os"
16+
"path/filepath"
1517
"time"
1618

1719
"github.com/IBM/alchemy-logging/src/go/alog"
@@ -41,6 +43,7 @@ type Config struct {
4143
APIConnect apiconnect.APIConnectNetConfig `yaml:"apiconnect"`
4244
Analytics analytics.AnalyticsNetConfig `yaml:"analytics"`
4345
Consumption consumption.ConsumptionNetConfig `yaml:"consumption"`
46+
Certs certs.CertsNetConfig `yaml:"certificates"`
4447
DataPower datapower.DataPowerNetConfig `yaml:"datapower"`
4548
Manager manager.ManagerNetConfig `yaml:"manager"`
4649
} `yaml:"nets"`
@@ -64,7 +67,7 @@ func ReadConfig() Config {
6467
log.Log(alog.INFO, "Loading config from %s ", config_path)
6568

6669
// Open YAML file
67-
file, err := os.Open(config_path)
70+
file, err := os.Open(filepath.Clean(config_path))
6871
if err != nil {
6972
log.Log(alog.ERROR, err.Error())
7073
}
@@ -105,10 +108,12 @@ func main() {
105108
// Set up logging
106109

107110
alog.Config(alog.INFO, alog.ChannelMap{
108-
"trawler": alog.DEBUG,
111+
"trawler": alog.INFO,
109112
"apim": alog.INFO,
113+
"nets": alog.INFO,
110114
"apic": alog.INFO,
111115
"a7s": alog.INFO,
116+
"cert": alog.DEBUG,
112117
"dp": alog.INFO,
113118
})
114119
// Read config file...
@@ -131,7 +136,6 @@ func main() {
131136
log.Log(alog.INFO, "Enabled analytics net with %s frequency", a7s.Frequency)
132137
go a7s.BackgroundFishing()
133138
}
134-
135139
// Consumption health net
136140
if config.Nets.Consumption.Enabled {
137141
c := consumption.Consumption{}
@@ -141,6 +145,15 @@ func main() {
141145
c.Fish()
142146
go c.BackgroundFishing()
143147
}
148+
// Certs net
149+
if config.Nets.Certs.Enabled {
150+
cert_net := certs.Certs{}
151+
cert_net.Config = config.Nets.Certs
152+
cert_net.Frequency = frequency(config.Nets.Consumption.Frequency)
153+
log.Log(alog.INFO, "Enabled certificate net with %s frequency", cert_net.Frequency)
154+
cert_net.Fish()
155+
go cert_net.BackgroundFishing()
156+
}
144157
// Manager net
145158
if config.Nets.Manager.Enabled {
146159
apim := manager.Manager{}
@@ -178,12 +191,12 @@ func main() {
178191
}
179192

180193
func ListenAndServe(mux *http.ServeMux, listenPort string) (*http.Server, error) {
181-
srv := &http.Server{}
194+
srv := &http.Server{
195+
Addr: ":" + listenPort,
196+
Handler: mux,
197+
ReadHeaderTimeout: 5 * time.Second, // for gosec G112 (CWE-400)
198+
}
182199
if os.Getenv("SECURE") != "true" {
183-
srv := &http.Server{
184-
Addr: ":" + listenPort,
185-
Handler: mux,
186-
}
187200
log.Log(alog.INFO, "Listening insecurely on http://0.0.0.0:%s/metrics", listenPort)
188201
err := srv.ListenAndServe()
189202
if err != nil {
@@ -193,10 +206,6 @@ func ListenAndServe(mux *http.ServeMux, listenPort string) (*http.Server, error)
193206

194207
} else {
195208

196-
srv := &http.Server{
197-
Addr: ":" + listenPort,
198-
Handler: mux,
199-
}
200209
certPath := os.Getenv("CERT_PATH")
201210
certReloader := CertReloader{
202211
CertFile: certPath + "/tls.crt",
@@ -206,7 +215,7 @@ func ListenAndServe(mux *http.ServeMux, listenPort string) (*http.Server, error)
206215
caFile := certPath + "/ca.crt"
207216

208217
var certPool *x509.CertPool = x509.NewCertPool()
209-
caBytes, err := os.ReadFile(caFile)
218+
caBytes, err := os.ReadFile(filepath.Clean(caFile))
210219
if err != nil {
211220
log.Log(alog.FATAL, "failed loading caFile: %v", err)
212221
return nil, err

go.mod

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module rickymoorhouse/exporter
22

3-
go 1.21
3+
go 1.23.0
4+
5+
toolchain go1.23.5
46

57
require (
68
github.com/IBM/alchemy-logging/src/go v1.0.3
@@ -12,12 +14,13 @@ require (
1214
github.com/beorn7/perks v1.0.1 // indirect
1315
github.com/cespare/xxhash/v2 v2.2.0 // indirect
1416
github.com/golang/protobuf v1.5.3 // indirect
17+
github.com/google/go-cmp v0.6.0 // indirect
1518
github.com/kr/text v0.2.0 // indirect
1619
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
1720
github.com/prometheus/client_model v0.4.0 // indirect
1821
github.com/prometheus/common v0.43.0 // indirect
1922
github.com/prometheus/procfs v0.9.0 // indirect
2023
github.com/stretchr/testify v1.8.1 // indirect
21-
golang.org/x/sys v0.8.0 // indirect
24+
golang.org/x/sys v0.32.0 // indirect
2225
google.golang.org/protobuf v1.30.0 // indirect
2326
)

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
1313
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
1414
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
1515
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
16-
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
17-
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
16+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
17+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1818
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
1919
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
2020
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -42,8 +42,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
4242
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
4343
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
4444
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
45-
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
46-
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
45+
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
46+
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
4747
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
4848
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
4949
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=

go.work

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
go 1.21
1+
go 1.23.0
2+
3+
toolchain go1.23.5
24

35
use (
46
.

0 commit comments

Comments
 (0)