Skip to content

Commit 0805745

Browse files
authored
fix: add missing services (#3235)
1 parent 876cd2b commit 0805745

File tree

11 files changed

+655
-28
lines changed

11 files changed

+655
-28
lines changed

.github/workflows/ci.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,14 @@ jobs:
408408
image: $DEPOT_IMAGE_URL
409409
sink-worker:
410410
image: $DEPOT_IMAGE_URL
411+
balance-worker:
412+
image: $DEPOT_IMAGE_URL
413+
notification-service:
414+
image: $DEPOT_IMAGE_URL
415+
billing-worker:
416+
image: $DEPOT_IMAGE_URL
417+
openmeter-jobs:
418+
image: $DEPOT_IMAGE_URL
411419
EOF
412420
413421
cat quickstart/docker-compose.override.yaml

.vscode/launch.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,19 @@
8484
"--billing-advancement-strategy=foreground",
8585
]
8686
},
87+
{
88+
"name": "Launch periodic jobs",
89+
"type": "go",
90+
"request": "launch",
91+
"mode": "auto",
92+
"program": "${workspaceFolder}/cmd/jobs",
93+
"args": [
94+
"--config",
95+
"${workspaceFolder}/config.yaml",
96+
"billing",
97+
"subscriptionsync",
98+
"list"
99+
]
100+
},
87101
]
88102
}

cmd/jobs/main.go

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

33
import (
44
"context"
5+
"errors"
56
"log/slog"
67
"os"
78
"os/signal"
@@ -13,49 +14,57 @@ import (
1314
"github.com/openmeterio/openmeter/cmd/jobs/billing"
1415
"github.com/openmeterio/openmeter/cmd/jobs/entitlement"
1516
"github.com/openmeterio/openmeter/cmd/jobs/internal"
17+
"github.com/openmeterio/openmeter/cmd/jobs/quickstart"
1618
"github.com/openmeterio/openmeter/pkg/log"
1719
)
1820

19-
var configFileName string
20-
21-
var rootCmd = cobra.Command{
22-
Use: "jobs",
23-
SilenceUsage: true,
24-
SilenceErrors: true,
25-
}
26-
2721
func main() {
22+
var configFileName string
23+
2824
defer log.PanicLogger(log.WithExit)
2925

3026
// Create os.Signal aware context.Context which will trigger context cancellation
3127
// upon receiving any of the listed signals.
3228
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGHUP, syscall.SIGTERM)
3329
defer cancel()
3430

35-
err := internal.InitializeApplication(ctx, configFileName)
36-
if err != nil {
37-
slog.Error("failed to initialize application", "error", err)
31+
rootCmd := cobra.Command{
32+
Use: "jobs",
33+
SilenceUsage: true,
34+
SilenceErrors: true,
35+
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
36+
err := internal.InitializeApplication(ctx, configFileName)
37+
if err != nil {
38+
slog.Error("failed to initialize application", "error", err)
3839

39-
// Call cleanup function is may not set yet
40-
if internal.AppShutdown != nil {
41-
internal.AppShutdown()
42-
}
40+
// Call cleanup function is may not set yet
41+
if internal.AppShutdown != nil {
42+
internal.AppShutdown()
43+
}
4344

44-
os.Exit(1)
45-
}
46-
defer internal.AppShutdown()
45+
return errors.New("failed to initialize application")
46+
}
4747

48-
if err = rootCmd.ExecuteContext(ctx); err != nil {
49-
slog.Error("failed to execute command", "error", err)
50-
os.Exit(1)
48+
return nil
49+
},
5150
}
52-
}
5351

54-
func init() {
5552
rootCmd.PersistentFlags().StringVarP(&configFileName, "config", "", "config.yaml", "config file (default is config.yaml)")
5653
_ = viper.BindPFlag("config", rootCmd.PersistentFlags().Lookup("config"))
5754

5855
rootCmd.AddCommand(versionCommand())
5956
rootCmd.AddCommand(entitlement.RootCommand())
6057
rootCmd.AddCommand(billing.Cmd)
58+
rootCmd.AddCommand(quickstart.Cmd)
59+
60+
defer func() {
61+
if internal.AppShutdown != nil {
62+
internal.AppShutdown()
63+
}
64+
}()
65+
66+
if err := rootCmd.ExecuteContext(ctx); err != nil {
67+
slog.Error("failed to execute command", "error", err)
68+
os.Exit(1)
69+
}
6170
}

