Skip to content

Commit 6ae6338

Browse files
v2: check in golang version
Signed-off-by: Ricky Moorhouse <[email protected]>
1 parent d4240ba commit 6ae6338

File tree

19 files changed

+2532
-0
lines changed

19 files changed

+2532
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ coverage.xml
44
__pycache__/
55
local/
66
*.pyc
7+
secrets/

exporter.go

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
package main
2+
3+
import (
4+
"crypto/tls"
5+
"crypto/x509"
6+
"fmt"
7+
"net/http"
8+
"nets"
9+
"nets/analytics"
10+
"nets/apiconnect"
11+
"nets/consumption"
12+
"nets/datapower"
13+
"nets/manager"
14+
"os"
15+
"time"
16+
17+
"github.com/IBM/alchemy-logging/src/go/alog"
18+
"github.com/prometheus/client_golang/prometheus"
19+
"github.com/prometheus/client_golang/prometheus/promauto"
20+
"github.com/prometheus/client_golang/prometheus/promhttp"
21+
"gopkg.in/yaml.v3"
22+
)
23+
24+
var (
25+
promCounter = promauto.NewCounterVec(
26+
prometheus.CounterOpts{
27+
Name: "myapp_processed_ops_total",
28+
Help: "The total number of processed events",
29+
},
30+
[]string{"collector"})
31+
)
32+
33+
var log = alog.UseChannel("trawler")
34+
35+
type Config struct {
36+
Prometheus struct {
37+
Port string `yaml:"port"`
38+
Enabled bool `yaml:"enabled"`
39+
} `yaml:"prometheus"`
40+
Nets struct {
41+
APIConnect apiconnect.APIConnectNetConfig `yaml:"apiconnect"`
42+
Analytics analytics.AnalyticsNetConfig `yaml:"analytics"`
43+
Consumption consumption.ConsumptionNetConfig `yaml:"consumption"`
44+
DataPower datapower.DataPowerNetConfig `yaml:"datapower"`
45+
Manager manager.ManagerNetConfig `yaml:"manager"`
46+
} `yaml:"nets"`
47+
}
48+
49+
type CertReloader struct {
50+
CertFile string // path to the x509 certificate for https
51+
KeyFile string // path to the x509 private key matching `CertFile`
52+
cachedCert *tls.Certificate
53+
cachedCertModTime time.Time
54+
}
55+
56+
func ReadConfig() Config {
57+
var config Config
58+
59+
config_path := os.Getenv("CONFIG_PATH")
60+
if config_path == "" {
61+
config_path = "config.yaml"
62+
}
63+
64+
log.Log(alog.INFO, "Loading config from %s ", config_path)
65+
66+
// Open YAML file
67+
file, err := os.Open(config_path)
68+
if err != nil {
69+
log.Log(alog.ERROR, err.Error())
70+
}
71+
defer file.Close()
72+
73+
// Decode YAML file to struct
74+
if file != nil {
75+
decoder := yaml.NewDecoder(file)
76+
if err := decoder.Decode(&config); err != nil {
77+
log.Log(alog.ERROR, err.Error())
78+
79+
}
80+
}
81+
82+
return config
83+
}
84+
85+
func enableNet(frequency int, newNet nets.BaseNet) {
86+
net_frequency := time.Duration(5)
87+
if frequency != 0 {
88+
log.Log(alog.INFO, "net is enabled at %ds frequency", frequency)
89+
net_frequency = time.Duration(frequency)
90+
}
91+
newNet.Frequency = net_frequency * time.Second
92+
//newNet.BackgroundFishing()
93+
}
94+
95+
func frequency(configFrequency int) time.Duration {
96+
if configFrequency == 0 {
97+
// Default is 10 seconds
98+
return time.Duration(10) * time.Second
99+
} else {
100+
return time.Duration(configFrequency) * time.Second
101+
}
102+
}
103+
104+
func main() {
105+
// Set up logging
106+
107+
alog.Config(alog.INFO, alog.ChannelMap{
108+
"trawler": alog.DEBUG,
109+
"apim": alog.INFO,
110+
"apic": alog.INFO,
111+
"a7s": alog.INFO,
112+
"dp": alog.INFO,
113+
})
114+
// Read config file...
115+
config := ReadConfig()
116+
117+
// Initialise appropriate nets...
118+
if config.Nets.APIConnect.Enabled {
119+
a := apiconnect.APIConnect{}
120+
a.Config = config.Nets.APIConnect
121+
a.Frequency = frequency(config.Nets.APIConnect.Frequency)
122+
log.Log(alog.INFO, "Enabled apiconnect net with %s frequency", a.Frequency)
123+
go a.BackgroundFishing()
124+
}
125+
126+
// Analytics net
127+
if config.Nets.Analytics.Enabled {
128+
a7s := analytics.Analytics{}
129+
a7s.Config = config.Nets.Analytics
130+
a7s.Frequency = frequency(config.Nets.Analytics.Frequency)
131+
log.Log(alog.INFO, "Enabled analytics net with %s frequency", a7s.Frequency)
132+
go a7s.BackgroundFishing()
133+
}
134+
135+
// Consumption health net
136+
if config.Nets.Consumption.Enabled {
137+
c := consumption.Consumption{}
138+
c.Config = config.Nets.Consumption
139+
c.Frequency = frequency(config.Nets.Consumption.Frequency)
140+
log.Log(alog.INFO, "Enabled consumption net with %s frequency", c.Frequency)
141+
c.Fish()
142+
go c.BackgroundFishing()
143+
}
144+
// Manager net
145+
if config.Nets.Manager.Enabled {
146+
apim := manager.Manager{}
147+
apim.Config = config.Nets.Manager
148+
apim.Frequency = frequency(config.Nets.Manager.Frequency)
149+
log.Log(alog.INFO, "Enabled management net with %s frequency", apim.Frequency)
150+
go apim.BackgroundFishing()
151+
}
152+
153+
// DataPower net (TODO implement)
154+
if config.Nets.DataPower.Enabled {
155+
dp := datapower.DataPower{}
156+
dp.Config = config.Nets.DataPower
157+
dp.Frequency = frequency(config.Nets.DataPower.Frequency)
158+
log.Log(alog.INFO, "Enabled datapower net with %s frequency", dp.Frequency)
159+
go dp.BackgroundFishing()
160+
}
161+
162+
mux := http.NewServeMux()
163+
mux.Handle("/metrics", promhttp.Handler())
164+
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
165+
fmt.Fprint(w, "ok")
166+
})
167+
168+
listenPort := "63512"
169+
if config.Prometheus.Port != "" {
170+
listenPort = config.Prometheus.Port
171+
}
172+
173+
_, err := ListenAndServe(mux, listenPort)
174+
if err != nil {
175+
log.Log(alog.ERROR, "Server Failed to Listen")
176+
}
177+
178+
}
179+
180+
func ListenAndServe(mux *http.ServeMux, listenPort string) (*http.Server, error) {
181+
srv := &http.Server{}
182+
if os.Getenv("SECURE") != "true" {
183+
srv := &http.Server{
184+
Addr: ":" + listenPort,
185+
Handler: mux,
186+
}
187+
log.Log(alog.INFO, "Listening insecurely on http://0.0.0.0:%s/metrics", listenPort)
188+
err := srv.ListenAndServe()
189+
if err != nil {
190+
log.Log(alog.FATAL, "failed to run insecure server: %s\n", err)
191+
return nil, err
192+
}
193+
194+
} else {
195+
196+
srv := &http.Server{
197+
Addr: ":" + listenPort,
198+
Handler: mux,
199+
}
200+
certPath := os.Getenv("CERT_PATH")
201+
certReloader := CertReloader{
202+
CertFile: certPath + "/tls.crt",
203+
KeyFile: certPath + "/tls.key",
204+
}
205+
206+
caFile := certPath + "/ca.crt"
207+
208+
var certPool *x509.CertPool = x509.NewCertPool()
209+
caBytes, err := os.ReadFile(caFile)
210+
if err != nil {
211+
log.Log(alog.FATAL, "failed loading caFile: %v", err)
212+
return nil, err
213+
}
214+
ok := certPool.AppendCertsFromPEM(caBytes)
215+
if !ok {
216+
log.Log(alog.FATAL, "could not parse certificate file: %v", caFile)
217+
return nil, err
218+
}
219+
220+
tlsConfig := tls.Config{
221+
MinVersion: tls.VersionTLS12,
222+
GetCertificate: certReloader.GetCertificate,
223+
ClientAuth: tls.RequireAndVerifyClientCert, // pragma: allowlist secret
224+
ClientCAs: certPool,
225+
RootCAs: certPool,
226+
}
227+
srv.TLSConfig = &tlsConfig
228+
log.Log(alog.INFO, "Listening securely on https://0.0.0.0:%s/metrics", listenPort)
229+
err = srv.ListenAndServeTLS(certReloader.CertFile, certReloader.KeyFile)
230+
if err != nil {
231+
log.Log(alog.FATAL, "failed to run secure server: %s\n", err)
232+
return nil, err
233+
}
234+
}
235+
return srv, nil
236+
}
237+
238+
// Implementation for tls.Config.GetCertificate useful when using
239+
// Kubernetes Secrets which update the filesystem at runtime.
240+
func (cr *CertReloader) GetCertificate(h *tls.ClientHelloInfo) (*tls.Certificate, error) {
241+
stat, err := os.Stat(cr.KeyFile)
242+
if err != nil {
243+
return nil, fmt.Errorf("failed checking key file modification time: %w", err)
244+
}
245+
246+
if cr.cachedCert == nil || stat.ModTime().After(cr.cachedCertModTime) {
247+
log.Log(alog.INFO, "Re-loading certs from file as updated since cached time: %v", cr.cachedCertModTime)
248+
pair, err := tls.LoadX509KeyPair(cr.CertFile, cr.KeyFile)
249+
if err != nil {
250+
return nil, fmt.Errorf("failed loading tls key pair: %w", err)
251+
}
252+
253+
cr.cachedCert = &pair
254+
cr.cachedCertModTime = stat.ModTime()
255+
}
256+
257+
return cr.cachedCert, nil
258+
}

