Skip to content
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e0059ec
feat(gateway): add GatewayGRPCAPI CRD for gRPC service exposure
gfyrag May 25, 2026
3971821
fix(e2e): increase chainsaw grpcapi deletion step timeout
gfyrag May 25, 2026
de1e325
feat: add Dockerfile and Pulumi deployment app
gfyrag May 28, 2026
c0fdbff
refactor(pulumi): take namespace as parameter instead of creating it
gfyrag May 28, 2026
6aa2687
fix: add -buildvcs=false to Dockerfile go build
gfyrag May 28, 2026
7f56f8c
feat(ledger): delegate v3 provisioning to ledger operator
flemzord Jul 14, 2026
ba358fc
fix(ledger): preserve replica settings for v3
flemzord Jul 14, 2026
abb0643
feat(gateway): integrate gRPC routing for Ledger v3
flemzord Jul 14, 2026
5740dcb
feat(ledger): configure v3 auth and monitoring
flemzord Jul 14, 2026
959063a
fix(ledger): preserve monitoring service name
flemzord Jul 14, 2026
122316d
fix(ledger): clear legacy readiness conditions for v3
flemzord Jul 14, 2026
7261997
chore: ignore local temporary files
flemzord Jul 14, 2026
062bea6
feat(ledger): configure v3 runtime resources and TLS
flemzord Jul 14, 2026
2d6e7de
feat(ledger): add v3 preview mode
flemzord Jul 14, 2026
3daf0df
feat(ledger): secure v3 cluster networking
flemzord Jul 15, 2026
1b0cb68
feat(ledger): add stack-targeted v3 configuration
flemzord Jul 15, 2026
b5bf838
feat(ledger): map topology spread setting to v3
flemzord Jul 15, 2026
9ca4316
fix(ledger): make v3 capability optional
flemzord Jul 15, 2026
9e85a4f
fix(operator): harden optional ledger v3 integration
flemzord Jul 15, 2026
cfbc18e
fix(ci): stabilize ledger integration tests
flemzord Jul 15, 2026
e605fad
fix(ledger): give ledger v3 raft TLS secret a dedicated name (#491)
Dav-14 Jul 16, 2026
158eb21
feat(connectivity): add Connectivity module bound to the stack ledger
Jul 16, 2026
1f6c39e
fix(connectivity): resolve ledger version via Versions + register CRD
Jul 16, 2026
d878371
docs: add 'Adding a module' developer guide
Jul 16, 2026
ccac19e
fix(connectivity): set image + pull secrets on the delegated resource
Jul 16, 2026
e6b4016
feat(connectivity): always deploy connectivity-api + expose via gateway
Jul 16, 2026
25d88fe
feat(connectivity): provision ledger credentials for connectivity-cor…
Dav-14 Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ charts

# E2E test artifacts
tests/e2e/artifacts/

# Local scratch files
tmp/
34 changes: 34 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
FROM golang:1.26-alpine AS builder

RUN apk add --no-cache git

WORKDIR /src

COPY go.mod go.sum ./
RUN go mod download

COPY . .

ARG VERSION=latest
ARG COMMIT=unknown
ARG LICENCE_PUBLIC_KEY_B64=""

WORKDIR /src/cmd

RUN set -e; \
LDFLAGS="-X github.com/formancehq/operator/v3/cmd.Version=${VERSION} \
-X github.com/formancehq/operator/v3/cmd.BuildDate=$(date +%s) \
-X github.com/formancehq/operator/v3/cmd.Commit=${COMMIT}"; \
if [ -n "$LICENCE_PUBLIC_KEY_B64" ]; then \
LICENCE_PUBLIC_KEY="$(printf '%s' "$LICENCE_PUBLIC_KEY_B64" | base64 -d)"; \
LDFLAGS="${LDFLAGS} -X 'github.com/formancehq/go-libs/v5/pkg/authn/licence.formancePublicKey=${LICENCE_PUBLIC_KEY}'"; \
fi; \
CGO_ENABLED=0 go build -buildvcs=false -o /usr/bin/operator -ldflags="${LDFLAGS}" .

FROM alpine:3.20

RUN apk update && apk add --no-cache ca-certificates curl

ENTRYPOINT ["/usr/bin/operator"]

COPY --from=builder /usr/bin/operator /usr/bin/operator
10 changes: 7 additions & 3 deletions Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,13 @@ compile:
SAVE ARTIFACT main

build-image:
FROM core+final-image
ENTRYPOINT ["/usr/bin/operator"]
COPY --pass-args (+compile/main) /usr/bin/operator
ARG LICENCE_PUBLIC_KEY_B64=""
ARG EARTHLY_BUILD_SHA
FROM DOCKERFILE \
--build-arg LICENCE_PUBLIC_KEY_B64=$LICENCE_PUBLIC_KEY_B64 \
--build-arg VERSION=$tag \
--build-arg COMMIT=$EARTHLY_BUILD_SHA \
-f Dockerfile .
ARG REPOSITORY=ghcr.io
ARG tag=latest
DO --pass-args core+SAVE_IMAGE --COMPONENT=operator --TAG=$tag
Expand Down
6 changes: 6 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,10 @@ resources:
kind: Broker
path: github.com/formancehq/operator/api/formance.com/v1beta1
version: v1beta1
- api:
crdVersion: v1
group: formance.com
kind: LedgerConfiguration
path: github.com/formancehq/operator/api/formance.com/v1beta1
version: v1beta1
version: "3"
103 changes: 103 additions & 0 deletions api/formance.com/v1beta1/connectivity_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
Copyright 2022.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1beta1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type ConnectivitySpec struct {
ModuleProperties `json:",inline"`
StackDependency `json:",inline"`
}

type ConnectivityStatus struct {
Status `json:",inline"`
}

// Connectivity is the module allowing to install a connectivity instance.
//
// Connectivity ingests data from external sources (blockchains, payment
// providers, ...) through a plugin system and writes double-entry
// transactions into the stack ledger. It delegates the actual workload to the
// connectivity operator (connectivity.formance.com), bound to the stack's
// Ledger v3 gRPC endpoint.
//
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster
// +kubebuilder:printcolumn:name="Stack",type=string,JSONPath=".spec.stack",description="Stack"
// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=".status.ready",description="Is ready"
// +kubebuilder:printcolumn:name="Info",type=string,JSONPath=".status.info",description="Info"
// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=".spec.version",description="Version"
// +kubebuilder:metadata:labels=formance.com/kind=module
type Connectivity struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ConnectivitySpec `json:"spec,omitempty"`
Status ConnectivityStatus `json:"status,omitempty"`
}