cmd/jobs/quickstart/cronjobs.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package quickstart
2+
3+
import (
4+
"log/slog"
5+
"os"
6+
"time"
7+
8+
"github.com/go-co-op/gocron/v2"
9+
"github.com/spf13/cobra"
10+
11+
"github.com/openmeterio/openmeter/cmd/jobs/internal"
12+
billingworkersubscription "github.com/openmeterio/openmeter/openmeter/billing/worker/subscription"
13+
)
14+
15+
var Cron = &cobra.Command{
16+
Use: "cron",
17+
Short: "Schedule the required cron jobs in the background.",
18+
RunE: func(cmd *cobra.Command, args []string) error {
19+
s, err := gocron.NewScheduler(
20+
gocron.WithLogger(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
21+
Level: slog.LevelInfo,
22+
}))),
23+
)
24+
if err != nil {
25+
return err
26+
}
27+
28+
namespaces := []string{"default"}
29+
batchSize := 10
30+
31+
// Sync subscriptions every hour
32+
_, err = s.NewJob(
33+
gocron.DurationJob(time.Hour),
34+
gocron.NewTask(func() {
35+
slog.Info("Syncing subscriptions")
36+
37+
err := internal.App.BillingSubscriptionReconciler.All(cmd.Context(), billingworkersubscription.ReconcilerAllInput{
38+
Namespaces: namespaces,
39+
Lookback: time.Hour,
40+
})
41+
if err != nil {
42+
slog.Error("Error syncing subscriptions", "error", err)
43+
}
44+
}),
45+
)
46+
if err != nil {
47+
return err
48+
}
49+
50+
// Collect invoices every minute
51+
_, err = s.NewJob(
52+
gocron.DurationJob(time.Minute),
53+
gocron.NewTask(func() {
54+
slog.Info("Collecting invoices")
55+
56+
err := internal.App.BillingCollector.All(cmd.Context(), namespaces, nil, batchSize)
57+
if err != nil {
58+
slog.Error("Error collecting invoices", "error", err)
59+
}
60+
}),
61+
)
62+
if err != nil {
63+
return err
64+
}
65+
66+
// Advance invoices every minute
67+
_, err = s.NewJob(
68+
gocron.DurationJob(time.Minute),
69+
gocron.NewTask(func() {
70+
slog.Info("Advancing invoices")
71+
72+
err := internal.App.BillingAutoAdvancer.All(cmd.Context(), namespaces, batchSize)
73+
if err != nil {
74+
slog.Error("Error advancing invoices", "error", err)
75+
}
76+
}),
77+
)
78+
if err != nil {
79+
return err
80+
}
81+
82+
s.Start()
83+
84+
<-cmd.Context().Done()
85+
if err := s.Shutdown(); err != nil {
86+
return err
87+
}
88+
89+
return nil
90+
},
91+
}
92+
93+
func init() {
94+
Cmd.AddCommand(Cron)
95+
}

cmd/jobs/quickstart/quickstart.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package quickstart
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
6+
"github.com/openmeterio/openmeter/cmd/jobs/billing/subscriptionsync"
7+
)
8+
9+
var Cmd = &cobra.Command{
10+
Use: "quickstart",
11+
Short: "Quickstart operations",
12+
Long: "Helpers for docker-compose based quickstart setup. Should not be used in production systems.",
13+
}
14+
15+
func init() {
16+
Cmd.AddCommand(subscriptionsync.Cmd)
17+
}

deploy/charts/openmeter/Chart.lock

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
dependencies:
2-
- name: strimzi-kafka-operator
3-
repository: https://strimzi.io/charts/
4-
version: 0.39.0
52
- name: altinity-clickhouse-operator
63
repository: https://docs.altinity.com/clickhouse-operator/
74
version: 0.23.3
@@ -14,5 +11,5 @@ dependencies:
1411
- name: redis
1512
repository: oci://registry-1.docker.io/bitnamicharts
1613
version: 20.2.1
17-
digest: sha256:f4de5a9b17965212a6afccfcdb46f054a8b5011e526f187c84dfb7344825bad8
18-
generated: "2024-11-08T11:40:40.003502+01:00"
14+
digest: sha256:984e797866c51fc1d921e3490d3f88b1023257345849449ffb0adb457e39a529
15+
generated: "2025-08-17T14:11:37.936915+02:00"