go.mod

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module rickymoorhouse/exporter
2+
3+
go 1.21
4+
5+
require (
6+
github.com/IBM/alchemy-logging/src/go v1.0.3
7+
github.com/prometheus/client_golang v1.15.1
8+
gopkg.in/yaml.v3 v3.0.1
9+
)
10+
11+
require (
12+
github.com/beorn7/perks v1.0.1 // indirect
13+
github.com/cespare/xxhash/v2 v2.2.0 // indirect
14+
github.com/golang/protobuf v1.5.3 // indirect
15+
github.com/kr/text v0.2.0 // indirect
16+
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
17+
github.com/prometheus/client_model v0.4.0 // indirect
18+
github.com/prometheus/common v0.43.0 // indirect
19+
github.com/prometheus/procfs v0.9.0 // indirect
20+
github.com/stretchr/testify v1.8.1 // indirect
21+
golang.org/x/sys v0.8.0 // indirect
22+
google.golang.org/protobuf v1.30.0 // indirect
23+
)

go.sum

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
github.com/IBM/alchemy-logging/src/go v1.0.3 h1:2QQ/I5cIoDfGooTEJzdzKZmWntHPIwNFIoo9ipFx0v4=
2+
github.com/IBM/alchemy-logging/src/go v1.0.3/go.mod h1:da1DJ0y3nkz/zKSyXGHkU8DC9lafh2S18W+KOvbqiFA=
3+
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
4+
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
5+
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
6+
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
7+
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
8+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
10+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11+
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
12+
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
13+
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
14+
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
15+
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=
18+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
19+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
20+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
21+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
22+
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
23+
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
24+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
25+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
26+
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
27+
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
28+
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
29+
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
30+
github.com/prometheus/common v0.43.0 h1:iq+BVjvYLei5f27wiuNiB1DN6DYQkp1c8Bx0Vykh5us=
31+
github.com/prometheus/common v0.43.0/go.mod h1:NCvr5cQIh3Y/gy73/RdVtC9r8xxrxwJnB+2lB3BxrFc=
32+
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
33+
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
34+
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
35+
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
36+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
37+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
38+
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
39+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
40+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
41+
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
42+
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
43+
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
44+
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=
47+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
48+
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
49+
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
50+
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
51+
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
52+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
53+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
54+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
55+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
56+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
57+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

go.work

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
go 1.21
2+
3+
use (
4+
.
5+
./nets
6+
)

0 commit comments

Comments
 (0)