func (in *Connectivity) IsEE() bool {
return false
}

func (in *Connectivity) IsReady() bool {
return in.Status.Ready
}

func (in *Connectivity) SetReady(b bool) {
in.Status.Ready = b
}

func (in *Connectivity) SetError(s string) {
in.Status.Info = s
}

func (in *Connectivity) GetConditions() *Conditions {
return &in.Status.Conditions
}

func (in *Connectivity) GetVersion() string {
return in.Spec.Version
}

func (a Connectivity) GetStack() string {
return a.Spec.Stack
}

func (a Connectivity) IsDebug() bool {
return a.Spec.Debug
}

func (a Connectivity) IsDev() bool {
return a.Spec.Dev
}

//+kubebuilder:object:root=true

// ConnectivityList contains a list of Connectivity
type ConnectivityList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Connectivity `json:"items"`
}

func init() {
SchemeBuilder.Register(&Connectivity{}, &ConnectivityList{})
}
3 changes: 3 additions & 0 deletions api/formance.com/v1beta1/gateway_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ type GatewayStatus struct {
// Detected http apis. See [GatewayHTTPAPI](#gatewayhttpapi)
//+optional
SyncHTTPAPIs []string `json:"syncHTTPAPIs"`
// Detected grpc apis. See [GatewayGRPCAPI](#gatewaygrpcapi)
//+optional
SyncGRPCAPIs []string `json:"syncGRPCAPIs,omitempty"`
}

//+kubebuilder:object:root=true
Expand Down
48 changes: 48 additions & 0 deletions api/formance.com/v1beta1/gatewaybackend_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Copyright 2022.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1beta1

