diff --git a/components/fctl/cmd/ledger/import.go b/components/fctl/cmd/ledger/import.go index fcb4e4aeb7..c34d93a86e 100644 --- a/components/fctl/cmd/ledger/import.go +++ b/components/fctl/cmd/ledger/import.go @@ -2,6 +2,7 @@ package ledger import ( "fmt" + fctl "github.com/formancehq/fctl/pkg" "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" "github.com/formancehq/stack/libs/go-libs/pointer" @@ -9,7 +10,7 @@ import ( "github.com/spf13/cobra" ) -type ImportStore struct {} +type ImportStore struct{} type ImportController struct { store *ImportStore inputFileFlag string @@ -46,7 +47,7 @@ func (c *ImportController) Run(cmd *cobra.Command, args []string) (fctl.Renderab store := fctl.GetStackStore(cmd.Context()) _, err := store.Client().Ledger.V2ImportLogs(cmd.Context(), operations.V2ImportLogsRequest{ - Ledger: args[0], + Ledger: args[0], RequestBody: pointer.For(fmt.Sprintf("file:%s", args[1])), }) diff --git a/components/operator/BREAKING_CHANGES b/components/operator/BREAKING_CHANGES deleted file mode 100644 index 19b2aba880..0000000000 --- a/components/operator/BREAKING_CHANGES +++ /dev/null @@ -1 +0,0 @@ -* secret annotations must be changed \ No newline at end of file diff --git a/components/operator/PROJECT b/components/operator/PROJECT index 804109aae4..f28660877d 100644 --- a/components/operator/PROJECT +++ b/components/operator/PROJECT @@ -184,4 +184,10 @@ resources: kind: Broker path: github.com/formancehq/operator/api/formance.com/v1beta1 version: v1beta1 +- api: + crdVersion: v1 + group: formance.com + kind: Analytics + path: github.com/formancehq/operator/api/formance.com/v1beta1 + version: v1beta1 version: "3" diff --git a/components/operator/TODO b/components/operator/TODO deleted file mode 100644 index a535b614e9..0000000000 --- a/components/operator/TODO +++ /dev/null @@ -1,2 +0,0 @@ -* add reindex job -* add canary deployments \ No newline at end of file diff --git a/components/operator/api/formance.com/v1beta1/analytics_types.go b/components/operator/api/formance.com/v1beta1/analytics_types.go new file mode 100644 index 0000000000..372376d2ee --- /dev/null +++ b/components/operator/api/formance.com/v1beta1/analytics_types.go @@ -0,0 +1,107 @@ +/* +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" +) + +// AnalyticsSpec defines the desired state of Analytics +type AnalyticsSpec struct { + ModuleProperties `json:",inline"` + StackDependency `json:",inline"` +} + +// AnalyticsStatus defines the observed state of Analytics +type AnalyticsStatus 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="Is ready" +//+kubebuilder:printcolumn:name="Info",type=string,JSONPath=".status.info",description="Info" +//+kubebuilder:metadata:labels=formance.com/kind=module +//+kubebuilder:metadata:labels=formance.com/is-ee=true + +// Analytics is the Schema for the analytics API +type Analytics struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AnalyticsSpec `json:"spec,omitempty"` + Status AnalyticsStatus `json:"status,omitempty"` +} + +func (in *Analytics) SetReady(b bool) { + in.Status.SetReady(b) +} + +func (in *Analytics) IsReady() bool { + //TODO implement me + + return in.Status.Ready +} + +func (in *Analytics) SetError(s string) { + in.Status.SetError(s) +} + +func (in *Analytics) GetConditions() *Conditions { + return &in.Status.Conditions +} + +func (in *Analytics) GetStack() string { + //TODO implement me + + return in.Spec.Stack +} + +func (in *Analytics) GetVersion() string { + //TODO implement me + return in.Spec.Version +} + +func (in *Analytics) IsDebug() bool { + //TODO implement me + return in.Spec.Debug +} + +func (in *Analytics) IsDev() bool { + //TODO implement me + return in.Spec.Dev +} + +func (in *Analytics) IsEE() bool { + //TODO implement me + return true +} + +//+kubebuilder:object:root=true + +// AnalyticsList contains a list of Analytics +type AnalyticsList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Analytics `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Analytics{}, &AnalyticsList{}) +} diff --git a/components/operator/api/formance.com/v1beta1/zz_generated.deepcopy.go b/components/operator/api/formance.com/v1beta1/zz_generated.deepcopy.go index a56f6bb724..f9ef6bc6f4 100644 --- a/components/operator/api/formance.com/v1beta1/zz_generated.deepcopy.go +++ b/components/operator/api/formance.com/v1beta1/zz_generated.deepcopy.go @@ -26,6 +26,98 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Analytics) DeepCopyInto(out *Analytics) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Analytics. +func (in *Analytics) DeepCopy() *Analytics { + if in == nil { + return nil + } + out := new(Analytics) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Analytics) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnalyticsList) DeepCopyInto(out *AnalyticsList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Analytics, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalyticsList. +func (in *AnalyticsList) DeepCopy() *AnalyticsList { + if in == nil { + return nil + } + out := new(AnalyticsList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AnalyticsList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnalyticsSpec) DeepCopyInto(out *AnalyticsSpec) { + *out = *in + out.ModuleProperties = in.ModuleProperties + out.StackDependency = in.StackDependency +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalyticsSpec. +func (in *AnalyticsSpec) DeepCopy() *AnalyticsSpec { + if in == nil { + return nil + } + out := new(AnalyticsSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AnalyticsStatus) DeepCopyInto(out *AnalyticsStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnalyticsStatus. +func (in *AnalyticsStatus) DeepCopy() *AnalyticsStatus { + if in == nil { + return nil + } + out := new(AnalyticsStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Auth) DeepCopyInto(out *Auth) { *out = *in diff --git a/components/operator/config/crd/bases/formance.com_analytics.yaml b/components/operator/config/crd/bases/formance.com_analytics.yaml new file mode 100644 index 0000000000..3f0ab4750a --- /dev/null +++ b/components/operator/config/crd/bases/formance.com_analytics.yaml @@ -0,0 +1,158 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + formance.com/is-ee: "true" + formance.com/kind: module + name: analytics.formance.com +spec: + group: formance.com + names: + kind: Analytics + listKind: AnalyticsList + plural: analytics + singular: analytics + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Stack + jsonPath: .spec.stack + name: Stack + type: string + - description: Is ready + jsonPath: .status.ready + name: Ready + type: string + - description: Info + jsonPath: .status.info + name: Info + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: Analytics is the Schema for the analytics API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AnalyticsSpec defines the desired state of Analytics + properties: + debug: + default: false + description: Allow to enable debug mode on the module + type: boolean + dev: + default: false + description: |- + Allow to enable dev mode on the module + Dev mode is used to allow some application to do custom setup in development mode (allow insecure certificates for example) + type: boolean + stack: + description: Stack indicates the stack on which the module is installed + type: string + version: + description: Version allow to override global version defined at stack + level for a specific module + type: string + type: object + status: + description: AnalyticsStatus defines the observed state of Analytics + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Status []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + pattern: ^([A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?)?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - status + - type + type: object + type: array + info: + description: Info can contain any additional like reconciliation errors + type: string + ready: + description: Ready indicates if the resource is seen as completely + reconciled + type: boolean + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/components/operator/config/crd/kustomization.yaml b/components/operator/config/crd/kustomization.yaml index 074a2302c4..be51257d7d 100644 --- a/components/operator/config/crd/kustomization.yaml +++ b/components/operator/config/crd/kustomization.yaml @@ -28,6 +28,7 @@ resources: - bases/formance.com_resourcereferences.yaml - bases/formance.com_brokerconsumers.yaml - bases/formance.com_brokers.yaml + - bases/formance.com_analytics.yaml #+kubebuilder:scaffold:crdkustomizeresource commonAnnotations: @@ -62,6 +63,7 @@ commonAnnotations: #- path: patches/webhook_in_formance.com_resourcereferences.yaml #- path: patches/webhook_in_formance.com_brokerconsumers.yaml #- path: patches/webhook_in_formance.com_brokers.yaml +#- path: patches/webhook_in_formance.com_analytics.yaml #+kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. @@ -100,6 +102,7 @@ commonAnnotations: #- path: patches/cainjection_in_formance.com_resourcereferences.yaml #- path: patches/cainjection_in_formance.com_brokerconsumers.yaml #- path: patches/cainjection_in_formance.com_brokers.yaml +#- path: patches/cainjection_in_formance.com_analytics.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch # [WEBHOOK] To enable webhook, uncomment the following section diff --git a/components/operator/config/rbac/formance.com_analytics_editor_role.yaml b/components/operator/config/rbac/formance.com_analytics_editor_role.yaml new file mode 100644 index 0000000000..ec5cbd292e --- /dev/null +++ b/components/operator/config/rbac/formance.com_analytics_editor_role.yaml @@ -0,0 +1,31 @@ +# permissions for end users to edit analytics. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: analytics-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: operatorv2 + app.kubernetes.io/part-of: operatorv2 + app.kubernetes.io/managed-by: kustomize + name: analytics-editor-role +rules: +- apiGroups: + - formance.com + resources: + - analytics + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - formance.com + resources: + - analytics/status + verbs: + - get diff --git a/components/operator/config/rbac/formance.com_analytics_viewer_role.yaml b/components/operator/config/rbac/formance.com_analytics_viewer_role.yaml new file mode 100644 index 0000000000..0abe07eac5 --- /dev/null +++ b/components/operator/config/rbac/formance.com_analytics_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view analytics. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: analytics-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: operatorv2 + app.kubernetes.io/part-of: operatorv2 + app.kubernetes.io/managed-by: kustomize + name: analytics-viewer-role +rules: +- apiGroups: + - formance.com + resources: + - analytics + verbs: + - get + - list + - watch +- apiGroups: + - formance.com + resources: + - analytics/status + verbs: + - get diff --git a/components/operator/config/rbac/role.yaml b/components/operator/config/rbac/role.yaml index 3b8234ffa2..2620f405d4 100644 --- a/components/operator/config/rbac/role.yaml +++ b/components/operator/config/rbac/role.yaml @@ -137,6 +137,32 @@ rules: - patch - update - watch +- apiGroups: + - formance.com + resources: + - analytics + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - formance.com + resources: + - analytics/finalizers + verbs: + - update +- apiGroups: + - formance.com + resources: + - analytics/status + verbs: + - get + - patch + - update - apiGroups: - formance.com resources: diff --git a/components/operator/config/samples/formance.com_v1beta1_analytics.yaml b/components/operator/config/samples/formance.com_v1beta1_analytics.yaml new file mode 100644 index 0000000000..4110b6090c --- /dev/null +++ b/components/operator/config/samples/formance.com_v1beta1_analytics.yaml @@ -0,0 +1,12 @@ +apiVersion: formance.com/v1beta1 +kind: Analytics +metadata: + labels: + app.kubernetes.io/name: analytics + app.kubernetes.io/instance: analytics-sample + app.kubernetes.io/part-of: operatorv2 + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: operatorv2 + name: analytics-sample +spec: + # TODO(user): Add fields here diff --git a/components/operator/config/samples/kustomization.yaml b/components/operator/config/samples/kustomization.yaml index f535db722d..f5054d5ea5 100644 --- a/components/operator/config/samples/kustomization.yaml +++ b/components/operator/config/samples/kustomization.yaml @@ -20,4 +20,5 @@ resources: - formance.com_v1beta1_resourcereference.yaml - formance.com_v1beta1_brokerconsumer.yaml - formance.com_v1beta1_broker.yaml +- formance.com_v1beta1_analytics.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/components/operator/docs/09-Configuration reference/02-Custom Resource Definitions.md b/components/operator/docs/09-Configuration reference/02-Custom Resource Definitions.md index c00572b77d..d40fdbc7f2 100644 --- a/components/operator/docs/09-Configuration reference/02-Custom Resource Definitions.md +++ b/components/operator/docs/09-Configuration reference/02-Custom Resource Definitions.md @@ -18,6 +18,7 @@ Various parts of the stack can be configured either using the CRD properties or Modules : +- [Analytics](#analytics) - [Auth](#auth) - [Gateway](#gateway) - [Ledger](#ledger) @@ -333,6 +334,93 @@ spec: ### Modules +#### Analytics + + + +Analytics is the Schema for the analytics API + + + + + + + + + + + + + + + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `apiVersion` _string_ | `formance.com/v1beta1` | | | +| `kind` _string_ | `Analytics` | | | +| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | | +| `spec` _[AnalyticsSpec](#analyticsspec)_ | | | | +| `status` _[AnalyticsStatus](#analyticsstatus)_ | | | | + + + +##### AnalyticsSpec + + + +AnalyticsSpec defines the desired state of Analytics + + + + + + + + + + + + + + + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `debug` _boolean_ | Allow to enable debug mode on the module | false | | +| `dev` _boolean_ | Allow to enable dev mode on the module
Dev mode is used to allow some application to do custom setup in development mode (allow insecure certificates for example) | false | | +| `version` _string_ | Version allow to override global version defined at stack level for a specific module | | | +| `stack` _string_ | Stack indicates the stack on which the module is installed | | | + + + + + +##### AnalyticsStatus + + + +AnalyticsStatus defines the observed state of Analytics + + + + + + + + + + + + + + + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `ready` _boolean_ | Ready indicates if the resource is seen as completely reconciled | | | +| `info` _string_ | Info can contain any additional like reconciliation errors | | | + + #### Auth diff --git a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_analytics.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_analytics.formance.com.yaml new file mode 100644 index 0000000000..3d7c842379 --- /dev/null +++ b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_analytics.formance.com.yaml @@ -0,0 +1,158 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + helm.sh/resource-policy: keep + labels: + formance.com/is-ee: "true" + formance.com/kind: module + name: analytics.formance.com +spec: + group: formance.com + names: + kind: Analytics + listKind: AnalyticsList + plural: analytics + singular: analytics + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Stack + jsonPath: .spec.stack + name: Stack + type: string + - description: Is ready + jsonPath: .status.ready + name: Ready + type: string + - description: Info + jsonPath: .status.info + name: Info + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: Analytics is the Schema for the analytics API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AnalyticsSpec defines the desired state of Analytics + properties: + debug: + default: false + description: Allow to enable debug mode on the module + type: boolean + dev: + default: false + description: |- + Allow to enable dev mode on the module + Dev mode is used to allow some application to do custom setup in development mode (allow insecure certificates for example) + type: boolean + stack: + description: Stack indicates the stack on which the module is installed + type: string + version: + description: Version allow to override global version defined at stack + level for a specific module + type: string + type: object + status: + description: AnalyticsStatus defines the observed state of Analytics + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Status []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + pattern: ^([A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?)?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - status + - type + type: object + type: array + info: + description: Info can contain any additional like reconciliation errors + type: string + ready: + description: Ready indicates if the resource is seen as completely + reconciled + type: boolean + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-manager-role.yaml b/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-manager-role.yaml index 138631613b..26ac1b7770 100644 --- a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-manager-role.yaml +++ b/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-manager-role.yaml @@ -136,6 +136,32 @@ rules: - patch - update - watch +- apiGroups: + - formance.com + resources: + - analytics + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - formance.com + resources: + - analytics/finalizers + verbs: + - update +- apiGroups: + - formance.com + resources: + - analytics/status + verbs: + - get + - patch + - update - apiGroups: - formance.com resources: diff --git a/components/operator/internal/resources/all.go b/components/operator/internal/resources/all.go index e196d757c4..aabcc0a01e 100644 --- a/components/operator/internal/resources/all.go +++ b/components/operator/internal/resources/all.go @@ -1,6 +1,7 @@ package resources import ( + _ "github.com/formancehq/operator/internal/resources/analytics" _ "github.com/formancehq/operator/internal/resources/authclients" _ "github.com/formancehq/operator/internal/resources/auths" _ "github.com/formancehq/operator/internal/resources/benthos" diff --git a/components/operator/internal/resources/analytics/init.go b/components/operator/internal/resources/analytics/init.go new file mode 100644 index 0000000000..118e4a2cd8 --- /dev/null +++ b/components/operator/internal/resources/analytics/init.go @@ -0,0 +1,36 @@ +/* +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 analytics + +import ( + "github.com/formancehq/operator/api/formance.com/v1beta1" + . "github.com/formancehq/operator/internal/core" +) + +//+kubebuilder:rbac:groups=formance.com,resources=analytics,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=formance.com,resources=analytics/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=formance.com,resources=analytics/finalizers,verbs=update + +func Reconcile(_ Context, _ *v1beta1.Stack, _ *v1beta1.Analytics, _ string) error { + return nil +} + +func init() { + Init( + WithModuleReconciler(Reconcile), + ) +} diff --git a/components/operator/internal/resources/ledgers/deployments.go b/components/operator/internal/resources/ledgers/deployments.go index fa21d5f116..92dde3c9c4 100644 --- a/components/operator/internal/resources/ledgers/deployments.go +++ b/components/operator/internal/resources/ledgers/deployments.go @@ -301,6 +301,16 @@ func createLedgerContainerFull(ctx core.Context, stack *v1beta1.Stack, v2 bool) container.Env = append(container.Env, brokers.GetPublisherEnvVars(stack, broker, "ledger", prefix)...) } + if v2 { + hasDependency, err := core.HasDependency(ctx, stack.Name, &v1beta1.Analytics{}) + if err != nil { + return nil, err + } + if hasDependency { + container.Env = append(container.Env, core.Env("EMIT_LOGS", "true")) + } + } + return container, nil } diff --git a/components/operator/internal/resources/ledgers/init.go b/components/operator/internal/resources/ledgers/init.go index aa5a8578e7..7c19cca21b 100644 --- a/components/operator/internal/resources/ledgers/init.go +++ b/components/operator/internal/resources/ledgers/init.go @@ -122,6 +122,7 @@ func init() { WithOwn[*v1beta1.Ledger](&v1beta1.BenthosStream{}), WithWatchSettings[*v1beta1.Ledger](), WithWatchDependency[*v1beta1.Ledger](&v1beta1.Search{}), + WithWatchDependency[*v1beta1.Ledger](&v1beta1.Analytics{}), brokertopics.Watch[*v1beta1.Ledger]("ledger"), databases.Watch[*v1beta1.Ledger](), ),