deploy/charts/openmeter/templates/deployment.yaml

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,3 +368,95 @@ spec:
368368
tolerations:
369369
{{- toYaml . | nindent 8 }}
370370
{{- end }}
371+
---
372+
apiVersion: apps/v1
373+
kind: Deployment
374+
metadata:
375+
name: {{ include "openmeter.componentName" (list . "billing-worker") }}
376+
labels:
377+
{{- include "openmeter.componentLabels" (list . "billing-worker") | nindent 4 }}
378+
spec:
379+
replicas: {{ .Values.billingWorker.replicaCount }}
380+
selector:
381+
matchLabels:
382+
{{- include "openmeter.componentSelectorLabels" (list . "billing-worker") | nindent 6 }}
383+
template:
384+
metadata:
385+
annotations:
386+
{{- with .Values.podAnnotations }}
387+
{{- toYaml . | nindent 8 }}
388+
{{- end }}
389+
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
390+
labels:
391+
{{- include "openmeter.componentLabels" (list . "billing-worker") | nindent 8 }}
392+
{{- with .Values.podLabels }}
393+
{{- toYaml . | nindent 8 }}
394+
{{- end }}
395+
spec:
396+
{{- with .Values.imagePullSecrets }}
397+
imagePullSecrets:
398+
{{- toYaml . | nindent 8 }}
399+
{{- end }}
400+
serviceAccountName: {{ include "openmeter.serviceAccountName" . }}
401+
securityContext:
402+
{{- toYaml .Values.podSecurityContext | nindent 8 }}
403+
{{ if or .Values.postgresql.enabled .Values.clickhouse.enabled -}}
404+
initContainers:
405+
{{- if .Values.postgresql.enabled -}}
406+
{{- include "openmeter.init.postgres" (list .) | nindent 8 }}
407+
{{- end }}
408+
{{- if .Values.clickhouse.enabled -}}
409+
{{- include "openmeter.init.clickhouse" (list .) | nindent 8 }}
410+
{{- end }}
411+
{{- end }}
412+
containers:
413+
- name: {{ .Chart.Name }}
414+
securityContext:
415+
{{- toYaml .Values.securityContext | nindent 12 }}
416+
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
417+
imagePullPolicy: {{ .Values.image.pullPolicy }}
418+
command: ["/entrypoint.sh", "openmeter-billing-worker"]
419+
args: ["--telemetry-address", "0.0.0.0:10000", "--config", "/etc/openmeter/config.yaml"]
420+
ports:
421+
- name: telemetry-http
422+
containerPort: 10000
423+
protocol: TCP
424+
livenessProbe:
425+
httpGet:
426+
path: /healthz/live
427+
port: telemetry-http
428+
readinessProbe:
429+
httpGet:
430+
path: /healthz/ready
431+
port: telemetry-http
432+
resources:
433+
{{- toYaml .Values.resources | nindent 12 }}
434+
volumeMounts:
435+
- name: config
436+
mountPath: /etc/openmeter
437+
{{- if ne (len .Values.caRootCertificates) 0 }}
438+
- name: ca-certificates
439+
mountPath: /usr/local/share/ca-certificates
440+
readOnly: true
441+
{{- end }}
442+
volumes:
443+
- name: config
444+
configMap:
445+
name: {{ include "openmeter.fullname" . }}
446+
{{- if ne (len .Values.caRootCertificates) 0 }}
447+
- name: ca-certificates
448+
configMap:
449+
name: ca-certificates
450+
{{- end }}
451+
{{- with .Values.nodeSelector }}
452+
nodeSelector:
453+
{{- toYaml . | nindent 8 }}
454+
{{- end }}
455+
{{- with .Values.affinity }}
456+
affinity:
457+
{{- toYaml . | nindent 8 }}
458+
{{- end }}
459+
{{- with .Values.tolerations }}
460+
tolerations:
461+
{{- toYaml . | nindent 8 }}
462+
{{- end }}

0 commit comments

Comments
 (0)