-
Notifications
You must be signed in to change notification settings - Fork 3
feat(ledger): integrate Ledger v3 operator #490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 29 commits
e0059ec
3971821
de1e325
c0fdbff
6aa2687
7f56f8c
ba358fc
abb0643
5740dcb
959063a
122316d
7261997
062bea6
2d6e7de
3daf0df
1b0cb68
b5bf838
9ca4316
9e85a4f
cfbc18e
e605fad
647f730
f94cf17
91328c7
b8fefe1
2a77ffe
34dfe7a
c202902
f76c581
8a31403
9abe429
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,3 +31,6 @@ charts | |
|
|
||
| # E2E test artifacts | ||
| tests/e2e/artifacts/ | ||
|
|
||
| # Local scratch files | ||
| tmp/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| 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 | ||
| RUN addgroup -S operator && adduser -S -G operator operator | ||
|
|
||
| ENTRYPOINT ["/usr/bin/operator"] | ||
|
|
||
| COPY --from=builder /usr/bin/operator /usr/bin/operator | ||
|
NumaryBot marked this conversation as resolved.
NumaryBot marked this conversation as resolved.
NumaryBot marked this conversation as resolved.
NumaryBot marked this conversation as resolved.
|
||
|
|
||
| USER operator | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 \ | ||
|
NumaryBot marked this conversation as resolved.
|
||
| --build-arg COMMIT=$EARTHLY_BUILD_SHA \ | ||
| -f Dockerfile . | ||
|
Comment on lines
+48
to
+54
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
awk '/^build-image:/{active=1} active && /ARG tag=/{declared=NR} active && /\$tag/{used=NR; exit} END {
if (!declared || declared > used) exit 1
}' EarthfileRepository: formancehq/operator Length of output: 157 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '--- Earthfile excerpt ---\n'
nl -ba Earthfile | sed -n '35,70p'
printf '\n--- Search for ARG tag occurrences ---\n'
rg -n '^\s*ARG\s+tag(\s*=|$)|\$tag\b' EarthfileRepository: formancehq/operator Length of output: 248 🏁 Script executed: #!/bin/bash
set -euo pipefail
nl -ba Earthfile | sed -n '35,70p'
rg -n '^\s*ARG\s+tag(\s*=|$)|\$tag\b' EarthfileRepository: formancehq/operator Length of output: 197 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- Earthfile excerpt (35-70) ---'
sed -n '35,70p' Earthfile | awk '{printf "%4d %s\n", NR+34, $0}'
echo
echo '--- ARG tag / $tag references ---'
awk '
/^\s*ARG\s+tag(\s*=|$)/ { print FNR ":" $0 }
/\$tag\b/ { print FNR ":" $0 }
' EarthfileRepository: formancehq/operator Length of output: 1846 Declare 🤖 Prompt for AI Agents |
||
| ARG REPOSITORY=ghcr.io | ||
| ARG tag=latest | ||
| DO --pass-args core+SAVE_IMAGE --COMPONENT=operator --TAG=$tag | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| /* | ||
| 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. | ||
| // The Secret must carry the `formance.com/gateway-backend-tls: "true"` | ||
| // label so that certificate rotations trigger a Gateway rollout. | ||
| // +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"` | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| /* | ||
| 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"` | ||
| } | ||
|
|
||
| //+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{}) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| /* | ||
| Copyright 2023. | ||
|
|
||
| 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" | ||
|
|
||
| ledgerv1alpha1 "github.com/formancehq/ledger/misc/operator/api/v1alpha1" | ||
| ) | ||
|
|
||
| const DefaultLedgerConfigurationName = "default" | ||
|
|
||
| type LedgerConfigurationSpec struct { | ||
| // Stacks on which the configuration is applied. Can contain `*` to | ||
| // indicate a wildcard, following the same convention as Settings. | ||
| // +optional | ||
| // +kubebuilder:validation:XValidation:rule="size(self) == 1 || !self.exists(stack, stack == '*')",message="the wildcard stack selector '*' cannot be combined with explicit stack names" | ||
| Stacks []string `json:"stacks,omitempty"` | ||
|
|
||
| // Cluster is the base Ledger v3 Cluster specification. Stack-specific | ||
| // Settings and values owned by the Operator are applied on top of it. | ||
| // +optional | ||
| Cluster ledgerv1alpha1.ClusterSpec `json:"cluster,omitempty"` | ||
| } | ||
|
|
||
| // +kubebuilder:object:root=true | ||
| // +kubebuilder:resource:scope=Cluster | ||
| // LedgerConfiguration defines the base specification applied to every Ledger v3 | ||
| // Cluster targeted by spec.stacks. A configuration targeting a stack by name | ||
| // takes priority over a configuration targeting all stacks with `*`. | ||
| type LedgerConfiguration struct { | ||
| metav1.TypeMeta `json:",inline"` | ||
| metav1.ObjectMeta `json:"metadata,omitempty"` | ||
|
|
||
| Spec LedgerConfigurationSpec `json:"spec,omitempty"` | ||
| } | ||
|
|
||
| func (in *LedgerConfiguration) GetStacks() []string { | ||
| return in.Spec.Stacks | ||
| } | ||
|
|
||
| func (in *LedgerConfiguration) IsWildcard() bool { | ||
|
NumaryBot marked this conversation as resolved.
|
||
| return len(in.Spec.Stacks) == 1 && in.Spec.Stacks[0] == "*" | ||
| } | ||
|
|
||
| // +kubebuilder:object:root=true | ||
|
|
||
| // LedgerConfigurationList contains a list of LedgerConfiguration | ||
| type LedgerConfigurationList struct { | ||
| metav1.TypeMeta `json:",inline"` | ||
| metav1.ListMeta `json:"metadata,omitempty"` | ||
| Items []LedgerConfiguration `json:"items"` | ||
| } | ||
|
|
||
| func init() { | ||
| SchemeBuilder.Register(&LedgerConfiguration{}, &LedgerConfigurationList{}) | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.