const GatewayBackendTLSSecretLabel = "formance.com/gateway-backend-tls"

// GatewayBackendTLS configures TLS when Gateway connects to a backend.
type GatewayBackendTLS struct {
// SecretName contains the CA used to verify the backend certificate.
// +kubebuilder:validation:MinLength=1
SecretName string `json:"secretName"`
// CASecretKey is the key containing the CA certificate.
// +optional
// +kubebuilder:default:="ca.crt"
CASecretKey string `json:"caSecretKey,omitempty"`
// ServerName is used for backend certificate verification.
// +kubebuilder:validation:MinLength=1
ServerName string `json:"serverName"`
}

// GatewayBackendRef selects the Kubernetes Service used by a Gateway route.
// When omitted, Gateway keeps using the module's historical Service.
type GatewayBackendRef struct {
// Name is the backend Service name in the Stack namespace.
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`
// Port is the backend Service port.
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=65535
Port int32 `json:"port"`
// TLS enables a verified TLS connection to the backend.
// +optional
TLS *GatewayBackendTLS `json:"tls,omitempty"`
}
91 changes: 91 additions & 0 deletions api/formance.com/v1beta1/gatewaygrpcapi_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
Copyright 2022.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1beta1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type GatewayGRPCAPISpec struct {
StackDependency `json:",inline"`
// Name indicates the module name (e.g. "ledger")
Name string `json:"name"`
// GRPCServices is the list of fully-qualified gRPC service names
// exposed by this module (e.g. "formance.ledger.v1.LedgerService")
GRPCServices []string `json:"grpcServices"`
// Port is the gRPC port on the backend service
//+optional
//+kubebuilder:default:=8081
Port int32 `json:"port,omitempty"`
// BackendRef overrides the historical <name>-grpc Service.
// +optional
BackendRef *GatewayBackendRef `json:"backendRef,omitempty"`
}

type GatewayGRPCAPIStatus struct {
Status `json:",inline"`
//+optional
Ready bool `json:"ready,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:scope=Cluster
//+kubebuilder:printcolumn:name="Stack",type=string,JSONPath=".spec.stack",description="Stack"
//+kubebuilder:printcolumn:name="Ready",type=string,JSONPath=".status.ready",description="Ready"

// GatewayGRPCAPI is the Schema for the GRPCAPIs API
type GatewayGRPCAPI struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec GatewayGRPCAPISpec `json:"spec,omitempty"`
Status GatewayGRPCAPIStatus `json:"status,omitempty"`
}

func (in *GatewayGRPCAPI) SetReady(b bool) {
in.Status.Ready = b
}

func (in *GatewayGRPCAPI) IsReady() bool {
return in.Status.Ready
}

func (in *GatewayGRPCAPI) SetError(s string) {
in.Status.Info = s
}

func (a GatewayGRPCAPI) GetStack() string {
return a.Spec.Stack
}

func (in *GatewayGRPCAPI) GetConditions() *Conditions {
return &in.Status.Conditions
}

//+kubebuilder:object:root=true

// GatewayGRPCAPIList contains a list of GatewayGRPCAPI
type GatewayGRPCAPIList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []GatewayGRPCAPI `json:"items"`
}

func init() {
SchemeBuilder.Register(&GatewayGRPCAPI{}, &GatewayGRPCAPIList{})
}
3 changes: 3 additions & 0 deletions api/formance.com/v1beta1/gatewayhttpapi_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ type GatewayHTTPAPIRule struct {
//+optional
//+kubebuilder:default:=false
Secured bool `json:"secured"`
// BackendRef overrides the historical module Service for this rule.
// +optional
BackendRef *GatewayBackendRef `json:"backendRef,omitempty"`
}

type GatewayHTTPAPISpec struct {
Expand Down
2 changes: 2 additions & 0 deletions api/formance.com/v1beta1/ledger_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const LedgerV3Label = "formance.com/ledger-v3"

type LedgerSpec struct {
ModuleProperties `json:",inline"`
StackDependency `json:",inline"`
Expand Down
Loading