From dd9f3b5ead91b1cefdebafe54e0acc45c96f5cc3 Mon Sep 17 00:00:00 2001 From: Maxence Maireaux Date: Thu, 26 Sep 2024 18:10:06 +0200 Subject: [PATCH 1/4] refactor: move all project to dedicated repo --- .github/workflows/main.yml | 130 +- Earthfile | 10 - components/Earthfile | 20 - components/operator/.dockerignore | 3 - .../.earthly/configuration/.helmignore | 23 - .../.earthly/configuration/Chart.yaml | 6 - .../templates/elasticsearch-secret.yaml | 12 - .../templates/postgres-secret.yaml | 11 - .../configuration/templates/settings.yaml | 70 - .../templates/temporal-secret.yaml | 61 - .../.earthly/configuration/values.yaml | 2 - .../operator/.earthly/k8s-versions.yaml | 17 - components/operator/.gitignore | 28 - components/operator/.goreleaser.yml | 40 - components/operator/Earthfile | 239 -- components/operator/Makefile | 181 - components/operator/PROJECT | 175 - components/operator/README.md | 185 - .../formance.com/v1beta1/analytics_types.go | 107 - .../api/formance.com/v1beta1/auth_types.go | 131 - .../formance.com/v1beta1/authclient_types.go | 120 - .../api/formance.com/v1beta1/benthos_types.go | 96 - .../v1beta1/benthosstream_types.go | 78 - .../api/formance.com/v1beta1/broker_types.go | 98 - .../v1beta1/brokerconsumer_types.go | 84 - .../formance.com/v1beta1/brokertopic_types.go | 82 - .../formance.com/v1beta1/database_types.go | 114 - .../api/formance.com/v1beta1/gateway_types.go | 130 - .../v1beta1/gatewayhttpapi_types.go | 94 - .../formance.com/v1beta1/groupversion_info.go | 45 - .../api/formance.com/v1beta1/ledger_types.go | 153 - .../v1beta1/orchestration_types.go | 105 - .../formance.com/v1beta1/payments_types.go | 101 - .../v1beta1/reconciliation_types.go | 99 - .../v1beta1/resourcereference_types.go | 124 - .../api/formance.com/v1beta1/search_types.go | 106 - .../formance.com/v1beta1/settings_types.go | 193 - .../api/formance.com/v1beta1/shared.go | 394 -- .../api/formance.com/v1beta1/stack_types.go | 122 - .../formance.com/v1beta1/stargate_types.go | 106 - .../formance.com/v1beta1/versions_types.go | 46 - .../api/formance.com/v1beta1/wallets_types.go | 99 - .../formance.com/v1beta1/webhooks_types.go | 98 - .../v1beta1/zz_generated.deepcopy.go | 2519 ------------ components/operator/build.Dockerfile | 4 - components/operator/cmd/main.go | 145 - .../crd/bases/formance.com_analytics.yaml | 158 - .../crd/bases/formance.com_authclients.yaml | 172 - .../config/crd/bases/formance.com_auths.yaml | 222 -- .../crd/bases/formance.com_benthos.yaml | 1555 -------- .../bases/formance.com_benthosstreams.yaml | 138 - .../bases/formance.com_brokerconsumers.yaml | 153 - .../crd/bases/formance.com_brokers.yaml | 156 - .../crd/bases/formance.com_brokertopics.yaml | 143 - .../crd/bases/formance.com_databases.yaml | 189 - .../bases/formance.com_gatewayhttpapis.yaml | 161 - .../crd/bases/formance.com_gateways.yaml | 202 - .../crd/bases/formance.com_ledgers.yaml | 215 -- .../bases/formance.com_orchestrations.yaml | 165 - .../crd/bases/formance.com_payments.yaml | 164 - .../bases/formance.com_reconciliations.yaml | 163 - .../formance.com_resourcereferences.yaml | 170 - .../crd/bases/formance.com_searches.yaml | 185 - .../crd/bases/formance.com_settings.yaml | 114 - .../config/crd/bases/formance.com_stacks.yaml | 205 - .../crd/bases/formance.com_stargates.yaml | 180 - .../crd/bases/formance.com_versions.yaml | 47 - .../crd/bases/formance.com_wallets.yaml | 164 - .../crd/bases/formance.com_webhooks.yaml | 163 - .../operator/config/crd/kustomization.yaml | 111 - .../operator/config/crd/kustomizeconfig.yaml | 19 - .../config/default/kustomization.yaml | 128 - .../default/manager_auth_proxy_patch.yaml | 39 - .../config/default/manager_config_patch.yaml | 10 - .../config/manager/kustomization.yaml | 9 - .../operator/config/manager/manager.yaml | 73 - .../manager/manager_auth_proxy_patch.yaml | 39 - .../config/prometheus/kustomization.yaml | 2 - .../operator/config/prometheus/monitor.yaml | 25 - .../config/rbac/auth_editor_role.yaml | 31 - .../rbac/auth_proxy_client_clusterrole.yaml | 16 - .../operator/config/rbac/auth_proxy_role.yaml | 24 - .../config/rbac/auth_proxy_role_binding.yaml | 19 - .../config/rbac/auth_proxy_service.yaml | 21 - .../config/rbac/auth_viewer_role.yaml | 27 - .../config/rbac/authclient_editor_role.yaml | 31 - .../config/rbac/authclient_viewer_role.yaml | 27 - .../config/rbac/benthos_editor_role.yaml | 31 - .../config/rbac/benthos_viewer_role.yaml | 27 - .../rbac/benthosstream_editor_role.yaml | 31 - .../rbac/benthosstream_viewer_role.yaml | 27 - .../config/rbac/brokertopic_editor_role.yaml | 31 - .../config/rbac/brokertopic_viewer_role.yaml | 27 - .../config/rbac/database_editor_role.yaml | 31 - .../config/rbac/database_viewer_role.yaml | 27 - .../formance.com_analytics_editor_role.yaml | 31 - .../formance.com_analytics_viewer_role.yaml | 27 - .../rbac/formance.com_broker_editor_role.yaml | 31 - .../rbac/formance.com_broker_viewer_role.yaml | 27 - ...rmance.com_brokerconsumer_editor_role.yaml | 31 - ...rmance.com_brokerconsumer_viewer_role.yaml | 27 - ...nce.com_resourcereference_editor_role.yaml | 31 - ...nce.com_resourcereference_viewer_role.yaml | 27 - .../formance.com_settings_editor_role.yaml | 31 - .../formance.com_settings_viewer_role.yaml | 27 - .../formance.com_versions_editor_role.yaml | 31 - .../formance.com_versions_viewer_role.yaml | 27 - .../config/rbac/gateway_editor_role.yaml | 31 - .../config/rbac/gateway_viewer_role.yaml | 27 - .../rbac/gatewayhttpapi_editor_role.yaml | 31 - .../rbac/gatewayhttpapi_viewer_role.yaml | 27 - .../operator/config/rbac/kustomization.yaml | 28 - .../config/rbac/leader_election_role.yaml | 44 - .../rbac/leader_election_role_binding.yaml | 19 - .../config/rbac/ledger_editor_role.yaml | 31 - .../config/rbac/ledger_viewer_role.yaml | 27 - .../rbac/orchestration_editor_role.yaml | 31 - .../rbac/orchestration_viewer_role.yaml | 27 - .../config/rbac/payments_editor_role.yaml | 31 - .../config/rbac/payments_viewer_role.yaml | 27 - .../rbac/reconciliation_editor_role.yaml | 31 - .../rbac/reconciliation_viewer_role.yaml | 27 - components/operator/config/rbac/role.yaml | 763 ---- .../operator/config/rbac/role_binding.yaml | 19 - .../config/rbac/search_editor_role.yaml | 31 - .../config/rbac/search_viewer_role.yaml | 27 - .../operator/config/rbac/service_account.yaml | 12 - ...ormance.com_configuration_editor_role.yaml | 31 - ...ormance.com_configuration_viewer_role.yaml | 27 - .../stack.formance.com_stack_editor_role.yaml | 31 - .../stack.formance.com_stack_viewer_role.yaml | 27 - ...ack.formance.com_versions_editor_role.yaml | 31 - ...ack.formance.com_versions_viewer_role.yaml | 27 - .../config/rbac/stack_editor_role.yaml | 31 - .../config/rbac/stack_viewer_role.yaml | 27 - .../config/rbac/stargate_editor_role.yaml | 31 - .../config/rbac/stargate_viewer_role.yaml | 27 - .../config/rbac/wallet_editor_role.yaml | 31 - .../config/rbac/wallet_viewer_role.yaml | 27 - .../config/rbac/webhooks_editor_role.yaml | 31 - .../config/rbac/webhooks_viewer_role.yaml | 27 - .../formance.com_v1beta1_analytics.yaml | 12 - .../samples/formance.com_v1beta1_auth.yaml | 12 - .../formance.com_v1beta1_authclient.yaml | 17 - .../samples/formance.com_v1beta1_broker.yaml | 12 - ...mance.com_v1beta1_brokerconfiguration.yaml | 15 - .../formance.com_v1beta1_brokerconsumer.yaml | 12 - ...nce.com_v1beta1_databaseconfiguration.yaml | 18 - ...om_v1beta1_elasticsearchconfiguration.yaml | 18 - .../samples/formance.com_v1beta1_gateway.yaml | 15 - .../samples/formance.com_v1beta1_ledger.yaml | 14 - ...om_v1beta1_opentelemetryconfiguration.yaml | 19 - .../formance.com_v1beta1_orchestration.yaml | 12 - .../formance.com_v1beta1_payments.yaml | 13 - .../formance.com_v1beta1_reconciliation.yaml | 12 - ....com_v1beta1_registriesconfigurations.yaml | 15 - ...ormance.com_v1beta1_resourcereference.yaml | 12 - .../samples/formance.com_v1beta1_search.yaml | 12 - ...m_v1beta1_searchbatchingconfiguration.yaml | 12 - .../formance.com_v1beta1_settings.yaml | 20 - .../samples/formance.com_v1beta1_stack.yaml | 11 - ...nce.com_v1beta1_temporalconfiguration.yaml | 65 - .../formance.com_v1beta1_versions.yaml | 12 - .../samples/formance.com_v1beta1_wallets.yaml | 12 - .../formance.com_v1beta1_webhooks.yaml | 14 - .../config/samples/kustomization.yaml | 24 - .../operator/config/webhook/manifests.yaml | 26 - .../operator/crd-doc-templates/gv_details.tpl | 95 - .../operator/crd-doc-templates/gv_list.tpl | 15 - .../operator/crd-doc-templates/type.tpl | 58 - .../crd-doc-templates/type_members.tpl | 8 - components/operator/docs.config.yaml | 22 - components/operator/docs/01-Requirements.md | 18 - components/operator/docs/02-Installation.md | 103 - .../operator/docs/03-Demo deployment.md | 33 - .../operator/docs/04-Modules/01-Stack.md | 24 - .../operator/docs/04-Modules/02-Gateway.md | 31 - .../operator/docs/04-Modules/03-Ledger.md | 22 - .../operator/docs/04-Modules/04-Payments.md | 22 - .../operator/docs/04-Modules/05-Auth.md | 43 - .../docs/04-Modules/06-Orchestration.md | 32 - .../operator/docs/04-Modules/07-Search.md | 35 - .../docs/04-Modules/08-Reconciliation.md | 25 - .../operator/docs/04-Modules/09-Wallets.md | 25 - .../operator/docs/04-Modules/10-Webhooks.md | 24 - .../01-PostgreSQL.md | 90 - .../02-Message broker.md | 55 - .../03-Elasticsearch.md | 25 - .../05-Infrastructure services/04-Temporal.md | 51 - .../01-Configure OpenTelemetry.md | 27 - .../01-Upgrade from the operator.md | 61 - .../docs/07-Upgrade/02-Database update.md | 23 - .../operator/docs/08-Troubleshooting.md | 11 - .../09-Configuration reference/01-Settings.md | 218 -- .../02-Custom Resource Definitions.md | 2558 ------------- components/operator/go.mod | 85 - components/operator/go.sum | 211 -- components/operator/hack/boilerplate.go.txt | 15 - components/operator/helm/crds/.helmignore | 28 - components/operator/helm/crds/Chart.yaml | 23 - components/operator/helm/crds/README.md | 45 - ...urcedefinition_analytics.formance.com.yaml | 158 - ...cedefinition_authclients.formance.com.yaml | 172 - ...resourcedefinition_auths.formance.com.yaml | 222 -- ...sourcedefinition_benthos.formance.com.yaml | 1555 -------- ...efinition_benthosstreams.formance.com.yaml | 138 - ...finition_brokerconsumers.formance.com.yaml | 153 - ...sourcedefinition_brokers.formance.com.yaml | 156 - ...edefinition_brokertopics.formance.com.yaml | 143 - ...urcedefinition_databases.formance.com.yaml | 189 - ...finition_gatewayhttpapis.formance.com.yaml | 161 - ...ourcedefinition_gateways.formance.com.yaml | 202 - ...sourcedefinition_ledgers.formance.com.yaml | 215 -- ...efinition_orchestrations.formance.com.yaml | 165 - ...ourcedefinition_payments.formance.com.yaml | 164 - ...finition_reconciliations.formance.com.yaml | 163 - ...ition_resourcereferences.formance.com.yaml | 170 - ...ourcedefinition_searches.formance.com.yaml | 185 - ...ourcedefinition_settings.formance.com.yaml | 114 - ...esourcedefinition_stacks.formance.com.yaml | 205 - ...urcedefinition_stargates.formance.com.yaml | 180 - ...ourcedefinition_versions.formance.com.yaml | 47 - ...sourcedefinition_wallets.formance.com.yaml | 164 - ...ourcedefinition_webhooks.formance.com.yaml | 163 - components/operator/helm/crds/values.yaml | 0 components/operator/helm/operator/.helmignore | 28 - components/operator/helm/operator/Chart.lock | 6 - components/operator/helm/operator/Chart.yaml | 29 - components/operator/helm/operator/README.md | 45 - .../helm/operator/templates/_helpers.tpl | 51 - .../helm/operator/templates/deployment.yaml | 133 - ..._v1_clusterrole_formance-manager-role.yaml | 762 ---- ...1_clusterrole_formance-metrics-reader.yaml | 16 - ...io_v1_clusterrole_formance-proxy-role.yaml | 24 - ...ebinding_formance-manager-rolebinding.yaml | 19 - ...olebinding_formance-proxy-rolebinding.yaml | 19 - ...v1_role_formance-leader-election-role.yaml | 44 - ..._formance-leader-election-rolebinding.yaml | 20 - ...ce-controller-manager-metrics-service.yaml | 21 - ...ceaccount_formance-controller-manager.yaml | 12 - .../operator/templates/licence-secret.yaml | 12 - components/operator/helm/operator/values.yaml | 85 - components/operator/internal/core/context.go | 46 - .../operator/internal/core/controllers.go | 184 - components/operator/internal/core/env.go | 84 - components/operator/internal/core/errors.go | 45 - components/operator/internal/core/manager.go | 28 - components/operator/internal/core/module.go | 14 - components/operator/internal/core/names.go | 24 - components/operator/internal/core/ns.go | 25 - components/operator/internal/core/platform.go | 13 - .../operator/internal/core/publisher.go | 37 - .../operator/internal/core/reconciler.go | 489 --- components/operator/internal/core/setup.go | 109 - components/operator/internal/core/shell.go | 12 - components/operator/internal/core/stacks.go | 91 - components/operator/internal/core/utils.go | 186 - components/operator/internal/core/version.go | 62 - components/operator/internal/core/volumes.go | 26 - components/operator/internal/core/watch.go | 52 - components/operator/internal/resources/all.go | 25 - .../internal/resources/analytics/init.go | 36 - .../resources/applications/application.go | 377 -- .../resources/applications/liveness.go | 57 - .../internal/resources/applications/ports.go | 10 - .../internal/resources/authclients/create.go | 51 - .../internal/resources/authclients/init.go | 58 - .../internal/resources/auths/configuration.go | 46 - .../internal/resources/auths/deployment.go | 126 - .../operator/internal/resources/auths/env.go | 53 - .../operator/internal/resources/auths/init.go | 115 - .../internal/resources/benthos/controller.go | 365 -- .../internal/resources/benthos/init.go | 38 - .../resources/benthosstreams/create.go | 90 - .../internal/resources/benthosstreams/init.go | 59 - .../resources/brokerconsumers/controller.go | 281 -- .../resources/brokerconsumers/create.go | 68 - .../resources/brokerconsumers/init.go | 19 - .../internal/resources/brokers/init.go | 20 - .../internal/resources/brokers/reconcile.go | 309 -- .../internal/resources/brokers/utils.go | 124 - .../internal/resources/brokers/watch.go | 30 - .../resources/brokertopics/brokertopics.go | 23 - .../resources/brokertopics/controller.go | 31 - .../internal/resources/brokertopics/init.go | 41 - .../internal/resources/brokertopics/watch.go | 33 - .../internal/resources/caddy/caddy.go | 151 - .../internal/resources/databases/create.go | 71 - .../internal/resources/databases/env.go | 109 - .../internal/resources/databases/init.go | 190 - .../internal/resources/databases/migrate.go | 51 - .../internal/resources/databases/watch.go | 34 - .../resources/gatewayhttpapis/create.go | 60 - .../resources/gatewayhttpapis/init.go | 46 - .../resources/gateways/Caddyfile.gotpl | 112 - .../internal/resources/gateways/caddyfile.go | 32 - .../resources/gateways/configuration.go | 33 - .../internal/resources/gateways/deployment.go | 44 - .../internal/resources/gateways/gateways.go | 49 - .../internal/resources/gateways/ingress.go | 96 - .../internal/resources/gateways/init.go | 102 - .../internal/resources/gateways/url.go | 15 - .../operator/internal/resources/jobs/job.go | 141 - .../internal/resources/ledgers/assets.go | 12 - .../resources/ledgers/assets/Caddyfile.gotpl | 30 - .../assets/reindex/v1.0.0/ledger_reindex.yaml | 16 - .../v1.0.0/ledger_reindex_accounts.yaml | 60 - .../reindex/v1.0.0/ledger_reindex_all.yaml | 18 - .../v1.0.0/ledger_reindex_transactions.yaml | 76 - .../v1.0.0/ledger_reindex_volumes.yaml | 60 - .../assets/reindex/v2.0.0/ledger_reindex.yaml | 13 - .../v2.0.0/ledger_reindex_accounts.yaml | 41 - .../reindex/v2.0.0/ledger_reindex_all.yaml | 20 - .../v2.0.0/ledger_reindex_transactions.yaml | 56 - .../internal/resources/ledgers/deployments.go | 438 --- .../internal/resources/ledgers/init.go | 131 - .../internal/resources/ledgers/reindex.go | 50 - .../internal/resources/licence/licence.go | 48 - .../resources/orchestrations/deployments.go | 208 - .../internal/resources/orchestrations/init.go | 120 - .../resources/payments/Caddyfile.gotpl | 49 - .../resources/payments/deployments.go | 300 -- .../internal/resources/payments/init.go | 147 - .../internal/resources/payments/payments.go | 8 - .../resources/reconciliations/deployments.go | 75 - .../resources/reconciliations/init.go | 105 - .../internal/resources/registries/image.go | 57 - .../resources/registries/registries.go | 82 - .../registries/registries_generated.go | 53 - .../resources/registries/registries_test.go | 49 - .../resources/resourcereferences/create.go | 55 - .../resources/resourcereferences/init.go | 226 -- .../searches/benthos/audit/gateway_audit.yaml | 34 - .../internal/resources/searches/benthos/fs.go | 11 - .../searches/benthos/global/config.yaml | 9 - .../searches/clean_legacy_consumers.go | 44 - .../internal/resources/searches/init.go | 247 -- .../internal/resources/services/services.go | 50 - .../internal/resources/settings/aws_role.go | 7 - .../internal/resources/settings/helpers.go | 385 -- .../resources/settings/helpers_test.go | 210 - .../resources/settings/opentelemetry.go | 92 - .../settings/resourcerequirements.go | 52 - .../internal/resources/settings/settings.go | 53 - .../internal/resources/stacks/init.go | 357 -- .../resources/stargates/deployment.go | 68 - .../internal/resources/stargates/init.go | 45 - .../internal/resources/wallets/deployment.go | 70 - .../internal/resources/wallets/init.go | 69 - .../internal/resources/webhooks/deployment.go | 188 - .../internal/resources/webhooks/init.go | 112 - .../internal/tests/auth_controller_test.go | 197 - .../tests/authclient_controller_test.go | 52 - .../internal/tests/benthos_controller_test.go | 122 - .../tests/benthosstream_controller_test.go | 41 - .../tests/brokerconsumer_controller_test.go | 109 - .../tests/brokertopic_controller_test.go | 82 - .../tests/database_controller_test.go | 217 -- .../internal/tests/gateway_controller_test.go | 257 -- .../tests/gatewayhttpapi_controller_test.go | 78 - .../internal/tests/internal/bootstrap.go | 229 -- .../internal/tests/internal/errors.go | 7 - .../internal/matcher_be_controlled_by.go | 13 - .../tests/internal/matcher_be_not_found.go | 35 - .../tests/internal/matcher_be_owned_by.go | 79 - .../tests/internal/matcher_be_ready.go | 36 - .../internal/matcher_match_golden_file.go | 69 - .../internal/matcher_target_deployment.go | 59 - .../operator/internal/tests/internal/utils.go | 21 - .../internal/tests/ledger_controller_test.go | 382 -- .../tests/orchestration_controller_test.go | 133 - .../tests/payments_controller_test.go | 143 - .../internal/tests/registries_test.go | 81 - .../resourcereferences_controller_test.go | 119 - .../tests/searches_controller_test.go | 90 - .../tests/settings_controller_test.go | 130 - .../internal/tests/stack_controller_test.go | 247 -- .../tests/stargate_controller_test.go | 66 - .../operator/internal/tests/suite_test.go | 13 - .../config-with-auth-client.yaml | 9 - .../configmap-with-audit.yaml | 52 - ...igmap-with-ledger-and-another-service.yaml | 70 - .../configmap-with-ledger-only.yaml | 52 - .../configmap-with-opentelemetry.yaml | 55 - .../internal/tests/wallets_controller_test.go | 113 - .../pkg/client/formance.com/v1beta1/auth.go | 91 - .../pkg/client/formance.com/v1beta1/client.go | 83 - .../client/formance.com/v1beta1/gateway.go | 91 - .../pkg/client/formance.com/v1beta1/ledger.go | 91 - .../formance.com/v1beta1/orchestration.go | 91 - .../client/formance.com/v1beta1/payments.go | 91 - .../formance.com/v1beta1/reconciliation.go | 91 - .../pkg/client/formance.com/v1beta1/search.go | 91 - .../pkg/client/formance.com/v1beta1/stack.go | 106 - .../client/formance.com/v1beta1/versions.go | 91 - .../client/formance.com/v1beta1/wallets.go | 91 - .../client/formance.com/v1beta1/webhooks.go | 91 - components/operator/scratch.Dockerfile | 4 - .../operator/tools/kubectl-stacks/Earthfile | 21 - .../operator/tools/kubectl-stacks/disable.go | 44 - .../operator/tools/kubectl-stacks/enable.go | 44 - .../operator/tools/kubectl-stacks/go.mod | 85 - .../operator/tools/kubectl-stacks/go.sum | 368 -- .../operator/tools/kubectl-stacks/list.go | 73 - .../operator/tools/kubectl-stacks/lock.go | 71 - .../operator/tools/kubectl-stacks/main.go | 63 - .../tools/kubectl-stacks/set-debug.go | 44 - .../operator/tools/kubectl-stacks/settings.go | 89 - .../operator/tools/kubectl-stacks/unlock.go | 68 - .../operator/tools/kubectl-stacks/upgrade.go | 104 - .../operator/tools/utils/.goreleaser.yml | 39 - components/operator/tools/utils/Earthfile | 52 - components/operator/tools/utils/LICENSE | 0 .../operator/tools/utils/build.Dockerfile | 4 - .../tools/utils/cmd/database-create.go | 27 - .../operator/tools/utils/cmd/database-drop.go | 27 - .../operator/tools/utils/cmd/database.go | 17 - components/operator/tools/utils/cmd/root.go | 41 - components/operator/tools/utils/go.mod | 79 - components/operator/tools/utils/go.sum | 212 -- components/operator/tools/utils/main.go | 11 - .../operator/tools/utils/scratch.Dockerfile | 4 - ee/Earthfile | 23 - ee/LICENSE | 21 - ee/agent/.earthly/values.yaml | 30 - ee/agent/.goreleaser.yml | 37 - ee/agent/Earthfile | 156 - ee/agent/Taskfile.yaml | 25 - ee/agent/agent.proto | 144 - ee/agent/build.Dockerfile | 4 - ee/agent/cmd/root.go | 206 - ee/agent/cmd/version.go | 21 - ee/agent/go.mod | 123 - ee/agent/go.sum | 302 -- ee/agent/helm/.gitignore | 1 - ee/agent/helm/.helmignore | 23 - ee/agent/helm/Chart.yaml | 14 - ee/agent/helm/README.md | 54 - ee/agent/helm/templates/_helpers.tpl | 14 - ee/agent/helm/templates/clusterrole.yaml | 18 - .../helm/templates/clusterrolebinding.yaml | 12 - ee/agent/helm/templates/deployment.yaml | 82 - ee/agent/helm/templates/serviceaccount.yaml | 8 - ee/agent/helm/values.yaml | 72 - ee/agent/internal/authenticator.go | 51 - ee/agent/internal/generated/agent.pb.go | 2047 ---------- ee/agent/internal/generated/agent_grpc.pb.go | 200 - ee/agent/internal/informer_modules.go | 119 - ee/agent/internal/informer_modules_test.go | 230 -- ee/agent/internal/informer_stacks.go | 123 - ee/agent/internal/informer_stacks_test.go | 147 - ee/agent/internal/informer_versions.go | 79 - ee/agent/internal/k8s_client.go | 157 - ee/agent/internal/k8s_client_test.go | 57 - ee/agent/internal/membership_client.go | 246 -- .../internal/membership_client_generated.go | 68 - ee/agent/internal/membership_listener.go | 446 --- ee/agent/internal/membership_listener_test.go | 208 - ee/agent/internal/module.go | 228 -- ee/agent/internal/utils.go | 63 - ee/agent/main.go | 11 - ee/agent/scratch.Dockerfile | 4 - ee/agent/tests/informer_stacks_test.go | 348 -- ee/agent/tests/informers_modules_test.go | 199 - .../tests/internal/matcher_be_owned_by.go | 74 - .../tests/internal/matcher_target_stack.go | 62 - ee/agent/tests/main_test.go | 76 - ee/agent/tests/membership_listener_test.go | 300 -- ee/orchestration/.gitignore | 3 - ee/orchestration/.goreleaser.yml | 37 - ee/orchestration/Earthfile | 100 - ee/orchestration/build.Dockerfile | 5 - ee/orchestration/cmd/root.go | 132 - ee/orchestration/cmd/serve.go | 102 - ee/orchestration/cmd/version.go | 19 - ee/orchestration/cmd/worker.go | 87 - ee/orchestration/deploy/auth/config.yaml | 8 - .../deploy/postgres/init-databases.sh | 11 - ee/orchestration/deploy/proxy/.gitignore | 1 - ee/orchestration/deploy/proxy/Caddyfile | 14 - ee/orchestration/examples/delay.yaml | 6 - .../examples/failing-workflow.yaml | 13 - .../examples/ledger-to-ledger.yaml | 14 - .../examples/ledger-to-wallet.yaml | 13 - .../examples/payin-to-wallet.yaml | 13 - .../examples/update-account-metadata.yaml | 8 - ee/orchestration/examples/wait_event.yaml | 4 - .../examples/wallet-to-payout.yaml | 14 - ee/orchestration/examples/workflow.yaml | 27 - ee/orchestration/go.mod | 187 - ee/orchestration/go.sum | 555 --- ee/orchestration/internal/api/backend.go | 43 - .../internal/api/backend_generated.go | 307 -- ee/orchestration/internal/api/handler_info.go | 17 - ee/orchestration/internal/api/module.go | 26 - ee/orchestration/internal/api/module_test.go | 58 - ee/orchestration/internal/api/router.go | 63 - .../api/v1/handler_abort_workflow_instance.go | 19 - .../internal/api/v1/handler_create_trigger.go | 40 - .../api/v1/handler_create_trigger_test.go | 33 - .../api/v1/handler_create_workflow.go | 50 - .../api/v1/handler_create_workflow_test.go | 25 - .../internal/api/v1/handler_delete_trigger.go | 28 - .../api/v1/handler_delete_workflow.go | 42 - .../api/v1/handler_delete_workflow_test.go | 44 - .../internal/api/v1/handler_get_trigger.go | 30 - .../internal/api/v1/handler_list_instances.go | 28 - .../api/v1/handler_list_instances_test.go | 92 - .../internal/api/v1/handler_list_triggers.go | 44 - .../v1/handler_list_triggers_occurrences.go | 27 - .../internal/api/v1/handler_list_workflows.go | 24 - .../internal/api/v1/handler_post_event.go | 28 - .../internal/api/v1/handler_read_instance.go | 21 - .../api/v1/handler_read_instance_history.go | 21 - .../api/v1/handler_read_instance_test.go | 60 - .../api/v1/handler_read_stage_history.go | 36 - .../internal/api/v1/handler_read_workflow.go | 21 - .../internal/api/v1/handler_run_workflow.go | 50 - .../api/v1/handler_run_workflow_test.go | 56 - ee/orchestration/internal/api/v1/main_test.go | 105 - ee/orchestration/internal/api/v1/module.go | 15 - ee/orchestration/internal/api/v1/router.go | 65 - .../api/v2/handler_abort_workflow_instance.go | 19 - .../internal/api/v2/handler_create_trigger.go | 40 - .../api/v2/handler_create_trigger_test.go | 33 - .../api/v2/handler_create_workflow.go | 50 - .../api/v2/handler_create_workflow_test.go | 25 - .../internal/api/v2/handler_delete_trigger.go | 28 - .../api/v2/handler_delete_workflow.go | 42 - .../api/v2/handler_delete_workflow_test.go | 44 - .../internal/api/v2/handler_get_trigger.go | 30 - .../internal/api/v2/handler_list_instances.go | 42 - .../api/v2/handler_list_instances_test.go | 91 - .../internal/api/v2/handler_list_triggers.go | 43 - .../v2/handler_list_triggers_occurrences.go | 43 - .../internal/api/v2/handler_list_workflows.go | 38 - .../internal/api/v2/handler_post_event.go | 28 - .../internal/api/v2/handler_read_instance.go | 21 - .../api/v2/handler_read_instance_history.go | 21 - .../api/v2/handler_read_instance_test.go | 54 - .../api/v2/handler_read_stage_history.go | 36 - .../internal/api/v2/handler_read_workflow.go | 21 - .../internal/api/v2/handler_run_workflow.go | 50 - .../api/v2/handler_run_workflow_test.go | 56 - .../internal/api/v2/handler_test_trigger.go | 30 - .../api/v2/handler_test_trigger_test.go | 124 - ee/orchestration/internal/api/v2/main_test.go | 102 - ee/orchestration/internal/api/v2/module.go | 15 - ee/orchestration/internal/api/v2/router.go | 66 - ee/orchestration/internal/schema/duration.go | 27 - ee/orchestration/internal/schema/map.go | 316 -- ee/orchestration/internal/schema/tag.go | 21 - .../internal/schema/validation.go | 56 - .../internal/storage/main_test.go | 21 - .../internal/storage/migrations.go | 175 - .../internal/storage/migrations_test.go | 44 - .../internal/temporalclient/client_module.go | 105 - .../internal/temporalclient/logger.go | 42 - .../internal/temporalworker/module.go | 86 - .../internal/triggers/activities.go | 140 - .../internal/triggers/expression.go | 152 - .../internal/triggers/listener.go | 117 - .../internal/triggers/main_test.go | 35 - ee/orchestration/internal/triggers/manager.go | 181 - ee/orchestration/internal/triggers/module.go | 46 - ee/orchestration/internal/triggers/trigger.go | 121 - .../internal/triggers/trigger_test.go | 177 - .../internal/triggers/workflow_trigger.go | 140 - .../triggers/workflow_trigger_test.go | 98 - .../internal/workflow/activities.go | 153 - .../internal/workflow/activities/activity.go | 88 - .../activities/activity_account_get.go | 49 - .../activity_ledger_add_account_metadata.go | 44 - .../activity_ledger_create_transaction.go | 78 - .../activity_payment_stripe_transfer.go | 56 - .../activities/activity_payments_get.go | 39 - .../activity_wallet_confirm_hold.go | 44 - .../activities/activity_wallet_credit.go | 65 - .../activities/activity_wallet_debit.go | 80 - .../activities/activity_wallet_get.go | 39 - .../activities/activity_wallet_list.go | 39 - .../activities/activity_wallet_void_hold.go | 35 - .../internal/workflow/activities_test.go | 41 - ee/orchestration/internal/workflow/config.go | 133 - ee/orchestration/internal/workflow/input.go | 6 - .../internal/workflow/instance.go | 41 - .../internal/workflow/main_test.go | 36 - ee/orchestration/internal/workflow/manager.go | 400 -- .../internal/workflow/manager_test.go | 78 - ee/orchestration/internal/workflow/module.go | 46 - ee/orchestration/internal/workflow/run.go | 100 - ee/orchestration/internal/workflow/stage.go | 41 - .../internal/workflow/stages/all/all.go | 8 - .../internal/workflow/stages/delay/delay.go | 21 - .../internal/workflow/stages/delay/run.go | 17 - .../workflow/stages/delay/run_test.go | 77 - .../workflow/stages/internal/context.go | 32 - .../stages/internal/stagestesting/schema.go | 53 - .../stages/internal/stagestesting/workflow.go | 57 - .../internal/workflow/stages/noop.go | 20 - .../internal/workflow/stages/schema.go | 19 - .../internal/workflow/stages/send/run.go | 446 --- .../internal/workflow/stages/send/run_test.go | 1447 ------- .../internal/workflow/stages/send/send.go | 106 - .../internal/workflow/stages/update/run.go | 20 - .../workflow/stages/update/run_test.go | 70 - .../internal/workflow/stages/update/update.go | 25 - .../workflow/stages/wait_event/run.go | 22 - .../workflow/stages/wait_event/wait_event.go | 17 - .../stages/wait_event/wait_event_test.go | 53 - ee/orchestration/internal/workflow/tracer.go | 7 - .../internal/workflow/workflow.go | 27 - ee/orchestration/main.go | 9 - ee/orchestration/openapi.yaml | 3361 ----------------- ee/orchestration/openapi/openapi-merge.json | 11 - ee/orchestration/openapi/v1.yaml | 1592 -------- ee/orchestration/openapi/v2.yaml | 1771 --------- ee/orchestration/pkg/.gitkeep | 0 ee/orchestration/pkg/events/events.go | 79 - ee/orchestration/scratch.Dockerfile | 5 - ee/reconciliation/.gitignore | 10 - ee/reconciliation/.goreleaser.yml | 37 - ee/reconciliation/Earthfile | 82 - ee/reconciliation/README.md | 1 - ee/reconciliation/build.Dockerfile | 5 - ee/reconciliation/cmd/migrate.go | 21 - ee/reconciliation/cmd/root.go | 51 - ee/reconciliation/cmd/serve.go | 113 - ee/reconciliation/cmd/version.go | 19 - ee/reconciliation/go.mod | 133 - ee/reconciliation/go.sum | 370 -- .../internal/api/api_utils_test.go | 23 - .../internal/api/backend/backend.go | 41 - .../internal/api/backend/backend_generated.go | 180 - ee/reconciliation/internal/api/module.go | 66 - ee/reconciliation/internal/api/policy.go | 118 - ee/reconciliation/internal/api/policy_test.go | 374 -- ee/reconciliation/internal/api/query.go | 43 - .../internal/api/reconciliation.go | 130 - .../internal/api/reconciliation_test.go | 471 --- ee/reconciliation/internal/api/router.go | 46 - .../internal/api/service/errors.go | 39 - .../internal/api/service/policy.go | 87 - .../internal/api/service/reconciliation.go | 203 - .../api/service/reconciliation_test.go | 281 -- .../internal/api/service/service.go | 72 - .../internal/api/service/service_test.go | 136 - .../internal/api/service/utils.go | 117 - .../internal/api/service/utils_test.go | 68 - ee/reconciliation/internal/api/utils.go | 56 - ee/reconciliation/internal/models/policy.go | 22 - .../internal/models/reconciliation.go | 35 - ee/reconciliation/internal/storage/error.go | 30 - .../internal/storage/migrations/migrations.go | 76 - ee/reconciliation/internal/storage/module.go | 33 - ee/reconciliation/internal/storage/ping.go | 5 - ee/reconciliation/internal/storage/policy.go | 133 - .../internal/storage/reconciliations.go | 100 - ee/reconciliation/internal/storage/store.go | 17 - ee/reconciliation/internal/storage/utils.go | 45 - ee/reconciliation/main.go | 7 - ee/reconciliation/openapi.yaml | 439 --- ee/reconciliation/scratch.Dockerfile | 5 - ee/wallets/.gitignore | 4 - ee/wallets/.goreleaser.yml | 37 - ee/wallets/Earthfile | 82 - ee/wallets/build.Dockerfile | 5 - ee/wallets/cmd/root.go | 29 - ee/wallets/cmd/serve.go | 101 - ee/wallets/deploy/auth/config.yaml | 5 - ee/wallets/deploy/postgres/init-databases.sh | 9 - ee/wallets/deploy/proxy/.gitignore | 1 - ee/wallets/deploy/proxy/Caddyfile | 8 - ee/wallets/go.mod | 94 - ee/wallets/go.sum | 289 -- ee/wallets/main.go | 7 - ee/wallets/openapi.yaml | 1159 ------ ee/wallets/pkg/api/handler_balances_create.go | 36 - .../pkg/api/handler_balances_create_test.go | 110 - ee/wallets/pkg/api/handler_balances_get.go | 24 - .../pkg/api/handler_balances_get_test.go | 89 - ee/wallets/pkg/api/handler_balances_list.go | 25 - .../pkg/api/handler_balances_list_test.go | 109 - ee/wallets/pkg/api/handler_holds_confirm.go | 54 - .../pkg/api/handler_holds_confirm_test.go | 255 -- ee/wallets/pkg/api/handler_holds_get.go | 17 - ee/wallets/pkg/api/handler_holds_get_test.go | 61 - ee/wallets/pkg/api/handler_holds_list.go | 24 - ee/wallets/pkg/api/handler_holds_list_test.go | 159 - ee/wallets/pkg/api/handler_holds_void.go | 29 - ee/wallets/pkg/api/handler_holds_void_test.go | 65 - .../pkg/api/handler_transactions_list.go | 22 - .../pkg/api/handler_transactions_list_test.go | 122 - ee/wallets/pkg/api/handler_wallets_create.go | 26 - .../pkg/api/handler_wallets_create_test.go | 53 - ee/wallets/pkg/api/handler_wallets_credit.go | 50 - .../pkg/api/handler_wallets_credit_test.go | 224 -- ee/wallets/pkg/api/handler_wallets_debit.go | 47 - .../pkg/api/handler_wallets_debit_test.go | 380 -- ee/wallets/pkg/api/handler_wallets_get.go | 24 - .../pkg/api/handler_wallets_get_test.go | 50 - ee/wallets/pkg/api/handler_wallets_list.go | 24 - .../pkg/api/handler_wallets_list_test.go | 194 - ee/wallets/pkg/api/handler_wallets_patch.go | 34 - .../pkg/api/handler_wallets_patch_test.go | 65 - ee/wallets/pkg/api/handler_wallets_summary.go | 17 - .../pkg/api/handler_wallets_summary_test.go | 181 - ee/wallets/pkg/api/main.go | 15 - ee/wallets/pkg/api/module.go | 21 - ee/wallets/pkg/api/router.go | 71 - ee/wallets/pkg/api/utils.go | 121 - ee/wallets/pkg/api/utils_test.go | 176 - ee/wallets/pkg/balance.go | 138 - ee/wallets/pkg/chart.go | 55 - ee/wallets/pkg/credit.go | 53 - ee/wallets/pkg/debit.go | 70 - ee/wallets/pkg/error.go | 66 - ee/wallets/pkg/hold.go | 122 - ee/wallets/pkg/ledger_interface.go | 324 -- ee/wallets/pkg/manager.go | 680 ---- ee/wallets/pkg/metadata.go | 96 - ee/wallets/pkg/module.go | 33 - ee/wallets/pkg/monetary.go | 17 - ee/wallets/pkg/numscript/cancel-hold.num | 9 - ee/wallets/pkg/numscript/confirm-hold.num | 20 - ee/wallets/pkg/numscript/credit-wallet.num | 13 - ee/wallets/pkg/numscript/debit-wallet.num | 21 - ee/wallets/pkg/scripts.go | 57 - ee/wallets/pkg/subject.go | 81 - ee/wallets/pkg/transaction.go | 25 - ee/wallets/pkg/utils.go | 5 - ee/wallets/pkg/wallet.go | 146 - ee/wallets/scratch.Dockerfile | 5 - 733 files changed, 1 insertion(+), 77625 deletions(-) delete mode 100644 components/Earthfile delete mode 100644 components/operator/.dockerignore delete mode 100644 components/operator/.earthly/configuration/.helmignore delete mode 100644 components/operator/.earthly/configuration/Chart.yaml delete mode 100644 components/operator/.earthly/configuration/templates/elasticsearch-secret.yaml delete mode 100644 components/operator/.earthly/configuration/templates/postgres-secret.yaml delete mode 100644 components/operator/.earthly/configuration/templates/settings.yaml delete mode 100644 components/operator/.earthly/configuration/templates/temporal-secret.yaml delete mode 100644 components/operator/.earthly/configuration/values.yaml delete mode 100644 components/operator/.earthly/k8s-versions.yaml delete mode 100644 components/operator/.gitignore delete mode 100644 components/operator/.goreleaser.yml delete mode 100644 components/operator/Earthfile delete mode 100644 components/operator/Makefile delete mode 100644 components/operator/PROJECT delete mode 100644 components/operator/README.md delete mode 100644 components/operator/api/formance.com/v1beta1/analytics_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/auth_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/authclient_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/benthos_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/benthosstream_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/broker_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/brokerconsumer_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/brokertopic_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/database_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/gateway_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/gatewayhttpapi_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/groupversion_info.go delete mode 100644 components/operator/api/formance.com/v1beta1/ledger_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/orchestration_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/payments_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/reconciliation_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/resourcereference_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/search_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/settings_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/shared.go delete mode 100644 components/operator/api/formance.com/v1beta1/stack_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/stargate_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/versions_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/wallets_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/webhooks_types.go delete mode 100644 components/operator/api/formance.com/v1beta1/zz_generated.deepcopy.go delete mode 100644 components/operator/build.Dockerfile delete mode 100644 components/operator/cmd/main.go delete mode 100644 components/operator/config/crd/bases/formance.com_analytics.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_authclients.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_auths.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_benthos.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_benthosstreams.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_brokerconsumers.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_brokers.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_brokertopics.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_databases.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_gatewayhttpapis.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_gateways.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_ledgers.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_orchestrations.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_payments.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_reconciliations.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_resourcereferences.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_searches.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_settings.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_stacks.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_stargates.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_versions.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_wallets.yaml delete mode 100644 components/operator/config/crd/bases/formance.com_webhooks.yaml delete mode 100644 components/operator/config/crd/kustomization.yaml delete mode 100644 components/operator/config/crd/kustomizeconfig.yaml delete mode 100644 components/operator/config/default/kustomization.yaml delete mode 100644 components/operator/config/default/manager_auth_proxy_patch.yaml delete mode 100644 components/operator/config/default/manager_config_patch.yaml delete mode 100644 components/operator/config/manager/kustomization.yaml delete mode 100644 components/operator/config/manager/manager.yaml delete mode 100644 components/operator/config/manager/manager_auth_proxy_patch.yaml delete mode 100644 components/operator/config/prometheus/kustomization.yaml delete mode 100644 components/operator/config/prometheus/monitor.yaml delete mode 100644 components/operator/config/rbac/auth_editor_role.yaml delete mode 100644 components/operator/config/rbac/auth_proxy_client_clusterrole.yaml delete mode 100644 components/operator/config/rbac/auth_proxy_role.yaml delete mode 100644 components/operator/config/rbac/auth_proxy_role_binding.yaml delete mode 100644 components/operator/config/rbac/auth_proxy_service.yaml delete mode 100644 components/operator/config/rbac/auth_viewer_role.yaml delete mode 100644 components/operator/config/rbac/authclient_editor_role.yaml delete mode 100644 components/operator/config/rbac/authclient_viewer_role.yaml delete mode 100644 components/operator/config/rbac/benthos_editor_role.yaml delete mode 100644 components/operator/config/rbac/benthos_viewer_role.yaml delete mode 100644 components/operator/config/rbac/benthosstream_editor_role.yaml delete mode 100644 components/operator/config/rbac/benthosstream_viewer_role.yaml delete mode 100644 components/operator/config/rbac/brokertopic_editor_role.yaml delete mode 100644 components/operator/config/rbac/brokertopic_viewer_role.yaml delete mode 100644 components/operator/config/rbac/database_editor_role.yaml delete mode 100644 components/operator/config/rbac/database_viewer_role.yaml delete mode 100644 components/operator/config/rbac/formance.com_analytics_editor_role.yaml delete mode 100644 components/operator/config/rbac/formance.com_analytics_viewer_role.yaml delete mode 100644 components/operator/config/rbac/formance.com_broker_editor_role.yaml delete mode 100644 components/operator/config/rbac/formance.com_broker_viewer_role.yaml delete mode 100644 components/operator/config/rbac/formance.com_brokerconsumer_editor_role.yaml delete mode 100644 components/operator/config/rbac/formance.com_brokerconsumer_viewer_role.yaml delete mode 100644 components/operator/config/rbac/formance.com_resourcereference_editor_role.yaml delete mode 100644 components/operator/config/rbac/formance.com_resourcereference_viewer_role.yaml delete mode 100644 components/operator/config/rbac/formance.com_settings_editor_role.yaml delete mode 100644 components/operator/config/rbac/formance.com_settings_viewer_role.yaml delete mode 100644 components/operator/config/rbac/formance.com_versions_editor_role.yaml delete mode 100644 components/operator/config/rbac/formance.com_versions_viewer_role.yaml delete mode 100644 components/operator/config/rbac/gateway_editor_role.yaml delete mode 100644 components/operator/config/rbac/gateway_viewer_role.yaml delete mode 100644 components/operator/config/rbac/gatewayhttpapi_editor_role.yaml delete mode 100644 components/operator/config/rbac/gatewayhttpapi_viewer_role.yaml delete mode 100644 components/operator/config/rbac/kustomization.yaml delete mode 100644 components/operator/config/rbac/leader_election_role.yaml delete mode 100644 components/operator/config/rbac/leader_election_role_binding.yaml delete mode 100644 components/operator/config/rbac/ledger_editor_role.yaml delete mode 100644 components/operator/config/rbac/ledger_viewer_role.yaml delete mode 100644 components/operator/config/rbac/orchestration_editor_role.yaml delete mode 100644 components/operator/config/rbac/orchestration_viewer_role.yaml delete mode 100644 components/operator/config/rbac/payments_editor_role.yaml delete mode 100644 components/operator/config/rbac/payments_viewer_role.yaml delete mode 100644 components/operator/config/rbac/reconciliation_editor_role.yaml delete mode 100644 components/operator/config/rbac/reconciliation_viewer_role.yaml delete mode 100644 components/operator/config/rbac/role.yaml delete mode 100644 components/operator/config/rbac/role_binding.yaml delete mode 100644 components/operator/config/rbac/search_editor_role.yaml delete mode 100644 components/operator/config/rbac/search_viewer_role.yaml delete mode 100644 components/operator/config/rbac/service_account.yaml delete mode 100644 components/operator/config/rbac/stack.formance.com_configuration_editor_role.yaml delete mode 100644 components/operator/config/rbac/stack.formance.com_configuration_viewer_role.yaml delete mode 100644 components/operator/config/rbac/stack.formance.com_stack_editor_role.yaml delete mode 100644 components/operator/config/rbac/stack.formance.com_stack_viewer_role.yaml delete mode 100644 components/operator/config/rbac/stack.formance.com_versions_editor_role.yaml delete mode 100644 components/operator/config/rbac/stack.formance.com_versions_viewer_role.yaml delete mode 100644 components/operator/config/rbac/stack_editor_role.yaml delete mode 100644 components/operator/config/rbac/stack_viewer_role.yaml delete mode 100644 components/operator/config/rbac/stargate_editor_role.yaml delete mode 100644 components/operator/config/rbac/stargate_viewer_role.yaml delete mode 100644 components/operator/config/rbac/wallet_editor_role.yaml delete mode 100644 components/operator/config/rbac/wallet_viewer_role.yaml delete mode 100644 components/operator/config/rbac/webhooks_editor_role.yaml delete mode 100644 components/operator/config/rbac/webhooks_viewer_role.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_analytics.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_auth.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_authclient.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_broker.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_brokerconfiguration.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_brokerconsumer.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_databaseconfiguration.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_elasticsearchconfiguration.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_gateway.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_ledger.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_opentelemetryconfiguration.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_orchestration.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_payments.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_reconciliation.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_registriesconfigurations.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_resourcereference.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_search.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_searchbatchingconfiguration.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_settings.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_stack.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_temporalconfiguration.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_versions.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_wallets.yaml delete mode 100644 components/operator/config/samples/formance.com_v1beta1_webhooks.yaml delete mode 100644 components/operator/config/samples/kustomization.yaml delete mode 100644 components/operator/config/webhook/manifests.yaml delete mode 100644 components/operator/crd-doc-templates/gv_details.tpl delete mode 100644 components/operator/crd-doc-templates/gv_list.tpl delete mode 100644 components/operator/crd-doc-templates/type.tpl delete mode 100644 components/operator/crd-doc-templates/type_members.tpl delete mode 100644 components/operator/docs.config.yaml delete mode 100644 components/operator/docs/01-Requirements.md delete mode 100644 components/operator/docs/02-Installation.md delete mode 100644 components/operator/docs/03-Demo deployment.md delete mode 100644 components/operator/docs/04-Modules/01-Stack.md delete mode 100644 components/operator/docs/04-Modules/02-Gateway.md delete mode 100644 components/operator/docs/04-Modules/03-Ledger.md delete mode 100644 components/operator/docs/04-Modules/04-Payments.md delete mode 100644 components/operator/docs/04-Modules/05-Auth.md delete mode 100644 components/operator/docs/04-Modules/06-Orchestration.md delete mode 100644 components/operator/docs/04-Modules/07-Search.md delete mode 100644 components/operator/docs/04-Modules/08-Reconciliation.md delete mode 100644 components/operator/docs/04-Modules/09-Wallets.md delete mode 100644 components/operator/docs/04-Modules/10-Webhooks.md delete mode 100644 components/operator/docs/05-Infrastructure services/01-PostgreSQL.md delete mode 100644 components/operator/docs/05-Infrastructure services/02-Message broker.md delete mode 100644 components/operator/docs/05-Infrastructure services/03-Elasticsearch.md delete mode 100644 components/operator/docs/05-Infrastructure services/04-Temporal.md delete mode 100644 components/operator/docs/06-Observability/01-Configure OpenTelemetry.md delete mode 100644 components/operator/docs/07-Upgrade/01-Upgrade from the operator.md delete mode 100644 components/operator/docs/07-Upgrade/02-Database update.md delete mode 100644 components/operator/docs/08-Troubleshooting.md delete mode 100644 components/operator/docs/09-Configuration reference/01-Settings.md delete mode 100644 components/operator/docs/09-Configuration reference/02-Custom Resource Definitions.md delete mode 100644 components/operator/go.mod delete mode 100644 components/operator/go.sum delete mode 100644 components/operator/hack/boilerplate.go.txt delete mode 100644 components/operator/helm/crds/.helmignore delete mode 100644 components/operator/helm/crds/Chart.yaml delete mode 100644 components/operator/helm/crds/README.md delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_analytics.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_authclients.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_auths.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_benthos.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_benthosstreams.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_brokerconsumers.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_brokers.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_brokertopics.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_databases.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_gatewayhttpapis.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_gateways.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_ledgers.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_orchestrations.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_payments.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_reconciliations.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_resourcereferences.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_searches.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_settings.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_stacks.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_stargates.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_versions.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_wallets.formance.com.yaml delete mode 100644 components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_webhooks.formance.com.yaml delete mode 100644 components/operator/helm/crds/values.yaml delete mode 100644 components/operator/helm/operator/.helmignore delete mode 100644 components/operator/helm/operator/Chart.lock delete mode 100644 components/operator/helm/operator/Chart.yaml delete mode 100644 components/operator/helm/operator/README.md delete mode 100644 components/operator/helm/operator/templates/_helpers.tpl delete mode 100644 components/operator/helm/operator/templates/deployment.yaml delete mode 100644 components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-manager-role.yaml delete mode 100644 components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-metrics-reader.yaml delete mode 100644 components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-proxy-role.yaml delete mode 100644 components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrolebinding_formance-manager-rolebinding.yaml delete mode 100644 components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrolebinding_formance-proxy-rolebinding.yaml delete mode 100644 components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_role_formance-leader-election-role.yaml delete mode 100644 components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_rolebinding_formance-leader-election-rolebinding.yaml delete mode 100644 components/operator/helm/operator/templates/gen/v1_service_formance-controller-manager-metrics-service.yaml delete mode 100644 components/operator/helm/operator/templates/gen/v1_serviceaccount_formance-controller-manager.yaml delete mode 100644 components/operator/helm/operator/templates/licence-secret.yaml delete mode 100644 components/operator/helm/operator/values.yaml delete mode 100644 components/operator/internal/core/context.go delete mode 100644 components/operator/internal/core/controllers.go delete mode 100644 components/operator/internal/core/env.go delete mode 100644 components/operator/internal/core/errors.go delete mode 100644 components/operator/internal/core/manager.go delete mode 100644 components/operator/internal/core/module.go delete mode 100644 components/operator/internal/core/names.go delete mode 100644 components/operator/internal/core/ns.go delete mode 100644 components/operator/internal/core/platform.go delete mode 100644 components/operator/internal/core/publisher.go delete mode 100644 components/operator/internal/core/reconciler.go delete mode 100644 components/operator/internal/core/setup.go delete mode 100644 components/operator/internal/core/shell.go delete mode 100644 components/operator/internal/core/stacks.go delete mode 100644 components/operator/internal/core/utils.go delete mode 100644 components/operator/internal/core/version.go delete mode 100644 components/operator/internal/core/volumes.go delete mode 100644 components/operator/internal/core/watch.go delete mode 100644 components/operator/internal/resources/all.go delete mode 100644 components/operator/internal/resources/analytics/init.go delete mode 100644 components/operator/internal/resources/applications/application.go delete mode 100644 components/operator/internal/resources/applications/liveness.go delete mode 100644 components/operator/internal/resources/applications/ports.go delete mode 100644 components/operator/internal/resources/authclients/create.go delete mode 100644 components/operator/internal/resources/authclients/init.go delete mode 100644 components/operator/internal/resources/auths/configuration.go delete mode 100644 components/operator/internal/resources/auths/deployment.go delete mode 100644 components/operator/internal/resources/auths/env.go delete mode 100644 components/operator/internal/resources/auths/init.go delete mode 100644 components/operator/internal/resources/benthos/controller.go delete mode 100644 components/operator/internal/resources/benthos/init.go delete mode 100644 components/operator/internal/resources/benthosstreams/create.go delete mode 100644 components/operator/internal/resources/benthosstreams/init.go delete mode 100644 components/operator/internal/resources/brokerconsumers/controller.go delete mode 100644 components/operator/internal/resources/brokerconsumers/create.go delete mode 100644 components/operator/internal/resources/brokerconsumers/init.go delete mode 100644 components/operator/internal/resources/brokers/init.go delete mode 100644 components/operator/internal/resources/brokers/reconcile.go delete mode 100644 components/operator/internal/resources/brokers/utils.go delete mode 100644 components/operator/internal/resources/brokers/watch.go delete mode 100644 components/operator/internal/resources/brokertopics/brokertopics.go delete mode 100644 components/operator/internal/resources/brokertopics/controller.go delete mode 100644 components/operator/internal/resources/brokertopics/init.go delete mode 100644 components/operator/internal/resources/brokertopics/watch.go delete mode 100644 components/operator/internal/resources/caddy/caddy.go delete mode 100644 components/operator/internal/resources/databases/create.go delete mode 100644 components/operator/internal/resources/databases/env.go delete mode 100644 components/operator/internal/resources/databases/init.go delete mode 100644 components/operator/internal/resources/databases/migrate.go delete mode 100644 components/operator/internal/resources/databases/watch.go delete mode 100644 components/operator/internal/resources/gatewayhttpapis/create.go delete mode 100644 components/operator/internal/resources/gatewayhttpapis/init.go delete mode 100644 components/operator/internal/resources/gateways/Caddyfile.gotpl delete mode 100644 components/operator/internal/resources/gateways/caddyfile.go delete mode 100644 components/operator/internal/resources/gateways/configuration.go delete mode 100644 components/operator/internal/resources/gateways/deployment.go delete mode 100644 components/operator/internal/resources/gateways/gateways.go delete mode 100644 components/operator/internal/resources/gateways/ingress.go delete mode 100644 components/operator/internal/resources/gateways/init.go delete mode 100644 components/operator/internal/resources/gateways/url.go delete mode 100644 components/operator/internal/resources/jobs/job.go delete mode 100644 components/operator/internal/resources/ledgers/assets.go delete mode 100644 components/operator/internal/resources/ledgers/assets/Caddyfile.gotpl delete mode 100644 components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex.yaml delete mode 100644 components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_accounts.yaml delete mode 100644 components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_all.yaml delete mode 100644 components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_transactions.yaml delete mode 100644 components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_volumes.yaml delete mode 100644 components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex.yaml delete mode 100644 components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex_accounts.yaml delete mode 100644 components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex_all.yaml delete mode 100644 components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex_transactions.yaml delete mode 100644 components/operator/internal/resources/ledgers/deployments.go delete mode 100644 components/operator/internal/resources/ledgers/init.go delete mode 100644 components/operator/internal/resources/ledgers/reindex.go delete mode 100644 components/operator/internal/resources/licence/licence.go delete mode 100644 components/operator/internal/resources/orchestrations/deployments.go delete mode 100644 components/operator/internal/resources/orchestrations/init.go delete mode 100644 components/operator/internal/resources/payments/Caddyfile.gotpl delete mode 100644 components/operator/internal/resources/payments/deployments.go delete mode 100644 components/operator/internal/resources/payments/init.go delete mode 100644 components/operator/internal/resources/payments/payments.go delete mode 100644 components/operator/internal/resources/reconciliations/deployments.go delete mode 100644 components/operator/internal/resources/reconciliations/init.go delete mode 100644 components/operator/internal/resources/registries/image.go delete mode 100644 components/operator/internal/resources/registries/registries.go delete mode 100644 components/operator/internal/resources/registries/registries_generated.go delete mode 100644 components/operator/internal/resources/registries/registries_test.go delete mode 100644 components/operator/internal/resources/resourcereferences/create.go delete mode 100644 components/operator/internal/resources/resourcereferences/init.go delete mode 100644 components/operator/internal/resources/searches/benthos/audit/gateway_audit.yaml delete mode 100644 components/operator/internal/resources/searches/benthos/fs.go delete mode 100644 components/operator/internal/resources/searches/benthos/global/config.yaml delete mode 100644 components/operator/internal/resources/searches/clean_legacy_consumers.go delete mode 100644 components/operator/internal/resources/searches/init.go delete mode 100644 components/operator/internal/resources/services/services.go delete mode 100644 components/operator/internal/resources/settings/aws_role.go delete mode 100644 components/operator/internal/resources/settings/helpers.go delete mode 100644 components/operator/internal/resources/settings/helpers_test.go delete mode 100644 components/operator/internal/resources/settings/opentelemetry.go delete mode 100644 components/operator/internal/resources/settings/resourcerequirements.go delete mode 100644 components/operator/internal/resources/settings/settings.go delete mode 100644 components/operator/internal/resources/stacks/init.go delete mode 100644 components/operator/internal/resources/stargates/deployment.go delete mode 100644 components/operator/internal/resources/stargates/init.go delete mode 100644 components/operator/internal/resources/wallets/deployment.go delete mode 100644 components/operator/internal/resources/wallets/init.go delete mode 100644 components/operator/internal/resources/webhooks/deployment.go delete mode 100644 components/operator/internal/resources/webhooks/init.go delete mode 100644 components/operator/internal/tests/auth_controller_test.go delete mode 100644 components/operator/internal/tests/authclient_controller_test.go delete mode 100644 components/operator/internal/tests/benthos_controller_test.go delete mode 100644 components/operator/internal/tests/benthosstream_controller_test.go delete mode 100644 components/operator/internal/tests/brokerconsumer_controller_test.go delete mode 100644 components/operator/internal/tests/brokertopic_controller_test.go delete mode 100644 components/operator/internal/tests/database_controller_test.go delete mode 100644 components/operator/internal/tests/gateway_controller_test.go delete mode 100644 components/operator/internal/tests/gatewayhttpapi_controller_test.go delete mode 100644 components/operator/internal/tests/internal/bootstrap.go delete mode 100644 components/operator/internal/tests/internal/errors.go delete mode 100644 components/operator/internal/tests/internal/matcher_be_controlled_by.go delete mode 100644 components/operator/internal/tests/internal/matcher_be_not_found.go delete mode 100644 components/operator/internal/tests/internal/matcher_be_owned_by.go delete mode 100644 components/operator/internal/tests/internal/matcher_be_ready.go delete mode 100644 components/operator/internal/tests/internal/matcher_match_golden_file.go delete mode 100644 components/operator/internal/tests/internal/matcher_target_deployment.go delete mode 100644 components/operator/internal/tests/internal/utils.go delete mode 100644 components/operator/internal/tests/ledger_controller_test.go delete mode 100644 components/operator/internal/tests/orchestration_controller_test.go delete mode 100644 components/operator/internal/tests/payments_controller_test.go delete mode 100644 components/operator/internal/tests/registries_test.go delete mode 100644 components/operator/internal/tests/resourcereferences_controller_test.go delete mode 100644 components/operator/internal/tests/searches_controller_test.go delete mode 100644 components/operator/internal/tests/settings_controller_test.go delete mode 100644 components/operator/internal/tests/stack_controller_test.go delete mode 100644 components/operator/internal/tests/stargate_controller_test.go delete mode 100644 components/operator/internal/tests/suite_test.go delete mode 100644 components/operator/internal/tests/testdata/resources/auth-controller/config-with-auth-client.yaml delete mode 100644 components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-audit.yaml delete mode 100644 components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-ledger-and-another-service.yaml delete mode 100644 components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-ledger-only.yaml delete mode 100644 components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-opentelemetry.yaml delete mode 100644 components/operator/internal/tests/wallets_controller_test.go delete mode 100644 components/operator/pkg/client/formance.com/v1beta1/auth.go delete mode 100644 components/operator/pkg/client/formance.com/v1beta1/client.go delete mode 100644 components/operator/pkg/client/formance.com/v1beta1/gateway.go delete mode 100644 components/operator/pkg/client/formance.com/v1beta1/ledger.go delete mode 100644 components/operator/pkg/client/formance.com/v1beta1/orchestration.go delete mode 100644 components/operator/pkg/client/formance.com/v1beta1/payments.go delete mode 100644 components/operator/pkg/client/formance.com/v1beta1/reconciliation.go delete mode 100644 components/operator/pkg/client/formance.com/v1beta1/search.go delete mode 100644 components/operator/pkg/client/formance.com/v1beta1/stack.go delete mode 100644 components/operator/pkg/client/formance.com/v1beta1/versions.go delete mode 100644 components/operator/pkg/client/formance.com/v1beta1/wallets.go delete mode 100644 components/operator/pkg/client/formance.com/v1beta1/webhooks.go delete mode 100644 components/operator/scratch.Dockerfile delete mode 100644 components/operator/tools/kubectl-stacks/Earthfile delete mode 100644 components/operator/tools/kubectl-stacks/disable.go delete mode 100644 components/operator/tools/kubectl-stacks/enable.go delete mode 100644 components/operator/tools/kubectl-stacks/go.mod delete mode 100644 components/operator/tools/kubectl-stacks/go.sum delete mode 100644 components/operator/tools/kubectl-stacks/list.go delete mode 100644 components/operator/tools/kubectl-stacks/lock.go delete mode 100644 components/operator/tools/kubectl-stacks/main.go delete mode 100644 components/operator/tools/kubectl-stacks/set-debug.go delete mode 100644 components/operator/tools/kubectl-stacks/settings.go delete mode 100644 components/operator/tools/kubectl-stacks/unlock.go delete mode 100644 components/operator/tools/kubectl-stacks/upgrade.go delete mode 100644 components/operator/tools/utils/.goreleaser.yml delete mode 100644 components/operator/tools/utils/Earthfile delete mode 100644 components/operator/tools/utils/LICENSE delete mode 100644 components/operator/tools/utils/build.Dockerfile delete mode 100644 components/operator/tools/utils/cmd/database-create.go delete mode 100644 components/operator/tools/utils/cmd/database-drop.go delete mode 100644 components/operator/tools/utils/cmd/database.go delete mode 100644 components/operator/tools/utils/cmd/root.go delete mode 100644 components/operator/tools/utils/go.mod delete mode 100644 components/operator/tools/utils/go.sum delete mode 100644 components/operator/tools/utils/main.go delete mode 100644 components/operator/tools/utils/scratch.Dockerfile delete mode 100644 ee/Earthfile delete mode 100644 ee/LICENSE delete mode 100644 ee/agent/.earthly/values.yaml delete mode 100644 ee/agent/.goreleaser.yml delete mode 100644 ee/agent/Earthfile delete mode 100644 ee/agent/Taskfile.yaml delete mode 100644 ee/agent/agent.proto delete mode 100644 ee/agent/build.Dockerfile delete mode 100644 ee/agent/cmd/root.go delete mode 100644 ee/agent/cmd/version.go delete mode 100644 ee/agent/go.mod delete mode 100644 ee/agent/go.sum delete mode 100644 ee/agent/helm/.gitignore delete mode 100644 ee/agent/helm/.helmignore delete mode 100644 ee/agent/helm/Chart.yaml delete mode 100644 ee/agent/helm/README.md delete mode 100644 ee/agent/helm/templates/_helpers.tpl delete mode 100644 ee/agent/helm/templates/clusterrole.yaml delete mode 100644 ee/agent/helm/templates/clusterrolebinding.yaml delete mode 100644 ee/agent/helm/templates/deployment.yaml delete mode 100644 ee/agent/helm/templates/serviceaccount.yaml delete mode 100644 ee/agent/helm/values.yaml delete mode 100644 ee/agent/internal/authenticator.go delete mode 100644 ee/agent/internal/generated/agent.pb.go delete mode 100644 ee/agent/internal/generated/agent_grpc.pb.go delete mode 100644 ee/agent/internal/informer_modules.go delete mode 100644 ee/agent/internal/informer_modules_test.go delete mode 100644 ee/agent/internal/informer_stacks.go delete mode 100644 ee/agent/internal/informer_stacks_test.go delete mode 100644 ee/agent/internal/informer_versions.go delete mode 100644 ee/agent/internal/k8s_client.go delete mode 100644 ee/agent/internal/k8s_client_test.go delete mode 100644 ee/agent/internal/membership_client.go delete mode 100644 ee/agent/internal/membership_client_generated.go delete mode 100644 ee/agent/internal/membership_listener.go delete mode 100644 ee/agent/internal/membership_listener_test.go delete mode 100644 ee/agent/internal/module.go delete mode 100644 ee/agent/internal/utils.go delete mode 100644 ee/agent/main.go delete mode 100644 ee/agent/scratch.Dockerfile delete mode 100644 ee/agent/tests/informer_stacks_test.go delete mode 100644 ee/agent/tests/informers_modules_test.go delete mode 100644 ee/agent/tests/internal/matcher_be_owned_by.go delete mode 100644 ee/agent/tests/internal/matcher_target_stack.go delete mode 100644 ee/agent/tests/main_test.go delete mode 100644 ee/agent/tests/membership_listener_test.go delete mode 100644 ee/orchestration/.gitignore delete mode 100644 ee/orchestration/.goreleaser.yml delete mode 100644 ee/orchestration/Earthfile delete mode 100644 ee/orchestration/build.Dockerfile delete mode 100644 ee/orchestration/cmd/root.go delete mode 100644 ee/orchestration/cmd/serve.go delete mode 100644 ee/orchestration/cmd/version.go delete mode 100644 ee/orchestration/cmd/worker.go delete mode 100644 ee/orchestration/deploy/auth/config.yaml delete mode 100755 ee/orchestration/deploy/postgres/init-databases.sh delete mode 100644 ee/orchestration/deploy/proxy/.gitignore delete mode 100644 ee/orchestration/deploy/proxy/Caddyfile delete mode 100644 ee/orchestration/examples/delay.yaml delete mode 100644 ee/orchestration/examples/failing-workflow.yaml delete mode 100644 ee/orchestration/examples/ledger-to-ledger.yaml delete mode 100644 ee/orchestration/examples/ledger-to-wallet.yaml delete mode 100644 ee/orchestration/examples/payin-to-wallet.yaml delete mode 100644 ee/orchestration/examples/update-account-metadata.yaml delete mode 100644 ee/orchestration/examples/wait_event.yaml delete mode 100644 ee/orchestration/examples/wallet-to-payout.yaml delete mode 100644 ee/orchestration/examples/workflow.yaml delete mode 100644 ee/orchestration/go.mod delete mode 100644 ee/orchestration/go.sum delete mode 100644 ee/orchestration/internal/api/backend.go delete mode 100644 ee/orchestration/internal/api/backend_generated.go delete mode 100644 ee/orchestration/internal/api/handler_info.go delete mode 100644 ee/orchestration/internal/api/module.go delete mode 100644 ee/orchestration/internal/api/module_test.go delete mode 100644 ee/orchestration/internal/api/router.go delete mode 100644 ee/orchestration/internal/api/v1/handler_abort_workflow_instance.go delete mode 100644 ee/orchestration/internal/api/v1/handler_create_trigger.go delete mode 100644 ee/orchestration/internal/api/v1/handler_create_trigger_test.go delete mode 100644 ee/orchestration/internal/api/v1/handler_create_workflow.go delete mode 100644 ee/orchestration/internal/api/v1/handler_create_workflow_test.go delete mode 100644 ee/orchestration/internal/api/v1/handler_delete_trigger.go delete mode 100644 ee/orchestration/internal/api/v1/handler_delete_workflow.go delete mode 100644 ee/orchestration/internal/api/v1/handler_delete_workflow_test.go delete mode 100644 ee/orchestration/internal/api/v1/handler_get_trigger.go delete mode 100644 ee/orchestration/internal/api/v1/handler_list_instances.go delete mode 100644 ee/orchestration/internal/api/v1/handler_list_instances_test.go delete mode 100644 ee/orchestration/internal/api/v1/handler_list_triggers.go delete mode 100644 ee/orchestration/internal/api/v1/handler_list_triggers_occurrences.go delete mode 100644 ee/orchestration/internal/api/v1/handler_list_workflows.go delete mode 100644 ee/orchestration/internal/api/v1/handler_post_event.go delete mode 100644 ee/orchestration/internal/api/v1/handler_read_instance.go delete mode 100644 ee/orchestration/internal/api/v1/handler_read_instance_history.go delete mode 100644 ee/orchestration/internal/api/v1/handler_read_instance_test.go delete mode 100644 ee/orchestration/internal/api/v1/handler_read_stage_history.go delete mode 100644 ee/orchestration/internal/api/v1/handler_read_workflow.go delete mode 100644 ee/orchestration/internal/api/v1/handler_run_workflow.go delete mode 100644 ee/orchestration/internal/api/v1/handler_run_workflow_test.go delete mode 100644 ee/orchestration/internal/api/v1/main_test.go delete mode 100644 ee/orchestration/internal/api/v1/module.go delete mode 100644 ee/orchestration/internal/api/v1/router.go delete mode 100644 ee/orchestration/internal/api/v2/handler_abort_workflow_instance.go delete mode 100644 ee/orchestration/internal/api/v2/handler_create_trigger.go delete mode 100644 ee/orchestration/internal/api/v2/handler_create_trigger_test.go delete mode 100644 ee/orchestration/internal/api/v2/handler_create_workflow.go delete mode 100644 ee/orchestration/internal/api/v2/handler_create_workflow_test.go delete mode 100644 ee/orchestration/internal/api/v2/handler_delete_trigger.go delete mode 100644 ee/orchestration/internal/api/v2/handler_delete_workflow.go delete mode 100644 ee/orchestration/internal/api/v2/handler_delete_workflow_test.go delete mode 100644 ee/orchestration/internal/api/v2/handler_get_trigger.go delete mode 100644 ee/orchestration/internal/api/v2/handler_list_instances.go delete mode 100644 ee/orchestration/internal/api/v2/handler_list_instances_test.go delete mode 100644 ee/orchestration/internal/api/v2/handler_list_triggers.go delete mode 100644 ee/orchestration/internal/api/v2/handler_list_triggers_occurrences.go delete mode 100644 ee/orchestration/internal/api/v2/handler_list_workflows.go delete mode 100644 ee/orchestration/internal/api/v2/handler_post_event.go delete mode 100644 ee/orchestration/internal/api/v2/handler_read_instance.go delete mode 100644 ee/orchestration/internal/api/v2/handler_read_instance_history.go delete mode 100644 ee/orchestration/internal/api/v2/handler_read_instance_test.go delete mode 100644 ee/orchestration/internal/api/v2/handler_read_stage_history.go delete mode 100644 ee/orchestration/internal/api/v2/handler_read_workflow.go delete mode 100644 ee/orchestration/internal/api/v2/handler_run_workflow.go delete mode 100644 ee/orchestration/internal/api/v2/handler_run_workflow_test.go delete mode 100644 ee/orchestration/internal/api/v2/handler_test_trigger.go delete mode 100644 ee/orchestration/internal/api/v2/handler_test_trigger_test.go delete mode 100644 ee/orchestration/internal/api/v2/main_test.go delete mode 100644 ee/orchestration/internal/api/v2/module.go delete mode 100644 ee/orchestration/internal/api/v2/router.go delete mode 100644 ee/orchestration/internal/schema/duration.go delete mode 100644 ee/orchestration/internal/schema/map.go delete mode 100644 ee/orchestration/internal/schema/tag.go delete mode 100644 ee/orchestration/internal/schema/validation.go delete mode 100644 ee/orchestration/internal/storage/main_test.go delete mode 100644 ee/orchestration/internal/storage/migrations.go delete mode 100644 ee/orchestration/internal/storage/migrations_test.go delete mode 100644 ee/orchestration/internal/temporalclient/client_module.go delete mode 100644 ee/orchestration/internal/temporalclient/logger.go delete mode 100644 ee/orchestration/internal/temporalworker/module.go delete mode 100644 ee/orchestration/internal/triggers/activities.go delete mode 100644 ee/orchestration/internal/triggers/expression.go delete mode 100644 ee/orchestration/internal/triggers/listener.go delete mode 100644 ee/orchestration/internal/triggers/main_test.go delete mode 100644 ee/orchestration/internal/triggers/manager.go delete mode 100644 ee/orchestration/internal/triggers/module.go delete mode 100644 ee/orchestration/internal/triggers/trigger.go delete mode 100644 ee/orchestration/internal/triggers/trigger_test.go delete mode 100644 ee/orchestration/internal/triggers/workflow_trigger.go delete mode 100644 ee/orchestration/internal/triggers/workflow_trigger_test.go delete mode 100644 ee/orchestration/internal/workflow/activities.go delete mode 100644 ee/orchestration/internal/workflow/activities/activity.go delete mode 100644 ee/orchestration/internal/workflow/activities/activity_account_get.go delete mode 100644 ee/orchestration/internal/workflow/activities/activity_ledger_add_account_metadata.go delete mode 100644 ee/orchestration/internal/workflow/activities/activity_ledger_create_transaction.go delete mode 100644 ee/orchestration/internal/workflow/activities/activity_payment_stripe_transfer.go delete mode 100644 ee/orchestration/internal/workflow/activities/activity_payments_get.go delete mode 100644 ee/orchestration/internal/workflow/activities/activity_wallet_confirm_hold.go delete mode 100644 ee/orchestration/internal/workflow/activities/activity_wallet_credit.go delete mode 100644 ee/orchestration/internal/workflow/activities/activity_wallet_debit.go delete mode 100644 ee/orchestration/internal/workflow/activities/activity_wallet_get.go delete mode 100644 ee/orchestration/internal/workflow/activities/activity_wallet_list.go delete mode 100644 ee/orchestration/internal/workflow/activities/activity_wallet_void_hold.go delete mode 100644 ee/orchestration/internal/workflow/activities_test.go delete mode 100644 ee/orchestration/internal/workflow/config.go delete mode 100644 ee/orchestration/internal/workflow/input.go delete mode 100644 ee/orchestration/internal/workflow/instance.go delete mode 100644 ee/orchestration/internal/workflow/main_test.go delete mode 100644 ee/orchestration/internal/workflow/manager.go delete mode 100644 ee/orchestration/internal/workflow/manager_test.go delete mode 100644 ee/orchestration/internal/workflow/module.go delete mode 100644 ee/orchestration/internal/workflow/run.go delete mode 100644 ee/orchestration/internal/workflow/stage.go delete mode 100644 ee/orchestration/internal/workflow/stages/all/all.go delete mode 100644 ee/orchestration/internal/workflow/stages/delay/delay.go delete mode 100644 ee/orchestration/internal/workflow/stages/delay/run.go delete mode 100644 ee/orchestration/internal/workflow/stages/delay/run_test.go delete mode 100644 ee/orchestration/internal/workflow/stages/internal/context.go delete mode 100644 ee/orchestration/internal/workflow/stages/internal/stagestesting/schema.go delete mode 100644 ee/orchestration/internal/workflow/stages/internal/stagestesting/workflow.go delete mode 100644 ee/orchestration/internal/workflow/stages/noop.go delete mode 100644 ee/orchestration/internal/workflow/stages/schema.go delete mode 100644 ee/orchestration/internal/workflow/stages/send/run.go delete mode 100644 ee/orchestration/internal/workflow/stages/send/run_test.go delete mode 100644 ee/orchestration/internal/workflow/stages/send/send.go delete mode 100644 ee/orchestration/internal/workflow/stages/update/run.go delete mode 100644 ee/orchestration/internal/workflow/stages/update/run_test.go delete mode 100644 ee/orchestration/internal/workflow/stages/update/update.go delete mode 100644 ee/orchestration/internal/workflow/stages/wait_event/run.go delete mode 100644 ee/orchestration/internal/workflow/stages/wait_event/wait_event.go delete mode 100644 ee/orchestration/internal/workflow/stages/wait_event/wait_event_test.go delete mode 100644 ee/orchestration/internal/workflow/tracer.go delete mode 100644 ee/orchestration/internal/workflow/workflow.go delete mode 100644 ee/orchestration/main.go delete mode 100644 ee/orchestration/openapi.yaml delete mode 100644 ee/orchestration/openapi/openapi-merge.json delete mode 100644 ee/orchestration/openapi/v1.yaml delete mode 100644 ee/orchestration/openapi/v2.yaml delete mode 100644 ee/orchestration/pkg/.gitkeep delete mode 100644 ee/orchestration/pkg/events/events.go delete mode 100644 ee/orchestration/scratch.Dockerfile delete mode 100644 ee/reconciliation/.gitignore delete mode 100644 ee/reconciliation/.goreleaser.yml delete mode 100644 ee/reconciliation/Earthfile delete mode 100644 ee/reconciliation/README.md delete mode 100644 ee/reconciliation/build.Dockerfile delete mode 100644 ee/reconciliation/cmd/migrate.go delete mode 100644 ee/reconciliation/cmd/root.go delete mode 100644 ee/reconciliation/cmd/serve.go delete mode 100644 ee/reconciliation/cmd/version.go delete mode 100644 ee/reconciliation/go.mod delete mode 100644 ee/reconciliation/go.sum delete mode 100644 ee/reconciliation/internal/api/api_utils_test.go delete mode 100644 ee/reconciliation/internal/api/backend/backend.go delete mode 100644 ee/reconciliation/internal/api/backend/backend_generated.go delete mode 100644 ee/reconciliation/internal/api/module.go delete mode 100644 ee/reconciliation/internal/api/policy.go delete mode 100644 ee/reconciliation/internal/api/policy_test.go delete mode 100644 ee/reconciliation/internal/api/query.go delete mode 100644 ee/reconciliation/internal/api/reconciliation.go delete mode 100644 ee/reconciliation/internal/api/reconciliation_test.go delete mode 100644 ee/reconciliation/internal/api/router.go delete mode 100644 ee/reconciliation/internal/api/service/errors.go delete mode 100644 ee/reconciliation/internal/api/service/policy.go delete mode 100644 ee/reconciliation/internal/api/service/reconciliation.go delete mode 100644 ee/reconciliation/internal/api/service/reconciliation_test.go delete mode 100644 ee/reconciliation/internal/api/service/service.go delete mode 100644 ee/reconciliation/internal/api/service/service_test.go delete mode 100644 ee/reconciliation/internal/api/service/utils.go delete mode 100644 ee/reconciliation/internal/api/service/utils_test.go delete mode 100644 ee/reconciliation/internal/api/utils.go delete mode 100644 ee/reconciliation/internal/models/policy.go delete mode 100644 ee/reconciliation/internal/models/reconciliation.go delete mode 100644 ee/reconciliation/internal/storage/error.go delete mode 100644 ee/reconciliation/internal/storage/migrations/migrations.go delete mode 100644 ee/reconciliation/internal/storage/module.go delete mode 100644 ee/reconciliation/internal/storage/ping.go delete mode 100644 ee/reconciliation/internal/storage/policy.go delete mode 100644 ee/reconciliation/internal/storage/reconciliations.go delete mode 100644 ee/reconciliation/internal/storage/store.go delete mode 100644 ee/reconciliation/internal/storage/utils.go delete mode 100644 ee/reconciliation/main.go delete mode 100644 ee/reconciliation/openapi.yaml delete mode 100644 ee/reconciliation/scratch.Dockerfile delete mode 100644 ee/wallets/.gitignore delete mode 100644 ee/wallets/.goreleaser.yml delete mode 100644 ee/wallets/Earthfile delete mode 100644 ee/wallets/build.Dockerfile delete mode 100644 ee/wallets/cmd/root.go delete mode 100644 ee/wallets/cmd/serve.go delete mode 100644 ee/wallets/deploy/auth/config.yaml delete mode 100755 ee/wallets/deploy/postgres/init-databases.sh delete mode 100644 ee/wallets/deploy/proxy/.gitignore delete mode 100644 ee/wallets/deploy/proxy/Caddyfile delete mode 100644 ee/wallets/go.mod delete mode 100644 ee/wallets/go.sum delete mode 100644 ee/wallets/main.go delete mode 100644 ee/wallets/openapi.yaml delete mode 100644 ee/wallets/pkg/api/handler_balances_create.go delete mode 100644 ee/wallets/pkg/api/handler_balances_create_test.go delete mode 100644 ee/wallets/pkg/api/handler_balances_get.go delete mode 100644 ee/wallets/pkg/api/handler_balances_get_test.go delete mode 100644 ee/wallets/pkg/api/handler_balances_list.go delete mode 100644 ee/wallets/pkg/api/handler_balances_list_test.go delete mode 100644 ee/wallets/pkg/api/handler_holds_confirm.go delete mode 100644 ee/wallets/pkg/api/handler_holds_confirm_test.go delete mode 100644 ee/wallets/pkg/api/handler_holds_get.go delete mode 100644 ee/wallets/pkg/api/handler_holds_get_test.go delete mode 100644 ee/wallets/pkg/api/handler_holds_list.go delete mode 100644 ee/wallets/pkg/api/handler_holds_list_test.go delete mode 100644 ee/wallets/pkg/api/handler_holds_void.go delete mode 100644 ee/wallets/pkg/api/handler_holds_void_test.go delete mode 100644 ee/wallets/pkg/api/handler_transactions_list.go delete mode 100644 ee/wallets/pkg/api/handler_transactions_list_test.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_create.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_create_test.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_credit.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_credit_test.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_debit.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_debit_test.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_get.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_get_test.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_list.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_list_test.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_patch.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_patch_test.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_summary.go delete mode 100644 ee/wallets/pkg/api/handler_wallets_summary_test.go delete mode 100644 ee/wallets/pkg/api/main.go delete mode 100644 ee/wallets/pkg/api/module.go delete mode 100644 ee/wallets/pkg/api/router.go delete mode 100644 ee/wallets/pkg/api/utils.go delete mode 100644 ee/wallets/pkg/api/utils_test.go delete mode 100644 ee/wallets/pkg/balance.go delete mode 100644 ee/wallets/pkg/chart.go delete mode 100644 ee/wallets/pkg/credit.go delete mode 100644 ee/wallets/pkg/debit.go delete mode 100644 ee/wallets/pkg/error.go delete mode 100644 ee/wallets/pkg/hold.go delete mode 100644 ee/wallets/pkg/ledger_interface.go delete mode 100644 ee/wallets/pkg/manager.go delete mode 100644 ee/wallets/pkg/metadata.go delete mode 100644 ee/wallets/pkg/module.go delete mode 100644 ee/wallets/pkg/monetary.go delete mode 100644 ee/wallets/pkg/numscript/cancel-hold.num delete mode 100644 ee/wallets/pkg/numscript/confirm-hold.num delete mode 100644 ee/wallets/pkg/numscript/credit-wallet.num delete mode 100644 ee/wallets/pkg/numscript/debit-wallet.num delete mode 100644 ee/wallets/pkg/scripts.go delete mode 100644 ee/wallets/pkg/subject.go delete mode 100644 ee/wallets/pkg/transaction.go delete mode 100644 ee/wallets/pkg/utils.go delete mode 100644 ee/wallets/pkg/wallet.go delete mode 100644 ee/wallets/scratch.Dockerfile diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 620bffb04f..3be665e6ca 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -40,26 +40,6 @@ jobs: exit 1 fi - Tests: - runs-on: "formance-runner" - needs: - - Dirty - steps: - - uses: 'actions/checkout@v4' - with: - fetch-depth: 0 - - name: Setup Env - uses: ./.github/actions/env - - run: > - earthly - --no-output - --allow-privileged - --secret SPEAKEASY_API_KEY=$SPEAKEASY_API_KEY - ${{ contains(github.event.pull_request.labels.*.name, 'no-cache') && '--no-cache' || '' }} - +tests - env: - SPEAKEASY_API_KEY: ${{ secrets.SPEAKEASY_API_KEY }} - TestsIntegration: runs-on: "formance-runner" needs: @@ -78,112 +58,4 @@ jobs: ${{ contains(github.event.pull_request.labels.*.name, 'no-cache') && '--no-cache' || '' }} +tests-integration env: - SPEAKEASY_API_KEY: ${{ secrets.SPEAKEASY_API_KEY }} - - Extract: - name: Extract - runs-on: "ubuntu-latest" - outputs: - components: ${{ steps.extract.outputs.components }} - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: actions/setup-node@v4 - with: - node-version: 18 - - name: Extract service name - id: extract - run: echo "components=$(node .github/actions/find-directory/index.js)" >> $GITHUB_OUTPUT - - GoReleaser: - runs-on: "ubuntu-latest" - if: contains(github.event.pull_request.labels.*.name, 'build-images') || github.ref == 'refs/heads/main' || github.event_name == 'merge_group' - needs: - - Extract - strategy: - matrix: - components: ${{ fromJson(needs.Extract.outputs.components) }} - steps: - - uses: earthly/actions-setup@v1 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - version: "latest" - - uses: 'actions/checkout@v4' - with: - fetch-depth: 0 - - name: Setup Env - uses: ./.github/actions/env - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: "NumaryBot" - password: ${{ secrets.NUMARY_GITHUB_TOKEN }} - - run: > - earthly - --no-output - --allow-privileged - --secret SPEAKEASY_API_KEY=$SPEAKEASY_API_KEY - --secret GITHUB_TOKEN=$GITHUB_TOKEN - --secret FURY_TOKEN=$FURY_TOKEN - --secret GORELEASER_KEY=$GORELEASER_KEY - ${{ contains(github.event.pull_request.labels.*.name, 'no-cache') && '--no-cache' || '' }} - +goreleaser --path=${{ matrix.components }} --mode=ci - env: - GITHUB_TOKEN: ${{ secrets.NUMARY_GITHUB_TOKEN }} - SPEAKEASY_API_KEY: ${{ secrets.SPEAKEASY_API_KEY }} - FURY_TOKEN: ${{ secrets.FURY_TOKEN }} - GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} - - Deploy: - runs-on: "ubuntu-latest" - if: github.ref == 'refs/heads/main' - needs: - - GoReleaser - - Tests - - TestsIntegration - steps: - - uses: earthly/actions-setup@v1 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - version: "latest" - - uses: 'actions/checkout@v4' - with: - fetch-depth: 0 - - name: Tailscale - uses: tailscale/github-action@v2 - with: - oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} - oauth-secret: ${{ secrets.TS_OAUTH_SECRET }} - tags: tag:ci - - name: "staging-regions: Sset Operator, Agent, Modules tags" - env: - # Only Region deployment need the token in order to deploy with argocd - ARGOCD_REGION_AUTH_TOKEN: ${{ secrets.ARGOCD_REGION_AUTH_TOKEN }} - # Only for module - STAGING_CLUSTER_KUBECONTEXT_NAME: ${{ secrets.STAGING_CLUSTER_KUBECONTEXT_NAME }} - STAGING_CLUSTER_NAME: ${{ secrets.STAGING_CLUSTER_NAME }} - STAGING_CLUSTER_REGION: ${{ secrets.STAGING_CLUSTER_REGION }} - TAG: ${{ github.sha }} - run: > - earthly - --no-output - --secret AUTH_TOKEN=$ARGOCD_REGION_AUTH_TOKEN - +staging-application-set - --TAG=$TAG - - - name: "staging-regions: Sync" - env: - # Only Region deployment need the token in order to deploy with argocd - ARGOCD_REGION_AUTH_TOKEN: ${{ secrets.ARGOCD_REGION_AUTH_TOKEN }} - STAGING_CLUSTER_KUBECONTEXT_NAME: ${{ secrets.STAGING_CLUSTER_KUBECONTEXT_NAME }} - STAGING_CLUSTER_NAME: ${{ secrets.STAGING_CLUSTER_NAME }} - STAGING_CLUSTER_REGION: ${{ secrets.STAGING_CLUSTER_REGION }} - TAG: ${{ github.sha }} - run: > - earthly - --no-output - --secret AUTH_TOKEN=$ARGOCD_REGION_AUTH_TOKEN - +staging-application-sync - --TAG=$TAG + SPEAKEASY_API_KEY: ${{ secrets.SPEAKEASY_API_KEY }} \ No newline at end of file diff --git a/Earthfile b/Earthfile index f982743ea7..949260a76e 100644 --- a/Earthfile +++ b/Earthfile @@ -146,11 +146,6 @@ staging-application-set: staging-application-sync: BUILD core+application-sync --APPLICATION=staging-eu-west-1-hosting-regions -tests: - LOCALLY - BUILD ./components+run --TARGET=tests - BUILD ./ee+run --TARGET=tests - tests-integration: FROM core+base-image BUILD ./tests/integration+tests @@ -158,16 +153,11 @@ tests-integration: pre-commit: # Generate the final spec and run all the pre-commit hooks LOCALLY BUILD ./releases+sdk-generate - BUILD ./libs+run --TARGET=pre-commit - BUILD ./components+run --TARGET=pre-commit - BUILD ./ee+run --TARGET=pre-commit BUILD ./helm/+pre-commit BUILD ./tests/integration+pre-commit tidy: # Run tidy on all the components LOCALLY - BUILD ./components+run --TARGET=tidy - BUILD ./ee+run --TARGET=tidy BUILD ./tests/integration+tidy tests-all: diff --git a/components/Earthfile b/components/Earthfile deleted file mode 100644 index 2521e19ba1..0000000000 --- a/components/Earthfile +++ /dev/null @@ -1,20 +0,0 @@ -VERSION 0.8 - -IMPORT github.com/formancehq/earthly:tags/v0.15.0 AS core -IMPORT .. AS stack - -deploy: - FROM core+base-image - ARG --required components - BUILD --pass-args ./$components+deploy - -deploy-staging: - FROM core+base-image - ARG --required components - BUILD --pass-args ./$components+deploy-staging - -run: - LOCALLY - ARG --required TARGET - BUILD ./operator+$TARGET - \ No newline at end of file diff --git a/components/operator/.dockerignore b/components/operator/.dockerignore deleted file mode 100644 index a3aab7af70..0000000000 --- a/components/operator/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file -# Ignore build and test binaries. -bin/ diff --git a/components/operator/.earthly/configuration/.helmignore b/components/operator/.earthly/configuration/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/components/operator/.earthly/configuration/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/components/operator/.earthly/configuration/Chart.yaml b/components/operator/.earthly/configuration/Chart.yaml deleted file mode 100644 index f6fdeae664..0000000000 --- a/components/operator/.earthly/configuration/Chart.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v2 -name: configuration -description: A Helm chart for Kubernetes -type: application -version: 0.1.0 -appVersion: "0.1.0" diff --git a/components/operator/.earthly/configuration/templates/elasticsearch-secret.yaml b/components/operator/.earthly/configuration/templates/elasticsearch-secret.yaml deleted file mode 100644 index bc793f175d..0000000000 --- a/components/operator/.earthly/configuration/templates/elasticsearch-secret.yaml +++ /dev/null @@ -1,12 +0,0 @@ ---- -apiVersion: v1 -kind: Secret -type: kubernetes.io/basic-auth -metadata: - name: elasticsearch - namespace: formance-system - labels: - formance.com/stack: any -stringData: - username: "admin" - password: "Complexpass#123" diff --git a/components/operator/.earthly/configuration/templates/postgres-secret.yaml b/components/operator/.earthly/configuration/templates/postgres-secret.yaml deleted file mode 100644 index 45407ad9e5..0000000000 --- a/components/operator/.earthly/configuration/templates/postgres-secret.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -apiVersion: v1 -kind: Secret -metadata: - name: postgres - namespace: formance-system - labels: - formance.com/stack: any -stringData: - username: "formance" - password: "formance" \ No newline at end of file diff --git a/components/operator/.earthly/configuration/templates/settings.yaml b/components/operator/.earthly/configuration/templates/settings.yaml deleted file mode 100644 index 7e5397633d..0000000000 --- a/components/operator/.earthly/configuration/templates/settings.yaml +++ /dev/null @@ -1,70 +0,0 @@ ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: default-postgres-uri -spec: - key: postgres.*.uri - stacks: - - '*' - value: postgresql://postgres-postgresql.formance.svc.cluster.local:5432?disableSSLMode=true&secret=postgres ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: default-broker -spec: - key: broker.dsn - stacks: - - '*' - value: nats://nats.default.svc.cluster.local:4222?replicas=1 ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: default-payments-encryption-key -spec: - key: payments.encryption-key - stacks: - - '*' - value: default-encryption-key ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: default-elasticsearch-dsn -spec: - key: elasticsearch.dsn - stacks: - - '*' - value: http://elasticsearch-master.formance.svc.cluster.local:9200?secret=elasticsearch ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: default-temporal-dsn -spec: - stacks: - - '*' - key: temporal.dsn - value: temporal://local-operator.sihc8.tmprl.cloud:7233/local-operator.sihc8?secret=temporal ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: stacks-temporal-dsn -spec: - stacks: - - '*' - key: opentelemetry.traces.dsn - value: grpc://otel-collector-opentelemetry-collector.formance.svc.cluster.local:4317?insecure=true ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: clear-database -spec: - stacks: - - '*' - key: clear-database - value: "true" \ No newline at end of file diff --git a/components/operator/.earthly/configuration/templates/temporal-secret.yaml b/components/operator/.earthly/configuration/templates/temporal-secret.yaml deleted file mode 100644 index fc70cfbbf5..0000000000 --- a/components/operator/.earthly/configuration/templates/temporal-secret.yaml +++ /dev/null @@ -1,61 +0,0 @@ ---- -apiVersion: v1 -kind: Secret -metadata: - name: temporal - namespace: formance-system - labels: - formance.com/stack: any -type: kubernetes.io/tls -stringData: - tls.crt: | - -----BEGIN CERTIFICATE----- - MIIDvDCCAqSgAwIBAgIUTQMMmzxFv5yUcH6H3l3AI+o01CswDQYJKoZIhvcNAQEL - BQAwFzEVMBMGA1UEAxMMZm9ybWFuY2UuY29tMB4XDTIzMDEyMDEwMTExNVoXDTMz - MDExNzA5MTE0NVowGTEXMBUGA1UEAwwOKi5mb3JtYW5jZS5jb20wggEiMA0GCSqG - SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7NlrS6MuTXIEdUIs4FKaQY3krG4w7KKpr - /ztQXYJ/4kyit+xnP6uuIiEs5qwfWJnS3V5a5ZGHF6x2GdZAKRMlHt3xxL7K39xu - sY06kwCcNP7eNDKdz4fbaRQ109vM6ANY6h1VgZ7A/e49swV5gpJ+YfPqRykood6H - afGSL0jLzFqTujjbNV6ZwIRD7ZMIa/NOYlb6oxlfZZXtMKwPY7An5fpDyEVJCRrP - G2dShu0WHZlctzCjR3WFNfNPIN44yaPdF9q/WweWwcei8pcoz+d5m9sjUeviIhfb - dXODDWbwJu1i1COOGz0suWchPQJCYGc9xOigCDWrH5A2BSu3C2gzAgMBAAGjgf0w - gfowDgYDVR0PAQH/BAQDAgOoMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD - AjAdBgNVHQ4EFgQU564vj1K2ZEtgkcLtl5JurExg6AcwHwYDVR0jBBgwFoAU9JfZ - psQJOHGZ+vYuZzZLPQRLYmwwOwYIKwYBBQUHAQEELzAtMCsGCCsGAQUFBzAChh9o - dHRwOi8vMTI3LjAuMC4xOjgyMDAvdjEvcGtpL2NhMBkGA1UdEQQSMBCCDiouZm9y - bWFuY2UuY29tMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly8xMjcuMC4wLjE6ODIw - MC92MS9wa2kvY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAW9ispaeU9UnoTUihFf+cx - RzNQ+JbxGoAihvri25YbxnXifjd/v9D9GnP50dkhfPcBQZnFtspsg9gAMla/Hhl8 - 3g4liINIIMYy1wHak9K22a3+k5yKspbFovtvsOoac5jt0fIl+2MiBY3G1V7lKiZL - LQiOlDdmBlzkldGD3ubunuh1NTMUbnBF8JTKquSqZv1i7Js6UbelJg89g9gh4N+R - gK3El3m5jc2sLFQbuWiDx8gZtNWAd5wihs9ban87Dc9YOZ6695Dd/woifhMRuIWG - YIezLQgPPPiyvTcTARipcA68eVu5GpFG8L3BKR9Mz5TThasRnsFwfa/ylbZkSWun - -----END CERTIFICATE----- - tls.key: | - -----BEGIN RSA PRIVATE KEY----- - MIIEowIBAAKCAQEAuzZa0ujLk1yBHVCLOBSmkGN5KxuMOyiqa/87UF2Cf+JMorfs - Zz+rriIhLOasH1iZ0t1eWuWRhxesdhnWQCkTJR7d8cS+yt/cbrGNOpMAnDT+3jQy - nc+H22kUNdPbzOgDWOodVYGewP3uPbMFeYKSfmHz6kcpKKHeh2nxki9Iy8xak7o4 - 2zVemcCEQ+2TCGvzTmJW+qMZX2WV7TCsD2OwJ+X6Q8hFSQkazxtnUobtFh2ZXLcw - o0d1hTXzTyDeOMmj3Rfav1sHlsHHovKXKM/neZvbI1Hr4iIX23Vzgw1m8CbtYtQj - jhs9LLlnIT0CQmBnPcTooAg1qx+QNgUrtwtoMwIDAQABAoIBADEmhhXVVI0tviAq - I0Ln+Qrzcr5kjx6BAK015yakRjy49xHJY+F/j905zKfzL8FTC5+WyszmdJyZFIg1 - JFDX99TJE9ADrWup9j+BkeiM654XM8q2vYs9DxgFsG6pXo2fZDGV1Xm7fCiDAmdk - ds1+AGP554XchOvMA5ZdtDSDAYOvgiTnhR+ic881U+L4DkHt+HRHv8ZFcuuUa5z/ - IVSoAR/yIUcQZeimp2l/SZoYk50pfzFNksAfnye6OS0PFhwNT/MX1+3u3ytm34Yj - fcXG/c1uKwfIR9GA/VseRDah0k+8fhsgECGeqtEJwUOqAzAmVWfyaCy6Ud/whAQP - qtl9aTECgYEA3/QJQO9MhlKCpxyOuTm/vAb/Tx0hO6Erd+jWwv8P2GMpM1n4kZd8 - O5/PPzPQKDlHu2gqNqwfqL77+RWw8xHQ25mUtfLVCiIPF4SVsNLD66E9KzU4yYpS - p40QckRHdaOO5gJmubkWV3UQczq2rPZyPs/Msy0r/8ilq4smMIjYpW8CgYEA1gBo - H2v14v7x4LhgpdJrMOg4gc80qJyFpxYxw2T/CdmyjVhsVCDGF/0d3j4Lo/SJB2y6 - YolJb6T3orCUnxOE8CHUktgHB7Auheh1Ls4xyA/HKExRvO8kh/YkBn+z3bIki0QB - w29yRx3d8hBu9hJT52f9veXN6wqzrp68H0Iw730CgYEA3nB/eHW25nuxtdZRlHxd - ip7Qm33tclLE4BbuqUO6M01asNyeXc2+4WH78WS/ThSGwQfXVfJkh7EaiO8YkHWT - o2rKIGaPX78wikVwgO73FmVSYkY8n0G6kx0zxqs25wuLdb3Q1ouWO0vVCP66TtWB - 6A1x3k3xs99RXi+ZwP9LYBUCgYAej3pPGmzH2N6T1+C9bXovRspjB0Me3RNdFBdR - LwgY0QTlmH4H2ZJQdK4iQbwJ0u8Kp2VKkw5wqh9PFWZz/Sab4EjqG32NhIRwTQ0G - /R0w08f+Ij/9+iy+WdE1OGFoRHthg/m4fh7Utxgt7FjcPSvMPRaIWtv4N9QHGNYG - pL42RQKBgCRDE6abLoeUN38GIfQ09YeWoaRgQ0WYzeNwzu1Yl2VwLifWjrbukKZX - p+3B/M7FaeXhjJ3qSVDXBXqI94B7NLjH32CxKsuil2ry7p+lLzdBDquUtMoL17lg - xpAA8tqK3W+E8gj01vKhbcGP28373jREU016/HCbEHRsNxW/BGDj - -----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/components/operator/.earthly/configuration/values.yaml b/components/operator/.earthly/configuration/values.yaml deleted file mode 100644 index 7f99d382c9..0000000000 --- a/components/operator/.earthly/configuration/values.yaml +++ /dev/null @@ -1,2 +0,0 @@ -gateway: - fallback: "" \ No newline at end of file diff --git a/components/operator/.earthly/k8s-versions.yaml b/components/operator/.earthly/k8s-versions.yaml deleted file mode 100644 index 82f4ed189c..0000000000 --- a/components/operator/.earthly/k8s-versions.yaml +++ /dev/null @@ -1,17 +0,0 @@ ---- -apiVersion: formance.com/v1beta1 -kind: Versions -metadata: - name: default -spec: - auth: latest - control: v.1.7.0 - gateway: latest - ledger: latest - orchestration: latest - payments: latest - reconciliation: latest - search: latest - wallets: latest - webhooks: latest - stargate: latest \ No newline at end of file diff --git a/components/operator/.gitignore b/components/operator/.gitignore deleted file mode 100644 index 4d5ca3f721..0000000000 --- a/components/operator/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ - -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib -bin/* -Dockerfile.cross - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Kubernetes Generated files - skip generated files, except for vendored files - -!vendor/**/zz_generated.* - -# editor and IDE paraphernalia -.idea -.vscode -*.swp -*.swo -*~ - -charts diff --git a/components/operator/.goreleaser.yml b/components/operator/.goreleaser.yml deleted file mode 100644 index c5136f0a1e..0000000000 --- a/components/operator/.goreleaser.yml +++ /dev/null @@ -1,40 +0,0 @@ -project_name: operator -includes: - - from_file: - path: ./../../.goreleaser.default.yaml - -monorepo: - tag_prefix: v - dir: ./ - -builds: - - binary: operator - id: operator - main: ./cmd - ldflags: - - -X github.com/formancehq/operator/cmd.BuildDate={{ .Date }} - - -X github.com/formancehq/operator/cmd.Version=v{{ .Version }} - - -X github.com/formancehq/operator/cmd.Commit={{ .ShortCommit }} - - -extldflags "-static" - env: - - CGO_ENABLED=0 - goos: - - linux - goarch: - - amd64 - - arm64 - -archives: - - id: "{{.ProjectName}}" - builds: - - operator - format: tar.gz - name_template: "{{.ProjectName}}_{{.Os}}-{{.Arch}}" - - -release: - prerelease: auto - footer: | - ## What to do next? - - Read the [documentation](https://docs.formance.com/) - - Join our [Slack server](https://formance.com/slack) \ No newline at end of file diff --git a/components/operator/Earthfile b/components/operator/Earthfile deleted file mode 100644 index da6a268686..0000000000 --- a/components/operator/Earthfile +++ /dev/null @@ -1,239 +0,0 @@ -VERSION 0.8 - -IMPORT github.com/formancehq/earthly:tags/v0.15.0 AS core -IMPORT ../.. AS stack -IMPORT .. AS components - -FROM core+base-image - -sources: - FROM core+builder-image - WORKDIR /src - WORKDIR /src/components/operator - COPY --dir api internal pkg cmd . - COPY go.* . - SAVE ARTIFACT /src - -compile: - FROM core+builder-image - COPY (+sources/*) /src - COPY --pass-args (+generate/*) /src/components/operator - WORKDIR /src/components/operator/cmd - DO --pass-args core+GO_COMPILE - -build-image: - FROM core+final-image - ENTRYPOINT ["/usr/bin/operator"] - COPY --pass-args (+compile/main) /usr/bin/operator - ARG REPOSITORY=ghcr.io - ARG tag=latest - DO --pass-args core+SAVE_IMAGE --COMPONENT=operator --TAG=$tag - -controller-gen: - FROM core+builder-image - DO --pass-args core+GO_INSTALL --package=sigs.k8s.io/controller-tools/cmd/controller-gen@v0.14.0 - -manifests: - FROM --pass-args +controller-gen - COPY (+sources/*) /src - WORKDIR /src/components/operator - COPY --dir config . - RUN --mount=type=cache,id=gomod,target=${GOPATH}/pkg/mod \ - --mount=type=cache,id=gobuild,target=/root/.cache/go-build \ - controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases - - SAVE ARTIFACT config AS LOCAL config - -generate: - FROM --pass-args +controller-gen - COPY +sources/* /src - WORKDIR /src/components/operator - COPY --dir hack . - RUN --mount=type=cache,id=gomod,target=${GOPATH}/pkg/mod \ - --mount=type=cache,id=gobuild,target=/root/.cache/go-build \ - controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..." - SAVE ARTIFACT internal AS LOCAL internal - SAVE ARTIFACT api AS LOCAL api - -generate-mock: - FROM core+builder-image - DO --pass-args core+GO_INSTALL --package=go.uber.org/mock/mockgen@latest - COPY (+sources/*) /src - WORKDIR /src/components/operator - RUN go generate -run mockgen ./... - SAVE ARTIFACT internal AS LOCAL internal - -helm-update: - FROM core+builder-image - RUN curl -s https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh | bash -s -- 4.5.4 /bin - RUN apk add helm - - WORKDIR /src - COPY --pass-args (+manifests/config) /src/config - COPY --dir helm hack . - - RUN rm -f helm/operator/templates/gen/* - RUN rm -f helm/crds/templates/crds/* - - RUN kustomize build config/default --output helm/operator/templates/gen - RUN kustomize build config/crd --output helm/crds/templates/crds - - RUN rm -f helm/operator/templates/gen/v1_namespace*.yaml - RUN rm -f helm/operator/templates/gen/apps_v1_deployment_*.yaml - - RUN helm dependencies update ./helm/operator - - SAVE ARTIFACT helm AS LOCAL helm - -deploy: - ARG LICENCE_TOKEN="" - ARG LICENCE_ISSUER="http://licence-api.formance.svc.cluster.local:8080/keys" - - COPY (+sources/*) /src - LET tag=$(tar cf - /src | sha1sum | awk '{print $1}') - WAIT - BUILD --pass-args +build-image --tag=$tag - BUILD --pass-args ./tools/utils+build-image --tag=$tag - END - FROM --pass-args core+vcluster-deployer-image - COPY --pass-args (+helm-update/helm) helm - WORKDIR helm - - # When all clients are using the new base CRDS chart, we can uncomment this step - # RUN helm upgrade --install --namespace formance-system --install formance-operator-crds \ - # --wait \ - # --create-namespace ./base - RUN helm upgrade --install --namespace formance-system --install formance-operator \ - --wait \ - --create-namespace \ - --set image.tag=$tag \ - --set operator.licence.token=$LICENCE_TOKEN \ - --set operator.licence.issuer=$LICENCE_ISSUER ./operator \ - --set operator.dev=true - WORKDIR / - COPY .earthly .earthly - WORKDIR .earthly - RUN kubectl get versions default || kubectl apply -f k8s-versions.yaml - ARG user - RUN --secret tld helm upgrade --install operator-configuration ./configuration \ - --namespace formance-system \ - --set gateway.fallback=https://console.$user.$tld - -deploy-staging: - FROM --pass-args core+base-argocd - ARG --required TAG - - ARG APPLICATION=staging-eu-west-1-hosting-regions - LET SERVER=argocd.internal.formance.cloud - - RUN --secret AUTH_TOKEN \ - argocd app set $APPLICATION \ - --parameter operator.image.tag=$TAG \ - --auth-token=$AUTH_TOKEN --server=$SERVER --grpc-web - - BUILD --pass-args core+deploy-staging - -lint: - FROM core+builder-image - COPY (+sources/*) /src - COPY --pass-args +tidy/go.* . - WORKDIR /src/components/operator - DO --pass-args stack+GO_LINT - SAVE ARTIFACT api AS LOCAL api - SAVE ARTIFACT internal AS LOCAL internal - -tests: - FROM core+builder-image - RUN apk update && apk add bash - DO --pass-args core+GO_INSTALL --package=sigs.k8s.io/controller-runtime/tools/setup-envtest@v0.0.0-20240320141353-395cfc7486e6 - ENV ENVTEST_VERSION 1.28.0 - RUN setup-envtest use $ENVTEST_VERSION -p path - ENV KUBEBUILDER_ASSETS /root/.local/share/kubebuilder-envtest/k8s/$ENVTEST_VERSION-linux-$(go env GOHOSTARCH) - DO --pass-args core+GO_INSTALL --package=github.com/onsi/ginkgo/v2/ginkgo@v2.14.0 - COPY (+sources/*) /src - COPY --pass-args (+manifests/config) /src/components/operator/config - COPY --pass-args (+generate/internal) /src/components/operator/internal - COPY --pass-args (+generate/api) /src/components/operator/api - WORKDIR /src/components/operator - COPY --dir hack . - ARG GOPROXY - ARG updateTestData=0 - ENV UPDATE_TEST_DATA=$updateTestData - ARG args= - RUN --mount=type=cache,id=gomod,target=$GOPATH/pkg/mod \ - --mount=type=cache,id=gobuild,target=/root/.cache/go-build \ - ginkgo $args -p ./... - IF [ "$updateTestData" = "1" ] - SAVE ARTIFACT internal/tests/testdata AS LOCAL internal/tests/testdata - END - -generate-docs: - FROM core+builder-image - COPY (+sources/*) /src - RUN go install github.com/elastic/crd-ref-docs@v0.0.12 - WORKDIR /src/components/operator - COPY docs.config.yaml . - COPY --dir api crd-doc-templates . - COPY docs docs - RUN mkdir -p "docs/09-Configuration reference" - RUN crd-ref-docs \ - --source-path=api/formance.com/v1beta1 \ - --renderer=markdown \ - --output-path="./docs/09-Configuration reference/02-Custom Resource Definitions.md" \ - --templates-dir=./crd-doc-templates \ - --config=./docs.config.yaml - SAVE ARTIFACT docs/* AS LOCAL docs/ - -pre-commit: - WAIT - BUILD --pass-args +tidy - END - BUILD --pass-args +lint - BUILD --pass-args +generate - BUILD --pass-args +manifests - BUILD --pass-args +helm-update - BUILD --pass-args +helm-validate - BUILD +generate-docs - -openapi: - RUN echo "not implemented" - -tidy: - FROM core+builder-image - COPY --pass-args (+sources/src) /src - WORKDIR /src/components/operator - DO --pass-args stack+GO_TIDY - BUILD ./tools/utils+tidy - BUILD ./tools/kubectl-stacks+tidy - -helm-validate: - FROM --pass-args core+helm-base - WORKDIR /src - COPY --pass-args (+helm-update/helm) . - - FOR dir IN $(ls -d */) - WORKDIR /src/$dir - DO --pass-args core+HELM_VALIDATE - END - SAVE ARTIFACT /src AS LOCAL helm - -helm-package: - FROM --pass-args +helm-validate - WORKDIR /src - FOR dir IN $(ls -d */) - WORKDIR /src/$dir - RUN helm package . - END - SAVE ARTIFACT /src AS LOCAL helm - -helm-publish: - FROM --pass-args +helm-package - WORKDIR /src - FOR dir IN $(ls -d */) - WORKDIR /src/$dir - DO --pass-args stack+HELM_PUBLISH --path=/src/${dir}*.tgz - END - -release: - BUILD --pass-args stack+goreleaser --path=components/operator - BUILD --pass-args stack+goreleaser --path=components/operator/tools/utils \ No newline at end of file diff --git a/components/operator/Makefile b/components/operator/Makefile deleted file mode 100644 index e81b510270..0000000000 --- a/components/operator/Makefile +++ /dev/null @@ -1,181 +0,0 @@ - -# Image URL to use all building/pushing image targets -IMG ?= controller:latest -# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. -ENVTEST_K8S_VERSION = 1.28.0 - -# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) -ifeq (,$(shell go env GOBIN)) -GOBIN=$(shell go env GOPATH)/bin -else -GOBIN=$(shell go env GOBIN) -endif - -# CONTAINER_TOOL defines the container tool to be used for building images. -# Be aware that the target commands are only tested with Docker which is -# scaffolded by default. However, you might want to replace it to use other -# tools. (i.e. podman) -CONTAINER_TOOL ?= docker - -# Setting SHELL to bash allows bash commands to be executed by recipes. -# Options are set to exit when a recipe line exits non-zero or a piped command fails. -SHELL = /usr/bin/env bash -o pipefail -.SHELLFLAGS = -ec - -.PHONY: all -all: build - -##@ General - -# The help target prints out all targets with their descriptions organized -# beneath their categories. The categories are represented by '##@' and the -# target descriptions by '##'. The awk command is responsible for reading the -# entire set of makefiles included in this invocation, looking for lines of the -# file as xyz: ## something, and then pretty-format the target and help. Then, -# if there's a line with ##@ something, that gets pretty-printed as a category. -# More info on the usage of ANSI control characters for terminal formatting: -# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters -# More info on the awk command: -# http://linuxcommand.org/lc3_adv_awk.php - -.PHONY: help -help: ## Display this help. - @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) - -##@ Development - -.PHONY: manifests -manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. - $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./api/..." output:crd:artifacts:config=config/crd/bases - $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./internal/..." output:crd:artifacts:config=config/crd/bases - -.PHONY: generate -generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. - $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./api/..." - $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./internal/..." - -.PHONY: fmt -fmt: ## Run go fmt against code. - go fmt ./... - -.PHONY: vet -vet: ## Run go vet against code. - go vet ./... - -.PHONY: test -test: manifests generate fmt vet envtest ## Run tests. - KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" ginkgo -p ./... - -GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint -GOLANGCI_LINT_VERSION ?= v1.54.2 -golangci-lint: - @[ -f $(GOLANGCI_LINT) ] || { \ - set -e ;\ - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell dirname $(GOLANGCI_LINT)) $(GOLANGCI_LINT_VERSION) ;\ - } - -.PHONY: lint -lint: golangci-lint ## Run golangci-lint linter & yamllint - $(GOLANGCI_LINT) run - -.PHONY: lint-fix -lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes - $(GOLANGCI_LINT) run --fix - -##@ Build - -.PHONY: build -build: manifests generate fmt vet ## Build manager binary. - go build -o bin/manager main.go - -.PHONY: run -run: manifests generate fmt vet ## Run a controller from your host. - go run ./cmd/main.go - -# If you wish to build the manager image targeting other platforms you can use the --platform flag. -# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. -# More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -.PHONY: docker-build -docker-build: ## Build docker image with the manager. - $(CONTAINER_TOOL) build -t ${IMG} . - -.PHONY: docker-push -docker-push: ## Push docker image with the manager. - $(CONTAINER_TOOL) push ${IMG} - -# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple -# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: -# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/ -# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=> then the export will fail) -# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. -PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le -.PHONY: docker-buildx -docker-buildx: ## Build and push docker image for the manager for cross-platform support - # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile - sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross - - $(CONTAINER_TOOL) buildx create --name project-v3-builder - $(CONTAINER_TOOL) buildx use project-v3-builder - - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . - - $(CONTAINER_TOOL) buildx rm project-v3-builder - rm Dockerfile.cross - -##@ Deployment - -ifndef ignore-not-found - ignore-not-found = false -endif - -.PHONY: install -install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. - $(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f - - -.PHONY: uninstall -uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - - -.PHONY: deploy -deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. - cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default | $(KUBECTL) apply -f - - -.PHONY: undeploy -undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - - -##@ Build Dependencies - -## Location to install dependencies to -LOCALBIN ?= $(shell pwd)/bin -$(LOCALBIN): - mkdir -p $(LOCALBIN) - -## Tool Binaries -KUBECTL ?= kubectl -KUSTOMIZE ?= $(LOCALBIN)/kustomize -CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen -ENVTEST ?= $(LOCALBIN)/setup-envtest - -## Tool Versions -KUSTOMIZE_VERSION ?= v5.2.1 -CONTROLLER_TOOLS_VERSION ?= v0.14.0 - -.PHONY: kustomize -kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading. -$(KUSTOMIZE): $(LOCALBIN) - @if test -x $(LOCALBIN)/kustomize && ! $(LOCALBIN)/kustomize version | grep -q $(KUSTOMIZE_VERSION); then \ - echo "$(LOCALBIN)/kustomize version is not expected $(KUSTOMIZE_VERSION). Removing it before installing."; \ - rm -rf $(LOCALBIN)/kustomize; \ - fi - test -s $(LOCALBIN)/kustomize || GOBIN=$(LOCALBIN) GO111MODULE=on go install sigs.k8s.io/kustomize/kustomize/v5@$(KUSTOMIZE_VERSION) - -.PHONY: controller-gen -controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. If wrong version is installed, it will be overwritten. -$(CONTROLLER_GEN): $(LOCALBIN) - test -s $(LOCALBIN)/controller-gen && $(LOCALBIN)/controller-gen --version | grep -q $(CONTROLLER_TOOLS_VERSION) || \ - GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION) - -.PHONY: envtest -envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. -$(ENVTEST): $(LOCALBIN) - test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest diff --git a/components/operator/PROJECT b/components/operator/PROJECT deleted file mode 100644 index a5607ad900..0000000000 --- a/components/operator/PROJECT +++ /dev/null @@ -1,175 +0,0 @@ -# Code generated by tool. DO NOT EDIT. -# This file is used to track the info used to scaffold your project -# and allow the plugins properly work. -# More info: https://book.kubebuilder.io/reference/project-config.html -layout: -- go.kubebuilder.io/v4 -multigroup: true -projectName: operatorv2 -repo: github.com/formancehq/operator -resources: -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: Database - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: Stack - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: Topic - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: TopicQuery - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: HTTPAPI - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: Ledger - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: Gateway - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: Auth - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - group: formance.com - kind: AuthClient - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: Wallet - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: Orchestration - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: Webhooks - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: Reconciliation - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: Payments - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - controller: true - group: formance.com - kind: Search - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - group: formance.com - kind: BenthosStream - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - group: formance.com - kind: Benthos - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - group: formance.com - kind: Registries - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - group: formance.com - kind: Stargate - path: github.com/formancehq/operator/api/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - group: formance.com - kind: Versions - path: github.com/formancehq/operator/api/formance.com/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - group: formance.com - kind: Settings - path: github.com/formancehq/operator/api/formance.com/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - group: formance.com - kind: ResourceReference - path: github.com/formancehq/operator/api/formance.com/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - group: formance.com - kind: BrokerConsumer - path: github.com/formancehq/operator/api/formance.com/v1beta1 - version: v1beta1 -- api: - crdVersion: v1 - group: formance.com - 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/README.md b/components/operator/README.md deleted file mode 100644 index b8a80a9a2b..0000000000 --- a/components/operator/README.md +++ /dev/null @@ -1,185 +0,0 @@ -# operator - -## Description - -The operator allow to install formance components on a k8s cluster. - -## Getting Started - -### Prerequisites -- go version v1.20.0+ -- docker version 17.03+. -- kubectl version v1.11.3+. -- k3d - -### To Deploy on the cluster - -**Create a dev cluster** - -```sh -k3d cluster create internal -``` - -**Install CRDs** - -```sh -make install -``` - -**Run operator** - -```sh -make run -``` - -**Install a PostgresServer** - -```sh -helm install postgres oci://registry-1.docker.io/bitnamicharts/postgresql \ - --set auth.username=formance \ - --set auth.password=formance \ - --set auth.database=formance -``` - -**Create a Settings object for database connection** - -```sh -cat </operator:tag -``` - -**NOTE:** This image ought to be published in the personal registry you specified. -And it is required to have access to pull the image from the working environment. -Make sure you have the proper permission to the registry if the above commands don’t work. - -**Install the CRDs into the cluster:** - -```sh -make install -``` - -**Deploy the Manager to the cluster with the image specified by `IMG`:** - -```sh -make deploy IMG=/operator:tag -``` - -**Run locally without building/pushing image** - -```sh -make run -``` - -> **NOTE**: If you encounter RBAC errors, you may need to grant yourself cluster-admin -privileges or be logged in as admin. - -**Create instances of your solution** -You can apply the samples (examples) from the config/sample: - -```sh -kubectl apply -k config/samples/ -``` - ->**NOTE**: Ensure that the samples has default values to test it out. - -### To Uninstall -**Delete the instances (CRs) from the cluster:** - -```sh -kubectl delete -k config/samples/ -``` - -**Delete the APIs(CRDs) from the cluster:** - -```sh -make uninstall -``` - -**UnDeploy the controller from the cluster:** - -```sh -make undeploy -``` - -## Settings - -See defined settings in [Settings](docs/09-Configuration%20reference/01-Settings.md) - -## Contributing - -**NOTE:** Run `make --help` for more information on all potential `make` targets - -More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html) - -## License - -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. - diff --git a/components/operator/api/formance.com/v1beta1/analytics_types.go b/components/operator/api/formance.com/v1beta1/analytics_types.go deleted file mode 100644 index 372376d2ee..0000000000 --- a/components/operator/api/formance.com/v1beta1/analytics_types.go +++ /dev/null @@ -1,107 +0,0 @@ -/* -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/auth_types.go b/components/operator/api/formance.com/v1beta1/auth_types.go deleted file mode 100644 index ab532ba308..0000000000 --- a/components/operator/api/formance.com/v1beta1/auth_types.go +++ /dev/null @@ -1,131 +0,0 @@ -/* -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 ( - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type DelegatedOIDCServerConfiguration struct { - // Issuer is the url of the delegated oidc server - Issuer string `json:"issuer,omitempty"` - // ClientID is the client id to use for authentication - ClientID string `json:"clientID,omitempty"` - // ClientSecret is the client secret to use for authentication - ClientSecret string `json:"clientSecret,omitempty"` -} - -type AuthSpec struct { - ModuleProperties `json:",inline"` - StackDependency `json:",inline"` - //+optional - // Contains information about a delegated authentication server to use to delegate authentication - DelegatedOIDCServer *DelegatedOIDCServerConfiguration `json:"delegatedOIDCServer,omitempty"` - //+optional - // Allow to override the default signing key used to sign JWT tokens. - SigningKey string `json:"signingKey,omitempty"` - //+optional - // Allow to override the default signing key used to sign JWT tokens using a k8s secret - SigningKeyFromSecret *v1.SecretKeySelector `json:"signingKeyFromSecret,omitempty"` - //+optional - // Allow to enable scopes usage on authentication. - // - // If not enabled, each service will check the authentication but will not restrict access following scopes. - // in this case, if authenticated, it is ok. - // +kubebuilder:default:=false - EnableScopes bool `json:"enableScopes"` -} - -type AuthStatus struct { - Status `json:",inline"` - //+optional - // Clients contains the list of clients created using [AuthClient](#authclient) - Clients []string `json:"clients"` -} - -// Auth represent the authentication module of a stack. -// -// It is an OIDC compliant server. -// -// Creating it for a stack automatically add authentication on all supported modules. -// -// The auth service is basically a proxy to another OIDC compliant server. -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status -// +kubebuilder:resource:scope=Cluster -// +kubebuilder:printcolumn:name="Clients",type=string,JSONPath=".status.clients",description="Synchronized auth clients" -// +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 -type Auth struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec AuthSpec `json:"spec,omitempty"` - Status AuthStatus `json:"status,omitempty"` -} - -func (in *Auth) IsEE() bool { - return false -} - -func (in *Auth) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *Auth) IsReady() bool { - return in.Status.Ready -} - -func (in *Auth) SetError(s string) { - in.Status.Info = s -} - -func (in *Auth) GetConditions() *Conditions { - return &in.Status.Conditions -} - -func (in *Auth) GetVersion() string { - return in.Spec.Version -} - -func (in Auth) GetStack() string { - return in.Spec.Stack -} - -func (in Auth) IsDebug() bool { - return in.Spec.Debug -} - -func (in Auth) IsDev() bool { - return in.Spec.Dev -} - -//+kubebuilder:object:root=true - -// AuthList contains a list of Auth -type AuthList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Auth `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Auth{}, &AuthList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/authclient_types.go b/components/operator/api/formance.com/v1beta1/authclient_types.go deleted file mode 100644 index 251d64231b..0000000000 --- a/components/operator/api/formance.com/v1beta1/authclient_types.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -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 ( - "gopkg.in/yaml.v3" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type AuthClientSpec struct { - StackDependency `json:",inline" yaml:",inline"` - // ID indicates the client id - // It must be used with oauth2 `client_id` parameter - ID string `json:"id" yaml:"id"` - // +optional - // Public indicate whether a client is confidential or not. - // Confidential clients are clients which the secret can be kept secret... - // As opposed to public clients which cannot have a secret (application single page for example) - // +kubebuilder:default:=false - Public bool `json:"public" yaml:"public"` - // +optional - // Description represents an optional description of the client - Description string `json:"description,omitempty" yaml:"description,omitempty"` - // +optional - // RedirectUris allow to list allowed redirect uris for the client - RedirectUris []string `json:"redirectUris,omitempty" yaml:"redirectUris"` - // +optional - // RedirectUris allow to list allowed post logout redirect uris for the client - PostLogoutRedirectUris []string `json:"postLogoutRedirectUris,omitempty" yaml:"PostLogoutRedirectUris"` - // +optional - // Scopes allow to five some scope to the client - Scopes []string `json:"scopes,omitempty" yaml:"scopes"` - // +optional - // Secret allow to configure a secret for the client. - // It is not required as some client could use some oauth2 flows which does not requires a client secret - Secret string `json:"secret,omitempty"` -} - -var _ yaml.Marshaler = (*AuthClientSpec)(nil) - -func (spec AuthClientSpec) MarshalYAML() (interface{}, error) { - type aux AuthClientSpec - return struct { - aux `yaml:",inline"` - Secrets []string `yaml:"secrets"` - }{ - aux: aux(spec), - Secrets: func() []string { - if spec.Secret == "" { - return []string{} - } - return []string{spec.Secret} - }(), - }, nil -} - -type AuthClientStatus 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" - -// AuthClient allow to create OAuth2/OIDC clients on the auth server (see [Auth](#auth)) -type AuthClient struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec AuthClientSpec `json:"spec,omitempty"` - Status AuthClientStatus `json:"status,omitempty"` -} - -func (a *AuthClient) SetReady(b bool) { - a.Status.Ready = b -} - -func (in *AuthClient) IsReady() bool { - return in.Status.Ready -} - -func (a *AuthClient) SetError(s string) { - a.Status.Info = s -} - -func (a AuthClient) GetStack() string { - return a.Spec.Stack -} - -func (in *AuthClient) GetConditions() *Conditions { - return &in.Status.Conditions -} - -//+kubebuilder:object:root=true - -// AuthClientList contains a list of AuthClient -type AuthClientList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []AuthClient `json:"items"` -} - -func init() { - SchemeBuilder.Register(&AuthClient{}, &AuthClientList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/benthos_types.go b/components/operator/api/formance.com/v1beta1/benthos_types.go deleted file mode 100644 index 2a7f53ce08..0000000000 --- a/components/operator/api/formance.com/v1beta1/benthos_types.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -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 ( - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// Batching allow to define custom batching configuration -type Batching struct { - // Count indicates the number of messages that can be kept in memory before being flushed to ElasticSearch - Count int `json:"count"` - // Period indicates the maximum duration messages can be kept in memory before being flushed to ElasticSearch - Period string `json:"period"` -} - -type BenthosSpec struct { - StackDependency `json:",inline"` - DevProperties `json:",inline"` - //+optional - ResourceProperties *corev1.ResourceRequirements `json:"resourceRequirements,omitempty"` - //+optional - Batching *Batching `json:"batching,omitempty"` - //+optional - InitContainers []corev1.Container `json:"initContainers"` -} - -type BenthosStatus struct { - Status `json:",inline"` - //+optional - ElasticSearchURI *URI `json:"elasticSearchURI"` -} - -//+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" - -// Benthos is the Schema for the benthos API -type Benthos struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec BenthosSpec `json:"spec,omitempty"` - Status BenthosStatus `json:"status,omitempty"` -} - -func (in *Benthos) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *Benthos) IsReady() bool { - return in.Status.Ready -} - -func (in *Benthos) SetError(s string) { - in.Status.Info = s -} - -func (a Benthos) GetStack() string { - return a.Spec.Stack -} - -func (in *Benthos) GetConditions() *Conditions { - return &in.Status.Conditions -} - -//+kubebuilder:object:root=true - -// BenthosList contains a list of Benthos -type BenthosList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Benthos `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Benthos{}, &BenthosList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/benthosstream_types.go b/components/operator/api/formance.com/v1beta1/benthosstream_types.go deleted file mode 100644 index 3c10c34ea6..0000000000 --- a/components/operator/api/formance.com/v1beta1/benthosstream_types.go +++ /dev/null @@ -1,78 +0,0 @@ -/* -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" -) - -type BenthosStreamSpec struct { - StackDependency `json:",inline"` - Data string `json:"data"` - Name string `json:"name"` -} - -type BenthosStreamStatus 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" - -// BenthosStream is the Schema for the benthosstreams API -type BenthosStream struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec BenthosStreamSpec `json:"spec,omitempty"` - Status BenthosStreamStatus `json:"status,omitempty"` -} - -func (in *BenthosStream) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *BenthosStream) IsReady() bool { - return in.Status.Ready -} - -func (in *BenthosStream) SetError(s string) { - in.Status.Info = s -} - -func (a BenthosStream) GetStack() string { - return a.Spec.Stack -} - -func (in *BenthosStream) GetConditions() *Conditions { - return &in.Status.Conditions -} - -//+kubebuilder:object:root=true - -// BenthosStreamList contains a list of BenthosStream -type BenthosStreamList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []BenthosStream `json:"items"` -} - -func init() { - SchemeBuilder.Register(&BenthosStream{}, &BenthosStreamList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/broker_types.go b/components/operator/api/formance.com/v1beta1/broker_types.go deleted file mode 100644 index c10ad52d75..0000000000 --- a/components/operator/api/formance.com/v1beta1/broker_types.go +++ /dev/null @@ -1,98 +0,0 @@ -/* -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" -) - -type BrokerSpec struct { - StackDependency `json:",inline"` -} - -// Mode defined how streams are created on the broker (mainly nats) -type Mode string - -const ( - ModeOneStreamByService = "OneStreamByService" - ModeOneStreamByStack = "OneStreamByStack" -) - -type BrokerStatus struct { - Status `json:",inline"` - //+optional - URI *URI `json:"uri,omitempty"` - //+optional - //+kubebuilder:validation:Enum:={OneStreamByService, OneStreamByStack} - // Mode indicating the configuration of the nats streams - // Two modes are defined : - // * OneStreamByService: In this case, each service will have a dedicated stream created - // * OneStreamByStack: In this case, a stream will be created for the stack and each service will use a specific subject inside this stream - Mode Mode `json:"mode"` - // Streams list streams created when Mode == ModeOneStreamByService - //+optional - Streams []string `json:"streams,omitempty"` -} - -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status -//+kubebuilder:resource:scope=Cluster -//+kubebuilder:printcolumn:name="Mode",type=string,JSONPath=".status.mode",description="Mode" -//+kubebuilder:printcolumn:name="Ready",type=string,JSONPath=".status.ready",description="Ready" -//+kubebuilder:printcolumn:name="Info",type=string,JSONPath=".status.info",description="Info" - -// Broker is the Schema for the brokers API -type Broker struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec BrokerSpec `json:"spec,omitempty"` - Status BrokerStatus `json:"status,omitempty"` -} - -func (in *Broker) SetReady(ready bool) { - in.Status.SetReady(ready) -} - -func (in *Broker) IsReady() bool { - return in.Status.Ready -} - -func (in *Broker) SetError(s string) { - in.Status.SetError(s) -} - -func (in *Broker) GetStack() string { - return in.Spec.GetStack() -} - -func (in *Broker) GetConditions() *Conditions { - return &in.Status.Conditions -} - -//+kubebuilder:object:root=true - -// BrokerList contains a list of Broker -type BrokerList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Broker `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Broker{}, &BrokerList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/brokerconsumer_types.go b/components/operator/api/formance.com/v1beta1/brokerconsumer_types.go deleted file mode 100644 index 2b14f27bbb..0000000000 --- a/components/operator/api/formance.com/v1beta1/brokerconsumer_types.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -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" -) - -type BrokerConsumerSpec struct { - StackDependency `json:",inline"` - Services []string `json:"services"` - QueriedBy string `json:"queriedBy"` - //+optional - // As the name is optional, if not provided, the name will be the QueriedBy property - // This is only applied when using one stream by stack see Mode - Name string `json:"name,omitempty"` -} - -type BrokerConsumerStatus struct { - Status `json:",inline"` -} - -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status -//+kubebuilder:resource:scope=Cluster -//+kubebuilder:printcolumn:name="Services",type=string,JSONPath=".spec.services",description="Listened services" -//+kubebuilder:printcolumn:name="Ready",type=string,JSONPath=".status.ready",description="Ready" -//+kubebuilder:printcolumn:name="Info",type=string,JSONPath=".status.info",description="Info" - -// BrokerConsumer is the Schema for the brokerconsumers API -type BrokerConsumer struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec BrokerConsumerSpec `json:"spec,omitempty"` - Status BrokerConsumerStatus `json:"status,omitempty"` -} - -func (in *BrokerConsumer) SetReady(b bool) { - in.Status.SetReady(b) -} - -func (in *BrokerConsumer) IsReady() bool { - return in.Status.Ready -} - -func (in *BrokerConsumer) SetError(s string) { - in.Status.SetError(s) -} - -func (in *BrokerConsumer) GetStack() string { - return in.Spec.Stack -} - -func (in *BrokerConsumer) GetConditions() *Conditions { - return &in.Status.Conditions -} - -//+kubebuilder:object:root=true - -// BrokerConsumerList contains a list of BrokerConsumer -type BrokerConsumerList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []BrokerConsumer `json:"items"` -} - -func init() { - SchemeBuilder.Register(&BrokerConsumer{}, &BrokerConsumerList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/brokertopic_types.go b/components/operator/api/formance.com/v1beta1/brokertopic_types.go deleted file mode 100644 index 3130ceda8c..0000000000 --- a/components/operator/api/formance.com/v1beta1/brokertopic_types.go +++ /dev/null @@ -1,82 +0,0 @@ -/* -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 BrokerTopicSpec struct { - StackDependency `json:",inline"` - //+required - Service string `json:"service"` -} - -type BrokerTopicStatus 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" -//+kubebuilder:printcolumn:name="Info",type=string,JSONPath=".status.info",description="Info" - -// BrokerTopic is the Schema for the brokertopics API -type BrokerTopic struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec BrokerTopicSpec `json:"spec,omitempty"` - Status BrokerTopicStatus `json:"status,omitempty"` -} - -func (in *BrokerTopic) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *BrokerTopic) IsReady() bool { - return in.Status.Ready -} - -func (in *BrokerTopic) SetError(s string) { - in.Status.Info = s -} - -func (a *BrokerTopic) GetStack() string { - return a.Spec.Stack -} - -func (a *BrokerTopic) isResource() {} - -func (in *BrokerTopic) GetConditions() *Conditions { - return &in.Status.Conditions -} - -//+kubebuilder:object:root=true - -// BrokerTopicList contains a list of BrokerTopic -type BrokerTopicList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []BrokerTopic `json:"items"` -} - -func init() { - SchemeBuilder.Register(&BrokerTopic{}, &BrokerTopicList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/database_types.go b/components/operator/api/formance.com/v1beta1/database_types.go deleted file mode 100644 index 3f92098b76..0000000000 --- a/components/operator/api/formance.com/v1beta1/database_types.go +++ /dev/null @@ -1,114 +0,0 @@ -/* -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" -) - -type DatabaseSpec struct { - StackDependency `json:",inline"` - // Service is a discriminator for the created database. - // Actually, it will be the module name (ledger, payments...). - // Therefore, the created database will be named `` - Service string `json:"service"` - // +kubebuilder:default:=false - Debug bool `json:"debug,omitempty"` -} - -type DatabaseStatus struct { - Status `json:",inline"` - //+optional - URI *URI `json:"uri,omitempty"` - //+optional - // The generated database name - Database string `json:"database,omitempty"` - //+optional - // OutOfSync indicates than a settings changed the uri of the postgres server - // The Database object need to be removed to be recreated - OutOfSync bool `json:"outOfSync,omitempty"` -} - -// Database represent a concrete database on a PostgreSQL server, it is created by modules requiring a database ([Ledger](#ledger) for example). -// -// It uses the settings `postgres..uri` which must have the following uri format: `postgresql://[@]@/` -// Additionally, the uri can define a query param `secret` indicating a k8s secret, than must be used to retrieve database credentials. -// -// On creation, the reconciler behind the Database object will create the database on the postgresql server using a k8s job. -// On Deletion, by default, the reconciler will let the database untouched. -// You can allow the reconciler to drop the database on the server by using the [Settings](#settings) `clear-database` with the value `true`. -// If you use that setting, the reconciler will use another job to drop the database. -// Be careful, no backup are performed! -// -// Database resource honors `aws.service-account` setting, so, you can create databases on an AWS server if you need. -// See [AWS accounts](#aws-account) -// -// Once a database is fully configured, it retains the postgres uri used. -// If the setting indicating the server uri changed, the Database object will set the field `.status.outOfSync` to true -// and will not change anything. -// -// Therefore, to switch to a new server, you must change the setting value, then drop the Database object. -// It will be recreated with correct uri. -// +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" -// +kubebuilder:printcolumn:name="Out of sync",type=string,JSONPath=".status.outOfSync",description="Is the databse configuration out of sync" -// +kubebuilder:printcolumn:name="Info",type=string,JSONPath=".status.info",description="Info" -type Database struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec DatabaseSpec `json:"spec,omitempty"` - Status DatabaseStatus `json:"status,omitempty"` -} - -func (in *Database) SetReady(b bool) { - in.Status.SetReady(b) -} - -func (in *Database) IsReady() bool { - return in.Status.Ready -} - -func (in *Database) SetError(s string) { - in.Status.SetError(s) -} - -func (a *Database) GetStack() string { - return a.Spec.Stack -} - -func (a *Database) isResource() {} - -func (in *Database) GetConditions() *Conditions { - return &in.Status.Conditions -} - -//+kubebuilder:object:root=true - -// DatabaseList contains a list of Database -type DatabaseList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Database `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Database{}, &DatabaseList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/gateway_types.go b/components/operator/api/formance.com/v1beta1/gateway_types.go deleted file mode 100644 index 4f335658fd..0000000000 --- a/components/operator/api/formance.com/v1beta1/gateway_types.go +++ /dev/null @@ -1,130 +0,0 @@ -/* -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 GatewayIngressTLS struct { - // Specify the secret name used for the tls configuration on the ingress - SecretName string `json:"secretName"` -} - -type GatewayIngress struct { - // Indicates the hostname on which the stack will be served. - // Example : `formance.example.com` - //+required - Host string `json:"host"` - // Indicate the scheme. - // - // Actually, It should be `https` unless you know what you are doing. - // +kubebuilder:default:="https" - Scheme string `json:"scheme"` - - // Ingress class to use - //+optional - IngressClassName *string `json:"ingressClassName,omitempty"` - - // Custom annotations to add on the ingress - Annotations map[string]string `json:"annotations,omitempty"` - // Allow to customize the tls part of the ingress - //+optional - TLS *GatewayIngressTLS `json:"tls,omitempty"` -} - -type GatewaySpec struct { - StackDependency `json:",inline"` - ModuleProperties `json:",inline"` - //+optional - // Allow to customize the generated ingress - Ingress *GatewayIngress `json:"ingress,omitempty"` -} - -type GatewayStatus struct { - Status `json:",inline"` - // Detected http apis. See [GatewayHTTPAPI](#gatewayhttpapi) - //+optional - SyncHTTPAPIs []string `json:"syncHTTPAPIs"` -} - -//+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="HTTP APIs",type=string,JSONPath=".status.syncHTTPAPIs",description="Synchronized http apis" -//+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 - -// Gateway is the Schema for the gateways API -type Gateway struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec GatewaySpec `json:"spec,omitempty"` - Status GatewayStatus `json:"status,omitempty"` -} - -func (in *Gateway) IsEE() bool { - return false -} - -func (in *Gateway) GetVersion() string { - return in.Spec.Version -} - -func (in *Gateway) GetConditions() *Conditions { - return &in.Status.Conditions -} - -func (in *Gateway) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *Gateway) IsReady() bool { - return in.Status.Ready -} - -func (in *Gateway) SetError(s string) { - in.Status.Info = s -} - -func (a Gateway) GetStack() string { - return a.Spec.Stack -} - -func (a Gateway) IsDebug() bool { - return a.Spec.Debug -} - -func (a Gateway) IsDev() bool { - return a.Spec.Dev -} - -//+kubebuilder:object:root=true - -// GatewayList contains a list of Gateway -type GatewayList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Gateway `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Gateway{}, &GatewayList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/gatewayhttpapi_types.go b/components/operator/api/formance.com/v1beta1/gatewayhttpapi_types.go deleted file mode 100644 index 5a199b5ad7..0000000000 --- a/components/operator/api/formance.com/v1beta1/gatewayhttpapi_types.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -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 GatewayHTTPAPIRule struct { - Path string `json:"path"` - //+optional - Methods []string `json:"methods"` - //+optional - //+kubebuilder:default:=false - Secured bool `json:"secured"` -} - -type GatewayHTTPAPISpec struct { - StackDependency `json:",inline"` - // Name indicates prefix api - Name string `json:"name"` - // Rules - Rules []GatewayHTTPAPIRule `json:"rules"` - // Health check endpoint - HealthCheckEndpoint string `json:"healthCheckEndpoint,omitempty"` -} - -type GatewayHTTPAPIStatus 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" - -// GatewayHTTPAPI is the Schema for the HTTPAPIs API -type GatewayHTTPAPI struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec GatewayHTTPAPISpec `json:"spec,omitempty"` - Status GatewayHTTPAPIStatus `json:"status,omitempty"` -} - -func (in *GatewayHTTPAPI) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *GatewayHTTPAPI) IsReady() bool { - return in.Status.Ready -} - -func (in *GatewayHTTPAPI) SetError(s string) { - in.Status.Info = s -} - -func (a GatewayHTTPAPI) GetStack() string { - return a.Spec.Stack -} - -func (in *GatewayHTTPAPI) GetConditions() *Conditions { - return &in.Status.Conditions -} - -//+kubebuilder:object:root=true - -// GatewayHTTPAPIList contains a list of GatewayHTTPAPI -type GatewayHTTPAPIList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []GatewayHTTPAPI `json:"items"` -} - -func init() { - SchemeBuilder.Register(&GatewayHTTPAPI{}, &GatewayHTTPAPIList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/groupversion_info.go b/components/operator/api/formance.com/v1beta1/groupversion_info.go deleted file mode 100644 index 0b91e4da56..0000000000 --- a/components/operator/api/formance.com/v1beta1/groupversion_info.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -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 contains API Schema definitions for the formance v1beta1 API group. -// -// It allow to configure a Formance stack. -// -// A stack is composed of a [Stack](#stack) resource and some [modules](#modules). -// -// Each module can create multiple resources following its needs. See [Other resources](#other-resources). -// -// Various parts of the stack can be configured either using the CRD properties or using some [Settings](#settings). -// -// +kubebuilder:object:generate=true -// +groupName=formance.com -package v1beta1 - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" -) - -var ( - // GroupVersion is group version used to register these objects - GroupVersion = schema.GroupVersion{Group: "formance.com", Version: "v1beta1"} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} - - // AddToScheme adds the types in this group-version to the given scheme. - AddToScheme = SchemeBuilder.AddToScheme -) diff --git a/components/operator/api/formance.com/v1beta1/ledger_types.go b/components/operator/api/formance.com/v1beta1/ledger_types.go deleted file mode 100644 index 6343893559..0000000000 --- a/components/operator/api/formance.com/v1beta1/ledger_types.go +++ /dev/null @@ -1,153 +0,0 @@ -/* -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 ( - "time" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type LockingStrategyRedisConfig struct { - Uri string `json:"uri,omitempty"` - // +optional - // +kubebuilder:default:=false - TLS bool `json:"tls"` - // +optional - // +kubebuilder:default:=false - InsecureTLS bool `json:"insecure,omitempty"` - // +optional - Duration time.Duration `json:"duration,omitempty"` - // +optional - Retry time.Duration `json:"retry,omitempty"` -} - -type LockingStrategy struct { - // +kubebuilder:Enum:={memory,redis} - // +kubebuilder:default:=memory - // +optional - Strategy string `json:"strategy,omitempty"` - // +optional - Redis *LockingStrategyRedisConfig `json:"redis"` -} - -type DeploymentStrategy string - -const ( - DeploymentStrategySingle = "single" - DeploymentStrategyMonoWriterMultipleReader = "single-writer" -) - -type LedgerSpec struct { - ModuleProperties `json:",inline"` - StackDependency `json:",inline"` - // +optional - Auth *AuthConfig `json:"auth,omitempty"` - //+kubebuilder:Enum:={single, single-writer} - //+kubebuilder:default:=single - //+optional - // Deprecated. - DeploymentStrategy DeploymentStrategy `json:"deploymentStrategy,omitempty"` - // Locking is intended for ledger v1 only - //+optional - Locking *LockingStrategy `json:"locking,omitempty"` -} - -type LedgerStatus struct { - Status `json:",inline"` -} - -// Ledger is the module allowing to install a ledger instance. -// -// The ledger is actually a stateful application on the writer part. -// So we cannot scale the ledger as we want without prior configuration. -// -// So, the ledger can run in two modes : -// * single instance: Only one instance will be deployed. We cannot scale in that mode. -// * single writer / multiple reader: In this mode, we will have a single writer and multiple readers if needed. -// -// Use setting `ledger.deployment-strategy` with either the value : -// - single : For the single instance mode. -// - single-writer: For the single writer / multiple reader mode. -// Under the hood, the operator create two deployments and force the scaling of the writer to stay at 1. -// Then you can scale the deployment of the reader to the value you want. -// -// +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 -type Ledger struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec LedgerSpec `json:"spec,omitempty"` - Status LedgerStatus `json:"status,omitempty"` -} - -func (in *Ledger) IsEE() bool { - return false -} - -func (in *Ledger) IsReady() bool { - return in.Status.Ready -} - -func (in *Ledger) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *Ledger) SetError(s string) { - in.Status.Info = s -} - -func (in *Ledger) GetConditions() *Conditions { - return &in.Status.Conditions -} - -func (in *Ledger) GetVersion() string { - return in.Spec.Version -} - -func (a Ledger) isEventPublisher() {} - -func (a Ledger) GetStack() string { - return a.Spec.Stack -} - -func (a Ledger) IsDebug() bool { - return a.Spec.Debug -} - -func (a Ledger) IsDev() bool { - return a.Spec.Dev -} - -//+kubebuilder:object:root=true - -// LedgerList contains a list of Ledger -type LedgerList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Ledger `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Ledger{}, &LedgerList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/orchestration_types.go b/components/operator/api/formance.com/v1beta1/orchestration_types.go deleted file mode 100644 index 5ee9f8312d..0000000000 --- a/components/operator/api/formance.com/v1beta1/orchestration_types.go +++ /dev/null @@ -1,105 +0,0 @@ -/* -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" -) - -type OrchestrationSpec struct { - StackDependency `json:",inline"` - ModuleProperties `json:",inline"` - // +optional - Auth *AuthConfig `json:"auth,omitempty"` -} - -type OrchestrationStatus struct { - Status `json:",inline"` - //+optional - TemporalURI *URI `json:"temporalURI,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="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 - -// Orchestration is the Schema for the orchestrations API -type Orchestration struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec OrchestrationSpec `json:"spec,omitempty"` - Status OrchestrationStatus `json:"status,omitempty"` -} - -func (in *Orchestration) isEventPublisher() {} - -func (in *Orchestration) IsEE() bool { - return false -} - -func (in *Orchestration) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *Orchestration) IsReady() bool { - return in.Status.Ready -} - -func (in *Orchestration) SetError(s string) { - in.Status.Info = s -} - -func (in *Orchestration) GetConditions() *Conditions { - return &in.Status.Conditions -} - -func (in *Orchestration) GetVersion() string { - return in.Spec.Version -} - -func (a Orchestration) GetStack() string { - return a.Spec.Stack -} - -func (a Orchestration) IsDebug() bool { - return a.Spec.Debug -} - -func (a Orchestration) IsDev() bool { - return a.Spec.Dev -} - -//+kubebuilder:object:root=true - -// OrchestrationList contains a list of Orchestration -type OrchestrationList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Orchestration `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Orchestration{}, &OrchestrationList{}) -} - -var _ EventPublisher = (*Orchestration)(nil) diff --git a/components/operator/api/formance.com/v1beta1/payments_types.go b/components/operator/api/formance.com/v1beta1/payments_types.go deleted file mode 100644 index 86ec13409f..0000000000 --- a/components/operator/api/formance.com/v1beta1/payments_types.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -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" -) - -type PaymentsSpec struct { - StackDependency `json:",inline"` - ModuleProperties `json:",inline"` - // +optional - EncryptionKey string `json:"encryptionKey"` - // +optional - Auth *AuthConfig `json:"auth,omitempty"` -} - -type PaymentsStatus 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 -// Payments is the Schema for the payments API -type Payments struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec PaymentsSpec `json:"spec,omitempty"` - Status PaymentsStatus `json:"status,omitempty"` -} - -func (in *Payments) IsEE() bool { - return false -} - -func (in *Payments) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *Payments) IsReady() bool { - return in.Status.Ready -} - -func (in *Payments) SetError(s string) { - in.Status.Info = s -} - -func (in *Payments) GetVersion() string { - return in.Spec.Version -} - -func (in Payments) isEventPublisher() {} - -func (in Payments) GetStack() string { - return in.Spec.Stack -} - -func (in Payments) IsDebug() bool { - return in.Spec.Debug -} - -func (in Payments) IsDev() bool { - return in.Spec.Dev -} - -func (in *Payments) GetConditions() *Conditions { - return &in.Status.Conditions -} - -//+kubebuilder:object:root=true - -// PaymentsList contains a list of Payments -type PaymentsList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Payments `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Payments{}, &PaymentsList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/reconciliation_types.go b/components/operator/api/formance.com/v1beta1/reconciliation_types.go deleted file mode 100644 index bb7a1b38ea..0000000000 --- a/components/operator/api/formance.com/v1beta1/reconciliation_types.go +++ /dev/null @@ -1,99 +0,0 @@ -/* -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" -) - -type ReconciliationSpec struct { - StackDependency `json:",inline"` - ModuleProperties `json:",inline"` - // +optional - Auth *AuthConfig `json:"auth,omitempty"` -} - -type ReconciliationStatus 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 - -// Reconciliation is the Schema for the reconciliations API -type Reconciliation struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec ReconciliationSpec `json:"spec,omitempty"` - Status ReconciliationStatus `json:"status,omitempty"` -} - -func (in *Reconciliation) IsEE() bool { - return true -} - -func (in *Reconciliation) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *Reconciliation) IsReady() bool { - return in.Status.Ready -} - -func (in *Reconciliation) SetError(s string) { - in.Status.Info = s -} - -func (in *Reconciliation) GetConditions() *Conditions { - return &in.Status.Conditions -} - -func (in *Reconciliation) GetVersion() string { - return in.Spec.Version -} - -func (a Reconciliation) IsDebug() bool { - return a.Spec.Debug -} - -func (a Reconciliation) IsDev() bool { - return a.Spec.Dev -} - -func (a Reconciliation) GetStack() string { - return a.Spec.Stack -} - -//+kubebuilder:object:root=true - -// ReconciliationList contains a list of Reconciliation -type ReconciliationList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Reconciliation `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Reconciliation{}, &ReconciliationList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/resourcereference_types.go b/components/operator/api/formance.com/v1beta1/resourcereference_types.go deleted file mode 100644 index 318f9f6bac..0000000000 --- a/components/operator/api/formance.com/v1beta1/resourcereference_types.go +++ /dev/null @@ -1,124 +0,0 @@ -/* -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" -) - -type ResourceReferenceSpec struct { - StackDependency `json:",inline"` - GroupVersionKind *metav1.GroupVersionKind `json:"gvk"` - Name string `json:"name"` -} - -type ResourceReferenceStatus struct { - Status `json:",inline"` - //+optional - SyncedResource string `json:"syncedResource,omitempty"` - //+optional - Hash string `json:"hash,omitempty"` -} - -// ResourceReference is a special resources used to refer to externally created resources. -// -// It includes k8s service accounts and secrets. -// -// Why? Because the operator create a namespace by stack, so, a stack does not have access to secrets and service -// accounts created externally. -// -// A ResourceReference is created by other resource who need to use a specific secret or service account. -// For example, if you want to use a secret for your database connection (see [Database](#database), you will -// create a setting indicating a secret name. You will need to create this secret yourself, and you will put this -// secret inside the namespace you want (`default` maybe). -// -// The Database reconciler will create a ResourceReference looking like that : -// ``` -// apiVersion: formance.com/v1beta1 -// kind: ResourceReference -// metadata: -// -// name: jqkuffjxcezj-qlii-auth-postgres -// ownerReferences: -// - apiVersion: formance.com/v1beta1 -// blockOwnerDeletion: true -// controller: true -// kind: Database -// name: jqkuffjxcezj-qlii-auth -// uid: 2cc4b788-3ffb-4e3d-8a30-07ed3941c8d2 -// -// spec: -// -// gvk: -// group: "" -// kind: Secret -// version: v1 -// name: postgres -// stack: jqkuffjxcezj-qlii -// -// status: -// -// ... -// -// ``` -// This reconciler behind this ResourceReference will search, in all namespaces, for a secret named "postgres". -// The secret must have a label `formance.com/stack` with the value matching either a specific stack or `any` to target any stack. -// -// Once the reconciler has found the secret, it will copy it inside the stack namespace, allowing the ResourceReconciler owner to use it. -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status -// +kubebuilder:resource:scope=Cluster -type ResourceReference struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec ResourceReferenceSpec `json:"spec,omitempty"` - Status ResourceReferenceStatus `json:"status,omitempty"` -} - -func (in *ResourceReference) SetReady(b bool) { - in.Status.SetReady(b) -} - -func (in *ResourceReference) IsReady() bool { - return in.Status.Ready -} - -func (in *ResourceReference) SetError(s string) { - in.Status.SetError(s) -} - -func (in *ResourceReference) GetStack() string { - return in.Spec.Stack -} - -func (in *ResourceReference) GetConditions() *Conditions { - return &in.Status.Conditions -} - -//+kubebuilder:object:root=true - -// ResourceReferenceList contains a list of ResourceReference -type ResourceReferenceList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ResourceReference `json:"items"` -} - -func init() { - SchemeBuilder.Register(&ResourceReference{}, &ResourceReferenceList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/search_types.go b/components/operator/api/formance.com/v1beta1/search_types.go deleted file mode 100644 index 86032fee53..0000000000 --- a/components/operator/api/formance.com/v1beta1/search_types.go +++ /dev/null @@ -1,106 +0,0 @@ -/* -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" -) - -type SearchSpec struct { - StackDependency `json:",inline"` - ModuleProperties `json:",inline"` - //+optional - Batching *Batching `json:"batching,omitempty"` - // +optional - Auth *AuthConfig `json:"auth,omitempty"` -} - -type SearchStatus struct { - Status `json:",inline"` - //+optional - ElasticSearchURI *URI `json:"elasticSearchURI,omitempty"` - // TopicCleaned is used to flag stacks where the topics have been cleaned (still search-ledgerv2 and co consumers) - //+optional - // +kubebuilder:default:=false - TopicCleaned bool `json:"topicCleaned,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="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 -// Search is the Schema for the searches API -type Search struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec SearchSpec `json:"spec,omitempty"` - Status SearchStatus `json:"status,omitempty"` -} - -func (in *Search) IsEE() bool { - return false -} - -func (in *Search) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *Search) IsReady() bool { - return in.Status.Ready -} - -func (in *Search) SetError(s string) { - in.Status.Info = s -} - -func (in *Search) GetConditions() *Conditions { - return &in.Status.Conditions -} - -func (in *Search) GetVersion() string { - return in.Spec.Version -} - -func (a Search) GetStack() string { - return a.Spec.Stack -} - -func (a Search) IsDebug() bool { - return a.Spec.Debug -} - -func (a Search) IsDev() bool { - return a.Spec.Dev -} - -//+kubebuilder:object:root=true - -// SearchList contains a list of Search -type SearchList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Search `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Search{}, &SearchList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/settings_types.go b/components/operator/api/formance.com/v1beta1/settings_types.go deleted file mode 100644 index 863d0d944a..0000000000 --- a/components/operator/api/formance.com/v1beta1/settings_types.go +++ /dev/null @@ -1,193 +0,0 @@ -/* -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" -) - -type SettingsSpec struct { - //+optional - // Stacks on which the setting is applied. Can contain `*` to indicate a wildcard. - Stacks []string `json:"stacks,omitempty"` - // The setting Key. See the documentation of each module or [global settings](#global-settings) to discover them. - Key string `json:"key"` - // The value. It must have a specific format following the Key. - Value string `json:"value"` -} - -// Settings represents a configurable piece of the stacks. -// -// The purpose of this resource is to be able to configure some common settings between a set of stacks. -// -// Example : -// ```yaml -// apiVersion: formance.com/v1beta1 -// kind: Settings -// metadata: -// -// name: postgres-uri -// -// spec: -// -// key: postgres.ledger.uri -// stacks: -// - stack0 -// value: postgresql://postgresql.formance.svc.cluster.local:5432 -// -// ``` -// -// This example create a setting named `postgres-uri` targeting the stack named `stack0` and the service `ledger` (see the key `postgres.ledger.uri`). -// -// Therefore, a [Database](#database) created for the stack `stack0` and the service named 'ledger' will use the uri `postgresql://postgresql.formance.svc.cluster.local:5432`. -// -// Settings allow to use wildcards in keys and in stacks list. -// -// For example, if you want to use the same database server for all the modules of a specific stack, you can write : -// ```yaml -// apiVersion: formance.com/v1beta1 -// kind: Settings -// metadata: -// -// name: postgres-uri -// -// spec: -// -// key: postgres.*.uri # There, we use a wildcard to indicate we want to use that setting of all services of the stack `stack0` -// stacks: -// - stack0 -// value: postgresql://postgresql.formance.svc.cluster.local:5432 -// -// ``` -// -// Also, we could use that setting for all of our stacks using : -// ```yaml -// apiVersion: formance.com/v1beta1 -// kind: Settings -// metadata: -// -// name: postgres-uri -// -// spec: -// -// key: postgres.*.uri # There, we use a wildcard to indicate we want to use that setting for all services of all stacks -// stacks: -// - * # There we select all the stacks -// value: postgresql://postgresql.formance.svc.cluster.local:5432 -// -// ``` -// -// Some settings are really global, while some are used by specific module. -// -// Refer to the documentation of each module and resource to discover available Settings. -// -// ##### Global settings -// ###### AWS account -// -// A stack can use an AWS account for authentication. -// -// It can be used to connect to any AWS service we could use. -// -// It includes RDS, OpenSearch and MSK. To do so, you can create the following setting: -// ```yaml -// apiVersion: formance.com/v1beta1 -// kind: Settings -// metadata: -// -// name: aws-service-account -// -// spec: -// -// key: aws.service-account -// stacks: -// - '*' -// value: aws-access -// -// ``` -// This setting instruct the operator than there is somewhere on the cluster a service account named `aws-access`. -// -// So, each time a service has the capability to use AWS, the operator will use this service account. -// -// The service account could look like that : -// ```yaml -// apiVersion: v1 -// kind: ServiceAccount -// metadata: -// -// annotations: -// eks.amazonaws.com/role-arn: arn:aws:iam::************:role/staging-eu-west-1-hosting-stack-access -// labels: -// formance.com/stack: any -// name: aws-access -// -// ``` -// You can note two things : -// 1. We have an annotation indicating the role arn used to connect to AWS. Refer to the AWS documentation to create this role -// 2. We have a label `formance.com/stack=any` indicating we are targeting all stacks. -// Refer to the documentation of [ResourceReference](#resourcereference) for further information. -// -// ###### JSON logging -// -// You can use the setting `logging.json` with the value `true` to configure elligible service to log as json. -// Example: -// ```yaml -// apiVersion: formance.com/v1beta1 -// kind: Settings -// metadata: -// -// name: json-logging -// -// spec: -// -// key: logging.json -// stacks: -// - '*' -// value: "true" -// -// ``` -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status -// +kubebuilder:resource:scope=Cluster -// +kubebuilder:printcolumn:name="Key",type=string,JSONPath=".spec.key",description="Key" -// +kubebuilder:printcolumn:name="Value",type=string,JSONPath=".spec.value",description="Value" -type Settings struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec SettingsSpec `json:"spec,omitempty"` -} - -func (in *Settings) GetStacks() []string { - return in.Spec.Stacks -} - -func (in *Settings) IsWildcard() bool { - return len(in.Spec.Stacks) == 1 && in.Spec.Stacks[0] == "*" -} - -//+kubebuilder:object:root=true - -// SettingsList contains a list of Settings -type SettingsList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Settings `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Settings{}, &SettingsList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/shared.go b/components/operator/api/formance.com/v1beta1/shared.go deleted file mode 100644 index 314fcd3dae..0000000000 --- a/components/operator/api/formance.com/v1beta1/shared.go +++ /dev/null @@ -1,394 +0,0 @@ -package v1beta1 - -import ( - "encoding/json" - "fmt" - "net/url" - "slices" - - "github.com/formancehq/go-libs/pointer" - "golang.org/x/mod/semver" - "k8s.io/apimachinery/pkg/api/equality" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// +kubebuilder:object:generate=false -type EventPublisher interface { - isEventPublisher() -} - -type DevProperties struct { - // +optional - // Allow to enable debug mode on the module - // +kubebuilder:default:=false - Debug bool `json:"debug"` - // +optional - // 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) - // +kubebuilder:default:=false - Dev bool `json:"dev"` -} - -func (p DevProperties) IsDebug() bool { - return p.Debug -} - -func (p DevProperties) IsDev() bool { - return p.Dev -} - -// Condition contains details for one aspect of the current state of this API Resource. -// --- -// This struct is intended for direct use as an array at the field path .status.conditions. For example, -// -// type FooStatus struct{ -// // Represents the observations of a foo's current state. -// // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" -// // +patchMergeKey=type -// // +patchStrategy=merge -// // +listType=map -// // +listMapKey=type -// Status []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` -// -// // other fields -// } -type Condition struct { - // 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) - // +required - // +kubebuilder:validation:Required - // +kubebuilder:validation: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])$` - // +kubebuilder:validation:MaxLength=316 - Type string `json:"type" protobuf:"bytes,1,opt,name=type"` - // status of the condition, one of True, False, Unknown. - // +required - // +kubebuilder:validation:Required - // +kubebuilder:validation:Enum=True;False;Unknown - Status metav1.ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status"` - // 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. - // +optional - // +kubebuilder:validation:Minimum=0 - ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,3,opt,name=observedGeneration"` - // 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. - // +required - // +kubebuilder:validation:Required - // +kubebuilder:validation:Type=string - // +kubebuilder:validation:Format=date-time - LastTransitionTime metav1.Time `json:"lastTransitionTime" protobuf:"bytes,4,opt,name=lastTransitionTime"` - // message is a human readable message indicating details about the transition. - // This may be an empty string. - // +kubebuilder:validation:Required - // +kubebuilder:validation:MaxLength=32768 - Message string `json:"message" protobuf:"bytes,6,opt,name=message"` - // 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. - // +optional - // +kubebuilder:validation:MaxLength=1024 - // +kubebuilder:validation:Pattern=`^([A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?)?$` - Reason string `json:"reason,omitempty" protobuf:"bytes,5,opt,name=reason"` -} - -func (in *Condition) SetStatus(v metav1.ConditionStatus) *Condition { - in.Status = v - - return in -} - -func (in *Condition) SetMessage(v string) *Condition { - in.Message = v - - return in -} - -func (in *Condition) SetReason(reason string) *Condition { - in.Reason = reason - - return in -} - -func (in *Condition) Fail(v string) *Condition { - in.SetStatus(metav1.ConditionFalse) - in.SetMessage(v) - - return in -} - -func NewCondition(t string, generation int64) *Condition { - return &Condition{ - Type: t, - Status: metav1.ConditionTrue, - ObservedGeneration: generation, - LastTransitionTime: metav1.Now(), - } -} - -type Conditions []Condition - -func (c *Conditions) Delete(p ConditionPredicate) *Conditions { - for i, existingCondition := range *c { - if p(existingCondition) { - if i < len(*c)-1 { - *c = append((*c)[:i], (*c)[i+1:]...) - } else { - *c = (*c)[:i] - } - return c - } - } - return c -} - -func (c *Conditions) AppendOrReplace(newCondition Condition, p ConditionPredicate) *Condition { - c.Delete(p) - *c = append(*c, newCondition) - slices.SortStableFunc(*c, func(a, b Condition) int { - switch { - case a.Type < b.Type: - return -1 - case a.Type > b.Type: - return 1 - default: - switch { - case a.Reason < b.Reason: - return -1 - case a.Reason > b.Reason: - return 1 - default: - return 0 - } - } - }) - return &newCondition -} - -func (c *Conditions) Get(conditionType string) *Condition { - for _, condition := range *c { - if condition.Type == conditionType { - return &condition - } - } - return nil -} - -func (c *Conditions) Check(p ConditionPredicate) bool { - for _, condition := range *c { - if condition.Status == metav1.ConditionTrue && p(condition) { - return true - } - } - return false -} - -// +kubebuilder:object:generate=false -type ConditionPredicate func(condition Condition) bool - -func AndConditions(predicates ...ConditionPredicate) ConditionPredicate { - return func(condition Condition) bool { - for _, predicate := range predicates { - if !predicate(condition) { - return false - } - } - return true - } -} - -func ConditionTypeMatch(t string) ConditionPredicate { - return func(condition Condition) bool { - return condition.Type == t - } -} - -func ConditionReasonMatch(reason string) ConditionPredicate { - return func(condition Condition) bool { - return condition.Reason == reason - } -} - -func ConditionGenerationMatch(generation int64) ConditionPredicate { - return func(condition Condition) bool { - return condition.ObservedGeneration == generation - } -} - -type Status struct { - //+optional - // Ready indicates if the resource is seen as completely reconciled - Ready bool `json:"ready"` - //+optional - // Info can contain any additional like reconciliation errors - Info string `json:"info,omitempty"` - //+optional - Conditions Conditions `json:"conditions,omitempty"` -} - -func (c *Status) SetReady(ready bool) { - c.Ready = ready -} - -func (c *Status) SetError(err string) { - c.Info = err -} - -type AuthConfig struct { - // +optional - ReadKeySetMaxRetries int `json:"readKeySetMaxRetries"` - // +optional - CheckScopes bool `json:"checkScopes"` -} - -// +kubebuilder:object:generate=false -type Module interface { - Dependent - GetVersion() string - IsDebug() bool - IsDev() bool - IsEE() bool -} - -type ModuleProperties struct { - DevProperties `json:",inline"` - //+optional - // Version allow to override global version defined at stack level for a specific module - Version string `json:"version,omitempty"` -} - -func (in *ModuleProperties) CompareVersion(stack *Stack, version string) int { - actualVersion := in.Version - if actualVersion == "" { - actualVersion = stack.Spec.Version - } - if !semver.IsValid(actualVersion) { - return 1 - } - - return semver.Compare(actualVersion, version) -} - -// +kubebuilder:object:generate=false -type Dependent interface { - Object - GetStack() string -} - -type StackDependency struct { - // Stack indicates the stack on which the module is installed - Stack string `json:"stack,omitempty" yaml:"-"` -} - -func (d StackDependency) GetStack() string { - return d.Stack -} - -// +kubebuilder:object:generate=false -type Object interface { - client.Object - SetReady(bool) - IsReady() bool - SetError(string) - GetConditions() *Conditions -} - -// +kubebuilder:object:generate=false -type Resource interface { - Dependent - isResource() -} - -// +k8s:openapi-gen=true -// +kubebuilder:validation:Type=string -type URI struct { - *url.URL `json:"-"` -} - -func (u URI) String() string { - if u.URL == nil { - return "nil" - } - return u.URL.String() -} - -func (u URI) IsZero() bool { - return u.URL == nil -} - -func (u *URI) DeepCopyInto(v *URI) { - cp := *u.URL - if u.User != nil { - cp.User = pointer.For(*u.User) - } - v.URL = pointer.For(cp) -} - -func (u *URI) MarshalJSON() ([]byte, error) { - return []byte(fmt.Sprintf(`"%s"`, u.String())), nil -} - -func (u *URI) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return nil - } - - v, err := url.Parse(s) - if err != nil { - panic(err) - } - - *u = URI{ - URL: v, - } - return nil -} - -func (in *URI) WithoutQuery() *URI { - cp := *in.URL - cp.ForceQuery = false - cp.RawQuery = "" - return &URI{ - URL: &cp, - } -} - -func ParseURL(v string) (*URI, error) { - ret, err := url.Parse(v) - if err != nil { - return nil, err - } - return &URI{ - URL: ret, - }, nil -} - -func init() { - if err := equality.Semantic.AddFunc(func(a, b *URI) bool { - if a == nil && b != nil { - return false - } - if a != nil && b == nil { - return false - } - if a == nil && b == nil { - return true - } - return a.String() == b.String() - }); err != nil { - panic(err) - } -} - -const ( - StackLabel = "formance.com/stack" - SkipLabel = "formance.com/skip" - CreatedByAgentLabel = "formance.com/created-by-agent" -) diff --git a/components/operator/api/formance.com/v1beta1/stack_types.go b/components/operator/api/formance.com/v1beta1/stack_types.go deleted file mode 100644 index 8cca584aab..0000000000 --- a/components/operator/api/formance.com/v1beta1/stack_types.go +++ /dev/null @@ -1,122 +0,0 @@ -/* -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" -) - -type StackSpec struct { - DevProperties `json:",inline"` - // +optional - // Version allow to specify the version of the components - // Must be a valid docker tag - Version string `json:"version,omitempty"` - // +optional - // VersionsFromFile allow to specify a formance.com/Versions object which contains individual versions - // for each component. - // Must reference a valid formance.com/Versions object - VersionsFromFile string `json:"versionsFromFile"` - // +optional - // +kubebuilder:default:=false - // EnableAudit enable audit at the stack level. - // Actually, it enables audit on [Gateway](#gateway) - EnableAudit bool `json:"enableAudit,omitempty"` - // +optional - // +kubebuilder:default:=false - // Disabled indicate the stack is disabled. - // A disabled stack disable everything - // It just keeps the namespace and the [Database](#database) resources. - Disabled bool `json:"disabled"` -} - -type StackStatus struct { - Status `json:",inline"` - // Modules register detected modules - Modules []string `json:"modules,omitempty"` -} - -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status -//+kubebuilder:resource:scope=Cluster -//+kubebuilder:printcolumn:name="Disable",type=string,JSONPath=".spec.disabled",description="Stack Disabled" -//+kubebuilder:printcolumn:name="Version",type="string",JSONPath=".spec.version",description="Stack Version" -//+kubebuilder:printcolumn:name="Versions From file",type="string",JSONPath=".spec.versionsFromFile",description="Stack Version From File" -//+kubebuilder:printcolumn:name="Ready",type="boolean",JSONPath=".status.ready",description="Is stack ready" -//+kubebuilder:printcolumn:name="Modules",type=string,JSONPath=".status.modules",description="Modules List Registered" -//+kubebuilder:printcolumn:name="Info",type=string,JSONPath=".status.info",description="Info" - -// Stack represents a formance stack. -// A Stack is basically a container. It holds some global properties and -// creates a namespace if not already existing. -// -// To do more, you need to create some [modules](#modules). -// -// The Stack resource allow to specify the version of the stack. -// -// It can be specified using either the field `.spec.version` or the `.spec.versionsFromFile` field (Refer to the documentation of [Versions](#versions) resource. -// -// The `version` field will have priority over `versionFromFile`. -// -// If `versions` and `versionsFromFile` are not specified, "latest" will be used. -type Stack struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec StackSpec `json:"spec,omitempty"` - Status StackStatus `json:"status,omitempty"` -} - -func (in *Stack) SetReady(b bool) { - in.Status.SetReady(b) -} - -func (in *Stack) IsReady() bool { - return in.Status.Ready -} - -func (in *Stack) SetError(s string) { - in.Status.SetError(s) -} - -func (in *Stack) GetVersion() string { - if in.Spec.Version == "" { - return "latest" - } - return in.Spec.Version -} - -func (in *Stack) MustSkip() bool { - return in.GetAnnotations()[SkipLabel] == "true" -} - -func (in *Stack) GetConditions() *Conditions { - return &in.Status.Conditions -} - -//+kubebuilder:object:root=true - -// StackList contains a list of Stack -type StackList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Stack `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Stack{}, &StackList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/stargate_types.go b/components/operator/api/formance.com/v1beta1/stargate_types.go deleted file mode 100644 index 235d3d5d27..0000000000 --- a/components/operator/api/formance.com/v1beta1/stargate_types.go +++ /dev/null @@ -1,106 +0,0 @@ -/* -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" -) - -type StargateAuthSpec struct { - ClientID string `json:"clientID"` - ClientSecret string `json:"clientSecret"` - Issuer string `json:"issuer"` -} - -type StargateSpec struct { - ModuleProperties `json:",inline"` - StackDependency `json:",inline"` - ServerURL string `json:"serverURL"` - OrganizationID string `json:"organizationID"` - StackID string `json:"stackID"` - Auth StargateAuthSpec `json:"auth"` -} - -// StargateStatus defines the observed state of Stargate -type StargateStatus 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 -// Stargate is the Schema for the stargates API -type Stargate struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec StargateSpec `json:"spec,omitempty"` - Status StargateStatus `json:"status,omitempty"` -} - -func (in *Stargate) IsEE() bool { - return false -} - -func (in *Stargate) GetVersion() string { - return in.Spec.Version -} - -func (in *Stargate) GetConditions() *Conditions { - return &in.Status.Conditions -} - -func (in *Stargate) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *Stargate) IsReady() bool { - return in.Status.Ready -} - -func (in *Stargate) SetError(s string) { - in.Status.Info = s -} - -func (a Stargate) IsDebug() bool { - return a.Spec.Debug -} - -func (a Stargate) IsDev() bool { - return a.Spec.Dev -} - -func (s Stargate) GetStack() string { - return s.Spec.Stack -} - -//+kubebuilder:object:root=true - -// StargateList contains a list of Stargate -type StargateList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Stargate `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Stargate{}, &StargateList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/versions_types.go b/components/operator/api/formance.com/v1beta1/versions_types.go deleted file mode 100644 index 4ec8a9f0de..0000000000 --- a/components/operator/api/formance.com/v1beta1/versions_types.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -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" -) - -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status -//+kubebuilder:resource:scope=Cluster - -// Versions is the Schema for the versions API -type Versions struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec map[string]string `json:"spec,omitempty"` -} - -//+kubebuilder:object:root=true - -// VersionsList contains a list of Versions -type VersionsList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Versions `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Versions{}, &VersionsList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/wallets_types.go b/components/operator/api/formance.com/v1beta1/wallets_types.go deleted file mode 100644 index 033caa90f8..0000000000 --- a/components/operator/api/formance.com/v1beta1/wallets_types.go +++ /dev/null @@ -1,99 +0,0 @@ -/* -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" -) - -type WalletsSpec struct { - ModuleProperties `json:",inline"` - StackDependency `json:",inline"` - // +optional - Auth *AuthConfig `json:"auth,omitempty"` -} - -// WalletsStatus defines the observed state of Wallets -type WalletsStatus 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 -// Wallets is the Schema for the wallets API -type Wallets struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec WalletsSpec `json:"spec,omitempty"` - Status WalletsStatus `json:"status,omitempty"` -} - -func (in *Wallets) IsEE() bool { - return false -} - -func (in *Wallets) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *Wallets) IsReady() bool { - return in.Status.Ready -} - -func (in *Wallets) SetError(s string) { - in.Status.Info = s -} - -func (in *Wallets) GetConditions() *Conditions { - return &in.Status.Conditions -} - -func (in *Wallets) GetVersion() string { - return in.Spec.Version -} - -func (a Wallets) GetStack() string { - return a.Spec.Stack -} - -func (a Wallets) IsDebug() bool { - return a.Spec.Debug -} - -func (a Wallets) IsDev() bool { - return a.Spec.Dev -} - -//+kubebuilder:object:root=true - -// WalletsList contains a list of Wallets -type WalletsList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Wallets `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Wallets{}, &WalletsList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/webhooks_types.go b/components/operator/api/formance.com/v1beta1/webhooks_types.go deleted file mode 100644 index 923f78b9a4..0000000000 --- a/components/operator/api/formance.com/v1beta1/webhooks_types.go +++ /dev/null @@ -1,98 +0,0 @@ -/* -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" -) - -type WebhooksSpec struct { - StackDependency `json:",inline"` - ModuleProperties `json:",inline"` - // +optional - Auth *AuthConfig `json:"auth,omitempty"` -} - -type WebhooksStatus 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 -// Webhooks is the Schema for the webhooks API -type Webhooks struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec WebhooksSpec `json:"spec,omitempty"` - Status WebhooksStatus `json:"status,omitempty"` -} - -func (in *Webhooks) IsEE() bool { - return false -} - -func (in *Webhooks) SetReady(b bool) { - in.Status.Ready = b -} - -func (in *Webhooks) IsReady() bool { - return in.Status.Ready -} - -func (in *Webhooks) SetError(s string) { - in.Status.Info = s -} - -func (in *Webhooks) GetConditions() *Conditions { - return &in.Status.Conditions -} - -func (in *Webhooks) GetVersion() string { - return in.Spec.Version -} - -func (a Webhooks) GetStack() string { - return a.Spec.Stack -} - -func (a Webhooks) IsDebug() bool { - return a.Spec.Debug -} - -func (a Webhooks) IsDev() bool { - return a.Spec.Dev -} - -//+kubebuilder:object:root=true - -// WebhooksList contains a list of Webhooks -type WebhooksList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Webhooks `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Webhooks{}, &WebhooksList{}) -} diff --git a/components/operator/api/formance.com/v1beta1/zz_generated.deepcopy.go b/components/operator/api/formance.com/v1beta1/zz_generated.deepcopy.go deleted file mode 100644 index f9ef6bc6f4..0000000000 --- a/components/operator/api/formance.com/v1beta1/zz_generated.deepcopy.go +++ /dev/null @@ -1,2519 +0,0 @@ -//go:build !ignore_autogenerated - -/* -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. -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package v1beta1 - -import ( - "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - 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 - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Auth. -func (in *Auth) DeepCopy() *Auth { - if in == nil { - return nil - } - out := new(Auth) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Auth) 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 *AuthClient) DeepCopyInto(out *AuthClient) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthClient. -func (in *AuthClient) DeepCopy() *AuthClient { - if in == nil { - return nil - } - out := new(AuthClient) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *AuthClient) 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 *AuthClientList) DeepCopyInto(out *AuthClientList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]AuthClient, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthClientList. -func (in *AuthClientList) DeepCopy() *AuthClientList { - if in == nil { - return nil - } - out := new(AuthClientList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *AuthClientList) 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 *AuthClientSpec) DeepCopyInto(out *AuthClientSpec) { - *out = *in - out.StackDependency = in.StackDependency - if in.RedirectUris != nil { - in, out := &in.RedirectUris, &out.RedirectUris - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.PostLogoutRedirectUris != nil { - in, out := &in.PostLogoutRedirectUris, &out.PostLogoutRedirectUris - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Scopes != nil { - in, out := &in.Scopes, &out.Scopes - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthClientSpec. -func (in *AuthClientSpec) DeepCopy() *AuthClientSpec { - if in == nil { - return nil - } - out := new(AuthClientSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AuthClientStatus) DeepCopyInto(out *AuthClientStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthClientStatus. -func (in *AuthClientStatus) DeepCopy() *AuthClientStatus { - if in == nil { - return nil - } - out := new(AuthClientStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AuthConfig) DeepCopyInto(out *AuthConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthConfig. -func (in *AuthConfig) DeepCopy() *AuthConfig { - if in == nil { - return nil - } - out := new(AuthConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AuthList) DeepCopyInto(out *AuthList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Auth, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthList. -func (in *AuthList) DeepCopy() *AuthList { - if in == nil { - return nil - } - out := new(AuthList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *AuthList) 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 *AuthSpec) DeepCopyInto(out *AuthSpec) { - *out = *in - out.ModuleProperties = in.ModuleProperties - out.StackDependency = in.StackDependency - if in.DelegatedOIDCServer != nil { - in, out := &in.DelegatedOIDCServer, &out.DelegatedOIDCServer - *out = new(DelegatedOIDCServerConfiguration) - **out = **in - } - if in.SigningKeyFromSecret != nil { - in, out := &in.SigningKeyFromSecret, &out.SigningKeyFromSecret - *out = new(v1.SecretKeySelector) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthSpec. -func (in *AuthSpec) DeepCopy() *AuthSpec { - if in == nil { - return nil - } - out := new(AuthSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AuthStatus) DeepCopyInto(out *AuthStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) - if in.Clients != nil { - in, out := &in.Clients, &out.Clients - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthStatus. -func (in *AuthStatus) DeepCopy() *AuthStatus { - if in == nil { - return nil - } - out := new(AuthStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Batching) DeepCopyInto(out *Batching) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Batching. -func (in *Batching) DeepCopy() *Batching { - if in == nil { - return nil - } - out := new(Batching) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Benthos) DeepCopyInto(out *Benthos) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Benthos. -func (in *Benthos) DeepCopy() *Benthos { - if in == nil { - return nil - } - out := new(Benthos) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Benthos) 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 *BenthosList) DeepCopyInto(out *BenthosList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Benthos, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BenthosList. -func (in *BenthosList) DeepCopy() *BenthosList { - if in == nil { - return nil - } - out := new(BenthosList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BenthosList) 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 *BenthosSpec) DeepCopyInto(out *BenthosSpec) { - *out = *in - out.StackDependency = in.StackDependency - out.DevProperties = in.DevProperties - if in.ResourceProperties != nil { - in, out := &in.ResourceProperties, &out.ResourceProperties - *out = new(v1.ResourceRequirements) - (*in).DeepCopyInto(*out) - } - if in.Batching != nil { - in, out := &in.Batching, &out.Batching - *out = new(Batching) - **out = **in - } - if in.InitContainers != nil { - in, out := &in.InitContainers, &out.InitContainers - *out = make([]v1.Container, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BenthosSpec. -func (in *BenthosSpec) DeepCopy() *BenthosSpec { - if in == nil { - return nil - } - out := new(BenthosSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BenthosStatus) DeepCopyInto(out *BenthosStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) - if in.ElasticSearchURI != nil { - in, out := &in.ElasticSearchURI, &out.ElasticSearchURI - *out = (*in).DeepCopy() - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BenthosStatus. -func (in *BenthosStatus) DeepCopy() *BenthosStatus { - if in == nil { - return nil - } - out := new(BenthosStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BenthosStream) DeepCopyInto(out *BenthosStream) { - *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 BenthosStream. -func (in *BenthosStream) DeepCopy() *BenthosStream { - if in == nil { - return nil - } - out := new(BenthosStream) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BenthosStream) 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 *BenthosStreamList) DeepCopyInto(out *BenthosStreamList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]BenthosStream, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BenthosStreamList. -func (in *BenthosStreamList) DeepCopy() *BenthosStreamList { - if in == nil { - return nil - } - out := new(BenthosStreamList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BenthosStreamList) 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 *BenthosStreamSpec) DeepCopyInto(out *BenthosStreamSpec) { - *out = *in - out.StackDependency = in.StackDependency -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BenthosStreamSpec. -func (in *BenthosStreamSpec) DeepCopy() *BenthosStreamSpec { - if in == nil { - return nil - } - out := new(BenthosStreamSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BenthosStreamStatus) DeepCopyInto(out *BenthosStreamStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BenthosStreamStatus. -func (in *BenthosStreamStatus) DeepCopy() *BenthosStreamStatus { - if in == nil { - return nil - } - out := new(BenthosStreamStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Broker) DeepCopyInto(out *Broker) { - *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 Broker. -func (in *Broker) DeepCopy() *Broker { - if in == nil { - return nil - } - out := new(Broker) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Broker) 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 *BrokerConsumer) DeepCopyInto(out *BrokerConsumer) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerConsumer. -func (in *BrokerConsumer) DeepCopy() *BrokerConsumer { - if in == nil { - return nil - } - out := new(BrokerConsumer) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BrokerConsumer) 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 *BrokerConsumerList) DeepCopyInto(out *BrokerConsumerList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]BrokerConsumer, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerConsumerList. -func (in *BrokerConsumerList) DeepCopy() *BrokerConsumerList { - if in == nil { - return nil - } - out := new(BrokerConsumerList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BrokerConsumerList) 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 *BrokerConsumerSpec) DeepCopyInto(out *BrokerConsumerSpec) { - *out = *in - out.StackDependency = in.StackDependency - if in.Services != nil { - in, out := &in.Services, &out.Services - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerConsumerSpec. -func (in *BrokerConsumerSpec) DeepCopy() *BrokerConsumerSpec { - if in == nil { - return nil - } - out := new(BrokerConsumerSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BrokerConsumerStatus) DeepCopyInto(out *BrokerConsumerStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerConsumerStatus. -func (in *BrokerConsumerStatus) DeepCopy() *BrokerConsumerStatus { - if in == nil { - return nil - } - out := new(BrokerConsumerStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BrokerList) DeepCopyInto(out *BrokerList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Broker, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerList. -func (in *BrokerList) DeepCopy() *BrokerList { - if in == nil { - return nil - } - out := new(BrokerList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BrokerList) 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 *BrokerSpec) DeepCopyInto(out *BrokerSpec) { - *out = *in - out.StackDependency = in.StackDependency -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerSpec. -func (in *BrokerSpec) DeepCopy() *BrokerSpec { - if in == nil { - return nil - } - out := new(BrokerSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BrokerStatus) DeepCopyInto(out *BrokerStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) - if in.URI != nil { - in, out := &in.URI, &out.URI - *out = (*in).DeepCopy() - } - if in.Streams != nil { - in, out := &in.Streams, &out.Streams - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerStatus. -func (in *BrokerStatus) DeepCopy() *BrokerStatus { - if in == nil { - return nil - } - out := new(BrokerStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BrokerTopic) DeepCopyInto(out *BrokerTopic) { - *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 BrokerTopic. -func (in *BrokerTopic) DeepCopy() *BrokerTopic { - if in == nil { - return nil - } - out := new(BrokerTopic) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BrokerTopic) 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 *BrokerTopicList) DeepCopyInto(out *BrokerTopicList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]BrokerTopic, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerTopicList. -func (in *BrokerTopicList) DeepCopy() *BrokerTopicList { - if in == nil { - return nil - } - out := new(BrokerTopicList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BrokerTopicList) 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 *BrokerTopicSpec) DeepCopyInto(out *BrokerTopicSpec) { - *out = *in - out.StackDependency = in.StackDependency -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerTopicSpec. -func (in *BrokerTopicSpec) DeepCopy() *BrokerTopicSpec { - if in == nil { - return nil - } - out := new(BrokerTopicSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BrokerTopicStatus) DeepCopyInto(out *BrokerTopicStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BrokerTopicStatus. -func (in *BrokerTopicStatus) DeepCopy() *BrokerTopicStatus { - if in == nil { - return nil - } - out := new(BrokerTopicStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Condition) DeepCopyInto(out *Condition) { - *out = *in - in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. -func (in *Condition) DeepCopy() *Condition { - if in == nil { - return nil - } - out := new(Condition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in Conditions) DeepCopyInto(out *Conditions) { - { - in := &in - *out = make(Conditions, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Conditions. -func (in Conditions) DeepCopy() Conditions { - if in == nil { - return nil - } - out := new(Conditions) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Database) DeepCopyInto(out *Database) { - *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 Database. -func (in *Database) DeepCopy() *Database { - if in == nil { - return nil - } - out := new(Database) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Database) 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 *DatabaseList) DeepCopyInto(out *DatabaseList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Database, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatabaseList. -func (in *DatabaseList) DeepCopy() *DatabaseList { - if in == nil { - return nil - } - out := new(DatabaseList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DatabaseList) 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 *DatabaseSpec) DeepCopyInto(out *DatabaseSpec) { - *out = *in - out.StackDependency = in.StackDependency -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatabaseSpec. -func (in *DatabaseSpec) DeepCopy() *DatabaseSpec { - if in == nil { - return nil - } - out := new(DatabaseSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DatabaseStatus) DeepCopyInto(out *DatabaseStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) - if in.URI != nil { - in, out := &in.URI, &out.URI - *out = (*in).DeepCopy() - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatabaseStatus. -func (in *DatabaseStatus) DeepCopy() *DatabaseStatus { - if in == nil { - return nil - } - out := new(DatabaseStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DelegatedOIDCServerConfiguration) DeepCopyInto(out *DelegatedOIDCServerConfiguration) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DelegatedOIDCServerConfiguration. -func (in *DelegatedOIDCServerConfiguration) DeepCopy() *DelegatedOIDCServerConfiguration { - if in == nil { - return nil - } - out := new(DelegatedOIDCServerConfiguration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DevProperties) DeepCopyInto(out *DevProperties) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DevProperties. -func (in *DevProperties) DeepCopy() *DevProperties { - if in == nil { - return nil - } - out := new(DevProperties) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Gateway) DeepCopyInto(out *Gateway) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Gateway. -func (in *Gateway) DeepCopy() *Gateway { - if in == nil { - return nil - } - out := new(Gateway) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Gateway) 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 *GatewayHTTPAPI) DeepCopyInto(out *GatewayHTTPAPI) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayHTTPAPI. -func (in *GatewayHTTPAPI) DeepCopy() *GatewayHTTPAPI { - if in == nil { - return nil - } - out := new(GatewayHTTPAPI) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *GatewayHTTPAPI) 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 *GatewayHTTPAPIList) DeepCopyInto(out *GatewayHTTPAPIList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]GatewayHTTPAPI, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayHTTPAPIList. -func (in *GatewayHTTPAPIList) DeepCopy() *GatewayHTTPAPIList { - if in == nil { - return nil - } - out := new(GatewayHTTPAPIList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *GatewayHTTPAPIList) 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 *GatewayHTTPAPIRule) DeepCopyInto(out *GatewayHTTPAPIRule) { - *out = *in - if in.Methods != nil { - in, out := &in.Methods, &out.Methods - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayHTTPAPIRule. -func (in *GatewayHTTPAPIRule) DeepCopy() *GatewayHTTPAPIRule { - if in == nil { - return nil - } - out := new(GatewayHTTPAPIRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GatewayHTTPAPISpec) DeepCopyInto(out *GatewayHTTPAPISpec) { - *out = *in - out.StackDependency = in.StackDependency - if in.Rules != nil { - in, out := &in.Rules, &out.Rules - *out = make([]GatewayHTTPAPIRule, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayHTTPAPISpec. -func (in *GatewayHTTPAPISpec) DeepCopy() *GatewayHTTPAPISpec { - if in == nil { - return nil - } - out := new(GatewayHTTPAPISpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GatewayHTTPAPIStatus) DeepCopyInto(out *GatewayHTTPAPIStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayHTTPAPIStatus. -func (in *GatewayHTTPAPIStatus) DeepCopy() *GatewayHTTPAPIStatus { - if in == nil { - return nil - } - out := new(GatewayHTTPAPIStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GatewayIngress) DeepCopyInto(out *GatewayIngress) { - *out = *in - if in.IngressClassName != nil { - in, out := &in.IngressClassName, &out.IngressClassName - *out = new(string) - **out = **in - } - if in.Annotations != nil { - in, out := &in.Annotations, &out.Annotations - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.TLS != nil { - in, out := &in.TLS, &out.TLS - *out = new(GatewayIngressTLS) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayIngress. -func (in *GatewayIngress) DeepCopy() *GatewayIngress { - if in == nil { - return nil - } - out := new(GatewayIngress) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GatewayIngressTLS) DeepCopyInto(out *GatewayIngressTLS) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayIngressTLS. -func (in *GatewayIngressTLS) DeepCopy() *GatewayIngressTLS { - if in == nil { - return nil - } - out := new(GatewayIngressTLS) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GatewayList) DeepCopyInto(out *GatewayList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Gateway, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayList. -func (in *GatewayList) DeepCopy() *GatewayList { - if in == nil { - return nil - } - out := new(GatewayList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *GatewayList) 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 *GatewaySpec) DeepCopyInto(out *GatewaySpec) { - *out = *in - out.StackDependency = in.StackDependency - out.ModuleProperties = in.ModuleProperties - if in.Ingress != nil { - in, out := &in.Ingress, &out.Ingress - *out = new(GatewayIngress) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewaySpec. -func (in *GatewaySpec) DeepCopy() *GatewaySpec { - if in == nil { - return nil - } - out := new(GatewaySpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GatewayStatus) DeepCopyInto(out *GatewayStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) - if in.SyncHTTPAPIs != nil { - in, out := &in.SyncHTTPAPIs, &out.SyncHTTPAPIs - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayStatus. -func (in *GatewayStatus) DeepCopy() *GatewayStatus { - if in == nil { - return nil - } - out := new(GatewayStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Ledger) DeepCopyInto(out *Ledger) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ledger. -func (in *Ledger) DeepCopy() *Ledger { - if in == nil { - return nil - } - out := new(Ledger) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Ledger) 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 *LedgerList) DeepCopyInto(out *LedgerList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Ledger, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LedgerList. -func (in *LedgerList) DeepCopy() *LedgerList { - if in == nil { - return nil - } - out := new(LedgerList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *LedgerList) 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 *LedgerSpec) DeepCopyInto(out *LedgerSpec) { - *out = *in - out.ModuleProperties = in.ModuleProperties - out.StackDependency = in.StackDependency - if in.Auth != nil { - in, out := &in.Auth, &out.Auth - *out = new(AuthConfig) - **out = **in - } - if in.Locking != nil { - in, out := &in.Locking, &out.Locking - *out = new(LockingStrategy) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LedgerSpec. -func (in *LedgerSpec) DeepCopy() *LedgerSpec { - if in == nil { - return nil - } - out := new(LedgerSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LedgerStatus) DeepCopyInto(out *LedgerStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LedgerStatus. -func (in *LedgerStatus) DeepCopy() *LedgerStatus { - if in == nil { - return nil - } - out := new(LedgerStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LockingStrategy) DeepCopyInto(out *LockingStrategy) { - *out = *in - if in.Redis != nil { - in, out := &in.Redis, &out.Redis - *out = new(LockingStrategyRedisConfig) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LockingStrategy. -func (in *LockingStrategy) DeepCopy() *LockingStrategy { - if in == nil { - return nil - } - out := new(LockingStrategy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LockingStrategyRedisConfig) DeepCopyInto(out *LockingStrategyRedisConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LockingStrategyRedisConfig. -func (in *LockingStrategyRedisConfig) DeepCopy() *LockingStrategyRedisConfig { - if in == nil { - return nil - } - out := new(LockingStrategyRedisConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ModuleProperties) DeepCopyInto(out *ModuleProperties) { - *out = *in - out.DevProperties = in.DevProperties -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ModuleProperties. -func (in *ModuleProperties) DeepCopy() *ModuleProperties { - if in == nil { - return nil - } - out := new(ModuleProperties) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Orchestration) DeepCopyInto(out *Orchestration) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Orchestration. -func (in *Orchestration) DeepCopy() *Orchestration { - if in == nil { - return nil - } - out := new(Orchestration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Orchestration) 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 *OrchestrationList) DeepCopyInto(out *OrchestrationList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Orchestration, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OrchestrationList. -func (in *OrchestrationList) DeepCopy() *OrchestrationList { - if in == nil { - return nil - } - out := new(OrchestrationList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *OrchestrationList) 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 *OrchestrationSpec) DeepCopyInto(out *OrchestrationSpec) { - *out = *in - out.StackDependency = in.StackDependency - out.ModuleProperties = in.ModuleProperties - if in.Auth != nil { - in, out := &in.Auth, &out.Auth - *out = new(AuthConfig) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OrchestrationSpec. -func (in *OrchestrationSpec) DeepCopy() *OrchestrationSpec { - if in == nil { - return nil - } - out := new(OrchestrationSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OrchestrationStatus) DeepCopyInto(out *OrchestrationStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) - if in.TemporalURI != nil { - in, out := &in.TemporalURI, &out.TemporalURI - *out = (*in).DeepCopy() - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OrchestrationStatus. -func (in *OrchestrationStatus) DeepCopy() *OrchestrationStatus { - if in == nil { - return nil - } - out := new(OrchestrationStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Payments) DeepCopyInto(out *Payments) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Payments. -func (in *Payments) DeepCopy() *Payments { - if in == nil { - return nil - } - out := new(Payments) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Payments) 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 *PaymentsList) DeepCopyInto(out *PaymentsList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Payments, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PaymentsList. -func (in *PaymentsList) DeepCopy() *PaymentsList { - if in == nil { - return nil - } - out := new(PaymentsList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PaymentsList) 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 *PaymentsSpec) DeepCopyInto(out *PaymentsSpec) { - *out = *in - out.StackDependency = in.StackDependency - out.ModuleProperties = in.ModuleProperties - if in.Auth != nil { - in, out := &in.Auth, &out.Auth - *out = new(AuthConfig) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PaymentsSpec. -func (in *PaymentsSpec) DeepCopy() *PaymentsSpec { - if in == nil { - return nil - } - out := new(PaymentsSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PaymentsStatus) DeepCopyInto(out *PaymentsStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PaymentsStatus. -func (in *PaymentsStatus) DeepCopy() *PaymentsStatus { - if in == nil { - return nil - } - out := new(PaymentsStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Reconciliation) DeepCopyInto(out *Reconciliation) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Reconciliation. -func (in *Reconciliation) DeepCopy() *Reconciliation { - if in == nil { - return nil - } - out := new(Reconciliation) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Reconciliation) 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 *ReconciliationList) DeepCopyInto(out *ReconciliationList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Reconciliation, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReconciliationList. -func (in *ReconciliationList) DeepCopy() *ReconciliationList { - if in == nil { - return nil - } - out := new(ReconciliationList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ReconciliationList) 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 *ReconciliationSpec) DeepCopyInto(out *ReconciliationSpec) { - *out = *in - out.StackDependency = in.StackDependency - out.ModuleProperties = in.ModuleProperties - if in.Auth != nil { - in, out := &in.Auth, &out.Auth - *out = new(AuthConfig) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReconciliationSpec. -func (in *ReconciliationSpec) DeepCopy() *ReconciliationSpec { - if in == nil { - return nil - } - out := new(ReconciliationSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ReconciliationStatus) DeepCopyInto(out *ReconciliationStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReconciliationStatus. -func (in *ReconciliationStatus) DeepCopy() *ReconciliationStatus { - if in == nil { - return nil - } - out := new(ReconciliationStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceReference) DeepCopyInto(out *ResourceReference) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceReference. -func (in *ResourceReference) DeepCopy() *ResourceReference { - if in == nil { - return nil - } - out := new(ResourceReference) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ResourceReference) 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 *ResourceReferenceList) DeepCopyInto(out *ResourceReferenceList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]ResourceReference, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceReferenceList. -func (in *ResourceReferenceList) DeepCopy() *ResourceReferenceList { - if in == nil { - return nil - } - out := new(ResourceReferenceList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ResourceReferenceList) 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 *ResourceReferenceSpec) DeepCopyInto(out *ResourceReferenceSpec) { - *out = *in - out.StackDependency = in.StackDependency - if in.GroupVersionKind != nil { - in, out := &in.GroupVersionKind, &out.GroupVersionKind - *out = new(metav1.GroupVersionKind) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceReferenceSpec. -func (in *ResourceReferenceSpec) DeepCopy() *ResourceReferenceSpec { - if in == nil { - return nil - } - out := new(ResourceReferenceSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceReferenceStatus) DeepCopyInto(out *ResourceReferenceStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceReferenceStatus. -func (in *ResourceReferenceStatus) DeepCopy() *ResourceReferenceStatus { - if in == nil { - return nil - } - out := new(ResourceReferenceStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Search) DeepCopyInto(out *Search) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Search. -func (in *Search) DeepCopy() *Search { - if in == nil { - return nil - } - out := new(Search) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Search) 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 *SearchList) DeepCopyInto(out *SearchList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Search, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SearchList. -func (in *SearchList) DeepCopy() *SearchList { - if in == nil { - return nil - } - out := new(SearchList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *SearchList) 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 *SearchSpec) DeepCopyInto(out *SearchSpec) { - *out = *in - out.StackDependency = in.StackDependency - out.ModuleProperties = in.ModuleProperties - if in.Batching != nil { - in, out := &in.Batching, &out.Batching - *out = new(Batching) - **out = **in - } - if in.Auth != nil { - in, out := &in.Auth, &out.Auth - *out = new(AuthConfig) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SearchSpec. -func (in *SearchSpec) DeepCopy() *SearchSpec { - if in == nil { - return nil - } - out := new(SearchSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SearchStatus) DeepCopyInto(out *SearchStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) - if in.ElasticSearchURI != nil { - in, out := &in.ElasticSearchURI, &out.ElasticSearchURI - *out = (*in).DeepCopy() - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SearchStatus. -func (in *SearchStatus) DeepCopy() *SearchStatus { - if in == nil { - return nil - } - out := new(SearchStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Settings) DeepCopyInto(out *Settings) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Settings. -func (in *Settings) DeepCopy() *Settings { - if in == nil { - return nil - } - out := new(Settings) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Settings) 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 *SettingsList) DeepCopyInto(out *SettingsList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Settings, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SettingsList. -func (in *SettingsList) DeepCopy() *SettingsList { - if in == nil { - return nil - } - out := new(SettingsList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *SettingsList) 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 *SettingsSpec) DeepCopyInto(out *SettingsSpec) { - *out = *in - if in.Stacks != nil { - in, out := &in.Stacks, &out.Stacks - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SettingsSpec. -func (in *SettingsSpec) DeepCopy() *SettingsSpec { - if in == nil { - return nil - } - out := new(SettingsSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Stack) DeepCopyInto(out *Stack) { - *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 Stack. -func (in *Stack) DeepCopy() *Stack { - if in == nil { - return nil - } - out := new(Stack) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Stack) 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 *StackDependency) DeepCopyInto(out *StackDependency) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackDependency. -func (in *StackDependency) DeepCopy() *StackDependency { - if in == nil { - return nil - } - out := new(StackDependency) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StackList) DeepCopyInto(out *StackList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Stack, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackList. -func (in *StackList) DeepCopy() *StackList { - if in == nil { - return nil - } - out := new(StackList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *StackList) 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 *StackSpec) DeepCopyInto(out *StackSpec) { - *out = *in - out.DevProperties = in.DevProperties -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackSpec. -func (in *StackSpec) DeepCopy() *StackSpec { - if in == nil { - return nil - } - out := new(StackSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StackStatus) DeepCopyInto(out *StackStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) - if in.Modules != nil { - in, out := &in.Modules, &out.Modules - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackStatus. -func (in *StackStatus) DeepCopy() *StackStatus { - if in == nil { - return nil - } - out := new(StackStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Stargate) DeepCopyInto(out *Stargate) { - *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 Stargate. -func (in *Stargate) DeepCopy() *Stargate { - if in == nil { - return nil - } - out := new(Stargate) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Stargate) 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 *StargateAuthSpec) DeepCopyInto(out *StargateAuthSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StargateAuthSpec. -func (in *StargateAuthSpec) DeepCopy() *StargateAuthSpec { - if in == nil { - return nil - } - out := new(StargateAuthSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StargateList) DeepCopyInto(out *StargateList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Stargate, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StargateList. -func (in *StargateList) DeepCopy() *StargateList { - if in == nil { - return nil - } - out := new(StargateList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *StargateList) 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 *StargateSpec) DeepCopyInto(out *StargateSpec) { - *out = *in - out.ModuleProperties = in.ModuleProperties - out.StackDependency = in.StackDependency - out.Auth = in.Auth -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StargateSpec. -func (in *StargateSpec) DeepCopy() *StargateSpec { - if in == nil { - return nil - } - out := new(StargateSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StargateStatus) DeepCopyInto(out *StargateStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StargateStatus. -func (in *StargateStatus) DeepCopy() *StargateStatus { - if in == nil { - return nil - } - out := new(StargateStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Status) DeepCopyInto(out *Status) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make(Conditions, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Status. -func (in *Status) DeepCopy() *Status { - if in == nil { - return nil - } - out := new(Status) - in.DeepCopyInto(out) - return out -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new URI. -func (in *URI) DeepCopy() *URI { - if in == nil { - return nil - } - out := new(URI) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Versions) DeepCopyInto(out *Versions) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - if in.Spec != nil { - in, out := &in.Spec, &out.Spec - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Versions. -func (in *Versions) DeepCopy() *Versions { - if in == nil { - return nil - } - out := new(Versions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Versions) 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 *VersionsList) DeepCopyInto(out *VersionsList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Versions, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VersionsList. -func (in *VersionsList) DeepCopy() *VersionsList { - if in == nil { - return nil - } - out := new(VersionsList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *VersionsList) 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 *Wallets) DeepCopyInto(out *Wallets) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Wallets. -func (in *Wallets) DeepCopy() *Wallets { - if in == nil { - return nil - } - out := new(Wallets) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Wallets) 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 *WalletsList) DeepCopyInto(out *WalletsList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Wallets, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WalletsList. -func (in *WalletsList) DeepCopy() *WalletsList { - if in == nil { - return nil - } - out := new(WalletsList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *WalletsList) 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 *WalletsSpec) DeepCopyInto(out *WalletsSpec) { - *out = *in - out.ModuleProperties = in.ModuleProperties - out.StackDependency = in.StackDependency - if in.Auth != nil { - in, out := &in.Auth, &out.Auth - *out = new(AuthConfig) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WalletsSpec. -func (in *WalletsSpec) DeepCopy() *WalletsSpec { - if in == nil { - return nil - } - out := new(WalletsSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WalletsStatus) DeepCopyInto(out *WalletsStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WalletsStatus. -func (in *WalletsStatus) DeepCopy() *WalletsStatus { - if in == nil { - return nil - } - out := new(WalletsStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Webhooks) DeepCopyInto(out *Webhooks) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Webhooks. -func (in *Webhooks) DeepCopy() *Webhooks { - if in == nil { - return nil - } - out := new(Webhooks) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Webhooks) 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 *WebhooksList) DeepCopyInto(out *WebhooksList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Webhooks, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhooksList. -func (in *WebhooksList) DeepCopy() *WebhooksList { - if in == nil { - return nil - } - out := new(WebhooksList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *WebhooksList) 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 *WebhooksSpec) DeepCopyInto(out *WebhooksSpec) { - *out = *in - out.StackDependency = in.StackDependency - out.ModuleProperties = in.ModuleProperties - if in.Auth != nil { - in, out := &in.Auth, &out.Auth - *out = new(AuthConfig) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhooksSpec. -func (in *WebhooksSpec) DeepCopy() *WebhooksSpec { - if in == nil { - return nil - } - out := new(WebhooksSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WebhooksStatus) DeepCopyInto(out *WebhooksStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhooksStatus. -func (in *WebhooksStatus) DeepCopy() *WebhooksStatus { - if in == nil { - return nil - } - out := new(WebhooksStatus) - in.DeepCopyInto(out) - return out -} diff --git a/components/operator/build.Dockerfile b/components/operator/build.Dockerfile deleted file mode 100644 index 278ea8b8e0..0000000000 --- a/components/operator/build.Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM ghcr.io/formancehq/base:22.04 -COPY operator /usr/bin/operator -ENV OTEL_SERVICE_NAME operator -ENTRYPOINT ["/usr/bin/operator"] diff --git a/components/operator/cmd/main.go b/components/operator/cmd/main.go deleted file mode 100644 index 4bcf2e1a27..0000000000 --- a/components/operator/cmd/main.go +++ /dev/null @@ -1,145 +0,0 @@ -/* -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 main - -import ( - "crypto/tls" - "flag" - "net/http" - "os" - - "sigs.k8s.io/controller-runtime/pkg/client" - - formancev1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - // to ensure that exec-entrypoint and run can make use of them. - _ "k8s.io/client-go/plugin/pkg/client/auth" - - "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - - _ "github.com/formancehq/operator/internal/resources" - - formancecomv1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - //+kubebuilder:scaffold:imports -) - -var ( - scheme = runtime.NewScheme() - setupLog = ctrl.Log.WithName("setup") -) - -func init() { - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(formancev1beta1.AddToScheme(scheme)) - utilruntime.Must(formancecomv1beta1.AddToScheme(scheme)) - //+kubebuilder:scaffold:scheme -} - -func main() { - var ( - metricsAddr string - enableLeaderElection bool - probeAddr string - region string - env string - licenceSecret string - utilsVersion string - ) - flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") - flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") - flag.BoolVar(&enableLeaderElection, "leader-elect", false, - "Enable leader election for controller manager. "+ - "Enabling this will ensure there is only one active controller manager.") - flag.StringVar(®ion, "region", "eu-west-1", "The cloud region in use for the operator") - flag.StringVar(&env, "env", "staging", "The current environment in use for the operator") - flag.StringVar(&licenceSecret, "licence-secret", "", "The licence secret that contains the token and the issuer") - flag.StringVar(&utilsVersion, "utils-version", "latest", "The version of the operator utils image") - opts := zap.Options{ - Development: false, - } - opts.BindFlags(flag.CommandLine) - flag.Parse() - - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - - http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{ - InsecureSkipVerify: true, - } - - mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Client: client.Options{ - Cache: &client.CacheOptions{ - Unstructured: true, - }, - }, - Scheme: scheme, - Metrics: metricsserver.Options{BindAddress: metricsAddr}, - HealthProbeBindAddress: probeAddr, - LeaderElection: enableLeaderElection, - LeaderElectionID: "6e1085e1.com", - // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily - // when the Manager ends. This requires the binary to immediately end when the - // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly - // speeds up voluntary leader transitions as the new leader don't have to wait - // LeaseDuration time first. - // - // In the default scaffold provided, the program ends immediately after - // the manager stops, so would be fine to enable this option. However, - // if you are doing or is intended to do any operation such as perform cleanups - // after the manager stops then its usage might be unsafe. - // LeaderElectionReleaseOnCancel: true, - }) - if err != nil { - setupLog.Error(err, "unable to start manager") - os.Exit(1) - } - - platform := core.Platform{ - Region: region, - Environment: env, - LicenceSecret: licenceSecret, - UtilsVersion: utilsVersion, - } - - if err := core.Setup(mgr, platform); err != nil { - setupLog.Error(err, "unable to create controllers") - os.Exit(1) - } - - if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up health check") - os.Exit(1) - } - if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up ready check") - os.Exit(1) - } - - setupLog.Info("starting manager") - if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { - setupLog.Error(err, "problem running manager") - os.Exit(1) - } -} diff --git a/components/operator/config/crd/bases/formance.com_analytics.yaml b/components/operator/config/crd/bases/formance.com_analytics.yaml deleted file mode 100644 index 3f0ab4750a..0000000000 --- a/components/operator/config/crd/bases/formance.com_analytics.yaml +++ /dev/null @@ -1,158 +0,0 @@ ---- -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/bases/formance.com_authclients.yaml b/components/operator/config/crd/bases/formance.com_authclients.yaml deleted file mode 100644 index e1c86954b3..0000000000 --- a/components/operator/config/crd/bases/formance.com_authclients.yaml +++ /dev/null @@ -1,172 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: authclients.formance.com -spec: - group: formance.com - names: - kind: AuthClient - listKind: AuthClientList - plural: authclients - singular: authclient - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack - jsonPath: .spec.stack - name: Stack - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: AuthClient allow to create OAuth2/OIDC clients on the auth server - (see [Auth](#auth)) - 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: - properties: - description: - description: Description represents an optional description of the - client - type: string - id: - description: |- - ID indicates the client id - It must be used with oauth2 `client_id` parameter - type: string - postLogoutRedirectUris: - description: RedirectUris allow to list allowed post logout redirect - uris for the client - items: - type: string - type: array - public: - default: false - description: |- - Public indicate whether a client is confidential or not. - Confidential clients are clients which the secret can be kept secret... - As opposed to public clients which cannot have a secret (application single page for example) - type: boolean - redirectUris: - description: RedirectUris allow to list allowed redirect uris for - the client - items: - type: string - type: array - scopes: - description: Scopes allow to five some scope to the client - items: - type: string - type: array - secret: - description: |- - Secret allow to configure a secret for the client. - It is not required as some client could use some oauth2 flows which does not requires a client secret - type: string - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - id - type: object - status: - 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/bases/formance.com_auths.yaml b/components/operator/config/crd/bases/formance.com_auths.yaml deleted file mode 100644 index a3325ce5e9..0000000000 --- a/components/operator/config/crd/bases/formance.com_auths.yaml +++ /dev/null @@ -1,222 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - labels: - formance.com/kind: module - name: auths.formance.com -spec: - group: formance.com - names: - kind: Auth - listKind: AuthList - plural: auths - singular: auth - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Synchronized auth clients - jsonPath: .status.clients - name: Clients - type: string - - 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: |- - Auth represent the authentication module of a stack. - - - It is an OIDC compliant server. - - - Creating it for a stack automatically add authentication on all supported modules. - - - The auth service is basically a proxy to another OIDC compliant server. - 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: - properties: - debug: - default: false - description: Allow to enable debug mode on the module - type: boolean - delegatedOIDCServer: - description: Contains information about a delegated authentication - server to use to delegate authentication - properties: - clientID: - description: ClientID is the client id to use for authentication - type: string - clientSecret: - description: ClientSecret is the client secret to use for authentication - type: string - issuer: - description: Issuer is the url of the delegated oidc server - type: string - type: object - 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 - enableScopes: - default: false - description: |- - Allow to enable scopes usage on authentication. - - - If not enabled, each service will check the authentication but will not restrict access following scopes. - in this case, if authenticated, it is ok. - type: boolean - signingKey: - description: Allow to override the default signing key used to sign - JWT tokens. - type: string - signingKeyFromSecret: - description: Allow to override the default signing key used to sign - JWT tokens using a k8s secret - properties: - key: - description: The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - 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: - properties: - clients: - description: Clients contains the list of clients created using [AuthClient](#authclient) - items: - type: string - type: array - 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/bases/formance.com_benthos.yaml b/components/operator/config/crd/bases/formance.com_benthos.yaml deleted file mode 100644 index a0fbc8d6f2..0000000000 --- a/components/operator/config/crd/bases/formance.com_benthos.yaml +++ /dev/null @@ -1,1555 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: benthos.formance.com -spec: - group: formance.com - names: - kind: Benthos - listKind: BenthosList - plural: benthos - singular: benthos - 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: Benthos is the Schema for the benthos 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: - properties: - batching: - description: Batching allow to define custom batching configuration - properties: - count: - description: Count indicates the number of messages that can be - kept in memory before being flushed to ElasticSearch - type: integer - period: - description: Period indicates the maximum duration messages can - be kept in memory before being flushed to ElasticSearch - type: string - required: - - count - - period - type: object - 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 - initContainers: - items: - description: A single application container that you want to run - within a pod. - properties: - args: - description: |- - Arguments to the entrypoint. - The container image's CMD is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - command: - description: |- - Entrypoint array. Not executed within a shell. - The container image's ENTRYPOINT is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - env: - description: |- - List of environment variables to set in the container. - Cannot be updated. - items: - description: EnvVar represents an environment variable present - in a Container. - properties: - name: - description: Name of the environment variable. Must be - a C_IDENTIFIER. - type: string - value: - description: |- - Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any service environment variables. If a variable cannot be resolved, - the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless of whether the variable - exists or not. - Defaults to "". - type: string - valueFrom: - description: Source for the environment variable's value. - Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? - type: string - optional: - description: Specify whether the ConfigMap or - its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - description: |- - Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, - spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - description: Selects a key of a secret in the pod's - namespace - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? - type: string - optional: - description: Specify whether the Secret or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - envFrom: - description: |- - List of sources to populate environment variables in the container. - The keys defined within a source must be a C_IDENTIFIER. All invalid keys - will be reported as an event when the container is starting. When a key exists in multiple - sources, the value associated with the last source will take precedence. - Values defined by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of a set - of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? - type: string - optional: - description: Specify whether the ConfigMap must be - defined - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? - type: string - optional: - description: Specify whether the Secret must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - image: - description: |- - Container image name. - More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management to default or override - container images in workload controllers like Deployments and StatefulSets. - type: string - imagePullPolicy: - description: |- - Image pull policy. - One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - type: string - lifecycle: - description: |- - Actions that the management system should take in response to container lifecycle events. - Cannot be updated. - properties: - postStart: - description: |- - PostStart is called immediately after a container is created. If the handler fails, - the container is terminated and restarted according to its restart policy. - Other management of the container blocks until the hook completes. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents the duration that the - container should sleep before being terminated. - properties: - seconds: - description: Seconds is the number of seconds to - sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for the backward compatibility. There are no validation of this field and - lifecycle hooks will fail in runtime when tcp handler is specified. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - API request or management event such as liveness/startup probe failure, - preemption, resource contention, etc. The handler is not called if the - container crashes or exits. The Pod's termination grace period countdown begins before the - PreStop hook is executed. Regardless of the outcome of the handler, the - container will eventually terminate within the Pod's termination grace - period (unless delayed by finalizers). Other management of the container blocks until the hook completes - or until the termination grace period is reached. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents the duration that the - container should sleep before being terminated. - properties: - seconds: - description: Seconds is the number of seconds to - sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for the backward compatibility. There are no validation of this field and - lifecycle hooks will fail in runtime when tcp handler is specified. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - description: |- - Periodic probe of container liveness. - Container will be restarted if the probe fails. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC port. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - name: - description: |- - Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: |- - List of ports to expose from the container. Not specifying a port here - DOES NOT prevent that port from being exposed. Any port which is - listening on the default "0.0.0.0" address inside a container will be - accessible from the network. - Modifying this array with strategic merge patch may corrupt the data. - For more information See https://github.com/kubernetes/kubernetes/issues/108255. - Cannot be updated. - items: - description: ContainerPort represents a network port in a - single container. - properties: - containerPort: - description: |- - Number of port to expose on the pod's IP address. - This must be a valid port number, 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port to. - type: string - hostPort: - description: |- - Number of port to expose on the host. - If specified, this must be a valid port number, 0 < x < 65536. - If HostNetwork is specified, this must match ContainerPort. - Most containers do not need this. - format: int32 - type: integer - name: - description: |- - If specified, this must be an IANA_SVC_NAME and unique within the pod. Each - named port in a pod must have a unique name. Name for the port that can be - referred to by services. - type: string - protocol: - default: TCP - description: |- - Protocol for port. Must be UDP, TCP, or SCTP. - Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: |- - Periodic probe of container service readiness. - Container will be removed from service endpoints if the probe fails. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC port. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - resizePolicy: - description: Resources resize policy for the container. - items: - description: ContainerResizePolicy represents resource resize - policy for the container. - properties: - resourceName: - description: |- - Name of the resource to which this resource resize policy applies. - Supported values: cpu, memory. - type: string - restartPolicy: - description: |- - Restart policy to apply when specified resource is resized. - If not specified, it defaults to NotRequired. - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - description: |- - Compute Resources required by this container. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. - - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - restartPolicy: - description: |- - RestartPolicy defines the restart behavior of individual containers in a pod. - This field may only be set for init containers, and the only allowed value is "Always". - For non-init containers or when this field is not specified, - the restart behavior is defined by the Pod's restart policy and the container type. - Setting the RestartPolicy as "Always" for the init container will have the following effect: - this init container will be continually restarted on - exit until all regular containers have terminated. Once all regular - containers have completed, all init containers with restartPolicy "Always" - will be shut down. This lifecycle differs from normal init containers and - is often referred to as a "sidecar" container. Although this init - container still starts in the init container sequence, it does not wait - for the container to complete before proceeding to the next init - container. Instead, the next init container starts immediately after this - init container is started, or after any startupProbe has successfully - completed. - type: string - securityContext: - description: |- - SecurityContext defines the security options the container should be run with. - If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - properties: - allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privileges than its parent process. This bool directly controls if - the no_new_privs flag will be set on the container process. - AllowPrivilegeEscalation is true always when the container is: - 1) run as Privileged - 2) has CAP_SYS_ADMIN - Note that this field cannot be set when spec.os.name is windows. - type: boolean - capabilities: - description: |- - The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the container runtime. - Note that this field cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: |- - Run container in privileged mode. - Processes in privileged containers are essentially equivalent to root on the host. - Defaults to false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: |- - procMount denotes the type of proc mount to use for the containers. - The default is DefaultProcMount which uses the container runtime defaults for - readonly paths and masked paths. - This requires the ProcMountType feature flag to be enabled. - Note that this field cannot be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: |- - Whether this container has a read-only root filesystem. - Default is false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: |- - The GID to run the entrypoint of the container process. - Uses runtime default if unset. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: |- - Indicates that the container must run as a non-root user. - If true, the Kubelet will validate the image at runtime to ensure that it - does not run as UID 0 (root) and fail to start the container if it does. - If unset or false, no such validation will be performed. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: |- - The UID to run the entrypoint of the container process. - Defaults to user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: |- - The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: |- - The seccomp options to use by this container. If seccomp options are - provided at both the pod & container level, the container options - override the pod options. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile defined in a file on the node should be used. - The profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must be set if type is "Localhost". Must NOT be set for any other type. - type: string - type: - description: |- - type indicates which kind of seccomp profile will be applied. - Valid options are: - - - Localhost - a profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile should be used. - Unconfined - no profile should be applied. - type: string - required: - - type - type: object - windowsOptions: - description: |- - The Windows specific settings applied to all containers. - If unspecified, the options from the PodSecurityContext will be used. - If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: |- - GMSACredentialSpec is where the GMSA admission webhook - (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the - GMSA credential spec named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: |- - HostProcess determines if a container should be run as a 'Host Process' container. - All of a Pod's containers must have the same effective HostProcess value - (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: |- - The UserName in Windows to run the entrypoint of the container process. - Defaults to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - startupProbe: - description: |- - StartupProbe indicates that the Pod has successfully initialized. - If specified, no other probes are executed until this completes successfully. - If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. - This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, - when it might take a long time to load data or warm a cache, than during steady-state operation. - This cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC port. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - stdin: - description: |- - Whether this container should allocate a buffer for stdin in the container runtime. If this - is not set, reads from stdin in the container will always result in EOF. - Default is false. - type: boolean - stdinOnce: - description: |- - Whether the container runtime should close the stdin channel after it has been opened by - a single attach. When stdin is true the stdin stream will remain open across multiple attach - sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the - first client attaches to stdin, and then remains open and accepts data until the client disconnects, - at which time stdin is closed and remains closed until the container is restarted. If this - flag is false, a container processes that reads from stdin will never receive an EOF. - Default is false - type: boolean - terminationMessagePath: - description: |- - Optional: Path at which the file to which the container's termination message - will be written is mounted into the container's filesystem. - Message written is intended to be brief final status, such as an assertion failure message. - Will be truncated by the node if greater than 4096 bytes. The total message length across - all containers will be limited to 12kb. - Defaults to /dev/termination-log. - Cannot be updated. - type: string - terminationMessagePolicy: - description: |- - Indicate how the termination message should be populated. File will use the contents of - terminationMessagePath to populate the container status message on both success and failure. - FallbackToLogsOnError will use the last chunk of container log output if the termination - message file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, whichever is smaller. - Defaults to File. - Cannot be updated. - type: string - tty: - description: |- - Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. - Default is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices to be - used by the container. - items: - description: volumeDevice describes a mapping of a raw block - device within a container. - properties: - devicePath: - description: devicePath is the path inside of the container - that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: |- - Pod volumes to mount into the container's filesystem. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: |- - Path within the container at which the volume should be mounted. Must - not contain ':'. - type: string - mountPropagation: - description: |- - mountPropagation determines how mounts are propagated from the host - to container and the other way around. - When not set, MountPropagationNone is used. - This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: |- - Mounted read-only if true, read-write otherwise (false or unspecified). - Defaults to false. - type: boolean - subPath: - description: |- - Path within the volume from which the container's volume should be mounted. - Defaults to "" (volume's root). - type: string - subPathExpr: - description: |- - Expanded path within the volume from which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. - Defaults to "" (volume's root). - SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: |- - Container's working directory. - If not specified, the container runtime's default will be used, which - might be configured in the container image. - Cannot be updated. - type: string - required: - - name - type: object - type: array - resourceRequirements: - description: ResourceRequirements describes the compute resource requirements. - properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. - - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - stack: - description: Stack indicates the stack on which the module is installed - type: string - type: object - status: - 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 - elasticSearchURI: - type: string - 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/bases/formance.com_benthosstreams.yaml b/components/operator/config/crd/bases/formance.com_benthosstreams.yaml deleted file mode 100644 index f6ca538f63..0000000000 --- a/components/operator/config/crd/bases/formance.com_benthosstreams.yaml +++ /dev/null @@ -1,138 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: benthosstreams.formance.com -spec: - group: formance.com - names: - kind: BenthosStream - listKind: BenthosStreamList - plural: benthosstreams - singular: benthosstream - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack - jsonPath: .spec.stack - name: Stack - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: BenthosStream is the Schema for the benthosstreams 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: - properties: - data: - type: string - name: - type: string - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - data - - name - type: object - status: - 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/bases/formance.com_brokerconsumers.yaml b/components/operator/config/crd/bases/formance.com_brokerconsumers.yaml deleted file mode 100644 index a2f22aa9e2..0000000000 --- a/components/operator/config/crd/bases/formance.com_brokerconsumers.yaml +++ /dev/null @@ -1,153 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: brokerconsumers.formance.com -spec: - group: formance.com - names: - kind: BrokerConsumer - listKind: BrokerConsumerList - plural: brokerconsumers - singular: brokerconsumer - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Listened services - jsonPath: .spec.services - name: Services - type: string - - description: Ready - jsonPath: .status.ready - name: Ready - type: string - - description: Info - jsonPath: .status.info - name: Info - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: BrokerConsumer is the Schema for the brokerconsumers 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: - properties: - name: - description: |- - As the name is optional, if not provided, the name will be the QueriedBy property - This is only applied when using one stream by stack see Mode - type: string - queriedBy: - type: string - services: - items: - type: string - type: array - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - queriedBy - - services - type: object - status: - 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/bases/formance.com_brokers.yaml b/components/operator/config/crd/bases/formance.com_brokers.yaml deleted file mode 100644 index 1dd199ad59..0000000000 --- a/components/operator/config/crd/bases/formance.com_brokers.yaml +++ /dev/null @@ -1,156 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: brokers.formance.com -spec: - group: formance.com - names: - kind: Broker - listKind: BrokerList - plural: brokers - singular: broker - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Mode - jsonPath: .status.mode - name: Mode - type: string - - description: Ready - jsonPath: .status.ready - name: Ready - type: string - - description: Info - jsonPath: .status.info - name: Info - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: Broker is the Schema for the brokers 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: - properties: - stack: - description: Stack indicates the stack on which the module is installed - type: string - type: object - status: - 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 - mode: - description: |- - Mode indicating the configuration of the nats streams - Two modes are defined : - * OneStreamByService: In this case, each service will have a dedicated stream created - * OneStreamByStack: In this case, a stream will be created for the stack and each service will use a specific subject inside this stream - enum: - - OneStreamByService - - OneStreamByStack - type: string - ready: - description: Ready indicates if the resource is seen as completely - reconciled - type: boolean - streams: - description: Streams list streams created when Mode == ModeOneStreamByService - items: - type: string - type: array - uri: - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/config/crd/bases/formance.com_brokertopics.yaml b/components/operator/config/crd/bases/formance.com_brokertopics.yaml deleted file mode 100644 index 888286f351..0000000000 --- a/components/operator/config/crd/bases/formance.com_brokertopics.yaml +++ /dev/null @@ -1,143 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: brokertopics.formance.com -spec: - group: formance.com - names: - kind: BrokerTopic - listKind: BrokerTopicList - plural: brokertopics - singular: brokertopic - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack - jsonPath: .spec.stack - name: Stack - type: string - - description: Ready - jsonPath: .status.ready - name: Ready - type: string - - description: Info - jsonPath: .status.info - name: Info - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: BrokerTopic is the Schema for the brokertopics 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: - properties: - service: - type: string - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - service - type: object - status: - 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/bases/formance.com_databases.yaml b/components/operator/config/crd/bases/formance.com_databases.yaml deleted file mode 100644 index 1d99490ccb..0000000000 --- a/components/operator/config/crd/bases/formance.com_databases.yaml +++ /dev/null @@ -1,189 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: databases.formance.com -spec: - group: formance.com - names: - kind: Database - listKind: DatabaseList - plural: databases - singular: database - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack - jsonPath: .spec.stack - name: Stack - type: string - - description: Ready - jsonPath: .status.ready - name: Ready - type: string - - description: Is the databse configuration out of sync - jsonPath: .status.outOfSync - name: Out of sync - type: string - - description: Info - jsonPath: .status.info - name: Info - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: |- - Database represent a concrete database on a PostgreSQL server, it is created by modules requiring a database ([Ledger](#ledger) for example). - - - It uses the settings `postgres..uri` which must have the following uri format: `postgresql://[@]@/` - Additionally, the uri can define a query param `secret` indicating a k8s secret, than must be used to retrieve database credentials. - - - On creation, the reconciler behind the Database object will create the database on the postgresql server using a k8s job. - On Deletion, by default, the reconciler will let the database untouched. - You can allow the reconciler to drop the database on the server by using the [Settings](#settings) `clear-database` with the value `true`. - If you use that setting, the reconciler will use another job to drop the database. - Be careful, no backup are performed! - - - Database resource honors `aws.service-account` setting, so, you can create databases on an AWS server if you need. - See [AWS accounts](#aws-account) - - - Once a database is fully configured, it retains the postgres uri used. - If the setting indicating the server uri changed, the Database object will set the field `.status.outOfSync` to true - and will not change anything. - - - Therefore, to switch to a new server, you must change the setting value, then drop the Database object. - It will be recreated with correct uri. - 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: - properties: - debug: - default: false - type: boolean - service: - description: |- - Service is a discriminator for the created database. - Actually, it will be the module name (ledger, payments...). - Therefore, the created database will be named `` - type: string - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - service - type: object - status: - 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 - database: - description: The generated database name - type: string - info: - description: Info can contain any additional like reconciliation errors - type: string - outOfSync: - description: |- - OutOfSync indicates than a settings changed the uri of the postgres server - The Database object need to be removed to be recreated - type: boolean - ready: - description: Ready indicates if the resource is seen as completely - reconciled - type: boolean - uri: - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/config/crd/bases/formance.com_gatewayhttpapis.yaml b/components/operator/config/crd/bases/formance.com_gatewayhttpapis.yaml deleted file mode 100644 index 9026733133..0000000000 --- a/components/operator/config/crd/bases/formance.com_gatewayhttpapis.yaml +++ /dev/null @@ -1,161 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: gatewayhttpapis.formance.com -spec: - group: formance.com - names: - kind: GatewayHTTPAPI - listKind: GatewayHTTPAPIList - plural: gatewayhttpapis - singular: gatewayhttpapi - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack - jsonPath: .spec.stack - name: Stack - type: string - - description: Ready - jsonPath: .status.ready - name: Ready - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: GatewayHTTPAPI is the Schema for the HTTPAPIs 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: - properties: - healthCheckEndpoint: - description: Health check endpoint - type: string - name: - description: Name indicates prefix api - type: string - rules: - description: Rules - items: - properties: - methods: - items: - type: string - type: array - path: - type: string - secured: - default: false - type: boolean - required: - - path - type: object - type: array - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - name - - rules - type: object - status: - 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/bases/formance.com_gateways.yaml b/components/operator/config/crd/bases/formance.com_gateways.yaml deleted file mode 100644 index e44cccb0ec..0000000000 --- a/components/operator/config/crd/bases/formance.com_gateways.yaml +++ /dev/null @@ -1,202 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - labels: - formance.com/kind: module - name: gateways.formance.com -spec: - group: formance.com - names: - kind: Gateway - listKind: GatewayList - plural: gateways - singular: gateway - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack - jsonPath: .spec.stack - name: Stack - type: string - - description: Synchronized http apis - jsonPath: .status.syncHTTPAPIs - name: HTTP APIs - 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: Gateway is the Schema for the gateways 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: - 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 - ingress: - description: Allow to customize the generated ingress - properties: - annotations: - additionalProperties: - type: string - description: Custom annotations to add on the ingress - type: object - host: - description: |- - Indicates the hostname on which the stack will be served. - Example : `formance.example.com` - type: string - ingressClassName: - description: Ingress class to use - type: string - scheme: - default: https - description: |- - Indicate the scheme. - - - Actually, It should be `https` unless you know what you are doing. - type: string - tls: - description: Allow to customize the tls part of the ingress - properties: - secretName: - description: Specify the secret name used for the tls configuration - on the ingress - type: string - required: - - secretName - type: object - required: - - host - - scheme - type: object - 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: - 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 - syncHTTPAPIs: - description: Detected http apis. See [GatewayHTTPAPI](#gatewayhttpapi) - items: - type: string - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/config/crd/bases/formance.com_ledgers.yaml b/components/operator/config/crd/bases/formance.com_ledgers.yaml deleted file mode 100644 index dc5ccb0425..0000000000 --- a/components/operator/config/crd/bases/formance.com_ledgers.yaml +++ /dev/null @@ -1,215 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - labels: - formance.com/kind: module - name: ledgers.formance.com -spec: - group: formance.com - names: - kind: Ledger - listKind: LedgerList - plural: ledgers - singular: ledger - 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: |- - Ledger is the module allowing to install a ledger instance. - - - The ledger is actually a stateful application on the writer part. - So we cannot scale the ledger as we want without prior configuration. - - - So, the ledger can run in two modes : - * single instance: Only one instance will be deployed. We cannot scale in that mode. - * single writer / multiple reader: In this mode, we will have a single writer and multiple readers if needed. - - - Use setting `ledger.deployment-strategy` with either the value : - - single : For the single instance mode. - - single-writer: For the single writer / multiple reader mode. - Under the hood, the operator create two deployments and force the scaling of the writer to stay at 1. - Then you can scale the deployment of the reader to the value you want. - 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - debug: - default: false - description: Allow to enable debug mode on the module - type: boolean - deploymentStrategy: - default: single - description: Deprecated. - type: string - 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 - locking: - description: Locking is intended for ledger v1 only - properties: - redis: - properties: - duration: - description: |- - A Duration represents the elapsed time between two instants - as an int64 nanosecond count. The representation limits the - largest representable duration to approximately 290 years. - format: int64 - type: integer - insecure: - default: false - type: boolean - retry: - description: |- - A Duration represents the elapsed time between two instants - as an int64 nanosecond count. The representation limits the - largest representable duration to approximately 290 years. - format: int64 - type: integer - tls: - default: false - type: boolean - uri: - type: string - type: object - strategy: - default: memory - type: string - type: object - 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: - 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/bases/formance.com_orchestrations.yaml b/components/operator/config/crd/bases/formance.com_orchestrations.yaml deleted file mode 100644 index c8c6b66852..0000000000 --- a/components/operator/config/crd/bases/formance.com_orchestrations.yaml +++ /dev/null @@ -1,165 +0,0 @@ ---- -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: orchestrations.formance.com -spec: - group: formance.com - names: - kind: Orchestration - listKind: OrchestrationList - plural: orchestrations - singular: orchestration - 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: Orchestration is the Schema for the orchestrations 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - 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: - 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 - temporalURI: - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/config/crd/bases/formance.com_payments.yaml b/components/operator/config/crd/bases/formance.com_payments.yaml deleted file mode 100644 index 355f83a68f..0000000000 --- a/components/operator/config/crd/bases/formance.com_payments.yaml +++ /dev/null @@ -1,164 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - labels: - formance.com/kind: module - name: payments.formance.com -spec: - group: formance.com - names: - kind: Payments - listKind: PaymentsList - plural: payments - singular: payments - 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: Payments is the Schema for the payments 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - 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 - encryptionKey: - type: string - 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: - 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/bases/formance.com_reconciliations.yaml b/components/operator/config/crd/bases/formance.com_reconciliations.yaml deleted file mode 100644 index 892b1f2ca9..0000000000 --- a/components/operator/config/crd/bases/formance.com_reconciliations.yaml +++ /dev/null @@ -1,163 +0,0 @@ ---- -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: reconciliations.formance.com -spec: - group: formance.com - names: - kind: Reconciliation - listKind: ReconciliationList - plural: reconciliations - singular: reconciliation - 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: Reconciliation is the Schema for the reconciliations 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - 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: - 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/bases/formance.com_resourcereferences.yaml b/components/operator/config/crd/bases/formance.com_resourcereferences.yaml deleted file mode 100644 index f64f7fe6b0..0000000000 --- a/components/operator/config/crd/bases/formance.com_resourcereferences.yaml +++ /dev/null @@ -1,170 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: resourcereferences.formance.com -spec: - group: formance.com - names: - kind: ResourceReference - listKind: ResourceReferenceList - plural: resourcereferences - singular: resourcereference - scope: Cluster - versions: - - name: v1beta1 - schema: - openAPIV3Schema: - description: "ResourceReference is a special resources used to refer to externally - created resources.\n\n\nIt includes k8s service accounts and secrets.\n\n\nWhy? - Because the operator create a namespace by stack, so, a stack does not have - access to secrets and service\naccounts created externally.\n\n\nA ResourceReference - is created by other resource who need to use a specific secret or service - account.\nFor example, if you want to use a secret for your database connection - (see [Database](#database), you will\ncreate a setting indicating a secret - name. You will need to create this secret yourself, and you will put this\nsecret - inside the namespace you want (`default` maybe).\n\n\nThe Database reconciler - will create a ResourceReference looking like that :\n```\napiVersion: formance.com/v1beta1\nkind: - ResourceReference\nmetadata:\n\n\n\tname: jqkuffjxcezj-qlii-auth-postgres\n\townerReferences:\n\t- - apiVersion: formance.com/v1beta1\n\t blockOwnerDeletion: true\n\t controller: - true\n\t kind: Database\n\t name: jqkuffjxcezj-qlii-auth\n\t uid: 2cc4b788-3ffb-4e3d-8a30-07ed3941c8d2\n\n\nspec:\n\n\n\tgvk:\n\t - \ group: \"\"\n\t kind: Secret\n\t version: v1\n\tname: postgres\n\tstack: - jqkuffjxcezj-qlii\n\n\nstatus:\n\n\n\t...\n\n\n```\nThis reconciler behind - this ResourceReference will search, in all namespaces, for a secret named - \"postgres\".\nThe secret must have a label `formance.com/stack` with the - value matching either a specific stack or `any` to target any stack.\n\n\nOnce - the reconciler has found the secret, it will copy it inside the stack namespace, - allowing the ResourceReconciler owner to use it." - 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: - properties: - gvk: - description: |- - GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion - to avoid automatic coercion. It doesn't use a GroupVersion to avoid custom marshalling - properties: - group: - type: string - kind: - type: string - version: - type: string - required: - - group - - kind - - version - type: object - name: - type: string - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - gvk - - name - type: object - status: - 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 - hash: - type: string - 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 - syncedResource: - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/config/crd/bases/formance.com_searches.yaml b/components/operator/config/crd/bases/formance.com_searches.yaml deleted file mode 100644 index c9aa65a1de..0000000000 --- a/components/operator/config/crd/bases/formance.com_searches.yaml +++ /dev/null @@ -1,185 +0,0 @@ ---- -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: searches.formance.com -spec: - group: formance.com - names: - kind: Search - listKind: SearchList - plural: searches - singular: search - 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: Search is the Schema for the searches 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - batching: - description: Batching allow to define custom batching configuration - properties: - count: - description: Count indicates the number of messages that can be - kept in memory before being flushed to ElasticSearch - type: integer - period: - description: Period indicates the maximum duration messages can - be kept in memory before being flushed to ElasticSearch - type: string - required: - - count - - period - type: object - 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: - 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 - elasticSearchURI: - type: string - 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 - topicCleaned: - default: false - description: TopicCleaned is used to flag stacks where the topics - have been cleaned (still search-ledgerv2 and co consumers) - type: boolean - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/config/crd/bases/formance.com_settings.yaml b/components/operator/config/crd/bases/formance.com_settings.yaml deleted file mode 100644 index e26671fcdd..0000000000 --- a/components/operator/config/crd/bases/formance.com_settings.yaml +++ /dev/null @@ -1,114 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: settings.formance.com -spec: - group: formance.com - names: - kind: Settings - listKind: SettingsList - plural: settings - singular: settings - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Key - jsonPath: .spec.key - name: Key - type: string - - description: Value - jsonPath: .spec.value - name: Value - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: "Settings represents a configurable piece of the stacks.\n\n\nThe - purpose of this resource is to be able to configure some common settings - between a set of stacks.\n\n\nExample :\n```yaml\napiVersion: formance.com/v1beta1\nkind: - Settings\nmetadata:\n\n\n\tname: postgres-uri\n\n\nspec:\n\n\n\tkey: postgres.ledger.uri\n\tstacks:\n\t- - stack0\n\tvalue: postgresql://postgresql.formance.svc.cluster.local:5432\n\n\n```\n\n\nThis - example create a setting named `postgres-uri` targeting the stack named - `stack0` and the service `ledger` (see the key `postgres.ledger.uri`).\n\n\nTherefore, - a [Database](#database) created for the stack `stack0` and the service named - 'ledger' will use the uri `postgresql://postgresql.formance.svc.cluster.local:5432`.\n\n\nSettings - allow to use wildcards in keys and in stacks list.\n\n\nFor example, if - you want to use the same database server for all the modules of a specific - stack, you can write :\n```yaml\napiVersion: formance.com/v1beta1\nkind: - Settings\nmetadata:\n\n\n\tname: postgres-uri\n\n\nspec:\n\n\n\tkey: postgres.*.uri - # There, we use a wildcard to indicate we want to use that setting of all - services of the stack `stack0`\n\tstacks:\n\t- stack0\n\tvalue: postgresql://postgresql.formance.svc.cluster.local:5432\n\n\n```\n\n\nAlso, - we could use that setting for all of our stacks using :\n```yaml\napiVersion: - formance.com/v1beta1\nkind: Settings\nmetadata:\n\n\n\tname: postgres-uri\n\n\nspec:\n\n\n\tkey: - postgres.*.uri # There, we use a wildcard to indicate we want to use that - setting for all services of all stacks\n\tstacks:\n\t- * # There we select - all the stacks\n\tvalue: postgresql://postgresql.formance.svc.cluster.local:5432\n\n\n```\n\n\nSome - settings are really global, while some are used by specific module.\n\n\nRefer - to the documentation of each module and resource to discover available Settings.\n\n\n##### - Global settings\n###### AWS account\n\n\nA stack can use an AWS account - for authentication.\n\n\nIt can be used to connect to any AWS service we - could use.\n\n\nIt includes RDS, OpenSearch and MSK. To do so, you can create - the following setting:\n```yaml\napiVersion: formance.com/v1beta1\nkind: - Settings\nmetadata:\n\n\n\tname: aws-service-account\n\n\nspec:\n\n\n\tkey: - aws.service-account\n\tstacks:\n\t- '*'\n\tvalue: aws-access\n\n\n```\nThis - setting instruct the operator than there is somewhere on the cluster a service - account named `aws-access`.\n\n\nSo, each time a service has the capability - to use AWS, the operator will use this service account.\n\n\nThe service - account could look like that :\n```yaml\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n\n\n\tannotations:\n\t - \ eks.amazonaws.com/role-arn: arn:aws:iam::************:role/staging-eu-west-1-hosting-stack-access\n\tlabels:\n\t - \ formance.com/stack: any\n\tname: aws-access\n\n\n```\nYou can note two - things :\n 1. We have an annotation indicating the role arn used to connect - to AWS. Refer to the AWS documentation to create this role\n 2. We have - a label `formance.com/stack=any` indicating we are targeting all stacks.\n - \ Refer to the documentation of [ResourceReference](#resourcereference) - for further information.\n\n\n###### JSON logging\n\n\nYou can use the setting - `logging.json` with the value `true` to configure elligible service to log - as json.\nExample:\n```yaml\napiVersion: formance.com/v1beta1\nkind: Settings\nmetadata:\n\n\n\tname: - json-logging\n\n\nspec:\n\n\n\tkey: logging.json\n\tstacks:\n\t- '*'\n\tvalue: - \"true\"\n\n\n```" - 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: - properties: - key: - description: The setting Key. See the documentation of each module - or [global settings](#global-settings) to discover them. - type: string - stacks: - description: Stacks on which the setting is applied. Can contain `*` - to indicate a wildcard. - items: - type: string - type: array - value: - description: The value. It must have a specific format following the - Key. - type: string - required: - - key - - value - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/config/crd/bases/formance.com_stacks.yaml b/components/operator/config/crd/bases/formance.com_stacks.yaml deleted file mode 100644 index 13ebc0d0e8..0000000000 --- a/components/operator/config/crd/bases/formance.com_stacks.yaml +++ /dev/null @@ -1,205 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: stacks.formance.com -spec: - group: formance.com - names: - kind: Stack - listKind: StackList - plural: stacks - singular: stack - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack Disabled - jsonPath: .spec.disabled - name: Disable - type: string - - description: Stack Version - jsonPath: .spec.version - name: Version - type: string - - description: Stack Version From File - jsonPath: .spec.versionsFromFile - name: Versions From file - type: string - - description: Is stack ready - jsonPath: .status.ready - name: Ready - type: boolean - - description: Modules List Registered - jsonPath: .status.modules - name: Modules - type: string - - description: Info - jsonPath: .status.info - name: Info - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: |- - Stack represents a formance stack. - A Stack is basically a container. It holds some global properties and - creates a namespace if not already existing. - - - To do more, you need to create some [modules](#modules). - - - The Stack resource allow to specify the version of the stack. - - - It can be specified using either the field `.spec.version` or the `.spec.versionsFromFile` field (Refer to the documentation of [Versions](#versions) resource. - - - The `version` field will have priority over `versionFromFile`. - - - If `versions` and `versionsFromFile` are not specified, "latest" will be used. - 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: - 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 - disabled: - default: false - description: |- - Disabled indicate the stack is disabled. - A disabled stack disable everything - It just keeps the namespace and the [Database](#database) resources. - type: boolean - enableAudit: - default: false - description: |- - EnableAudit enable audit at the stack level. - Actually, it enables audit on [Gateway](#gateway) - type: boolean - version: - description: |- - Version allow to specify the version of the components - Must be a valid docker tag - type: string - versionsFromFile: - description: |- - VersionsFromFile allow to specify a formance.com/Versions object which contains individual versions - for each component. - Must reference a valid formance.com/Versions object - type: string - type: object - status: - 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 - modules: - description: Modules register detected modules - items: - type: string - type: array - 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/bases/formance.com_stargates.yaml b/components/operator/config/crd/bases/formance.com_stargates.yaml deleted file mode 100644 index f94cc4b8d2..0000000000 --- a/components/operator/config/crd/bases/formance.com_stargates.yaml +++ /dev/null @@ -1,180 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - labels: - formance.com/kind: module - name: stargates.formance.com -spec: - group: formance.com - names: - kind: Stargate - listKind: StargateList - plural: stargates - singular: stargate - 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: Stargate is the Schema for the stargates 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: - properties: - auth: - properties: - clientID: - type: string - clientSecret: - type: string - issuer: - type: string - required: - - clientID - - clientSecret - - issuer - type: object - 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 - organizationID: - type: string - serverURL: - type: string - stack: - description: Stack indicates the stack on which the module is installed - type: string - stackID: - type: string - version: - description: Version allow to override global version defined at stack - level for a specific module - type: string - required: - - auth - - organizationID - - serverURL - - stackID - type: object - status: - description: StargateStatus defines the observed state of Stargate - 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/bases/formance.com_versions.yaml b/components/operator/config/crd/bases/formance.com_versions.yaml deleted file mode 100644 index 6e59f41f96..0000000000 --- a/components/operator/config/crd/bases/formance.com_versions.yaml +++ /dev/null @@ -1,47 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: versions.formance.com -spec: - group: formance.com - names: - kind: Versions - listKind: VersionsList - plural: versions - singular: versions - scope: Cluster - versions: - - name: v1beta1 - schema: - openAPIV3Schema: - description: Versions is the Schema for the versions 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: - additionalProperties: - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/config/crd/bases/formance.com_wallets.yaml b/components/operator/config/crd/bases/formance.com_wallets.yaml deleted file mode 100644 index f4db6cbff1..0000000000 --- a/components/operator/config/crd/bases/formance.com_wallets.yaml +++ /dev/null @@ -1,164 +0,0 @@ ---- -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: wallets.formance.com -spec: - group: formance.com - names: - kind: Wallets - listKind: WalletsList - plural: wallets - singular: wallets - 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: Wallets is the Schema for the wallets 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - 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: WalletsStatus defines the observed state of Wallets - 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/bases/formance.com_webhooks.yaml b/components/operator/config/crd/bases/formance.com_webhooks.yaml deleted file mode 100644 index 6464e1d50c..0000000000 --- a/components/operator/config/crd/bases/formance.com_webhooks.yaml +++ /dev/null @@ -1,163 +0,0 @@ ---- -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: webhooks.formance.com -spec: - group: formance.com - names: - kind: Webhooks - listKind: WebhooksList - plural: webhooks - singular: webhooks - 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: Webhooks is the Schema for the webhooks 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - 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: - 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 deleted file mode 100644 index 126bc6398a..0000000000 --- a/components/operator/config/crd/kustomization.yaml +++ /dev/null @@ -1,111 +0,0 @@ -# This kustomization.yaml is not intended to be run by itself, -# since it depends on service name and namespace that are out of this kustomize package. -# It should be run by config/default -resources: - - bases/formance.com_databases.yaml - - bases/formance.com_stacks.yaml - - bases/formance.com_brokertopics.yaml - - bases/formance.com_gatewayhttpapis.yaml - - bases/formance.com_ledgers.yaml - - bases/formance.com_gateways.yaml - - bases/formance.com_auths.yaml - - bases/formance.com_authclients.yaml - - bases/formance.com_wallets.yaml - - bases/formance.com_orchestrations.yaml - - bases/formance.com_webhooks.yaml - - bases/formance.com_reconciliations.yaml - - bases/formance.com_payments.yaml - - bases/formance.com_searches.yaml - - bases/formance.com_benthosstreams.yaml - - bases/formance.com_benthos.yaml - - bases/formance.com_stargates.yaml - - bases/formance.com_versions.yaml - - bases/formance.com_settings.yaml - - bases/formance.com_resourcereferences.yaml - - bases/formance.com_brokerconsumers.yaml - - bases/formance.com_brokers.yaml - - bases/formance.com_analytics.yaml -#+kubebuilder:scaffold:crdkustomizeresource - -commonAnnotations: - helm.sh/resource-policy: keep -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. -# patches here are for enabling the conversion webhook for each CRD -#- path: patches/webhook_in_databases.yaml -#- path: patches/webhook_in_stacks.yaml -#- path: patches/webhook_in_topics.yaml -#- path: patches/webhook_in_topicqueries.yaml -#- path: patches/webhook_in_httpapis.yaml -#- path: patches/webhook_in_ledgers.yaml -#- path: patches/webhook_in_opentelemetryconfigurations.yaml -#- path: patches/webhook_in_gateways.yaml -#- path: patches/webhook_in_auths.yaml -#- path: patches/webhook_in_authclients.yaml -#- path: patches/webhook_in_wallets.yaml -#- path: patches/webhook_in_orchestrations.yaml -#- path: patches/webhook_in_webhooks.yaml -#- path: patches/webhook_in_reconciliations.yaml -#- path: patches/webhook_in_payments.yaml -#- path: patches/webhook_in_searches.yaml -#- path: patches/webhook_in_streams.yaml -#- path: patches/webhook_in_benthos.yaml -#- path: patches/webhook_in_stargates.yaml -#- path: patches/webhook_in_stack.formance.com_stacks.yaml -#- path: patches/webhook_in_stack.formance.com_configurations.yaml -#- path: patches/webhook_in_stack.formance.com_versions.yaml -#- path: patches/webhook_in_formance.com_versions.yaml -#- path: patches/webhook_in_formance.com_settings.yaml -#- path: patches/webhook_in_formance.com_secretreferences.yaml -#- 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. -# patches here are for enabling the CA injection for each CRD -#- path: patches/cainjection_in_databases.yaml -#- path: patches/cainjection_in_databaseconfigurations.yaml -#- path: patches/cainjection_in_stacks.yaml -#- path: patches/cainjection_in_topics.yaml -#- path: patches/cainjection_in_brokerconfigurations.yaml -#- path: patches/cainjection_in_topicqueries.yaml -#- path: patches/cainjection_in_httpapis.yaml -#- path: patches/cainjection_in_ledgers.yaml -#- path: patches/cainjection_in_opentelemetryconfigurations.yaml -#- path: patches/cainjection_in_gateways.yaml -#- path: patches/cainjection_in_auths.yaml -#- path: patches/cainjection_in_authclients.yaml -#- path: patches/cainjection_in_wallets.yaml -#- path: patches/cainjection_in_orchestrations.yaml -#- path: patches/cainjection_in_webhooks.yaml -#- path: patches/cainjection_in_reconciliations.yaml -#- path: patches/cainjection_in_payments.yaml -#- path: patches/cainjection_in_searches.yaml -#- path: patches/cainjection_in_benthosstreams.yaml -#- path: patches/cainjection_in_benthos.yaml -#- path: patches/cainjection_in_elasticsearchconfigurations.yaml -#- path: patches/cainjection_in_registriesconfigurations.yaml -#- path: patches/cainjection_in_stargates.yaml -#- path: patches/cainjection_in_stack.formance.com_stacks.yaml -#- path: patches/cainjection_in_stack.formance.com_configurations.yaml -#- path: patches/cainjection_in_stack.formance.com_versions.yaml -#- path: patches/cainjection_in_formance.com_temporalconfigurations.yaml -#- path: patches/cainjection_in_formance.com_versions.yaml -#- path: patches/cainjection_in_formance.com_searchbatchingconfigurations.yaml -#- path: patches/cainjection_in_formance.com_settings.yaml -#- path: patches/cainjection_in_formance.com_secretreferences.yaml -#- 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 -# the following config is for teaching kustomize how to do kustomization for CRDs. - -# configurations: -# - kustomizeconfig.yaml - -# replacements: -# - path: replacement.yaml diff --git a/components/operator/config/crd/kustomizeconfig.yaml b/components/operator/config/crd/kustomizeconfig.yaml deleted file mode 100644 index ec5c150a9d..0000000000 --- a/components/operator/config/crd/kustomizeconfig.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# This file is for teaching kustomize how to substitute name and namespace reference in CRD -nameReference: -- kind: Service - version: v1 - fieldSpecs: - - kind: CustomResourceDefinition - version: v1 - group: apiextensions.k8s.io - path: spec/conversion/webhook/clientConfig/service/name - -namespace: -- kind: CustomResourceDefinition - version: v1 - group: apiextensions.k8s.io - path: spec/conversion/webhook/clientConfig/service/namespace - create: false - -varReference: -- path: metadata/annotations diff --git a/components/operator/config/default/kustomization.yaml b/components/operator/config/default/kustomization.yaml deleted file mode 100644 index 5c60a59a28..0000000000 --- a/components/operator/config/default/kustomization.yaml +++ /dev/null @@ -1,128 +0,0 @@ -# Adds namespace to all resources. -namespace: "{{ .Release.Namespace }}" - -resources: - - ../rbac - - ../manager -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -#- ../webhook -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. -#- ../certmanager -# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. -#- ../prometheus - -patches: - [] - # Protect the /metrics endpoint by putting it behind auth. - # If you want your controller-manager to expose the /metrics - # endpoint w/o any authn/z, please comment the following line. - # - path: manager_auth_proxy_patch.yaml -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -#- path: manager_webhook_patch.yaml - -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. -# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. -# 'CERTMANAGER' needs to be enabled to use ca injection -#- path: webhookcainjection_patch.yaml - -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -# Uncomment the following replacements to add the cert-manager CA injection annotations -#replacements: -# - source: # Add cert-manager annotation to ValidatingWebhookConfiguration, MutatingWebhookConfiguration and CRDs -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -# fieldPath: .metadata.namespace # namespace of the certificate CR -# targets: -# - select: -# kind: ValidatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - select: -# kind: MutatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - select: -# kind: CustomResourceDefinition -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - source: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -# fieldPath: .metadata.name -# targets: -# - select: -# kind: ValidatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true -# - select: -# kind: MutatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true -# - select: -# kind: CustomResourceDefinition -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true -# - source: # Add cert-manager annotation to the webhook Service -# kind: Service -# version: v1 -# name: webhook-service -# fieldPath: .metadata.name # namespace of the service -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# fieldPaths: -# - .spec.dnsNames.0 -# - .spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 0 -# create: true -# - source: -# kind: Service -# version: v1 -# name: webhook-service -# fieldPath: .metadata.namespace # namespace of the service -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# fieldPaths: -# - .spec.dnsNames.0 -# - .spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 1 -# create: true diff --git a/components/operator/config/default/manager_auth_proxy_patch.yaml b/components/operator/config/default/manager_auth_proxy_patch.yaml deleted file mode 100644 index 3180b9261d..0000000000 --- a/components/operator/config/default/manager_auth_proxy_patch.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# This patch inject a sidecar container which is a HTTP proxy for the -# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: kube-rbac-proxy - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0 - args: - - "--secure-listen-address=0.0.0.0:8443" - - "--upstream=http://127.0.0.1:8080/" - - "--logtostderr=true" - - "--v=0" - ports: - - containerPort: 8443 - protocol: TCP - name: https - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - - name: manager - args: - - "--health-probe-bind-address=:8081" - - "--metrics-bind-address=127.0.0.1:8080" - - "--leader-elect" diff --git a/components/operator/config/default/manager_config_patch.yaml b/components/operator/config/default/manager_config_patch.yaml deleted file mode 100644 index 112d09862c..0000000000 --- a/components/operator/config/default/manager_config_patch.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: manager diff --git a/components/operator/config/manager/kustomization.yaml b/components/operator/config/manager/kustomization.yaml deleted file mode 100644 index 662de057fb..0000000000 --- a/components/operator/config/manager/kustomization.yaml +++ /dev/null @@ -1,9 +0,0 @@ -resources: - - manager.yaml - -patches: - [] - # Protect the /metrics endpoint by putting it behind auth. - # If you want your controller-manager to expose the /metrics - # endpoint w/o any authn/z, please comment the following line. - # - path: manager_auth_proxy_patch.yaml diff --git a/components/operator/config/manager/manager.yaml b/components/operator/config/manager/manager.yaml deleted file mode 100644 index 0837f6a3fd..0000000000 --- a/components/operator/config/manager/manager.yaml +++ /dev/null @@ -1,73 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: namespace - app.kubernetes.io/instance: system - app.kubernetes.io/component: manager - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - name: system ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system - labels: - control-plane: controller-manager - app.kubernetes.io/name: deployment - app.kubernetes.io/instance: controller-manager - app.kubernetes.io/component: manager - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize -spec: - selector: - matchLabels: - control-plane: controller-manager - replicas: 1 - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - control-plane: controller-manager - spec: - securityContext: - runAsNonRoot: true - containers: - - command: - - /manager - args: - - --leader-elect - image: controller:latest - name: manager - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 10m - memory: 64Mi - serviceAccountName: formance-controller-manager - terminationGracePeriodSeconds: 10 diff --git a/components/operator/config/manager/manager_auth_proxy_patch.yaml b/components/operator/config/manager/manager_auth_proxy_patch.yaml deleted file mode 100644 index 3180b9261d..0000000000 --- a/components/operator/config/manager/manager_auth_proxy_patch.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# This patch inject a sidecar container which is a HTTP proxy for the -# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: kube-rbac-proxy - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0 - args: - - "--secure-listen-address=0.0.0.0:8443" - - "--upstream=http://127.0.0.1:8080/" - - "--logtostderr=true" - - "--v=0" - ports: - - containerPort: 8443 - protocol: TCP - name: https - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - - name: manager - args: - - "--health-probe-bind-address=:8081" - - "--metrics-bind-address=127.0.0.1:8080" - - "--leader-elect" diff --git a/components/operator/config/prometheus/kustomization.yaml b/components/operator/config/prometheus/kustomization.yaml deleted file mode 100644 index ed137168a1..0000000000 --- a/components/operator/config/prometheus/kustomization.yaml +++ /dev/null @@ -1,2 +0,0 @@ -resources: -- monitor.yaml diff --git a/components/operator/config/prometheus/monitor.yaml b/components/operator/config/prometheus/monitor.yaml deleted file mode 100644 index e6e16a2c77..0000000000 --- a/components/operator/config/prometheus/monitor.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Prometheus Monitor Service (Metrics) -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: servicemonitor - app.kubernetes.io/instance: controller-manager-metrics-monitor - app.kubernetes.io/component: metrics - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - name: controller-manager-metrics-monitor - namespace: system -spec: - endpoints: - - path: /metrics - port: https - scheme: https - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - tlsConfig: - insecureSkipVerify: true - selector: - matchLabels: - control-plane: controller-manager diff --git a/components/operator/config/rbac/auth_editor_role.yaml b/components/operator/config/rbac/auth_editor_role.yaml deleted file mode 100644 index 18c6bd9673..0000000000 --- a/components/operator/config/rbac/auth_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit auths. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: auth-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: auth-editor-role -rules: -- apiGroups: - - formance.com - resources: - - auths - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - auths/status - verbs: - - get diff --git a/components/operator/config/rbac/auth_proxy_client_clusterrole.yaml b/components/operator/config/rbac/auth_proxy_client_clusterrole.yaml deleted file mode 100644 index ffc7642b48..0000000000 --- a/components/operator/config/rbac/auth_proxy_client_clusterrole.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: metrics-reader - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - name: metrics-reader -rules: -- nonResourceURLs: - - "/metrics" - verbs: - - get diff --git a/components/operator/config/rbac/auth_proxy_role.yaml b/components/operator/config/rbac/auth_proxy_role.yaml deleted file mode 100644 index 6e351d1fa2..0000000000 --- a/components/operator/config/rbac/auth_proxy_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: proxy-role - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - name: proxy-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create diff --git a/components/operator/config/rbac/auth_proxy_role_binding.yaml b/components/operator/config/rbac/auth_proxy_role_binding.yaml deleted file mode 100644 index ec13d53b04..0000000000 --- a/components/operator/config/rbac/auth_proxy_role_binding.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/name: clusterrolebinding - app.kubernetes.io/instance: proxy-rolebinding - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - name: proxy-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: proxy-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/components/operator/config/rbac/auth_proxy_service.yaml b/components/operator/config/rbac/auth_proxy_service.yaml deleted file mode 100644 index f726ad77ed..0000000000 --- a/components/operator/config/rbac/auth_proxy_service.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: service - app.kubernetes.io/instance: controller-manager-metrics-service - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - name: controller-manager-metrics-service - namespace: system -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: https - selector: - control-plane: controller-manager diff --git a/components/operator/config/rbac/auth_viewer_role.yaml b/components/operator/config/rbac/auth_viewer_role.yaml deleted file mode 100644 index e17eacd286..0000000000 --- a/components/operator/config/rbac/auth_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view auths. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: auth-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: auth-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - auths - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - auths/status - verbs: - - get diff --git a/components/operator/config/rbac/authclient_editor_role.yaml b/components/operator/config/rbac/authclient_editor_role.yaml deleted file mode 100644 index 1abbac2436..0000000000 --- a/components/operator/config/rbac/authclient_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit authclients. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: authclient-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: authclient-editor-role -rules: -- apiGroups: - - formance.com - resources: - - authclients - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - authclients/status - verbs: - - get diff --git a/components/operator/config/rbac/authclient_viewer_role.yaml b/components/operator/config/rbac/authclient_viewer_role.yaml deleted file mode 100644 index 413065ad2b..0000000000 --- a/components/operator/config/rbac/authclient_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view authclients. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: authclient-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: authclient-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - authclients - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - authclients/status - verbs: - - get diff --git a/components/operator/config/rbac/benthos_editor_role.yaml b/components/operator/config/rbac/benthos_editor_role.yaml deleted file mode 100644 index ce816e747f..0000000000 --- a/components/operator/config/rbac/benthos_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit benthos. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: benthos-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: benthos-editor-role -rules: -- apiGroups: - - formance.com - resources: - - benthos - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - benthos/status - verbs: - - get diff --git a/components/operator/config/rbac/benthos_viewer_role.yaml b/components/operator/config/rbac/benthos_viewer_role.yaml deleted file mode 100644 index 7bbe75310e..0000000000 --- a/components/operator/config/rbac/benthos_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view benthos. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: benthos-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: benthos-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - benthos - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - benthos/status - verbs: - - get diff --git a/components/operator/config/rbac/benthosstream_editor_role.yaml b/components/operator/config/rbac/benthosstream_editor_role.yaml deleted file mode 100644 index 43ffdc3e82..0000000000 --- a/components/operator/config/rbac/benthosstream_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit benthosstreams. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: stream-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: stream-editor-role -rules: -- apiGroups: - - formance.com - resources: - - benthosstreams - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - benthosstreams/status - verbs: - - get diff --git a/components/operator/config/rbac/benthosstream_viewer_role.yaml b/components/operator/config/rbac/benthosstream_viewer_role.yaml deleted file mode 100644 index 8a2308adb7..0000000000 --- a/components/operator/config/rbac/benthosstream_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view benthosstreams. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: stream-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: stream-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - benthosstreams - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - benthosstreams/status - verbs: - - get diff --git a/components/operator/config/rbac/brokertopic_editor_role.yaml b/components/operator/config/rbac/brokertopic_editor_role.yaml deleted file mode 100644 index 962320ee4f..0000000000 --- a/components/operator/config/rbac/brokertopic_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit brokertopics. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: topic-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: topic-editor-role -rules: -- apiGroups: - - formance.com - resources: - - brokertopics - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - brokertopics/status - verbs: - - get diff --git a/components/operator/config/rbac/brokertopic_viewer_role.yaml b/components/operator/config/rbac/brokertopic_viewer_role.yaml deleted file mode 100644 index 1cf86831a8..0000000000 --- a/components/operator/config/rbac/brokertopic_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view brokertopics. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: topic-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: topic-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - brokertopics - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - brokertopics/status - verbs: - - get diff --git a/components/operator/config/rbac/database_editor_role.yaml b/components/operator/config/rbac/database_editor_role.yaml deleted file mode 100644 index a6b98467dd..0000000000 --- a/components/operator/config/rbac/database_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit databases. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: database-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: database-editor-role -rules: -- apiGroups: - - formance.com - resources: - - databases - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - databases/status - verbs: - - get diff --git a/components/operator/config/rbac/database_viewer_role.yaml b/components/operator/config/rbac/database_viewer_role.yaml deleted file mode 100644 index fa17766e9e..0000000000 --- a/components/operator/config/rbac/database_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view databases. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: database-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: database-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - databases - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - databases/status - verbs: - - get diff --git a/components/operator/config/rbac/formance.com_analytics_editor_role.yaml b/components/operator/config/rbac/formance.com_analytics_editor_role.yaml deleted file mode 100644 index ec5cbd292e..0000000000 --- a/components/operator/config/rbac/formance.com_analytics_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# 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 deleted file mode 100644 index 0abe07eac5..0000000000 --- a/components/operator/config/rbac/formance.com_analytics_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# 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/formance.com_broker_editor_role.yaml b/components/operator/config/rbac/formance.com_broker_editor_role.yaml deleted file mode 100644 index 3d607ef40e..0000000000 --- a/components/operator/config/rbac/formance.com_broker_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit brokers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: broker-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: broker-editor-role -rules: -- apiGroups: - - formance.com - resources: - - brokers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - brokers/status - verbs: - - get diff --git a/components/operator/config/rbac/formance.com_broker_viewer_role.yaml b/components/operator/config/rbac/formance.com_broker_viewer_role.yaml deleted file mode 100644 index 3fc0fb919b..0000000000 --- a/components/operator/config/rbac/formance.com_broker_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view brokers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: broker-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: broker-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - brokers - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - brokers/status - verbs: - - get diff --git a/components/operator/config/rbac/formance.com_brokerconsumer_editor_role.yaml b/components/operator/config/rbac/formance.com_brokerconsumer_editor_role.yaml deleted file mode 100644 index da8c2508b0..0000000000 --- a/components/operator/config/rbac/formance.com_brokerconsumer_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit brokerconsumers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: brokerconsumer-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: brokerconsumer-editor-role -rules: -- apiGroups: - - formance.com - resources: - - brokerconsumers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - brokerconsumers/status - verbs: - - get diff --git a/components/operator/config/rbac/formance.com_brokerconsumer_viewer_role.yaml b/components/operator/config/rbac/formance.com_brokerconsumer_viewer_role.yaml deleted file mode 100644 index 7c32a930d7..0000000000 --- a/components/operator/config/rbac/formance.com_brokerconsumer_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view brokerconsumers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: brokerconsumer-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: brokerconsumer-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - brokerconsumers - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - brokerconsumers/status - verbs: - - get diff --git a/components/operator/config/rbac/formance.com_resourcereference_editor_role.yaml b/components/operator/config/rbac/formance.com_resourcereference_editor_role.yaml deleted file mode 100644 index da8c13871b..0000000000 --- a/components/operator/config/rbac/formance.com_resourcereference_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit resourcereferences. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: resourcereference-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: resourcereference-editor-role -rules: -- apiGroups: - - formance.com - resources: - - resourcereferences - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - resourcereferences/status - verbs: - - get diff --git a/components/operator/config/rbac/formance.com_resourcereference_viewer_role.yaml b/components/operator/config/rbac/formance.com_resourcereference_viewer_role.yaml deleted file mode 100644 index e143b7ee37..0000000000 --- a/components/operator/config/rbac/formance.com_resourcereference_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view resourcereferences. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: resourcereference-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: resourcereference-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - resourcereferences - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - resourcereferences/status - verbs: - - get diff --git a/components/operator/config/rbac/formance.com_settings_editor_role.yaml b/components/operator/config/rbac/formance.com_settings_editor_role.yaml deleted file mode 100644 index ba976418b1..0000000000 --- a/components/operator/config/rbac/formance.com_settings_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit settings. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: settings-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: settings-editor-role -rules: -- apiGroups: - - formance.com - resources: - - settings - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - settings/status - verbs: - - get diff --git a/components/operator/config/rbac/formance.com_settings_viewer_role.yaml b/components/operator/config/rbac/formance.com_settings_viewer_role.yaml deleted file mode 100644 index 530bd20454..0000000000 --- a/components/operator/config/rbac/formance.com_settings_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view settings. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: settings-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: settings-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - settings - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - settings/status - verbs: - - get diff --git a/components/operator/config/rbac/formance.com_versions_editor_role.yaml b/components/operator/config/rbac/formance.com_versions_editor_role.yaml deleted file mode 100644 index 7b0f8b6fee..0000000000 --- a/components/operator/config/rbac/formance.com_versions_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit versions. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: versions-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: versions-editor-role -rules: -- apiGroups: - - formance.com - resources: - - versions - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - versions/status - verbs: - - get diff --git a/components/operator/config/rbac/formance.com_versions_viewer_role.yaml b/components/operator/config/rbac/formance.com_versions_viewer_role.yaml deleted file mode 100644 index 2a0a73f69c..0000000000 --- a/components/operator/config/rbac/formance.com_versions_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view versions. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: versions-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: versions-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - versions - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - versions/status - verbs: - - get diff --git a/components/operator/config/rbac/gateway_editor_role.yaml b/components/operator/config/rbac/gateway_editor_role.yaml deleted file mode 100644 index 3ffe4975ad..0000000000 --- a/components/operator/config/rbac/gateway_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit gateways. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: gateway-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: gateway-editor-role -rules: -- apiGroups: - - formance.com - resources: - - gateways - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - gateways/status - verbs: - - get diff --git a/components/operator/config/rbac/gateway_viewer_role.yaml b/components/operator/config/rbac/gateway_viewer_role.yaml deleted file mode 100644 index 4348998945..0000000000 --- a/components/operator/config/rbac/gateway_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view gateways. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: gateway-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: gateway-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - gateways - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - gateways/status - verbs: - - get diff --git a/components/operator/config/rbac/gatewayhttpapi_editor_role.yaml b/components/operator/config/rbac/gatewayhttpapi_editor_role.yaml deleted file mode 100644 index 73586165ea..0000000000 --- a/components/operator/config/rbac/gatewayhttpapi_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit gatewayhttpapis. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: httpapi-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: httpapi-editor-role -rules: -- apiGroups: - - formance.com - resources: - - gatewayhttpapis - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - gatewayhttpapis/status - verbs: - - get diff --git a/components/operator/config/rbac/gatewayhttpapi_viewer_role.yaml b/components/operator/config/rbac/gatewayhttpapi_viewer_role.yaml deleted file mode 100644 index 1a36762ee5..0000000000 --- a/components/operator/config/rbac/gatewayhttpapi_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view gatewayhttpapis. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: httpapi-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: httpapi-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - gatewayhttpapis - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - gatewayhttpapis/status - verbs: - - get diff --git a/components/operator/config/rbac/kustomization.yaml b/components/operator/config/rbac/kustomization.yaml deleted file mode 100644 index 8d7d79407e..0000000000 --- a/components/operator/config/rbac/kustomization.yaml +++ /dev/null @@ -1,28 +0,0 @@ -resources: - # All RBAC will be applied under this service account in - # the deployment namespace. You may comment out this resource - # if your manager will use a service account that exists at - # runtime. Be sure to update RoleBinding and ClusterRoleBinding - # subjects if changing service account names. - - # Cluster Scopes - - role.yaml - - role_binding.yaml - - leader_election_role.yaml - - leader_election_role_binding.yaml - - # Namespaced Scopes - - service_account.yaml - # Comment the following 4 lines if you want to disable - # the auth proxy (https://github.com/brancz/kube-rbac-proxy) - # which protects your /metrics endpoint. - - # Cluster scopes - - auth_proxy_role.yaml - - auth_proxy_role_binding.yaml - - auth_proxy_client_clusterrole.yaml - - # Namespaced Scopes - - auth_proxy_service.yaml - -namePrefix: "formance-" diff --git a/components/operator/config/rbac/leader_election_role.yaml b/components/operator/config/rbac/leader_election_role.yaml deleted file mode 100644 index 72ec3e32bc..0000000000 --- a/components/operator/config/rbac/leader_election_role.yaml +++ /dev/null @@ -1,44 +0,0 @@ -# permissions to do leader election. -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app.kubernetes.io/name: role - app.kubernetes.io/instance: leader-election-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: leader-election-role -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch diff --git a/components/operator/config/rbac/leader_election_role_binding.yaml b/components/operator/config/rbac/leader_election_role_binding.yaml deleted file mode 100644 index a672712d08..0000000000 --- a/components/operator/config/rbac/leader_election_role_binding.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/name: rolebinding - app.kubernetes.io/instance: leader-election-rolebinding - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - name: leader-election-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: leader-election-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/components/operator/config/rbac/ledger_editor_role.yaml b/components/operator/config/rbac/ledger_editor_role.yaml deleted file mode 100644 index 90e6c7642c..0000000000 --- a/components/operator/config/rbac/ledger_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit ledgers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: ledger-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: ledger-editor-role -rules: -- apiGroups: - - formance.com - resources: - - ledgers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - ledgers/status - verbs: - - get diff --git a/components/operator/config/rbac/ledger_viewer_role.yaml b/components/operator/config/rbac/ledger_viewer_role.yaml deleted file mode 100644 index 014de7244d..0000000000 --- a/components/operator/config/rbac/ledger_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view ledgers. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: ledger-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: ledger-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - ledgers - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - ledgers/status - verbs: - - get diff --git a/components/operator/config/rbac/orchestration_editor_role.yaml b/components/operator/config/rbac/orchestration_editor_role.yaml deleted file mode 100644 index 2fdbb80284..0000000000 --- a/components/operator/config/rbac/orchestration_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit orchestrations. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: orchestration-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: orchestration-editor-role -rules: -- apiGroups: - - formance.com - resources: - - orchestrations - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - orchestrations/status - verbs: - - get diff --git a/components/operator/config/rbac/orchestration_viewer_role.yaml b/components/operator/config/rbac/orchestration_viewer_role.yaml deleted file mode 100644 index 5f359d22bf..0000000000 --- a/components/operator/config/rbac/orchestration_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view orchestrations. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: orchestration-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: orchestration-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - orchestrations - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - orchestrations/status - verbs: - - get diff --git a/components/operator/config/rbac/payments_editor_role.yaml b/components/operator/config/rbac/payments_editor_role.yaml deleted file mode 100644 index 8e3c053a9e..0000000000 --- a/components/operator/config/rbac/payments_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit payments. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: payments-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: payments-editor-role -rules: -- apiGroups: - - formance.com - resources: - - payments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - payments/status - verbs: - - get diff --git a/components/operator/config/rbac/payments_viewer_role.yaml b/components/operator/config/rbac/payments_viewer_role.yaml deleted file mode 100644 index 1c393519a6..0000000000 --- a/components/operator/config/rbac/payments_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view payments. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: payments-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: payments-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - payments - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - payments/status - verbs: - - get diff --git a/components/operator/config/rbac/reconciliation_editor_role.yaml b/components/operator/config/rbac/reconciliation_editor_role.yaml deleted file mode 100644 index 1cf0296e8d..0000000000 --- a/components/operator/config/rbac/reconciliation_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit reconciliations. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: reconciliation-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: reconciliation-editor-role -rules: -- apiGroups: - - formance.com - resources: - - reconciliations - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - reconciliations/status - verbs: - - get diff --git a/components/operator/config/rbac/reconciliation_viewer_role.yaml b/components/operator/config/rbac/reconciliation_viewer_role.yaml deleted file mode 100644 index 1351b2f182..0000000000 --- a/components/operator/config/rbac/reconciliation_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view reconciliations. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: reconciliation-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: reconciliation-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - reconciliations - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - reconciliations/status - verbs: - - get diff --git a/components/operator/config/rbac/role.yaml b/components/operator/config/rbac/role.yaml deleted file mode 100644 index 0fe054036e..0000000000 --- a/components/operator/config/rbac/role.yaml +++ /dev/null @@ -1,763 +0,0 @@ ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: manager-role -rules: -- apiGroups: - - apps - resources: - - deployments - verbs: - - create - - delete - - deletecollection - - get - - list - - patch - - update - - watch -- apiGroups: - - batch - resources: - - cronjobs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - batch - resources: - - jobs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - cert-manager.io - resources: - - certificates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - events - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - namespaces - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - pods - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - secrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - serviceaccounts - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - services - verbs: - - create - - delete - - get - - list - - 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: - - authclients - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - authclients/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - authclients/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - auths - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - auths/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - auths/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - benthos - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - benthos/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - benthos/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - benthosstreams - verbs: - - create - - delete - - deletecollection - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - benthosstreams/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - benthosstreams/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - brokerconsumers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - brokerconsumers/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - brokerconsumers/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - brokers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - brokers/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - brokers/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - brokertopics - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - brokertopics/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - brokertopics/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - databases - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - databases/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - databases/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - gatewayhttpapis - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - gatewayhttpapis/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - gatewayhttpapis/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - gateways - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - gateways/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - gateways/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - ledgers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - ledgers/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - ledgers/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - orchestrations - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - orchestrations/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - orchestrations/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - payments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - payments/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - payments/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - reconciliations - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - reconciliations/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - reconciliations/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - resourcereferences - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - resourcereferences/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - resourcereferences/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - searches - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - searches/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - searches/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - settings - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - settings/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - settings/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - stacks - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - stacks/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - stacks/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - stargates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - stargates/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - stargates/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - versions - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - versions/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - versions/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - wallets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - wallets/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - wallets/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - webhooks - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - webhooks/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - webhooks/status - verbs: - - get - - patch - - update -- apiGroups: - - networking.k8s.io - resources: - - ingresses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - policy - resources: - - poddisruptionbudgets - verbs: - - create - - delete - - deletecollection - - get - - list - - patch - - update - - watch diff --git a/components/operator/config/rbac/role_binding.yaml b/components/operator/config/rbac/role_binding.yaml deleted file mode 100644 index f50f946587..0000000000 --- a/components/operator/config/rbac/role_binding.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/name: clusterrolebinding - app.kubernetes.io/instance: manager-rolebinding - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - name: manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: manager-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/components/operator/config/rbac/search_editor_role.yaml b/components/operator/config/rbac/search_editor_role.yaml deleted file mode 100644 index b4c74ab2a6..0000000000 --- a/components/operator/config/rbac/search_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit searches. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: search-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: search-editor-role -rules: -- apiGroups: - - formance.com - resources: - - searches - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - searches/status - verbs: - - get diff --git a/components/operator/config/rbac/search_viewer_role.yaml b/components/operator/config/rbac/search_viewer_role.yaml deleted file mode 100644 index 12d8c8d145..0000000000 --- a/components/operator/config/rbac/search_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view searches. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: search-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: search-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - searches - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - searches/status - verbs: - - get diff --git a/components/operator/config/rbac/service_account.yaml b/components/operator/config/rbac/service_account.yaml deleted file mode 100644 index 63c0badfaa..0000000000 --- a/components/operator/config/rbac/service_account.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/name: serviceaccount - app.kubernetes.io/instance: controller-manager-sa - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - name: controller-manager - namespace: system diff --git a/components/operator/config/rbac/stack.formance.com_configuration_editor_role.yaml b/components/operator/config/rbac/stack.formance.com_configuration_editor_role.yaml deleted file mode 100644 index c52332047c..0000000000 --- a/components/operator/config/rbac/stack.formance.com_configuration_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit configurations. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: configuration-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: configuration-editor-role -rules: -- apiGroups: - - stack.formance.com - resources: - - configurations - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - stack.formance.com - resources: - - configurations/status - verbs: - - get diff --git a/components/operator/config/rbac/stack.formance.com_configuration_viewer_role.yaml b/components/operator/config/rbac/stack.formance.com_configuration_viewer_role.yaml deleted file mode 100644 index 150af1720c..0000000000 --- a/components/operator/config/rbac/stack.formance.com_configuration_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view configurations. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: configuration-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: configuration-viewer-role -rules: -- apiGroups: - - stack.formance.com - resources: - - configurations - verbs: - - get - - list - - watch -- apiGroups: - - stack.formance.com - resources: - - configurations/status - verbs: - - get diff --git a/components/operator/config/rbac/stack.formance.com_stack_editor_role.yaml b/components/operator/config/rbac/stack.formance.com_stack_editor_role.yaml deleted file mode 100644 index 0643b28202..0000000000 --- a/components/operator/config/rbac/stack.formance.com_stack_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit stacks. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: stack-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: stack-editor-role -rules: -- apiGroups: - - stack.formance.com - resources: - - stacks - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - stack.formance.com - resources: - - stacks/status - verbs: - - get diff --git a/components/operator/config/rbac/stack.formance.com_stack_viewer_role.yaml b/components/operator/config/rbac/stack.formance.com_stack_viewer_role.yaml deleted file mode 100644 index 428fd84889..0000000000 --- a/components/operator/config/rbac/stack.formance.com_stack_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view stacks. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: stack-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: stack-viewer-role -rules: -- apiGroups: - - stack.formance.com - resources: - - stacks - verbs: - - get - - list - - watch -- apiGroups: - - stack.formance.com - resources: - - stacks/status - verbs: - - get diff --git a/components/operator/config/rbac/stack.formance.com_versions_editor_role.yaml b/components/operator/config/rbac/stack.formance.com_versions_editor_role.yaml deleted file mode 100644 index 2e71320e7b..0000000000 --- a/components/operator/config/rbac/stack.formance.com_versions_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit versions. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: versions-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: versions-editor-role -rules: -- apiGroups: - - stack.formance.com - resources: - - versions - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - stack.formance.com - resources: - - versions/status - verbs: - - get diff --git a/components/operator/config/rbac/stack.formance.com_versions_viewer_role.yaml b/components/operator/config/rbac/stack.formance.com_versions_viewer_role.yaml deleted file mode 100644 index 5a15caa1cd..0000000000 --- a/components/operator/config/rbac/stack.formance.com_versions_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view versions. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: versions-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: versions-viewer-role -rules: -- apiGroups: - - stack.formance.com - resources: - - versions - verbs: - - get - - list - - watch -- apiGroups: - - stack.formance.com - resources: - - versions/status - verbs: - - get diff --git a/components/operator/config/rbac/stack_editor_role.yaml b/components/operator/config/rbac/stack_editor_role.yaml deleted file mode 100644 index a594bb82ff..0000000000 --- a/components/operator/config/rbac/stack_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit stacks. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: stack-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: stack-editor-role -rules: -- apiGroups: - - formance.com - resources: - - stacks - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - stacks/status - verbs: - - get diff --git a/components/operator/config/rbac/stack_viewer_role.yaml b/components/operator/config/rbac/stack_viewer_role.yaml deleted file mode 100644 index 00fe20922f..0000000000 --- a/components/operator/config/rbac/stack_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view stacks. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: stack-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: stack-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - stacks - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - stacks/status - verbs: - - get diff --git a/components/operator/config/rbac/stargate_editor_role.yaml b/components/operator/config/rbac/stargate_editor_role.yaml deleted file mode 100644 index 85aa06dc8a..0000000000 --- a/components/operator/config/rbac/stargate_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit stargates. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: stargate-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: stargate-editor-role -rules: -- apiGroups: - - formance.com - resources: - - stargates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - stargates/status - verbs: - - get diff --git a/components/operator/config/rbac/stargate_viewer_role.yaml b/components/operator/config/rbac/stargate_viewer_role.yaml deleted file mode 100644 index b5de56b8dc..0000000000 --- a/components/operator/config/rbac/stargate_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view stargates. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: stargate-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: stargate-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - stargates - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - stargates/status - verbs: - - get diff --git a/components/operator/config/rbac/wallet_editor_role.yaml b/components/operator/config/rbac/wallet_editor_role.yaml deleted file mode 100644 index 4e0fcd6edc..0000000000 --- a/components/operator/config/rbac/wallet_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit wallets. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: wallets-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: wallets-editor-role -rules: -- apiGroups: - - formance.com - resources: - - wallets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - wallets/status - verbs: - - get diff --git a/components/operator/config/rbac/wallet_viewer_role.yaml b/components/operator/config/rbac/wallet_viewer_role.yaml deleted file mode 100644 index 7bdfd7f25c..0000000000 --- a/components/operator/config/rbac/wallet_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view wallets. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: wallets-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: wallets-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - wallets - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - wallets/status - verbs: - - get diff --git a/components/operator/config/rbac/webhooks_editor_role.yaml b/components/operator/config/rbac/webhooks_editor_role.yaml deleted file mode 100644 index 795a379e2e..0000000000 --- a/components/operator/config/rbac/webhooks_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit webhooks. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: webhooks-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: webhooks-editor-role -rules: -- apiGroups: - - formance.com - resources: - - webhooks - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - webhooks/status - verbs: - - get diff --git a/components/operator/config/rbac/webhooks_viewer_role.yaml b/components/operator/config/rbac/webhooks_viewer_role.yaml deleted file mode 100644 index 1d0d44ed74..0000000000 --- a/components/operator/config/rbac/webhooks_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view webhooks. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: webhooks-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: webhooks-viewer-role -rules: -- apiGroups: - - formance.com - resources: - - webhooks - verbs: - - get - - list - - watch -- apiGroups: - - formance.com - resources: - - webhooks/status - verbs: - - get diff --git a/components/operator/config/samples/formance.com_v1beta1_analytics.yaml b/components/operator/config/samples/formance.com_v1beta1_analytics.yaml deleted file mode 100644 index 4110b6090c..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_analytics.yaml +++ /dev/null @@ -1,12 +0,0 @@ -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/formance.com_v1beta1_auth.yaml b/components/operator/config/samples/formance.com_v1beta1_auth.yaml deleted file mode 100644 index 73f49dc889..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_auth.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: Auth -metadata: - labels: - app.kubernetes.io/name: auth - app.kubernetes.io/instance: auth0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: auth0 -spec: - stack: stack0 diff --git a/components/operator/config/samples/formance.com_v1beta1_authclient.yaml b/components/operator/config/samples/formance.com_v1beta1_authclient.yaml deleted file mode 100644 index 5f5c0c1a2d..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_authclient.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: AuthClient -metadata: - labels: - app.kubernetes.io/name: authclient - app.kubernetes.io/instance: authclient0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: authclient0 -spec: - stack: stack0 - id: client0 - secret: client0 - scopes: - - ledger:read - - ledger:write diff --git a/components/operator/config/samples/formance.com_v1beta1_broker.yaml b/components/operator/config/samples/formance.com_v1beta1_broker.yaml deleted file mode 100644 index be941bd7d0..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_broker.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: Broker -metadata: - labels: - app.kubernetes.io/name: broker - app.kubernetes.io/instance: broker-sample - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: broker-sample -spec: - # TODO(user): Add fields here diff --git a/components/operator/config/samples/formance.com_v1beta1_brokerconfiguration.yaml b/components/operator/config/samples/formance.com_v1beta1_brokerconfiguration.yaml deleted file mode 100644 index d170f1369b..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_brokerconfiguration.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: BrokerConfiguration -metadata: - labels: - app.kubernetes.io/name: brokerconfiguration - app.kubernetes.io/instance: brokerconfiguration0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - formance.com/stack: any - name: brokerconfiguration0 -spec: - nats: - replicas: 1 - url: nats.default.svc.cluster.local:4222 diff --git a/components/operator/config/samples/formance.com_v1beta1_brokerconsumer.yaml b/components/operator/config/samples/formance.com_v1beta1_brokerconsumer.yaml deleted file mode 100644 index 96c9de8f26..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_brokerconsumer.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: BrokerConsumer -metadata: - labels: - app.kubernetes.io/name: brokerconsumer - app.kubernetes.io/instance: brokerconsumer-sample - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: brokerconsumer-sample -spec: - # TODO(user): Add fields here diff --git a/components/operator/config/samples/formance.com_v1beta1_databaseconfiguration.yaml b/components/operator/config/samples/formance.com_v1beta1_databaseconfiguration.yaml deleted file mode 100644 index e33f57203d..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_databaseconfiguration.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: DatabaseConfiguration -metadata: - labels: - app.kubernetes.io/name: databaseconfiguration - app.kubernetes.io/instance: databaseconfiguration0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - formance.com/stack: stack0 - formance.com/service: any - name: databaseconfiguration0 -spec: - username: formance - password: formance - host: postgres-postgresql.formance.svc.cluster.local - port: 5432 - disableSSLMode: true diff --git a/components/operator/config/samples/formance.com_v1beta1_elasticsearchconfiguration.yaml b/components/operator/config/samples/formance.com_v1beta1_elasticsearchconfiguration.yaml deleted file mode 100644 index 5a012b49f5..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_elasticsearchconfiguration.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: ElasticSearchConfiguration -metadata: - labels: - app.kubernetes.io/name: elasticsearchconfiguration - app.kubernetes.io/instance: elasticsearchconfiguration0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - formance.com/stack: any - name: elasticsearchconfiguration0 -spec: - host: elasticsearch-master.formance.svc.cluster.local - port: 9200 - scheme: http - basicAuth: - username: "admin" - password: "Complexpass#123" diff --git a/components/operator/config/samples/formance.com_v1beta1_gateway.yaml b/components/operator/config/samples/formance.com_v1beta1_gateway.yaml deleted file mode 100644 index 48a542ea81..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_gateway.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: Gateway -metadata: - labels: - app.kubernetes.io/name: gateway - app.kubernetes.io/instance: gateway0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: gateway0 -spec: - stack: stack0 - ingress: - host: testing.formance.dev - scheme: https \ No newline at end of file diff --git a/components/operator/config/samples/formance.com_v1beta1_ledger.yaml b/components/operator/config/samples/formance.com_v1beta1_ledger.yaml deleted file mode 100644 index d7480a3986..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_ledger.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: Ledger -metadata: - labels: - app.kubernetes.io/name: ledger - app.kubernetes.io/instance: ledger0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: stack0-ledger -spec: - stack: stack0 - debug: true - dev: true \ No newline at end of file diff --git a/components/operator/config/samples/formance.com_v1beta1_opentelemetryconfiguration.yaml b/components/operator/config/samples/formance.com_v1beta1_opentelemetryconfiguration.yaml deleted file mode 100644 index 26419d584b..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_opentelemetryconfiguration.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: OpenTelemetryConfiguration -metadata: - labels: - app.kubernetes.io/name: opentelemetryconfigurations - app.kubernetes.io/instance: opentelemetryconfigurations0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - formance.com/stack: any - name: opentelemetryconfigurations0 -spec: - traces: - otlp: - endpoint: otel-collector-opentelemetry-collector.formance.svc.cluster.local - insecure: true - mode: grpc - port: 4317 - # resourceAttributes: "foo=bar" \ No newline at end of file diff --git a/components/operator/config/samples/formance.com_v1beta1_orchestration.yaml b/components/operator/config/samples/formance.com_v1beta1_orchestration.yaml deleted file mode 100644 index 838fdee5b8..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_orchestration.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: Orchestration -metadata: - labels: - app.kubernetes.io/name: orchestration - app.kubernetes.io/instance: orchestration0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: orchestration0 -spec: - stack: stack0 \ No newline at end of file diff --git a/components/operator/config/samples/formance.com_v1beta1_payments.yaml b/components/operator/config/samples/formance.com_v1beta1_payments.yaml deleted file mode 100644 index 8a11b9f16b..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_payments.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: Payments -metadata: - labels: - app.kubernetes.io/name: payments - app.kubernetes.io/instance: payments0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: payments0 -spec: - stack: stack0 - encryptionKey: ClaptonIsGod diff --git a/components/operator/config/samples/formance.com_v1beta1_reconciliation.yaml b/components/operator/config/samples/formance.com_v1beta1_reconciliation.yaml deleted file mode 100644 index 9043216dfd..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_reconciliation.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: Reconciliation -metadata: - labels: - app.kubernetes.io/name: reconciliation - app.kubernetes.io/instance: reconciliation0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: reconciliation0 -spec: - stack: stack0 diff --git a/components/operator/config/samples/formance.com_v1beta1_registriesconfigurations.yaml b/components/operator/config/samples/formance.com_v1beta1_registriesconfigurations.yaml deleted file mode 100644 index 6bdedf6763..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_registriesconfigurations.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: RegistriesConfiguration -metadata: - labels: - app.kubernetes.io/name: registriesconfigurations - app.kubernetes.io/instance: registriesconfigurations - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - formance.com/stack: any - name: registriesconfiguration0 -spec: - #registries: - # ghcr.io: - # endpoint: localhost:5000 diff --git a/components/operator/config/samples/formance.com_v1beta1_resourcereference.yaml b/components/operator/config/samples/formance.com_v1beta1_resourcereference.yaml deleted file mode 100644 index 782c180500..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_resourcereference.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: ResourceReference -metadata: - labels: - app.kubernetes.io/name: resourcereference - app.kubernetes.io/instance: resourcereference-sample - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: resourcereference-sample -spec: - # TODO(user): Add fields here diff --git a/components/operator/config/samples/formance.com_v1beta1_search.yaml b/components/operator/config/samples/formance.com_v1beta1_search.yaml deleted file mode 100644 index 43329f1f2d..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_search.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: Search -metadata: - labels: - app.kubernetes.io/name: search - app.kubernetes.io/instance: search0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: search0 -spec: - stack: stack0 diff --git a/components/operator/config/samples/formance.com_v1beta1_searchbatchingconfiguration.yaml b/components/operator/config/samples/formance.com_v1beta1_searchbatchingconfiguration.yaml deleted file mode 100644 index 98537f16a3..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_searchbatchingconfiguration.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: SearchBatchingConfiguration -metadata: - labels: - app.kubernetes.io/name: searchbatchingconfiguration - app.kubernetes.io/instance: searchbatchingconfiguration-sample - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: searchbatchingconfiguration-sample -spec: - # TODO(user): Add fields here diff --git a/components/operator/config/samples/formance.com_v1beta1_settings.yaml b/components/operator/config/samples/formance.com_v1beta1_settings.yaml deleted file mode 100644 index fffe8e8f75..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_settings.yaml +++ /dev/null @@ -1,20 +0,0 @@ ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: resource-requirements -spec: - stacks: - - "*" - key: deployments.*.containers.*.resource-requirements.limits - value: memory=1024Mi ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: search-batching -spec: - stacks: - - "*" - key: search.batching - value: count=10,period=10s diff --git a/components/operator/config/samples/formance.com_v1beta1_stack.yaml b/components/operator/config/samples/formance.com_v1beta1_stack.yaml deleted file mode 100644 index db5fcbe056..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_stack.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: Stack -metadata: - labels: - app.kubernetes.io/name: stack - app.kubernetes.io/instance: stack0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: stack0 -spec: {} diff --git a/components/operator/config/samples/formance.com_v1beta1_temporalconfiguration.yaml b/components/operator/config/samples/formance.com_v1beta1_temporalconfiguration.yaml deleted file mode 100644 index bc1bba05b3..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_temporalconfiguration.yaml +++ /dev/null @@ -1,65 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: TemporalConfiguration -metadata: - labels: - app.kubernetes.io/name: temporalconfiguration - app.kubernetes.io/instance: temporalconfiguration0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: temporalconfiguration0 -spec: - address: "local-operator.sihc8.tmprl.cloud:7233" - namespace: "local-operator.sihc8" - tls: - crt: | - -----BEGIN CERTIFICATE----- - MIIDvDCCAqSgAwIBAgIUTQMMmzxFv5yUcH6H3l3AI+o01CswDQYJKoZIhvcNAQEL - BQAwFzEVMBMGA1UEAxMMZm9ybWFuY2UuY29tMB4XDTIzMDEyMDEwMTExNVoXDTMz - MDExNzA5MTE0NVowGTEXMBUGA1UEAwwOKi5mb3JtYW5jZS5jb20wggEiMA0GCSqG - SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7NlrS6MuTXIEdUIs4FKaQY3krG4w7KKpr - /ztQXYJ/4kyit+xnP6uuIiEs5qwfWJnS3V5a5ZGHF6x2GdZAKRMlHt3xxL7K39xu - sY06kwCcNP7eNDKdz4fbaRQ109vM6ANY6h1VgZ7A/e49swV5gpJ+YfPqRykood6H - afGSL0jLzFqTujjbNV6ZwIRD7ZMIa/NOYlb6oxlfZZXtMKwPY7An5fpDyEVJCRrP - G2dShu0WHZlctzCjR3WFNfNPIN44yaPdF9q/WweWwcei8pcoz+d5m9sjUeviIhfb - dXODDWbwJu1i1COOGz0suWchPQJCYGc9xOigCDWrH5A2BSu3C2gzAgMBAAGjgf0w - gfowDgYDVR0PAQH/BAQDAgOoMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD - AjAdBgNVHQ4EFgQU564vj1K2ZEtgkcLtl5JurExg6AcwHwYDVR0jBBgwFoAU9JfZ - psQJOHGZ+vYuZzZLPQRLYmwwOwYIKwYBBQUHAQEELzAtMCsGCCsGAQUFBzAChh9o - dHRwOi8vMTI3LjAuMC4xOjgyMDAvdjEvcGtpL2NhMBkGA1UdEQQSMBCCDiouZm9y - bWFuY2UuY29tMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly8xMjcuMC4wLjE6ODIw - MC92MS9wa2kvY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAW9ispaeU9UnoTUihFf+cx - RzNQ+JbxGoAihvri25YbxnXifjd/v9D9GnP50dkhfPcBQZnFtspsg9gAMla/Hhl8 - 3g4liINIIMYy1wHak9K22a3+k5yKspbFovtvsOoac5jt0fIl+2MiBY3G1V7lKiZL - LQiOlDdmBlzkldGD3ubunuh1NTMUbnBF8JTKquSqZv1i7Js6UbelJg89g9gh4N+R - gK3El3m5jc2sLFQbuWiDx8gZtNWAd5wihs9ban87Dc9YOZ6695Dd/woifhMRuIWG - YIezLQgPPPiyvTcTARipcA68eVu5GpFG8L3BKR9Mz5TThasRnsFwfa/ylbZkSWun - -----END CERTIFICATE----- - key: | - -----BEGIN RSA PRIVATE KEY----- - MIIEowIBAAKCAQEAuzZa0ujLk1yBHVCLOBSmkGN5KxuMOyiqa/87UF2Cf+JMorfs - Zz+rriIhLOasH1iZ0t1eWuWRhxesdhnWQCkTJR7d8cS+yt/cbrGNOpMAnDT+3jQy - nc+H22kUNdPbzOgDWOodVYGewP3uPbMFeYKSfmHz6kcpKKHeh2nxki9Iy8xak7o4 - 2zVemcCEQ+2TCGvzTmJW+qMZX2WV7TCsD2OwJ+X6Q8hFSQkazxtnUobtFh2ZXLcw - o0d1hTXzTyDeOMmj3Rfav1sHlsHHovKXKM/neZvbI1Hr4iIX23Vzgw1m8CbtYtQj - jhs9LLlnIT0CQmBnPcTooAg1qx+QNgUrtwtoMwIDAQABAoIBADEmhhXVVI0tviAq - I0Ln+Qrzcr5kjx6BAK015yakRjy49xHJY+F/j905zKfzL8FTC5+WyszmdJyZFIg1 - JFDX99TJE9ADrWup9j+BkeiM654XM8q2vYs9DxgFsG6pXo2fZDGV1Xm7fCiDAmdk - ds1+AGP554XchOvMA5ZdtDSDAYOvgiTnhR+ic881U+L4DkHt+HRHv8ZFcuuUa5z/ - IVSoAR/yIUcQZeimp2l/SZoYk50pfzFNksAfnye6OS0PFhwNT/MX1+3u3ytm34Yj - fcXG/c1uKwfIR9GA/VseRDah0k+8fhsgECGeqtEJwUOqAzAmVWfyaCy6Ud/whAQP - qtl9aTECgYEA3/QJQO9MhlKCpxyOuTm/vAb/Tx0hO6Erd+jWwv8P2GMpM1n4kZd8 - O5/PPzPQKDlHu2gqNqwfqL77+RWw8xHQ25mUtfLVCiIPF4SVsNLD66E9KzU4yYpS - p40QckRHdaOO5gJmubkWV3UQczq2rPZyPs/Msy0r/8ilq4smMIjYpW8CgYEA1gBo - H2v14v7x4LhgpdJrMOg4gc80qJyFpxYxw2T/CdmyjVhsVCDGF/0d3j4Lo/SJB2y6 - YolJb6T3orCUnxOE8CHUktgHB7Auheh1Ls4xyA/HKExRvO8kh/YkBn+z3bIki0QB - w29yRx3d8hBu9hJT52f9veXN6wqzrp68H0Iw730CgYEA3nB/eHW25nuxtdZRlHxd - ip7Qm33tclLE4BbuqUO6M01asNyeXc2+4WH78WS/ThSGwQfXVfJkh7EaiO8YkHWT - o2rKIGaPX78wikVwgO73FmVSYkY8n0G6kx0zxqs25wuLdb3Q1ouWO0vVCP66TtWB - 6A1x3k3xs99RXi+ZwP9LYBUCgYAej3pPGmzH2N6T1+C9bXovRspjB0Me3RNdFBdR - LwgY0QTlmH4H2ZJQdK4iQbwJ0u8Kp2VKkw5wqh9PFWZz/Sab4EjqG32NhIRwTQ0G - /R0w08f+Ij/9+iy+WdE1OGFoRHthg/m4fh7Utxgt7FjcPSvMPRaIWtv4N9QHGNYG - pL42RQKBgCRDE6abLoeUN38GIfQ09YeWoaRgQ0WYzeNwzu1Yl2VwLifWjrbukKZX - p+3B/M7FaeXhjJ3qSVDXBXqI94B7NLjH32CxKsuil2ry7p+lLzdBDquUtMoL17lg - xpAA8tqK3W+E8gj01vKhbcGP28373jREU016/HCbEHRsNxW/BGDj - -----END RSA PRIVATE KEY----- diff --git a/components/operator/config/samples/formance.com_v1beta1_versions.yaml b/components/operator/config/samples/formance.com_v1beta1_versions.yaml deleted file mode 100644 index b239c23a8e..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_versions.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: Versions -metadata: - labels: - app.kubernetes.io/name: versions - app.kubernetes.io/instance: versions-sample - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: versions-sample -spec: - # TODO(user): Add fields here diff --git a/components/operator/config/samples/formance.com_v1beta1_wallets.yaml b/components/operator/config/samples/formance.com_v1beta1_wallets.yaml deleted file mode 100644 index c1b8082b94..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_wallets.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: Wallets -metadata: - labels: - app.kubernetes.io/name: wallets - app.kubernetes.io/instance: wallets0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: wallets0 -spec: - stack: stack0 diff --git a/components/operator/config/samples/formance.com_v1beta1_webhooks.yaml b/components/operator/config/samples/formance.com_v1beta1_webhooks.yaml deleted file mode 100644 index 2debdc7907..0000000000 --- a/components/operator/config/samples/formance.com_v1beta1_webhooks.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: formance.com/v1beta1 -kind: Webhooks -metadata: - labels: - app.kubernetes.io/name: webhooks - app.kubernetes.io/instance: webhooks0 - app.kubernetes.io/part-of: operatorv2 - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: operatorv2 - name: webhooks0 -spec: - stack: stack0 - debug: true - version: local2 diff --git a/components/operator/config/samples/kustomization.yaml b/components/operator/config/samples/kustomization.yaml deleted file mode 100644 index f5054d5ea5..0000000000 --- a/components/operator/config/samples/kustomization.yaml +++ /dev/null @@ -1,24 +0,0 @@ -## Append samples of your project ## -resources: -- stack.formance.com_v1beta3_stack.yaml -- stack.formance.com_v1beta3_configuration.yaml -- stack.formance.com_v1beta3_versions.yaml -- formance.com_v1beta1_database.yaml -- formance.com_v1beta1_stack.yaml -- formance.com_v1beta1_ledger.yaml -- formance.com_v1beta1_opentelemetryconfigurations.yaml -- formance.com_v1beta1_gateway.yaml -- formance.com_v1beta1_auth.yaml -- formance.com_v1beta1_authclient.yaml -- formance.com_v1beta1_wallets.yaml -- formance.com_v1beta1_orchestration.yaml -- formance.com_v1beta1_webhooks.yaml -- formance.com_v1beta1_reconciliation.yaml -- formance.com_v1beta1_payments.yaml -- formance.com_v1beta1_search.yaml -- formance.com_v1beta1_stargate.yaml -- 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/config/webhook/manifests.yaml b/components/operator/config/webhook/manifests.yaml deleted file mode 100644 index 640f9d71b7..0000000000 --- a/components/operator/config/webhook/manifests.yaml +++ /dev/null @@ -1,26 +0,0 @@ ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: mutating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate-stack-formance-com-v1beta2-stack - failurePolicy: Fail - name: mstacks-v1beta2.kb.io - rules: - - apiGroups: - - stack.formance.com - apiVersions: - - v1beta2 - operations: - - CREATE - - UPDATE - resources: - - stacks - sideEffects: None diff --git a/components/operator/crd-doc-templates/gv_details.tpl b/components/operator/crd-doc-templates/gv_details.tpl deleted file mode 100644 index d69a71d02c..0000000000 --- a/components/operator/crd-doc-templates/gv_details.tpl +++ /dev/null @@ -1,95 +0,0 @@ -{{- define "rootType" }} -{{ template "type" (dict "Type" . "Recurse" false "Prefix" 4)}} - -{{- range $k, $field := .Fields }} -{{ if $field.Type.IsBasic }}{{ continue }}{{ end }} -{{- if eq $field.Name "spec" }} -{{ template "type" (dict "Type" $field.Type "Recurse" true "Prefix" 5) }} -{{- end }} -{{- end }} - -{{- range $k, $field := .Fields }} -{{ if $field.Type.IsBasic }}{{ continue }}{{ end }} -{{- if eq $field.Name "status" }} -{{ template "type" (dict "Type" $field.Type "Recurse" true "Prefix" 5) }} -{{- end }} -{{- end }} -{{- end }} - -{{- define "gvDetails" -}} -{{- $gv := . -}} - -## {{ $gv.GroupVersionString }} - -{{ $gv.Doc }} - -{{- if $gv.Kinds }} -Modules : -{{- range $gv.SortedTypes }} -{{- $k8sMetadata := index .Markers "kubebuilder:metadata" }} -{{- if gt (len $k8sMetadata) 0 }} -{{- $labels := (index $k8sMetadata 0).Labels }} -{{- if gt (len $labels) 0 }} -{{- $isModule := has "formance.com/kind=module" $labels }} -{{- if $isModule }} -- {{ $gv.TypeForKind .Name | markdownRenderTypeLink }} -{{- end }} -{{- end }} -{{- end }} -{{- end }} - -Other resources : -{{- range $gv.SortedTypes }} -{{- if eq .Name "Stack"}}{{ continue }}{{ end }} -{{- if eq .Name "Settings"}}{{ continue }}{{ end }} -{{- $k8sMetadata := index .Markers "kubebuilder:metadata" }} -{{- $isModule := and (gt (len $k8sMetadata) 0) (has "formance.com/kind=module" (index $k8sMetadata 0).Labels) }} -{{- $kubeBuilderIsRoot := index .Markers "kubebuilder:object:root" }} -{{- $isRoot := and (gt (len $kubeBuilderIsRoot) 0) (index $kubeBuilderIsRoot 0) }} -{{- if and (not $isModule) $isRoot }} -- {{ $gv.TypeForKind .Name | markdownRenderTypeLink }} -{{- end }} -{{- end }} - -### Main resources - -{{- /** Display details about Stack resource */}} -{{ template "rootType" (index $gv.Types "Stack") }} - -{{- /** Display details about Setting resource */}} -{{ template "rootType" (index $gv.Types "Settings") }} - -### Modules - -{{- range $gv.SortedTypes }} -{{- $k8sMetadata := index .Markers "kubebuilder:metadata" }} -{{- if gt (len $k8sMetadata) 0 }} -{{- $labels := (index $k8sMetadata 0).Labels }} -{{- if gt (len $labels) 0 }} -{{- $isModule := has "formance.com/kind=module" $labels }} -{{- if $isModule }} -{{ template "rootType" . }} -{{- end }} -{{- end }} -{{- end }} -{{- end }} - -### Other resources - -{{- range $gv.SortedTypes }} -{{- if eq .Name "Stack" }}{{ continue }}{{ end }} -{{- if eq .Name "Settings" }}{{ continue }}{{ end }} -{{- $k8sMetadata := index .Markers "kubebuilder:metadata" }} -{{- $isModule := and (gt (len $k8sMetadata) 0) (has "formance.com/kind=module" (index $k8sMetadata 0).Labels) }} -{{- $kubeBuilderIsRoot := index .Markers "kubebuilder:object:root" }} -{{- $isRoot := and (gt (len $kubeBuilderIsRoot) 0) (index $kubeBuilderIsRoot 0) }} - -{{- if and (not $isModule) $isRoot }} -{{ template "rootType" . }} -{{- end }} -{{- end }} - - -{{- end }} -{{- end }} - diff --git a/components/operator/crd-doc-templates/gv_list.tpl b/components/operator/crd-doc-templates/gv_list.tpl deleted file mode 100644 index a4d3dadf18..0000000000 --- a/components/operator/crd-doc-templates/gv_list.tpl +++ /dev/null @@ -1,15 +0,0 @@ -{{- define "gvList" -}} -{{- $groupVersions := . -}} - -# API Reference - -## Packages -{{- range $groupVersions }} -- {{ markdownRenderGVLink . }} -{{- end }} - -{{ range $groupVersions }} -{{ template "gvDetails" . }} -{{ end }} - -{{- end -}} diff --git a/components/operator/crd-doc-templates/type.tpl b/components/operator/crd-doc-templates/type.tpl deleted file mode 100644 index 4d2a3eb3b1..0000000000 --- a/components/operator/crd-doc-templates/type.tpl +++ /dev/null @@ -1,58 +0,0 @@ -{{- define "type" -}} -{{- $type := .Type -}} -{{- $recurse := .Recurse -}} -{{- $prefix := .Prefix -}} - -{{ repeat ($prefix | int) "#" }} {{ $type.Name }} - -{{ if $type.IsAlias }}_Underlying type:_ _{{ markdownRenderTypeLink $type.UnderlyingType }}_{{ end }} - -{{ $type.Doc }} - -{{/*{{ if $type.Validation -}}*/}} -{{/*_Validation:_*/}} -{{/*{{- range $type.Validation }}*/}} -{{/*- {{ . }}*/}} -{{/*{{- end }}*/}} -{{/*{{- end }}*/}} - -{{/*{{ if $type.References -}}*/}} -{{/*_Appears in:_*/}} -{{/*{{- range $type.SortedReferences }}*/}} -{{/*- {{ markdownRenderTypeLink . }}*/}} -{{/*{{- end }}*/}} -{{/*{{- end }}*/}} - -{{ if $type.Members -}} -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -{{ if $type.GVK -}} -| `apiVersion` _string_ | `{{ $type.GVK.Group }}/{{ $type.GVK.Version }}` | | | -| `kind` _string_ | `{{ $type.GVK.Kind }}` | | | -{{ end -}} - -{{ range $type.Members -}} -{{- if or (has "Type: string" .Type.Validation) (eq (markdownRenderType .Type) "[Duration](#duration)") -}} -| `{{ .Name }}` _string_ | {{ template "type_members" . }} | {{ markdownRenderDefault .Default }} | {{ range .Validation -}} {{ . }}
{{ end }} | -{{- else -}} -| `{{ .Name }}` _{{ markdownRenderType .Type }}_ | {{ template "type_members" . }} | {{ markdownRenderDefault .Default }} | {{ range .Validation -}} {{ . }}
{{ end }} | -{{- end }} -{{ end -}} - -{{ end -}} - -{{- if $recurse }} -{{- if eq $type.Kind 4}} -{{- $dummy := set . "Fields" $type.UnderlyingType.Fields }} -{{- else }} -{{- $dummy := set . "Fields" $type.Fields }} -{{- end }} -{{- range $k, $field := .Fields }} -{{- if hasPrefix "github.com/formancehq/operator/api" $field.Type.Package }} -{{- if has "Type: string" $field.Type.Validation }}{{ continue }}{{ end }} -{{ template "type" (dict "Type" $field.Type "Recurse" true "Prefix" (min (add $prefix 1) 6)) }} -{{- end }} -{{- end }} -{{- end }} - -{{- end -}} diff --git a/components/operator/crd-doc-templates/type_members.tpl b/components/operator/crd-doc-templates/type_members.tpl deleted file mode 100644 index 041758a872..0000000000 --- a/components/operator/crd-doc-templates/type_members.tpl +++ /dev/null @@ -1,8 +0,0 @@ -{{- define "type_members" -}} -{{- $field := . -}} -{{- if eq $field.Name "metadata" -}} -Refer to Kubernetes API documentation for fields of `metadata`. -{{- else -}} -{{ markdownRenderFieldDoc $field.Doc }} -{{- end -}} -{{- end -}} diff --git a/components/operator/docs.config.yaml b/components/operator/docs.config.yaml deleted file mode 100644 index 82f93b1c76..0000000000 --- a/components/operator/docs.config.yaml +++ /dev/null @@ -1,22 +0,0 @@ -processor: - # RE2 regular expressions describing types that should be excluded from the generated documentation. - ignoreTypes: - - "(.*)List$" - - Conditions - - Condition - - AuthConfig # notes/todo(gfyrag): Not exposing that as I think we should use a Setting - # RE2 regular expressions describing type fields that should be excluded from the generated documentation. - ignoreFields: - #- "status$" - - "TypeMeta$" - - conditions - - apiVersion - -render: - # Version of Kubernetes to use when generating links to Kubernetes API documentation. - kubernetesVersion: 1.27 - # Generate better link for known types - knownTypes: - - name: SecretObjectReference - package: sigs.k8s.io/gateway-api/apis/v1beta1 - link: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.SecretObjectReference diff --git a/components/operator/docs/01-Requirements.md b/components/operator/docs/01-Requirements.md deleted file mode 100644 index 7ace720d89..0000000000 --- a/components/operator/docs/01-Requirements.md +++ /dev/null @@ -1,18 +0,0 @@ -Before creating our region and deploying the Formance Operator, let's make sure that our cluster is ready to host our operator and have the required following items below in place. - -## Ingress controller (optional) - -If you want to expose your stacks outside of your Kubernetes cluster, you'll need an Ingress Controller. At Formance, we use Traefik as our Ingress Controller, but you can use another Ingress Controller without any issues. - -SSL certificate management can be done either at the level of your LoadBalancer upstream of the Ingress Controller or directly by your Ingress Controller. - -:::info -As the Formance Operator will create standard `Ingress` objects to be picked up, alternative ingress controllers can work just as great but might require additional configuration not covered in this setup guide. -::: - -## Stateful dependencies - -To function properly, the Formance Modules deployed in your Kubernetes cluster will need certain dependencies among the following stateful dependencies. - -The list of dependencies changes according to the modules you wish to deploy. -In every module installation guide, you will find a list of required dependencies as well as a guide on how to integrate them with your Formance deployment. diff --git a/components/operator/docs/02-Installation.md b/components/operator/docs/02-Installation.md deleted file mode 100644 index db1d2f01f4..0000000000 --- a/components/operator/docs/02-Installation.md +++ /dev/null @@ -1,103 +0,0 @@ -The deployment of resources is orchestrated by the Formance Kubernetes Operator, which is driven by the CRDs present in the Kubernetes Cluster and reconciles them against the current state of the cluster. - -This essentially means that the operator will be creating and maintaining pods, services, and other resources on your cluster on your behalf. It is also the last mile of this setup guide before you get to actually use your Formance Stack — let's get started! - - -## Setup - - -With the emergence of multiple tools and services that use helm templatization. We have choosen to separate `Custom Resource Definitions`(CRDs) separatelty from operator deployment. As noticed within [Helm CRDs best practicies](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/), -this allow us to have more control over the CRDs lifecycle and also avoid deletion of the CRDs when the operator is uninstalled. - -### Helm installation - -If you don't have Helm installed, you can follow the [official Helm installation guide](https://helm.sh/docs/intro/install/). -Dependending of your needs, you can install the CRDs and the operator separatly or together. - -### Operator CRDs -To install the Formance Operator CRDs, you can use the following command: - -```bash -helm upgrade --install operator-crds oci://ghcr.io/formancehq/helm/operator-crds \ ---version v2.0.3 \ ---namespace formance-system \ ---create-namespace -``` - -As noticed above, the version will always be the same as the operator version. CRDs **must always** be upgraded before the operator. - -### Operator Deployment - -From version v2.0.3, CRDs are now packaged with `helm.sh/resource-policy: keep` to avoid deletion of the CRDs when the operator is uninstalled. - -You can deploy Formance Operator using Helm: - -```bash -helm upgrade --install regions oci://ghcr.io/formancehq/helm/regions \ ---version v2.0.3 \ ---namespace formance-system \ ---create-namespace \ ---set operator.operator-crds.create=false -``` - -### Migrating from Operator chart with CRDs to dedicated CRDs chart - -First make **sure** you've already upgraded the operator chart with crds `operator-crds.create=true` to make sure the `helm.sh/resource-policy: keep` is present. -You can verify this by running: - -```bash -kubectl get crds authclients.formance.com -o json | jq .metadata.annotations -{ - "controller-gen.kubebuilder.io/version": "v0.14.0", - "helm.sh/resource-policy": "keep", <---- This should be present - "meta.helm.sh/release-name": "formance-operator", - "meta.helm.sh/release-namespace": "formance-system" -} -``` - -If using Helm Release, you might want to set appropriate helm release ownership annotations to the new chart using kubectl: - -#### Migration bash script - -```bash -#!/bin/bash - -# Set the required namespace and release name -NAMESPACE=formance-system -RELEASE_NAME=operator-crds - -for GROUP in stack.formance.com formance.com -do - NAMES=$(kubectl api-resources --api-group=$GROUP --verbs=list -o name) - for CRD in $NAMES - do - echo "----- Annotating $CRD -----" - kubectl annotate crd $CRD meta.helm.sh/release-name=$RELEASE_NAME --overwrite - kubectl annotate crd $CRD meta.helm.sh/release-namespace=$NAMESPACE --overwrite - echo "--------- Done ----------" - done -done - -``` - -Then you will be able to disable `operator-crds.create: false` and install the operator-crds chart separately. - -#### Disable CRDs creation - -```bash -helm upgrade --install regions oci://ghcr.io/formancehq/helm/regions \ ---version v2.0.3 \ ---namespace $NAMESPACE \ ---create-namespace \ ---set operator.operator-crds.create=false - -``` - -#### Install the new charts - -```bash -helm upgrade --install $RELEASE_NAME oci://ghcr.io/formancehq/helm/operator-crds \ ---version v2.0.3 \ ---namespace $NAMESPACE \ ---create-namespace -``` \ No newline at end of file diff --git a/components/operator/docs/03-Demo deployment.md b/components/operator/docs/03-Demo deployment.md deleted file mode 100644 index eaac57bda4..0000000000 --- a/components/operator/docs/03-Demo deployment.md +++ /dev/null @@ -1,33 +0,0 @@ -# Demo deployment - -:::warning -This guide assumes that you have already installed the Formance Operator on your cluster. If you haven't done so, please refer to the [installation guide](02-Installation.md) before proceeding. -::: - -If you want to have a sample deployment, you can use our Demo Helm chart which will deploy all the necessary resources to install Formance on your cluster. -This will install the following components: -- Gateway -- Ledger -- Payments -- PostgreSQL - -```bash -helm upgrade --install demo oci://ghcr.io/formancehq/helm/demo \ ---version 2.0.0 \ ---namespace formance-system \ ---create-namespace -``` - -You can verify that the installation was successful by using the following command: -```bash -kubectl get pods,svc -n formance-dev -``` - -### How to access to Demo environement -```BASH -kubectl port-forward -n formance-dev svc/gateway 8080:8080 -``` -You can now check the different versions of the components installed on your cluster using the following command: -```bash -curl http://localhost:8080/versions -``` diff --git a/components/operator/docs/04-Modules/01-Stack.md b/components/operator/docs/04-Modules/01-Stack.md deleted file mode 100644 index e8fe97eac0..0000000000 --- a/components/operator/docs/04-Modules/01-Stack.md +++ /dev/null @@ -1,24 +0,0 @@ -## Overview - -A Stack represents a set of modules that are deployed together. It is used as a way to group modules and to deploy them together with a consistent set of versions and configurations. - -When you deploy a Formance module, such as Ledger or Payments, you deploy them within a Stack. This allows you to ensure that they are all deployed with the same versions and configurations. - -## Stack Object -The first object that needs to be created is the Stack object. This allows linking the different modules and deploying them together. - -:::info -You can find all the available parameters in [the comprehensive CRD documentation](../09-Configuration%20reference/02-Custom%20Resource%20Definitions.md#stack). -::: - -```yaml -apiVersion: formance.com/v1beta1 -kind: Stack -metadata: - name: formance-dev -spec: - versionsFromFile: v2.0 -``` - -During the deployment of the Operator and for its future upgrades, the Versions files are automatically updated following the semver pattern. -It is possible to specify a specific version by using the `versionFromFile` field in the Stack file. diff --git a/components/operator/docs/04-Modules/02-Gateway.md b/components/operator/docs/04-Modules/02-Gateway.md deleted file mode 100644 index 8e20ddedf3..0000000000 --- a/components/operator/docs/04-Modules/02-Gateway.md +++ /dev/null @@ -1,31 +0,0 @@ -The Gateway's role is to centralize all incoming connections to your stack. If you need to expose your Stack to the outside, it is necessary to route all the traffic through it. -## Gateway Object - -:::info -You can find all the available parameters in [the comprehensive CRD documentation](../09-Configuration%20reference/02-Custom%20Resource%20Definitions.md#gateway). -::: - -```yaml -apiVersion: formance.com/v1beta1 -kind: Gateway -metadata: - name: formance-dev -spec: - stack: formance-dev -``` - - -### Expose the Gateway with Ingress -To expose the Gateway to the outside, we will use an Ingress object. The Ingress will be the entry point to your stack. - -```yaml -apiVersion: formance.com/v1beta1 -kind: Gateway -metadata: - name: formance-dev -spec: - stack: formance-dev - ingress: - host: YOUR_DOMAIN - scheme: http|https -``` \ No newline at end of file diff --git a/components/operator/docs/04-Modules/03-Ledger.md b/components/operator/docs/04-Modules/03-Ledger.md deleted file mode 100644 index 642c288757..0000000000 --- a/components/operator/docs/04-Modules/03-Ledger.md +++ /dev/null @@ -1,22 +0,0 @@ -Formance Ledger is a real-time money tracking microservice that lets you model and record complex financial transactions. It offers atomic, multi-posting transactions and is programmable using Numscript, a dedicated DSL (Domain Specific Language) to model and templatize such transactions. - -## Requirements - -Formance Ledger requires: -- **PostgreSQL**: See configuration guide [here](../05-Infrastructure%20services/01-PostgreSQL.md). -- (Optional) **Broker**: See configuration guide [here](../05-Infrastructure%20services/02-Message%20broker.md). - -## Ledger Object - -:::info -You can find all the available parameters in [the comprehensive CRD documentation](../09-Configuration%20reference/02-Custom%20Resource%20Definitions.md#ledger). -::: - -```yaml -apiVersion: formance.com/v1beta1 -kind: Ledger -metadata: - name: formance-dev -spec: - stack: formance-dev -``` diff --git a/components/operator/docs/04-Modules/04-Payments.md b/components/operator/docs/04-Modules/04-Payments.md deleted file mode 100644 index 0743261a4c..0000000000 --- a/components/operator/docs/04-Modules/04-Payments.md +++ /dev/null @@ -1,22 +0,0 @@ -Formance Payments is a unified API that abstracts over multiple different payment providers like Stripe and Wise, simplifying the process of building money flows that stitch multiple payment providers together. - -## Requirements - -Formance Payments requires: -- **PostgreSQL**: See configuration guide [here](../05-Infrastructure%20services/01-PostgreSQL.md). -- (Optional) **Broker**: See configuration guide [here](../05-Infrastructure%20services/02-Message%20broker.md). - -## Payments Object - -:::info -You can find all the available parameters in [the comprehensive CRD documentation](../09-Configuration%20reference/02-Custom%20Resource%20Definitions.md#payments). -::: - -```yaml -apiVersion: formance.com/v1beta1 -kind: Payments -metadata: - name: formance-dev -spec: - stack: formance-dev -``` diff --git a/components/operator/docs/04-Modules/05-Auth.md b/components/operator/docs/04-Modules/05-Auth.md deleted file mode 100644 index 1d01a2c169..0000000000 --- a/components/operator/docs/04-Modules/05-Auth.md +++ /dev/null @@ -1,43 +0,0 @@ -:::warning -This Module is subject to a user license. -::: - -## Requirements - -Formance Auth requires: -- **PostgreSQL**: See configuration guide [here](../05-Infrastructure%20services/02-Message%20broker.md). - -## Auth Object -:::info -You can find all the available parameters in [the comprehensive CRD documentation](../09-Configuration%20reference/02-Custom%20Resource%20Definitions.md#auth). -::: - -```yaml -apiVersion: formance.com/v1beta1 -kind: Auth -metadata: - name: formance-dev -spec: - stack: formance-dev -``` - -### Define oAuth2 clients -You can define oAuth2 clients to secure your stack. The Auth will then be able to authenticate the incoming requests and forward them to the right service. - -Here, you can replace `YOUR_ID` and `YOUR_SECRET` with your own arbitrary string values. - -```yaml -apiVersion: formance.com/v1beta1 -kind: AuthClient -metadata: - name: formance-dev-clients -spec: - id: YOUR_ID - secret: YOUR_SECRET - scopes: - - ledger:read - - ledger:write - - payments:read - - payments:write - stack: formance-dev -``` \ No newline at end of file diff --git a/components/operator/docs/04-Modules/06-Orchestration.md b/components/operator/docs/04-Modules/06-Orchestration.md deleted file mode 100644 index 3c694a5ebf..0000000000 --- a/components/operator/docs/04-Modules/06-Orchestration.md +++ /dev/null @@ -1,32 +0,0 @@ -:::warning -This Module is subject to a user license. -::: - -Formance Flows is a handy service that lets you quickly set up end-to-end money flows, without the headache of piecing together APIs and untangling complex systems. - -With a clever compatibility model, you can easily move value between different ledgers, wallets, and payment processors. Plus, Formance Flows takes care of translating and interpreting the transactions for you. - -On top of that, Formance Flows comes with flexible workflow capabilities, so you can create complex flows that account for delays or external events, as well as retry and fallback options. All of this helps make your financial management smoother and stress-free. - - -## Requirements - -Formance Flows requires: -- **PostgreSQL**: See configuration guide [here](../05-Infrastructure%20services/01-PostgreSQL.md). -- **Temporal**: See configuration guide [here](../05-Infrastructure%20services/04-Temporal.md). -- **Broker**: See configuration guide [here](../05-Infrastructure%20services/02-Message%20broker.md). - -## Orchestration Object - -:::info -You can find all the available parameters in [the comprehensive CRD documentation](../09-Configuration%20reference/02-Custom%20Resource%20Definitions.md#orchestration). -::: - -```yaml -apiVersion: formance.com/v1beta1 -kind: Orchestration -metadata: - name: formance-dev -spec: - stack: formance-dev -``` diff --git a/components/operator/docs/04-Modules/07-Search.md b/components/operator/docs/04-Modules/07-Search.md deleted file mode 100644 index 22440b863e..0000000000 --- a/components/operator/docs/04-Modules/07-Search.md +++ /dev/null @@ -1,35 +0,0 @@ -:::warning -This Module is subject to a user license. -::: - -## Overview - -Formance Search is a service that provides a search engine for your Formance stack. It is based on Elasticsearch and provides a powerful search engine for your data. - -Search comes with with two components: -- **Search**: The public search service itself used to search your data. -- **[Benthos](https://www.benthos.dev/)**: The data pipeline that indexes your data into the search engine. - -Benthos is a stream processor that is used to ingest data from your Formance stack into the Eleasticsearch search engine. Benthos listens to the [messages broker](../05-Infrastructure%20services/02-Message%20broker.md), transforms the data and indexes it into the search engine. - -When you install the Search module with the Formance Operator, it will automatically install and configure Benthos on your behalf. - -## Requirements - -Formance Search requires: -- **Elasticsearch / OpenSearch**: See configuration guide [here](../05-Infrastructure%20services/03-Elasticsearch.md). - -## Search Object - -:::info -You can find all the available parameters in [the comprehensive CRD documentation](../09-Configuration%20reference/02-Custom%20Resource%20Definitions.md). -::: - -```yaml -apiVersion: formance.com/v1beta1 -kind: Search -metadata: - name: formance-dev -spec: - stack: formance-dev -``` diff --git a/components/operator/docs/04-Modules/08-Reconciliation.md b/components/operator/docs/04-Modules/08-Reconciliation.md deleted file mode 100644 index 31d1b07d4c..0000000000 --- a/components/operator/docs/04-Modules/08-Reconciliation.md +++ /dev/null @@ -1,25 +0,0 @@ -:::warning -This Module is subject to a user license. -::: - -## Requirements - -Formance Reconciliation requires: -- **PostgreSQL**: See configuration guide [here](../05-Infrastructure%20services/01-PostgreSQL.md). -- **Ledger**: See configuration guide [here](../04-Modules/03-Ledger.md). -- **Payments**: See configuration guide [here](../04-Modules/04-Payments.md). - -## Reconciliation Object - -:::info -You can find all the available parameters in [the comprehensive CRD documentation](../09-Configuration%20reference/02-Custom%20Resource%20Definitions.md#reconciliation). -::: - -```yaml -apiVersion: formance.com/v1beta1 -kind: Reconciliation -metadata: - name: formance-dev -spec: - stack: formance-dev -``` diff --git a/components/operator/docs/04-Modules/09-Wallets.md b/components/operator/docs/04-Modules/09-Wallets.md deleted file mode 100644 index 24e7a7413c..0000000000 --- a/components/operator/docs/04-Modules/09-Wallets.md +++ /dev/null @@ -1,25 +0,0 @@ -:::warning -This Module is subject to a user license. -::: - -Wallets is a fully managed, white-label wallet service to materialize and spend users funds. It comes with built-in support for multi-currency balances and temporary holds capabilities (and upcoming support for reserved funds and expirable fungibles). It is built on top of the Formance Ledger service and is designed to provide an easy way to add wallets capabilities to your application without having to worry about the underlying transactions structure, providing an opinionated model implementation. - -## Requirements - -Formance Wallets requires: -- **Ledger**: See configuration guide [here](../04-Modules/03-Ledger.md). - -## Wallets Object - -:::info -You can find all the available parameters in [the comprehensive CRD documentation](../09-Configuration%20reference/02-Custom%20Resource%20Definitions.md#wallets). -::: - -```yaml -apiVersion: formance.com/v1beta1 -kind: Wallets -metadata: - name: formance-dev -spec: - stack: formance-dev -``` diff --git a/components/operator/docs/04-Modules/10-Webhooks.md b/components/operator/docs/04-Modules/10-Webhooks.md deleted file mode 100644 index 62e974cd16..0000000000 --- a/components/operator/docs/04-Modules/10-Webhooks.md +++ /dev/null @@ -1,24 +0,0 @@ -:::warning -This Module is subject to a user license. -::: - -## Requirements - -Formance Webhooks requires: -- **PostgreSQL**: See configuration guide [here](../05-Infrastructure%20services/01-PostgreSQL.md). -- **Broker**: See configuration guide [here](../05-Infrastructure%20services/02-Message%20broker.md). - -## Webhooks Object - -:::info -You can find all the available parameters in [the comprehensive CRD documentation](../09-Configuration%20reference/02-Custom%20Resource%20Definitions.md#webhooks). -::: - -```yaml -apiVersion: formance.com/v1beta1 -kind: Webhooks -metadata: - name: formance-dev -spec: - stack: formance-dev -``` diff --git a/components/operator/docs/05-Infrastructure services/01-PostgreSQL.md b/components/operator/docs/05-Infrastructure services/01-PostgreSQL.md deleted file mode 100644 index af50bb33cc..0000000000 --- a/components/operator/docs/05-Infrastructure services/01-PostgreSQL.md +++ /dev/null @@ -1,90 +0,0 @@ -_Version 14 or higher is required._ - -The recommended way to spin up a PostgreSQL deployment is to use your cloud provider's managed services. It is recommended to start with a small instance and scale up as needed, starting with for example a `db.m4.large` sizing on AWS. - - -## Create the database settings - -### Option 1: Use the same server for all modules - -In this example, you'll set up a configuration for a PostgreSQL cluster that will be used only by the `formance-dev` stack but will apply to all the modules of this stack. -Thus, the different modules of the Stack will use this PostgreSQL cluster while being isolated in their own database. - -:::info -This database is created following the format: `{stackName}-{module}` -::: - -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-postgres-uri -spec: - key: postgres.*.uri - stacks: - - 'formance-dev' - value: postgresql://formance:formance@postgresql.formance-system.svc:5432?disableSSLMode=true -``` - -### Option 2: Use different servers for each module - -In this example you'll set up a configuration dedicated Postgres cluster for the `ledger` and `payments` modules of the `formance-dev` stack. - -```yaml ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-ledger-postgres-uri -spec: - key: postgres.ledger.uri - stacks: - - 'formance-dev' - value: postgresql://formance:formance@postgresql-ledger.formance-system.svc:5432?disableSSLMode=true ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-payments-postgres-uri -spec: - key: postgres.payments.uri - stacks: - - 'formance-dev' - value: postgresql://formance:formance@postgresql-payments.formance-system.svc:5432?disableSSLMode=true -``` - -### Option 3: Use PostgreSQL on AWS RDS with an IAM role - -In this example, you'll use an AWS IAM role to connect to the database. The `formance-dev` stack will use this configuration. - -```yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: aws-rds-access-role - namespace: formance-system - labels: - formance.com/stack: any - annotations: - eks.amazonaws.com/role-arn: arn:aws:iam::AWS_ACCOUNT_ID:role/AWS_ROLE_NAME ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-aws-service-account -spec: - stacks: - - formance-dev - key: aws.service-account - value: aws-rds-access-role ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-postgres-uri -spec: - key: postgres.*.uri - stacks: - - 'formance-dev' - value: postgresql://formance@postgresql.formance-system.svc:5432 - ``` diff --git a/components/operator/docs/05-Infrastructure services/02-Message broker.md b/components/operator/docs/05-Infrastructure services/02-Message broker.md deleted file mode 100644 index d05b4dcc78..0000000000 --- a/components/operator/docs/05-Infrastructure services/02-Message broker.md +++ /dev/null @@ -1,55 +0,0 @@ -# Message Broker - -The broker is the messaging system that the Formance stack uses to communicate between its modules. The Formance stack supports both [NATS](https://nats.io/) and [Kafka](https://kafka.apache.org/) as brokers. - -The broker sends messages between the different modules of the Formance stack. The producers are Ledger, Gateway, and Payments. The consumers are Benthos, Orchestration and Webhooks. Benthos is used to transform messages so that they can be ingested by the ElasticSearch / OpenSearch cluster to power the Search module. - -:::info -This stream is created following the format: `{stackName}-{module}` -::: - -## Option 1: NATS - -_Version 2.6 or higher with Jetstream is required._ - -The recommended way to spin up a NATS deployment is through the official NATS helm [chart](https://artifacthub.io/packages/helm/nats/nats). - -:::info -Depending on your setup, you may need to activate Jetsream mode on your NATS deployment manually. Jetstream is required for the resources deployed by the Formance Operator to function properly. -::: - -### Create the NATS settings - -In this example, you'll set up a configuration for the Broker of the `formance-dev` stack. This configuration will apply to all the modules of this stack. - -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-nats -spec: - key: broker.dsn - stacks: - - 'formance-dev' - value: nats://nats.formance-system.svc:4222?replicas=3 -``` - -## Option 2: Kafka - -The Formance stack also supports Kafka as a broker. To use Kafka, you need to set up a Kafka cluster and configure the Formance Operator to use it. - -### Create the Kafka settings - -In this example, you'll set up a configuration for the Broker of the `formance-dev` stack. This configuration will apply to all the modules of this stack. - -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-nats -spec: - key: broker.dsn - stacks: - - 'formance-dev' - value: kafka://kafka.formance-system.svc:9092 -``` \ No newline at end of file diff --git a/components/operator/docs/05-Infrastructure services/03-Elasticsearch.md b/components/operator/docs/05-Infrastructure services/03-Elasticsearch.md deleted file mode 100644 index e6604b3ba6..0000000000 --- a/components/operator/docs/05-Infrastructure services/03-Elasticsearch.md +++ /dev/null @@ -1,25 +0,0 @@ -# Elasticsearch - -_Version 7.10 or higher is required._ - -The recommended way to spin up an Elasticsearch / OpenSearch deployment is to use your cloud provider's managed service, or Elastic Cloud itself. - -:::info -If you are using Elastic Cloud, make sure to use a deployment in a network with low latency to your cluster. -::: - -## Create the ElasticSearch / OpenSearch settings - -In this example, you'll set up a configuration for the Broker of the `formance-dev` stack. This configuration will apply to all the modules of this stack. - -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-es -spec: - key: elasticsearch.dsn - stacks: - - 'formance-dev' - value: https://es.formance-system.svc:443? -``` diff --git a/components/operator/docs/05-Infrastructure services/04-Temporal.md b/components/operator/docs/05-Infrastructure services/04-Temporal.md deleted file mode 100644 index 693338f64b..0000000000 --- a/components/operator/docs/05-Infrastructure services/04-Temporal.md +++ /dev/null @@ -1,51 +0,0 @@ -### Temporal - -:::info -Using Temporal is only required for stacks using the flows service. It can be ommitted now if you don't plan on using it yet, and added at a later time. -::: - -The recommended way to spin up a Temporal deployment is through Temporal Cloud, or by using the official Temporal helm [chart](https://github.com/temporalio/helm-charts). - - -## Create the Temporal settings - -In this example, you'll set up a configuration for the Orchestration of the `formance-dev` stack. This configuration will apply to all the modules of this stack. - -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-temporal-dsn -spec: - key: temporal.dsn - stacks: - - 'formance-dev' - value: temporal://dev-eu-west-1.fsdfsdf.tmprl.cloud:7233/dev-eu-west-1.fsdfsdf? ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-temporal-tls-crt -spec: - key: temporal.tls.crt - stacks: - - 'formance-dev' - value: | - -----BEGIN CERTIFICATE----- - CERTIFICATE_CONTENT - -----END CERTIFICATE----- - ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-temporal-tls-key -spec: - key: temporal.tls.key - stacks: - - 'formance-dev' - value: | - -----BEGIN PRIVATE KEY----- - PRIVATE_KEY_CONTENT - -----END PRIVATE KEY----- -``` diff --git a/components/operator/docs/06-Observability/01-Configure OpenTelemetry.md b/components/operator/docs/06-Observability/01-Configure OpenTelemetry.md deleted file mode 100644 index 16cc030c69..0000000000 --- a/components/operator/docs/06-Observability/01-Configure OpenTelemetry.md +++ /dev/null @@ -1,27 +0,0 @@ -# Configure OpenTelemetry - -## Overview - -Formance uses OpenTelemetry to collect and send telemetry data to your monitoring system. [OpenTelemetry](https://opentelemetry.io/) is an open-source observability framework for cloud-native software. It provides a single set of APIs, libraries, agents, and instrumentation to capture distributed traces and metrics from your applications. - -## Configuration - -### Prerequisites - -This guide assumes that you already have an OpenTelemetry server running and that you have the necessary credentials to connect to it. - -### Configuration - -In this example, you'll set up an OpenTelemetry configuration for the `formance-dev` stack. This configuration will apply to all the modules of this stack. - -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: stacks-otel-collector -spec: - key: opentelemetry.*.dsn - stacks: - - "formance-dev" - value: grpc://opentelemetry-collector.formance-system.svc:4317?insecure=true -``` diff --git a/components/operator/docs/07-Upgrade/01-Upgrade from the operator.md b/components/operator/docs/07-Upgrade/01-Upgrade from the operator.md deleted file mode 100644 index 3abb855679..0000000000 --- a/components/operator/docs/07-Upgrade/01-Upgrade from the operator.md +++ /dev/null @@ -1,61 +0,0 @@ -It is good practice to keep the operator up to date with the latest [releases](https://github.com/formancehq/stack/releases) to anticipate for any future component upgrades. As there is no immediate impact on the deployed stacks when upgrading the operator, it is advised to simply ensure the operator is running the latest version most of the time. - -You can download the latest version of Formance directly from [our github repo](https://github.com/formancehq/stack/releases). -```bash -helm upgrade regions oci://ghcr.io/formancehq/helm/regions \ ---version LATEST_RELEASE \ ---namespace formance-system -``` - -Once the upgrade is complete, you can verify the operator is running the latest version with the usual `kubectl` commands: - -```bash -kubectl -n formance-system describe deployments operator -``` - -## Components upgrade -The upgrade process is managed by the operator, who will upgrade the components one by one, as specified in the `versions` CRD. Any migration that needs to be carried out will also be managed by the operator. - -When the Operator is upgraded to the latest version, the patch versions will be automatically applied to all the stacks managed by the Operator. - -If you wish to change the Minor or Major version, you need to modify your Stack object and specify the new version. The version is represented by the `versionFromFile` object. - -```bash -kubectl edit stack stack1 -``` - -:::warning -Do not update the versions CRD unless you are ready to upgrade your deployment. -::: - -Once updated, the operator will start the upgrade process. You can follow the process in the `status` section of the `stack` CRD. The status will be updated in real time, and will indicate the health status of the various services, such as whether they are `healthy` or not. - -For each component, a [rolling upgrade](https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/) will be performed, meaning that the component will be upgraded one by one, and the service will be kept running during the upgrade process. - -:::info -Note that the rollout process is managed by Kubernetes, and as such, the operator has no control over it. As a result, the upgrade process may be interrupted by Kubernetes, and a service may be unavailable for a short period of time. -::: - - - -## Updating from Operator v1 to Operator v2 - -If you wish to update the operator from version 1 to version 2, we have managed the major steps of the migration for you. -Thus, the Configuration CRD from v1 will be migrated to the Settings CRD of v2, and the same will happen for the Versions CRD. - -All the Stack CRDs will also be split and migrated to the different Module CRDs of v2. - -However, it is important to note that the Stack CRDs from v1 will not be deleted, and the Operator will replicate each change to the v2 objects. -Therefore, after the migration, you will have both v1 and v2 objects in your cluster. We recommend deleting the v1 objects once you are sure that the migration went smoothly. - -To migrate the operator from version 1 to version 2, you simply need to update the operator with the following command: - -```bash -helm upgrade regions oci://ghcr.io/formancehq/helm/regions \ ---version LATEST_RELEASE \ ---namespace formance-system -``` - -As soon as Operator v2 starts, it will begin migrating v1 objects to v2 objects, then create the new associated resources. All steps have been designed to be carried out without any service interruption. However, we recommend performing this update in Staging before doing it in Production. - -If you encounter any issues, do not hesitate to contact us. We will be happy to help you with the migration process. \ No newline at end of file diff --git a/components/operator/docs/07-Upgrade/02-Database update.md b/components/operator/docs/07-Upgrade/02-Database update.md deleted file mode 100644 index 92f238f5c4..0000000000 --- a/components/operator/docs/07-Upgrade/02-Database update.md +++ /dev/null @@ -1,23 +0,0 @@ -# Database update - -This page describes how the operator updates the database schema when deploying a new version of a module. - -## Database updates management - -The database migrations are handled automatically by the Formance Kubernetes Operator. This applies for all the services that are deployed by the operator. - -:::info -The services come with the guarantee that the database schema will be updated in a backward-compatible way. This means that the database schema will be updated in a way that the old version of the service will still be able to work with the new schema. -::: - -## Database update process - -The process starts when the operator detects that a new version of a module is set to be deployed. - -First, the operator starts a Kubernetes Job that runs the database migration. The job is responsible for updating the database schema to the new version. Most of the time, the database migration is done using the `migrate` command embeded in the service. - -If the database migration fails, the operator will stop the deployment of the new version of the module and will keep the old version running. The database migration is applied as a transaction, so if it fails, the database is not updated and the old version of the module is still able to work with the old schema. - -When the database migration is complete, the operator will start the deployment of the new version of the module. It ensures that the new version is running properly before sending traffic to it. - -Once the new version is running, the operator will eventually stop the old version of the module and clean up the resources that are not needed anymore. diff --git a/components/operator/docs/08-Troubleshooting.md b/components/operator/docs/08-Troubleshooting.md deleted file mode 100644 index f4204f5076..0000000000 --- a/components/operator/docs/08-Troubleshooting.md +++ /dev/null @@ -1,11 +0,0 @@ -# Troubleshooting - -There are two places where you can encounter issues with your deployment. - -## Option 1: Operator failures - -If the operator itself encounters an error, it is very likely that there is either a bug in the operator or an issue with your Kubernetes. In this case, you should contact the Formance support team. - -## Option 2: Stack failures - -If the operator is running fine, but the stack is failing, you can troubleshoot the stack by activating the open telemetry publication as described in the [observability section](06-Observability/01-Configure%20OpenTelemetry.md). diff --git a/components/operator/docs/09-Configuration reference/01-Settings.md b/components/operator/docs/09-Configuration reference/01-Settings.md deleted file mode 100644 index c93b8d5609..0000000000 --- a/components/operator/docs/09-Configuration reference/01-Settings.md +++ /dev/null @@ -1,218 +0,0 @@ -The Settings CRD is one of the most important CRDs in Operator v2. It enables all the necessary adjustments so that the Operator can adapt to your usage and environment. - -Settings are encoded as string, but under the hood, each setting can be unmarshalled to a specific type. - -While we have some basic types (string, number, bool ...), we also have some complex structures: -* Maps: maps are just one level dictionary with values as string. Repeat `=` pattern for each entry, while separating with comma. -* URIs: URIs are used each time we need to address an external resource (postgres, kafka ...). URIs are convenient to encode a lot of information in a simple, normalized format. - -## Available settings - -| Key | Type | Example | Description | -|------------------------------------------------------------------------------------------|--------|--------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------| -| aws.service-account | string | | AWS Role | -| postgres.``.uri | URI | | Postgres database configuration | -| elasticsearch.dsn | URI | | Elasticsearch connection URI | -| temporal.dsn | URI | | Temporal URI | -| temporal.tls.crt | string | | Temporal certificate | -| temporal.tls.key | string | | Temporal certificate key | -| broker.dsn | URI | | Broker URI | -| opentelemetry.traces.dsn | URI | | OpenTelemetry collector URI | -| opentelemetry.traces.resource-attributes | Map | key1=value1,key2=value2 | Opentelemetry additional resource attributes | -| clear-database | bool | true | Whether to remove databases on stack deletion | -| ledger.deployment-strategy | string | single | Ledger deployment type | -| ledger.logs.max-batch-size | Int | 1024 | Ledger logs batching max size | -| payments.encryption-key | string | | Payments data encryption key | -| deployments.``.init-containers.``.resource-requirements | Map | cpu=X, mem=X | | -| deployments.``.containers.``.resource-requirements | Map | cpu=X, mem=X | | -| deployments.``.init-containers.``.run-as | Map | user=X, group=X | | -| deployments.``.containers.``.run-as | Map | user=X, group=X | | -| deployments.``.replicas | string | 2 | | -| caddy.image | string | | Caddy image | -| registries.``.endpoint | string | | Specify a custom endpoint for a specific docker repository | -| registries.``.images.``.rewrite | string | formancehq/example | Allow to rewrite the image path | -| search.batching | Map | period=1s, count=10 | Override default batching parameters | -| services.``.annotations | Map | | Allow to specify custom annotations to apply on created k8s services | -| gateway.ingress.annotations | Map | | Allow to specify custom annotations to apply on the gateway ingress | -| logging.json | bool | | Configure services to log as json | -| modules.``.database.connection-pool | Map | max-idle=10, max-idle-time=10, max-open=10 | Configure database connection pool for each module. See [Golang documentation](https://go.dev/doc/database/manage-connections) | -| orchestration.max-parallel-activities | Int | 10 | Configure max parallel temporal activities on orchestration workers | - - -### Postgres URI format - -Scheme: postgresql - -Query params : - -| Name | Type | Default | Description | -|----------------|--------|---------|------------------------------------------------------| -| secret | string | | Specify a secret where credentials are defined | -| disableSSLMode | bool | false | Disable SSL on Postgres connection | - -### ElasticSearch URI format - -Scheme: elasticsearch - -Query params : - -| Name | Type | Default | Description | -|--------|--------|---------|------------------------------------------------| -| secret | string | | Specify a secret where credentials are defined | - -### Temporal URI format - -Scheme : temporal - -Path : Match the temporal namespace - -Query params : - -| Name | Type | Default | Description | -|--------|--------|---------|----------------------------------------------------------| -| secret | string | | Specify a secret where temporal certificates are defined | - -### Broker URI format - -Scheme : nats | kafka - -#### Broker URI format (nats) - -Scheme: nats - -Query params : - -| Name | Type | Default | Description | -|----------|--------|---------|---------------------------------------------------------------------------| -| replicas | number | 1 | Specify the number of replicas to configure on newly created nats streams | - -#### Broker URI format (kafka) - -Scheme: kafka - -Query params : - -| Name | Type | Default | Description | -|------------------|--------|---------|------------------------------------------------| -| saslEnabled | bool | false | Specify is sasl authentication must be enabled | -| saslUsername | string | | Username on sasl authentication | -| saslPassword | string | | Password on sasl authentication | -| saslMechanism | string | | Mechanism on sasl authentication | -| saslSCRAMSHASize | string | | SCRAM SHA size on sasl authentication | -| tls | bool | false | Whether enable ssl or not | - - - -The process is always the same: you create a YAML file, submit it to Kubernetes, and the Operator takes care of the rest. -All the values present in the `Metadata` section are not used by the Operator. Conversely, the `Spec` section is used to define the Operator's parameters. -You will always find 3 parameters there: -- **stacks**: defines the stacks that should use this configuration (you can put a `*` to indicate that all stacks should use this configuration) -- **key**: defines the key of the configuration (you can put a `*` so that it applies to all services) -- **value**: defines the value of the configuration - -## Examples -### Define PostgreSQL clusters -In this example, you will set up a configuration for a PostgreSQL cluster that will be used only by the `formance-dev` stack but will apply to all the modules of this stack. -Thus, the different modules of the Stack will use this PostgreSQL cluster while being isolated in their own database. - -:::info -This database is created following the format: `{stackName}-{module}` -::: - -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-postgres-uri -spec: - key: postgres.*.uri - stacks: - - 'formance-dev' - value: postgresql://formance:formance@postgresql.formance-system.svc:5432?disableSSLMode=true -``` - -### Use AWS IAM Role -In this example, you'll use an AWS IAM role to connect to the database. The `formance-dev` stack will use this configuration. - -```yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: aws-rds-access-role - namespace: formance-system - labels: - formance.com/stack: any - annotations: - eks.amazonaws.com/role-arn: arn:aws:iam::AWS_ACCOUNT_ID:role/AWS_ROLE_NAME ---- -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-postgres-uri -spec: - key: postgres.*.uri - stacks: - - 'formance-dev' - value: postgresql://formance@postgresql.formance-system.svc:5432 - ``` - -### Define module resource requests -In this example, you'll set up a configuration for the resource requests of the `formance-dev` stack. This configuration will apply to all the modules of this stack. - -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-resource-requests -spec: - key: deployments.*.containers.*.resource-requirements.requests - stacks: - - 'formance-dev' - value: cpu=10m,memory=100Mi -``` - -### Define a Broker -In this example, you'll set up a configuration for the Broker of the `formance-dev` stack. This configuration will apply to all the modules of this stack. - -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: formance-dev-broker -spec: - key: broker.dsn - stacks: - - 'formance-dev' - value: nats://nats.formance-system.svc:4222?replicas=3 -``` - -### Define a OpenTelemetry Collector - -In this example, you'll set up a configuration to send traces and metrics to an OpenTelemetry collector. This configuration will apply to all modules in this stack. - -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - name: stacks-otel-collector -spec: - key: opentelemetry.*.dsn - stacks: - - "formance-dev" - value: grpc://opentelemetry-collector.formance-system.svc:4317?insecure=true -``` - - - - - - - - - - - - - - - \ No newline at end of file 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 deleted file mode 100644 index 77e3507616..0000000000 --- a/components/operator/docs/09-Configuration reference/02-Custom Resource Definitions.md +++ /dev/null @@ -1,2558 +0,0 @@ -# API Reference - -## Packages -- [formance.com/v1beta1](#formancecomv1beta1) - - -## formance.com/v1beta1 - -Package v1beta1 contains API Schema definitions for the formance v1beta1 API group. - -It allow to configure a Formance stack. - -A stack is composed of a [Stack](#stack) resource and some [modules](#modules). - -Each module can create multiple resources following its needs. See [Other resources](#other-resources). - -Various parts of the stack can be configured either using the CRD properties or using some [Settings](#settings). - - -Modules : -- [Analytics](#analytics) -- [Auth](#auth) -- [Gateway](#gateway) -- [Ledger](#ledger) -- [Orchestration](#orchestration) -- [Payments](#payments) -- [Reconciliation](#reconciliation) -- [Search](#search) -- [Stargate](#stargate) -- [Wallets](#wallets) -- [Webhooks](#webhooks) - -Other resources : -- [AuthClient](#authclient) -- [Benthos](#benthos) -- [BenthosStream](#benthosstream) -- [Broker](#broker) -- [BrokerConsumer](#brokerconsumer) -- [BrokerTopic](#brokertopic) -- [Database](#database) -- [GatewayHTTPAPI](#gatewayhttpapi) -- [ResourceReference](#resourcereference) -- [Versions](#versions) - -### Main resources - -#### Stack - - - -Stack represents a formance stack. -A Stack is basically a container. It holds some global properties and -creates a namespace if not already existing. - - -To do more, you need to create some [modules](#modules). - - -The Stack resource allow to specify the version of the stack. - - -It can be specified using either the field `.spec.version` or the `.spec.versionsFromFile` field (Refer to the documentation of [Versions](#versions) resource. - - -The `version` field will have priority over `versionFromFile`. - - -If `versions` and `versionsFromFile` are not specified, "latest" will be used. - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Stack` | | | -| `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` _[StackSpec](#stackspec)_ | | | | -| `status` _[StackStatus](#stackstatus)_ | | | | - - - -##### StackSpec - - - - - - - - - - - - - - - - - - - -| 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 specify the version of the components
Must be a valid docker tag | | | -| `versionsFromFile` _string_ | VersionsFromFile allow to specify a formance.com/Versions object which contains individual versions
for each component.
Must reference a valid formance.com/Versions object | | | -| `enableAudit` _boolean_ | EnableAudit enable audit at the stack level.
Actually, it enables audit on [Gateway](#gateway) | false | | -| `disabled` _boolean_ | Disabled indicate the stack is disabled.
A disabled stack disable everything
It just keeps the namespace and the [Database](#database) resources. | false | | - - - - - -##### StackStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `modules` _string array_ | Modules register detected modules | | | - - -#### Settings - - - -Settings represents a configurable piece of the stacks. - - -The purpose of this resource is to be able to configure some common settings between a set of stacks. - - -Example : -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - - - name: postgres-uri - - -spec: - - - key: postgres.ledger.uri - stacks: - - stack0 - value: postgresql://postgresql.formance.svc.cluster.local:5432 - - -``` - - -This example create a setting named `postgres-uri` targeting the stack named `stack0` and the service `ledger` (see the key `postgres.ledger.uri`). - - -Therefore, a [Database](#database) created for the stack `stack0` and the service named 'ledger' will use the uri `postgresql://postgresql.formance.svc.cluster.local:5432`. - - -Settings allow to use wildcards in keys and in stacks list. - - -For example, if you want to use the same database server for all the modules of a specific stack, you can write : -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - - - name: postgres-uri - - -spec: - - - key: postgres.*.uri # There, we use a wildcard to indicate we want to use that setting of all services of the stack `stack0` - stacks: - - stack0 - value: postgresql://postgresql.formance.svc.cluster.local:5432 - - -``` - - -Also, we could use that setting for all of our stacks using : -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - - - name: postgres-uri - - -spec: - - - key: postgres.*.uri # There, we use a wildcard to indicate we want to use that setting for all services of all stacks - stacks: - - * # There we select all the stacks - value: postgresql://postgresql.formance.svc.cluster.local:5432 - - -``` - - -Some settings are really global, while some are used by specific module. - - -Refer to the documentation of each module and resource to discover available Settings. - - -##### Global settings -###### AWS account - - -A stack can use an AWS account for authentication. - - -It can be used to connect to any AWS service we could use. - - -It includes RDS, OpenSearch and MSK. To do so, you can create the following setting: -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - - - name: aws-service-account - - -spec: - - - key: aws.service-account - stacks: - - '*' - value: aws-access - - -``` -This setting instruct the operator than there is somewhere on the cluster a service account named `aws-access`. - - -So, each time a service has the capability to use AWS, the operator will use this service account. - - -The service account could look like that : -```yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - - - annotations: - eks.amazonaws.com/role-arn: arn:aws:iam::************:role/staging-eu-west-1-hosting-stack-access - labels: - formance.com/stack: any - name: aws-access - - -``` -You can note two things : - 1. We have an annotation indicating the role arn used to connect to AWS. Refer to the AWS documentation to create this role - 2. We have a label `formance.com/stack=any` indicating we are targeting all stacks. - Refer to the documentation of [ResourceReference](#resourcereference) for further information. - - -###### JSON logging - - -You can use the setting `logging.json` with the value `true` to configure elligible service to log as json. -Example: -```yaml -apiVersion: formance.com/v1beta1 -kind: Settings -metadata: - - - name: json-logging - - -spec: - - - key: logging.json - stacks: - - '*' - value: "true" - - -``` - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Settings` | | | -| `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` _[SettingsSpec](#settingsspec)_ | | | | - - - -##### SettingsSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stacks` _string array_ | Stacks on which the setting is applied. Can contain `*` to indicate a wildcard. | | | -| `key` _string_ | The setting Key. See the documentation of each module or [global settings](#global-settings) to discover them. | | | -| `value` _string_ | The value. It must have a specific format following the Key. | | | - - - - -### 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 - - - -Auth represent the authentication module of a stack. - - -It is an OIDC compliant server. - - -Creating it for a stack automatically add authentication on all supported modules. - - -The auth service is basically a proxy to another OIDC compliant server. - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Auth` | | | -| `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` _[AuthSpec](#authspec)_ | | | | -| `status` _[AuthStatus](#authstatus)_ | | | | - - - -##### AuthSpec - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `delegatedOIDCServer` _[DelegatedOIDCServerConfiguration](#delegatedoidcserverconfiguration)_ | Contains information about a delegated authentication server to use to delegate authentication | | | -| `signingKey` _string_ | Allow to override the default signing key used to sign JWT tokens. | | | -| `signingKeyFromSecret` _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#secretkeyselector-v1-core)_ | Allow to override the default signing key used to sign JWT tokens using a k8s secret | | | -| `enableScopes` _boolean_ | Allow to enable scopes usage on authentication.

If not enabled, each service will check the authentication but will not restrict access following scopes.
in this case, if authenticated, it is ok. | false | | - -###### DelegatedOIDCServerConfiguration - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `issuer` _string_ | Issuer is the url of the delegated oidc server | | | -| `clientID` _string_ | ClientID is the client id to use for authentication | | | -| `clientSecret` _string_ | ClientSecret is the client secret to use for authentication | | | - - - - - -##### AuthStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `clients` _string array_ | Clients contains the list of clients created using [AuthClient](#authclient) | | | - - -#### Gateway - - - -Gateway is the Schema for the gateways API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Gateway` | | | -| `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` _[GatewaySpec](#gatewayspec)_ | | | | -| `status` _[GatewayStatus](#gatewaystatus)_ | | | | - - - -##### GatewaySpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `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 | | | -| `ingress` _[GatewayIngress](#gatewayingress)_ | Allow to customize the generated ingress | | | - -###### GatewayIngress - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `host` _string_ | Indicates the hostname on which the stack will be served.
Example : `formance.example.com` | | | -| `scheme` _string_ | Indicate the scheme.

Actually, It should be `https` unless you know what you are doing. | https | | -| `ingressClassName` _string_ | Ingress class to use | | | -| `annotations` _object (keys:string, values:string)_ | Custom annotations to add on the ingress | | | -| `tls` _[GatewayIngressTLS](#gatewayingresstls)_ | Allow to customize the tls part of the ingress | | | - -###### GatewayIngressTLS - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `secretName` _string_ | Specify the secret name used for the tls configuration on the ingress | | | - - - - - -##### GatewayStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `syncHTTPAPIs` _string array_ | Detected http apis. See [GatewayHTTPAPI](#gatewayhttpapi) | | | - - -#### Ledger - - - -Ledger is the module allowing to install a ledger instance. - - -The ledger is actually a stateful application on the writer part. -So we cannot scale the ledger as we want without prior configuration. - - -So, the ledger can run in two modes : -* single instance: Only one instance will be deployed. We cannot scale in that mode. -* single writer / multiple reader: In this mode, we will have a single writer and multiple readers if needed. - - -Use setting `ledger.deployment-strategy` with either the value : - - single : For the single instance mode. - - single-writer: For the single writer / multiple reader mode. - Under the hood, the operator create two deployments and force the scaling of the writer to stay at 1. - Then you can scale the deployment of the reader to the value you want. - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Ledger` | | | -| `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` _[LedgerSpec](#ledgerspec)_ | | | | -| `status` _[LedgerStatus](#ledgerstatus)_ | | | | - - - -##### LedgerSpec - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `deploymentStrategy` _[DeploymentStrategy](#deploymentstrategy)_ | Deprecated. | single | | -| `locking` _[LockingStrategy](#lockingstrategy)_ | Locking is intended for ledger v1 only | | | - -###### DeploymentStrategy - -_Underlying type:_ _string_ - - - - - - - - - - - - - - - - - - -###### LockingStrategy - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `strategy` _string_ | | memory | | -| `redis` _[LockingStrategyRedisConfig](#lockingstrategyredisconfig)_ | | | | - -###### LockingStrategyRedisConfig - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `uri` _string_ | | | | -| `tls` _boolean_ | | false | | -| `insecure` _boolean_ | | false | | -| `duration` _string_ | | | | -| `retry` _string_ | | | | - - - - - -##### LedgerStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | - - -#### Orchestration - - - -Orchestration is the Schema for the orchestrations API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Orchestration` | | | -| `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` _[OrchestrationSpec](#orchestrationspec)_ | | | | -| `status` _[OrchestrationStatus](#orchestrationstatus)_ | | | | - - - -##### OrchestrationSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `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 | | | - - - - - -##### OrchestrationStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `temporalURI` _string_ | | | Type: string
| - - -#### Payments - - - -Payments is the Schema for the payments API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Payments` | | | -| `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` _[PaymentsSpec](#paymentsspec)_ | | | | -| `status` _[PaymentsStatus](#paymentsstatus)_ | | | | - - - -##### PaymentsSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `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 | | | -| `encryptionKey` _string_ | | | | - - - - - -##### PaymentsStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | - - -#### Reconciliation - - - -Reconciliation is the Schema for the reconciliations API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Reconciliation` | | | -| `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` _[ReconciliationSpec](#reconciliationspec)_ | | | | -| `status` _[ReconciliationStatus](#reconciliationstatus)_ | | | | - - - -##### ReconciliationSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `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 | | | - - - - - -##### ReconciliationStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | - - -#### Search - - - -Search is the Schema for the searches API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Search` | | | -| `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` _[SearchSpec](#searchspec)_ | | | | -| `status` _[SearchStatus](#searchstatus)_ | | | | - - - -##### SearchSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `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 | | | -| `batching` _[Batching](#batching)_ | | | | - -###### Batching - - - -Batching allow to define custom batching configuration - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `count` _integer_ | Count indicates the number of messages that can be kept in memory before being flushed to ElasticSearch | | | -| `period` _string_ | Period indicates the maximum duration messages can be kept in memory before being flushed to ElasticSearch | | | - - - - - -##### SearchStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `elasticSearchURI` _string_ | | | Type: string
| -| `topicCleaned` _boolean_ | TopicCleaned is used to flag stacks where the topics have been cleaned (still search-ledgerv2 and co consumers) | false | | - - -#### Stargate - - - -Stargate is the Schema for the stargates API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Stargate` | | | -| `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` _[StargateSpec](#stargatespec)_ | | | | -| `status` _[StargateStatus](#stargatestatus)_ | | | | - - - -##### StargateSpec - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `serverURL` _string_ | | | | -| `organizationID` _string_ | | | | -| `stackID` _string_ | | | | -| `auth` _[StargateAuthSpec](#stargateauthspec)_ | | | | - -###### StargateAuthSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `clientID` _string_ | | | | -| `clientSecret` _string_ | | | | -| `issuer` _string_ | | | | - - - - - -##### StargateStatus - - - -StargateStatus defines the observed state of Stargate - - - - - - - - - - - - - - - -| 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 | | | - - -#### Wallets - - - -Wallets is the Schema for the wallets API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Wallets` | | | -| `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` _[WalletsSpec](#walletsspec)_ | | | | -| `status` _[WalletsStatus](#walletsstatus)_ | | | | - - - -##### WalletsSpec - - - - - - - - - - - - - - - - - - - -| 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 | | | - - - - - -##### WalletsStatus - - - -WalletsStatus defines the observed state of Wallets - - - - - - - - - - - - - - - -| 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 | | | - - -#### Webhooks - - - -Webhooks is the Schema for the webhooks API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Webhooks` | | | -| `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` _[WebhooksSpec](#webhooksspec)_ | | | | -| `status` _[WebhooksStatus](#webhooksstatus)_ | | | | - - - -##### WebhooksSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `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 | | | - - - - - -##### WebhooksStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | - - -### Other resources - -#### AuthClient - - - -AuthClient allow to create OAuth2/OIDC clients on the auth server (see [Auth](#auth)) - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `AuthClient` | | | -| `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` _[AuthClientSpec](#authclientspec)_ | | | | -| `status` _[AuthClientStatus](#authclientstatus)_ | | | | - - - -##### AuthClientSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `id` _string_ | ID indicates the client id
It must be used with oauth2 `client_id` parameter | | | -| `public` _boolean_ | Public indicate whether a client is confidential or not.
Confidential clients are clients which the secret can be kept secret...
As opposed to public clients which cannot have a secret (application single page for example) | false | | -| `description` _string_ | Description represents an optional description of the client | | | -| `redirectUris` _string array_ | RedirectUris allow to list allowed redirect uris for the client | | | -| `postLogoutRedirectUris` _string array_ | RedirectUris allow to list allowed post logout redirect uris for the client | | | -| `scopes` _string array_ | Scopes allow to five some scope to the client | | | -| `secret` _string_ | Secret allow to configure a secret for the client.
It is not required as some client could use some oauth2 flows which does not requires a client secret | | | - - - - - -##### AuthClientStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | - - -#### Benthos - - - -Benthos is the Schema for the benthos API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Benthos` | | | -| `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` _[BenthosSpec](#benthosspec)_ | | | | -| `status` _[BenthosStatus](#benthosstatus)_ | | | | - - - -##### BenthosSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `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 | | -| `resourceRequirements` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#resourcerequirements-v1-core)_ | | | | -| `batching` _[Batching](#batching)_ | | | | -| `initContainers` _[Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#container-v1-core) array_ | | | | - -###### Batching - - - -Batching allow to define custom batching configuration - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `count` _integer_ | Count indicates the number of messages that can be kept in memory before being flushed to ElasticSearch | | | -| `period` _string_ | Period indicates the maximum duration messages can be kept in memory before being flushed to ElasticSearch | | | - - - - - -##### BenthosStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `elasticSearchURI` _string_ | | | Type: string
| - - -#### BenthosStream - - - -BenthosStream is the Schema for the benthosstreams API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `BenthosStream` | | | -| `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` _[BenthosStreamSpec](#benthosstreamspec)_ | | | | -| `status` _[BenthosStreamStatus](#benthosstreamstatus)_ | | | | - - - -##### BenthosStreamSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `data` _string_ | | | | -| `name` _string_ | | | | - - - - - -##### BenthosStreamStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | - - -#### Broker - - - -Broker is the Schema for the brokers API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Broker` | | | -| `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` _[BrokerSpec](#brokerspec)_ | | | | -| `status` _[BrokerStatus](#brokerstatus)_ | | | | - - - -##### BrokerSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | - - - - - -##### BrokerStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `uri` _string_ | | | Type: string
| -| `mode` _[Mode](#mode)_ | Mode indicating the configuration of the nats streams
Two modes are defined :
* OneStreamByService: In this case, each service will have a dedicated stream created
* OneStreamByStack: In this case, a stream will be created for the stack and each service will use a specific subject inside this stream | | Enum: [OneStreamByService OneStreamByStack]
| -| `streams` _string array_ | Streams list streams created when Mode == ModeOneStreamByService | | | - -###### Mode - -_Underlying type:_ _string_ - -Mode defined how streams are created on the broker (mainly nats) - - - - - - - - - - - - - - - - - -#### BrokerConsumer - - - -BrokerConsumer is the Schema for the brokerconsumers API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `BrokerConsumer` | | | -| `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` _[BrokerConsumerSpec](#brokerconsumerspec)_ | | | | -| `status` _[BrokerConsumerStatus](#brokerconsumerstatus)_ | | | | - - - -##### BrokerConsumerSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `services` _string array_ | | | | -| `queriedBy` _string_ | | | | -| `name` _string_ | As the name is optional, if not provided, the name will be the QueriedBy property
This is only applied when using one stream by stack see Mode | | | - - - - - -##### BrokerConsumerStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | - - -#### BrokerTopic - - - -BrokerTopic is the Schema for the brokertopics API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `BrokerTopic` | | | -| `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` _[BrokerTopicSpec](#brokertopicspec)_ | | | | -| `status` _[BrokerTopicStatus](#brokertopicstatus)_ | | | | - - - -##### BrokerTopicSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `service` _string_ | | | | - - - - - -##### BrokerTopicStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | - - -#### Database - - - -Database represent a concrete database on a PostgreSQL server, it is created by modules requiring a database ([Ledger](#ledger) for example). - - -It uses the settings `postgres..uri` which must have the following uri format: `postgresql://[@]@/` -Additionally, the uri can define a query param `secret` indicating a k8s secret, than must be used to retrieve database credentials. - - -On creation, the reconciler behind the Database object will create the database on the postgresql server using a k8s job. -On Deletion, by default, the reconciler will let the database untouched. -You can allow the reconciler to drop the database on the server by using the [Settings](#settings) `clear-database` with the value `true`. -If you use that setting, the reconciler will use another job to drop the database. -Be careful, no backup are performed! - - -Database resource honors `aws.service-account` setting, so, you can create databases on an AWS server if you need. -See [AWS accounts](#aws-account) - - -Once a database is fully configured, it retains the postgres uri used. -If the setting indicating the server uri changed, the Database object will set the field `.status.outOfSync` to true -and will not change anything. - - -Therefore, to switch to a new server, you must change the setting value, then drop the Database object. -It will be recreated with correct uri. - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Database` | | | -| `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` _[DatabaseSpec](#databasespec)_ | | | | -| `status` _[DatabaseStatus](#databasestatus)_ | | | | - - - -##### DatabaseSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `service` _string_ | Service is a discriminator for the created database.
Actually, it will be the module name (ledger, payments...).
Therefore, the created database will be named `` | | | -| `debug` _boolean_ | | false | | - - - - - -##### DatabaseStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `uri` _string_ | | | Type: string
| -| `database` _string_ | The generated database name | | | -| `outOfSync` _boolean_ | OutOfSync indicates than a settings changed the uri of the postgres server
The Database object need to be removed to be recreated | | | - - -#### GatewayHTTPAPI - - - -GatewayHTTPAPI is the Schema for the HTTPAPIs API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `GatewayHTTPAPI` | | | -| `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` _[GatewayHTTPAPISpec](#gatewayhttpapispec)_ | | | | -| `status` _[GatewayHTTPAPIStatus](#gatewayhttpapistatus)_ | | | | - - - -##### GatewayHTTPAPISpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `name` _string_ | Name indicates prefix api | | | -| `rules` _[GatewayHTTPAPIRule](#gatewayhttpapirule) array_ | Rules | | | -| `healthCheckEndpoint` _string_ | Health check endpoint | | | - -###### GatewayHTTPAPIRule - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `path` _string_ | | | | -| `methods` _string array_ | | | | -| `secured` _boolean_ | | false | | - - - - - -##### GatewayHTTPAPIStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `ready` _boolean_ | | | | - - -#### ResourceReference - - - -ResourceReference is a special resources used to refer to externally created resources. - - -It includes k8s service accounts and secrets. - - -Why? Because the operator create a namespace by stack, so, a stack does not have access to secrets and service -accounts created externally. - - -A ResourceReference is created by other resource who need to use a specific secret or service account. -For example, if you want to use a secret for your database connection (see [Database](#database), you will -create a setting indicating a secret name. You will need to create this secret yourself, and you will put this -secret inside the namespace you want (`default` maybe). - - -The Database reconciler will create a ResourceReference looking like that : -``` -apiVersion: formance.com/v1beta1 -kind: ResourceReference -metadata: - - - name: jqkuffjxcezj-qlii-auth-postgres - ownerReferences: - - apiVersion: formance.com/v1beta1 - blockOwnerDeletion: true - controller: true - kind: Database - name: jqkuffjxcezj-qlii-auth - uid: 2cc4b788-3ffb-4e3d-8a30-07ed3941c8d2 - - -spec: - - - gvk: - group: "" - kind: Secret - version: v1 - name: postgres - stack: jqkuffjxcezj-qlii - - -status: - - - ... - - -``` -This reconciler behind this ResourceReference will search, in all namespaces, for a secret named "postgres". -The secret must have a label `formance.com/stack` with the value matching either a specific stack or `any` to target any stack. - - -Once the reconciler has found the secret, it will copy it inside the stack namespace, allowing the ResourceReconciler owner to use it. - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `ResourceReference` | | | -| `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` _[ResourceReferenceSpec](#resourcereferencespec)_ | | | | -| `status` _[ResourceReferenceStatus](#resourcereferencestatus)_ | | | | - - - -##### ResourceReferenceSpec - - - - - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `stack` _string_ | Stack indicates the stack on which the module is installed | | | -| `gvk` _[GroupVersionKind](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#groupversionkind-v1-meta)_ | | | | -| `name` _string_ | | | | - - - - - -##### ResourceReferenceStatus - - - - - - - - - - - - - - - - - - - -| 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 | | | -| `syncedResource` _string_ | | | | -| `hash` _string_ | | | | - - -#### Versions - - - -Versions is the Schema for the versions API - - - - - - - - - - - - - - - -| Field | Description | Default | Validation | -| --- | --- | --- | --- | -| `apiVersion` _string_ | `formance.com/v1beta1` | | | -| `kind` _string_ | `Versions` | | | -| `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` _object (keys:string, values:string)_ | | | | - - - - - diff --git a/components/operator/go.mod b/components/operator/go.mod deleted file mode 100644 index 102768c807..0000000000 --- a/components/operator/go.mod +++ /dev/null @@ -1,85 +0,0 @@ -module github.com/formancehq/operator - -go 1.22.0 - -toolchain go1.22.7 - -require ( - github.com/formancehq/go-libs v1.7.1 - github.com/formancehq/search v0.0.0-00010101000000-000000000000 - github.com/go-logr/logr v1.4.2 - github.com/google/go-cmp v0.6.0 - github.com/google/uuid v1.6.0 - github.com/iancoleman/strcase v0.3.0 - github.com/imdario/mergo v0.3.13 - github.com/onsi/ginkgo/v2 v2.20.2 - github.com/onsi/gomega v1.34.2 - github.com/pkg/errors v0.9.1 - github.com/stoewer/go-strcase v1.2.0 - github.com/stretchr/testify v1.9.0 - golang.org/x/mod v0.21.0 - gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.29.0 - k8s.io/apimachinery v0.29.0 - k8s.io/client-go v0.29.0 - k8s.io/utils v0.0.0-20230726121419-3b25d923346b - sigs.k8s.io/controller-runtime v0.17.1 -) - -require github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - -require ( - github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch/v5 v5.8.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - go.uber.org/mock v0.4.0 - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.25.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/apiextensions-apiserver v0.29.0 // indirect - k8s.io/component-base v0.29.0 // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect -) - -replace github.com/formancehq/search => github.com/formancehq/search v0.0.0-20240925174151-fe1cfd5a69cd diff --git a/components/operator/go.sum b/components/operator/go.sum deleted file mode 100644 index d95bc7e5a4..0000000000 --- a/components/operator/go.sum +++ /dev/null @@ -1,211 +0,0 @@ -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= -github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= -github.com/formancehq/go-libs v1.7.1 h1:9D5cxKWFlVtdX5AYDXeUz1Nb9PdoEfQX0f/yeLsU324= -github.com/formancehq/go-libs v1.7.1/go.mod h1:pWTScpoyieF7OoJ6WVmXNG9NhDjbZbAmFqd7UOw85iI= -github.com/formancehq/search v0.0.0-20240925174151-fe1cfd5a69cd h1:zsv//syEUoJWo2VswR9vXvrbDAAoxm8rLXkCxYl114s= -github.com/formancehq/search v0.0.0-20240925174151-fe1cfd5a69cd/go.mod h1:vmUx4wanfOqGBZk0t2bhAXx+r+Pp9WaIA1UQQNc9Zds= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= -github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 h1:c5FlPPgxOn7kJz3VoPLkQYQXGBS3EklQ4Zfi57uOuqQ= -github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= -github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= -github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= -github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= -github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= -gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= -k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= -k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= -k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= -k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= -k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= -k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.17.1 h1:V1dQELMGVk46YVXXQUbTFujU7u4DQj6YUj9Rb6cuzz8= -sigs.k8s.io/controller-runtime v0.17.1/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/components/operator/hack/boilerplate.go.txt b/components/operator/hack/boilerplate.go.txt deleted file mode 100644 index 65b8622718..0000000000 --- a/components/operator/hack/boilerplate.go.txt +++ /dev/null @@ -1,15 +0,0 @@ -/* -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. -*/ \ No newline at end of file diff --git a/components/operator/helm/crds/.helmignore b/components/operator/helm/crds/.helmignore deleted file mode 100644 index 9e8e34ffa6..0000000000 --- a/components/operator/helm/crds/.helmignore +++ /dev/null @@ -1,28 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ - -# ignore kustomization.yaml files -templates/rbac/kustomization.yaml -templates/certmanager/kustomiz*.yaml -templates/webhook/kustomiz*.yaml diff --git a/components/operator/helm/crds/Chart.yaml b/components/operator/helm/crds/Chart.yaml deleted file mode 100644 index 3012c9e747..0000000000 --- a/components/operator/helm/crds/Chart.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: v2 -name: operator-crds -description: Formance Operator CRDS Helm Chart -home: "https://formance.com" -sources: - - "https://github.com/formancehq/stack" -maintainers: - - name: "Formance Team" - email: "support@formance.com" -icon: "https://avatars.githubusercontent.com/u/84325077?s=200&v=4" - -type: application - -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -# Versions are expected to follow Semantic Versioning (https://semver.org/) -version: v2.1.0-beta.1 - -# This is the version number of the application being deployed. This version number should be -# incremented each time you make changes to the application. Versions are not expected to -# follow Semantic Versioning. They should reflect the version the application is using. -# It is recommended to use it with quotes. -appVersion: v2.1.0-beta.1 \ No newline at end of file diff --git a/components/operator/helm/crds/README.md b/components/operator/helm/crds/README.md deleted file mode 100644 index fb189891b8..0000000000 --- a/components/operator/helm/crds/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# operator - -![Version: 0.2.6](https://img.shields.io/badge/Version-0.2.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.16.15](https://img.shields.io/badge/AppVersion-v0.16.15-informational?style=flat-square) - -Formance Operator Helm Chart - -**Homepage:** - -## Maintainers - -| Name | Email | Url | -| ---- | ------ | --- | -| Formance Team | | | - -## Source Code - -* - -## Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| affinity | object | `{}` | | -| fullnameOverride | string | `""` | | -| image.pullPolicy | string | `"IfNotPresent"` | | -| image.repository | string | `"ghcr.io/formancehq/operator"` | | -| image.tag | string | `"v0.16.15"` | | -| imagePullSecrets | list | `[]` | | -| nameOverride | string | `""` | | -| nodeSelector | object | `{}` | | -| operator.disableWebhooks | bool | `false` | | -| operator.enableLeaderElection | bool | `true` | | -| operator.env | string | `"staging"` | | -| operator.metricsAddr | string | `":8080"` | | -| operator.probeAddr | string | `":8081"` | | -| operator.region | string | `"eu-west-1"` | | -| podAnnotations | object | `{}` | | -| podSecurityContext | object | `{}` | | -| replicaCount | int | `1` | | -| resources | object | `{}` | | -| securityContext | object | `{}` | | -| tolerations | list | `[]` | | - ----------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) 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 deleted file mode 100644 index 3d7c842379..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_analytics.formance.com.yaml +++ /dev/null @@ -1,158 +0,0 @@ -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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_authclients.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_authclients.formance.com.yaml deleted file mode 100644 index 9287566a4e..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_authclients.formance.com.yaml +++ /dev/null @@ -1,172 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - helm.sh/resource-policy: keep - name: authclients.formance.com -spec: - group: formance.com - names: - kind: AuthClient - listKind: AuthClientList - plural: authclients - singular: authclient - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack - jsonPath: .spec.stack - name: Stack - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: AuthClient allow to create OAuth2/OIDC clients on the auth server - (see [Auth](#auth)) - 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: - properties: - description: - description: Description represents an optional description of the - client - type: string - id: - description: |- - ID indicates the client id - It must be used with oauth2 `client_id` parameter - type: string - postLogoutRedirectUris: - description: RedirectUris allow to list allowed post logout redirect - uris for the client - items: - type: string - type: array - public: - default: false - description: |- - Public indicate whether a client is confidential or not. - Confidential clients are clients which the secret can be kept secret... - As opposed to public clients which cannot have a secret (application single page for example) - type: boolean - redirectUris: - description: RedirectUris allow to list allowed redirect uris for - the client - items: - type: string - type: array - scopes: - description: Scopes allow to five some scope to the client - items: - type: string - type: array - secret: - description: |- - Secret allow to configure a secret for the client. - It is not required as some client could use some oauth2 flows which does not requires a client secret - type: string - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - id - type: object - status: - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_auths.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_auths.formance.com.yaml deleted file mode 100644 index 53775233c8..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_auths.formance.com.yaml +++ /dev/null @@ -1,222 +0,0 @@ -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/kind: module - name: auths.formance.com -spec: - group: formance.com - names: - kind: Auth - listKind: AuthList - plural: auths - singular: auth - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Synchronized auth clients - jsonPath: .status.clients - name: Clients - type: string - - 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: |- - Auth represent the authentication module of a stack. - - - It is an OIDC compliant server. - - - Creating it for a stack automatically add authentication on all supported modules. - - - The auth service is basically a proxy to another OIDC compliant server. - 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: - properties: - debug: - default: false - description: Allow to enable debug mode on the module - type: boolean - delegatedOIDCServer: - description: Contains information about a delegated authentication - server to use to delegate authentication - properties: - clientID: - description: ClientID is the client id to use for authentication - type: string - clientSecret: - description: ClientSecret is the client secret to use for authentication - type: string - issuer: - description: Issuer is the url of the delegated oidc server - type: string - type: object - 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 - enableScopes: - default: false - description: |- - Allow to enable scopes usage on authentication. - - - If not enabled, each service will check the authentication but will not restrict access following scopes. - in this case, if authenticated, it is ok. - type: boolean - signingKey: - description: Allow to override the default signing key used to sign - JWT tokens. - type: string - signingKeyFromSecret: - description: Allow to override the default signing key used to sign - JWT tokens using a k8s secret - properties: - key: - description: The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - 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: - properties: - clients: - description: Clients contains the list of clients created using [AuthClient](#authclient) - items: - type: string - type: array - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_benthos.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_benthos.formance.com.yaml deleted file mode 100644 index a4a746f850..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_benthos.formance.com.yaml +++ /dev/null @@ -1,1555 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - helm.sh/resource-policy: keep - name: benthos.formance.com -spec: - group: formance.com - names: - kind: Benthos - listKind: BenthosList - plural: benthos - singular: benthos - 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: Benthos is the Schema for the benthos 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: - properties: - batching: - description: Batching allow to define custom batching configuration - properties: - count: - description: Count indicates the number of messages that can be - kept in memory before being flushed to ElasticSearch - type: integer - period: - description: Period indicates the maximum duration messages can - be kept in memory before being flushed to ElasticSearch - type: string - required: - - count - - period - type: object - 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 - initContainers: - items: - description: A single application container that you want to run - within a pod. - properties: - args: - description: |- - Arguments to the entrypoint. - The container image's CMD is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - command: - description: |- - Entrypoint array. Not executed within a shell. - The container image's ENTRYPOINT is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container's environment. If a variable - cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless - of whether the variable exists or not. Cannot be updated. - More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell - items: - type: string - type: array - env: - description: |- - List of environment variables to set in the container. - Cannot be updated. - items: - description: EnvVar represents an environment variable present - in a Container. - properties: - name: - description: Name of the environment variable. Must be - a C_IDENTIFIER. - type: string - value: - description: |- - Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in the container and - any service environment variables. If a variable cannot be resolved, - the reference in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless of whether the variable - exists or not. - Defaults to "". - type: string - valueFrom: - description: Source for the environment variable's value. - Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? - type: string - optional: - description: Specify whether the ConfigMap or - its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - description: |- - Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, - spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - description: |- - Selects a resource of the container: only resources limits and requests - (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - description: Selects a key of a secret in the pod's - namespace - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? - type: string - optional: - description: Specify whether the Secret or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - envFrom: - description: |- - List of sources to populate environment variables in the container. - The keys defined within a source must be a C_IDENTIFIER. All invalid keys - will be reported as an event when the container is starting. When a key exists in multiple - sources, the value associated with the last source will take precedence. - Values defined by an Env with a duplicate key will take precedence. - Cannot be updated. - items: - description: EnvFromSource represents the source of a set - of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? - type: string - optional: - description: Specify whether the ConfigMap must be - defined - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? - type: string - optional: - description: Specify whether the Secret must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - image: - description: |- - Container image name. - More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management to default or override - container images in workload controllers like Deployments and StatefulSets. - type: string - imagePullPolicy: - description: |- - Image pull policy. - One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/containers/images#updating-images - type: string - lifecycle: - description: |- - Actions that the management system should take in response to container lifecycle events. - Cannot be updated. - properties: - postStart: - description: |- - PostStart is called immediately after a container is created. If the handler fails, - the container is terminated and restarted according to its restart policy. - Other management of the container blocks until the hook completes. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents the duration that the - container should sleep before being terminated. - properties: - seconds: - description: Seconds is the number of seconds to - sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for the backward compatibility. There are no validation of this field and - lifecycle hooks will fail in runtime when tcp handler is specified. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: |- - PreStop is called immediately before a container is terminated due to an - API request or management event such as liveness/startup probe failure, - preemption, resource contention, etc. The handler is not called if the - container crashes or exits. The Pod's termination grace period countdown begins before the - PreStop hook is executed. Regardless of the outcome of the handler, the - container will eventually terminate within the Pod's termination grace - period (unless delayed by finalizers). Other management of the container blocks until the hook completes - or until the termination grace period is reached. - More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - sleep: - description: Sleep represents the duration that the - container should sleep before being terminated. - properties: - seconds: - description: Seconds is the number of seconds to - sleep. - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - description: |- - Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept - for the backward compatibility. There are no validation of this field and - lifecycle hooks will fail in runtime when tcp handler is specified. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - description: |- - Periodic probe of container liveness. - Container will be restarted if the probe fails. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC port. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - name: - description: |- - Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: |- - List of ports to expose from the container. Not specifying a port here - DOES NOT prevent that port from being exposed. Any port which is - listening on the default "0.0.0.0" address inside a container will be - accessible from the network. - Modifying this array with strategic merge patch may corrupt the data. - For more information See https://github.com/kubernetes/kubernetes/issues/108255. - Cannot be updated. - items: - description: ContainerPort represents a network port in a - single container. - properties: - containerPort: - description: |- - Number of port to expose on the pod's IP address. - This must be a valid port number, 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port to. - type: string - hostPort: - description: |- - Number of port to expose on the host. - If specified, this must be a valid port number, 0 < x < 65536. - If HostNetwork is specified, this must match ContainerPort. - Most containers do not need this. - format: int32 - type: integer - name: - description: |- - If specified, this must be an IANA_SVC_NAME and unique within the pod. Each - named port in a pod must have a unique name. Name for the port that can be - referred to by services. - type: string - protocol: - default: TCP - description: |- - Protocol for port. Must be UDP, TCP, or SCTP. - Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: |- - Periodic probe of container service readiness. - Container will be removed from service endpoints if the probe fails. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC port. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - resizePolicy: - description: Resources resize policy for the container. - items: - description: ContainerResizePolicy represents resource resize - policy for the container. - properties: - resourceName: - description: |- - Name of the resource to which this resource resize policy applies. - Supported values: cpu, memory. - type: string - restartPolicy: - description: |- - Restart policy to apply when specified resource is resized. - If not specified, it defaults to NotRequired. - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - description: |- - Compute Resources required by this container. - Cannot be updated. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. - - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - restartPolicy: - description: |- - RestartPolicy defines the restart behavior of individual containers in a pod. - This field may only be set for init containers, and the only allowed value is "Always". - For non-init containers or when this field is not specified, - the restart behavior is defined by the Pod's restart policy and the container type. - Setting the RestartPolicy as "Always" for the init container will have the following effect: - this init container will be continually restarted on - exit until all regular containers have terminated. Once all regular - containers have completed, all init containers with restartPolicy "Always" - will be shut down. This lifecycle differs from normal init containers and - is often referred to as a "sidecar" container. Although this init - container still starts in the init container sequence, it does not wait - for the container to complete before proceeding to the next init - container. Instead, the next init container starts immediately after this - init container is started, or after any startupProbe has successfully - completed. - type: string - securityContext: - description: |- - SecurityContext defines the security options the container should be run with. - If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - properties: - allowPrivilegeEscalation: - description: |- - AllowPrivilegeEscalation controls whether a process can gain more - privileges than its parent process. This bool directly controls if - the no_new_privs flag will be set on the container process. - AllowPrivilegeEscalation is true always when the container is: - 1) run as Privileged - 2) has CAP_SYS_ADMIN - Note that this field cannot be set when spec.os.name is windows. - type: boolean - capabilities: - description: |- - The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by the container runtime. - Note that this field cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: |- - Run container in privileged mode. - Processes in privileged containers are essentially equivalent to root on the host. - Defaults to false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: |- - procMount denotes the type of proc mount to use for the containers. - The default is DefaultProcMount which uses the container runtime defaults for - readonly paths and masked paths. - This requires the ProcMountType feature flag to be enabled. - Note that this field cannot be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: |- - Whether this container has a read-only root filesystem. - Default is false. - Note that this field cannot be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: |- - The GID to run the entrypoint of the container process. - Uses runtime default if unset. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: |- - Indicates that the container must run as a non-root user. - If true, the Kubelet will validate the image at runtime to ensure that it - does not run as UID 0 (root) and fail to start the container if it does. - If unset or false, no such validation will be performed. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: |- - The UID to run the entrypoint of the container process. - Defaults to user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: |- - The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a random SELinux context for each - container. May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: |- - The seccomp options to use by this container. If seccomp options are - provided at both the pod & container level, the container options - override the pod options. - Note that this field cannot be set when spec.os.name is windows. - properties: - localhostProfile: - description: |- - localhostProfile indicates a profile defined in a file on the node should be used. - The profile must be preconfigured on the node to work. - Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must be set if type is "Localhost". Must NOT be set for any other type. - type: string - type: - description: |- - type indicates which kind of seccomp profile will be applied. - Valid options are: - - - Localhost - a profile defined in a file on the node should be used. - RuntimeDefault - the container runtime default profile should be used. - Unconfined - no profile should be applied. - type: string - required: - - type - type: object - windowsOptions: - description: |- - The Windows specific settings applied to all containers. - If unspecified, the options from the PodSecurityContext will be used. - If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: |- - GMSACredentialSpec is where the GMSA admission webhook - (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the - GMSA credential spec named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: |- - HostProcess determines if a container should be run as a 'Host Process' container. - All of a Pod's containers must have the same effective HostProcess value - (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). - In addition, if HostProcess is true then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: |- - The UserName in Windows to run the entrypoint of the container process. - Defaults to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set in both SecurityContext and - PodSecurityContext, the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - startupProbe: - description: |- - StartupProbe indicates that the Pod has successfully initialized. - If specified, no other probes are executed until this completes successfully. - If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. - This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, - when it might take a long time to load data or warm a cache, than during steady-state operation. - This cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: |- - Command is the command line to execute inside the container, the working directory for the - command is root ('/') in the container's filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use - a shell, you need to explicitly call out to that shell. - Exit status of 0 is treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC port. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: |- - Service is the name of the service to place in the gRPC HealthCheckRequest - (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - - - If this is not specified, the default behavior is defined by gRPC. - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: |- - Host name to connect to, defaults to the pod IP. You probably want to set - "Host" in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: |- - The header field name. - This will be canonicalized upon output, so case-variant names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Name or number of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: |- - Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: |- - Number of seconds after the container has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - periodSeconds: - description: |- - How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: |- - Number or name of the port to access on the container. - Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: |- - Optional duration in seconds the pod needs to terminate gracefully upon probe failure. - The grace period is the duration in seconds after the processes running in the pod are sent - a termination signal and the time when the processes are forcibly halted with a kill signal. - Set this value longer than the expected cleanup time for your process. - If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this - value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates stop immediately via - the kill signal (no opportunity to shut down). - This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. - Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: |- - Number of seconds after which the probe times out. - Defaults to 1 second. Minimum value is 1. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes - format: int32 - type: integer - type: object - stdin: - description: |- - Whether this container should allocate a buffer for stdin in the container runtime. If this - is not set, reads from stdin in the container will always result in EOF. - Default is false. - type: boolean - stdinOnce: - description: |- - Whether the container runtime should close the stdin channel after it has been opened by - a single attach. When stdin is true the stdin stream will remain open across multiple attach - sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the - first client attaches to stdin, and then remains open and accepts data until the client disconnects, - at which time stdin is closed and remains closed until the container is restarted. If this - flag is false, a container processes that reads from stdin will never receive an EOF. - Default is false - type: boolean - terminationMessagePath: - description: |- - Optional: Path at which the file to which the container's termination message - will be written is mounted into the container's filesystem. - Message written is intended to be brief final status, such as an assertion failure message. - Will be truncated by the node if greater than 4096 bytes. The total message length across - all containers will be limited to 12kb. - Defaults to /dev/termination-log. - Cannot be updated. - type: string - terminationMessagePolicy: - description: |- - Indicate how the termination message should be populated. File will use the contents of - terminationMessagePath to populate the container status message on both success and failure. - FallbackToLogsOnError will use the last chunk of container log output if the termination - message file is empty and the container exited with an error. - The log output is limited to 2048 bytes or 80 lines, whichever is smaller. - Defaults to File. - Cannot be updated. - type: string - tty: - description: |- - Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. - Default is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices to be - used by the container. - items: - description: volumeDevice describes a mapping of a raw block - device within a container. - properties: - devicePath: - description: devicePath is the path inside of the container - that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: |- - Pod volumes to mount into the container's filesystem. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: |- - Path within the container at which the volume should be mounted. Must - not contain ':'. - type: string - mountPropagation: - description: |- - mountPropagation determines how mounts are propagated from the host - to container and the other way around. - When not set, MountPropagationNone is used. - This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: |- - Mounted read-only if true, read-write otherwise (false or unspecified). - Defaults to false. - type: boolean - subPath: - description: |- - Path within the volume from which the container's volume should be mounted. - Defaults to "" (volume's root). - type: string - subPathExpr: - description: |- - Expanded path within the volume from which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. - Defaults to "" (volume's root). - SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: |- - Container's working directory. - If not specified, the container runtime's default will be used, which - might be configured in the container image. - Cannot be updated. - type: string - required: - - name - type: object - type: array - resourceRequirements: - description: ResourceRequirements describes the compute resource requirements. - properties: - claims: - description: |- - Claims lists the names of resources, defined in spec.resourceClaims, - that are used by this container. - - - This is an alpha field and requires enabling the - DynamicResourceAllocation feature gate. - - - This field is immutable. It can only be set for containers. - items: - description: ResourceClaim references one entry in PodSpec.ResourceClaims. - properties: - name: - description: |- - Name must match the name of one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes that resource available - inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Limits describes the maximum amount of compute resources allowed. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: |- - Requests describes the minimum amount of compute resources required. - If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - type: object - type: object - stack: - description: Stack indicates the stack on which the module is installed - type: string - type: object - status: - 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 - elasticSearchURI: - type: string - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_benthosstreams.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_benthosstreams.formance.com.yaml deleted file mode 100644 index 70d1c8d816..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_benthosstreams.formance.com.yaml +++ /dev/null @@ -1,138 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - helm.sh/resource-policy: keep - name: benthosstreams.formance.com -spec: - group: formance.com - names: - kind: BenthosStream - listKind: BenthosStreamList - plural: benthosstreams - singular: benthosstream - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack - jsonPath: .spec.stack - name: Stack - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: BenthosStream is the Schema for the benthosstreams 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: - properties: - data: - type: string - name: - type: string - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - data - - name - type: object - status: - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_brokerconsumers.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_brokerconsumers.formance.com.yaml deleted file mode 100644 index 1f4cd8d5e0..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_brokerconsumers.formance.com.yaml +++ /dev/null @@ -1,153 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - helm.sh/resource-policy: keep - name: brokerconsumers.formance.com -spec: - group: formance.com - names: - kind: BrokerConsumer - listKind: BrokerConsumerList - plural: brokerconsumers - singular: brokerconsumer - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Listened services - jsonPath: .spec.services - name: Services - type: string - - description: Ready - jsonPath: .status.ready - name: Ready - type: string - - description: Info - jsonPath: .status.info - name: Info - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: BrokerConsumer is the Schema for the brokerconsumers 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: - properties: - name: - description: |- - As the name is optional, if not provided, the name will be the QueriedBy property - This is only applied when using one stream by stack see Mode - type: string - queriedBy: - type: string - services: - items: - type: string - type: array - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - queriedBy - - services - type: object - status: - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_brokers.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_brokers.formance.com.yaml deleted file mode 100644 index 4faf7b5f35..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_brokers.formance.com.yaml +++ /dev/null @@ -1,156 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - helm.sh/resource-policy: keep - name: brokers.formance.com -spec: - group: formance.com - names: - kind: Broker - listKind: BrokerList - plural: brokers - singular: broker - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Mode - jsonPath: .status.mode - name: Mode - type: string - - description: Ready - jsonPath: .status.ready - name: Ready - type: string - - description: Info - jsonPath: .status.info - name: Info - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: Broker is the Schema for the brokers 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: - properties: - stack: - description: Stack indicates the stack on which the module is installed - type: string - type: object - status: - 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 - mode: - description: |- - Mode indicating the configuration of the nats streams - Two modes are defined : - * OneStreamByService: In this case, each service will have a dedicated stream created - * OneStreamByStack: In this case, a stream will be created for the stack and each service will use a specific subject inside this stream - enum: - - OneStreamByService - - OneStreamByStack - type: string - ready: - description: Ready indicates if the resource is seen as completely - reconciled - type: boolean - streams: - description: Streams list streams created when Mode == ModeOneStreamByService - items: - type: string - type: array - uri: - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_brokertopics.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_brokertopics.formance.com.yaml deleted file mode 100644 index 8a0d80861f..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_brokertopics.formance.com.yaml +++ /dev/null @@ -1,143 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - helm.sh/resource-policy: keep - name: brokertopics.formance.com -spec: - group: formance.com - names: - kind: BrokerTopic - listKind: BrokerTopicList - plural: brokertopics - singular: brokertopic - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack - jsonPath: .spec.stack - name: Stack - type: string - - description: Ready - jsonPath: .status.ready - name: Ready - type: string - - description: Info - jsonPath: .status.info - name: Info - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: BrokerTopic is the Schema for the brokertopics 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: - properties: - service: - type: string - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - service - type: object - status: - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_databases.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_databases.formance.com.yaml deleted file mode 100644 index eb4e19dc54..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_databases.formance.com.yaml +++ /dev/null @@ -1,189 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - helm.sh/resource-policy: keep - name: databases.formance.com -spec: - group: formance.com - names: - kind: Database - listKind: DatabaseList - plural: databases - singular: database - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack - jsonPath: .spec.stack - name: Stack - type: string - - description: Ready - jsonPath: .status.ready - name: Ready - type: string - - description: Is the databse configuration out of sync - jsonPath: .status.outOfSync - name: Out of sync - type: string - - description: Info - jsonPath: .status.info - name: Info - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: |- - Database represent a concrete database on a PostgreSQL server, it is created by modules requiring a database ([Ledger](#ledger) for example). - - - It uses the settings `postgres..uri` which must have the following uri format: `postgresql://[@]@/` - Additionally, the uri can define a query param `secret` indicating a k8s secret, than must be used to retrieve database credentials. - - - On creation, the reconciler behind the Database object will create the database on the postgresql server using a k8s job. - On Deletion, by default, the reconciler will let the database untouched. - You can allow the reconciler to drop the database on the server by using the [Settings](#settings) `clear-database` with the value `true`. - If you use that setting, the reconciler will use another job to drop the database. - Be careful, no backup are performed! - - - Database resource honors `aws.service-account` setting, so, you can create databases on an AWS server if you need. - See [AWS accounts](#aws-account) - - - Once a database is fully configured, it retains the postgres uri used. - If the setting indicating the server uri changed, the Database object will set the field `.status.outOfSync` to true - and will not change anything. - - - Therefore, to switch to a new server, you must change the setting value, then drop the Database object. - It will be recreated with correct uri. - 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: - properties: - debug: - default: false - type: boolean - service: - description: |- - Service is a discriminator for the created database. - Actually, it will be the module name (ledger, payments...). - Therefore, the created database will be named `` - type: string - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - service - type: object - status: - 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 - database: - description: The generated database name - type: string - info: - description: Info can contain any additional like reconciliation errors - type: string - outOfSync: - description: |- - OutOfSync indicates than a settings changed the uri of the postgres server - The Database object need to be removed to be recreated - type: boolean - ready: - description: Ready indicates if the resource is seen as completely - reconciled - type: boolean - uri: - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_gatewayhttpapis.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_gatewayhttpapis.formance.com.yaml deleted file mode 100644 index 405c1baa3e..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_gatewayhttpapis.formance.com.yaml +++ /dev/null @@ -1,161 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - helm.sh/resource-policy: keep - name: gatewayhttpapis.formance.com -spec: - group: formance.com - names: - kind: GatewayHTTPAPI - listKind: GatewayHTTPAPIList - plural: gatewayhttpapis - singular: gatewayhttpapi - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack - jsonPath: .spec.stack - name: Stack - type: string - - description: Ready - jsonPath: .status.ready - name: Ready - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: GatewayHTTPAPI is the Schema for the HTTPAPIs 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: - properties: - healthCheckEndpoint: - description: Health check endpoint - type: string - name: - description: Name indicates prefix api - type: string - rules: - description: Rules - items: - properties: - methods: - items: - type: string - type: array - path: - type: string - secured: - default: false - type: boolean - required: - - path - type: object - type: array - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - name - - rules - type: object - status: - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_gateways.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_gateways.formance.com.yaml deleted file mode 100644 index 6211aa3243..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_gateways.formance.com.yaml +++ /dev/null @@ -1,202 +0,0 @@ -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/kind: module - name: gateways.formance.com -spec: - group: formance.com - names: - kind: Gateway - listKind: GatewayList - plural: gateways - singular: gateway - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack - jsonPath: .spec.stack - name: Stack - type: string - - description: Synchronized http apis - jsonPath: .status.syncHTTPAPIs - name: HTTP APIs - 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: Gateway is the Schema for the gateways 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: - 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 - ingress: - description: Allow to customize the generated ingress - properties: - annotations: - additionalProperties: - type: string - description: Custom annotations to add on the ingress - type: object - host: - description: |- - Indicates the hostname on which the stack will be served. - Example : `formance.example.com` - type: string - ingressClassName: - description: Ingress class to use - type: string - scheme: - default: https - description: |- - Indicate the scheme. - - - Actually, It should be `https` unless you know what you are doing. - type: string - tls: - description: Allow to customize the tls part of the ingress - properties: - secretName: - description: Specify the secret name used for the tls configuration - on the ingress - type: string - required: - - secretName - type: object - required: - - host - - scheme - type: object - 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: - 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 - syncHTTPAPIs: - description: Detected http apis. See [GatewayHTTPAPI](#gatewayhttpapi) - items: - type: string - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_ledgers.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_ledgers.formance.com.yaml deleted file mode 100644 index 19c8ad6d71..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_ledgers.formance.com.yaml +++ /dev/null @@ -1,215 +0,0 @@ -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/kind: module - name: ledgers.formance.com -spec: - group: formance.com - names: - kind: Ledger - listKind: LedgerList - plural: ledgers - singular: ledger - 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: |- - Ledger is the module allowing to install a ledger instance. - - - The ledger is actually a stateful application on the writer part. - So we cannot scale the ledger as we want without prior configuration. - - - So, the ledger can run in two modes : - * single instance: Only one instance will be deployed. We cannot scale in that mode. - * single writer / multiple reader: In this mode, we will have a single writer and multiple readers if needed. - - - Use setting `ledger.deployment-strategy` with either the value : - - single : For the single instance mode. - - single-writer: For the single writer / multiple reader mode. - Under the hood, the operator create two deployments and force the scaling of the writer to stay at 1. - Then you can scale the deployment of the reader to the value you want. - 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - debug: - default: false - description: Allow to enable debug mode on the module - type: boolean - deploymentStrategy: - default: single - description: Deprecated. - type: string - 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 - locking: - description: Locking is intended for ledger v1 only - properties: - redis: - properties: - duration: - description: |- - A Duration represents the elapsed time between two instants - as an int64 nanosecond count. The representation limits the - largest representable duration to approximately 290 years. - format: int64 - type: integer - insecure: - default: false - type: boolean - retry: - description: |- - A Duration represents the elapsed time between two instants - as an int64 nanosecond count. The representation limits the - largest representable duration to approximately 290 years. - format: int64 - type: integer - tls: - default: false - type: boolean - uri: - type: string - type: object - strategy: - default: memory - type: string - type: object - 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: - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_orchestrations.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_orchestrations.formance.com.yaml deleted file mode 100644 index 2c1a242b1a..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_orchestrations.formance.com.yaml +++ /dev/null @@ -1,165 +0,0 @@ -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: orchestrations.formance.com -spec: - group: formance.com - names: - kind: Orchestration - listKind: OrchestrationList - plural: orchestrations - singular: orchestration - 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: Orchestration is the Schema for the orchestrations 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - 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: - 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 - temporalURI: - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_payments.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_payments.formance.com.yaml deleted file mode 100644 index eb948d85fb..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_payments.formance.com.yaml +++ /dev/null @@ -1,164 +0,0 @@ -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/kind: module - name: payments.formance.com -spec: - group: formance.com - names: - kind: Payments - listKind: PaymentsList - plural: payments - singular: payments - 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: Payments is the Schema for the payments 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - 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 - encryptionKey: - type: string - 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: - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_reconciliations.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_reconciliations.formance.com.yaml deleted file mode 100644 index 37e4a65428..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_reconciliations.formance.com.yaml +++ /dev/null @@ -1,163 +0,0 @@ -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: reconciliations.formance.com -spec: - group: formance.com - names: - kind: Reconciliation - listKind: ReconciliationList - plural: reconciliations - singular: reconciliation - 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: Reconciliation is the Schema for the reconciliations 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - 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: - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_resourcereferences.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_resourcereferences.formance.com.yaml deleted file mode 100644 index 81a8ef8958..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_resourcereferences.formance.com.yaml +++ /dev/null @@ -1,170 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - helm.sh/resource-policy: keep - name: resourcereferences.formance.com -spec: - group: formance.com - names: - kind: ResourceReference - listKind: ResourceReferenceList - plural: resourcereferences - singular: resourcereference - scope: Cluster - versions: - - name: v1beta1 - schema: - openAPIV3Schema: - description: "ResourceReference is a special resources used to refer to externally - created resources.\n\n\nIt includes k8s service accounts and secrets.\n\n\nWhy? - Because the operator create a namespace by stack, so, a stack does not have - access to secrets and service\naccounts created externally.\n\n\nA ResourceReference - is created by other resource who need to use a specific secret or service - account.\nFor example, if you want to use a secret for your database connection - (see [Database](#database), you will\ncreate a setting indicating a secret - name. You will need to create this secret yourself, and you will put this\nsecret - inside the namespace you want (`default` maybe).\n\n\nThe Database reconciler - will create a ResourceReference looking like that :\n```\napiVersion: formance.com/v1beta1\nkind: - ResourceReference\nmetadata:\n\n\n\tname: jqkuffjxcezj-qlii-auth-postgres\n\townerReferences:\n\t- - apiVersion: formance.com/v1beta1\n\t blockOwnerDeletion: true\n\t controller: - true\n\t kind: Database\n\t name: jqkuffjxcezj-qlii-auth\n\t uid: 2cc4b788-3ffb-4e3d-8a30-07ed3941c8d2\n\n\nspec:\n\n\n\tgvk:\n\t - \ group: \"\"\n\t kind: Secret\n\t version: v1\n\tname: postgres\n\tstack: - jqkuffjxcezj-qlii\n\n\nstatus:\n\n\n\t...\n\n\n```\nThis reconciler behind - this ResourceReference will search, in all namespaces, for a secret named - \"postgres\".\nThe secret must have a label `formance.com/stack` with the - value matching either a specific stack or `any` to target any stack.\n\n\nOnce - the reconciler has found the secret, it will copy it inside the stack namespace, - allowing the ResourceReconciler owner to use it." - 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: - properties: - gvk: - description: |- - GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion - to avoid automatic coercion. It doesn't use a GroupVersion to avoid custom marshalling - properties: - group: - type: string - kind: - type: string - version: - type: string - required: - - group - - kind - - version - type: object - name: - type: string - stack: - description: Stack indicates the stack on which the module is installed - type: string - required: - - gvk - - name - type: object - status: - 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 - hash: - type: string - 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 - syncedResource: - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_searches.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_searches.formance.com.yaml deleted file mode 100644 index 91c91fb916..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_searches.formance.com.yaml +++ /dev/null @@ -1,185 +0,0 @@ -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: searches.formance.com -spec: - group: formance.com - names: - kind: Search - listKind: SearchList - plural: searches - singular: search - 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: Search is the Schema for the searches 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - batching: - description: Batching allow to define custom batching configuration - properties: - count: - description: Count indicates the number of messages that can be - kept in memory before being flushed to ElasticSearch - type: integer - period: - description: Period indicates the maximum duration messages can - be kept in memory before being flushed to ElasticSearch - type: string - required: - - count - - period - type: object - 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: - 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 - elasticSearchURI: - type: string - 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 - topicCleaned: - default: false - description: TopicCleaned is used to flag stacks where the topics - have been cleaned (still search-ledgerv2 and co consumers) - type: boolean - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_settings.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_settings.formance.com.yaml deleted file mode 100644 index f20aafe5e0..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_settings.formance.com.yaml +++ /dev/null @@ -1,114 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - helm.sh/resource-policy: keep - name: settings.formance.com -spec: - group: formance.com - names: - kind: Settings - listKind: SettingsList - plural: settings - singular: settings - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Key - jsonPath: .spec.key - name: Key - type: string - - description: Value - jsonPath: .spec.value - name: Value - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: "Settings represents a configurable piece of the stacks.\n\n\nThe - purpose of this resource is to be able to configure some common settings - between a set of stacks.\n\n\nExample :\n```yaml\napiVersion: formance.com/v1beta1\nkind: - Settings\nmetadata:\n\n\n\tname: postgres-uri\n\n\nspec:\n\n\n\tkey: postgres.ledger.uri\n\tstacks:\n\t- - stack0\n\tvalue: postgresql://postgresql.formance.svc.cluster.local:5432\n\n\n```\n\n\nThis - example create a setting named `postgres-uri` targeting the stack named - `stack0` and the service `ledger` (see the key `postgres.ledger.uri`).\n\n\nTherefore, - a [Database](#database) created for the stack `stack0` and the service named - 'ledger' will use the uri `postgresql://postgresql.formance.svc.cluster.local:5432`.\n\n\nSettings - allow to use wildcards in keys and in stacks list.\n\n\nFor example, if - you want to use the same database server for all the modules of a specific - stack, you can write :\n```yaml\napiVersion: formance.com/v1beta1\nkind: - Settings\nmetadata:\n\n\n\tname: postgres-uri\n\n\nspec:\n\n\n\tkey: postgres.*.uri - # There, we use a wildcard to indicate we want to use that setting of all - services of the stack `stack0`\n\tstacks:\n\t- stack0\n\tvalue: postgresql://postgresql.formance.svc.cluster.local:5432\n\n\n```\n\n\nAlso, - we could use that setting for all of our stacks using :\n```yaml\napiVersion: - formance.com/v1beta1\nkind: Settings\nmetadata:\n\n\n\tname: postgres-uri\n\n\nspec:\n\n\n\tkey: - postgres.*.uri # There, we use a wildcard to indicate we want to use that - setting for all services of all stacks\n\tstacks:\n\t- * # There we select - all the stacks\n\tvalue: postgresql://postgresql.formance.svc.cluster.local:5432\n\n\n```\n\n\nSome - settings are really global, while some are used by specific module.\n\n\nRefer - to the documentation of each module and resource to discover available Settings.\n\n\n##### - Global settings\n###### AWS account\n\n\nA stack can use an AWS account - for authentication.\n\n\nIt can be used to connect to any AWS service we - could use.\n\n\nIt includes RDS, OpenSearch and MSK. To do so, you can create - the following setting:\n```yaml\napiVersion: formance.com/v1beta1\nkind: - Settings\nmetadata:\n\n\n\tname: aws-service-account\n\n\nspec:\n\n\n\tkey: - aws.service-account\n\tstacks:\n\t- '*'\n\tvalue: aws-access\n\n\n```\nThis - setting instruct the operator than there is somewhere on the cluster a service - account named `aws-access`.\n\n\nSo, each time a service has the capability - to use AWS, the operator will use this service account.\n\n\nThe service - account could look like that :\n```yaml\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n\n\n\tannotations:\n\t - \ eks.amazonaws.com/role-arn: arn:aws:iam::************:role/staging-eu-west-1-hosting-stack-access\n\tlabels:\n\t - \ formance.com/stack: any\n\tname: aws-access\n\n\n```\nYou can note two - things :\n 1. We have an annotation indicating the role arn used to connect - to AWS. Refer to the AWS documentation to create this role\n 2. We have - a label `formance.com/stack=any` indicating we are targeting all stacks.\n - \ Refer to the documentation of [ResourceReference](#resourcereference) - for further information.\n\n\n###### JSON logging\n\n\nYou can use the setting - `logging.json` with the value `true` to configure elligible service to log - as json.\nExample:\n```yaml\napiVersion: formance.com/v1beta1\nkind: Settings\nmetadata:\n\n\n\tname: - json-logging\n\n\nspec:\n\n\n\tkey: logging.json\n\tstacks:\n\t- '*'\n\tvalue: - \"true\"\n\n\n```" - 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: - properties: - key: - description: The setting Key. See the documentation of each module - or [global settings](#global-settings) to discover them. - type: string - stacks: - description: Stacks on which the setting is applied. Can contain `*` - to indicate a wildcard. - items: - type: string - type: array - value: - description: The value. It must have a specific format following the - Key. - type: string - required: - - key - - value - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_stacks.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_stacks.formance.com.yaml deleted file mode 100644 index 7c8bb271e8..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_stacks.formance.com.yaml +++ /dev/null @@ -1,205 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - helm.sh/resource-policy: keep - name: stacks.formance.com -spec: - group: formance.com - names: - kind: Stack - listKind: StackList - plural: stacks - singular: stack - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Stack Disabled - jsonPath: .spec.disabled - name: Disable - type: string - - description: Stack Version - jsonPath: .spec.version - name: Version - type: string - - description: Stack Version From File - jsonPath: .spec.versionsFromFile - name: Versions From file - type: string - - description: Is stack ready - jsonPath: .status.ready - name: Ready - type: boolean - - description: Modules List Registered - jsonPath: .status.modules - name: Modules - type: string - - description: Info - jsonPath: .status.info - name: Info - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: |- - Stack represents a formance stack. - A Stack is basically a container. It holds some global properties and - creates a namespace if not already existing. - - - To do more, you need to create some [modules](#modules). - - - The Stack resource allow to specify the version of the stack. - - - It can be specified using either the field `.spec.version` or the `.spec.versionsFromFile` field (Refer to the documentation of [Versions](#versions) resource. - - - The `version` field will have priority over `versionFromFile`. - - - If `versions` and `versionsFromFile` are not specified, "latest" will be used. - 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: - 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 - disabled: - default: false - description: |- - Disabled indicate the stack is disabled. - A disabled stack disable everything - It just keeps the namespace and the [Database](#database) resources. - type: boolean - enableAudit: - default: false - description: |- - EnableAudit enable audit at the stack level. - Actually, it enables audit on [Gateway](#gateway) - type: boolean - version: - description: |- - Version allow to specify the version of the components - Must be a valid docker tag - type: string - versionsFromFile: - description: |- - VersionsFromFile allow to specify a formance.com/Versions object which contains individual versions - for each component. - Must reference a valid formance.com/Versions object - type: string - type: object - status: - 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 - modules: - description: Modules register detected modules - items: - type: string - type: array - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_stargates.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_stargates.formance.com.yaml deleted file mode 100644 index 3eb62b4658..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_stargates.formance.com.yaml +++ /dev/null @@ -1,180 +0,0 @@ -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/kind: module - name: stargates.formance.com -spec: - group: formance.com - names: - kind: Stargate - listKind: StargateList - plural: stargates - singular: stargate - 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: Stargate is the Schema for the stargates 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: - properties: - auth: - properties: - clientID: - type: string - clientSecret: - type: string - issuer: - type: string - required: - - clientID - - clientSecret - - issuer - type: object - 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 - organizationID: - type: string - serverURL: - type: string - stack: - description: Stack indicates the stack on which the module is installed - type: string - stackID: - type: string - version: - description: Version allow to override global version defined at stack - level for a specific module - type: string - required: - - auth - - organizationID - - serverURL - - stackID - type: object - status: - description: StargateStatus defines the observed state of Stargate - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_versions.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_versions.formance.com.yaml deleted file mode 100644 index ee42789b2a..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_versions.formance.com.yaml +++ /dev/null @@ -1,47 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - helm.sh/resource-policy: keep - name: versions.formance.com -spec: - group: formance.com - names: - kind: Versions - listKind: VersionsList - plural: versions - singular: versions - scope: Cluster - versions: - - name: v1beta1 - schema: - openAPIV3Schema: - description: Versions is the Schema for the versions 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: - additionalProperties: - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_wallets.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_wallets.formance.com.yaml deleted file mode 100644 index cdcda48136..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_wallets.formance.com.yaml +++ /dev/null @@ -1,164 +0,0 @@ -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: wallets.formance.com -spec: - group: formance.com - names: - kind: Wallets - listKind: WalletsList - plural: wallets - singular: wallets - 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: Wallets is the Schema for the wallets 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - 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: WalletsStatus defines the observed state of Wallets - 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/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_webhooks.formance.com.yaml b/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_webhooks.formance.com.yaml deleted file mode 100644 index 2f34b2b332..0000000000 --- a/components/operator/helm/crds/templates/crds/apiextensions.k8s.io_v1_customresourcedefinition_webhooks.formance.com.yaml +++ /dev/null @@ -1,163 +0,0 @@ -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: webhooks.formance.com -spec: - group: formance.com - names: - kind: Webhooks - listKind: WebhooksList - plural: webhooks - singular: webhooks - 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: Webhooks is the Schema for the webhooks 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: - properties: - auth: - properties: - checkScopes: - type: boolean - readKeySetMaxRetries: - type: integer - type: object - 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: - 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/crds/values.yaml b/components/operator/helm/crds/values.yaml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/components/operator/helm/operator/.helmignore b/components/operator/helm/operator/.helmignore deleted file mode 100644 index 9e8e34ffa6..0000000000 --- a/components/operator/helm/operator/.helmignore +++ /dev/null @@ -1,28 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ - -# ignore kustomization.yaml files -templates/rbac/kustomization.yaml -templates/certmanager/kustomiz*.yaml -templates/webhook/kustomiz*.yaml diff --git a/components/operator/helm/operator/Chart.lock b/components/operator/helm/operator/Chart.lock deleted file mode 100644 index ec8bb801db..0000000000 --- a/components/operator/helm/operator/Chart.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: operator-crds - repository: file://../crds - version: v2.1.0-beta.1 -digest: sha256:466e804e65bcff5acfc01b30687c54d82c5590e2c0f4914b1667c1cdde3a1a31 -generated: "2024-09-10T10:31:01.470558289Z" diff --git a/components/operator/helm/operator/Chart.yaml b/components/operator/helm/operator/Chart.yaml deleted file mode 100644 index 71ade17cf2..0000000000 --- a/components/operator/helm/operator/Chart.yaml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: v2 -name: operator -description: Formance Operator Helm Chart -home: "https://formance.com" -sources: - - "https://github.com/formancehq/stack" -maintainers: - - name: "Formance Team" - email: "support@formance.com" -icon: "https://avatars.githubusercontent.com/u/84325077?s=200&v=4" - -type: application - -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -# Versions are expected to follow Semantic Versioning (https://semver.org/) -version: v2.1.0-beta.1 - -# This is the version number of the application being deployed. This version number should be -# incremented each time you make changes to the application. Versions are not expected to -# follow Semantic Versioning. They should reflect the version the application is using. -# It is recommended to use it with quotes. -appVersion: v2.1.0-beta.1 - -dependencies: - - name: operator-crds - version: v2.1.0-beta.1 - repository: "file://../crds" - condition: operator-crds.create diff --git a/components/operator/helm/operator/README.md b/components/operator/helm/operator/README.md deleted file mode 100644 index fb189891b8..0000000000 --- a/components/operator/helm/operator/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# operator - -![Version: 0.2.6](https://img.shields.io/badge/Version-0.2.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.16.15](https://img.shields.io/badge/AppVersion-v0.16.15-informational?style=flat-square) - -Formance Operator Helm Chart - -**Homepage:** - -## Maintainers - -| Name | Email | Url | -| ---- | ------ | --- | -| Formance Team | | | - -## Source Code - -* - -## Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| affinity | object | `{}` | | -| fullnameOverride | string | `""` | | -| image.pullPolicy | string | `"IfNotPresent"` | | -| image.repository | string | `"ghcr.io/formancehq/operator"` | | -| image.tag | string | `"v0.16.15"` | | -| imagePullSecrets | list | `[]` | | -| nameOverride | string | `""` | | -| nodeSelector | object | `{}` | | -| operator.disableWebhooks | bool | `false` | | -| operator.enableLeaderElection | bool | `true` | | -| operator.env | string | `"staging"` | | -| operator.metricsAddr | string | `":8080"` | | -| operator.probeAddr | string | `":8081"` | | -| operator.region | string | `"eu-west-1"` | | -| podAnnotations | object | `{}` | | -| podSecurityContext | object | `{}` | | -| replicaCount | int | `1` | | -| resources | object | `{}` | | -| securityContext | object | `{}` | | -| tolerations | list | `[]` | | - ----------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) diff --git a/components/operator/helm/operator/templates/_helpers.tpl b/components/operator/helm/operator/templates/_helpers.tpl deleted file mode 100644 index 5e218ec1c1..0000000000 --- a/components/operator/helm/operator/templates/_helpers.tpl +++ /dev/null @@ -1,51 +0,0 @@ -{{/* -Expand the name of the chart. -*/}} -{{- define "operator.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "operator.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- $name := default .Chart.Name .Values.nameOverride }} -{{- if contains $name .Release.Name }} -{{- .Release.Name | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "operator.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "operator.labels" -}} -helm.sh/chart: {{ include "operator.chart" . }} -{{ include "operator.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "operator.selectorLabels" -}} -app.kubernetes.io/name: {{ include "operator.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} diff --git a/components/operator/helm/operator/templates/deployment.yaml b/components/operator/helm/operator/templates/deployment.yaml deleted file mode 100644 index f5cf92b496..0000000000 --- a/components/operator/helm/operator/templates/deployment.yaml +++ /dev/null @@ -1,133 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "operator.fullname" . }} - labels: - {{- include "operator.labels" . | nindent 4 }} - control-plane: controller-manager -spec: - selector: - matchLabels: - {{- include "operator.selectorLabels" . | nindent 6 }} - template: - metadata: - {{- with .Values.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "operator.selectorLabels" . | nindent 8 }} - control-plane: formance-controller-manager - spec: - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: formance-controller-manager - securityContext: - {{- toYaml .Values.podSecurityContext | nindent 8 }} - containers: - - name: {{ .Chart.Name }} - securityContext: - {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - command: - - /usr/bin/operator - args: - {{- with .Values.operator.metricsAddr }} - - --metrics-bind-address={{ $.Values.operator.metricsAddr }} - {{- end }} - {{- with .Values.operator.probeAddr }} - - --health-probe-bind-address={{ $.Values.operator.probeAddr }} - {{- end }} - {{- with .Values.operator.enableLeaderElection }} - - --leader-elect - {{- end }} - {{- with .Values.operator.env }} - - --env={{ $.Values.operator.env }} - {{- end }} - {{- with .Values.operator.region }} - - --region={{ $.Values.operator.region }} - {{- end }} - {{ if .Values.operator.licence.create }} - - --licence-secret={{ include "operator.fullname" . }}-licence - {{- else }} - - --licence-secret={{ .Values.operator.licence.secretName }} - {{- end }} - {{- if .Values.operator.disableWebhooks }} - - --disable-webhooks - {{- end }} - {{ if .Values.operator.utils.tag }} - - --utils-version={{ .Values.operator.utils.tag }} - {{- end }} - {{- if .Values.operator.dev }} - - --zap-devel - - Development - {{- end }} - ports: - - containerPort: 9443 - name: webhook-server - protocol: TCP - livenessProbe: - httpGet: - path: /healthz - port: {{ regexReplaceAll ":" .Values.operator.probeAddr "" | default "8081" }} - initialDelaySeconds: 15 - periodSeconds: 20 - readinessProbe: - httpGet: - path: /readyz - port: {{ regexReplaceAll ":" .Values.operator.probeAddr "" | default "8081" }} - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - {{- toYaml .Values.resources | nindent 12 }} - {{- if .Values.webhooks.enabled }} - volumeMounts: - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cert - readOnly: true - {{- end }} - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1{{- .Values.operator.metricsAddr | default ":8080" -}}/ - - --logtostderr=true - - --v=0 - image: "{{ .Values.kubeRbacProxy.image.repository }}:{{ .Values.kubeRbacProxy.image.tag | default "latest" }}" - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - protocol: TCP - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - {{- with .Values.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- if .Values.webhooks.enabled }} - volumes: - - name: cert - secret: - defaultMode: 420 - secretName: webhook-server-cert - {{- end }} 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 deleted file mode 100644 index fa548655e3..0000000000 --- a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-manager-role.yaml +++ /dev/null @@ -1,762 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: formance-manager-role -rules: -- apiGroups: - - apps - resources: - - deployments - verbs: - - create - - delete - - deletecollection - - get - - list - - patch - - update - - watch -- apiGroups: - - batch - resources: - - cronjobs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - batch - resources: - - jobs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - cert-manager.io - resources: - - certificates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - events - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - namespaces - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - pods - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - secrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - serviceaccounts - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - services - verbs: - - create - - delete - - get - - list - - 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: - - authclients - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - authclients/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - authclients/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - auths - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - auths/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - auths/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - benthos - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - benthos/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - benthos/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - benthosstreams - verbs: - - create - - delete - - deletecollection - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - benthosstreams/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - benthosstreams/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - brokerconsumers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - brokerconsumers/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - brokerconsumers/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - brokers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - brokers/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - brokers/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - brokertopics - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - brokertopics/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - brokertopics/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - databases - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - databases/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - databases/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - gatewayhttpapis - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - gatewayhttpapis/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - gatewayhttpapis/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - gateways - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - gateways/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - gateways/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - ledgers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - ledgers/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - ledgers/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - orchestrations - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - orchestrations/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - orchestrations/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - payments - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - payments/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - payments/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - reconciliations - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - reconciliations/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - reconciliations/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - resourcereferences - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - resourcereferences/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - resourcereferences/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - searches - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - searches/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - searches/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - settings - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - settings/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - settings/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - stacks - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - stacks/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - stacks/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - stargates - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - stargates/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - stargates/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - versions - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - versions/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - versions/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - wallets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - wallets/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - wallets/status - verbs: - - get - - patch - - update -- apiGroups: - - formance.com - resources: - - webhooks - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - formance.com - resources: - - webhooks/finalizers - verbs: - - update -- apiGroups: - - formance.com - resources: - - webhooks/status - verbs: - - get - - patch - - update -- apiGroups: - - networking.k8s.io - resources: - - ingresses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - policy - resources: - - poddisruptionbudgets - verbs: - - create - - delete - - deletecollection - - get - - list - - patch - - update - - watch diff --git a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-metrics-reader.yaml b/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-metrics-reader.yaml deleted file mode 100644 index c0d7dde69c..0000000000 --- a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-metrics-reader.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/instance: metrics-reader - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: clusterrole - app.kubernetes.io/part-of: operatorv2 - name: formance-metrics-reader -rules: -- nonResourceURLs: - - /metrics - verbs: - - get diff --git a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-proxy-role.yaml b/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-proxy-role.yaml deleted file mode 100644 index bd3d63813a..0000000000 --- a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrole_formance-proxy-role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/instance: proxy-role - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: clusterrole - app.kubernetes.io/part-of: operatorv2 - name: formance-proxy-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create diff --git a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrolebinding_formance-manager-rolebinding.yaml b/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrolebinding_formance-manager-rolebinding.yaml deleted file mode 100644 index 488a44868e..0000000000 --- a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrolebinding_formance-manager-rolebinding.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/instance: manager-rolebinding - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: clusterrolebinding - app.kubernetes.io/part-of: operatorv2 - name: formance-manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: formance-manager-role -subjects: -- kind: ServiceAccount - name: formance-controller-manager - namespace: '{{ .Release.Namespace }}' diff --git a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrolebinding_formance-proxy-rolebinding.yaml b/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrolebinding_formance-proxy-rolebinding.yaml deleted file mode 100644 index 3ea21f3ad5..0000000000 --- a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_clusterrolebinding_formance-proxy-rolebinding.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/instance: proxy-rolebinding - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: clusterrolebinding - app.kubernetes.io/part-of: operatorv2 - name: formance-proxy-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: formance-proxy-role -subjects: -- kind: ServiceAccount - name: formance-controller-manager - namespace: '{{ .Release.Namespace }}' diff --git a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_role_formance-leader-election-role.yaml b/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_role_formance-leader-election-role.yaml deleted file mode 100644 index c9791df41b..0000000000 --- a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_role_formance-leader-election-role.yaml +++ /dev/null @@ -1,44 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/instance: leader-election-role - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: role - app.kubernetes.io/part-of: operatorv2 - name: formance-leader-election-role - namespace: '{{ .Release.Namespace }}' -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch diff --git a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_rolebinding_formance-leader-election-rolebinding.yaml b/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_rolebinding_formance-leader-election-rolebinding.yaml deleted file mode 100644 index d75b982a54..0000000000 --- a/components/operator/helm/operator/templates/gen/rbac.authorization.k8s.io_v1_rolebinding_formance-leader-election-rolebinding.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/instance: leader-election-rolebinding - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: rolebinding - app.kubernetes.io/part-of: operatorv2 - name: formance-leader-election-rolebinding - namespace: '{{ .Release.Namespace }}' -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: formance-leader-election-role -subjects: -- kind: ServiceAccount - name: formance-controller-manager - namespace: '{{ .Release.Namespace }}' diff --git a/components/operator/helm/operator/templates/gen/v1_service_formance-controller-manager-metrics-service.yaml b/components/operator/helm/operator/templates/gen/v1_service_formance-controller-manager-metrics-service.yaml deleted file mode 100644 index 2fdb7995f4..0000000000 --- a/components/operator/helm/operator/templates/gen/v1_service_formance-controller-manager-metrics-service.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/instance: controller-manager-metrics-service - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: service - app.kubernetes.io/part-of: operatorv2 - control-plane: controller-manager - name: formance-controller-manager-metrics-service - namespace: '{{ .Release.Namespace }}' -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: https - selector: - control-plane: controller-manager diff --git a/components/operator/helm/operator/templates/gen/v1_serviceaccount_formance-controller-manager.yaml b/components/operator/helm/operator/templates/gen/v1_serviceaccount_formance-controller-manager.yaml deleted file mode 100644 index f0cba0d602..0000000000 --- a/components/operator/helm/operator/templates/gen/v1_serviceaccount_formance-controller-manager.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: operatorv2 - app.kubernetes.io/instance: controller-manager-sa - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: serviceaccount - app.kubernetes.io/part-of: operatorv2 - name: formance-controller-manager - namespace: '{{ .Release.Namespace }}' diff --git a/components/operator/helm/operator/templates/licence-secret.yaml b/components/operator/helm/operator/templates/licence-secret.yaml deleted file mode 100644 index f0a71ef10d..0000000000 --- a/components/operator/helm/operator/templates/licence-secret.yaml +++ /dev/null @@ -1,12 +0,0 @@ -{{- if .Values.operator.licence.create }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ include "operator.fullname" . }}-licence - namespace: '{{ .Release.Namespace }}' - labels: - formance.com/stack: any -stringData: - token: {{ .Values.operator.licence.token }} - issuer: {{ .Values.operator.licence.issuer }} -{{- end }} \ No newline at end of file diff --git a/components/operator/helm/operator/values.yaml b/components/operator/helm/operator/values.yaml deleted file mode 100644 index a5e4b22784..0000000000 --- a/components/operator/helm/operator/values.yaml +++ /dev/null @@ -1,85 +0,0 @@ -# Default values for operator. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -replicaCount: 1 - -image: - repository: ghcr.io/formancehq/operator - pullPolicy: IfNotPresent - # Overrides the image tag whose default is the chart appVersion. - tag: v2.1.0-beta.1 - -imagePullSecrets: [] -nameOverride: "" -fullnameOverride: "" - -operator: - dev: false - # The region to use for the operator - region: "eu-west-1" - # The environment to use for the operator - env: "staging" - # The address the metric endpoint binds to - metricsAddr: ":8080" - # The address the probe endpoint binds to - probeAddr: ":8081" - # Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager. - enableLeaderElection: true - - # Licence secret must have the label formance.com/stack: any to be referenced by the operator on any stack namespace - # Have a `token` and `issuer` key - licence: - create: true - secretName: "" - token: "" - issuer: "" - - utils: - tag: "v2.0.14" - -podAnnotations: {} - -podSecurityContext: - {} - # fsGroup: 2000 - -securityContext: - {} - # capabilities: - # drop: - # - ALL - # readOnlyRootFilesystem: true - # runAsNonRoot: true - # runAsUser: 1000 - -resources: - {} - # We usually recommend not to specify default resources and to leave this as a conscious - # choice for the user. This also increases chances charts run on environments with little - # resources, such as Minikube. If you do want to specify resources, uncomment the following - # lines, adjust them as necessary, and remove the curly braces after 'resources:'. - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - -nodeSelector: {} - -tolerations: [] - -affinity: {} - -webhooks: - enabled: false - -kubeRbacProxy: - image: - repository: gcr.io/kubebuilder/kube-rbac-proxy - pullPolicy: IfNotPresent - tag: v0.15.0 - -operator-crds: - create: true diff --git a/components/operator/internal/core/context.go b/components/operator/internal/core/context.go deleted file mode 100644 index 98f9b7c8aa..0000000000 --- a/components/operator/internal/core/context.go +++ /dev/null @@ -1,46 +0,0 @@ -package core - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type Context interface { - context.Context - GetClient() client.Client - GetScheme() *runtime.Scheme - GetAPIReader() client.Reader - GetPlatform() Platform -} - -type defaultContext struct { - context.Context - mgr Manager -} - -func (d defaultContext) GetAPIReader() client.Reader { - return d.mgr.GetAPIReader() -} - -func (d defaultContext) GetPlatform() Platform { - return d.mgr.GetPlatform() -} - -func (d defaultContext) GetClient() client.Client { - return d.mgr.GetClient() -} - -func (d defaultContext) GetScheme() *runtime.Scheme { - return d.mgr.GetScheme() -} - -var _ Context = &defaultContext{} - -func NewContext(mgr Manager, ctx context.Context) *defaultContext { - return &defaultContext{ - Context: ctx, - mgr: mgr, - } -} diff --git a/components/operator/internal/core/controllers.go b/components/operator/internal/core/controllers.go deleted file mode 100644 index aff88f292f..0000000000 --- a/components/operator/internal/core/controllers.go +++ /dev/null @@ -1,184 +0,0 @@ -package core - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/pkg/errors" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/log" -) - -type ObjectController[T client.Object] func(ctx Context, reconcilerOptions *ReconcilerOptions[T], req T) error - -func ForObjectController[T v1beta1.Object](controller ObjectController[T]) ObjectController[T] { - return func(ctx Context, reconcilerOptions *ReconcilerOptions[T], object T) error { - setStatus := func(err error) { - if err != nil { - object.SetReady(false) - object.SetError(err.Error()) - } else { - object.SetReady(true) - object.SetError("Up to date") - } - } - - var reconcilerError error - err := controller(ctx, reconcilerOptions, object) - if err != nil { - setStatus(err) - if !IsApplicationError(err) { - reconcilerError = err - } - } else { - for _, condition := range *object.GetConditions() { - if condition.ObservedGeneration != object.GetGeneration() { - continue - } - - if condition.Status != metav1.ConditionTrue { - str := condition.Type - if condition.Reason != "" { - str += "/" + condition.Reason - } - - setStatus(NewPendingError().WithMessage("pending condition: " + str)) - return nil - } - } - setStatus(nil) - } - - return reconcilerError - } -} - -type StackDependentObjectController[T v1beta1.Dependent] func(ctx Context, stack *v1beta1.Stack, reconcilerOptions *ReconcilerOptions[T], req T) error - -func ForStackDependency[T v1beta1.Dependent](ctrl StackDependentObjectController[T], allowDeleted bool) ObjectController[T] { - return func(ctx Context, reconcilerOptions *ReconcilerOptions[T], t T) error { - stack := &v1beta1.Stack{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: t.GetStack(), - }, stack); err != nil { - if apierrors.IsNotFound(err) { - return NewStackNotFoundError() - } else { - return err - } - } else { - if stack.GetAnnotations()[v1beta1.SkipLabel] == "true" { - t.GetConditions(). - AppendOrReplace(v1beta1.Condition{ - Type: "ReconciledWithStack", - Status: metav1.ConditionTrue, - ObservedGeneration: stack.GetGeneration(), - LastTransitionTime: metav1.Now(), - Message: "Reconciled with stack specification", - Reason: "Skipped", - }, v1beta1.ConditionTypeMatch("ReconciledWithStack")) - return nil - } - } - - if !allowDeleted { - if !stack.GetDeletionTimestamp().IsZero() { - return NewStackNotFoundError() - } - } - - return ctrl(ctx, stack, reconcilerOptions, t) - } -} - -type ModuleController[T v1beta1.Module] func(ctx Context, stack *v1beta1.Stack, reconcilerOptions *ReconcilerOptions[T], req T, version string) error - -func ForModule[T v1beta1.Module](underlyingController ModuleController[T]) StackDependentObjectController[T] { - return func(ctx Context, stack *v1beta1.Stack, reconcilerOptions *ReconcilerOptions[T], t T) error { - - moduleVersion, err := GetModuleVersion(ctx, stack, t) - if err != nil { - return err - } - - hasOwnerReference, err := HasOwnerReference(ctx, stack, t) - if err != nil { - return err - } - - if !hasOwnerReference { - patch := client.MergeFrom(t.DeepCopyObject().(T)) - if err := controllerutil.SetOwnerReference(stack, t, ctx.GetScheme()); err != nil { - return err - } - if err := ctx.GetClient().Patch(ctx, t, patch); err != nil { - return errors.Wrap(err, "patching object to add owner reference on stack") - } - log.FromContext(ctx).Info("Add owner reference on stack") - } - - if stack.Spec.Disabled { - // notes(gfyrag): When disabling a stack, we remove all owned objects for modules. - // Owned objects must be controlled by the module. - // if not, they will not be automatically removed on stack removal. - // resources objects (like Database and BrokerTopic) are not removed since we could re-enable the stack later. - if err := removeAllModulesOwnedObjects(ctx, t, reconcilerOptions.Owns); err != nil { - return err - } - } else { - err = underlyingController(ctx, stack, reconcilerOptions, t, moduleVersion) - if err != nil { - return err - } - } - - t.GetConditions().AppendOrReplace(v1beta1.Condition{ - Type: "ReconciledWithStack", - Status: metav1.ConditionTrue, - ObservedGeneration: stack.GetGeneration(), - LastTransitionTime: metav1.Now(), - Message: "Reconciled with stack specification", - Reason: "Spec", - }, v1beta1.ConditionTypeMatch("ReconciledWithStack")) - - return nil - } -} - -func removeAllModulesOwnedObjects(ctx Context, owner client.Object, owns map[client.Object][]builder.OwnsOption) error { - for object := range owns { - if _, ok := object.(v1beta1.Resource); ok { - // Resources must not be deleted - continue - } - - gvk, err := apiutil.GVKForObject(object, ctx.GetScheme()) - if err != nil { - return err - } - - list := &unstructured.UnstructuredList{} - list.SetGroupVersionKind(gvk) - if err := ctx.GetClient().List(ctx, list); err != nil { - return err - } - - for _, item := range list.Items { - hasControllerReference, err := HasControllerReference(ctx, owner, &item) - if err != nil { - return err - } - if hasControllerReference { - if err := ctx.GetClient().Delete(ctx, &item); err != nil { - return err - } - } - } - } - return nil -} diff --git a/components/operator/internal/core/env.go b/components/operator/internal/core/env.go deleted file mode 100644 index 3411190234..0000000000 --- a/components/operator/internal/core/env.go +++ /dev/null @@ -1,84 +0,0 @@ -package core - -import ( - "fmt" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - corev1 "k8s.io/api/core/v1" -) - -func Env(name string, value string) corev1.EnvVar { - return corev1.EnvVar{ - Name: name, - Value: value, - } -} - -func EnvFromBool(name string, vb bool) corev1.EnvVar { - value := "true" - if !vb { - value = "false" - } - return Env(name, value) -} - -func EnvFromConfig(name, configName, key string) corev1.EnvVar { - return corev1.EnvVar{ - Name: name, - ValueFrom: &corev1.EnvVarSource{ - ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ - Key: key, - LocalObjectReference: corev1.LocalObjectReference{ - Name: configName, - }, - }, - }, - } -} - -func EnvFromSecret(name, secretName, key string) corev1.EnvVar { - return corev1.EnvVar{ - Name: name, - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - Key: key, - LocalObjectReference: corev1.LocalObjectReference{ - Name: secretName, - }, - }, - }, - } -} - -func EnvVarPlaceholder(key string) string { - return fmt.Sprintf("$(%s)", key) -} - -func ComputeEnvVar(format string, keys ...string) string { - return fmt.Sprintf(format, - collectionutils.Map(keys, func(key string) any { - return EnvVarPlaceholder(key) - })..., - ) -} - -// TODO: The stack reconciler can create a config map container env var for dev and debug -// This way, we avoid the need to fetch the stack object at each reconciliation loop -func GetDevEnvVars(stack *v1beta1.Stack, service interface { - IsDebug() bool - IsDev() bool -}) []corev1.EnvVar { - return GetDevEnvVarsWithPrefix(stack, service, "") -} - -func GetDevEnvVarsWithPrefix(stack *v1beta1.Stack, service interface { - IsDebug() bool - IsDev() bool -}, prefix string) []corev1.EnvVar { - return []corev1.EnvVar{ - EnvFromBool(fmt.Sprintf("%sDEBUG", prefix), stack.Spec.Debug || service.IsDebug()), - EnvFromBool(fmt.Sprintf("%sDEV", prefix), stack.Spec.Dev || service.IsDev()), - Env(fmt.Sprintf("%sSTACK", prefix), stack.Name), - } -} diff --git a/components/operator/internal/core/errors.go b/components/operator/internal/core/errors.go deleted file mode 100644 index 97bff2b82a..0000000000 --- a/components/operator/internal/core/errors.go +++ /dev/null @@ -1,45 +0,0 @@ -package core - -import ( - "fmt" - - "github.com/pkg/errors" -) - -type ApplicationError struct { - message string -} - -func (e *ApplicationError) Error() string { - return e.message -} - -func (e *ApplicationError) Is(err error) bool { - _, ok := err.(*ApplicationError) - return ok -} - -func (e *ApplicationError) WithMessage(msg string, args ...any) *ApplicationError { - e.message = fmt.Sprintf(msg, args...) - return e -} - -func NewApplicationError() *ApplicationError { - return &ApplicationError{} -} - -func NewStackNotFoundError() *ApplicationError { - return NewApplicationError().WithMessage("stack not found") -} - -func NewPendingError() *ApplicationError { - return NewApplicationError().WithMessage("pending") -} - -func NewMissingSettingsError(msg string) *ApplicationError { - return NewApplicationError().WithMessage(msg) -} - -func IsApplicationError(err error) bool { - return errors.Is(err, &ApplicationError{}) -} diff --git a/components/operator/internal/core/manager.go b/components/operator/internal/core/manager.go deleted file mode 100644 index 449646be04..0000000000 --- a/components/operator/internal/core/manager.go +++ /dev/null @@ -1,28 +0,0 @@ -package core - -import ( - ctrl "sigs.k8s.io/controller-runtime" -) - -type Manager interface { - ctrl.Manager - GetPlatform() Platform -} - -type defaultManager struct { - ctrl.Manager - platform Platform -} - -func (d defaultManager) GetPlatform() Platform { - return d.platform -} - -var _ Manager = (*defaultManager)(nil) - -func NewDefaultManager(m ctrl.Manager, platform Platform) *defaultManager { - return &defaultManager{ - Manager: m, - platform: platform, - } -} diff --git a/components/operator/internal/core/module.go b/components/operator/internal/core/module.go deleted file mode 100644 index 0972f0841b..0000000000 --- a/components/operator/internal/core/module.go +++ /dev/null @@ -1,14 +0,0 @@ -package core - -import ( - "github.com/iancoleman/strcase" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func LowerCamelCaseKind(ctx Context, ob client.Object) string { - kinds, _, err := ctx.GetScheme().ObjectKinds(ob) - if err != nil { - panic(err) - } - return strcase.ToLowerCamel(kinds[0].Kind) -} diff --git a/components/operator/internal/core/names.go b/components/operator/internal/core/names.go deleted file mode 100644 index 365231c333..0000000000 --- a/components/operator/internal/core/names.go +++ /dev/null @@ -1,24 +0,0 @@ -package core - -import ( - "fmt" - - "k8s.io/apimachinery/pkg/types" -) - -func GetObjectName(stack, name string) string { - return fmt.Sprintf("%s-%s", stack, name) -} - -func GetNamespacedResourceName(namespace, name string) types.NamespacedName { - return types.NamespacedName{ - Namespace: namespace, - Name: name, - } -} - -func GetResourceName(name string) types.NamespacedName { - return types.NamespacedName{ - Name: name, - } -} diff --git a/components/operator/internal/core/ns.go b/components/operator/internal/core/ns.go deleted file mode 100644 index b0923376aa..0000000000 --- a/components/operator/internal/core/ns.go +++ /dev/null @@ -1,25 +0,0 @@ -package core - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -func WithTemporaryNamespace(ctx Context, name string, callback func() error) error { - ns, _, err := CreateOrUpdate[*v1.Namespace](ctx, types.NamespacedName{ - Name: name, - }) - if err != nil { - return err - } - - if err := callback(); err != nil { - return err - } - - if err := ctx.GetClient().Delete(ctx, ns); err != nil { - return err - } - - return nil -} diff --git a/components/operator/internal/core/platform.go b/components/operator/internal/core/platform.go deleted file mode 100644 index f11c498b65..0000000000 --- a/components/operator/internal/core/platform.go +++ /dev/null @@ -1,13 +0,0 @@ -package core - -type Platform struct { - // Cloud region where the stack is deployed - Region string - // Cloud environment where the stack is deployed: staging, production, - // sandbox, etc. - Environment string - // The licence information - LicenceSecret string - // The operator utils image version - UtilsVersion string -} diff --git a/components/operator/internal/core/publisher.go b/components/operator/internal/core/publisher.go deleted file mode 100644 index 11fc809b0c..0000000000 --- a/components/operator/internal/core/publisher.go +++ /dev/null @@ -1,37 +0,0 @@ -package core - -import ( - "reflect" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func ListEventPublishers(ctx Context, stackName string) ([]unstructured.Unstructured, error) { - ret := make([]unstructured.Unstructured, 0) - for gvk, rtype := range ctx.GetScheme().AllKnownTypes() { - object, ok := reflect.New(rtype).Interface().(client.Object) - if !ok { - continue - } - - if _, ok := object.(v1beta1.EventPublisher); ok { - us := &unstructured.UnstructuredList{} - us.SetGroupVersionKind(gvk) - - if err := ctx.GetClient().List(ctx, us, client.MatchingFields{ - "stack": stackName, - }); err != nil { - return nil, err - } - - for _, item := range us.Items { - item.SetGroupVersionKind(gvk) - ret = append(ret, item) - } - } - } - - return ret, nil -} diff --git a/components/operator/internal/core/reconciler.go b/components/operator/internal/core/reconciler.go deleted file mode 100644 index 21686c68e0..0000000000 --- a/components/operator/internal/core/reconciler.go +++ /dev/null @@ -1,489 +0,0 @@ -package core - -import ( - "context" - "fmt" - "reflect" - "strings" - "time" - - "sigs.k8s.io/controller-runtime/pkg/log" - - "github.com/pkg/errors" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - - "k8s.io/client-go/util/workqueue" - - . "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/predicate" - - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func MapObjectToReconcileRequests[T client.Object](items ...T) []reconcile.Request { - return Map(items, func(object T) reconcile.Request { - return reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: object.GetName(), - Namespace: object.GetNamespace(), - }, - } - }) -} - -type Initializer func(mgr Manager) error - -var initializers = make([]Initializer, 0) - -func Init(i ...Initializer) { - initializers = append(initializers, i...) -} - -type ReconcilerOptionsWatch struct { - Handler func(mgr Manager, builder *builder.Builder, target client.Object) (handler.EventHandler, []builder.WatchesOption) -} - -type Finalizer[T client.Object] func(ctx Context, t T) error - -type finalizerConfig[T client.Object] struct { - name string - fn Finalizer[T] -} - -type ReconcilerOptions[T client.Object] struct { - Owns map[client.Object][]builder.OwnsOption - Watchers map[client.Object]ReconcilerOptionsWatch - Finalizers []finalizerConfig[T] - Raws []func(Context, *builder.Builder) error -} - -type ReconcilerOption[T client.Object] func(*ReconcilerOptions[T]) - -func WithOwn[T client.Object](v client.Object, opts ...builder.OwnsOption) ReconcilerOption[T] { - return func(options *ReconcilerOptions[T]) { - options.Owns[v] = opts - } -} - -func WithRaw[T client.Object](fn func(Context, *builder.Builder) error) ReconcilerOption[T] { - return func(options *ReconcilerOptions[T]) { - options.Raws = append(options.Raws, fn) - } -} - -func BuildReconcileRequests(ctx context.Context, client client.Client, scheme *runtime.Scheme, target client.Object, opts ...client.ListOption) []reconcile.Request { - kinds, _, err := scheme.ObjectKinds(target) - if err != nil { - return []reconcile.Request{} - } - - us := &unstructured.UnstructuredList{} - us.SetGroupVersionKind(kinds[0]) - if err := client.List(ctx, us, opts...); err != nil { - return []reconcile.Request{} - } - - return MapObjectToReconcileRequests( - Map(us.Items, ToPointer[unstructured.Unstructured])..., - ) -} - -func WithFinalizer[T client.Object](name string, callback Finalizer[T]) ReconcilerOption[T] { - return func(r *ReconcilerOptions[T]) { - r.Finalizers = append(r.Finalizers, finalizerConfig[T]{ - name: name, - fn: callback, - }) - } -} - -func WithWatchSettings[T client.Object]() ReconcilerOption[T] { - return func(options *ReconcilerOptions[T]) { - options.Watchers[&v1beta1.Settings{}] = ReconcilerOptionsWatch{ - Handler: func(mgr Manager, builder *builder.Builder, target client.Object) (handler.EventHandler, []builder.WatchesOption) { - return handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, object client.Object) []reconcile.Request { - settings := object.(*v1beta1.Settings) - - ret := make([]reconcile.Request, 0) - if !settings.IsWildcard() { - for _, stack := range settings.GetStacks() { - ret = append(ret, BuildReconcileRequests(ctx, mgr.GetClient(), mgr.GetScheme(), target, client.MatchingFields{ - "stack": stack, - })...) - } - } else { - ret = append(ret, BuildReconcileRequests(ctx, mgr.GetClient(), mgr.GetScheme(), target)...) - } - - return ret - }), nil - }, - } - } -} - -func WithWatchDependency[T client.Object](t v1beta1.Dependent) ReconcilerOption[T] { - return func(options *ReconcilerOptions[T]) { - options.Watchers[t] = ReconcilerOptionsWatch{ - Handler: func(mgr Manager, builder *builder.Builder, target client.Object) (handler.EventHandler, []builder.WatchesOption) { - return handler.EnqueueRequestsFromMapFunc(WatchDependents(mgr, target)), nil - }, - } - } -} - -func WithWatchStack[T client.Object]() ReconcilerOption[T] { - return func(options *ReconcilerOptions[T]) { - options.Watchers[&v1beta1.Stack{}] = ReconcilerOptionsWatch{ - Handler: func(mgr Manager, b *builder.Builder, target client.Object) (handler.EventHandler, []builder.WatchesOption) { - return handler.EnqueueRequestsFromMapFunc(Watch(mgr, target)), []builder.WatchesOption{ - builder.WithPredicates(predicate.Or( - predicate.GenerationChangedPredicate{}, - predicate.AnnotationChangedPredicate{}, - )), - } - }, - } - } -} - -func WithWatch[T client.Object, WATCHED client.Object](fn func(ctx Context, object WATCHED) []reconcile.Request) ReconcilerOption[T] { - var watched WATCHED - watched = reflect.New(reflect.TypeOf(watched).Elem()).Interface().(WATCHED) - return func(options *ReconcilerOptions[T]) { - options.Watchers[watched] = ReconcilerOptionsWatch{ - Handler: func(mgr Manager, b *builder.Builder, target client.Object) (handler.EventHandler, []builder.WatchesOption) { - return handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, object client.Object) []reconcile.Request { - return fn(NewContext(mgr, ctx), object.(WATCHED)) - }), []builder.WatchesOption{} - }, - } - } -} - -func withReconciler[T client.Object](controller ObjectController[T], opts ...ReconcilerOption[T]) Initializer { - return func(mgr Manager) error { - - options := ReconcilerOptions[T]{ - Owns: map[client.Object][]builder.OwnsOption{}, - Watchers: map[client.Object]ReconcilerOptionsWatch{}, - } - for _, opt := range opts { - opt(&options) - } - - var t T - t = reflect.New(reflect.TypeOf(t).Elem()).Interface().(T) - b := ctrl.NewControllerManagedBy(mgr). - For(t, builder.WithPredicates(predicate.Or( - predicate.GenerationChangedPredicate{}, - predicate.Funcs{ - CreateFunc: func(event event.CreateEvent) bool { - return true - }, - DeleteFunc: func(deleteEvent event.DeleteEvent) bool { - return true - }, - UpdateFunc: func(updateEvent event.UpdateEvent) bool { - l: - for _, referenceFromNew := range updateEvent.ObjectNew.GetOwnerReferences() { - for _, referenceFromOld := range updateEvent.ObjectOld.GetOwnerReferences() { - if referenceFromNew.UID == referenceFromOld.UID { - continue l - } - } - return true - } - - return len(updateEvent.ObjectOld.GetOwnerReferences()) != len(updateEvent.ObjectNew.GetOwnerReferences()) - }, - GenericFunc: func(genericEvent event.GenericEvent) bool { - return true - }, - }, - ))) - - for object, ownsOptions := range options.Owns { - b = b.Owns(object, ownsOptions...) - } - for object, watch := range options.Watchers { - h, options := watch.Handler(mgr, b, t) - b = b.Watches(object, h, options...) - } - for _, raw := range options.Raws { - if err := raw(NewContext(mgr, context.Background()), b); err != nil { - return err - } - } - - return b.Complete(reconcile.Func(reconcileObject(mgr, controller, options))) - } -} - -func WithReconciler[T client.Object](controller func(ctx Context, req T) error, opts ...ReconcilerOption[T]) Initializer { - return withReconciler(func(ctx Context, reconcilerOptions *ReconcilerOptions[T], req T) error { - return controller(ctx, req) - }, opts...) -} - -func reconcileObject[T client.Object](mgr Manager, controller ObjectController[T], reconcilerOptions ReconcilerOptions[T]) func(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { - return func(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { - - var object T - object = reflect.New(reflect.TypeOf(object).Elem()).Interface().(T) - if err := mgr.GetClient().Get(ctx, types.NamespacedName{ - Name: request.Name, - }, object); err != nil { - if apierrors.IsNotFound(err) { - return ctrl.Result{}, nil - } - return ctrl.Result{}, err - } - - objectFinalizers := object.GetFinalizers() - l: - for _, existingFinalizer := range objectFinalizers { - for expectedFinalizer := range reconcilerOptions.Finalizers { - if expectedFinalizer == expectedFinalizer { - continue l - } - } - controllerutil.RemoveFinalizer(object, existingFinalizer) - } - if len(objectFinalizers) != len(object.GetFinalizers()) { - if err := mgr.GetClient().Update(ctx, object); err != nil { - if apierrors.IsConflict(err) { - log.FromContext(ctx).Info(fmt.Sprintf("Catching conflict error: %s", err)) - return reconcile.Result{RequeueAfter: time.Second}, nil - } - return reconcile.Result{}, errors.Wrapf(err, "patching resource to update finalizers") - } - } - - reconcileContext := NewContext(mgr, ctx) - if !object.GetDeletionTimestamp().IsZero() { - log.FromContext(ctx).Info("Resource " + request.Name + " deleted, calling finalizers...") - for _, f := range reconcilerOptions.Finalizers { - - if !Contains(object.GetFinalizers(), f.name) { - continue - } - - if err := f.fn(reconcileContext, object); err != nil { - if IsApplicationError(err) { - log.FromContext(ctx).Info(fmt.Sprintf("Finalizer respond with error: %s", err)) - if setError, ok := any(object).(interface { - SetError(string) - }); ok { - setError.SetError(err.Error()) - if err := mgr.GetClient().Status().Update(ctx, object); err != nil { - log.FromContext(ctx).Info(fmt.Sprintf("Catching error: %s", err)) - return reconcile.Result{}, errors.Wrapf(err, "patching resource to remove finalizer '%s'", f.name) - } - } - - return reconcile.Result{ - RequeueAfter: time.Second, - }, nil - } - return reconcile.Result{}, errors.Wrapf(err, "executing finalizer '%s'", f.name) - } - - if controllerutil.RemoveFinalizer(object, f.name) { - if err := mgr.GetClient().Update(ctx, object); err != nil { - if apierrors.IsConflict(err) { - log.FromContext(ctx).Info(fmt.Sprintf("Catching conflict error: %s", err)) - return reconcile.Result{RequeueAfter: time.Second}, nil - } - return reconcile.Result{}, errors.Wrapf(err, "patching resource to remove finalizer '%s'", f.name) - } - - log.FromContext(ctx).Info(fmt.Sprintf("Finalizer %s removed", f.name)) - } - } - log.FromContext(ctx).Info("All finalizers executed, can definitely delete the resource") - - return reconcile.Result{}, nil - } - - log.FromContext(ctx).Info("Reconcile " + request.Name) - missingFinalizers := make([]string, 0) - for _, f := range reconcilerOptions.Finalizers { - if !Contains(object.GetFinalizers(), f.name) { - missingFinalizers = append(missingFinalizers, f.name) - } - } - if len(missingFinalizers) > 0 { - log.FromContext(ctx).Info(fmt.Sprintf("Adding finalizers %s", missingFinalizers)) - patch := client.MergeFrom(object.DeepCopyObject().(T)) - finalizers := object.GetFinalizers() - finalizers = append(finalizers, missingFinalizers...) - object.SetFinalizers(finalizers) - - if err := mgr.GetClient().Patch(ctx, object, patch); err != nil { - return reconcile.Result{}, errors.Wrap(err, "patching missing finalizers") - } - } - - cp := object.DeepCopyObject().(T) - patch := client.MergeFrom(cp) - - var reconcilerError error - err := controller(reconcileContext, &reconcilerOptions, object) - if err != nil { - log.FromContext(ctx).Info(fmt.Sprintf("Terminated with error: %s", err)) - if !IsApplicationError(err) { - reconcilerError = errors.Wrap(err, "reconciling resource") - } - } - - if err := mgr.GetClient().Status().Patch(ctx, object, patch); err != nil { - if apierrors.IsNotFound(err) { - // Ignore resource deleted - return ctrl.Result{}, nil - } - return ctrl.Result{}, errors.Wrap(err, "patching resource to update status") - } - - if apierrors.IsConflict(reconcilerError) { - return ctrl.Result{ - Requeue: true, - }, nil - } - - return ctrl.Result{}, reconcilerError - } -} - -func withStdReconciler[T v1beta1.Object](ctrl ObjectController[T], opts ...ReconcilerOption[T]) Initializer { - return withReconciler(ForObjectController(ctrl), opts...) -} - -func WithStdReconciler[T v1beta1.Object](ctrl func(ctx Context, req T) error, opts ...ReconcilerOption[T]) Initializer { - return withStdReconciler(func(ctx Context, reconcilerOptions *ReconcilerOptions[T], req T) error { - return ctrl(ctx, req) - }, opts...) -} - -func withStackDependencyReconciler[T v1beta1.Dependent](fn ObjectController[T], opts ...ReconcilerOption[T]) Initializer { - opts = append(opts, WithWatchStack[T]()) - return withStdReconciler(fn, opts...) -} - -func WithStackDependencyReconciler[T v1beta1.Dependent](fn func(ctx Context, stack *v1beta1.Stack, req T) error, opts ...ReconcilerOption[T]) Initializer { - return withStackDependencyReconciler( - ForStackDependency(func(ctx Context, stack *v1beta1.Stack, reconcilerOptions *ReconcilerOptions[T], req T) error { - return fn(ctx, stack, req) - }, false), - opts...) -} - -func WithResourceReconciler[T v1beta1.Dependent](fn func(ctx Context, stack *v1beta1.Stack, req T) error, opts ...ReconcilerOption[T]) Initializer { - return withStackDependencyReconciler( - ForStackDependency(func(ctx Context, stack *v1beta1.Stack, reconcilerOptions *ReconcilerOptions[T], req T) error { - return fn(ctx, stack, req) - }, true), - opts...) -} - -func WithModuleReconciler[T v1beta1.Module](fn func(ctx Context, stack *v1beta1.Stack, req T, version string) error, opts ...ReconcilerOption[T]) Initializer { - opts = append(opts, WithWatchVersions[T]) - return withStackDependencyReconciler( - ForStackDependency( - ForModule(func(ctx Context, stack *v1beta1.Stack, reconcilerOptions *ReconcilerOptions[T], req T, version string) error { - return fn(ctx, stack, req, version) - }), - false, - ), - opts...) -} - -func WithWatchVersions[T client.Object](options *ReconcilerOptions[T]) { - - reconcileModule := func(ctx context.Context, mgr Manager, target client.Object, versionFileName string, limitingInterface workqueue.RateLimitingInterface) { - stackList := &v1beta1.StackList{} - if err := mgr.GetClient().List(ctx, stackList, client.MatchingFields{ - ".spec.versionsFromFile": versionFileName, - }); err != nil { - panic(err) - } - - kinds, _, err := mgr.GetScheme().ObjectKinds(target) - if err != nil { - panic(err) - } - - for _, stack := range stackList.Items { - list := &unstructured.UnstructuredList{} - list.SetGroupVersionKind(kinds[0]) - if err := mgr.GetClient().List(ctx, list, client.MatchingFields{ - "stack": stack.Name, - }); err != nil { - panic(err) - } - - for _, item := range list.Items { - limitingInterface.Add(reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: item.GetName(), - }, - }) - } - } - } - - options.Watchers[&v1beta1.Versions{}] = ReconcilerOptionsWatch{ - Handler: func(mgr Manager, builder *builder.Builder, target client.Object) (handler.EventHandler, []builder.WatchesOption) { - return handler.Funcs{ - CreateFunc: func(ctx context.Context, createEvent event.CreateEvent, limitingInterface workqueue.RateLimitingInterface) { - reconcileModule(ctx, mgr, target, createEvent.Object.GetName(), limitingInterface) - }, - UpdateFunc: func(ctx context.Context, updateEvent event.UpdateEvent, limitingInterface workqueue.RateLimitingInterface) { - oldObject := updateEvent.ObjectOld.(*v1beta1.Versions) - newObject := updateEvent.ObjectNew.(*v1beta1.Versions) - - kinds, _, err := mgr.GetScheme().ObjectKinds(target) - if err != nil { - panic(err) - } - kind := strings.ToLower(kinds[0].Kind) - if oldObject.Spec[kind] == newObject.Spec[kind] { - return - } - - reconcileModule(ctx, mgr, target, updateEvent.ObjectNew.GetName(), limitingInterface) - }, - DeleteFunc: func(ctx context.Context, deleteEvent event.DeleteEvent, limitingInterface workqueue.RateLimitingInterface) { - reconcileModule(ctx, mgr, target, deleteEvent.Object.GetName(), limitingInterface) - }, - }, nil - }, - } -} - -func WithIndex[T client.Object](name string, eval func(t T) []string) Initializer { - return func(mgr Manager) error { - var t T - t = reflect.New(reflect.TypeOf(t).Elem()).Interface().(T) - return mgr.GetFieldIndexer(). - IndexField(context.Background(), t, name, func(rawObj client.Object) []string { - return eval(rawObj.(T)) - }) - } -} - -func WithSimpleIndex[T client.Object](name string, eval func(t T) string) Initializer { - return WithIndex(name, func(t T) []string { - return []string{eval(t)} - }) -} diff --git a/components/operator/internal/core/setup.go b/components/operator/internal/core/setup.go deleted file mode 100644 index 8271f00bda..0000000000 --- a/components/operator/internal/core/setup.go +++ /dev/null @@ -1,109 +0,0 @@ -package core - -import ( - "context" - "reflect" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func Setup(mgr ctrl.Manager, platform Platform) error { - - if err := indexStackDependentsObjects(mgr); err != nil { - return err - } - - if err := indexSettings(mgr); err != nil { - return err - } - - wrappedMgr := NewDefaultManager(mgr, platform) - for _, initializer := range initializers { - if err := initializer(wrappedMgr); err != nil { - return err - } - } - - return nil -} - -// indexStackDependentsObjects automatically add an index on `stack` property for all stack dependents objects -func indexStackDependentsObjects(mgr ctrl.Manager) error { - for _, rtype := range mgr.GetScheme().AllKnownTypes() { - - object, ok := reflect.New(rtype).Interface().(client.Object) - if !ok { - continue - } - - _, ok = object.(v1beta1.Dependent) - if !ok { - continue - } - - mgr.GetLogger().Info("Detect stack dependency object, automatically index field", "type", rtype) - if err := mgr.GetFieldIndexer(). - IndexField(context.Background(), object, "stack", func(object client.Object) []string { - return []string{object.(v1beta1.Dependent).GetStack()} - }); err != nil { - mgr.GetLogger().Error(err, "indexing stack field", "type", rtype) - return err - } - - kinds, _, err := mgr.GetScheme().ObjectKinds(object) - if err != nil { - return err - } - us := &unstructured.Unstructured{} - us.SetGroupVersionKind(kinds[0]) - if err := mgr.GetFieldIndexer(). - IndexField(context.Background(), us, "stack", func(object client.Object) []string { - stack := object.(*unstructured.Unstructured).Object["spec"].(map[string]any)["stack"] - if stack == nil { - return []string{} - } - return []string{stack.(string)} - }); err != nil { - mgr.GetLogger().Error(err, "indexing stack field", "type", &unstructured.Unstructured{}) - return err - } - } - return nil -} - -func indexSettings(mgr ctrl.Manager) error { - if err := mgr.GetFieldIndexer(). - IndexField(context.Background(), &v1beta1.Settings{}, "stack", func(object client.Object) []string { - return object.(*v1beta1.Settings).GetStacks() - }); err != nil { - mgr.GetLogger().Error(err, "indexing stack field", "type", &v1beta1.Settings{}) - return err - } - - kinds, _, err := mgr.GetScheme().ObjectKinds(&v1beta1.Settings{}) - if err != nil { - return err - } - us := &unstructured.Unstructured{} - us.SetGroupVersionKind(kinds[0]) - if err := mgr.GetFieldIndexer(). - IndexField(context.Background(), us, "stack", func(object client.Object) []string { - u := object.(*unstructured.Unstructured) - spec := u.UnstructuredContent()["spec"].(map[string]any) - if stacks, ok := spec["stacks"]; !ok { - return []string{} - } else { - return collectionutils.Map(stacks.([]any), func(v any) string { - return v.(string) - }) - } - }); err != nil { - mgr.GetLogger().Error(err, "indexing stack field", "type", &unstructured.Unstructured{}) - return err - } - return nil -} diff --git a/components/operator/internal/core/shell.go b/components/operator/internal/core/shell.go deleted file mode 100644 index 8dcdc245b4..0000000000 --- a/components/operator/internal/core/shell.go +++ /dev/null @@ -1,12 +0,0 @@ -package core - -import "fmt" - -func ShellScript(cmd string, args ...any) []string { - return []string{"sh", "-c", - fmt.Sprintf(`/bin/sh <<'EOF' - set -x - `+cmd+` - -EOF`, args...)} -} diff --git a/components/operator/internal/core/stacks.go b/components/operator/internal/core/stacks.go deleted file mode 100644 index f9e848bb19..0000000000 --- a/components/operator/internal/core/stacks.go +++ /dev/null @@ -1,91 +0,0 @@ -package core - -import ( - "reflect" - - "github.com/pkg/errors" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -var ( - ErrNotFound = errors.New("no configuration found") - ErrMultipleInstancesFound = errors.New("multiple resources found") -) - -func GetAllStackDependencies(ctx Context, stackName string, to any) error { - slice := reflect.Indirect(reflect.ValueOf(to)).Interface() - objectType := reflect.TypeOf(slice).Elem() - - kinds, _, err := ctx.GetScheme().ObjectKinds(reflect.New(objectType.Elem()).Interface().(client.Object)) - if err != nil { - return err - } - - list := &unstructured.UnstructuredList{} - list.SetGroupVersionKind(kinds[0]) - - err = ctx.GetClient().List(ctx, list, client.MatchingFields{ - "stack": stackName, - }) - if err != nil { - return err - } - - ret := reflect.ValueOf(slice) - for _, item := range list.Items { - t := reflect.New(objectType.Elem()).Interface().(client.Object) - if err := runtime.DefaultUnstructuredConverter.FromUnstructured(item.Object, t); err != nil { - panic(err) - } - ret = reflect.Append(ret, reflect.ValueOf(t)) - } - - reflect.ValueOf(to).Elem().Set(ret) - - return nil -} - -func GetSingleDependency(ctx Context, stackName string, to client.Object) error { - - slice := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(to)), 0, 0).Interface() - err := GetAllStackDependencies(ctx, stackName, &slice) - if err != nil { - return err - } - - switch reflect.ValueOf(slice).Len() { - case 0: - return ErrNotFound - case 1: - reflect.Indirect(reflect.ValueOf(to)).Set(reflect.ValueOf(slice).Index(0).Elem()) - return nil - default: - return ErrMultipleInstancesFound - } -} - -func HasDependency(ctx Context, stackName string, to client.Object) (bool, error) { - err := GetSingleDependency(ctx, stackName, to) - if err != nil && !errors.Is(err, ErrMultipleInstancesFound) { - switch { - default: - return false, err - case errors.Is(err, ErrNotFound): - return false, nil - } - } - return true, nil -} - -func GetIfExists(ctx Context, stackName string, to client.Object) (bool, error) { - err := GetSingleDependency(ctx, stackName, to) - if err != nil && !errors.Is(err, ErrNotFound) { - return false, err - } - if errors.Is(err, ErrNotFound) { - return false, nil - } - return true, nil -} diff --git a/components/operator/internal/core/utils.go b/components/operator/internal/core/utils.go deleted file mode 100644 index 99c7385b1c..0000000000 --- a/components/operator/internal/core/utils.go +++ /dev/null @@ -1,186 +0,0 @@ -package core - -import ( - "bytes" - "crypto/sha256" - "encoding/base64" - "encoding/json" - "io/fs" - "path/filepath" - "reflect" - "strings" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - "github.com/formancehq/go-libs/pointer" - "k8s.io/apimachinery/pkg/api/equality" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - - corev1 "k8s.io/api/core/v1" -) - -func HashFromConfigMaps(configMaps ...*corev1.ConfigMap) string { - digest := sha256.New() - for _, configMap := range configMaps { - if err := json.NewEncoder(digest).Encode(configMap.Data); err != nil { - panic(err) - } - } - return base64.StdEncoding.EncodeToString(digest.Sum(nil)) -} - -func HashFromResources(resources ...*unstructured.Unstructured) string { - buf := bytes.NewBufferString("") - for _, resource := range resources { - buf.WriteString(string(resource.GetUID())) - buf.WriteString(resource.GetResourceVersion()) - } - digest := sha256.New() - digest.Write(buf.Bytes()) - - return base64.StdEncoding.EncodeToString(digest.Sum(nil)) -} - -func CopyDir(f fs.FS, root, path string, ret *map[string]string) { - dirEntries, err := fs.ReadDir(f, path) - if err != nil { - panic(err) - } - for _, dirEntry := range dirEntries { - dirEntryPath := filepath.Join(path, dirEntry.Name()) - if dirEntry.IsDir() { - CopyDir(f, root, dirEntryPath, ret) - } else { - fileContent, err := fs.ReadFile(f, dirEntryPath) - if err != nil { - panic(err) - } - sanitizedPath := strings.TrimPrefix(dirEntryPath, root) - sanitizedPath = strings.TrimPrefix(sanitizedPath, "/") - (*ret)[sanitizedPath] = string(fileContent) - } - } -} - -type ObjectMutator[T any] func(t T) error - -func WithController[T client.Object](scheme *runtime.Scheme, owner client.Object) ObjectMutator[T] { - return func(t T) error { - if !metav1.IsControlledBy(t, owner) { - if err := controllerutil.SetControllerReference(owner, t, scheme); err != nil { - return err - } - } - return nil - } -} - -func WithOwner[T client.Object](scheme *runtime.Scheme, owner client.Object) ObjectMutator[T] { - return func(t T) error { - if err := controllerutil.SetOwnerReference(owner, t, scheme); err != nil { - panic(err) - } - - return nil - } -} - -func WithAnnotations[T client.Object](newAnnotations map[string]string) ObjectMutator[T] { - return func(t T) error { - annotations := t.GetAnnotations() - if annotations == nil { - annotations = make(map[string]string) - } - for k, v := range newAnnotations { - annotations[k] = v - } - t.SetAnnotations(annotations) - - return nil - } -} - -func WithLabels[T client.Object](newLabels map[string]string) ObjectMutator[T] { - return func(t T) error { - annotations := t.GetLabels() - if annotations == nil { - annotations = make(map[string]string) - } - for k, v := range newLabels { - annotations[k] = v - } - t.SetLabels(annotations) - - return nil - } -} - -func CreateOrUpdate[T client.Object](ctx Context, - key types.NamespacedName, mutators ...ObjectMutator[T]) (T, controllerutil.OperationResult, error) { - - var ret T - ret = reflect.New(reflect.TypeOf(ret).Elem()).Interface().(T) - ret.SetNamespace(key.Namespace) - ret.SetName(key.Name) - operationResult, err := controllerutil.CreateOrUpdate(ctx, ctx.GetClient(), ret, func() error { - for _, mutate := range mutators { - if err := mutate(ret); err != nil { - return err - } - } - return nil - }) - return ret, operationResult, err -} - -func DeleteIfExists[T client.Object](ctx Context, name types.NamespacedName) error { - var t T - t = reflect.New(reflect.TypeOf(t).Elem()).Interface().(T) - if err := ctx.GetClient().Get(ctx, name, t); err != nil { - if client.IgnoreNotFound(err) == nil { - return nil - } - return err - } - return ctx.GetClient().Delete(ctx, t) -} - -func hasOwnerReference(ctx Context, owner client.Object, object client.Object, controller, blockOwnerDeletion bool) (bool, error) { - kinds, _, err := ctx.GetScheme().ObjectKinds(owner) - if err != nil { - return false, nil - } - expectedOwnerReference := metav1.OwnerReference{ - APIVersion: kinds[0].GroupVersion().String(), - Kind: kinds[0].Kind, - Name: owner.GetName(), - UID: owner.GetUID(), - } - if controller { - expectedOwnerReference.Controller = pointer.For(true) - } - if blockOwnerDeletion { - expectedOwnerReference.BlockOwnerDeletion = pointer.For(true) - } - - for _, reference := range object.GetOwnerReferences() { - if equality.Semantic.DeepDerivative(expectedOwnerReference, reference) { - return true, nil - } - } - - return false, nil -} - -func HasControllerReference(ctx Context, owner client.Object, object client.Object) (bool, error) { - return hasOwnerReference(ctx, owner, object, true, true) -} - -func HasOwnerReference(ctx Context, owner client.Object, object client.Object) (bool, error) { - return hasOwnerReference(ctx, owner, object, false, false) -} diff --git a/components/operator/internal/core/version.go b/components/operator/internal/core/version.go deleted file mode 100644 index 28aa0a08ae..0000000000 --- a/components/operator/internal/core/version.go +++ /dev/null @@ -1,62 +0,0 @@ -package core - -import ( - "strings" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "golang.org/x/mod/semver" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func GetModuleVersion(ctx Context, stack *v1beta1.Stack, module v1beta1.Module) (string, error) { - if module.GetVersion() != "" { - return module.GetVersion(), nil - } - if stack.Spec.Version != "" { - return stack.Spec.Version, nil - } - if stack.Spec.VersionsFromFile != "" { - versions := &v1beta1.Versions{} - err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: stack.Spec.VersionsFromFile, - }, versions) - if client.IgnoreNotFound(err) != nil { - return "", err - } - if err == nil { - kinds, _, err := ctx.GetScheme().ObjectKinds(module) - if err != nil { - return "", err - } - kind := strings.ToLower(kinds[0].Kind) - - version, ok := versions.Spec[kind] - if ok && version != "" { - return version, nil - } - } - } - - return "latest", nil -} - -func IsGreaterOrEqual(version string, than string) bool { - if !semver.IsValid(than) { - return !semver.IsValid(version) // Any semver version is considered lower - } - if !semver.IsValid(version) { - return true - } - return semver.Compare(version, than) >= 0 -} - -func IsLower(version string, than string) bool { - if !semver.IsValid(than) { - return semver.IsValid(version) // Any semver version is considered higher - } - if !semver.IsValid(version) { - return false - } - return semver.Compare(version, than) < 0 -} diff --git a/components/operator/internal/core/volumes.go b/components/operator/internal/core/volumes.go deleted file mode 100644 index d14b1aa3cb..0000000000 --- a/components/operator/internal/core/volumes.go +++ /dev/null @@ -1,26 +0,0 @@ -package core - -import ( - corev1 "k8s.io/api/core/v1" -) - -func NewVolumeFromConfigMap(name string, configMap *corev1.ConfigMap) corev1.Volume { - return corev1.Volume{ - Name: name, - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: configMap.Name, - }, - }, - }, - } -} - -func NewVolumeMount(name, mountPath string, readOnly bool) corev1.VolumeMount { - return corev1.VolumeMount{ - Name: name, - ReadOnly: readOnly, - MountPath: mountPath, - } -} diff --git a/components/operator/internal/core/watch.go b/components/operator/internal/core/watch.go deleted file mode 100644 index 43a25cd0db..0000000000 --- a/components/operator/internal/core/watch.go +++ /dev/null @@ -1,52 +0,0 @@ -package core - -import ( - "context" - "reflect" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func WatchDependents(mgr Manager, t client.Object) func(ctx context.Context, object client.Object) []reconcile.Request { - return func(ctx context.Context, object client.Object) []reconcile.Request { - - slice := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(t)), 0, 0).Interface() - - err := GetAllStackDependencies( - NewContext(mgr, ctx), - object.(v1beta1.Dependent).GetStack(), &slice) - if err != nil { - return nil - } - - objects := make([]client.Object, 0) - for i := 0; i < reflect.ValueOf(slice).Len(); i++ { - objects = append(objects, reflect.ValueOf(slice).Index(i).Interface().(client.Object)) - } - - return MapObjectToReconcileRequests(objects...) - } -} - -func Watch(mgr Manager, t client.Object) func(ctx context.Context, object client.Object) []reconcile.Request { - return func(ctx context.Context, object client.Object) []reconcile.Request { - - slice := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(t)), 0, 0).Interface() - - err := GetAllStackDependencies( - NewContext(mgr, ctx), - object.(*v1beta1.Stack).Name, &slice) - if err != nil { - return nil - } - - objects := make([]client.Object, 0) - for i := 0; i < reflect.ValueOf(slice).Len(); i++ { - objects = append(objects, reflect.ValueOf(slice).Index(i).Interface().(client.Object)) - } - - return MapObjectToReconcileRequests(objects...) - } -} diff --git a/components/operator/internal/resources/all.go b/components/operator/internal/resources/all.go deleted file mode 100644 index 81e38697da..0000000000 --- a/components/operator/internal/resources/all.go +++ /dev/null @@ -1,25 +0,0 @@ -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" - _ "github.com/formancehq/operator/internal/resources/benthosstreams" - _ "github.com/formancehq/operator/internal/resources/brokers" - _ "github.com/formancehq/operator/internal/resources/brokertopics" - _ "github.com/formancehq/operator/internal/resources/databases" - _ "github.com/formancehq/operator/internal/resources/gatewayhttpapis" - _ "github.com/formancehq/operator/internal/resources/gateways" - _ "github.com/formancehq/operator/internal/resources/ledgers" - _ "github.com/formancehq/operator/internal/resources/orchestrations" - _ "github.com/formancehq/operator/internal/resources/payments" - _ "github.com/formancehq/operator/internal/resources/reconciliations" - _ "github.com/formancehq/operator/internal/resources/resourcereferences" - _ "github.com/formancehq/operator/internal/resources/searches" - _ "github.com/formancehq/operator/internal/resources/settings" - _ "github.com/formancehq/operator/internal/resources/stacks" - _ "github.com/formancehq/operator/internal/resources/stargates" - _ "github.com/formancehq/operator/internal/resources/wallets" - _ "github.com/formancehq/operator/internal/resources/webhooks" -) diff --git a/components/operator/internal/resources/analytics/init.go b/components/operator/internal/resources/analytics/init.go deleted file mode 100644 index 118e4a2cd8..0000000000 --- a/components/operator/internal/resources/analytics/init.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -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/applications/application.go b/components/operator/internal/resources/applications/application.go deleted file mode 100644 index 39544f9b5a..0000000000 --- a/components/operator/internal/resources/applications/application.go +++ /dev/null @@ -1,377 +0,0 @@ -package applications - -import ( - "fmt" - - "github.com/formancehq/operator/internal/resources/licence" - "github.com/formancehq/operator/internal/resources/settings" - v1 "k8s.io/api/policy/v1" - "k8s.io/apimachinery/pkg/util/intstr" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/formancehq/go-libs/pointer" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/stoewer/go-strcase" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" -) - -func checkStatus(deployment *appsv1.Deployment) (bool, string) { - if deployment.Status.ObservedGeneration != deployment.Generation { - return false, fmt.Sprintf("Generation not matching, generation: %d, observed: %d)", - deployment.Generation, deployment.Status.ObservedGeneration) - } - if deployment.Spec.Replicas != nil && deployment.Status.UpdatedReplicas < *deployment.Spec.Replicas { - return false, fmt.Sprintf("waiting for deployment %q rollout to finish: %d out of %d new replicas have been updated", - deployment.Name, deployment.Status.UpdatedReplicas, *deployment.Spec.Replicas) - } - if deployment.Status.Replicas > deployment.Status.UpdatedReplicas { - return false, fmt.Sprintf("waiting for deployment %q rollout to finish: %d old replicas are pending termination", - deployment.Name, deployment.Status.Replicas-deployment.Status.UpdatedReplicas) - } - if deployment.Status.AvailableReplicas < deployment.Status.UpdatedReplicas { - return false, fmt.Sprintf("waiting for deployment %q rollout to finish: %d of %d updated replicas are available", - deployment.Name, deployment.Status.AvailableReplicas, deployment.Status.UpdatedReplicas) - } - - return true, "deployment is ready" -} - -func mergeResourceRequirements(dest, src corev1.ResourceRequirements) corev1.ResourceRequirements { - if dest.Limits == nil { - dest.Limits = src.Limits - } - if dest.Requests == nil { - dest.Requests = src.Requests - } - if dest.Claims == nil { - dest.Claims = src.Claims - } - return dest -} - -type runAs struct { - User *int64 `json:"user"` - Group *int64 `json:"group"` -} - -func configureSecurityContext(container *corev1.Container, runAs *runAs) { - if container.SecurityContext == nil { - container.SecurityContext = &corev1.SecurityContext{} - } - if container.SecurityContext.Capabilities == nil { - container.SecurityContext.Capabilities = &corev1.Capabilities{} - } - if container.SecurityContext.Capabilities.Drop == nil { - container.SecurityContext.Capabilities.Drop = []corev1.Capability{"all"} - } - if container.SecurityContext.Privileged == nil { - container.SecurityContext.Privileged = pointer.For(false) - } - if container.SecurityContext.ReadOnlyRootFilesystem == nil { - container.SecurityContext.ReadOnlyRootFilesystem = pointer.For(true) - } - if container.SecurityContext.AllowPrivilegeEscalation == nil { - container.SecurityContext.AllowPrivilegeEscalation = pointer.For(false) - } - if container.SecurityContext.RunAsUser == nil && runAs != nil && runAs.User != nil { - container.SecurityContext.RunAsUser = runAs.User - } - if container.SecurityContext.RunAsGroup == nil && runAs != nil && runAs.Group != nil { - container.SecurityContext.RunAsGroup = runAs.Group - } - if container.SecurityContext.RunAsNonRoot == nil { - container.SecurityContext.RunAsNonRoot = pointer.For(runAs.User != nil || runAs.Group != nil) - } -} - -type Application struct { - stateful bool - isEE bool - owner v1beta1.Dependent - deploymentTpl *appsv1.Deployment -} - -func (a Application) Stateful() Application { - return a.WithStateful(true) -} - -func (a Application) WithStateful(v bool) Application { - a.stateful = v - return a -} - -func (a Application) IsEE() Application { - return a.WithEE(true) -} - -func (a Application) WithEE(v bool) Application { - a.isEE = v - return a -} - -func (a Application) Install(ctx core.Context) error { - deploymentLabels := map[string]string{ - "app.kubernetes.io/name": a.deploymentTpl.Name, - } - - err := a.handleDeployment(ctx, deploymentLabels) - if err != nil { - return err - } - - return a.handlePDB(ctx, deploymentLabels) -} - -func (a Application) handleDeployment(ctx core.Context, deploymentLabels map[string]string) error { - condition := v1beta1.Condition{ - Type: "DeploymentReady", - ObservedGeneration: a.owner.GetGeneration(), - LastTransitionTime: metav1.Now(), - Reason: strcase.UpperCamelCase(a.deploymentTpl.Name), - } - defer func() { - a.owner.GetConditions().AppendOrReplace(condition, v1beta1.AndConditions( - v1beta1.ConditionTypeMatch("DeploymentReady"), - v1beta1.ConditionReasonMatch(strcase.UpperCamelCase(a.deploymentTpl.Name)), - )) - }() - - mutators := make([]core.ObjectMutator[*appsv1.Deployment], 0) - mutators = append(mutators, func(deployment *appsv1.Deployment) error { - a.deploymentTpl.Spec.DeepCopyInto(&deployment.Spec) - deployment.SetName(a.deploymentTpl.Name) - deployment.SetNamespace(a.owner.GetStack()) - - // Configure matching labels - deployment.Spec.Selector = &metav1.LabelSelector{ - MatchLabels: deploymentLabels, - } - deployment.Spec.Template.Labels = deploymentLabels - - // Configure security context - deployment.Spec.Template.Spec.SecurityContext = &corev1.PodSecurityContext{ - RunAsNonRoot: pointer.For(true), - SeccompProfile: &corev1.SeccompProfile{ - Type: corev1.SeccompProfileTypeRuntimeDefault, - }, - } - - for ind, container := range deployment.Spec.Template.Spec.InitContainers { - resourceRequirements, err := settings.GetResourceRequirements(ctx, a.owner.GetStack(), - "deployments", deployment.Name, "init-containers", container.Name, "resource-requirements") - if err != nil { - return err - } - container.Resources = mergeResourceRequirements(container.Resources, *resourceRequirements) - - runAs, err := settings.GetAs[runAs](ctx, a.owner.GetStack(), - "deployments", deployment.Name, "init-containers", container.Name, "run-as") - if err != nil { - return err - } - - configureSecurityContext(&container, runAs) - deployment.Spec.Template.Spec.InitContainers[ind] = container - } - for ind, container := range deployment.Spec.Template.Spec.Containers { - resourceRequirements, err := settings.GetResourceRequirements(ctx, a.owner.GetStack(), - "deployments", deployment.Name, "containers", container.Name, "resource-requirements") - if err != nil { - return err - } - container.Resources = mergeResourceRequirements(container.Resources, *resourceRequirements) - - runAs, err := settings.GetAs[runAs](ctx, a.owner.GetStack(), - "deployments", deployment.Name, "containers", container.Name, "run-as") - if err != nil { - return err - } - - configureSecurityContext(&container, runAs) - deployment.Spec.Template.Spec.Containers[ind] = container - } - - return nil - }) - - if !a.stateful { - mutators = append(mutators, - func(t *appsv1.Deployment) error { - replicas, err := settings.GetInt32(ctx, a.owner.GetStack(), "deployments", a.deploymentTpl.Name, "replicas") - if err != nil { - return err - } - t.Spec.Replicas = replicas - return nil - }) - } else { - mutators = append(mutators, - func(t *appsv1.Deployment) error { - t.Spec.Strategy = appsv1.DeploymentStrategy{ - Type: appsv1.RecreateDeploymentStrategyType, - } - return nil - }) - } - - if a.isEE { - licenceSecretResourceRef, licenceEnv, err := licence.GetLicenceEnvVars(ctx, a.deploymentTpl.Name, a.owner) - if err != nil { - return err - } - if len(licenceEnv) > 0 { - mutators = append(mutators, func(t *appsv1.Deployment) error { - for i, container := range t.Spec.Template.Spec.InitContainers { - container.Env = append(container.Env, licenceEnv...) - t.Spec.Template.Spec.InitContainers[i] = container - } - for i, container := range t.Spec.Template.Spec.Containers { - container.Env = append(container.Env, licenceEnv...) - t.Spec.Template.Spec.Containers[i] = container - } - if licenceSecretResourceRef != nil { - if t.Spec.Template.Annotations == nil { - t.Spec.Template.Annotations = map[string]string{} - } - t.Spec.Template.Annotations["licence-secret-hash"] = licenceSecretResourceRef.Status.Hash - } - - return nil - }) - } - } - - mutators = append(mutators, core.WithController[*appsv1.Deployment](ctx.GetScheme(), a.owner)) - - isJsonLogging, err := settings.GetBoolOrFalse(ctx, a.owner.GetStack(), "logging", "json") - if err != nil { - return err - } - if isJsonLogging { - mutators = append(mutators, func(t *appsv1.Deployment) error { - v := corev1.EnvVar{ - Name: "JSON_FORMATTING_LOGGER", - Value: "true", - } - for i, container := range t.Spec.Template.Spec.InitContainers { - container.Env = append(container.Env, v) - t.Spec.Template.Spec.InitContainers[i] = container - } - for i, container := range t.Spec.Template.Spec.Containers { - container.Env = append(container.Env, v) - t.Spec.Template.Spec.Containers[i] = container - } - - return nil - }) - } - - deployment, _, err := core.CreateOrUpdate[*appsv1.Deployment](ctx, types.NamespacedName{ - Namespace: a.owner.GetStack(), - Name: a.deploymentTpl.Name, - }, mutators...) - if err != nil { - condition.Message = err.Error() - condition.Status = metav1.ConditionFalse - return err - } - - ready, message := checkStatus(deployment) - condition.Message = message - if !ready { - condition.Status = metav1.ConditionFalse - } else { - condition.Status = metav1.ConditionTrue - } - - return nil -} - -type podDisruptionBudgetConfiguration struct { - MinAvailable string `json:"minAvailable"` - MaxUnavailable string `json:"maxUnavailable"` -} - -func (a Application) handlePDB(ctx core.Context, deploymentLabels map[string]string) error { - podDisruptionBudgetCondition := v1beta1.NewCondition("PodDisruptionBudget", a.owner.GetGeneration()). - SetReason(strcase.UpperCamelCase(a.deploymentTpl.Name)) - defer func() { - a.owner.GetConditions().AppendOrReplace(*podDisruptionBudgetCondition, v1beta1.AndConditions( - v1beta1.ConditionTypeMatch("PodDisruptionBudget"), - v1beta1.ConditionReasonMatch(strcase.UpperCamelCase(a.deploymentTpl.Name)), - )) - }() - if !a.stateful { - - pdb, err := settings.GetAs[podDisruptionBudgetConfiguration](ctx, a.owner.GetStack(), "deployments", a.deploymentTpl.Name, "pod-disruption-budget") - if err != nil { - return err - } - - if pdb.MinAvailable != "" || pdb.MaxUnavailable != "" { - podDisruptionBudgetConfiguredCondition := v1beta1.NewCondition("PodDisruptionBudgetConfigured", a.owner.GetGeneration()). - SetReason(strcase.UpperCamelCase(a.deploymentTpl.Name)) - - defer func() { - a.owner.GetConditions().AppendOrReplace(*podDisruptionBudgetConfiguredCondition, v1beta1.AndConditions( - v1beta1.ConditionTypeMatch("PodDisruptionBudgetConfigured"), - v1beta1.ConditionReasonMatch(strcase.UpperCamelCase(a.deploymentTpl.Name)), - )) - }() - - _, _, err = core.CreateOrUpdate(ctx, types.NamespacedName{ - Namespace: a.owner.GetStack(), - Name: a.deploymentTpl.Name, - }, func(t *v1.PodDisruptionBudget) error { - if pdb.MinAvailable != "" { - t.Spec.MinAvailable = pointer.For(intstr.Parse(pdb.MinAvailable)) - } - if pdb.MaxUnavailable != "" { - t.Spec.MaxUnavailable = pointer.For(intstr.Parse(pdb.MaxUnavailable)) - } - t.Spec.Selector = &metav1.LabelSelector{ - MatchLabels: deploymentLabels, - } - return nil - }, - core.WithController[*v1.PodDisruptionBudget](ctx.GetScheme(), a.owner), - ) - if err != nil { - podDisruptionBudgetConfiguredCondition.SetStatus(metav1.ConditionFalse).SetMessage(err.Error()) - return err - } - } else { - if err := a.deletePDBIfExists(ctx); err != nil { - return err - } - podDisruptionBudgetCondition.SetMessage("no PDB found") - } - } else { - if err := a.deletePDBIfExists(ctx); err != nil { - return err - } - - podDisruptionBudgetCondition.SetMessage("application defined as stateful") - } - - return nil -} - -func (a Application) deletePDBIfExists(ctx core.Context) error { - pdb := &v1.PodDisruptionBudget{} - pdb.SetName(a.deploymentTpl.Name) - pdb.SetNamespace(a.owner.GetStack()) - - return client.IgnoreNotFound(ctx.GetClient().Delete(ctx, pdb)) -} - -func New(owner v1beta1.Dependent, deploymentTpl *appsv1.Deployment) *Application { - return &Application{ - owner: owner, - deploymentTpl: deploymentTpl, - } -} diff --git a/components/operator/internal/resources/applications/liveness.go b/components/operator/internal/resources/applications/liveness.go deleted file mode 100644 index f8d3555cc6..0000000000 --- a/components/operator/internal/resources/applications/liveness.go +++ /dev/null @@ -1,57 +0,0 @@ -package applications - -import ( - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/intstr" - "k8s.io/utils/pointer" -) - -func DefaultLiveness(port string, opts ...ProbeOpts) *corev1.Probe { - return liveness(newProbeHandler(port, opts...)) -} -func liveness(handler corev1.ProbeHandler) *corev1.Probe { - return &corev1.Probe{ - ProbeHandler: handler, - InitialDelaySeconds: 1, - TimeoutSeconds: 30, - PeriodSeconds: 2, - SuccessThreshold: 1, - FailureThreshold: 20, - TerminationGracePeriodSeconds: pointer.Int64(10), - } -} - -type ProbeOpts func(*corev1.ProbeHandler) *corev1.ProbeHandler - -func newProbeHandler(port string, opts ...ProbeOpts) corev1.ProbeHandler { - probe := corev1.ProbeHandler{ - HTTPGet: &corev1.HTTPGetAction{ - Port: intstr.FromString(port), - Scheme: "HTTP", - }, - } - - for _, opt := range append(defaultProbeOptions, opts...) { - opt(&probe) - } - - return probe -} - -var defaultProbeOptions = []ProbeOpts{ - WithProbePath("/_healthcheck"), -} - -func WithHost(host string) ProbeOpts { - return func(p *corev1.ProbeHandler) *corev1.ProbeHandler { - p.HTTPGet.Host = host - return p - } -} - -func WithProbePath(path string) ProbeOpts { - return func(p *corev1.ProbeHandler) *corev1.ProbeHandler { - p.HTTPGet.Path = path - return p - } -} diff --git a/components/operator/internal/resources/applications/ports.go b/components/operator/internal/resources/applications/ports.go deleted file mode 100644 index 93afa87699..0000000000 --- a/components/operator/internal/resources/applications/ports.go +++ /dev/null @@ -1,10 +0,0 @@ -package applications - -import v1 "k8s.io/api/core/v1" - -func StandardHTTPPort() v1.ContainerPort { - return v1.ContainerPort{ - Name: "http", - ContainerPort: 8080, - } -} diff --git a/components/operator/internal/resources/authclients/create.go b/components/operator/internal/resources/authclients/create.go deleted file mode 100644 index 3129e2fe2e..0000000000 --- a/components/operator/internal/resources/authclients/create.go +++ /dev/null @@ -1,51 +0,0 @@ -package authclients - -import ( - "fmt" - - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/google/uuid" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func Create(ctx core.Context, stack *v1beta1.Stack, owner client.Object, objectName string, options ...func(spec *v1beta1.AuthClientSpec)) (*v1beta1.AuthClient, error) { - authClient, _, err := core.CreateOrUpdate[*v1beta1.AuthClient](ctx, types.NamespacedName{ - Name: core.GetObjectName(stack.Name, objectName), - }, - func(t *v1beta1.AuthClient) error { - t.Spec.Stack = stack.Name - if t.Spec.ID == "" { - t.Spec.ID = uuid.NewString() - } - if t.Spec.Secret == "" { - t.Spec.Secret = uuid.NewString() - } - for _, option := range options { - option(&t.Spec) - } - - return nil - }, - core.WithController[*v1beta1.AuthClient](ctx.GetScheme(), owner), - ) - if err != nil { - return nil, err - } - return authClient, err -} - -func WithScopes(scopes ...string) func(client *v1beta1.AuthClientSpec) { - return func(clientSpec *v1beta1.AuthClientSpec) { - clientSpec.Scopes = scopes - } -} - -func GetEnvVars(authClient *v1beta1.AuthClient) []v1.EnvVar { - return []v1.EnvVar{ - core.EnvFromSecret("STACK_CLIENT_ID", fmt.Sprintf("auth-client-%s", authClient.Name), "id"), - core.EnvFromSecret("STACK_CLIENT_SECRET", fmt.Sprintf("auth-client-%s", authClient.Name), "secret"), - } -} diff --git a/components/operator/internal/resources/authclients/init.go b/components/operator/internal/resources/authclients/init.go deleted file mode 100644 index de0453524f..0000000000 --- a/components/operator/internal/resources/authclients/init.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -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 authclients - -import ( - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -//+kubebuilder:rbac:groups=formance.com,resources=authclients,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=authclients/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=authclients/finalizers,verbs=update - -func Reconcile(ctx Context, stack *v1beta1.Stack, authClient *v1beta1.AuthClient) error { - - _, _, err := CreateOrUpdate[*corev1.Secret](ctx, types.NamespacedName{ - Name: fmt.Sprintf("auth-client-%s", authClient.Name), - Namespace: stack.Name, - }, - func(t *corev1.Secret) error { - t.StringData = map[string]string{ - "id": authClient.Spec.ID, - "secret": authClient.Spec.Secret, - } - - return nil - }, - WithController[*corev1.Secret](ctx.GetScheme(), authClient), - ) - - return err -} - -func init() { - Init( - WithStackDependencyReconciler(Reconcile, - WithOwn[*v1beta1.AuthClient](&corev1.Secret{}), - ), - ) -} diff --git a/components/operator/internal/resources/auths/configuration.go b/components/operator/internal/resources/auths/configuration.go deleted file mode 100644 index 484a1b9aaf..0000000000 --- a/components/operator/internal/resources/auths/configuration.go +++ /dev/null @@ -1,46 +0,0 @@ -package auths - -import ( - "sort" - - . "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "gopkg.in/yaml.v3" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -func createConfiguration(ctx Context, stack *v1beta1.Stack, auth *v1beta1.Auth, items []*v1beta1.AuthClient) (*corev1.ConfigMap, error) { - - sort.Slice(items, func(i, j int) bool { - return items[i].Name < items[j].Name - }) - - yamlData, err := yaml.Marshal(struct { - Clients any `yaml:"clients"` - }{ - Clients: Map(items, func(from *v1beta1.AuthClient) any { - return from.Spec - }), - }) - if err != nil { - return nil, err - } - - cm, _, err := CreateOrUpdate[*corev1.ConfigMap](ctx, types.NamespacedName{ - Namespace: stack.Name, - Name: "auth-configuration", - }, func(t *corev1.ConfigMap) error { - t.Data = map[string]string{ - "config.yaml": string(yamlData), - } - - return nil - }, WithController[*corev1.ConfigMap](ctx.GetScheme(), auth)) - if err != nil { - return nil, err - } - - return cm, nil -} diff --git a/components/operator/internal/resources/auths/deployment.go b/components/operator/internal/resources/auths/deployment.go deleted file mode 100644 index 99f4d2936f..0000000000 --- a/components/operator/internal/resources/auths/deployment.go +++ /dev/null @@ -1,126 +0,0 @@ -package auths - -import ( - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/applications" - "github.com/formancehq/operator/internal/resources/databases" - "github.com/formancehq/operator/internal/resources/gateways" - "github.com/formancehq/operator/internal/resources/settings" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func createDeployment(ctx Context, stack *v1beta1.Stack, auth *v1beta1.Auth, database *v1beta1.Database, - configMap *corev1.ConfigMap, image string) error { - - env := make([]corev1.EnvVar, 0) - otlpEnv, err := settings.GetOTELEnvVars(ctx, stack.Name, LowerCamelCaseKind(ctx, auth)) - if err != nil { - return err - } - env = append(env, otlpEnv...) - - gatewayEnv, err := gateways.EnvVarsIfEnabled(ctx, stack.Name) - if err != nil { - return err - } - - postgresEnvVar, err := databases.GetPostgresEnvVars(ctx, stack, database) - if err != nil { - return err - } - - env = append(env, gatewayEnv...) - env = append(env, GetDevEnvVars(stack, auth)...) - env = append(env, postgresEnvVar...) - env = append(env, Env("CONFIG", "/config/config.yaml")) - - authUrl, err := getUrl(ctx, stack.Name) - if err != nil { - return err - } - env = append(env, Env("BASE_URL", authUrl)) - - if auth.Spec.SigningKey != "" && auth.Spec.SigningKeyFromSecret != nil { - return fmt.Errorf("cannot specify signing key using both .spec.signingKey and .spec.signingKeyFromSecret fields") - } - if auth.Spec.SigningKey != "" { - env = append(env, Env("SIGNING_KEY", auth.Spec.SigningKey)) - } - if auth.Spec.SigningKeyFromSecret != nil { - env = append(env, corev1.EnvVar{ - Name: "SIGNING_KEY", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: auth.Spec.SigningKeyFromSecret, - }, - }) - } - if auth.Spec.DelegatedOIDCServer != nil { - env = append(env, - Env("DELEGATED_CLIENT_SECRET", auth.Spec.DelegatedOIDCServer.ClientSecret), - Env("DELEGATED_CLIENT_ID", auth.Spec.DelegatedOIDCServer.ClientID), - Env("DELEGATED_ISSUER", auth.Spec.DelegatedOIDCServer.Issuer), - ) - } - if stack.Spec.Dev || auth.Spec.Dev { - env = append(env, Env("CAOS_OIDC_DEV", "1")) - } - - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - return applications. - New(auth, &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "auth", - }, - Spec: appsv1.DeploymentSpec{ - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: map[string]string{ - "config-hash": HashFromConfigMaps(configMap), - }, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{{ - Name: "auth", - Args: []string{"serve"}, - Env: env, - Image: image, - VolumeMounts: []corev1.VolumeMount{ - NewVolumeMount("config", "/config", true), - }, - Ports: []corev1.ContainerPort{applications.StandardHTTPPort()}, - LivenessProbe: applications.DefaultLiveness("http"), - }}, - Volumes: []corev1.Volume{ - NewVolumeFromConfigMap("config", configMap), - }, - ServiceAccountName: serviceAccountName, - }, - }, - }, - }). - IsEE(). - Install(ctx) -} - -func getUrl(ctx Context, stackName string) (string, error) { - gateway := &v1beta1.Gateway{} - ok, err := GetIfExists(ctx, stackName, gateway) - if err != nil { - return "", err - } - - if ok { - return gateways.URL(gateway) + "/api/auth", nil - } - - return "http://auth:8080", nil -} diff --git a/components/operator/internal/resources/auths/env.go b/components/operator/internal/resources/auths/env.go deleted file mode 100644 index 8239fa902c..0000000000 --- a/components/operator/internal/resources/auths/env.go +++ /dev/null @@ -1,53 +0,0 @@ -package auths - -import ( - "fmt" - "strconv" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - v1 "k8s.io/api/core/v1" -) - -func ProtectedEnvVars(ctx Context, stack *v1beta1.Stack, moduleName string, auth *v1beta1.AuthConfig) ([]v1.EnvVar, error) { - return ProtectedAPIEnvVarsWithPrefix(ctx, stack, moduleName, auth, "") -} - -func ProtectedAPIEnvVarsWithPrefix(ctx Context, stack *v1beta1.Stack, moduleName string, auth *v1beta1.AuthConfig, prefix string) ([]v1.EnvVar, error) { - ret := make([]v1.EnvVar, 0) - - hasAuth, err := HasDependency(ctx, stack.Name, &v1beta1.Auth{}) - if err != nil { - return nil, err - } - if !hasAuth { - return ret, nil - } - - url, err := getUrl(ctx, stack.Name) - if err != nil { - return nil, err - } - - ret = append(ret, - Env(fmt.Sprintf("%sAUTH_ENABLED", prefix), "true"), - Env(fmt.Sprintf("%sAUTH_ISSUER", prefix), url), - ) - - if auth != nil { - if auth.ReadKeySetMaxRetries != 0 { - ret = append(ret, - Env(fmt.Sprintf("%sAUTH_READ_KEY_SET_MAX_RETRIES", prefix), strconv.Itoa(auth.ReadKeySetMaxRetries)), - ) - } - - if auth.CheckScopes { - ret = append(ret, - Env(fmt.Sprintf("%sAUTH_CHECK_SCOPES", prefix), "true"), - Env(fmt.Sprintf("%sAUTH_SERVICE", prefix), moduleName), - ) - } - } - - return ret, nil -} diff --git a/components/operator/internal/resources/auths/init.go b/components/operator/internal/resources/auths/init.go deleted file mode 100644 index 4e0c9fd989..0000000000 --- a/components/operator/internal/resources/auths/init.go +++ /dev/null @@ -1,115 +0,0 @@ -/* -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 auths - -import ( - . "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/databases" - "github.com/formancehq/operator/internal/resources/gatewayhttpapis" - "github.com/formancehq/operator/internal/resources/jobs" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/settings" - "github.com/pkg/errors" - appsv1 "k8s.io/api/apps/v1" - batchv1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" -) - -//+kubebuilder:rbac:groups=formance.com,resources=auths,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=auths/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=auths/finalizers,verbs=update - -func Reconcile(ctx Context, stack *v1beta1.Stack, auth *v1beta1.Auth, version string) error { - - authClientList := make([]*v1beta1.AuthClient, 0) - err := GetAllStackDependencies(ctx, auth.Spec.Stack, &authClientList) - if err != nil { - return err - } - - configMap, err := createConfiguration(ctx, stack, auth, authClientList) - if err != nil { - return errors.Wrap(err, "creating configuration") - } - - database, err := databases.Create(ctx, stack, auth) - if err != nil { - return errors.Wrap(err, "creating database") - } - - if !database.Status.Ready { - return NewPendingError().WithMessage("database is not ready") - } - - image, err := registries.GetImage(ctx, stack, "auth", version) - if err != nil { - return errors.Wrap(err, "resolving image") - } - - if IsGreaterOrEqual(version, "v2.0.0-rc.5") && databases.GetSavedModuleVersion(database) != version { - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return errors.Wrap(err, "getting service account name") - } - - migrateContainer, err := databases.MigrateDatabaseContainer(ctx, stack, image, database) - if err != nil { - return errors.Wrap(err, "creating migrate container") - } - - if err := jobs.Handle(ctx, auth, "migrate", - migrateContainer, - jobs.WithServiceAccount(serviceAccountName), - ); err != nil { - return err - } - - if err := databases.SaveModuleVersion(ctx, database, version); err != nil { - return errors.Wrap(err, "saving module version in database object") - } - } - - if err := createDeployment(ctx, stack, auth, database, configMap, image); err != nil { - return errors.Wrap(err, "creating deployment") - } - - if err := gatewayhttpapis.Create(ctx, auth, gatewayhttpapis.WithHealthCheckEndpoint("_healthcheck"), gatewayhttpapis.WithRules(gatewayhttpapis.RuleUnsecured())); err != nil { - return errors.Wrap(err, "creating http api") - } - - auth.Status.Clients = Map(authClientList, (*v1beta1.AuthClient).GetName) - - return nil -} - -func init() { - Init( - WithModuleReconciler(Reconcile, - WithOwn[*v1beta1.Auth](&appsv1.Deployment{}), - WithOwn[*v1beta1.Auth](&v1beta1.GatewayHTTPAPI{}), - WithOwn[*v1beta1.Auth](&v1beta1.Database{}), - WithOwn[*v1beta1.Auth](&corev1.ConfigMap{}), - WithOwn[*v1beta1.Auth](&batchv1.Job{}), - WithOwn[*v1beta1.Auth](&v1beta1.ResourceReference{}), - WithWatchSettings[*v1beta1.Auth](), - WithWatchDependency[*v1beta1.Auth](&v1beta1.AuthClient{}), - databases.Watch[*v1beta1.Auth](), - ), - ) -} diff --git a/components/operator/internal/resources/benthos/controller.go b/components/operator/internal/resources/benthos/controller.go deleted file mode 100644 index 0382988e53..0000000000 --- a/components/operator/internal/resources/benthos/controller.go +++ /dev/null @@ -1,365 +0,0 @@ -package benthos - -import ( - "embed" - "fmt" - "sort" - - . "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/applications" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/resourcereferences" - benthosOperator "github.com/formancehq/operator/internal/resources/searches/benthos" - "github.com/formancehq/operator/internal/resources/services" - "github.com/formancehq/operator/internal/resources/settings" - "github.com/formancehq/search/benthos" - "github.com/pkg/errors" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -//+kubebuilder:rbac:groups=formance.com,resources=benthos,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=benthos/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=benthos/finalizers,verbs=update - -func Reconcile(ctx Context, stack *v1beta1.Stack, b *v1beta1.Benthos) error { - - if err := createDeployment(ctx, stack, b); err != nil { - return err - } - - if err := createService(ctx, b); err != nil { - return err - } - - return nil -} - -func createService(ctx Context, b *v1beta1.Benthos) error { - _, err := services.Create(ctx, b, "benthos", func(t *corev1.Service) error { - t.Labels = map[string]string{ - "app.kubernetes.io/service-name": "benthos", - } - t.Spec = corev1.ServiceSpec{ - Ports: []corev1.ServicePort{{ - Name: "http", - Port: 4195, - Protocol: "TCP", - TargetPort: intstr.FromString("http"), - }}, - Selector: map[string]string{ - "app.kubernetes.io/name": "benthos", - }, - } - - return nil - }) - return err -} - -// TODO(gfyrag): there is a ton of search related configuration -// We need to this controller and keep it focused on benthos -func createDeployment(ctx Context, stack *v1beta1.Stack, b *v1beta1.Benthos) error { - brokerURI, err := settings.RequireURL(ctx, stack.Name, "broker", "dsn") - if err != nil { - return errors.Wrap(err, "searching broker configuration") - } - - elasticSearchURI, err := settings.RequireURL(ctx, stack.Name, "elasticsearch", "dsn") - if err != nil { - return errors.Wrap(err, "searching elasticsearch configuration") - } - - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - awsIAMEnabled := serviceAccountName != "" - var resourceReference *v1beta1.ResourceReference - if secret := elasticSearchURI.Query().Get("secret"); !awsIAMEnabled && secret != "" { - resourceReference, err = resourcereferences.Create(ctx, b, "elasticsearch", secret, &corev1.Secret{}) - } else { - err = resourcereferences.Delete(ctx, b, "elasticsearch") - } - if err != nil { - return err - } - - broker := &v1beta1.Broker{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: stack.Name, - }, broker); err != nil { - return err - } - if !broker.Status.Ready { - return NewPendingError().WithMessage("broker not ready") - } - - var topicPrefix string - switch broker.Status.Mode { - case v1beta1.ModeOneStreamByService: - topicPrefix = b.Spec.Stack + "-" - case v1beta1.ModeOneStreamByStack: - topicPrefix = b.Spec.Stack + "." - } - - env := []corev1.EnvVar{ - Env("OPENSEARCH_URL", elasticSearchURI.WithoutQuery().String()), - Env("TOPIC_PREFIX", topicPrefix), - Env("OPENSEARCH_INDEX", "stacks"), - Env("STACK", b.Spec.Stack), - } - if awsIAMEnabled { - env = append(env, Env("AWS_IAM_ENABLED", "true")) - } - - if b.Spec.Batching != nil { - if b.Spec.Batching.Count != 0 { - env = append(env, Env("OPENSEARCH_BATCHING_COUNT", fmt.Sprint(b.Spec.Batching.Count))) - } - if b.Spec.Batching.Period != "" { - env = append(env, Env("OPENSEARCH_BATCHING_PERIOD", b.Spec.Batching.Period)) - } - } - - otelEnvVars, err := settings.GetOTELEnvVars(ctx, stack.Name, "benthos") - if err != nil { - return err - } - env = append(env, otelEnvVars...) - - if brokerURI.Scheme == "kafka" { - env = append(env, Env("KAFKA_ADDRESS", brokerURI.Host)) - if settings.IsTrue(brokerURI.Query().Get("tls")) { - env = append(env, Env("KAFKA_TLS_ENABLED", "true")) - } - if settings.IsTrue(brokerURI.Query().Get("saslEnabled")) { - env = append(env, - Env("KAFKA_SASL_USERNAME", brokerURI.Query().Get("saslUsername")), - Env("KAFKA_SASL_PASSWORD", brokerURI.Query().Get("saslPassword")), - Env("KAFKA_SASL_MECHANISM", brokerURI.Query().Get("saslMechanism")), - ) - } - } - if brokerURI.Scheme == "nats" { - env = append(env, Env("NATS_URL", brokerURI.Host)) - if broker.Status.Mode == v1beta1.ModeOneStreamByStack { - env = append(env, Env("NATS_BIND", "true")) - } - } - if secret := elasticSearchURI.Query().Get("secret"); elasticSearchURI.User != nil || secret != "" { - env = append(env, Env("BASIC_AUTH_ENABLED", "true")) - if secret == "" { - password, _ := brokerURI.User.Password() - env = append(env, - Env("BASIC_AUTH_USERNAME", brokerURI.User.Username()), - Env("BASIC_AUTH_PASSWORD", password), - ) - } else { - env = append(env, - EnvFromSecret("BASIC_AUTH_USERNAME", secret, "username"), - EnvFromSecret("BASIC_AUTH_PASSWORD", secret, "password"), - ) - } - } else { - // Even if basic auth is not enabled, we need to set the env vars - // to avoid benthos to crash due to linting errors - env = append(env, - Env("BASIC_AUTH_ENABLED", "false"), - Env("BASIC_AUTH_USERNAME", "username"), - Env("BASIC_AUTH_PASSWORD", "password"), - ) - } - - cmd := []string{ - "/benthos", - "-r", "/resources/*.yaml", - "-t", "/templates/*.yaml", - } - - openTelemetryEnabled, err := settings.HasOpenTelemetryTracesEnabled(ctx, stack.Name) - if err != nil { - return err - } - if openTelemetryEnabled { - cmd = append(cmd, "-c", "/global/config.yaml") - } - - cmd = append(cmd, "--log.level", "trace", "streams", "/streams/*.yaml") - - volumes := make([]corev1.Volume, 0) - volumeMounts := make([]corev1.VolumeMount, 0) - - type directory struct { - name string - fs embed.FS - } - - directories := []directory{ - { - name: "templates", - fs: benthos.Templates, - }, - { - name: "resources", - fs: benthos.Resources, - }, - } - if openTelemetryEnabled { - directories = append(directories, directory{ - name: "global", - fs: benthosOperator.Global, - }) - } - - if stack.Spec.EnableAudit { - directories = append(directories, directory{ - name: "audit", - fs: benthosOperator.Audit, - }) - } else { - kinds, _, err := ctx.GetScheme().ObjectKinds(&corev1.ConfigMap{}) - if err != nil { - return err - } - - object := &unstructured.Unstructured{} - object.SetGroupVersionKind(kinds[0]) - object.SetNamespace(stack.Name) - object.SetName("benthos-audit") - if err := client.IgnoreNotFound(ctx.GetClient().Delete(ctx, object)); err != nil { - return errors.Wrap(err, "deleting audit config map") - } - } - - configMaps := make([]*corev1.ConfigMap, 0) - - for _, x := range directories { - data := make(map[string]string) - - CopyDir(x.fs, x.name, x.name, &data) - - configMap, _, err := CreateOrUpdate[*corev1.ConfigMap](ctx, types.NamespacedName{ - Namespace: b.Spec.Stack, - Name: "benthos-" + x.name, - }, - func(t *corev1.ConfigMap) error { - t.Data = data - - return nil - }, - WithController[*corev1.ConfigMap](ctx.GetScheme(), b), - ) - if err != nil { - return err - } - - configMaps = append(configMaps, configMap) - - volumes = append(volumes, corev1.Volume{ - Name: x.name, - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "benthos-" + x.name, - }, - }, - }, - }) - volumeMounts = append(volumeMounts, corev1.VolumeMount{ - Name: x.name, - ReadOnly: true, - MountPath: "/" + x.name, - }) - } - - if stack.Spec.EnableAudit { - cmd = append(cmd, "/audit/gateway_audit.yaml") - } - - streamList := &v1beta1.BenthosStreamList{} - if err := ctx.GetClient().List(ctx, streamList, client.MatchingFields{ - "stack": b.Spec.Stack, - }); err != nil { - return err - } - - streams := streamList.Items - sort.Slice(streams, func(i, j int) bool { - return streams[i].Name < streams[j].Name - }) - - benthosImage, err := registries.GetBenthosImage(ctx, stack, "v4.23.1-es") - if err != nil { - return err - } - - podAnnotations := map[string]string{ - "config-hash": HashFromConfigMaps(configMaps...), - } - if resourceReference != nil { - podAnnotations["elasticsearch-secret-hash"] = resourceReference.Status.Hash - } - - return applications. - New(b, &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "benthos", - }, - Spec: appsv1.DeploymentSpec{ - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: podAnnotations, - }, - Spec: corev1.PodSpec{ - InitContainers: b.Spec.InitContainers, - Containers: []corev1.Container{{ - Name: "benthos", - Image: benthosImage, - Env: env, - Command: cmd, - Ports: []corev1.ContainerPort{{ - Name: "http", - ContainerPort: 4195, - }}, - VolumeMounts: append(volumeMounts, corev1.VolumeMount{ - Name: "streams", - ReadOnly: true, - MountPath: "/streams", - }), - }}, - Volumes: append(volumes, corev1.Volume{ - Name: "streams", - VolumeSource: corev1.VolumeSource{ - Projected: &corev1.ProjectedVolumeSource{ - Sources: Map(streams, func(stream v1beta1.BenthosStream) corev1.VolumeProjection { - return corev1.VolumeProjection{ - ConfigMap: &corev1.ConfigMapProjection{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: fmt.Sprintf("stream-%s", stream.Name), - }, - Items: []corev1.KeyToPath{{ - Key: "stream.yaml", - Path: stream.Spec.Name + ".yaml", - }}, - }, - } - }), - }, - }, - }), - ServiceAccountName: serviceAccountName, - }, - }, - }, - }). - Install(ctx) -} diff --git a/components/operator/internal/resources/benthos/init.go b/components/operator/internal/resources/benthos/init.go deleted file mode 100644 index 7da04697f5..0000000000 --- a/components/operator/internal/resources/benthos/init.go +++ /dev/null @@ -1,38 +0,0 @@ -/* -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 benthos - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/brokers" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" -) - -func init() { - Init( - WithStackDependencyReconciler(Reconcile, - WithWatchSettings[*v1beta1.Benthos](), - WithWatchDependency[*v1beta1.Benthos](&v1beta1.BenthosStream{}), - WithOwn[*v1beta1.Benthos](&corev1.ConfigMap{}), - WithOwn[*v1beta1.Benthos](&appsv1.Deployment{}), - WithOwn[*v1beta1.Benthos](&v1beta1.ResourceReference{}), - brokers.Watch[*v1beta1.Benthos](), - ), - ) -} diff --git a/components/operator/internal/resources/benthosstreams/create.go b/components/operator/internal/resources/benthosstreams/create.go deleted file mode 100644 index 9d2439e5d0..0000000000 --- a/components/operator/internal/resources/benthosstreams/create.go +++ /dev/null @@ -1,90 +0,0 @@ -package benthosstreams - -import ( - "embed" - "fmt" - - "github.com/formancehq/go-libs/collectionutils" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - - "strings" - - "github.com/pkg/errors" - "k8s.io/apimachinery/pkg/types" -) - -func LoadFromFileSystem(ctx Context, fs embed.FS, - owner v1beta1.Module, streamDirectory, discr string, opts ...ObjectMutator[*v1beta1.BenthosStream]) error { - streamFiles, err := fs.ReadDir(streamDirectory) - if err != nil { - return err - } - - search := &v1beta1.Search{} - hasSearch, err := HasDependency(ctx, owner.GetStack(), search) - if err != nil { - return err - } - - if hasSearch { - names := make([]string, 0) - for _, file := range streamFiles { - streamContent, err := fs.ReadFile(streamDirectory + "/" + file.Name()) - if err != nil { - return err - } - - sanitizedName := strings.ReplaceAll(file.Name(), "_", "-") - - opts = append(opts, - func(stream *v1beta1.BenthosStream) error { - stream.Spec.Data = string(streamContent) - stream.Spec.Stack = owner.GetStack() - stream.Spec.Name = strings.TrimSuffix(file.Name(), ".yaml") - - return nil - }, - WithLabels[*v1beta1.BenthosStream](map[string]string{ - "service": string(owner.GetUID()) + "-" + discr, - }), - WithController[*v1beta1.BenthosStream](ctx.GetScheme(), owner)) - - name := fmt.Sprintf("%s-%s", owner.GetStack(), sanitizedName) - _, _, err = CreateOrUpdate[*v1beta1.BenthosStream](ctx, types.NamespacedName{ - Name: name, - }, opts...) - if err != nil { - return errors.Wrap(err, "creating stream") - } - - names = append(names, name) - } - - // Clean potential orphan streams - l := &v1beta1.BenthosStreamList{} - if err := ctx.GetClient().List(ctx, l, client.MatchingLabels{ - "service": string(owner.GetUID()) + "-" + discr, - }); err != nil { - return err - } - - for _, stream := range l.Items { - if !collectionutils.Contains(names, stream.Name) { - if err := ctx.GetClient().Delete(ctx, &stream); err != nil { - return err - } - } - } - } else { - if err := ctx.GetClient().DeleteAllOf(ctx, &v1beta1.BenthosStream{}, client.MatchingLabels{ - "service": string(owner.GetUID()) + "-" + discr, - }); err != nil { - return err - } - } - - return nil -} diff --git a/components/operator/internal/resources/benthosstreams/init.go b/components/operator/internal/resources/benthosstreams/init.go deleted file mode 100644 index b95d9f0d2c..0000000000 --- a/components/operator/internal/resources/benthosstreams/init.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -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 benthosstreams - -import ( - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -//+kubebuilder:rbac:groups=formance.com,resources=benthosstreams,verbs=get;list;watch;create;update;patch;delete;deletecollection -//+kubebuilder:rbac:groups=formance.com,resources=benthosstreams/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=benthosstreams/finalizers,verbs=update - -func Reconcile(ctx Context, _ *v1beta1.Stack, stream *v1beta1.BenthosStream) error { - _, _, err := CreateOrUpdate[*corev1.ConfigMap](ctx, types.NamespacedName{ - Namespace: stream.Spec.Stack, - Name: fmt.Sprintf("stream-%s", stream.Name), - }, - WithController[*corev1.ConfigMap](ctx.GetScheme(), stream), - func(t *corev1.ConfigMap) error { - t.Data = map[string]string{ - "stream.yaml": stream.Spec.Data, - } - - return nil - }, - ) - if err != nil { - return err - } - - return err -} - -func init() { - Init( - WithStackDependencyReconciler(Reconcile, - WithOwn[*v1beta1.BenthosStream](&corev1.ConfigMap{}), - ), - ) -} diff --git a/components/operator/internal/resources/brokerconsumers/controller.go b/components/operator/internal/resources/brokerconsumers/controller.go deleted file mode 100644 index b3da4a7de5..0000000000 --- a/components/operator/internal/resources/brokerconsumers/controller.go +++ /dev/null @@ -1,281 +0,0 @@ -/* -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 brokerconsumers - -import ( - "fmt" - "strings" - - "github.com/formancehq/go-libs/collectionutils" - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/jobs" - "github.com/formancehq/operator/internal/resources/registries" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" -) - -const ( - ConditionTypeReady = "Ready" - ConditionTypeBrokerTopicCreated = "BrokerTopicCreated" - ConditionTypeNatsStackConsumerCreated = "NatsStackConsumerCreated" - ConditionTypeNatsServiceConsumerCreated = "NatsServiceConsumerCreated" -) - -//+kubebuilder:rbac:groups=formance.com,resources=brokerconsumers,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=brokerconsumers/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=brokerconsumers/finalizers,verbs=update - -func Reconcile(ctx core.Context, stack *v1beta1.Stack, consumer *v1beta1.BrokerConsumer) error { - - for _, service := range consumer.Spec.Services { - topic := &v1beta1.BrokerTopic{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: core.GetObjectName(consumer.Spec.Stack, service), - }, topic); err != nil { - if !errors.IsNotFound(err) { - return err - } - topic = &v1beta1.BrokerTopic{ - ObjectMeta: ctrl.ObjectMeta{ - Name: core.GetObjectName(consumer.Spec.Stack, service), - }, - Spec: v1beta1.BrokerTopicSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: consumer.Spec.Stack, - }, - Service: service, - }, - } - if err := controllerutil.SetOwnerReference(consumer, topic, ctx.GetScheme()); err != nil { - return err - } - - if err := controllerutil.SetOwnerReference(stack, topic, ctx.GetScheme()); err != nil { - return err - } - if err := ctx.GetClient().Create(ctx, topic); err != nil { - return err - } - return nil - } else { - patch := client.MergeFromWithOptions(topic.DeepCopy(), client.MergeFromWithOptimisticLock{}) - if err := controllerutil.SetOwnerReference(consumer, topic, ctx.GetScheme()); err != nil { - return err - } - if err := ctx.GetClient().Patch(ctx, topic, patch); err != nil { - return err - } - } - - if !topic.Status.Ready { - consumer.GetConditions().AppendOrReplace(v1beta1.Condition{ - Type: ConditionTypeReady, - Status: metav1.ConditionFalse, - ObservedGeneration: consumer.Generation, - LastTransitionTime: metav1.Now(), - Message: fmt.Sprintf("BrokerTopic %s not yet ready", topic.Name), - }, v1beta1.ConditionTypeMatch(ConditionTypeReady)) - consumer.GetConditions().AppendOrReplace(v1beta1.Condition{ - Type: ConditionTypeBrokerTopicCreated, - Status: metav1.ConditionFalse, - ObservedGeneration: consumer.Generation, - LastTransitionTime: metav1.Now(), - Message: fmt.Sprintf("BrokerTopic %s not yet ready", topic.Name), - }, v1beta1.ConditionTypeMatch(ConditionTypeBrokerTopicCreated)) - return core.NewPendingError() - } - } - - consumer.GetConditions().AppendOrReplace(v1beta1.Condition{ - Type: ConditionTypeBrokerTopicCreated, - Status: metav1.ConditionTrue, - ObservedGeneration: consumer.Generation, - LastTransitionTime: metav1.Now(), - Message: "All topics created", - }, v1beta1.ConditionTypeMatch(ConditionTypeBrokerTopicCreated)) - - broker := &v1beta1.Broker{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: stack.Name, - }, broker); err != nil { - return err - } - - if !broker.Status.Ready { - return core.NewPendingError().WithMessage("broker not ready") - } - - if broker.Status.URI.Scheme == "nats" { - switch broker.Status.Mode { - case v1beta1.ModeOneStreamByStack: - if !consumer.Status.Conditions.Check( - v1beta1.AndConditions( - v1beta1.ConditionTypeMatch(ConditionTypeNatsStackConsumerCreated), - v1beta1.ConditionGenerationMatch(consumer.Generation), - ), - ) { - if err := createStackNatsConsumer(ctx, stack, consumer, broker); err != nil { - return err - } - } - case v1beta1.ModeOneStreamByService: - for _, service := range consumer.Spec.Services { - if !consumer.Status.Conditions.Check( - v1beta1.AndConditions( - v1beta1.ConditionTypeMatch(ConditionTypeNatsServiceConsumerCreated), - v1beta1.ConditionGenerationMatch(consumer.Generation), - v1beta1.ConditionReasonMatch(service), - ), - ) { - if err := createServiceNatsConsumer(ctx, stack, consumer, broker, service); err != nil { - return err - } - } - } - } - } - - consumer.GetConditions().AppendOrReplace(v1beta1.Condition{ - Type: ConditionTypeReady, - Status: metav1.ConditionTrue, - ObservedGeneration: consumer.Generation, - LastTransitionTime: metav1.Now(), - Message: "Consumer completely configured", - }, v1beta1.ConditionTypeMatch(ConditionTypeReady)) - - return nil -} - -func createServiceNatsConsumer(ctx core.Context, stack *v1beta1.Stack, consumer *v1beta1.BrokerConsumer, broker *v1beta1.Broker, service string) error { - const script = ` - exists=$(nats consumer ls $STACK-$SERVICE -n | grep $NAME) - [[ -z "$exists" ]] || { - nats --server $NATS_URI consumer add $STACK-$SERVICE $NAME \ - --deliver-group $NAME \ - --deliver all \ - --max-pending 1024 \ - --ack explicit \ - --target $STACK-$NAME \ - --replay instant \ - --filter $STACK-$SERVICE \ - --defaults - }` - - natsBoxImage, err := registries.GetNatsBoxImage(ctx, stack, "0.14.1") - if err != nil { - return err - } - - err = jobs.Handle(ctx, consumer, "cc-"+service, corev1.Container{ - Image: natsBoxImage, - Name: "create-consumer", - Args: core.ShellScript(script), - Env: []corev1.EnvVar{ - core.Env("NATS_URI", fmt.Sprintf("nats://%s", broker.Status.URI.Host)), - core.Env("STACK", stack.Name), - core.Env("NAME", consumer.Spec.QueriedBy), - core.Env("SERVICE", service), - }, - }) - - condition := v1beta1.NewCondition(ConditionTypeNatsServiceConsumerCreated, consumer.Generation). - SetReason(service) - defer func() { - consumer.Status.Conditions.AppendOrReplace(*condition, v1beta1.AndConditions( - v1beta1.ConditionTypeMatch(ConditionTypeNatsServiceConsumerCreated), - v1beta1.ConditionReasonMatch(service), - )) - }() - - if err != nil { - condition.Fail(fmt.Sprintf("Error creating consumer on nats: %s", err)) - return err - } else { - condition.SetMessage("Nats consumer created") - } - return err -} - -func createStackNatsConsumer(ctx core.Context, stack *v1beta1.Stack, consumer *v1beta1.BrokerConsumer, broker *v1beta1.Broker) error { - const script = ` - filters="" - for f in $SUBJECTS; do - filters="$filters --filter $f" - done - nats --server $NATS_URI consumer add $STREAM $NAME \ - --deliver-group $DELIVER \ - --deliver all \ - --max-pending 1024 \ - --ack explicit \ - --target $STREAM-$NAME \ - --replay instant \ - --defaults $filters - ` - - natsBoxImage, err := registries.GetNatsBoxImage(ctx, stack, "0.14.1") - if err != nil { - return err - } - - consumerName := consumer.Spec.QueriedBy - if consumer.Spec.Name != "" { - consumerName += "_" + consumer.Spec.Name - } - - err = jobs.Handle(ctx, consumer, "create-consumer", corev1.Container{ - Image: natsBoxImage, - Name: "create-consumer", - Args: core.ShellScript(script), - Env: []corev1.EnvVar{ - core.Env("NATS_URI", fmt.Sprintf("nats://%s", broker.Status.URI.Host)), - core.Env("STREAM", stack.Name), - core.Env("NAME", consumerName), - core.Env("DELIVER", consumer.Spec.QueriedBy), - core.Env("SUBJECTS", strings.Join( - collectionutils.Map(consumer.Spec.Services, func(from string) string { - return fmt.Sprintf("%s.%s", stack.Name, from) - }), " ", - )), - }, - }) - if err != nil { - consumer.GetConditions().AppendOrReplace(v1beta1.Condition{ - Type: ConditionTypeNatsStackConsumerCreated, - Status: metav1.ConditionFalse, - ObservedGeneration: consumer.Generation, - LastTransitionTime: metav1.Now(), - Message: fmt.Sprintf("Error creating consumer on nats: %s", err), - }, v1beta1.ConditionTypeMatch(ConditionTypeNatsStackConsumerCreated)) - return err - } else { - consumer.GetConditions().AppendOrReplace(v1beta1.Condition{ - Type: ConditionTypeNatsStackConsumerCreated, - Status: metav1.ConditionTrue, - ObservedGeneration: consumer.Generation, - LastTransitionTime: metav1.Now(), - Message: "Nats consumer created", - }, v1beta1.ConditionTypeMatch(ConditionTypeNatsStackConsumerCreated)) - } - - return nil -} diff --git a/components/operator/internal/resources/brokerconsumers/create.go b/components/operator/internal/resources/brokerconsumers/create.go deleted file mode 100644 index 7d883968d8..0000000000 --- a/components/operator/internal/resources/brokerconsumers/create.go +++ /dev/null @@ -1,68 +0,0 @@ -package brokerconsumers - -import ( - "fmt" - "sort" - "strings" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - . "github.com/formancehq/go-libs/collectionutils" - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func Create(ctx core.Context, owner interface { - client.Object - GetStack() string -}, name string, services ...string) (*v1beta1.BrokerConsumer, error) { - queriedBy := strings.ToLower(owner.GetObjectKind().GroupVersionKind().Kind) - - sort.Strings(services) - - brokerConsumerName := fmt.Sprintf("%s-%s", owner.GetName(), - strings.ToLower(owner.GetObjectKind().GroupVersionKind().Kind), - ) - if name != "" { - brokerConsumerName += "-" + name - } - - brokerConsumer, _, err := core.CreateOrUpdate[*v1beta1.BrokerConsumer](ctx, types.NamespacedName{ - Name: brokerConsumerName, - }, - func(t *v1beta1.BrokerConsumer) error { - t.Spec.QueriedBy = queriedBy - t.Spec.Stack = owner.GetStack() - t.Spec.Services = services - t.Spec.Name = name - - return nil - }, - core.WithController[*v1beta1.BrokerConsumer](ctx.GetScheme(), owner), - ) - if err != nil { - return nil, err - } - - return brokerConsumer, nil -} - -func CreateOrUpdateOnAllServices(ctx core.Context, consumer interface { - client.Object - GetStack() string -}) (*v1beta1.BrokerConsumer, error) { - services, err := core.ListEventPublishers(ctx, consumer.GetStack()) - if err != nil { - return nil, err - } - - filteredServices := Filter(services, func(u unstructured.Unstructured) bool { - return u.GetKind() != consumer.GetObjectKind().GroupVersionKind().Kind - }) - - return Create(ctx, consumer, "", Map(filteredServices, func(from unstructured.Unstructured) string { - return strings.ToLower(from.GetKind()) - })...) -} diff --git a/components/operator/internal/resources/brokerconsumers/init.go b/components/operator/internal/resources/brokerconsumers/init.go deleted file mode 100644 index b93d1847a5..0000000000 --- a/components/operator/internal/resources/brokerconsumers/init.go +++ /dev/null @@ -1,19 +0,0 @@ -package brokerconsumers - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/brokers" - v1 "k8s.io/api/batch/v1" - "sigs.k8s.io/controller-runtime/pkg/builder" -) - -func init() { - core.Init( - core.WithStackDependencyReconciler(Reconcile, - core.WithOwn[*v1beta1.BrokerConsumer](&v1beta1.BrokerTopic{}, builder.MatchEveryOwner), - core.WithOwn[*v1beta1.BrokerConsumer](&v1.Job{}), - brokers.Watch[*v1beta1.BrokerConsumer](), - ), - ) -} diff --git a/components/operator/internal/resources/brokers/init.go b/components/operator/internal/resources/brokers/init.go deleted file mode 100644 index 3fab9aebc2..0000000000 --- a/components/operator/internal/resources/brokers/init.go +++ /dev/null @@ -1,20 +0,0 @@ -package brokers - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - v1 "k8s.io/api/batch/v1" -) - -//+kubebuilder:rbac:groups=formance.com,resources=brokers,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=brokers/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=brokers/finalizers,verbs=update - -func init() { - core.Init( - core.WithResourceReconciler(Reconcile, - core.WithFinalizer[*v1beta1.Broker]("clear", deleteBroker), - core.WithOwn[*v1beta1.Broker](&v1.Job{}), - ), - ) -} diff --git a/components/operator/internal/resources/brokers/reconcile.go b/components/operator/internal/resources/brokers/reconcile.go deleted file mode 100644 index 9d26076644..0000000000 --- a/components/operator/internal/resources/brokers/reconcile.go +++ /dev/null @@ -1,309 +0,0 @@ -package brokers - -import ( - "fmt" - "sort" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/jobs" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/settings" - "github.com/pkg/errors" - "golang.org/x/mod/semver" - batchv1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func Reconcile(ctx core.Context, stack *v1beta1.Stack, broker *v1beta1.Broker) error { - - brokerURI, err := settings.RequireURL(ctx, stack.Name, "broker", "dsn") - if err != nil { - return err - } - if brokerURI == nil { - return errors.New("broker configuration not found") - } - - if broker.Status.Mode == "" { - if err := detectBrokerMode(ctx, stack, broker, brokerURI); err != nil { - return err - } - } - - switch brokerURI.Scheme { - case "nats": - switch broker.Status.Mode { - case v1beta1.ModeOneStreamByService: - if err := createOneStreamByTopic(ctx, stack, broker, brokerURI); err != nil { - return err - } - case v1beta1.ModeOneStreamByStack: - if err := createOneStreamByStack(ctx, stack, broker, brokerURI); err != nil { - return err - } - } - } - - broker.Status.URI = brokerURI - - return nil -} - -func detectBrokerMode(ctx core.Context, stack *v1beta1.Stack, broker *v1beta1.Broker, uri *v1beta1.URI) error { - if hasLegacyStream, err := detectBrokerModeByCheckingExistentStreams(ctx, stack, broker, uri); err != nil { - return err - } else if hasLegacyStream { - broker.Status.Mode = v1beta1.ModeOneStreamByService - return nil - } - if ok, err := hasAllVersionsGreaterThan(ctx, stack, "v2.0.0-rc.27"); err != nil { - return err - } else if ok { - broker.Status.Mode = v1beta1.ModeOneStreamByStack - } else { - broker.Status.Mode = v1beta1.ModeOneStreamByService - } - - return nil -} - -func hasAllVersionsGreaterThan(ctx core.Context, stack *v1beta1.Stack, ref string) (bool, error) { - switch { - case stack.Spec.Version != "": - if !semver.IsValid(stack.Spec.Version) { - return true, nil - } - return semver.Compare(stack.Spec.Version, ref) >= 0, nil - case stack.Spec.VersionsFromFile != "": - versions := &v1beta1.Versions{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: stack.Spec.VersionsFromFile, - }, versions); err != nil { - return false, err - } - for service, v := range versions.Spec { - // notes(gfyrag): control is stick to version v1.7.0 - if service == "control" { - continue - } - if !semver.IsValid(v) { - continue - } - if semver.Compare(v, ref) < 0 { - return false, nil - } - } - - return true, nil - default: - // notes(gfyrag): Using latest, be careful, we cannot sure `latest` image on the nodes are really latest - return true, nil - } -} - -func detectBrokerModeByCheckingExistentStreams(ctx core.Context, stack *v1beta1.Stack, broker *v1beta1.Broker, uri *v1beta1.URI) (bool, error) { - const script = ` - # notes(gfyrag): Check if we have any stream named "$STACK-xxx" - v=$(nats stream ls -n --server $NATS_URI | grep "$STACK-") - # exit with code 12 if we detect any streams - [[ -z "$v" ]] || exit 12; -` - - natsBoxImage, err := registries.GetNatsBoxImage(ctx, stack, "0.14.1") - if err != nil { - return false, err - } - - hasLegacyStream := false - if err := jobs.Handle(ctx, broker, "detect-mode", corev1.Container{ - Image: natsBoxImage, - Name: "detect-mode", - Args: core.ShellScript(script), - Env: []corev1.EnvVar{ - core.Env("NATS_URI", fmt.Sprintf("nats://%s", uri.Host)), - core.Env("STACK", broker.Spec.Stack), - }, - }, - // notes(gfyrag): As the time of writing these lines, the succeedPolicy feature (https://kubernetes.io/docs/concepts/workloads/controllers/job/#success-policy) - // is too early to be used. Keep an eye on the k8s versions to switch when appropriate. - jobs.WithPodFailurePolicy(batchv1.PodFailurePolicy{ - Rules: []batchv1.PodFailurePolicyRule{{ - Action: batchv1.PodFailurePolicyActionFailJob, - OnExitCodes: &batchv1.PodFailurePolicyOnExitCodesRequirement{ - Operator: batchv1.PodFailurePolicyOnExitCodesOpIn, - Values: []int32{12}, - }, - }}, - }), - jobs.WithValidator(func(job *batchv1.Job) bool { - if job.Status.Succeeded > 0 { - return true - } - // notes(gfyrag): podFailurePolicy mark the job as failed - // so, we need to watch conditions to determine if it fails because of exit code 12 - for _, condition := range job.Status.Conditions { - if condition.Type == "Failed" && - condition.Reason == "PodFailurePolicy" && - condition.Status == "True" { - hasLegacyStream = true - return true - } - } - return false - }), - ); err != nil { - return false, err - } - - return hasLegacyStream, nil -} - -func deleteBroker(ctx core.Context, broker *v1beta1.Broker) error { - if !broker.Status.Ready { - return nil - } - if broker.Status.URI.Scheme != "nats" { - return nil - } - - script := "" - switch broker.Status.Mode { - case v1beta1.ModeOneStreamByService: - script = ` - for stream in $(nats --server $NATS_URI stream ls -n | grep $STACK); do - nats stream info --server $NATS_URI $stream && nats stream rm -f --server $NATS_URI $stream || true - done - ` - case v1beta1.ModeOneStreamByStack: - script = ` - nats stream info --server $NATS_URI $STACK && nats stream rm -f --server $NATS_URI $STACK || true - ` - } - - stack := &v1beta1.Stack{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: broker.Spec.Stack, - }, stack); err != nil { - return err - } - - natsBoxImage, err := registries.GetNatsBoxImage(ctx, stack, "0.14.1") - if err != nil { - return err - } - - return jobs.Handle(ctx, broker, "delete-streams", corev1.Container{ - Image: natsBoxImage, - Name: "delete-streams", - Args: core.ShellScript(script), - Env: []corev1.EnvVar{ - core.Env("NATS_URI", fmt.Sprintf("nats://%s", broker.Status.URI.Host)), - core.Env("STACK", broker.Spec.Stack), - }, - }) -} - -func createOneStreamByStack(ctx core.Context, stack *v1beta1.Stack, broker *v1beta1.Broker, uri *v1beta1.URI) error { - - if broker.Status.Ready { - return nil - } - - const script = ` - index=$(nats --server $NATS_URI stream ls -n | grep "$STREAM") - [[ -z "$index" ]] && { - nats stream add \ - --server $NATS_URI \ - --retention interest \ - --subjects $STREAM.* \ - --defaults \ - --replicas $REPLICAS \ - --no-allow-direct \ - $STREAM - } || true` - - natsBoxImage, err := registries.GetNatsBoxImage(ctx, stack, "0.14.1") - if err != nil { - return err - } - - return jobs.Handle(ctx, broker, "create-stream", corev1.Container{ - Image: natsBoxImage, - Name: "create-topic", - Args: core.ShellScript(script), - Env: []corev1.EnvVar{ - core.Env("NATS_URI", fmt.Sprintf("nats://%s", uri.Host)), - core.Env("STREAM", stack.Name), - core.Env("REPLICAS", func() string { - if replicas := uri.Query().Get("replicas"); replicas != "" { - return replicas - } - return "1" - }()), - }, - }) -} - -func createOneStreamByTopic(ctx core.Context, stack *v1beta1.Stack, broker *v1beta1.Broker, brokerURI *v1beta1.URI) error { - l := &v1beta1.BrokerTopicList{} - if err := ctx.GetClient().List(ctx, l, client.MatchingFields{ - "stack": stack.Name, - }); err != nil { - return err - } - - for _, item := range l.Items { - item := item - if !collectionutils.Contains(broker.Status.Streams, item.Spec.Service) { - if err := createNatsTopic(ctx, stack, broker, &item, brokerURI); err != nil { - return err - } - broker.Status.Streams = append(broker.Status.Streams, item.Spec.Service) - } - } - - sort.Strings(broker.Status.Streams) - - return nil -} - -func createNatsTopic(ctx core.Context, stack *v1beta1.Stack, broker *v1beta1.Broker, topic *v1beta1.BrokerTopic, brokerURI *v1beta1.URI) error { - const script = ` - index=$(nats --server $NATS_URI stream ls -j | jq "index(\"$SUBJECT\")") - if [ "$index" = "null" ]; then - nats stream add \ - --server $NATS_URI \ - --retention interest \ - --subjects $SUBJECT \ - --defaults \ - --replicas $REPLICAS \ - --no-allow-direct \ - $STREAM - fi` - - natsBoxImage, err := registries.GetNatsBoxImage(ctx, stack, "0.14.1") - if err != nil { - return err - } - - return jobs.Handle(ctx, broker, "create-topic-"+topic.Spec.Service, corev1.Container{ - Image: natsBoxImage, - Name: "create-topic", - Args: core.ShellScript(script), - Env: []corev1.EnvVar{ - core.Env("NATS_URI", fmt.Sprintf("nats://%s", brokerURI.Host)), - core.Env("SUBJECT", fmt.Sprintf("%s-%s", stack.Name, topic.Spec.Service)), - core.Env("STREAM", fmt.Sprintf("%s-%s", stack.Name, topic.Spec.Service)), - core.Env("REPLICAS", func() string { - if replicas := brokerURI.Query().Get("replicas"); replicas != "" { - return replicas - } - return "1" - }()), - }, - }) -} diff --git a/components/operator/internal/resources/brokers/utils.go b/components/operator/internal/resources/brokers/utils.go deleted file mode 100644 index 93d94b3343..0000000000 --- a/components/operator/internal/resources/brokers/utils.go +++ /dev/null @@ -1,124 +0,0 @@ -package brokers - -import ( - "fmt" - "strings" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/internal/resources/settings" - "k8s.io/apimachinery/pkg/types" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - v1 "k8s.io/api/core/v1" -) - -func GetBrokerEnvVars(ctx core.Context, brokerURI *v1beta1.URI, stackName, serviceName string) ([]v1.EnvVar, error) { - return GetEnvVarsWithPrefix(ctx, brokerURI, stackName, serviceName, "") -} - -func GetEnvVarsWithPrefix(ctx core.Context, brokerURI *v1beta1.URI, stackName, serviceName, prefix string) ([]v1.EnvVar, error) { - ret := make([]v1.EnvVar, 0) - - ret = append(ret, core.Env(fmt.Sprintf("%sBROKER", prefix), brokerURI.Scheme)) - - if brokerURI.Query().Get("circuitBreakerEnabled") == "true" { - ret = append(ret, core.Env(fmt.Sprintf("%sPUBLISHER_CIRCUIT_BREAKER_ENABLED", prefix), "true")) - if openInterval := brokerURI.Query().Get("circuitBreakerOpenInterval"); openInterval != "" { - ret = append(ret, core.Env(fmt.Sprintf("%sPUBLISHER_CIRCUIT_BREAKER_OPEN_INTERVAL_DURATION", prefix), openInterval)) - } - } - - switch { - case brokerURI.Scheme == "kafka": - ret = append(ret, - core.Env(fmt.Sprintf("%sBROKER", prefix), "kafka"), - core.Env(fmt.Sprintf("%sPUBLISHER_KAFKA_ENABLED", prefix), "true"), - core.Env(fmt.Sprintf("%sPUBLISHER_KAFKA_BROKER", prefix), brokerURI.Host), - ) - if settings.IsTrue(brokerURI.Query().Get("saslEnabled")) { - ret = append(ret, - core.Env(fmt.Sprintf("%sPUBLISHER_KAFKA_SASL_ENABLED", prefix), "true"), - core.Env(fmt.Sprintf("%sPUBLISHER_KAFKA_SASL_USERNAME", prefix), brokerURI.Query().Get("saslUsername")), - core.Env(fmt.Sprintf("%sPUBLISHER_KAFKA_SASL_PASSWORD", prefix), brokerURI.Query().Get("saslPassword")), - core.Env(fmt.Sprintf("%sPUBLISHER_KAFKA_SASL_MECHANISM", prefix), brokerURI.Query().Get("saslMechanism")), - core.Env(fmt.Sprintf("%sPUBLISHER_KAFKA_SASL_SCRAM_SHA_SIZE", prefix), brokerURI.Query().Get("saslSCRAMSHASize")), - ) - - serviceAccount, err := settings.GetAWSServiceAccount(ctx, stackName) - if err != nil { - return nil, err - } - - if serviceAccount != "" { - ret = append(ret, core.Env(fmt.Sprintf("%sPUBLISHER_KAFKA_SASL_IAM_ENABLED", prefix), "true")) - } - } - if settings.IsTrue(brokerURI.Query().Get("tls")) { - ret = append(ret, - core.Env(fmt.Sprintf("%sPUBLISHER_KAFKA_TLS_ENABLED", prefix), "true"), - ) - } - - case brokerURI.Scheme == "nats": - ret = append(ret, - core.Env(fmt.Sprintf("%sPUBLISHER_NATS_ENABLED", prefix), "true"), - core.Env(fmt.Sprintf("%sPUBLISHER_NATS_URL", prefix), brokerURI.Host), - core.Env(fmt.Sprintf("%sPUBLISHER_NATS_CLIENT_ID", prefix), fmt.Sprintf("%s-%s", stackName, serviceName)), - ) - } - - return ret, nil -} - -func GetPublisherEnvVars(stack *v1beta1.Stack, broker *v1beta1.Broker, service, prefix string) []v1.EnvVar { - switch broker.Status.Mode { - case v1beta1.ModeOneStreamByService: - return []v1.EnvVar{ - core.Env(fmt.Sprintf("%sPUBLISHER_TOPIC_MAPPING", prefix), "*:"+core.GetObjectName(stack.Name, service)), - } - case v1beta1.ModeOneStreamByStack: - ret := []v1.EnvVar{ - core.Env(fmt.Sprintf("%sPUBLISHER_TOPIC_MAPPING", prefix), fmt.Sprintf("*:%s.%s", stack.Name, service)), - } - - if broker.Status.URI.Scheme == "nats" { - ret = append(ret, core.Env(fmt.Sprintf("%sPUBLISHER_NATS_AUTO_PROVISION", prefix), "false")) - } - return ret - default: - panic(fmt.Sprintf("mode '%s' not handled", broker.Status.Mode)) - } -} - -func GetTopicsEnvVars(ctx core.Context, stack *v1beta1.Stack, key string, services ...string) ([]v1.EnvVar, error) { - - broker := &v1beta1.Broker{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: stack.Name, - }, broker); err != nil { - return nil, err - } - - if !broker.Status.Ready { - return nil, core.NewPendingError().WithMessage("broker not ready") - } - - ret := []v1.EnvVar{ - core.Env(key, strings.Join(collectionutils.Map(services, func(from string) string { - switch broker.Status.Mode { - case v1beta1.ModeOneStreamByService: - return fmt.Sprintf("%s-%s", stack.Name, from) - case v1beta1.ModeOneStreamByStack: - return fmt.Sprintf("%s.%s", stack.Name, from) - } - return "" - }), " ")), - } - - if broker.Status.URI.Scheme == "nats" { - ret = append(ret, core.Env("PUBLISHER_NATS_AUTO_PROVISION", "false")) - } - - return ret, nil -} diff --git a/components/operator/internal/resources/brokers/watch.go b/components/operator/internal/resources/brokers/watch.go deleted file mode 100644 index 430dc5e55a..0000000000 --- a/components/operator/internal/resources/brokers/watch.go +++ /dev/null @@ -1,30 +0,0 @@ -package brokers - -import ( - "reflect" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func Watch[T client.Object]() core.ReconcilerOption[T] { - return core.WithWatch[T, *v1beta1.Broker](func(ctx core.Context, topic *v1beta1.Broker) []reconcile.Request { - var t T - slice := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(t)), 0, 0).Interface() - - err := core.GetAllStackDependencies(ctx, topic.Spec.Stack, &slice) - if err != nil { - - return nil - } - - objects := make([]client.Object, 0) - for i := 0; i < reflect.ValueOf(slice).Len(); i++ { - objects = append(objects, reflect.ValueOf(slice).Index(i).Interface().(client.Object)) - } - - return core.MapObjectToReconcileRequests(objects...) - }) -} diff --git a/components/operator/internal/resources/brokertopics/brokertopics.go b/components/operator/internal/resources/brokertopics/brokertopics.go deleted file mode 100644 index 9b838a52d2..0000000000 --- a/components/operator/internal/resources/brokertopics/brokertopics.go +++ /dev/null @@ -1,23 +0,0 @@ -package brokertopics - -import ( - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func Find(ctx core.Context, stack *v1beta1.Stack, name string) (*v1beta1.BrokerTopic, error) { - topicList := &v1beta1.BrokerTopicList{} - if err := ctx.GetClient().List(ctx, topicList, client.MatchingFields{ - ".spec.service": name, - "stack": stack.Name, - }); err != nil { - return nil, err - } - - if len(topicList.Items) == 0 { - return nil, nil - } - - return &topicList.Items[0], nil -} diff --git a/components/operator/internal/resources/brokertopics/controller.go b/components/operator/internal/resources/brokertopics/controller.go deleted file mode 100644 index 3cd3c32ae1..0000000000 --- a/components/operator/internal/resources/brokertopics/controller.go +++ /dev/null @@ -1,31 +0,0 @@ -package brokertopics - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "k8s.io/apimachinery/pkg/types" -) - -func Reconcile(ctx core.Context, stack *v1beta1.Stack, topic *v1beta1.BrokerTopic) error { - - if len(topic.GetOwnerReferences()) == 1 { // Remains only the stack - return ctx.GetClient().Delete(ctx, topic) - } - - broker, _, err := core.CreateOrUpdate[*v1beta1.Broker](ctx, types.NamespacedName{ - Name: stack.Name, - }, func(t *v1beta1.Broker) error { - t.Spec.Stack = stack.Name - return nil - }, core.WithController[*v1beta1.Broker](ctx.GetScheme(), stack)) - if err != nil { - return err - } - - if !broker.Status.Ready { - return core.NewApplicationError().WithMessage("broker not ready") - } - topic.Status.Ready = broker.Status.Ready - - return nil -} diff --git a/components/operator/internal/resources/brokertopics/init.go b/components/operator/internal/resources/brokertopics/init.go deleted file mode 100644 index 3e7f4620c4..0000000000 --- a/components/operator/internal/resources/brokertopics/init.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -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 brokertopics - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/brokers" - batchv1 "k8s.io/api/batch/v1" -) - -//+kubebuilder:rbac:groups=formance.com,resources=brokertopics,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=brokertopics/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=brokertopics/finalizers,verbs=update - -func init() { - core.Init( - core.WithStackDependencyReconciler(Reconcile, - core.WithOwn[*v1beta1.BrokerTopic](&batchv1.Job{}), - core.WithWatchSettings[*v1beta1.BrokerTopic](), - brokers.Watch[*v1beta1.BrokerTopic](), - ), - core.WithSimpleIndex[*v1beta1.BrokerTopic](".spec.service", func(t *v1beta1.BrokerTopic) string { - return t.Spec.Service - }), - ) -} diff --git a/components/operator/internal/resources/brokertopics/watch.go b/components/operator/internal/resources/brokertopics/watch.go deleted file mode 100644 index c60fd6cf6d..0000000000 --- a/components/operator/internal/resources/brokertopics/watch.go +++ /dev/null @@ -1,33 +0,0 @@ -package brokertopics - -import ( - "reflect" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func Watch[T client.Object](service string) core.ReconcilerOption[T] { - return core.WithWatch[T, *v1beta1.BrokerTopic](func(ctx core.Context, topic *v1beta1.BrokerTopic) []reconcile.Request { - if topic.Spec.Service != service { - return []reconcile.Request{} - } - - var t T - slice := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(t)), 0, 0).Interface() - - err := core.GetAllStackDependencies(ctx, topic.Spec.Stack, &slice) - if err != nil { - return []reconcile.Request{} - } - - objects := make([]client.Object, 0) - for i := 0; i < reflect.ValueOf(slice).Len(); i++ { - objects = append(objects, reflect.ValueOf(slice).Index(i).Interface().(client.Object)) - } - - return core.MapObjectToReconcileRequests(objects...) - }) -} diff --git a/components/operator/internal/resources/caddy/caddy.go b/components/operator/internal/resources/caddy/caddy.go deleted file mode 100644 index 290a2d0a8e..0000000000 --- a/components/operator/internal/resources/caddy/caddy.go +++ /dev/null @@ -1,151 +0,0 @@ -package caddy - -import ( - "bytes" - "fmt" - "strings" - "text/template" - - "github.com/formancehq/operator/internal/resources/settings" - - "github.com/formancehq/operator/internal/core" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "golang.org/x/mod/semver" - appsv1 "k8s.io/api/apps/v1" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -func DeploymentTemplate(ctx core.Context, stack *v1beta1.Stack, owner v1beta1.Object, caddyfile *v1.ConfigMap, image string, env []v1.EnvVar) (*appsv1.Deployment, error) { - t := &appsv1.Deployment{} - - otlpEnv, err := settings.GetOTELEnvVars(ctx, stack.Name, core.LowerCamelCaseKind(ctx, owner)) - if err != nil { - return nil, err - } - - if len(otlpEnv) > 0 { - env = append(env, otlpEnv...) - scheme := "https" - for _, envVar := range env { - if envVar.Name == "OTEL_TRACES_EXPORTER_OTLP_INSECURE" { - if envVar.Value == "true" { - scheme = "http" - } - break - } - } - env = append(env, core.Env("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", fmt.Sprintf("%s://$(OTEL_TRACES_EXPORTER_OTLP_ENDPOINT)", scheme))) - env = append(env, core.Env("OTEL_EXPORTER_OTLP_PROTOCOL", "$(OTEL_TRACES_EXPORTER_OTLP_MODE)")) - } - - t.Spec.Template.Annotations = collectionutils.MergeMaps(t.Spec.Template.Annotations, map[string]string{ - "caddyfile-hash": core.HashFromConfigMaps(caddyfile), - }) - t.Spec.Template.Spec.Volumes = []v1.Volume{ - volumeFromConfigMap("caddyfile", caddyfile), - { - Name: "data", - VolumeSource: v1.VolumeSource{ - EmptyDir: &v1.EmptyDirVolumeSource{}, - }, - }, - } - t.Spec.Template.Spec.Containers = []v1.Container{ - { - Name: "gateway", - Command: []string{"/usr/bin/caddy"}, - Args: []string{ - "run", - "--config", "/gateway/Caddyfile", - "--adapter", "caddyfile", - }, - Image: image, - Env: env, - VolumeMounts: []v1.VolumeMount{ - core.NewVolumeMount("caddyfile", "/gateway", true), - core.NewVolumeMount("data", "/data", false), - }, - Ports: []v1.ContainerPort{{ - Name: "http", - ContainerPort: 8080, - }, { - Name: "metrics", - ContainerPort: 3080, - }}, - SecurityContext: &v1.SecurityContext{ - Capabilities: &v1.Capabilities{ - Add: []v1.Capability{"NET_BIND_SERVICE"}, - }, - }, - }, - } - - return t, nil -} - -func volumeFromConfigMap(name string, cm *v1.ConfigMap) v1.Volume { - return v1.Volume{ - Name: name, - VolumeSource: v1.VolumeSource{ - ConfigMap: &v1.ConfigMapVolumeSource{ - LocalObjectReference: v1.LocalObjectReference{ - Name: cm.Name, - }, - }, - }, - } -} - -func ComputeCaddyfile(ctx core.Context, stack *v1beta1.Stack, _tpl string, additionalData map[string]any) (string, error) { - tpl := template.Must(template.New("main").Funcs(map[string]any{ - "join": strings.Join, - "semver_compare": semver.Compare, - "semver_is_valid": semver.IsValid, - }).Parse(_tpl)) - buf := bytes.NewBufferString("") - - openTelemetryEnabled, err := settings.HasOpenTelemetryTracesEnabled(ctx, stack.Name) - if err != nil { - return "", err - } - - data := map[string]any{ - "EnableOpenTelemetry": openTelemetryEnabled, - } - data = collectionutils.MergeMaps(data, additionalData) - - if err := tpl.Execute(buf, data); err != nil { - return "", err - } - - return buf.String(), nil -} - -func CreateCaddyfileConfigMap(ctx core.Context, stack *v1beta1.Stack, - name, _tpl string, additionalData map[string]any, options ...core.ObjectMutator[*v1.ConfigMap]) (*v1.ConfigMap, error) { - caddyfile, err := ComputeCaddyfile(ctx, stack, _tpl, additionalData) - if err != nil { - return nil, err - } - - options = append([]core.ObjectMutator[*v1.ConfigMap]{ - func(t *v1.ConfigMap) error { - t.Data = map[string]string{ - "Caddyfile": caddyfile, - } - - return nil - }, - }, options...) - - configMap, _, err := core.CreateOrUpdate[*v1.ConfigMap](ctx, types.NamespacedName{ - Namespace: stack.Name, - Name: name, - }, - options..., - ) - return configMap, err -} diff --git a/components/operator/internal/resources/databases/create.go b/components/operator/internal/resources/databases/create.go deleted file mode 100644 index 49e1045540..0000000000 --- a/components/operator/internal/resources/databases/create.go +++ /dev/null @@ -1,71 +0,0 @@ -package databases - -import ( - "strings" - - "github.com/pkg/errors" - - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func Create(ctx core.Context, stack *v1beta1.Stack, owner interface { - v1beta1.Object - IsDebug() bool -}) (*v1beta1.Database, error) { - condition := v1beta1.Condition{ - Type: "DatabaseReady", - ObservedGeneration: owner.GetGeneration(), - LastTransitionTime: metav1.Now(), - } - defer func() { - owner.GetConditions().AppendOrReplace(condition, v1beta1.ConditionTypeMatch("DatabaseReady")) - }() - - serviceName := strings.ToLower(owner.GetObjectKind().GroupVersionKind().Kind) - database, _, err := core.CreateOrUpdate[*v1beta1.Database](ctx, types.NamespacedName{ - Name: core.GetObjectName(stack.Name, serviceName), - }, - func(t *v1beta1.Database) error { - t.Spec.Stack = stack.Name - t.Spec.Service = serviceName - t.Spec.Debug = stack.Spec.Debug || owner.IsDebug() - - return nil - }, - core.WithController[*v1beta1.Database](ctx.GetScheme(), owner), - core.WithOwner[*v1beta1.Database](ctx.GetScheme(), stack), - ) - if err != nil { - condition.Message = err.Error() - condition.Status = metav1.ConditionFalse - return nil, err - } - if !database.Status.Ready { - condition.Message = "database creation pending" - condition.Status = metav1.ConditionFalse - } else { - condition.Message = "database is ok" - condition.Status = metav1.ConditionTrue - } - - return database, err -} - -const ServiceVersion = "formance.com/module-version" - -func SaveModuleVersion(ctx core.Context, database *v1beta1.Database, version string) error { - patch := client.MergeFrom(database.DeepCopy()) - if database.Annotations == nil { - database.Annotations = make(map[string]string) - } - database.Annotations[ServiceVersion] = version - return errors.Wrap(ctx.GetClient().Patch(ctx, database, patch), "patching database") -} - -func GetSavedModuleVersion(database *v1beta1.Database) string { - return database.Annotations[ServiceVersion] -} diff --git a/components/operator/internal/resources/databases/env.go b/components/operator/internal/resources/databases/env.go deleted file mode 100644 index e042c890af..0000000000 --- a/components/operator/internal/resources/databases/env.go +++ /dev/null @@ -1,109 +0,0 @@ -package databases - -import ( - "fmt" - "strconv" - "time" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/settings" - "github.com/pkg/errors" - corev1 "k8s.io/api/core/v1" -) - -func GetPostgresEnvVars(ctx core.Context, stack *v1beta1.Stack, db *v1beta1.Database) ([]corev1.EnvVar, error) { - return PostgresEnvVarsWithPrefix(ctx, stack, db, "") -} - -func PostgresEnvVarsWithPrefix(ctx core.Context, stack *v1beta1.Stack, database *v1beta1.Database, prefix string) ([]corev1.EnvVar, error) { - ret := []corev1.EnvVar{ - core.Env(fmt.Sprintf("%sPOSTGRES_HOST", prefix), database.Status.URI.Hostname()), - core.Env(fmt.Sprintf("%sPOSTGRES_PORT", prefix), database.Status.URI.Port()), - core.Env(fmt.Sprintf("%sPOSTGRES_DATABASE", prefix), database.Status.Database), - } - if database.Status.URI.User.Username() != "" || database.Status.URI.Query().Get("secret") != "" { - if database.Status.URI.User.Username() != "" { - password, _ := database.Status.URI.User.Password() - ret = append(ret, - core.Env(fmt.Sprintf("%sPOSTGRES_USERNAME", prefix), database.Status.URI.User.Username()), - core.Env(fmt.Sprintf("%sPOSTGRES_PASSWORD", prefix), password), - ) - } else { - secret := database.Status.URI.Query().Get("secret") - ret = append(ret, - core.EnvFromSecret(fmt.Sprintf("%sPOSTGRES_USERNAME", prefix), secret, "username"), - core.EnvFromSecret(fmt.Sprintf("%sPOSTGRES_PASSWORD", prefix), secret, "password"), - ) - } - ret = append(ret, - core.Env(fmt.Sprintf("%sPOSTGRES_NO_DATABASE_URI", prefix), core.ComputeEnvVar("postgresql://%s:%s@%s:%s", - fmt.Sprintf("%sPOSTGRES_USERNAME", prefix), - fmt.Sprintf("%sPOSTGRES_PASSWORD", prefix), - fmt.Sprintf("%sPOSTGRES_HOST", prefix), - fmt.Sprintf("%sPOSTGRES_PORT", prefix), - )), - ) - } else { - ret = append(ret, - core.Env(fmt.Sprintf("%sPOSTGRES_NO_DATABASE_URI", prefix), core.ComputeEnvVar("postgresql://%s:%s", - fmt.Sprintf("%sPOSTGRES_HOST", prefix), - fmt.Sprintf("%sPOSTGRES_PORT", prefix), - )), - ) - } - - awsRole, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return nil, err - } - - if awsRole != "" { - ret = append(ret, core.Env(fmt.Sprintf("%sPOSTGRES_AWS_ENABLE_IAM", prefix), "true")) - } - - f := "%s/%s" - if settings.IsTrue(database.Status.URI.Query().Get("disableSSLMode")) { - f += "?sslmode=disable" - } - ret = append(ret, - core.Env(fmt.Sprintf("%sPOSTGRES_URI", prefix), core.ComputeEnvVar(f, - fmt.Sprintf("%sPOSTGRES_NO_DATABASE_URI", prefix), - fmt.Sprintf("%sPOSTGRES_DATABASE", prefix))), - ) - - config, err := settings.GetAs[connectionPoolConfiguration](ctx, stack.Name, "modules", database.Spec.Service, "database", "connection-pool") - if err != nil { - return nil, err - } - - if config.MaxIdle != "" { - _, err := strconv.ParseUint(config.MaxIdle, 10, 64) - if err != nil { - return nil, errors.Wrap(err, "cannot parse max idle value") - } - ret = append(ret, core.Env(fmt.Sprintf("%sPOSTGRES_MAX_IDLE_CONNS", prefix), config.MaxIdle)) - } - if config.MaxIdleTime != "" { - _, err := time.ParseDuration(config.MaxIdleTime) - if err != nil { - return nil, errors.Wrap(err, "cannot parse max idle time value") - } - ret = append(ret, core.Env(fmt.Sprintf("%sPOSTGRES_CONN_MAX_IDLE_TIME", prefix), config.MaxIdleTime)) - } - if config.MaxOpen != "" { - _, err := strconv.ParseUint(config.MaxOpen, 10, 64) - if err != nil { - return nil, errors.Wrap(err, "cannot parse max open conns value") - } - ret = append(ret, core.Env(fmt.Sprintf("%sPOSTGRES_CONN_MAX_OPEN_CONNS", prefix), config.MaxOpen)) - } - - return ret, nil -} - -type connectionPoolConfiguration struct { - MaxIdle string `json:"max-idle,omitempty"` - MaxIdleTime string `json:"max-idle-time,omitempty"` - MaxOpen string `json:"max-open,omitempty"` -} diff --git a/components/operator/internal/resources/databases/init.go b/components/operator/internal/resources/databases/init.go deleted file mode 100644 index fb685b30ac..0000000000 --- a/components/operator/internal/resources/databases/init.go +++ /dev/null @@ -1,190 +0,0 @@ -/* -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 databases - -import ( - "fmt" - - "github.com/formancehq/go-libs/pointer" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/jobs" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/resourcereferences" - "github.com/formancehq/operator/internal/resources/settings" - "github.com/pkg/errors" - batchv1 "k8s.io/api/batch/v1" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" -) - -const ( - databaseFinalizer = "delete-database" -) - -//+kubebuilder:rbac:groups=formance.com,resources=databases,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=databases/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=databases/finalizers,verbs=update - -func Reconcile(ctx core.Context, stack *v1beta1.Stack, database *v1beta1.Database) error { - - databaseURL, err := settings.RequireURL(ctx, database.Spec.Stack, "postgres", database.Spec.Service, "uri") - if err != nil { - return errors.Wrap(err, "retrieving database configuration") - } - - if secret := databaseURL.Query().Get("secret"); secret != "" { - _, err = resourcereferences.Create(ctx, database, "postgres", secret, &v1.Secret{}) - } else { - err = resourcereferences.Delete(ctx, database, "postgres") - } - if err != nil { - return err - } - - awsRole, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - if awsRole != "" { - _, err = resourcereferences.Create(ctx, database, "database", awsRole, &v1.ServiceAccount{}) - } else { - err = resourcereferences.Delete(ctx, database, "database") - } - if err != nil { - return err - } - - if database.Status.URI != nil && database.Status.URI.Host != databaseURL.Host { - object := &batchv1.Job{} - object.SetName(fmt.Sprintf("%s-create-database", database.Spec.Service)) - object.SetNamespace(database.Spec.Stack) - if err := ctx.GetClient().Delete(ctx, object, &client.DeleteOptions{ - GracePeriodSeconds: pointer.For(int64(0)), - }); client.IgnoreNotFound(err) != nil { - return err - } - } - - if database.Status.Ready { - if database.Status.URI.Host == databaseURL.Host { - database.Status.URI = databaseURL - } else { - database.Status.OutOfSync = true - } - } else { - dbName := core.GetObjectName(database.Spec.Stack, database.Spec.Service) - database.Status.URI = databaseURL - database.Status.Database = dbName - - if err := handleDatabaseJob(ctx, stack, database, "create-database", "db", "create"); err != nil { - return err - } - } - - return nil -} - -func Delete(ctx core.Context, database *v1beta1.Database) error { - if database.Status.URI == nil { - return nil - } - - clearDatabase, err := settings.GetBoolOrFalse(ctx, database.Spec.Stack, "clear-database") - if err != nil { - return err - } - if !clearDatabase { - return nil - } - - logger := log.FromContext(ctx) - logger = logger.WithValues("name", database.Name) - logger.Info("Deleting database") - - stack := &v1beta1.Stack{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: database.Spec.Stack, - }, stack); err != nil { - return err - } - - if err := handleDatabaseJob(ctx, stack, database, "drop-database", "db", "drop"); err != nil { - return err - } - - database.Status.URI = nil - logger.Info("Database deleted.") - - return nil -} - -func handleDatabaseJob(ctx core.Context, stack *v1beta1.Stack, database *v1beta1.Database, name string, args ...string) error { - - operatorUtilsImage, err := registries.GetImage(ctx, stack, "operator-utils", ctx.GetPlatform().UtilsVersion) - if err != nil { - return err - } - - annotations := make(map[string]string) - secretReference := &v1beta1.ResourceReference{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: fmt.Sprintf("%s-postgres", database.Name), - }, secretReference); client.IgnoreNotFound(err) != nil { - return err - } else if err == nil { - annotations["secret-hash"] = secretReference.Status.Hash - } - - env, err := GetPostgresEnvVars(ctx, stack, database) - if err != nil { - return err - } - - if database.Spec.Debug { - env = append(env, core.Env("DEBUG", "true")) - } - - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - return jobs.Handle(ctx, database, name, v1.Container{ - Name: name, - Image: operatorUtilsImage, - Args: args, - Env: env, - }, - jobs.Mutator(core.WithAnnotations[*batchv1.Job](annotations)), - jobs.WithServiceAccount(serviceAccountName), - ) -} - -func init() { - core.Init( - core.WithResourceReconciler(Reconcile, - core.WithOwn[*v1beta1.Database](&batchv1.Job{}), - core.WithOwn[*v1beta1.Database](&v1beta1.ResourceReference{}), - core.WithWatchSettings[*v1beta1.Database](), - core.WithFinalizer(databaseFinalizer, Delete), - ), - ) -} diff --git a/components/operator/internal/resources/databases/migrate.go b/components/operator/internal/resources/databases/migrate.go deleted file mode 100644 index 3239e856ca..0000000000 --- a/components/operator/internal/resources/databases/migrate.go +++ /dev/null @@ -1,51 +0,0 @@ -package databases - -import ( - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/jobs" - v1 "k8s.io/api/core/v1" -) - -type MigrationConfiguration struct { - Command []string - AdditionalEnv []v1.EnvVar -} - -func MigrateDatabaseContainer(ctx core.Context, stack *v1beta1.Stack, image string, database *v1beta1.Database, options ...func(m *MigrationConfiguration)) (v1.Container, error) { - m := &MigrationConfiguration{} - for _, option := range options { - option(m) - } - args := m.Command - if len(args) == 0 { - args = []string{"migrate"} - } - - env, err := GetPostgresEnvVars(ctx, stack, database) - if err != nil { - return v1.Container{}, err - } - - if m.AdditionalEnv != nil { - env = append(env, m.AdditionalEnv...) - } - - return v1.Container{ - Name: "migrate", - Image: image, - Args: args, - Env: env, - }, nil -} - -func Migrate(ctx core.Context, stack *v1beta1.Stack, image string, database *v1beta1.Database, options ...func(m *MigrationConfiguration)) error { - container, err := MigrateDatabaseContainer(ctx, stack, image, database, options...) - if err != nil { - return err - } - - return jobs.Handle(ctx, database, fmt.Sprintf("%s-migration", database.Name), container) -} diff --git a/components/operator/internal/resources/databases/watch.go b/components/operator/internal/resources/databases/watch.go deleted file mode 100644 index aa6e568590..0000000000 --- a/components/operator/internal/resources/databases/watch.go +++ /dev/null @@ -1,34 +0,0 @@ -package databases - -import ( - "reflect" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func Watch[T client.Object]() core.ReconcilerOption[T] { - var t T - t = reflect.New(reflect.TypeOf(t).Elem()).Interface().(T) - return core.WithWatch[T, *v1beta1.Database](func(ctx core.Context, database *v1beta1.Database) []reconcile.Request { - if database.Spec.Service != core.LowerCamelCaseKind(ctx, t) { - return []reconcile.Request{} - } - - slice := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(t)), 0, 0).Interface() - - err := core.GetAllStackDependencies(ctx, database.Spec.Stack, &slice) - if err != nil { - return []reconcile.Request{} - } - - objects := make([]client.Object, 0) - for i := 0; i < reflect.ValueOf(slice).Len(); i++ { - objects = append(objects, reflect.ValueOf(slice).Index(i).Interface().(client.Object)) - } - - return core.MapObjectToReconcileRequests(objects...) - }) -} diff --git a/components/operator/internal/resources/gatewayhttpapis/create.go b/components/operator/internal/resources/gatewayhttpapis/create.go deleted file mode 100644 index 6bfa9ff8b4..0000000000 --- a/components/operator/internal/resources/gatewayhttpapis/create.go +++ /dev/null @@ -1,60 +0,0 @@ -package gatewayhttpapis - -import ( - "strings" - - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "k8s.io/apimachinery/pkg/types" -) - -type option func(spec *v1beta1.GatewayHTTPAPI) - -var defaultOptions = []option{ - WithRules(RuleSecured()), -} - -func Create(ctx core.Context, owner v1beta1.Module, options ...option) error { - objectName := strings.ToLower(owner.GetObjectKind().GroupVersionKind().Kind) - _, _, err := core.CreateOrUpdate[*v1beta1.GatewayHTTPAPI](ctx, types.NamespacedName{ - Name: core.GetObjectName(owner.GetStack(), core.LowerCamelCaseKind(ctx, owner)), - }, - func(t *v1beta1.GatewayHTTPAPI) error { - t.Spec = v1beta1.GatewayHTTPAPISpec{ - StackDependency: v1beta1.StackDependency{ - Stack: owner.GetStack(), - }, - Name: objectName, - } - for _, option := range append(defaultOptions, options...) { - option(t) - } - - return nil - }, - core.WithController[*v1beta1.GatewayHTTPAPI](ctx.GetScheme(), owner), - ) - return err -} - -func WithRules(rules ...v1beta1.GatewayHTTPAPIRule) func(httpapi *v1beta1.GatewayHTTPAPI) { - return func(httpapi *v1beta1.GatewayHTTPAPI) { - httpapi.Spec.Rules = rules - } -} - -func WithHealthCheckEndpoint(v string) func(httpapi *v1beta1.GatewayHTTPAPI) { - return func(httpapi *v1beta1.GatewayHTTPAPI) { - httpapi.Spec.HealthCheckEndpoint = v - } -} - -func RuleSecured() v1beta1.GatewayHTTPAPIRule { - return v1beta1.GatewayHTTPAPIRule{} -} - -func RuleUnsecured() v1beta1.GatewayHTTPAPIRule { - return v1beta1.GatewayHTTPAPIRule{ - Secured: true, - } -} diff --git a/components/operator/internal/resources/gatewayhttpapis/init.go b/components/operator/internal/resources/gatewayhttpapis/init.go deleted file mode 100644 index aaefba6ffd..0000000000 --- a/components/operator/internal/resources/gatewayhttpapis/init.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -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 gatewayhttpapis - -import ( - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/services" - corev1 "k8s.io/api/core/v1" -) - -//+kubebuilder:rbac:groups=formance.com,resources=gatewayhttpapis,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=gatewayhttpapis/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=gatewayhttpapis/finalizers,verbs=update - -func Reconcile(ctx Context, _ *v1beta1.Stack, httpAPI *v1beta1.GatewayHTTPAPI) error { - _, err := services.Create(ctx, httpAPI, httpAPI.Spec.Name, services.WithDefault(httpAPI.Spec.Name)) - if err != nil { - return err - } - - return nil -} - -func init() { - Init( - WithStackDependencyReconciler(Reconcile, - WithOwn[*v1beta1.GatewayHTTPAPI](&corev1.Service{}), - WithWatchSettings[*v1beta1.GatewayHTTPAPI](), - ), - ) -} diff --git a/components/operator/internal/resources/gateways/Caddyfile.gotpl b/components/operator/internal/resources/gateways/Caddyfile.gotpl deleted file mode 100644 index 9316309bd5..0000000000 --- a/components/operator/internal/resources/gateways/Caddyfile.gotpl +++ /dev/null @@ -1,112 +0,0 @@ -(cors) { - header { - Access-Control-Allow-Methods "GET,OPTIONS,PUT,POST,DELETE,HEAD,PATCH" - Access-Control-Allow-Headers content-type - Access-Control-Max-Age 100 - Access-Control-Allow-Origin * - } -} -{{- $values := . }} -{{- if .EnableAudit }} -(audit) { - audit { - # Kafka publisher - {{- if (eq .Broker "kafka") }} - publisher_kafka_broker {$PUBLISHER_KAFKA_BROKER:redpanda:29092} - publisher_kafka_enabled {$PUBLISHER_KAFKA_ENABLED:false} - publisher_kafka_tls_enabled {$PUBLISHER_KAFKA_TLS_ENABLED:false} - publisher_kafka_sasl_enabled {$PUBLISHER_KAFKA_SASL_ENABLED:false} - publisher_kafka_sasl_username {$PUBLISHER_KAFKA_SASL_USERNAME} - publisher_kafka_sasl_password {$PUBLISHER_KAFKA_SASL_PASSWORD} - publisher_kafka_sasl_mechanism {$PUBLISHER_KAFKA_SASL_MECHANISM} - publisher_kafka_sasl_scram_sha_size {$PUBLISHER_KAFKA_SASL_SCRAM_SHA_SIZE} - {{- end }} - {{- if (eq .Broker "nats") }} - # Nats publisher - publisher_nats_enabled {$PUBLISHER_NATS_ENABLED:true} - publisher_nats_url {$PUBLISHER_NATS_URL:nats://nats:4222} - publisher_nats_client_id {$PUBLISHER_NATS_CLIENT_ID:gateway} - publisher_nats_max_reconnects {$PUBLISHER_NATS_MAX_RECONNECTS:30} - publisher_nats_max_reconnects_wait {$PUBLISHER_NATS_MAX_RECONNECT_WAIT:2s} - {{- end }} - } -} -{{- end }} - -{ - {{ if .Debug }}debug{{ end }} - servers { - metrics - } - admin :3080 - - # Many directives manipulate the HTTP handler chain and the order in which - # those directives are evaluated matters. So the jwtauth directive must be - # ordered. - # c.f. https://caddyserver.com/docs/caddyfile/directives#directive-order - order versions after metrics - {{- if .EnableAudit }} - order audit after encode - {{- end }} -} - -:{{ .Port }} { - {{- if .EnableOpenTelemetry }} - tracing { - span gateway - } - {{- end }} - log { - output stdout - {{- if .Debug }} - level DEBUG - {{- end }} - } - - {{- if .EnableAudit }} - import audit - {{- end }} - - {{- range $i, $service := .Services }} - {{- range $j, $rule := $service.Rules }} - handle /api/{{ $service.Name }}{{ $rule.Path }}* { - {{- if $rule.Methods }} - method {{ join $rule.Methods " " }} - {{- end }} - uri strip_prefix /api/{{ $service.Name }} - import cors - reverse_proxy {{ $service.Name }}:8080 { - header_up Host {upstream_hostport} - } - } - {{- end }} - {{- end }} - - handle /versions { - versions { - region "{{ .Platform.Region }}" - env "{{ .Platform.Environment }}" - endpoints { - {{- range $i, $service := .Services }} - {{- $healthCheckEndpoint := $service.HealthCheckEndpoint }} - {{- if eq $healthCheckEndpoint "" }} - {{- $healthCheckEndpoint = "_healthcheck" }} - {{- end }} - - {{- if or (not (semver_is_valid $values.Gateway.Version)) (gt (semver_compare $values.Gateway.Version "v0.1.7") 0) }} - {{ $service.Name }} { - http://{{ $service.Name }}:8080/_info http://{{ $service.Name }}:8080/{{ $service.HealthCheckEndpoint }} - } - {{- else }} - {{ $service.Name }} http://{{ $service.Name }}:8080/_info http://{{ $service.Name }}:8080/{{ $service.HealthCheckEndpoint }} - {{- end }} - {{- end }} - } - } - } - - # Respond 404 if service does not exists - handle /api/* { - respond "Not Found" 404 - } -} \ No newline at end of file diff --git a/components/operator/internal/resources/gateways/caddyfile.go b/components/operator/internal/resources/gateways/caddyfile.go deleted file mode 100644 index 8cb6a5fda2..0000000000 --- a/components/operator/internal/resources/gateways/caddyfile.go +++ /dev/null @@ -1,32 +0,0 @@ -package gateways - -import ( - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/caddy" -) - -func CreateCaddyfile(ctx core.Context, stack *v1beta1.Stack, - gateway *v1beta1.Gateway, httpAPIs []*v1beta1.GatewayHTTPAPI, broker *v1beta1.Broker) (string, error) { - - data := map[string]any{ - "Services": collectionutils.Map(httpAPIs, func(from *v1beta1.GatewayHTTPAPI) v1beta1.GatewayHTTPAPISpec { - return from.Spec - }), - "Platform": ctx.GetPlatform(), - "Debug": stack.Spec.Debug, - "Port": 8080, - "Gateway": map[string]any{ - "Version": gateway.Spec.Version, - }, - } - - // TODO(gfyrag): Check if search is enabled - if stack.Spec.EnableAudit && broker != nil { - data["EnableAudit"] = true - data["Broker"] = broker.Status.URI.Scheme - } - - return caddy.ComputeCaddyfile(ctx, stack, Caddyfile, data) -} diff --git a/components/operator/internal/resources/gateways/configuration.go b/components/operator/internal/resources/gateways/configuration.go deleted file mode 100644 index 1173df6ab5..0000000000 --- a/components/operator/internal/resources/gateways/configuration.go +++ /dev/null @@ -1,33 +0,0 @@ -package gateways - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -func createConfigMap(ctx core.Context, stack *v1beta1.Stack, - gateway *v1beta1.Gateway, httpAPIs []*v1beta1.GatewayHTTPAPI, broker *v1beta1.Broker) (*v1.ConfigMap, error) { - - caddyfile, err := CreateCaddyfile(ctx, stack, gateway, httpAPIs, broker) - if err != nil { - return nil, err - } - - caddyfileConfigMap, _, err := core.CreateOrUpdate[*v1.ConfigMap](ctx, types.NamespacedName{ - Namespace: stack.Name, - Name: "gateway", - }, - func(t *v1.ConfigMap) error { - t.Data = map[string]string{ - "Caddyfile": caddyfile, - } - - return nil - }, - core.WithController[*v1.ConfigMap](ctx.GetScheme(), gateway), - ) - - return caddyfileConfigMap, err -} diff --git a/components/operator/internal/resources/gateways/deployment.go b/components/operator/internal/resources/gateways/deployment.go deleted file mode 100644 index 83ccc8ee83..0000000000 --- a/components/operator/internal/resources/gateways/deployment.go +++ /dev/null @@ -1,44 +0,0 @@ -package gateways - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/applications" - "github.com/formancehq/operator/internal/resources/brokers" - "github.com/formancehq/operator/internal/resources/caddy" - "github.com/formancehq/operator/internal/resources/registries" - v1 "k8s.io/api/core/v1" -) - -func createDeployment(ctx core.Context, stack *v1beta1.Stack, - gateway *v1beta1.Gateway, caddyfileConfigMap *v1.ConfigMap, - broker *v1beta1.Broker, version string) error { - - env := GetEnvVars(gateway) - env = append(env, core.GetDevEnvVars(stack, gateway)...) - - if stack.Spec.EnableAudit && broker != nil { - brokerEnvVar, err := brokers.GetBrokerEnvVars(ctx, broker.Status.URI, stack.Name, "gateway") - if err != nil { - return err - } - - env = append(env, brokerEnvVar...) - } - - image, err := registries.GetImage(ctx, stack, "gateway", version) - if err != nil { - return err - } - - caddyTpl, err := caddy.DeploymentTemplate(ctx, stack, gateway, caddyfileConfigMap, image, env) - if err != nil { - return err - } - - caddyTpl.Name = "gateway" - return applications. - New(gateway, caddyTpl). - IsEE(). - Install(ctx) -} diff --git a/components/operator/internal/resources/gateways/gateways.go b/components/operator/internal/resources/gateways/gateways.go deleted file mode 100644 index 0bce6f77df..0000000000 --- a/components/operator/internal/resources/gateways/gateways.go +++ /dev/null @@ -1,49 +0,0 @@ -package gateways - -import ( - _ "embed" - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - v1 "k8s.io/api/core/v1" -) - -//go:embed Caddyfile.gotpl -var Caddyfile string - -func EnvVarsIfEnabled(ctx core.Context, stackName string) ([]v1.EnvVar, error) { - return EnvVarsIfEnabledWithPrefix(ctx, stackName, "") -} - -func EnvVarsIfEnabledWithPrefix(ctx core.Context, stackName, prefix string) ([]v1.EnvVar, error) { - gateway := &v1beta1.Gateway{} - ok, err := core.GetIfExists(ctx, stackName, gateway) - if err != nil { - return nil, err - } - if !ok { - return nil, nil - } - - return GetEnvVarsWithPrefix(gateway, prefix), nil -} - -func GetEnvVars(gateway *v1beta1.Gateway) []v1.EnvVar { - return GetEnvVarsWithPrefix(gateway, "") -} - -func GetEnvVarsWithPrefix(gateway *v1beta1.Gateway, prefix string) []v1.EnvVar { - ret := []v1.EnvVar{{ - Name: fmt.Sprintf("%sSTACK_URL", prefix), - Value: "http://gateway:8080", - }} - if gateway.Spec.Ingress != nil { - ret = append(ret, v1.EnvVar{ - Name: fmt.Sprintf("%sSTACK_PUBLIC_URL", prefix), - Value: fmt.Sprintf("%s://%s", gateway.Spec.Ingress.Scheme, gateway.Spec.Ingress.Host), - }) - } - - return ret -} diff --git a/components/operator/internal/resources/gateways/ingress.go b/components/operator/internal/resources/gateways/ingress.go deleted file mode 100644 index c5dbdda7a0..0000000000 --- a/components/operator/internal/resources/gateways/ingress.go +++ /dev/null @@ -1,96 +0,0 @@ -package gateways - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/settings" - v1 "k8s.io/api/networking/v1" - "k8s.io/apimachinery/pkg/types" -) - -func createIngress(ctx core.Context, stack *v1beta1.Stack, - gateway *v1beta1.Gateway) error { - - annotations, err := settings.GetMap(ctx, stack.Name, "gateway", "ingress", "annotations") - if err != nil { - return err - } - if annotations == nil { - annotations = map[string]string{} - } - - ingressClassName, err := settings.GetString(ctx, stack.Name, "gateway", "ingress", "class") - if err != nil { - return err - } - - name := types.NamespacedName{ - Namespace: stack.Name, - Name: "gateway", - } - if gateway.Spec.Ingress == nil { - return core.DeleteIfExists[*v1.Ingress](ctx, name) - } - - if gateway.Spec.Ingress.Annotations != nil { - for k, v := range gateway.Spec.Ingress.Annotations { - annotations[k] = v - } - } - - _, _, err = core.CreateOrUpdate[*v1.Ingress](ctx, name, - func(ingress *v1.Ingress) error { - pathType := v1.PathTypePrefix - ingress.ObjectMeta.Annotations = annotations - ingress.Spec.TLS = func() []v1.IngressTLS { - if gateway.Spec.Ingress.TLS == nil { - return nil - } - return []v1.IngressTLS{{ - SecretName: gateway.Spec.Ingress.TLS.SecretName, - Hosts: []string{gateway.Spec.Ingress.Host}, - }} - }() - ingress.Spec.Rules = []v1.IngressRule{ - { - Host: gateway.Spec.Ingress.Host, - IngressRuleValue: v1.IngressRuleValue{ - HTTP: &v1.HTTPIngressRuleValue{ - Paths: []v1.HTTPIngressPath{ - { - Path: "/", - PathType: &pathType, - Backend: v1.IngressBackend{ - Service: &v1.IngressServiceBackend{ - Name: "gateway", - Port: v1.ServiceBackendPort{ - Name: "http", - }, - }, - }, - }, - }, - }, - }, - }, - } - - return nil - }, - func(ingress *v1.Ingress) error { - if gateway.Spec.Ingress.IngressClassName != nil { - ingress.Spec.IngressClassName = gateway.Spec.Ingress.IngressClassName - return nil - } - - if ingressClassName != nil { - ingress.Spec.IngressClassName = ingressClassName - } - - return nil - }, - core.WithController[*v1.Ingress](ctx.GetScheme(), gateway), - ) - - return err -} diff --git a/components/operator/internal/resources/gateways/init.go b/components/operator/internal/resources/gateways/init.go deleted file mode 100644 index c5c25967a5..0000000000 --- a/components/operator/internal/resources/gateways/init.go +++ /dev/null @@ -1,102 +0,0 @@ -/* -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 gateways - -import ( - _ "embed" - "sort" - - "k8s.io/apimachinery/pkg/types" - - . "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/brokertopics" - "github.com/formancehq/operator/internal/resources/services" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" -) - -//+kubebuilder:rbac:groups=formance.com,resources=gateways,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=gateways/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=gateways/finalizers,verbs=update - -func Reconcile(ctx Context, stack *v1beta1.Stack, gateway *v1beta1.Gateway, version string) error { - - httpAPIs := make([]*v1beta1.GatewayHTTPAPI, 0) - err := GetAllStackDependencies(ctx, gateway.Spec.Stack, &httpAPIs) - if err != nil { - return err - } - - sort.Slice(httpAPIs, func(i, j int) bool { - return httpAPIs[i].Spec.Name < httpAPIs[j].Spec.Name - }) - - var broker *v1beta1.Broker - if t, err := brokertopics.Find(ctx, stack, "gateway"); err != nil { - return err - } else if t != nil && t.Status.Ready { - broker = &v1beta1.Broker{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: stack.Name, - }, broker); err != nil { - return err - } - } - - configMap, err := createConfigMap(ctx, stack, gateway, httpAPIs, broker) - if err != nil { - return err - } - - if err := createDeployment(ctx, stack, gateway, configMap, broker, version); err != nil { - return err - } - - if _, err := services.Create(ctx, gateway, "gateway", services.WithDefault("gateway")); err != nil { - return err - } - - if err := createIngress(ctx, stack, gateway); err != nil { - return err - } - - gateway.Status.SyncHTTPAPIs = Map(httpAPIs, func(from *v1beta1.GatewayHTTPAPI) string { - return from.Spec.Name - }) - - return nil -} - -func init() { - Init( - WithModuleReconciler(Reconcile, - WithOwn[*v1beta1.Gateway](&corev1.ConfigMap{}), - WithOwn[*v1beta1.Gateway](&appsv1.Deployment{}), - WithOwn[*v1beta1.Gateway](&corev1.Service{}), - WithOwn[*v1beta1.Gateway](&networkingv1.Ingress{}), - WithOwn[*v1beta1.Gateway](&v1beta1.BenthosStream{}), - WithOwn[*v1beta1.Gateway](&v1beta1.ResourceReference{}), - WithWatchSettings[*v1beta1.Gateway](), - WithWatchDependency[*v1beta1.Gateway](&v1beta1.GatewayHTTPAPI{}), - WithWatchDependency[*v1beta1.Gateway](&v1beta1.Auth{}), - brokertopics.Watch[*v1beta1.Gateway]("gateway"), - ), - ) -} diff --git a/components/operator/internal/resources/gateways/url.go b/components/operator/internal/resources/gateways/url.go deleted file mode 100644 index ac007660b5..0000000000 --- a/components/operator/internal/resources/gateways/url.go +++ /dev/null @@ -1,15 +0,0 @@ -package gateways - -import ( - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" -) - -func URL(gateway *v1beta1.Gateway) string { - if gateway.Spec.Ingress != nil { - return fmt.Sprintf("%s://%s", gateway.Spec.Ingress.Scheme, gateway.Spec.Ingress.Host) - } else { - return fmt.Sprintf("http://gateway:8080") - } -} diff --git a/components/operator/internal/resources/jobs/job.go b/components/operator/internal/resources/jobs/job.go deleted file mode 100644 index 998e4bfc7c..0000000000 --- a/components/operator/internal/resources/jobs/job.go +++ /dev/null @@ -1,141 +0,0 @@ -package jobs - -import ( - "fmt" - - "github.com/formancehq/go-libs/pointer" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/pkg/errors" - batchv1 "k8s.io/api/batch/v1" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/equality" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" -) - -type handleJobConfiguration struct { - preCreate func() error - mutators []core.ObjectMutator[*batchv1.Job] - validator func(job *batchv1.Job) bool -} - -type HandleJobOption func(configuration *handleJobConfiguration) - -func PreCreate(preCreate func() error) HandleJobOption { - return func(configuration *handleJobConfiguration) { - configuration.preCreate = preCreate - } -} - -func Mutator(mutator core.ObjectMutator[*batchv1.Job]) HandleJobOption { - return func(configuration *handleJobConfiguration) { - configuration.mutators = append(configuration.mutators, mutator) - } -} - -func WithServiceAccount(serviceAccountName string) HandleJobOption { - return Mutator(func(t *batchv1.Job) error { - t.Spec.Template.Spec.ServiceAccountName = serviceAccountName - return nil - }) -} - -func WithPodFailurePolicy(p batchv1.PodFailurePolicy) HandleJobOption { - return Mutator(func(t *batchv1.Job) error { - t.Spec.PodFailurePolicy = &p - return nil - }) -} - -func WithValidator(v func(job *batchv1.Job) bool) HandleJobOption { - return func(configuration *handleJobConfiguration) { - configuration.validator = v - } -} - -var defaultOptions = []HandleJobOption{ - WithValidator(func(job *batchv1.Job) bool { - return job.Status.Succeeded > 0 - }), -} - -func Handle(ctx core.Context, owner v1beta1.Dependent, jobName string, container v1.Container, options ...HandleJobOption) error { - - configuration := &handleJobConfiguration{} - for _, option := range append(defaultOptions, options...) { - option(configuration) - } - - jobName = fmt.Sprintf("%s-%s", owner.GetUID(), jobName) - job := &batchv1.Job{} - err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Namespace: owner.GetStack(), - Name: jobName, - }, job) - if err != nil && client.IgnoreNotFound(err) != nil { - return err - } - - if configuration.validator(job) { - return nil - } - - if err == nil { // Job found - if !equality.Semantic.DeepDerivative(container, job.Spec.Template.Spec.Containers[0]) { - if err := ctx.GetClient().Delete(ctx, job, &client.DeleteOptions{ - GracePeriodSeconds: pointer.For(int64(0)), - PropagationPolicy: pointer.For(metav1.DeletePropagationForeground), - }); err != nil { - return err - } - } else { - return core.NewPendingError() - } - } - - if configuration.preCreate != nil { - err := configuration.preCreate() - if err != nil { - return errors.Wrap(err, "in precreate") - } - } - - job = &batchv1.Job{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: owner.GetStack(), - Name: jobName, - }, - Spec: batchv1.JobSpec{ - BackoffLimit: pointer.For(int32(10000)), - TTLSecondsAfterFinished: pointer.For(int32(30)), - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - RestartPolicy: v1.RestartPolicyOnFailure, - Containers: []v1.Container{container}, - }, - }, - }, - } - - for _, mutator := range configuration.mutators { - if err := mutator(job); err != nil { - return err - } - } - - if job.Spec.PodFailurePolicy != nil { - job.Spec.Template.Spec.RestartPolicy = v1.RestartPolicyNever - } - - if err := controllerutil.SetControllerReference(owner, job, ctx.GetScheme()); err != nil { - return err - } - if err := ctx.GetClient().Create(ctx, job); err != nil { - return err - } - - return core.NewPendingError() -} diff --git a/components/operator/internal/resources/ledgers/assets.go b/components/operator/internal/resources/ledgers/assets.go deleted file mode 100644 index 1363d6bf46..0000000000 --- a/components/operator/internal/resources/ledgers/assets.go +++ /dev/null @@ -1,12 +0,0 @@ -package ledgers - -import ( - "embed" - _ "embed" -) - -//go:embed assets/Caddyfile.gotpl -var Caddyfile string - -//go:embed assets/reindex -var reindexStreams embed.FS diff --git a/components/operator/internal/resources/ledgers/assets/Caddyfile.gotpl b/components/operator/internal/resources/ledgers/assets/Caddyfile.gotpl deleted file mode 100644 index d453818639..0000000000 --- a/components/operator/internal/resources/ledgers/assets/Caddyfile.gotpl +++ /dev/null @@ -1,30 +0,0 @@ -{ - {{ if .Debug }}debug{{ end }} -} - -:8080 { - {{- if .EnableOpenTelemetry }} - tracing { - span gateway - } - {{- end }} - log { - output stdout - {{- if .Debug }} - level DEBUG - {{- end }} - } - - handle { - method GET - reverse_proxy ledger-read:8080{ - header_up Host {upstream_hostport} - } - } - - handle { - reverse_proxy ledger-write:8080{ - header_up Host {upstream_hostport} - } - } -} \ No newline at end of file diff --git a/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex.yaml b/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex.yaml deleted file mode 100644 index 8db8e1756c..0000000000 --- a/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex.yaml +++ /dev/null @@ -1,16 +0,0 @@ -input: - http_server: - path: / - -output: - broker: - outputs: - - http_client: - verb: POST - url: http://localhost:4195/ledger_reindex_volumes - - http_client: - verb: POST - url: http://localhost:4195/ledger_reindex_transactions - - http_client: - verb: POST - url: http://localhost:4195/ledger_reindex_accounts diff --git a/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_accounts.yaml b/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_accounts.yaml deleted file mode 100644 index 56dfae153e..0000000000 --- a/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_accounts.yaml +++ /dev/null @@ -1,60 +0,0 @@ -input: - http_server: - path: / - -pipeline: - processors: - - bloblang: | - meta ledger = this.ledger - meta batchSize = 100 - - postgres_query: - service: ledger - query: 'select count(*) as accounts_count from "${! meta("ledger") }".accounts' - - unarchive: - format: json_array - - bloblang: | - meta loopCount = (this.accounts_count.number() / meta("batchSize").number()).ceil() - meta loopIndex = 0 - - bloblang: | - root = if meta("loopCount") == "0" { - deleted() - } - - while: - check: 'meta("loopIndex") < meta("loopCount")' - processors: - - postgres_query: - service: ledger - query: | - select address, metadata - from "${! meta("ledger") }".accounts - offset ${! meta("loopIndex").number() * meta("batchSize").number() } - limit ${! meta("batchSize") } - - bloblang: - meta loopIndex = meta("loopIndex").number() + 1 - - unarchive: - format: json_array - - bloblang: | - root = this.assign({ - "metadata": this.metadata.parse_json() - }) - - bloblang: | - root = { - "document": { - "data": { - "address": this.address, - "ledger": meta("ledger"), - "metadata": this.metadata - }, - "indexed": { - "address": this.address, - "ledger": meta("ledger") - }, - "kind": "ACCOUNT", - "ledger": meta("ledger") - }, - "id": "ACCOUNT-%s-%s".format(meta("ledger"), this.address), - "action": "upsert" - } - -output: - resource: elasticsearch diff --git a/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_all.yaml b/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_all.yaml deleted file mode 100644 index 1a86110be5..0000000000 --- a/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_all.yaml +++ /dev/null @@ -1,18 +0,0 @@ -input: - http_server: - path: / - -pipeline: - processors: - - postgres_query: - service: ledger - query: 'select * from "_system".ledgers' - - unarchive: - format: json_array - -output: - broker: - outputs: - - http_client: - verb: POST - url: http://localhost:4195/ledger_reindex diff --git a/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_transactions.yaml b/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_transactions.yaml deleted file mode 100644 index a8b5cefe53..0000000000 --- a/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_transactions.yaml +++ /dev/null @@ -1,76 +0,0 @@ -input: - http_server: - path: / - -pipeline: - processors: - - bloblang: | - meta ledger = this.ledger - meta batchSize = 100 - - postgres_query: - service: ledger - query: 'select count(*) as transactions_count from "${! meta("ledger") }".transactions' - - unarchive: - format: json_array - - bloblang: | - meta loopCount = (this.transactions_count.number() / meta("batchSize").number()).ceil() - meta loopIndex = 0 - - bloblang: | - root = if meta("loopCount") == "0" { - deleted() - } - - while: - check: 'meta("loopIndex") < meta("loopCount")' - processors: - - postgres_query: - service: ledger - query: | - select id, timestamp, reference, metadata, postings - from "${! meta("ledger") }".transactions - offset ${! meta("loopIndex").number() * meta("batchSize").number() } - limit ${! meta("batchSize") } - - bloblang: - meta loopIndex = meta("loopIndex").number() + 1 - - unarchive: - format: json_array - - bloblang: | - root = this.assign({ - "postings": this.postings.parse_json(), - "metadata": this.metadata.parse_json() - }) - - bloblang: | - root = { - "id": "TRANSACTION-%s-%s".format(meta("ledger"), this.id), - "action": "upsert", - "document": { - "data": { - "postings": this.postings, - "reference": this.reference, - "txid": this.txid, - "timestamp": this.timestamp, - "metadata": if this.metadata { this.metadata } else {{}}, - "ledger": meta("ledger") - }, - "indexed": { - "reference": this.reference, - "txid": this.id, - "timestamp": this.timestamp, - "asset": this.postings.map_each(p -> p.asset), - "source": this.postings.map_each(p -> p.source), - "destination": this.postings.map_each(p -> p.destination), - "amount": this.postings.map_each(p -> if p.asset.contains("/") { - [ - p.amount, - p.amount / range(0, p.asset.split("/").index(1).number()).fold(1, t -> t.tally * 10) # amount / pow(10, decimal part of asset) - ] - } else { [ p.amount ] }).flatten().map_each(v -> "%v".format(v)), - "ledger": meta("ledger") - }, - "kind": "TRANSACTION", - "ledger": meta("ledger"), - "when": this.date - } - } - -output: - resource: elasticsearch diff --git a/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_volumes.yaml b/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_volumes.yaml deleted file mode 100644 index 622238608b..0000000000 --- a/components/operator/internal/resources/ledgers/assets/reindex/v1.0.0/ledger_reindex_volumes.yaml +++ /dev/null @@ -1,60 +0,0 @@ -input: - http_server: - path: / - -pipeline: - processors: - - bloblang: | - meta ledger = this.ledger - meta batchSize = 100 - - postgres_query: - service: ledger - query: 'select count(*) as volumes_count from "${! meta("ledger") }".volumes' - - unarchive: - format: json_array - - bloblang: | - meta loopCount = (this.volumes_count.number() / meta("batchSize").number()).ceil() - meta loopIndex = 0 - - bloblang: | - root = if meta("loopCount") == "0" { - deleted() - } - - while: - check: 'meta("loopIndex") < meta("loopCount")' - processors: - - postgres_query: - service: ledger - query: | - select account, asset, input, output - from "${! meta("ledger") }".volumes - offset ${! meta("loopIndex").number() * meta("batchSize").number() } - limit ${! meta("batchSize") } - - bloblang: - meta loopIndex = meta("loopIndex").number() + 1 - - unarchive: - format: json_array - - bloblang: | - root = { - "id": "ASSET-%s-%s-%s".format(meta("ledger"), this.account, this.asset), - "action": "upsert", - "document": { - "data": { - "name": this.asset, - "input": this.input, - "output": this.output, - "account": this.account, - "ledger": meta("ledger") - }, - "indexed": { - "account": this.account, - "name": this.asset, - "ledger": meta("ledger") - }, - "kind": "ASSET", - "ledger": meta("ledger"), - "when": this.date - } - } - -output: - resource: elasticsearch diff --git a/components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex.yaml b/components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex.yaml deleted file mode 100644 index 00e8546fa7..0000000000 --- a/components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex.yaml +++ /dev/null @@ -1,13 +0,0 @@ -input: - http_server: - path: / - -output: - broker: - outputs: - - http_client: - verb: POST - url: http://localhost:4195/ledger_reindex_transactions - - http_client: - verb: POST - url: http://localhost:4195/ledger_reindex_accounts diff --git a/components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex_accounts.yaml b/components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex_accounts.yaml deleted file mode 100644 index 2853214552..0000000000 --- a/components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex_accounts.yaml +++ /dev/null @@ -1,41 +0,0 @@ -input: - http_server: - path: / - -pipeline: - processors: - - bloblang: | - meta ledger = this.ledger - - postgres_query: - service: ledger - query: | - select address, metadata - from "${! meta("ledger") }".accounts - - unarchive: - format: json_array - - bloblang: | - root = this.assign({ - "metadata": this.metadata.parse_json() - }) - - bloblang: | - root = { - "document": { - "data": { - "address": this.address, - "ledger": meta("ledger"), - "metadata": this.metadata - }, - "indexed": { - "address": this.address, - "ledger": meta("ledger") - }, - "kind": "ACCOUNT", - "ledger": meta("ledger"), - "when": this.date - }, - "id": "ACCOUNT-%s-%s".format(meta("ledger"), this.address), - "action": "upsert" - } - -output: - resource: elasticsearch diff --git a/components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex_all.yaml b/components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex_all.yaml deleted file mode 100644 index 6b8a2b044d..0000000000 --- a/components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex_all.yaml +++ /dev/null @@ -1,20 +0,0 @@ -input: - http_server: - path: / - -pipeline: - processors: - - postgres_query: - service: ledger - query: 'select * from "_system".ledgers' - - unarchive: - format: json_array - - log: - message: "Process ledger: ${! this.ledger }" - -output: - broker: - outputs: - - http_client: - verb: POST - url: http://localhost:4195/ledger_reindex diff --git a/components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex_transactions.yaml b/components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex_transactions.yaml deleted file mode 100644 index 1052d7ac6a..0000000000 --- a/components/operator/internal/resources/ledgers/assets/reindex/v2.0.0/ledger_reindex_transactions.yaml +++ /dev/null @@ -1,56 +0,0 @@ -input: - http_server: - path: / - -pipeline: - processors: - - bloblang: | - meta ledger = this.ledger - - postgres_query: - service: ledger - query: | - select id::varchar as id, timestamp, reference, metadata, postings - from "${! meta("ledger") }".transactions; - - unarchive: - format: json_array - - bloblang: | - root = this.assign({ - "postings": this.postings.parse_json(), - "metadata": this.metadata.parse_json() - }) - - bloblang: | - root = { - "id": "TRANSACTION-%s-%s".format(meta("ledger"), this.id), - "action": "upsert", - "document": { - "data": { - "postings": this.postings, - "reference": this.reference, - "txid": this.id, - "timestamp": this.timestamp, - "metadata": if this.metadata { this.metadata } else {{}}, - "ledger": meta("ledger") - }, - "indexed": { - "reference": this.reference, - "txid": this.id, - "timestamp": this.timestamp, - "asset": this.postings.map_each(p -> p.asset), - "source": this.postings.map_each(p -> p.source), - "destination": this.postings.map_each(p -> p.destination), - "amount": this.postings.map_each(p -> if p.asset.contains("/") { - [ - p.amount, - p.amount / range(0, p.asset.split("/").index(1).number()).fold(1, t -> t.tally * 10) # amount / pow(10, decimal part of asset) - ] - } else { [ p.amount ] }).flatten().map_each(v -> "%v".format(v)), - "ledger": meta("ledger") - }, - "kind": "TRANSACTION", - "ledger": meta("ledger"), - "when": this.date - } - } - -output: - resource: elasticsearch diff --git a/components/operator/internal/resources/ledgers/deployments.go b/components/operator/internal/resources/ledgers/deployments.go deleted file mode 100644 index 4e489ea361..0000000000 --- a/components/operator/internal/resources/ledgers/deployments.go +++ /dev/null @@ -1,438 +0,0 @@ -package ledgers - -import ( - "fmt" - "strconv" - - "github.com/formancehq/operator/internal/resources/brokers" - "github.com/formancehq/operator/internal/resources/brokertopics" - "github.com/formancehq/operator/internal/resources/caddy" - "k8s.io/apimachinery/pkg/types" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/applications" - "github.com/formancehq/operator/internal/resources/auths" - "github.com/formancehq/operator/internal/resources/databases" - "github.com/formancehq/operator/internal/resources/gateways" - "github.com/formancehq/operator/internal/resources/jobs" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/services" - "github.com/formancehq/operator/internal/resources/settings" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -const ( - ConditionTypeDeploymentStrategy = "LedgerDeploymentStrategy" - ReasonLedgerSingle = "Single" - ReasonLedgerMonoWriterMultipleReader = "MonoWriterMultipleReader" -) - -func hasDeploymentStrategyChanged(ctx core.Context, stack *v1beta1.Stack, ledger *v1beta1.Ledger, strategy string) (err error) { - condition := v1beta1.NewCondition(ConditionTypeDeploymentStrategy, ledger.Generation).SetReason( - func() string { - switch strategy { - case v1beta1.DeploymentStrategySingle: - return ReasonLedgerSingle - case v1beta1.DeploymentStrategyMonoWriterMultipleReader: - return ReasonLedgerMonoWriterMultipleReader - default: - return "unknown strategy" - } - }(), - ).SetMessage("Deployment strategy initialized") - - defer func() { - ledger.GetConditions().AppendOrReplace(*condition, v1beta1.AndConditions( - v1beta1.ConditionTypeMatch(ConditionTypeDeploymentStrategy), - v1beta1.ConditionGenerationMatch(ledger.Generation), - )) - }() - - // There is no generation 0, so we can't check for a change in strategy - // Uninstall is useless if the ledger deployment strategy has not changed - if ledger.GetConditions().Check(v1beta1.AndConditions( - v1beta1.ConditionTypeMatch(ConditionTypeDeploymentStrategy), - v1beta1.ConditionReasonMatch(condition.Reason), - v1beta1.ConditionGenerationMatch(ledger.Generation-1), - )) || ledger.GetGeneration() == 1 { - return - } - - condition.SetMessage("Deployment strategy has changed") - switch strategy { - case v1beta1.DeploymentStrategySingle: - return uninstallLedgerMonoWriterMultipleReader(ctx, stack) - case v1beta1.DeploymentStrategyMonoWriterMultipleReader: - return core.DeleteIfExists[*appsv1.Deployment](ctx, core.GetNamespacedResourceName(stack.Name, "ledger")) - default: - return fmt.Errorf("unknown deployment strategy %s", strategy) - } -} - -func installLedger(ctx core.Context, stack *v1beta1.Stack, - ledger *v1beta1.Ledger, database *v1beta1.Database, image string, isV2 bool) (err error) { - - deploymentStrategySettings, err := settings.GetStringOrDefault(ctx, stack.Name, v1beta1.DeploymentStrategySingle, "ledger", "deployment-strategy") - if err != nil { - return err - } - - if ledger.Spec.DeploymentStrategy == v1beta1.DeploymentStrategyMonoWriterMultipleReader { - deploymentStrategySettings = v1beta1.DeploymentStrategyMonoWriterMultipleReader - } - - if err = hasDeploymentStrategyChanged(ctx, stack, ledger, deploymentStrategySettings); err != nil { - return - } - - switch deploymentStrategySettings { - case v1beta1.DeploymentStrategySingle: - return installLedgerSingleInstance(ctx, stack, ledger, database, image, isV2) - case v1beta1.DeploymentStrategyMonoWriterMultipleReader: - return installLedgerMonoWriterMultipleReader(ctx, stack, ledger, database, image, isV2) - default: - return fmt.Errorf("unknown deployment strategy %s", deploymentStrategySettings) - } -} - -func installLedgerSingleInstance(ctx core.Context, stack *v1beta1.Stack, - ledger *v1beta1.Ledger, database *v1beta1.Database, version string, v2 bool) error { - container, err := createLedgerContainerFull(ctx, stack, v2) - if err != nil { - return err - } - - err = setCommonContainerConfiguration(ctx, stack, ledger, version, database, container, v2) - if err != nil { - return err - } - - if !v2 && ledger.Spec.Locking != nil && ledger.Spec.Locking.Strategy == "redis" { - container.Env = append(container.Env, - core.Env("NUMARY_LOCK_STRATEGY", "redis"), - core.Env("NUMARY_LOCK_STRATEGY_REDIS_URL", ledger.Spec.Locking.Redis.Uri), - core.Env("NUMARY_LOCK_STRATEGY_REDIS_TLS_ENABLED", strconv.FormatBool(ledger.Spec.Locking.Redis.TLS)), - core.Env("NUMARY_LOCK_STRATEGY_REDIS_TLS_INSECURE", strconv.FormatBool(ledger.Spec.Locking.Redis.InsecureTLS)), - ) - - if ledger.Spec.Locking.Redis.Duration != 0 { - container.Env = append(container.Env, core.Env("NUMARY_LOCK_STRATEGY_REDIS_DURATION", ledger.Spec.Locking.Redis.Duration.String())) - } - - if ledger.Spec.Locking.Redis.Retry != 0 { - container.Env = append(container.Env, core.Env("NUMARY_LOCK_STRATEGY_REDIS_RETRY", ledger.Spec.Locking.Redis.Retry.String())) - } - } - - if err := createDeployment(ctx, stack, ledger, "ledger", *container, v2, 1); err != nil { - return err - } - - return nil -} - -func getUpgradeContainer(ctx core.Context, stack *v1beta1.Stack, database *v1beta1.Database, image, version string) (corev1.Container, error) { - return databases.MigrateDatabaseContainer(ctx, stack, image, database, - func(m *databases.MigrationConfiguration) { - if core.IsLower(version, "v2.0.0-rc.6") { - m.Command = []string{"buckets", "upgrade-all"} - } - m.AdditionalEnv = []corev1.EnvVar{ - core.Env("STORAGE_POSTGRES_CONN_STRING", "$(POSTGRES_URI)"), - } - }, - ) -} - -func installLedgerMonoWriterMultipleReader(ctx core.Context, stack *v1beta1.Stack, ledger *v1beta1.Ledger, database *v1beta1.Database, image string, v2 bool) error { - - createDeployment := func(name string, container corev1.Container, replicas uint64) error { - err := setCommonContainerConfiguration(ctx, stack, ledger, image, database, &container, v2) - if err != nil { - return err - } - - if err := createDeployment(ctx, stack, ledger, name, container, v2, replicas); err != nil { - return err - } - - if _, err := services.Create(ctx, ledger, name, services.WithDefault(name)); err != nil { - return err - } - - return nil - } - - container, err := createLedgerContainerWriteOnly(ctx, stack, v2) - if err != nil { - return err - } - if err := createDeployment("ledger-write", *container, 1); err != nil { - return err - } - - container = createLedgerContainerReadOnly(v2) - if err := createDeployment("ledger-read", *container, 0); err != nil { - return err - } - - if err := createGatewayDeployment(ctx, stack, ledger); err != nil { - return err - } - - return nil -} - -func uninstallLedgerMonoWriterMultipleReader(ctx core.Context, stack *v1beta1.Stack) error { - - remove := func(name string) error { - if err := core.DeleteIfExists[*appsv1.Deployment](ctx, core.GetNamespacedResourceName(stack.Name, name)); err != nil { - return err - } - if err := core.DeleteIfExists[*corev1.Service](ctx, core.GetNamespacedResourceName(stack.Name, name)); err != nil { - return err - } - - return nil - } - - if err := remove("ledger-write"); err != nil { - return err - } - - if err := remove("ledger-read"); err != nil { - return err - } - - if err := core.DeleteIfExists[*appsv1.Deployment](ctx, core.GetNamespacedResourceName(stack.Name, "ledger-gateway")); err != nil { - return err - } - - return nil -} - -func createDeployment(ctx core.Context, stack *v1beta1.Stack, ledger *v1beta1.Ledger, name string, container corev1.Container, v2 bool, replicas uint64) error { - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - var volumes []corev1.Volume - if !v2 { - volumes = []corev1.Volume{{ - Name: "config", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }} - } - - tpl := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - Spec: appsv1.DeploymentSpec{ - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{container}, - Volumes: volumes, - ServiceAccountName: serviceAccountName, - }, - }, - }, - } - - return applications. - New(ledger, tpl). - WithStateful(replicas > 0). - Install(ctx) -} - -func setCommonContainerConfiguration(ctx core.Context, stack *v1beta1.Stack, ledger *v1beta1.Ledger, image string, database *v1beta1.Database, container *corev1.Container, v2 bool) error { - - prefix := "" - if !v2 { - prefix = "NUMARY_" - } - env := make([]corev1.EnvVar, 0) - otlpEnv, err := settings.GetOTELEnvVarsWithPrefix(ctx, stack.Name, core.LowerCamelCaseKind(ctx, ledger), prefix) - if err != nil { - return err - } - env = append(env, otlpEnv...) - - gatewayEnv, err := gateways.EnvVarsIfEnabledWithPrefix(ctx, stack.Name, prefix) - if err != nil { - return err - } - env = append(env, gatewayEnv...) - env = append(env, core.GetDevEnvVarsWithPrefix(stack, ledger, prefix)...) - - authEnvVars, err := auths.ProtectedAPIEnvVarsWithPrefix(ctx, stack, "ledger", ledger.Spec.Auth, prefix) - if err != nil { - return err - } - env = append(env, authEnvVars...) - - postgresEnvVar, err := databases.PostgresEnvVarsWithPrefix(ctx, stack, database, prefix) - if err != nil { - return err - } - env = append(env, postgresEnvVar...) - - container.Image = image - container.Env = append(container.Env, env...) - container.Env = append(container.Env, core.Env(fmt.Sprintf("%sSTORAGE_POSTGRES_CONN_STRING", prefix), fmt.Sprintf("$(%sPOSTGRES_URI)", prefix))) - container.Env = append(container.Env, core.Env(fmt.Sprintf("%sSTORAGE_DRIVER", prefix), "postgres")) - container.Ports = []corev1.ContainerPort{applications.StandardHTTPPort()} - container.LivenessProbe = applications.DefaultLiveness("http") - - return nil -} - -func createBaseLedgerContainer(v2 bool) *corev1.Container { - ret := &corev1.Container{ - Name: "ledger", - } - var bindFlag = "BIND" - if !v2 { - bindFlag = "NUMARY_SERVER_HTTP_BIND_ADDRESS" - } - ret.Env = append(ret.Env, core.Env(bindFlag, ":8080")) - if !v2 { - ret.VolumeMounts = []corev1.VolumeMount{{ - Name: "config", - ReadOnly: false, - MountPath: "/root/.numary", - }} - } - - return ret -} - -func createLedgerContainerFull(ctx core.Context, stack *v1beta1.Stack, v2 bool) (*corev1.Container, error) { - container := createBaseLedgerContainer(v2) - - var broker *v1beta1.Broker - if t, err := brokertopics.Find(ctx, stack, "ledger"); err != nil { - return nil, err - } else if t != nil && t.Status.Ready { - broker = &v1beta1.Broker{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: stack.Name, - }, broker); err != nil { - return nil, err - } - } - - if broker != nil { - if !broker.Status.Ready { - return nil, core.NewPendingError().WithMessage("broker not ready") - } - prefix := "" - if !v2 { - prefix = "NUMARY_" - } - - brokerEnvVar, err := brokers.GetEnvVarsWithPrefix(ctx, broker.Status.URI, stack.Name, "ledger", prefix) - if err != nil { - return nil, err - } - - container.Env = append(container.Env, brokerEnvVar...) - 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")) - } - - logsBatchSize, err := settings.GetInt(ctx, stack.Name, "ledger", "logs", "max-batch-size") - if err != nil { - return nil, err - } - if logsBatchSize != nil && *logsBatchSize != 0 { - container.Env = append(container.Env, core.Env("LEDGER_BATCH_SIZE", fmt.Sprint(*logsBatchSize))) - } - } - - return container, nil -} - -func createLedgerContainerWriteOnly(ctx core.Context, stack *v1beta1.Stack, v2 bool) (*corev1.Container, error) { - return createLedgerContainerFull(ctx, stack, v2) -} - -func createLedgerContainerReadOnly(v2 bool) *corev1.Container { - container := createBaseLedgerContainer(v2) - container.Env = append(container.Env, core.Env("READ_ONLY", "true")) - return container -} - -func createGatewayDeployment(ctx core.Context, stack *v1beta1.Stack, ledger *v1beta1.Ledger) error { - - caddyfileConfigMap, err := caddy.CreateCaddyfileConfigMap(ctx, stack, "ledger", Caddyfile, map[string]any{ - "Debug": stack.Spec.Debug || ledger.Spec.Debug, - }, core.WithController[*corev1.ConfigMap](ctx.GetScheme(), ledger)) - if err != nil { - return err - } - - env := make([]corev1.EnvVar, 0) - env = append(env, core.GetDevEnvVars(stack, ledger)...) - - caddyImage, err := registries.GetCaddyImage(ctx, stack, "2.7.6-alpine") - if err != nil { - return err - } - - tpl, err := caddy.DeploymentTemplate(ctx, stack, ledger, caddyfileConfigMap, caddyImage, env) - if err != nil { - return err - } - - tpl.Name = "ledger-gateway" - return applications. - New(ledger, tpl). - Install(ctx) -} - -func migrate(ctx core.Context, stack *v1beta1.Stack, ledger *v1beta1.Ledger, database *v1beta1.Database, image, version string) error { - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - upgradeContainer, err := getUpgradeContainer(ctx, stack, database, image, version) - if err != nil { - return err - } - - return jobs.Handle(ctx, ledger, "migrate-v2", upgradeContainer, - jobs.PreCreate(func() error { - list := &appsv1.DeploymentList{} - if err := ctx.GetClient().List(ctx, list, client.InNamespace(stack.Name)); err != nil { - return err - } - - for _, item := range list.Items { - if controller := metav1.GetControllerOf(&item); controller != nil && controller.UID == ledger.GetUID() { - if err := ctx.GetClient().Delete(ctx, &item); err != nil { - return err - } - } - } - return nil - }), - jobs.WithServiceAccount(serviceAccountName), - ) -} diff --git a/components/operator/internal/resources/ledgers/init.go b/components/operator/internal/resources/ledgers/init.go deleted file mode 100644 index ca058737cc..0000000000 --- a/components/operator/internal/resources/ledgers/init.go +++ /dev/null @@ -1,131 +0,0 @@ -/* -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 ledgers - -import ( - _ "embed" - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/benthosstreams" - "github.com/formancehq/operator/internal/resources/brokertopics" - "github.com/formancehq/operator/internal/resources/databases" - "github.com/formancehq/operator/internal/resources/gatewayhttpapis" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/search/benthos" - "github.com/pkg/errors" - "golang.org/x/mod/semver" - appsv1 "k8s.io/api/apps/v1" - batchv1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" -) - -//+kubebuilder:rbac:groups=formance.com,resources=ledgers,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=ledgers/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=ledgers/finalizers,verbs=update -//+kubebuilder:rbac:groups=batch,resources=cronjobs,verbs=get;list;watch;create;update;patch;delete - -func Reconcile(ctx Context, stack *v1beta1.Stack, ledger *v1beta1.Ledger, version string) error { - database, err := databases.Create(ctx, stack, ledger) - if err != nil { - return err - } - - image, err := registries.GetImage(ctx, stack, "ledger", version) - if err != nil { - return err - } - - if err := gatewayhttpapis.Create(ctx, ledger, gatewayhttpapis.WithHealthCheckEndpoint("_healthcheck")); err != nil { - return err - } - - isV2 := false - if !semver.IsValid(version) || semver.Compare(version, "v2.0.0-alpha") > 0 { - isV2 = true - } - - if err := benthosstreams.LoadFromFileSystem(ctx, benthos.Streams, ledger, "streams/ledger", "ingestion"); err != nil { - return err - } - - streamsVersion := "v1.0.0" - if isV2 { - streamsVersion = "v2.0.0" - } - if err := benthosstreams.LoadFromFileSystem(ctx, reindexStreams, ledger, fmt.Sprintf("assets/reindex/%s", streamsVersion), "reindex"); err != nil { - return err - } - - hasDependency, err := HasDependency(ctx, stack.Name, &v1beta1.Search{}) - if err != nil { - return err - } - if hasDependency { - _, err = createReindexCronJob(ctx, ledger) - if err != nil { - return err - } - } else { - err = deleteReindexCronJob(ctx, ledger) - if err != nil { - return err - } - } - - if !database.Status.Ready { - return NewPendingError().WithMessage("database not ready") - } - - if isV2 && databases.GetSavedModuleVersion(database) != version { - if err := migrate(ctx, stack, ledger, database, image, version); err != nil { - return err - } - - if err := databases.SaveModuleVersion(ctx, database, version); err != nil { - return errors.Wrap(err, "saving module version in database object") - } - } - - err = installLedger(ctx, stack, ledger, database, image, isV2) - if err != nil { - return err - } - - return nil -} - -func init() { - Init( - WithModuleReconciler(Reconcile, - WithOwn[*v1beta1.Ledger](&appsv1.Deployment{}), - WithOwn[*v1beta1.Ledger](&batchv1.Job{}), - WithOwn[*v1beta1.Ledger](&corev1.Service{}), - WithOwn[*v1beta1.Ledger](&v1beta1.GatewayHTTPAPI{}), - WithOwn[*v1beta1.Ledger](&v1beta1.Database{}), - WithOwn[*v1beta1.Ledger](&batchv1.CronJob{}), - WithOwn[*v1beta1.Ledger](&corev1.ConfigMap{}), - 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](), - ), - ) -} diff --git a/components/operator/internal/resources/ledgers/reindex.go b/components/operator/internal/resources/ledgers/reindex.go deleted file mode 100644 index 7132fab4fa..0000000000 --- a/components/operator/internal/resources/ledgers/reindex.go +++ /dev/null @@ -1,50 +0,0 @@ -package ledgers - -import ( - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/formancehq/go-libs/pointer" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - batchv1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -func createReindexCronJob(ctx core.Context, ledger *v1beta1.Ledger) (*batchv1.CronJob, error) { - cronJob, _, err := core.CreateOrUpdate[*batchv1.CronJob](ctx, types.NamespacedName{ - Namespace: ledger.Spec.Stack, - Name: "reindex-ledger", - }, func(t *batchv1.CronJob) error { - t.Spec = batchv1.CronJobSpec{ - Suspend: pointer.For(true), - Schedule: "* * * * *", - JobTemplate: batchv1.JobTemplateSpec{ - Spec: batchv1.JobSpec{ - TTLSecondsAfterFinished: pointer.For(int32(30)), - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyOnFailure, - Containers: []corev1.Container{{ - Image: "curlimages/curl:8.2.1", - Name: "reindex-ledger", - Command: core.ShellScript(` - curl http://benthos.%s.svc.cluster.local:4195/ledger_reindex_all -X POST -H 'Content-Type: application/json' -d '{}'`, ledger.Spec.Stack), - }}, - }, - }, - }, - }, - } - - return nil - }, core.WithController[*batchv1.CronJob](ctx.GetScheme(), ledger)) - return cronJob, err -} - -func deleteReindexCronJob(ctx core.Context, ledger *v1beta1.Ledger) error { - cronJob := &batchv1.CronJob{} - cronJob.SetNamespace(ledger.Spec.Stack) - cronJob.SetName("reindex-ledger") - return client.IgnoreNotFound(ctx.GetClient().Delete(ctx, cronJob)) -} diff --git a/components/operator/internal/resources/licence/licence.go b/components/operator/internal/resources/licence/licence.go deleted file mode 100644 index 0376cebf01..0000000000 --- a/components/operator/internal/resources/licence/licence.go +++ /dev/null @@ -1,48 +0,0 @@ -package licence - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/resourcereferences" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -func GetLicenceEnvVars(ctx core.Context, ownerName string, owner v1beta1.Dependent) (*v1beta1.ResourceReference, []v1.EnvVar, error) { - ret := make([]v1.EnvVar, 0) - - platform := ctx.GetPlatform() - - var resourceReference *v1beta1.ResourceReference - var err error - if platform.LicenceSecret != "" { - resourceReference, err = resourcereferences.Create(ctx, owner, ownerName+"-licence", platform.LicenceSecret, &v1.Secret{}) - if err != nil { - return nil, nil, err - } - } else { - err := resourcereferences.Delete(ctx, owner, ownerName+"-licence") - if err != nil { - return nil, nil, err - } - - ret = append(ret, core.Env("LICENCE_ENABLED", "false")) - return nil, ret, nil - } - - ns := &v1.Namespace{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: "kube-system", - }, ns); err != nil { - return nil, nil, err - } - - ret = append(ret, core.Env("LICENCE_ENABLED", "false")) - - ret = append(ret, core.EnvFromSecret("LICENCE_TOKEN", platform.LicenceSecret, "token")) - ret = append(ret, core.EnvFromSecret("LICENCE_ISSUER", platform.LicenceSecret, "issuer")) - ret = append(ret, core.Env("LICENCE_VALIDATE_TICK", "24h")) - ret = append(ret, core.Env("LICENCE_CLUSTER_ID", string(ns.UID))) - - return resourceReference, ret, nil -} diff --git a/components/operator/internal/resources/orchestrations/deployments.go b/components/operator/internal/resources/orchestrations/deployments.go deleted file mode 100644 index 04563e2c8b..0000000000 --- a/components/operator/internal/resources/orchestrations/deployments.go +++ /dev/null @@ -1,208 +0,0 @@ -package orchestrations - -import ( - "fmt" - "strings" - - "github.com/formancehq/operator/internal/resources/brokers" - appsv1 "k8s.io/api/apps/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/applications" - "github.com/formancehq/operator/internal/resources/authclients" - "github.com/formancehq/operator/internal/resources/auths" - "github.com/formancehq/operator/internal/resources/databases" - "github.com/formancehq/operator/internal/resources/gateways" - "github.com/formancehq/operator/internal/resources/resourcereferences" - "github.com/formancehq/operator/internal/resources/settings" - "github.com/pkg/errors" - corev1 "k8s.io/api/core/v1" -) - -func createAuthClient(ctx Context, stack *v1beta1.Stack, orchestration *v1beta1.Orchestration) (*v1beta1.AuthClient, error) { - - hasAuth, err := HasDependency(ctx, stack.Name, &v1beta1.Auth{}) - if err != nil { - return nil, err - } - if !hasAuth { - return nil, nil - } - - return authclients.Create(ctx, stack, orchestration, "orchestration", - func(spec *v1beta1.AuthClientSpec) { - spec.Scopes = []string{ - "ledger:read", - "ledger:write", - "payments:read", - "payments:write", - "wallets:read", - "wallets:write", - } - }) -} - -func createDeployment(ctx Context, stack *v1beta1.Stack, orchestration *v1beta1.Orchestration, - database *v1beta1.Database, client *v1beta1.AuthClient, - consumer *v1beta1.BrokerConsumer, image string) error { - - env := make([]corev1.EnvVar, 0) - otlpEnv, err := settings.GetOTELEnvVars(ctx, stack.Name, LowerCamelCaseKind(ctx, orchestration)) - if err != nil { - return err - } - env = append(env, otlpEnv...) - - gatewayEnv, err := gateways.EnvVarsIfEnabled(ctx, stack.Name) - if err != nil { - return err - } - - postgresEnvVar, err := databases.GetPostgresEnvVars(ctx, stack, database) - if err != nil { - return err - } - - env = append(env, gatewayEnv...) - env = append(env, GetDevEnvVars(stack, orchestration)...) - env = append(env, postgresEnvVar...) - - temporalURI, err := settings.RequireURL(ctx, stack.Name, "temporal", "dsn") - if err != nil { - return err - } - - if err := validateTemporalURI(temporalURI); err != nil { - return err - } - - var temporalSecretResourceReference *v1beta1.ResourceReference - if secret := temporalURI.Query().Get("secret"); secret != "" { - temporalSecretResourceReference, err = resourcereferences.Create(ctx, orchestration, "temporal", secret, &corev1.Secret{}) - } else { - err = resourcereferences.Delete(ctx, orchestration, "temporal") - } - if err != nil { - return err - } - - topics, err := brokers.GetTopicsEnvVars(ctx, stack, "TOPICS", consumer.Spec.Services...) - if err != nil { - return err - } - env = append(env, topics...) - - env = append(env, - Env("POSTGRES_DSN", "$(POSTGRES_URI)"), - Env("TEMPORAL_TASK_QUEUE", stack.Name), - Env("TEMPORAL_ADDRESS", temporalURI.Host), - Env("TEMPORAL_NAMESPACE", temporalURI.Path[1:]), - Env("WORKER", "true"), - ) - - authEnvVars, err := auths.ProtectedEnvVars(ctx, stack, "orchestration", orchestration.Spec.Auth) - if err != nil { - return err - } - env = append(env, authEnvVars...) - - if client != nil { - env = append(env, authclients.GetEnvVars(client)...) - } - - if secret := temporalURI.Query().Get("secret"); secret == "" { - temporalTLSCrt, err := settings.GetStringOrEmpty(ctx, stack.Name, "temporal", "tls", "crt") - if err != nil { - return err - } - - temporalTLSKey, err := settings.GetStringOrEmpty(ctx, stack.Name, "temporal", "tls", "key") - if err != nil { - return err - } - - env = append(env, - Env("TEMPORAL_SSL_CLIENT_KEY", temporalTLSKey), - Env("TEMPORAL_SSL_CLIENT_CERT", temporalTLSCrt), - ) - } else { - env = append(env, - EnvFromSecret("TEMPORAL_SSL_CLIENT_KEY", secret, "tls.key"), - EnvFromSecret("TEMPORAL_SSL_CLIENT_CERT", secret, "tls.crt"), - ) - } - - broker := &v1beta1.Broker{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: stack.Name, - }, broker); err != nil { - return err - } - - brokerEnvVars, err := brokers.GetBrokerEnvVars(ctx, broker.Status.URI, stack.Name, "orchestration") - if err != nil && !errors.Is(err, ErrNotFound) { - return err - } - env = append(env, brokerEnvVars...) - env = append(env, brokers.GetPublisherEnvVars(stack, broker, "orchestration", "")...) - - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - annotations := map[string]string{} - if temporalSecretResourceReference != nil { - annotations["database-secret-hash"] = temporalSecretResourceReference.Status.Hash - } - - maxParallelActivities, err := settings.GetIntOrDefault(ctx, stack.Name, 10, "orchestration", "max-parallel-activities") - if err != nil { - return err - } - env = append(env, Env("TEMPORAL_MAX_PARALLEL_ACTIVITIES", fmt.Sprint(maxParallelActivities))) - - tpl := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "orchestration", - }, - Spec: appsv1.DeploymentSpec{ - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - ServiceAccountName: serviceAccountName, - Containers: []corev1.Container{{ - Name: "api", - Env: env, - Image: image, - Ports: []corev1.ContainerPort{applications.StandardHTTPPort()}, - LivenessProbe: applications.DefaultLiveness("http"), - }}, - }, - }, - }, - } - - return applications. - New(orchestration, tpl). - IsEE(). - Install(ctx) -} - -func validateTemporalURI(temporalURI *v1beta1.URI) error { - if temporalURI.Scheme != "temporal" { - return fmt.Errorf("invalid temporal uri: %s", temporalURI.String()) - } - - if temporalURI.Path == "" { - return fmt.Errorf("invalid temporal uri: %s", temporalURI.String()) - } - - if !strings.HasPrefix(temporalURI.Path, "/") { - return fmt.Errorf("invalid temporal uri: %s", temporalURI.String()) - } - - return nil -} diff --git a/components/operator/internal/resources/orchestrations/init.go b/components/operator/internal/resources/orchestrations/init.go deleted file mode 100644 index dc6cda43d2..0000000000 --- a/components/operator/internal/resources/orchestrations/init.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -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 orchestrations - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/brokerconsumers" - "github.com/formancehq/operator/internal/resources/brokertopics" - "github.com/formancehq/operator/internal/resources/databases" - "github.com/formancehq/operator/internal/resources/gatewayhttpapis" - "github.com/formancehq/operator/internal/resources/jobs" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/settings" - "github.com/pkg/errors" - appsv1 "k8s.io/api/apps/v1" - batchv1 "k8s.io/api/batch/v1" -) - -//+kubebuilder:rbac:groups=formance.com,resources=orchestrations,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=orchestrations/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=orchestrations/finalizers,verbs=update - -func Reconcile(ctx Context, stack *v1beta1.Stack, o *v1beta1.Orchestration, version string) error { - - database, err := databases.Create(ctx, stack, o) - if err != nil { - return err - } - - authClient, err := createAuthClient(ctx, stack, o) - if err != nil { - return err - } - - consumer, err := brokerconsumers.CreateOrUpdateOnAllServices(ctx, o) - if err != nil { - return err - } - - if err := gatewayhttpapis.Create(ctx, o, gatewayhttpapis.WithHealthCheckEndpoint("_healthcheck")); err != nil { - return err - } - - if !database.Status.Ready { - return NewPendingError().WithMessage("database not ready") - } - - image, err := registries.GetImage(ctx, stack, "orchestration", version) - if err != nil { - return errors.Wrap(err, "resolving image") - } - - if IsGreaterOrEqual(version, "v2.0.0-rc.5") && databases.GetSavedModuleVersion(database) != version { - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return errors.Wrap(err, "getting service account name") - } - - migrateContainer, err := databases.MigrateDatabaseContainer(ctx, stack, image, database) - if err != nil { - return errors.Wrap(err, "creating migrate container") - } - - if err := jobs.Handle(ctx, o, "migrate", - migrateContainer, - jobs.WithServiceAccount(serviceAccountName), - ); err != nil { - return err - } - - if err := databases.SaveModuleVersion(ctx, database, version); err != nil { - return errors.Wrap(err, "saving module version in database object") - } - } - - if consumer.Status.Ready { - if err := createDeployment(ctx, stack, o, database, authClient, consumer, image); err != nil { - return err - } - } else { - return NewPendingError().WithMessage("waiting for consumers to be ready") - } - - return nil -} - -func init() { - Init( - WithModuleReconciler(Reconcile, - WithOwn[*v1beta1.Orchestration](&v1beta1.BrokerConsumer{}), - WithOwn[*v1beta1.Orchestration](&v1beta1.AuthClient{}), - WithOwn[*v1beta1.Orchestration](&appsv1.Deployment{}), - WithOwn[*v1beta1.Orchestration](&v1beta1.GatewayHTTPAPI{}), - WithOwn[*v1beta1.Orchestration](&v1beta1.ResourceReference{}), - WithOwn[*v1beta1.Orchestration](&batchv1.Job{}), - WithWatchSettings[*v1beta1.Orchestration](), - WithWatchDependency[*v1beta1.Orchestration](&v1beta1.Ledger{}), - WithWatchDependency[*v1beta1.Orchestration](&v1beta1.Auth{}), - WithWatchDependency[*v1beta1.Orchestration](&v1beta1.Payments{}), - WithWatchDependency[*v1beta1.Orchestration](&v1beta1.Wallets{}), - brokertopics.Watch[*v1beta1.Orchestration]("orchestration"), - databases.Watch[*v1beta1.Orchestration](), - ), - ) -} diff --git a/components/operator/internal/resources/payments/Caddyfile.gotpl b/components/operator/internal/resources/payments/Caddyfile.gotpl deleted file mode 100644 index 33173ff570..0000000000 --- a/components/operator/internal/resources/payments/Caddyfile.gotpl +++ /dev/null @@ -1,49 +0,0 @@ -{ - {{ if .Debug }}debug{{ end }} -} - -:8080 { - {{- if .EnableOpenTelemetry }} - tracing { - span gateway - } - {{- end }} - log { - output stdout - {{- if .Debug }} - level DEBUG - {{- end }} - } - - handle /connectors* { - reverse_proxy payments-connectors:8080 - } - handle /connectors/webhooks* { - reverse_proxy payments-connectors:8080 - } - handle /configs* { - reverse_proxy payments-connectors:8080 - } - - @bank-accounts { - path /bank-accounts* - method POST PATCH - } - - handle @bank-accounts { - reverse_proxy payments-connectors:8080 - } - - @transfer-initiations { - path /transfer-initiations* - method DELETE POST - } - - handle @transfer-initiations { - reverse_proxy payments-connectors:8080 - } - - handle /* { - reverse_proxy payments-read:8080 - } -} \ No newline at end of file diff --git a/components/operator/internal/resources/payments/deployments.go b/components/operator/internal/resources/payments/deployments.go deleted file mode 100644 index c86f7a7ae0..0000000000 --- a/components/operator/internal/resources/payments/deployments.go +++ /dev/null @@ -1,300 +0,0 @@ -package payments - -import ( - "github.com/formancehq/operator/internal/resources/brokers" - "github.com/formancehq/operator/internal/resources/brokertopics" - "github.com/formancehq/operator/internal/resources/caddy" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/settings" - appsv1 "k8s.io/api/apps/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/applications" - "github.com/formancehq/operator/internal/resources/auths" - "github.com/formancehq/operator/internal/resources/databases" - "github.com/formancehq/operator/internal/resources/gateways" - "github.com/formancehq/operator/internal/resources/services" - v1 "k8s.io/api/core/v1" -) - -func getEncryptionKey(ctx core.Context, payments *v1beta1.Payments) (string, error) { - encryptionKey := payments.Spec.EncryptionKey - if encryptionKey == "" { - return settings.GetStringOrEmpty(ctx, payments.Spec.Stack, "payments", "encryption-key") - } - return "", nil -} - -func commonEnvVars(ctx core.Context, stack *v1beta1.Stack, payments *v1beta1.Payments, database *v1beta1.Database) ([]v1.EnvVar, error) { - env := make([]v1.EnvVar, 0) - otlpEnv, err := settings.GetOTELEnvVars(ctx, stack.Name, core.LowerCamelCaseKind(ctx, payments)) - if err != nil { - return nil, err - } - env = append(env, otlpEnv...) - - gatewayEnv, err := gateways.EnvVarsIfEnabled(ctx, stack.Name) - if err != nil { - return nil, err - } - - postgresEnvVar, err := databases.GetPostgresEnvVars(ctx, stack, database) - if err != nil { - return nil, err - } - - env = append(env, gatewayEnv...) - env = append(env, core.GetDevEnvVars(stack, payments)...) - env = append(env, postgresEnvVar...) - - encryptionKey, err := getEncryptionKey(ctx, payments) - if err != nil { - return nil, err - } - env = append(env, - core.Env("POSTGRES_DATABASE_NAME", "$(POSTGRES_DATABASE)"), - core.Env("CONFIG_ENCRYPTION_KEY", encryptionKey), - ) - - return env, nil -} - -func createFullDeployment(ctx core.Context, stack *v1beta1.Stack, - payments *v1beta1.Payments, database *v1beta1.Database, image string) error { - - env, err := commonEnvVars(ctx, stack, payments, database) - if err != nil { - return err - } - - authEnvVars, err := auths.ProtectedEnvVars(ctx, stack, "payments", payments.Spec.Auth) - if err != nil { - return err - } - env = append(env, authEnvVars...) - - var broker *v1beta1.Broker - if t, err := brokertopics.Find(ctx, stack, "payments"); err != nil { - return err - } else if t != nil && t.Status.Ready { - broker = &v1beta1.Broker{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: stack.Name, - }, broker); err != nil { - return err - } - } - - if broker != nil { - if !broker.Status.Ready { - return core.NewPendingError().WithMessage("broker not ready") - } - brokerEnvVar, err := brokers.GetBrokerEnvVars(ctx, broker.Status.URI, stack.Name, "payments") - if err != nil { - return err - } - - env = append(env, brokerEnvVar...) - env = append(env, brokers.GetPublisherEnvVars(stack, broker, "payments", "")...) - } - - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - err = applications. - New(payments, &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "payments", - }, - Spec: appsv1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - ServiceAccountName: serviceAccountName, - Containers: []v1.Container{{ - Name: "api", - Args: []string{"serve"}, - Env: env, - Image: image, - LivenessProbe: applications.DefaultLiveness("http", applications.WithProbePath("/_health")), - Ports: []v1.ContainerPort{applications.StandardHTTPPort()}, - }}, - // Ensure empty - InitContainers: []v1.Container{}, - }, - }, - }, - }). - Install(ctx) - if err != nil { - return err - } - - return nil -} - -func createReadDeployment(ctx core.Context, stack *v1beta1.Stack, payments *v1beta1.Payments, database *v1beta1.Database, image string) error { - - env, err := commonEnvVars(ctx, stack, payments, database) - if err != nil { - return err - } - - authEnvVars, err := auths.ProtectedEnvVars(ctx, stack, "payments", payments.Spec.Auth) - if err != nil { - return err - } - env = append(env, authEnvVars...) - - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - err = applications. - New(payments, &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "payments-read", - }, - Spec: appsv1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - ServiceAccountName: serviceAccountName, - Containers: []v1.Container{{ - Name: "api", - Args: []string{"api", "serve"}, - Env: env, - Image: image, - LivenessProbe: applications.DefaultLiveness("http", applications.WithProbePath("/_health")), - Ports: []v1.ContainerPort{applications.StandardHTTPPort()}, - }}, - // Ensure empty - InitContainers: []v1.Container{}, - }, - }, - }, - }). - Install(ctx) - if err != nil { - return err - } - - _, err = services.Create(ctx, payments, "payments-read", services.WithDefault("payments-read")) - if err != nil { - return err - } - - return nil -} - -func createConnectorsDeployment(ctx core.Context, stack *v1beta1.Stack, payments *v1beta1.Payments, - database *v1beta1.Database, image string) error { - - env, err := commonEnvVars(ctx, stack, payments, database) - if err != nil { - return err - } - - var broker *v1beta1.Broker - if t, err := brokertopics.Find(ctx, stack, "payments"); err != nil { - return err - } else if t != nil && t.Status.Ready { - broker = &v1beta1.Broker{} - if err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Name: stack.Name, - }, broker); err != nil { - return err - } - } - - if broker != nil { - if !broker.Status.Ready { - return core.NewPendingError().WithMessage("broker not ready") - } - brokerEnvVar, err := brokers.GetBrokerEnvVars(ctx, broker.Status.URI, stack.Name, "payments") - if err != nil { - return err - } - - env = append(env, brokerEnvVar...) - env = append(env, brokers.GetPublisherEnvVars(stack, broker, "payments", "")...) - } - - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - err = applications. - New(payments, &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "payments-connectors", - }, - Spec: appsv1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - ServiceAccountName: serviceAccountName, - Containers: []v1.Container{{ - Name: "connectors", - Args: []string{"connectors", "serve"}, - Env: env, - Image: image, - Ports: []v1.ContainerPort{applications.StandardHTTPPort()}, - LivenessProbe: applications.DefaultLiveness("http", - applications.WithProbePath("/_health")), - }}, - // Ensure empty - InitContainers: []v1.Container{}, - }, - }, - }, - }). - WithStateful(true). - Install(ctx) - if err != nil { - return err - } - - _, err = services.Create(ctx, payments, "payments-connectors", services.WithDefault("payments-connectors")) - if err != nil { - return err - } - - return err -} - -func createGateway(ctx core.Context, stack *v1beta1.Stack, p *v1beta1.Payments) error { - - caddyfileConfigMap, err := caddy.CreateCaddyfileConfigMap(ctx, stack, "payments", Caddyfile, map[string]any{ - "Debug": stack.Spec.Debug || p.Spec.Debug, - }, core.WithController[*v1.ConfigMap](ctx.GetScheme(), p)) - if err != nil { - return err - } - - env := make([]v1.EnvVar, 0) - - env = append(env, core.GetDevEnvVars(stack, p)...) - - caddyImage, err := registries.GetCaddyImage(ctx, stack, "2.7.6-alpine") - if err != nil { - return err - } - - deploymentTemplate, err := caddy.DeploymentTemplate(ctx, stack, p, caddyfileConfigMap, caddyImage, env) - if err != nil { - return err - } - // notes(gfyrag): reset init containers in case of upgrading from v1 to v2 - deploymentTemplate.Spec.Template.Spec.InitContainers = make([]v1.Container, 0) - - deploymentTemplate.Name = "payments" - - return applications. - New(p, deploymentTemplate). - Install(ctx) -} diff --git a/components/operator/internal/resources/payments/init.go b/components/operator/internal/resources/payments/init.go deleted file mode 100644 index 0996302bdc..0000000000 --- a/components/operator/internal/resources/payments/init.go +++ /dev/null @@ -1,147 +0,0 @@ -/* -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 payments - -import ( - _ "embed" - "net/http" - - "github.com/formancehq/operator/internal/resources/jobs" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/settings" - "github.com/pkg/errors" - batchv1 "k8s.io/api/batch/v1" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/benthosstreams" - "github.com/formancehq/operator/internal/resources/brokertopics" - "github.com/formancehq/operator/internal/resources/databases" - "github.com/formancehq/operator/internal/resources/gatewayhttpapis" - "github.com/formancehq/search/benthos" - "golang.org/x/mod/semver" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" -) - -//+kubebuilder:rbac:groups=formance.com,resources=payments,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=payments/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=payments/finalizers,verbs=update - -func Reconcile(ctx Context, stack *v1beta1.Stack, p *v1beta1.Payments, version string) error { - - database, err := databases.Create(ctx, stack, p) - if err != nil { - return err - } - - if !database.Status.Ready { - return NewPendingError().WithMessage("database not ready") - } - - image, err := registries.GetImage(ctx, stack, "payments", version) - if err != nil { - return err - } - - if databases.GetSavedModuleVersion(database) != version { - encryptionKey, err := getEncryptionKey(ctx, p) - if err != nil { - return err - } - - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - migrateContainer, err := databases.MigrateDatabaseContainer(ctx, stack, image, database, - func(m *databases.MigrationConfiguration) { - m.AdditionalEnv = []corev1.EnvVar{ - Env("CONFIG_ENCRYPTION_KEY", encryptionKey), - } - }, - ) - if err != nil { - return err - } - - if err := jobs.Handle(ctx, p, "migrate", - migrateContainer, - jobs.WithServiceAccount(serviceAccountName), - ); err != nil { - return err - } - - if err := databases.SaveModuleVersion(ctx, database, version); err != nil { - return errors.Wrap(err, "saving module version in database object") - } - } - - if semver.IsValid(version) && semver.Compare(version, "v1.0.0-alpha") < 0 { - if err := createFullDeployment(ctx, stack, p, database, image); err != nil { - return err - } - } else { - if err := createReadDeployment(ctx, stack, p, database, image); err != nil { - return err - } - - if err := createConnectorsDeployment(ctx, stack, p, database, image); err != nil { - return err - } - if err := createGateway(ctx, stack, p); err != nil { - return err - } - } - - if err := benthosstreams.LoadFromFileSystem(ctx, benthos.Streams, p, "streams/payments", "ingestion"); err != nil { - return err - } - - if err := gatewayhttpapis.Create(ctx, p, - gatewayhttpapis.WithHealthCheckEndpoint("_health"), - gatewayhttpapis.WithRules( - v1beta1.GatewayHTTPAPIRule{ - Path: "/connectors/webhooks", - Methods: []string{http.MethodPost}, - Secured: true, - }, - gatewayhttpapis.RuleSecured(), - )); err != nil { - return err - } - - return nil -} - -func init() { - Init( - WithModuleReconciler(Reconcile, - WithOwn[*v1beta1.Payments](&appsv1.Deployment{}), - WithOwn[*v1beta1.Payments](&corev1.Service{}), - WithOwn[*v1beta1.Payments](&v1beta1.GatewayHTTPAPI{}), - WithOwn[*v1beta1.Payments](&batchv1.Job{}), - WithOwn[*v1beta1.Payments](&corev1.ConfigMap{}), - WithOwn[*v1beta1.Payments](&v1beta1.BenthosStream{}), - WithWatchSettings[*v1beta1.Payments](), - WithWatchDependency[*v1beta1.Payments](&v1beta1.Search{}), - databases.Watch[*v1beta1.Payments](), - brokertopics.Watch[*v1beta1.Payments]("payments"), - ), - ) -} diff --git a/components/operator/internal/resources/payments/payments.go b/components/operator/internal/resources/payments/payments.go deleted file mode 100644 index c6457cf1eb..0000000000 --- a/components/operator/internal/resources/payments/payments.go +++ /dev/null @@ -1,8 +0,0 @@ -package payments - -import ( - _ "embed" -) - -//go:embed Caddyfile.gotpl -var Caddyfile string diff --git a/components/operator/internal/resources/reconciliations/deployments.go b/components/operator/internal/resources/reconciliations/deployments.go deleted file mode 100644 index 1160ec00a0..0000000000 --- a/components/operator/internal/resources/reconciliations/deployments.go +++ /dev/null @@ -1,75 +0,0 @@ -package reconciliations - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/applications" - "github.com/formancehq/operator/internal/resources/authclients" - "github.com/formancehq/operator/internal/resources/auths" - "github.com/formancehq/operator/internal/resources/databases" - "github.com/formancehq/operator/internal/resources/gateways" - "github.com/formancehq/operator/internal/resources/settings" - appsv1 "k8s.io/api/apps/v1" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func createDeployment(ctx core.Context, stack *v1beta1.Stack, reconciliation *v1beta1.Reconciliation, - database *v1beta1.Database, authClient *v1beta1.AuthClient, image string) error { - env := make([]v1.EnvVar, 0) - otlpEnv, err := settings.GetOTELEnvVars(ctx, stack.Name, core.LowerCamelCaseKind(ctx, reconciliation)) - if err != nil { - return err - } - env = append(env, otlpEnv...) - - gatewayEnv, err := gateways.EnvVarsIfEnabled(ctx, stack.Name) - if err != nil { - return err - } - - postgresEnvVar, err := databases.GetPostgresEnvVars(ctx, stack, database) - if err != nil { - return err - } - - env = append(env, gatewayEnv...) - env = append(env, core.GetDevEnvVars(stack, reconciliation)...) - env = append(env, postgresEnvVar...) - env = append(env, core.Env("POSTGRES_DATABASE_NAME", "$(POSTGRES_DATABASE)")) - env = append(env, authclients.GetEnvVars(authClient)...) - - authEnvVars, err := auths.ProtectedEnvVars(ctx, stack, "reconciliation", reconciliation.Spec.Auth) - if err != nil { - return err - } - env = append(env, authEnvVars...) - - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - return applications. - New(reconciliation, &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "reconciliation", - }, - Spec: appsv1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - ServiceAccountName: serviceAccountName, - Containers: []v1.Container{{ - Name: "reconciliation", - Env: env, - Image: image, - Ports: []v1.ContainerPort{applications.StandardHTTPPort()}, - LivenessProbe: applications.DefaultLiveness("http"), - }}, - }, - }, - }, - }). - IsEE(). - Install(ctx) -} diff --git a/components/operator/internal/resources/reconciliations/init.go b/components/operator/internal/resources/reconciliations/init.go deleted file mode 100644 index 6c4fa62ecf..0000000000 --- a/components/operator/internal/resources/reconciliations/init.go +++ /dev/null @@ -1,105 +0,0 @@ -/* -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 reconciliations - -import ( - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/authclients" - "github.com/formancehq/operator/internal/resources/databases" - "github.com/formancehq/operator/internal/resources/gatewayhttpapis" - "github.com/formancehq/operator/internal/resources/jobs" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/settings" - "github.com/pkg/errors" - appsv1 "k8s.io/api/apps/v1" - batchv1 "k8s.io/api/batch/v1" -) - -//+kubebuilder:rbac:groups=formance.com,resources=reconciliations,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=reconciliations/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=reconciliations/finalizers,verbs=update - -func Reconcile(ctx Context, stack *v1beta1.Stack, reconciliation *v1beta1.Reconciliation, version string) error { - database, err := databases.Create(ctx, stack, reconciliation) - if err != nil { - return err - } - - authClient, err := authclients.Create(ctx, stack, reconciliation, "reconciliation", - authclients.WithScopes("ledger:read", "payments:read")) - if err != nil { - return err - } - - if database.Status.Ready { - - image, err := registries.GetImage(ctx, stack, "reconciliation", version) - if err != nil { - return errors.Wrap(err, "resolving image") - } - - if IsGreaterOrEqual(version, "v2.0.0-rc.5") && databases.GetSavedModuleVersion(database) != version { - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return errors.Wrap(err, "resolving service account") - } - - migrateContainer, err := databases.MigrateDatabaseContainer(ctx, stack, image, database) - if err != nil { - return errors.Wrap(err, "creating migration container") - } - - if err := jobs.Handle(ctx, reconciliation, "migrate", - migrateContainer, - jobs.WithServiceAccount(serviceAccountName), - ); err != nil { - return err - } - - if err := databases.SaveModuleVersion(ctx, database, version); err != nil { - return errors.Wrap(err, "saving module version in database object") - } - } - - if err := createDeployment(ctx, stack, reconciliation, database, authClient, image); err != nil { - return err - } - } - - if err := gatewayhttpapis.Create(ctx, reconciliation, gatewayhttpapis.WithHealthCheckEndpoint("_healthcheck")); err != nil { - return err - } - - return nil -} - -func init() { - Init( - WithModuleReconciler(Reconcile, - WithOwn[*v1beta1.Reconciliation](&v1beta1.Database{}), - WithOwn[*v1beta1.Reconciliation](&appsv1.Deployment{}), - WithOwn[*v1beta1.Reconciliation](&v1beta1.AuthClient{}), - WithOwn[*v1beta1.Reconciliation](&v1beta1.GatewayHTTPAPI{}), - WithOwn[*v1beta1.Reconciliation](&batchv1.Job{}), - WithOwn[*v1beta1.Reconciliation](&v1beta1.ResourceReference{}), - WithWatchSettings[*v1beta1.Reconciliation](), - WithWatchDependency[*v1beta1.Reconciliation](&v1beta1.Ledger{}), - WithWatchDependency[*v1beta1.Reconciliation](&v1beta1.Payments{}), - ), - ) -} diff --git a/components/operator/internal/resources/registries/image.go b/components/operator/internal/resources/registries/image.go deleted file mode 100644 index 0903c4c7d5..0000000000 --- a/components/operator/internal/resources/registries/image.go +++ /dev/null @@ -1,57 +0,0 @@ -package registries - -import ( - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/settings" -) - -// Format Accepted: -// ENDPOINT/ORGANIZATION/REPOSITORY:VERSION -// ghcr.io//: -// public.ecr.aws//jeffail/benthos -// docker.io//: - -func NormalizeVersion(version string) string { - if version == "" { - version = "latest" - } - return version -} - -func GetImage(ctx core.Context, stack *v1beta1.Stack, name, version string) (string, error) { - return TranslateImage(stack.Name, NewImageSettingsOverrider(ctx), - fmt.Sprintf("ghcr.io/formancehq/%s:%s", name, NormalizeVersion(version))) -} - -func GetBenthosImage(ctx core.Context, stack *v1beta1.Stack, version string) (string, error) { - return TranslateImage(stack.Name, NewImageSettingsOverrider(ctx), - fmt.Sprintf("public.ecr.aws/formance-internal/jeffail/benthos:%s", NormalizeVersion(version))) -} - -func GetNatsBoxImage(ctx core.Context, stack *v1beta1.Stack, version string) (string, error) { - return TranslateImage(stack.Name, NewImageSettingsOverrider(ctx), - fmt.Sprintf("docker.io/natsio/nats-box:%s", NormalizeVersion(version))) -} - -func GetCaddyImage(ctx core.Context, stack *v1beta1.Stack, version string) (string, error) { - image := fmt.Sprintf("docker.io/caddy/caddy:%s", NormalizeVersion(version)) - newCaddyImage, err := TranslateImage(stack.Name, NewImageSettingsOverrider(ctx), - image) - if err != nil { - return "", err - } - - defaultCaddyImage := "caddy:2.7.6-alpine" - caddyImage, err := settings.GetStringOrDefault(ctx, stack.Name, defaultCaddyImage, "caddy", "image") - if err != nil { - return "", err - } - if newCaddyImage != image && caddyImage == defaultCaddyImage { - caddyImage = newCaddyImage - } - - return caddyImage, nil -} diff --git a/components/operator/internal/resources/registries/registries.go b/components/operator/internal/resources/registries/registries.go deleted file mode 100644 index d390bd3a88..0000000000 --- a/components/operator/internal/resources/registries/registries.go +++ /dev/null @@ -1,82 +0,0 @@ -package registries - -import ( - "fmt" - "strings" - - "github.com/formancehq/operator/internal/resources/settings" - - "github.com/formancehq/operator/internal/core" -) - -// ghcr.io//: -// public.ecr.aws//jeffail/benthos: -// docker.io//: -// version: "v2.0.0-rc.35-scratch@sha256:4a29620448a90f3ae50d2e375c993b86ef141ead4b6ac1edd1674e9ff6b933f8" -// docker.io//:v2.0.0-rc.35-scratch@sha256:4a29620448a90f3ae50d2e375c993b86ef141ead4b6ac1edd1674e9ff6b933f8 -type imageOrigin struct { - Registry string - Image string - Version string -} - -func (o imageOrigin) String() string { - return fmt.Sprintf("%s/%s:%s", o.Registry, o.Image, o.Version) -} - -//go:generate mockgen -source ./registries.go -destination ./registries_generated.go -package registries . ImageSettingsOverrider -type ImageSettingsOverrider interface { - OverrideWithSetting(*imageOrigin, string) error -} - -type defaultImageSettingOverrider struct { - ctx core.Context -} - -func NewImageSettingsOverrider(ctx core.Context) ImageSettingsOverrider { - return &defaultImageSettingOverrider{ctx: ctx} -} - -func (is *defaultImageSettingOverrider) OverrideWithSetting(o *imageOrigin, stackName string) (err error) { - imageOverride, err := settings.GetStringOrEmpty(is.ctx, stackName, "registries", o.Registry, "images", o.Image, "rewrite") - if err != nil { - return err - } - if imageOverride != "" { - o.Image = imageOverride - } - - registryEndpoint, err := settings.GetStringOrEmpty(is.ctx, stackName, "registries", o.Registry, "endpoint") - if err != nil { - return err - } - if registryEndpoint != "" { - o.Registry = registryEndpoint - } - - return nil -} - -func TranslateImage( - stackName string, - settingsOverrider ImageSettingsOverrider, - image string, -) (string, error) { - repository, version, found := strings.Cut(image, ":") - if !found { - return "", fmt.Errorf("invalid image format: %s", image) - } - - organizationImage := strings.SplitN(repository, "/", 2) - origin := &imageOrigin{ - Registry: organizationImage[0], - Image: organizationImage[1], - Version: version, - } - - if err := settingsOverrider.OverrideWithSetting(origin, stackName); err != nil { - return "", err - } - - return origin.String(), nil -} diff --git a/components/operator/internal/resources/registries/registries_generated.go b/components/operator/internal/resources/registries/registries_generated.go deleted file mode 100644 index 808d33f32c..0000000000 --- a/components/operator/internal/resources/registries/registries_generated.go +++ /dev/null @@ -1,53 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: ./registries.go -// -// Generated by this command: -// -// mockgen -source ./registries.go -destination ./registries_generated.go -package registries . ImageSettingsOverrider -// - -// Package registries is a generated GoMock package. -package registries - -import ( - reflect "reflect" - - gomock "go.uber.org/mock/gomock" -) - -// MockImageSettingsOverrider is a mock of ImageSettingsOverrider interface. -type MockImageSettingsOverrider struct { - ctrl *gomock.Controller - recorder *MockImageSettingsOverriderMockRecorder -} - -// MockImageSettingsOverriderMockRecorder is the mock recorder for MockImageSettingsOverrider. -type MockImageSettingsOverriderMockRecorder struct { - mock *MockImageSettingsOverrider -} - -// NewMockImageSettingsOverrider creates a new mock instance. -func NewMockImageSettingsOverrider(ctrl *gomock.Controller) *MockImageSettingsOverrider { - mock := &MockImageSettingsOverrider{ctrl: ctrl} - mock.recorder = &MockImageSettingsOverriderMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockImageSettingsOverrider) EXPECT() *MockImageSettingsOverriderMockRecorder { - return m.recorder -} - -// OverrideWithSetting mocks base method. -func (m *MockImageSettingsOverrider) OverrideWithSetting(arg0 *imageOrigin, arg1 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "OverrideWithSetting", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// OverrideWithSetting indicates an expected call of OverrideWithSetting. -func (mr *MockImageSettingsOverriderMockRecorder) OverrideWithSetting(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OverrideWithSetting", reflect.TypeOf((*MockImageSettingsOverrider)(nil).OverrideWithSetting), arg0, arg1) -} diff --git a/components/operator/internal/resources/registries/registries_test.go b/components/operator/internal/resources/registries/registries_test.go deleted file mode 100644 index b11455328e..0000000000 --- a/components/operator/internal/resources/registries/registries_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package registries_test - -import ( - "testing" - - "github.com/formancehq/operator/internal/resources/registries" - "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" -) - -func TestTranslateImage(t *testing.T) { - ctrl := gomock.NewController(t) - t.Cleanup(ctrl.Finish) - - type testCase struct { - url string - } - // ghcr.io//: - // public.ecr.aws//jeffail/benthos: - // docker.io//: - // version: "v2.0.0-rc.35-scratch@sha256:4a29620448a90f3ae50d2e375c993b86ef141ead4b6ac1edd1674e9ff6b933f8" - // docker.io//:v2.0.0-rc.35-scratch@sha256:4a29620448a90f3ae50d2e375c993b86ef141ead4b6ac1edd1674e9ff6b933f8 - testCases := []testCase{ - { - url: "ghcr.io/formancehq/stack:latest", - }, - { - url: "public.ecr.aws/formance-internal/jeffail/benthos:latest", - }, - { - url: "docker.io/natsio/nats-box:latest", - }, - { - url: "docker.io/caddy/caddy:2.7.6-alpine", - }, - { - url: "ghcr.io/formancehq/operator-utils:v2.0.0-rc.35-scratch@sha256:4a29620448a90f3ae50d2e375c993b86ef141ead4b6ac1edd1674e9ff6b933f8", - }, - } - - for _, tc := range testCases { - mockImageSettingsOverrider := registries.NewMockImageSettingsOverrider(ctrl) - mockImageSettingsOverrider.EXPECT().OverrideWithSetting(gomock.Any(), gomock.Any()).Return(nil) - - fullImageString, err := registries.TranslateImage("stackName", mockImageSettingsOverrider, tc.url) - require.NoError(t, err) - require.Equal(t, tc.url, fullImageString) - } -} diff --git a/components/operator/internal/resources/resourcereferences/create.go b/components/operator/internal/resources/resourcereferences/create.go deleted file mode 100644 index d795514e71..0000000000 --- a/components/operator/internal/resources/resourcereferences/create.go +++ /dev/null @@ -1,55 +0,0 @@ -package resourcereferences - -import ( - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" -) - -func Create(ctx core.Context, owner v1beta1.Dependent, name, resourceName string, object client.Object) (*v1beta1.ResourceReference, error) { - - gvk, err := apiutil.GVKForObject(object, ctx.GetScheme()) - if err != nil { - return nil, err - } - - resourceReferenceName := fmt.Sprintf("%s-%s", owner.GetName(), name) - resourceReference, _, err := core.CreateOrUpdate[*v1beta1.ResourceReference](ctx, types.NamespacedName{ - Name: resourceReferenceName, - }, func(t *v1beta1.ResourceReference) error { - t.Spec.Stack = owner.GetStack() - t.Spec.Name = resourceName - t.Spec.GroupVersionKind = &metav1.GroupVersionKind{ - Group: gvk.Group, - Version: gvk.Version, - Kind: gvk.Kind, - } - - return nil - }, core.WithController[*v1beta1.ResourceReference](ctx.GetScheme(), owner)) - if err != nil { - return nil, err - } - - if !resourceReference.Status.Ready { - return nil, core.NewPendingError() - } - - return resourceReference, nil -} - -func Delete(ctx core.Context, owner v1beta1.Dependent, name string) error { - resourceReferenceName := fmt.Sprintf("%s-%s", owner.GetName(), name) - reference := &v1beta1.ResourceReference{} - reference.SetNamespace(owner.GetStack()) - reference.SetName(resourceReferenceName) - if err := ctx.GetClient().Delete(ctx, reference); client.IgnoreNotFound(err) != nil { - return err - } - return nil -} diff --git a/components/operator/internal/resources/resourcereferences/init.go b/components/operator/internal/resources/resourcereferences/init.go deleted file mode 100644 index 2023cc0119..0000000000 --- a/components/operator/internal/resources/resourcereferences/init.go +++ /dev/null @@ -1,226 +0,0 @@ -package resourcereferences - -import ( - "fmt" - "strings" - - "github.com/imdario/mergo" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/pkg/errors" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/selection" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -//+kubebuilder:rbac:groups=formance.com,resources=resourcereferences,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=resourcereferences/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=resourcereferences/finalizers,verbs=update -// +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=core,resources=serviceaccounts,verbs=get;list;watch;create;update;patch;delete - -func init() { - core.Init( - core.WithStackDependencyReconciler[*v1beta1.ResourceReference](Reconcile, - core.WithWatch[*v1beta1.ResourceReference, *v1.Secret](watchResource[*v1.Secret]), - core.WithWatch[*v1beta1.ResourceReference, *v1.ServiceAccount](watchResource[*v1.ServiceAccount]), - ), - ) -} - -func watchResource[T client.Object](ctx core.Context, object T) []reconcile.Request { - ret := make([]reconcile.Request, 0) - - // Watch resources created by the ResourceReference - var resourceReference string - for _, reference := range object.GetOwnerReferences() { - gvk, err := apiutil.GVKForObject(&v1beta1.ResourceReference{}, ctx.GetScheme()) - if err != nil { - panic(err) - } - apiVersion, kind := gvk.ToAPIVersionAndKind() - if reference.Kind == kind && reference.APIVersion == apiVersion { - resourceReference = reference.Name - break - } - } - - if resourceReference != "" { - return append(ret, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: resourceReference, - }, - }) - } - - // Watch resources which should be replicated by the ResourceReferences - if object.GetLabels()[v1beta1.StackLabel] != "any" { - for _, stack := range strings.Split(object.GetLabels()[v1beta1.StackLabel], ",") { - ret = append(ret, core.BuildReconcileRequests( - ctx, - ctx.GetClient(), - ctx.GetScheme(), - &v1beta1.ResourceReference{}, - client.MatchingFields{ - "stack": stack, - }, - )...) - } - } else { - ret = append(ret, core.BuildReconcileRequests( - ctx, - ctx.GetClient(), - ctx.GetScheme(), - &v1beta1.ResourceReference{}, - )...) - } - - return ret -} - -const ( - AnyValue = "any" - - RewrittenResourceName = "formance.com/referenced-by-name" -) - -func Reconcile(ctx core.Context, stack *v1beta1.Stack, req *v1beta1.ResourceReference) error { - resource, err := findMatchingResource(ctx, stack.Name, *req.Spec.GroupVersionKind, req.Spec.Name) - if err != nil { - return err - } - - gvk := schema.GroupVersionKind{ - Group: req.Spec.GroupVersionKind.Group, - Version: req.Spec.GroupVersionKind.Version, - Kind: req.Spec.GroupVersionKind.Kind, - } - - if req.Status.SyncedResource != "" && req.Spec.Name != req.Status.SyncedResource { - oldResource := &unstructured.Unstructured{} - oldResource.SetGroupVersionKind(gvk) - err := ctx.GetClient().Get(ctx, types.NamespacedName{ - Namespace: stack.Name, - Name: req.Status.SyncedResource, - }, oldResource) - if client.IgnoreNotFound(err) != nil { - return err - } - - if err == nil { // Can be not found, if the resource has been manually deleted - patch := client.MergeFrom(oldResource.DeepCopy()) - if err := controllerutil.RemoveOwnerReference(req, oldResource, ctx.GetScheme()); err == nil { - if err := ctx.GetClient().Patch(ctx, oldResource, patch); err != nil { - return nil - } - } - if len(oldResource.GetOwnerReferences()) == 0 { - if err := ctx.GetClient().Delete(ctx, oldResource); err != nil { - return err - } - } - } - } - - annotations := make(map[string]any) - originalMetadata := resource.UnstructuredContent()["metadata"] - if originalMetadata != nil { - metadata := originalMetadata.(map[string]any) - originalAnnotations := metadata["annotations"] - if originalAnnotations != nil { - annotations = originalAnnotations.(map[string]any) - } - } - - unstructured.RemoveNestedField(resource.UnstructuredContent(), "metadata") - unstructured.RemoveNestedField(resource.UnstructuredContent(), "status") - - newResource := &unstructured.Unstructured{} - newResource.SetGroupVersionKind(gvk) - newResource.SetNamespace(stack.Name) - newResource.SetName(req.Spec.Name) - - _, err = controllerutil.CreateOrUpdate(ctx, ctx.GetClient(), newResource, func() error { - content := newResource.UnstructuredContent() - if err := mergo.MergeWithOverwrite(&content, resource.UnstructuredContent()); err != nil { - return err - } - - if err := unstructured.SetNestedMap(content, annotations, "metadata", "annotations"); err != nil { - panic(err) - } - - hasOwnerReference, err := core.HasOwnerReference(ctx, req, newResource) - if err != nil { - return err - } - if !hasOwnerReference { - if err := controllerutil.SetOwnerReference(req, newResource, ctx.GetScheme()); err != nil { - return err - } - } - - return nil - }) - if err != nil { - return err - } - - req.Status.Hash = core.HashFromResources(newResource) - req.Status.SyncedResource = req.Spec.Name - - return nil -} - -func findMatchingResource(ctx core.Context, stack string, gvk metav1.GroupVersionKind, name string) (*unstructured.Unstructured, error) { - requirement, err := labels.NewRequirement(v1beta1.StackLabel, selection.In, []string{stack, AnyValue}) - if err != nil { - return nil, err - } - - list := &unstructured.UnstructuredList{} - list.SetGroupVersionKind(schema.GroupVersionKind{ - Group: gvk.Group, - Version: gvk.Version, - Kind: gvk.Kind, - }) - if err := ctx.GetClient().List(ctx, list, &client.ListOptions{ - LabelSelector: labels.NewSelector().Add(*requirement), - }); err != nil { - return nil, errors.Wrap(err, "listing resources") - } - - foundResources := make([]*unstructured.Unstructured, 0) - for _, item := range list.Items { - resourceName, ok := item.GetAnnotations()[RewrittenResourceName] - if !ok { - resourceName = item.GetName() - } - - if resourceName != name { - continue - } - foundResources = append(foundResources, item.DeepCopy()) - } - - if len(foundResources) > 1 { - return nil, fmt.Errorf("found more than one matching item for '%s': %s", name, collectionutils.Map(foundResources, func(from *unstructured.Unstructured) string { - return from.GetName() - })) - } - if len(foundResources) == 0 { - return nil, fmt.Errorf("item not found: %s", name) - } - - return foundResources[0], nil -} diff --git a/components/operator/internal/resources/searches/benthos/audit/gateway_audit.yaml b/components/operator/internal/resources/searches/benthos/audit/gateway_audit.yaml deleted file mode 100644 index 431d364dd1..0000000000 --- a/components/operator/internal/resources/searches/benthos/audit/gateway_audit.yaml +++ /dev/null @@ -1,34 +0,0 @@ -input: - event_bus: - topic: gateway - consumer_group: search - -pipeline: - processors: - - log: - message: "receive audit message: ${! this.payload.id }" - - switch_event_type: - events: - - label: AUDIT - version: v1 - processors: - - bloblang: | - root = { - "document": { - "data": this.payload, - "indexed": { - "identity": this.payload.identity, - "requestPath": this.payload.request.path, - "requestMethod": this.payload.request.method, - "responseStatusCode": this.payload.response.status_code, - }, - "kind": "AUDIT", - "when": this.date - }, - "action": "index", - "id": "AUDIT-%s".format(this.payload.id) - } - - -output: - resource: elasticsearch diff --git a/components/operator/internal/resources/searches/benthos/fs.go b/components/operator/internal/resources/searches/benthos/fs.go deleted file mode 100644 index e0452abe26..0000000000 --- a/components/operator/internal/resources/searches/benthos/fs.go +++ /dev/null @@ -1,11 +0,0 @@ -package benthos - -import ( - "embed" -) - -//go:embed global -var Global embed.FS - -//go:embed audit -var Audit embed.FS diff --git a/components/operator/internal/resources/searches/benthos/global/config.yaml b/components/operator/internal/resources/searches/benthos/global/config.yaml deleted file mode 100644 index c91c6a81ca..0000000000 --- a/components/operator/internal/resources/searches/benthos/global/config.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -tracer: - open_telemetry_collector: - tags: - service.name: search-ingester - service.version: latest - grpc: - - url: ${OTEL_TRACES_EXPORTER_OTLP_ENDPOINT} - # a useless comment diff --git a/components/operator/internal/resources/searches/clean_legacy_consumers.go b/components/operator/internal/resources/searches/clean_legacy_consumers.go deleted file mode 100644 index 54b6fa7d7d..0000000000 --- a/components/operator/internal/resources/searches/clean_legacy_consumers.go +++ /dev/null @@ -1,44 +0,0 @@ -package searches - -import ( - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/jobs" - "github.com/formancehq/operator/internal/resources/settings" - corev1 "k8s.io/api/core/v1" -) - -func cleanConsumers(ctx Context, search *v1beta1.Search) error { - - brokerURI, err := settings.RequireURL(ctx, search.Spec.Stack, "broker", "dsn") - if err != nil { - return err - } - - if brokerURI == nil { - return nil - } - - //todo: better handle errors - const script = ` - for service in ledger payments audit; do - for consumer in search-ledgerv2 search-payments-resets search-audit; do - index=$(nats --server $NATS_URI consumer ls $STACK-$service -j | jq "index(\"$consumer\")") - if [ "$index" != "null" ]; then - nats --server $NATS_URI consumer rm $STACK-$service $consumer -f || true - fi - done - done -` - return jobs.Handle(ctx, search, "clean-consumers", corev1.Container{ - Image: "natsio/nats-box:0.14.1", - Name: "delete-consumer", - Args: ShellScript(script), - Env: []corev1.EnvVar{ - Env("NATS_URI", fmt.Sprintf("nats://%s", brokerURI.Host)), - Env("STACK", search.Spec.Stack), - }, - }) -} diff --git a/components/operator/internal/resources/searches/init.go b/components/operator/internal/resources/searches/init.go deleted file mode 100644 index 97857a185f..0000000000 --- a/components/operator/internal/resources/searches/init.go +++ /dev/null @@ -1,247 +0,0 @@ -/* -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 searches - -import ( - "fmt" - "strconv" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/applications" - "github.com/formancehq/operator/internal/resources/auths" - "github.com/formancehq/operator/internal/resources/brokerconsumers" - "github.com/formancehq/operator/internal/resources/gatewayhttpapis" - "github.com/formancehq/operator/internal/resources/gateways" - . "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/resourcereferences" - "github.com/formancehq/operator/internal/resources/settings" - appsv1 "k8s.io/api/apps/v1" - v1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -//+kubebuilder:rbac:groups=formance.com,resources=searches,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=searches/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=searches/finalizers,verbs=update - -func Reconcile(ctx Context, stack *v1beta1.Stack, search *v1beta1.Search, version string) error { - elasticSearchURI, err := settings.RequireURL(ctx, stack.Name, "elasticsearch", "dsn") - if err != nil { - return err - } - - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - awsIAMEnabled := serviceAccountName != "" - - var elasticSearchSecretResourceRef *v1beta1.ResourceReference - if secret := elasticSearchURI.Query().Get("secret"); !awsIAMEnabled && secret != "" { - elasticSearchSecretResourceRef, err = resourcereferences.Create(ctx, search, "elasticsearch", secret, &corev1.Secret{}) - } else { - err = resourcereferences.Delete(ctx, search, "elasticsearch") - } - if err != nil { - return err - } - - env := make([]corev1.EnvVar, 0) - if awsIAMEnabled { - env = append(env, Env("AWS_IAM_ENABLED", "true")) - } - - otlpEnv, err := settings.GetOTELEnvVars(ctx, stack.Name, LowerCamelCaseKind(ctx, search)) - if err != nil { - return err - } - env = append(env, otlpEnv...) - env = append(env, GetDevEnvVars(stack, search)...) - - gatewayEnvVars, err := gateways.EnvVarsIfEnabled(ctx, stack.Name) - if err != nil { - return err - } - env = append(env, gatewayEnvVars...) - - env = append(env, - Env("OPEN_SEARCH_SERVICE", elasticSearchURI.Host), - Env("OPEN_SEARCH_SCHEME", elasticSearchURI.Scheme), - Env("ES_INDICES", "stacks"), - ) - if secret := elasticSearchURI.Query().Get("secret"); elasticSearchURI.User != nil || secret != "" { - if secret == "" { - password, _ := elasticSearchURI.User.Password() - env = append(env, - Env("OPEN_SEARCH_USERNAME", elasticSearchURI.User.Username()), - Env("OPEN_SEARCH_PASSWORD", password), - ) - } else { - env = append(env, - EnvFromSecret("OPEN_SEARCH_USERNAME", secret, "username"), - EnvFromSecret("OPEN_SEARCH_PASSWORD", secret, "password"), - ) - } - } - - authEnvVars, err := auths.ProtectedEnvVars(ctx, stack, "search", search.Spec.Auth) - if err != nil { - return err - } - env = append(env, authEnvVars...) - - image, err := GetImage(ctx, stack, "search", version) - if err != nil { - return err - } - - if err := createConsumers(ctx, search); err != nil { - return err - } - - batching := search.Spec.Batching - if batching == nil { - - batchingMap, err := settings.GetMapOrEmpty(ctx, stack.Name, "search", "batching") - if err != nil { - return err - } - - batching = &v1beta1.Batching{} - if countString, ok := batchingMap["count"]; ok { - count, err := strconv.ParseUint(countString, 10, 64) - if err != nil { - return err - } - batching.Count = int(count) - } - - if period, ok := batchingMap["period"]; ok { - batching.Period = period - } - } - - _, _, err = CreateOrUpdate[*v1beta1.Benthos](ctx, types.NamespacedName{ - Name: GetObjectName(stack.Name, "benthos"), - }, - WithController[*v1beta1.Benthos](ctx.GetScheme(), search), - func(t *v1beta1.Benthos) error { - t.Spec.Stack = stack.Name - t.Spec.Batching = batching - t.Spec.DevProperties = search.Spec.DevProperties - t.Spec.InitContainers = []corev1.Container{{ - Name: "init-mapping", - Image: image, - Args: []string{"init-mapping"}, - Env: env, - }} - - return nil - }, - ) - if err != nil { - return err - } - - annotations := map[string]string{} - if elasticSearchSecretResourceRef != nil { - annotations["elasticsearch-secret-hash"] = elasticSearchSecretResourceRef.Status.Hash - } - - err = applications. - New(search, &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "search", - }, - Spec: appsv1.DeploymentSpec{ - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: annotations, - }, - Spec: corev1.PodSpec{ - ServiceAccountName: serviceAccountName, - Containers: []corev1.Container{{ - Name: "search", - Image: image, - Ports: []corev1.ContainerPort{applications.StandardHTTPPort()}, - Env: env, - LivenessProbe: applications.DefaultLiveness("http"), - }}, - }, - }, - }, - }). - IsEE(). - Install(ctx) - if err != nil { - return err - } - - if err := gatewayhttpapis.Create(ctx, search, gatewayhttpapis.WithHealthCheckEndpoint("_healthcheck")); err != nil { - return err - } - - if !search.Status.TopicCleaned { - if err := cleanConsumers(ctx, search); err != nil { - return fmt.Errorf("failed to clean consumers for search: %w", err) - } - search.Status.TopicCleaned = true - } - - return err -} - -func createConsumers(ctx Context, search *v1beta1.Search) error { - for _, o := range []v1beta1.Module{ - &v1beta1.Payments{}, - &v1beta1.Ledger{}, - &v1beta1.Gateway{}, - } { - if ok, err := HasDependency(ctx, search.Spec.Stack, o); err != nil { - return err - } else if ok { - consumer, err := brokerconsumers.Create(ctx, search, LowerCamelCaseKind(ctx, o), LowerCamelCaseKind(ctx, o)) - if err != nil { - return err - } - if !consumer.Status.Ready { - return NewPendingError().WithMessage("waiting for consumer %s to be ready", consumer.Name) - } - } - } - - return nil -} - -func init() { - Init( - WithModuleReconciler(Reconcile, - WithWatchSettings[*v1beta1.Search](), - WithOwn[*v1beta1.Search](&v1beta1.BrokerConsumer{}), - WithOwn[*v1beta1.Search](&v1beta1.ResourceReference{}), - WithOwn[*v1beta1.Search](&v1beta1.Benthos{}), - WithOwn[*v1beta1.Search](&v1beta1.GatewayHTTPAPI{}), - WithOwn[*v1beta1.Search](&appsv1.Deployment{}), - WithOwn[*v1beta1.Search](&v1.Job{}), - ), - ) -} diff --git a/components/operator/internal/resources/services/services.go b/components/operator/internal/resources/services/services.go deleted file mode 100644 index db23c39dff..0000000000 --- a/components/operator/internal/resources/services/services.go +++ /dev/null @@ -1,50 +0,0 @@ -package services - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/settings" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" -) - -func Create(ctx core.Context, owner v1beta1.Dependent, name string, mutators ...core.ObjectMutator[*corev1.Service]) (*corev1.Service, error) { - mutators = append(mutators, - core.WithController[*corev1.Service](ctx.GetScheme(), owner), - ) - mutators = append(mutators, func(t *corev1.Service) error { - var err error - t.ObjectMeta.Annotations, err = settings.GetMapOrEmpty(ctx, owner.GetStack(), "services", name, "annotations") - if err != nil { - return err - } - return nil - }) - service, _, err := core.CreateOrUpdate[*corev1.Service](ctx, types.NamespacedName{ - Name: name, - Namespace: owner.GetStack(), - }, mutators...) - return service, err -} - -func WithDefault(name string) core.ObjectMutator[*corev1.Service] { - return func(t *corev1.Service) error { - t.Labels = map[string]string{ - "app.kubernetes.io/service-name": name, - } - t.Spec = corev1.ServiceSpec{ - Ports: []corev1.ServicePort{{ - Name: "http", - Port: 8080, - Protocol: "TCP", - TargetPort: intstr.FromString("http"), - }}, - Selector: map[string]string{ - "app.kubernetes.io/name": name, - }, - } - - return nil - } -} diff --git a/components/operator/internal/resources/settings/aws_role.go b/components/operator/internal/resources/settings/aws_role.go deleted file mode 100644 index 5d0554d8f2..0000000000 --- a/components/operator/internal/resources/settings/aws_role.go +++ /dev/null @@ -1,7 +0,0 @@ -package settings - -import "github.com/formancehq/operator/internal/core" - -func GetAWSServiceAccount(ctx core.Context, stackName string) (string, error) { - return GetStringOrEmpty(ctx, stackName, "aws", "service-account") -} diff --git a/components/operator/internal/resources/settings/helpers.go b/components/operator/internal/resources/settings/helpers.go deleted file mode 100644 index 5cccf276cf..0000000000 --- a/components/operator/internal/resources/settings/helpers.go +++ /dev/null @@ -1,385 +0,0 @@ -package settings - -import ( - "encoding/json" - "fmt" - "reflect" - "slices" - "strconv" - "strings" - - "github.com/formancehq/go-libs/pointer" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/pkg/errors" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func Get(ctx core.Context, stack string, keys ...string) (*string, error) { - allSettingsTargetingStack := &v1beta1.SettingsList{} - if err := ctx.GetClient().List(ctx, allSettingsTargetingStack, client.MatchingFields{ - "stack": stack, - "keylen": fmt.Sprint(len(keys)), - }); err != nil { - return nil, errors.Wrap(err, "listings settings") - } - - allSettingsTargetingAllStacks := &v1beta1.SettingsList{} - if err := ctx.GetClient().List(ctx, allSettingsTargetingAllStacks, client.MatchingFields{ - "stack": "*", - "keylen": fmt.Sprint(len(keys)), - }); err != nil { - return nil, errors.Wrap(err, "listings settings") - } - - return findMatchingSettings(append(allSettingsTargetingStack.Items, allSettingsTargetingAllStacks.Items...), keys...) -} - -func GetString(ctx core.Context, stack string, keys ...string) (*string, error) { - return Get(ctx, stack, keys...) -} - -func GetStringOrDefault(ctx core.Context, stack, defaultValue string, keys ...string) (string, error) { - value, err := GetString(ctx, stack, keys...) - if err != nil { - return "", err - } - if value == nil { - return defaultValue, nil - } - return *value, nil -} - -func GetStringOrEmpty(ctx core.Context, stack string, keys ...string) (string, error) { - return GetStringOrDefault(ctx, stack, "", keys...) -} - -func GetStringSlice(ctx core.Context, stack string, keys ...string) ([]string, error) { - value, err := GetString(ctx, stack, keys...) - if err != nil { - return nil, err - } - if value == nil { - return nil, err - } - return strings.Split(*value, ","), nil -} - -func RequireString(ctx core.Context, stack string, keys ...string) (string, error) { - value, err := GetString(ctx, stack, keys...) - if err != nil { - return "", err - } - if value == nil { - return "", core.NewMissingSettingsError(fmt.Sprintf("settings '%s' not found for stack '%s'", strings.Join(keys, "."), stack)) - } - return *value, nil -} - -func GetURL(ctx core.Context, stack string, keys ...string) (*v1beta1.URI, error) { - value, err := GetString(ctx, stack, keys...) - if err != nil { - return nil, err - } - if value == nil { - return nil, nil - } - return v1beta1.ParseURL(*value) -} - -func RequireURL(ctx core.Context, stack string, keys ...string) (*v1beta1.URI, error) { - value, err := RequireString(ctx, stack, keys...) - if err != nil { - return nil, err - } - return v1beta1.ParseURL(value) -} - -func GetInt64(ctx core.Context, stack string, keys ...string) (*int64, error) { - value, err := Get(ctx, stack, keys...) - if err != nil { - return nil, err - } - if value == nil { - return nil, nil - } - intValue, err := strconv.ParseInt(*value, 10, 64) - if err != nil { - return nil, err - } - - return &intValue, nil -} - -func GetInt32(ctx core.Context, stack string, keys ...string) (*int32, error) { - value, err := Get(ctx, stack, keys...) - if err != nil { - return nil, err - } - if value == nil { - return nil, nil - } - intValue, err := strconv.ParseInt(*value, 10, 32) - if err != nil { - return nil, err - } - - return pointer.For(int32(intValue)), nil -} - -func GetUInt64(ctx core.Context, stack string, keys ...string) (*uint64, error) { - value, err := Get(ctx, stack, keys...) - if err != nil { - return nil, err - } - if value == nil { - return nil, nil - } - intValue, err := strconv.ParseUint(*value, 10, 64) - if err != nil { - return nil, err - } - - return &intValue, nil -} - -func GetUInt16(ctx core.Context, stack string, keys ...string) (*uint16, error) { - value, err := Get(ctx, stack, keys...) - if err != nil { - return nil, err - } - if value == nil { - return nil, nil - } - intValue, err := strconv.ParseUint(*value, 10, 16) - if err != nil { - return nil, err - } - - return pointer.For(uint16(intValue)), nil -} - -func GetInt(ctx core.Context, stack string, keys ...string) (*int, error) { - value, err := GetInt64(ctx, stack, keys...) - if err != nil { - return nil, err - } - if value == nil { - return nil, nil - } - return pointer.For(int(*value)), nil -} - -func GetUInt(ctx core.Context, stack string, keys ...string) (*uint, error) { - value, err := GetUInt64(ctx, stack, keys...) - if err != nil { - return nil, err - } - if value == nil { - return nil, nil - } - return pointer.For(uint(*value)), nil -} - -func GetIntOrDefault(ctx core.Context, stack string, defaultValue int, keys ...string) (int, error) { - value, err := GetInt(ctx, stack, keys...) - if err != nil { - return 0, err - } - - if value == nil { - return defaultValue, nil - } - return *value, nil -} - -func GetUInt16OrDefault(ctx core.Context, stack string, defaultValue uint16, keys ...string) (uint16, error) { - value, err := GetUInt16(ctx, stack, keys...) - if err != nil { - return 0, err - } - - if value == nil { - return defaultValue, nil - } - return *value, nil -} - -func GetInt32OrDefault(ctx core.Context, stack string, defaultValue int32, keys ...string) (int32, error) { - value, err := GetInt32(ctx, stack, keys...) - if err != nil { - return 0, err - } - - if value == nil { - return defaultValue, nil - } - return *value, nil -} - -func GetBool(ctx core.Context, stack string, keys ...string) (*bool, error) { - value, err := Get(ctx, stack, keys...) - if err != nil { - return nil, err - } - if value == nil { - return nil, nil - } - return pointer.For(*value == "true"), nil -} - -func GetBoolOrDefault(ctx core.Context, stack string, defaultValue bool, keys ...string) (bool, error) { - value, err := GetBool(ctx, stack, keys...) - if err != nil { - return false, err - } - if value == nil { - return defaultValue, nil - } - return *value, nil -} - -func GetBoolOrFalse(ctx core.Context, stack string, keys ...string) (bool, error) { - return GetBoolOrDefault(ctx, stack, false, keys...) -} - -func GetBoolOrTrue(ctx core.Context, stack string, keys ...string) (bool, error) { - return GetBoolOrDefault(ctx, stack, true, keys...) -} - -func GetMap(ctx core.Context, stack string, keys ...string) (map[string]string, error) { - value, err := GetString(ctx, stack, keys...) - if err != nil { - return nil, err - } - if value == nil { - return nil, nil - } - ret := make(map[string]string) - parts := strings.Split(*value, ",") - for _, part := range parts { - part := strings.TrimSpace(part) - parts := strings.SplitN(part, "=", 2) - ret[parts[0]] = parts[1] - } - - return ret, nil -} - -// TODO(gfyrag): GetAs only allow to map to structure containing only strings. -// With a bit of reflection, we could be able to have a more smart mapping to structure with usefull types. -func GetAs[T any](ctx core.Context, stack string, keys ...string) (*T, error) { - m, err := GetMap(ctx, stack, keys...) - if err != nil { - return nil, err - } - - var ret T - ret = reflect.New(reflect.TypeOf(ret)).Elem().Interface().(T) - if m == nil { - return &ret, nil - } - - data, err := json.Marshal(m) - if err != nil { - panic(err) - } - - if err := json.Unmarshal(data, &ret); err != nil { - return nil, err - } - - return &ret, nil -} - -func GetMapOrEmpty(ctx core.Context, stack string, keys ...string) (map[string]string, error) { - value, err := GetMap(ctx, stack, keys...) - if err != nil { - return nil, err - } - if value == nil { - return map[string]string{}, nil - } - - return value, nil -} - -func findMatchingSettings(settings []v1beta1.Settings, flattenKeys ...string) (*string, error) { - - // Keys can be passed as "a.b.c", instead of "a", "b", "c" - // Keys can be passed as "a.b.*", instead of "a", "b", "*" - // Keys can be passed as "a.*.c", instead of "a", "*", "c" - // Keys can be passed as "a."*.*".c," instead of "a", "b", "c" - slices.SortFunc(settings, sortSettingsByPriority) - - for _, setting := range settings { - if matchSetting(setting, flattenKeys...) { - return &setting.Spec.Value, nil - } - } - - return nil, nil -} - -func matchSetting(setting v1beta1.Settings, keys ...string) bool { - settingKeyParts := SplitKeywordWithDot(setting.Spec.Key) - for i, settingKeyPart := range settingKeyParts { - if settingKeyPart == "*" { - continue - } - if settingKeyPart != keys[i] { - return false - } - } - return true -} - -func SplitKeywordWithDot(key string) []string { - segments := "" - needQuote := false - for _, v := range key { - switch v { - case '"': - needQuote = !needQuote - case '.': - if !needQuote { - segments += " " - continue - } - segments += string(v) - default: - segments += string(v) - } - } - - return strings.Split(segments, " ") -} - -func sortSettingsByPriority(a, b v1beta1.Settings) int { - switch { - case a.IsWildcard() && !b.IsWildcard(): - return 1 - case !a.IsWildcard() && b.IsWildcard(): - return -1 - } - aKeys := SplitKeywordWithDot(a.Spec.Key) - bKeys := SplitKeywordWithDot(b.Spec.Key) - - for i := 0; i < len(aKeys); i++ { - if aKeys[i] == bKeys[i] { - continue - } - if aKeys[i] == "*" { - return 1 - } - if bKeys[i] == "*" { - return -1 - } - } - - return 0 -} - -func IsTrue(v string) bool { - return strings.ToLower(v) == "true" || v == "1" -} diff --git a/components/operator/internal/resources/settings/helpers_test.go b/components/operator/internal/resources/settings/helpers_test.go deleted file mode 100644 index 21313b0a3b..0000000000 --- a/components/operator/internal/resources/settings/helpers_test.go +++ /dev/null @@ -1,210 +0,0 @@ -package settings - -import ( - "fmt" - "testing" - - . "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/stretchr/testify/require" -) - -func TestSplitKeywordWithDot(t *testing.T) { - t.Parallel() - type testCase struct { - key string - expectedResult []string - } - testCases := []testCase{ - { - key: `"postgres.payments.dsn"`, - expectedResult: []string{"postgres.payments.dsn"}, - }, - { - key: `resource-requirements."payments.io".containers.payments.limits`, - expectedResult: []string{"resource-requirements", "payments.io", "containers", "payments", "limits"}, - }, - } - for i, tc := range testCases { - tc := tc - t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { - t.Parallel() - result := SplitKeywordWithDot(tc.key) - require.Equal(t, tc.expectedResult, result) - }) - } - -} - -func TestFindMatchingSettings(t *testing.T) { - t.Parallel() - type settings struct { - key string - value string - isWildcard bool - } - type testCase struct { - settings []settings - key string - expectedResult string - } - testCases := []testCase{ - { - settings: []settings{ - {"postgres.ledger.dsn", "postgresql://localhost:5433", false}, - {"postgres.*.dsn", "postgresql://localhost:5432", false}, - }, - key: "postgres.payments.dsn", - expectedResult: "postgresql://localhost:5432", - }, - { - settings: []settings{ - {"postgres.*.dsn", "postgresql://localhost:5432", false}, - {"postgres.ledger.dsn", "postgresql://localhost:5433", false}, - }, - key: "postgres.ledger.dsn", - expectedResult: "postgresql://localhost:5433", - }, - { - settings: []settings{ - {"resource-requirements.*.containers.*.limits", "vvv", false}, - {"resource-requirements.ledger.containers.*.limits", "xxx", false}, - }, - key: "resource-requirements.ledger.containers.ledger.limits", - expectedResult: "xxx", - }, - { - settings: []settings{ - {"resource-requirements.*.containers.*.limits", "vvv", false}, - {"resource-requirements.*.containers.ledger.limits", "xxx", false}, - }, - key: "resource-requirements.payments.containers.payments.limits", - expectedResult: "vvv", - }, - { - settings: []settings{ - {"resource-requirements.*.containers.ledger.limits", "xxx", false}, - {"resource-requirements.*.containers.*.limits", "vvv", false}, - }, - key: "resource-requirements.ledger.containers.ledger.limits", - expectedResult: "xxx", - }, - { - settings: []settings{ - {"resource-requirements.*.containers.*.limits", "memory=512Mi", true}, - {"resource-requirements.*.containers.*.limits", "memory=1024Mi", false}, - }, - key: "resource-requirements.ledger.containers.ledger.limits", - expectedResult: "memory=1024Mi", - }, - { - settings: []settings{ - {"resource-requirements.ledger.containers.ledger.limits", "memory=512Mi", true}, - {"resource-requirements.*.containers.*.limits", "memory=1024Mi", false}, - }, - key: "resource-requirements.ledger.containers.ledger.limits", - expectedResult: "memory=1024Mi", - }, - { - settings: []settings{ - {"resource-requirements.ledger.containers.ledger.limits", "memory=512Mi", true}, - {"resource-requirements.*.containers.*.limits", "memory=1024Mi", false}, - }, - key: "resource-requirements.payments.containers.payments.limits", - expectedResult: "memory=1024Mi", - }, - { - settings: []settings{ - {"resource-requirements.*.containers.payments.limits", "memory=512Mi", true}, - {"resource-requirements.*.containers.*.limits", "memory=1024Mi", false}, - }, - key: "resource-requirements.payments.containers.payments.limits", - expectedResult: "memory=1024Mi", - }, - { - settings: []settings{ - { - key: `registries."ghcr.io".images.ledger.rewrite`, - value: "example", - isWildcard: false, - }, - }, - key: `registries."ghcr.io".images.ledger.rewrite`, - expectedResult: "example", - }, - { - settings: []settings{ - { - key: "registries.*.images.ledger.rewrite", - value: "example", - isWildcard: false, - }, - }, - key: `registries."ghcr.io".images.ledger.rewrite`, - expectedResult: "example", - }, - { - settings: []settings{ - { - key: "registries.*.images.caddy/caddy.rewrite", - value: "example", - isWildcard: false, - }, - }, - key: `registries."docker.io".images.caddy/caddy.rewrite`, - expectedResult: "example", - }, - { - settings: []settings{ - { - key: "registries.*.endpoint", - value: "example.com", - }, - }, - key: `registries."ghcr.io".endpoint`, - expectedResult: "example.com", - }, - { - settings: []settings{ - { - key: "registries.*.endpoint", - value: "example.com", - }, - }, - key: `registries."public.ecr.aws".endpoint`, - expectedResult: "example.com", - }, - { - settings: []settings{ - { - key: "registries.*.endpoint", - value: "example.com", - }, - }, - key: `registries."docker.io".endpoint`, - expectedResult: "example.com", - }, - } - for i, tc := range testCases { - tc := tc - t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { - t.Parallel() - value, err := findMatchingSettings(Map(tc.settings, func(from settings) v1beta1.Settings { - ret := v1beta1.Settings{ - Spec: v1beta1.SettingsSpec{ - Key: from.key, - Value: from.value, - }, - } - if from.isWildcard { - ret.Spec.Stacks = []string{"*"} - } - return ret - }), SplitKeywordWithDot(tc.key)...) - require.NoError(t, err) - require.NotNil(t, value) - require.Equal(t, tc.expectedResult, *value) - }) - } - -} diff --git a/components/operator/internal/resources/settings/opentelemetry.go b/components/operator/internal/resources/settings/opentelemetry.go deleted file mode 100644 index 8f3f4ded34..0000000000 --- a/components/operator/internal/resources/settings/opentelemetry.go +++ /dev/null @@ -1,92 +0,0 @@ -package settings - -import ( - "fmt" - "strings" - - "github.com/formancehq/operator/internal/core" - v1 "k8s.io/api/core/v1" -) - -type MonitoringType string - -const ( - MonitoringTypeTraces MonitoringType = "TRACES" - MonitoringTypeMetrics MonitoringType = "METRICS" -) - -func GetOTELEnvVars(ctx core.Context, stack, serviceName string) ([]v1.EnvVar, error) { - return GetOTELEnvVarsWithPrefix(ctx, stack, serviceName, "") -} - -func GetOTELEnvVarsWithPrefix(ctx core.Context, stack, serviceName, prefix string) ([]v1.EnvVar, error) { - - traces, err := otelEnvVars(ctx, stack, MonitoringTypeTraces, serviceName, prefix) - if err != nil { - return nil, err - } - - metrics, err := otelEnvVars(ctx, stack, MonitoringTypeMetrics, serviceName, prefix) - if err != nil { - return nil, err - } - - return append(traces, metrics...), nil -} - -func HasOpenTelemetryTracesEnabled(ctx core.Context, stack string) (bool, error) { - v, err := GetURL(ctx, stack, "opentelemetry", "traces", "dsn") - if err != nil { - return false, err - } - - if v == nil { - return false, nil - } - - return true, nil -} - -func otelEnvVars(ctx core.Context, stack string, monitoringType MonitoringType, serviceName, prefix string) ([]v1.EnvVar, error) { - - otlp, err := GetURL(ctx, stack, "opentelemetry", strings.ToLower(string(monitoringType)), "dsn") - if err != nil { - return nil, err - } - if otlp == nil { - return nil, nil - } - - ret := []v1.EnvVar{ - core.Env(fmt.Sprintf("%sOTEL_%s", prefix, string(monitoringType)), "true"), - core.Env(fmt.Sprintf("%sOTEL_%s_BATCH", prefix, string(monitoringType)), "true"), - core.Env(fmt.Sprintf("%sOTEL_%s_EXPORTER", prefix, string(monitoringType)), "otlp"), - core.EnvFromBool(fmt.Sprintf("%sOTEL_%s_EXPORTER_OTLP_INSECURE", prefix, string(monitoringType)), - IsTrue(otlp.Query().Get("insecure"))), - core.Env(fmt.Sprintf("%sOTEL_%s_EXPORTER_OTLP_MODE", prefix, string(monitoringType)), otlp.Scheme), - core.Env(fmt.Sprintf("%sOTEL_%s_PORT", prefix, string(monitoringType)), otlp.Port()), - core.Env(fmt.Sprintf("%sOTEL_%s_ENDPOINT", prefix, string(monitoringType)), otlp.Hostname()), - core.Env(fmt.Sprintf("%sOTEL_%s_EXPORTER_OTLP_ENDPOINT", prefix, string(monitoringType)), core.ComputeEnvVar("%s:%s", - fmt.Sprintf("%sOTEL_%s_ENDPOINT", prefix, string(monitoringType)), - fmt.Sprintf("%sOTEL_%s_PORT", prefix, string(monitoringType)))), - core.Env(fmt.Sprintf("%sOTEL_SERVICE_NAME", prefix), serviceName), - } - - resourceAttributes, err := GetMap(ctx, "opentelemetry", strings.ToLower(string(monitoringType)), "resource-attributes") - if err != nil { - return nil, err - } - - if resourceAttributes == nil { - resourceAttributes = map[string]string{} - } - resourceAttributes["stack"] = stack - - resourceAttributesStr := "" - for k, v := range resourceAttributes { - resourceAttributesStr = fmt.Sprintf("%s%s=%s ", resourceAttributesStr, k, v) - } - ret = append(ret, core.Env(fmt.Sprintf("%sOTEL_RESOURCE_ATTRIBUTES", prefix), resourceAttributesStr)) - - return ret, nil -} diff --git a/components/operator/internal/resources/settings/resourcerequirements.go b/components/operator/internal/resources/settings/resourcerequirements.go deleted file mode 100644 index 698817d8e6..0000000000 --- a/components/operator/internal/resources/settings/resourcerequirements.go +++ /dev/null @@ -1,52 +0,0 @@ -package settings - -import ( - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/internal/core" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" -) - -func GetResourceRequirements(ctx core.Context, stack string, keys ...string) (*v1.ResourceRequirements, error) { - limits, err := GetResourceList(ctx, stack, append(keys, "limits")...) - if err != nil { - return nil, err - } - - requests, err := GetResourceList(ctx, stack, append(keys, "requests")...) - if err != nil { - return nil, err - } - - claims, err := GetStringSlice(ctx, stack, append(keys, "claims")...) - if err != nil { - return nil, err - } - - return &v1.ResourceRequirements{ - Limits: limits, - Requests: requests, - Claims: collectionutils.Map(claims, func(from string) v1.ResourceClaim { - return v1.ResourceClaim{ - Name: from, - } - }), - }, nil -} - -func GetResourceList(ctx core.Context, stack string, keys ...string) (v1.ResourceList, error) { - value, err := GetMap(ctx, stack, keys...) - if err != nil { - return nil, err - } - if value == nil { - return nil, nil - } - - ret := v1.ResourceList{} - for key, qty := range value { - ret[v1.ResourceName(key)], err = resource.ParseQuantity(qty) - } - - return ret, nil -} diff --git a/components/operator/internal/resources/settings/settings.go b/components/operator/internal/resources/settings/settings.go deleted file mode 100644 index 79c35e373e..0000000000 --- a/components/operator/internal/resources/settings/settings.go +++ /dev/null @@ -1,53 +0,0 @@ -package settings - -import ( - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/pkg/errors" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" -) - -// +kubebuilder:rbac:groups=formance.com,resources=settings,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=formance.com,resources=settings/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=formance.com,resources=settings/finalizers,verbs=update - -func init() { - core.Init( - core.WithSimpleIndex("keylen", func(t *v1beta1.Settings) string { - return fmt.Sprint(len(SplitKeywordWithDot(t.Spec.Key))) - }), - ) -} - -func New(name, key, value string, stacks ...string) *v1beta1.Settings { - return &v1beta1.Settings{ - ObjectMeta: v1.ObjectMeta{ - Name: name, - }, - Spec: v1beta1.SettingsSpec{ - Stacks: stacks, - Key: key, - Value: value, - }, - } -} - -func CreateOrUpdate(ctx core.Context, name, key string, value any, stacks ...string) (*v1beta1.Settings, error) { - settings, _, err := core.CreateOrUpdate[*v1beta1.Settings](ctx, types.NamespacedName{ - Name: name, - }, func(t *v1beta1.Settings) error { - t.Spec.Key = key - t.Spec.Value = fmt.Sprint(value) - t.Spec.Stacks = stacks - - return nil - }) - if err != nil { - return nil, errors.Wrapf(err, "creating settings '%s' with key '%s'", name, key) - } - - return settings, nil -} diff --git a/components/operator/internal/resources/stacks/init.go b/components/operator/internal/resources/stacks/init.go deleted file mode 100644 index 545db17127..0000000000 --- a/components/operator/internal/resources/stacks/init.go +++ /dev/null @@ -1,357 +0,0 @@ -package stacks - -import ( - "context" - "fmt" - "reflect" - "sort" - "strings" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/pkg/errors" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - . "github.com/formancehq/operator/internal/core" - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/predicate" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -// +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete;deletecollection -// +kubebuilder:rbac:groups=policy,resources=poddisruptionbudgets,verbs=get;list;watch;create;update;patch;delete;deletecollection -// +kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=core,resources=events,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=formance.com,resources=stacks,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=formance.com,resources=stacks/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=formance.com,resources=stacks/finalizers,verbs=update -// +kubebuilder:rbac:groups=formance.com,resources=versions,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=formance.com,resources=versions/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=formance.com,resources=versions/finalizers,verbs=update - -func setModulesCondition(ctx Context, stack *v1beta1.Stack) error { - for _, rtype := range ctx.GetScheme().AllKnownTypes() { - v := reflect.New(rtype).Interface() - r, ok := v.(v1beta1.Module) - if !ok { - continue - } - - gvk, err := apiutil.GVKForObject(r, ctx.GetScheme()) - if err != nil { - return err - } - l := &unstructured.UnstructuredList{} - l.SetGroupVersionKind(gvk) - if err := ctx.GetClient().List(ctx, l, client.MatchingFields{ - "stack": stack.Name, - }); err != nil { - return err - } - - if len(l.Items) == 0 { - continue - } - - func() { - condition := v1beta1.NewCondition("ModuleReconciliation", stack.Generation). - SetReason(gvk.Kind) - defer func() { - stack.GetConditions().AppendOrReplace(*condition, v1beta1.AndConditions( - v1beta1.ConditionTypeMatch("ModuleReconciliation"), - v1beta1.ConditionReasonMatch(gvk.Kind), - )) - }() - - switch len(l.Items) { - case 1: - type AnyModule struct { - Meta metav1.ObjectMeta `json:"metadata"` - Status v1beta1.Status `json:"status"` - } - - module := AnyModule{} - if err := runtime.DefaultUnstructuredConverter.FromUnstructured(l.Items[0].UnstructuredContent(), &module); err != nil { - panic(err) - } - - stackReconcileCondition := module.Status.Conditions.Get("ReconciledWithStack") - if stackReconcileCondition == nil { - condition.SetStatus(metav1.ConditionFalse).SetMessage("Module not yet reconciled") - return - } - if stackReconcileCondition.Status != metav1.ConditionTrue { - condition.SetStatus(metav1.ConditionFalse).SetMessage("Module not declared as reconciled for stack") - return - } - if stackReconcileCondition.Reason == "Spec" && stack.MustSkip() { - condition.SetStatus(metav1.ConditionFalse).SetMessage("Module should be skipped but is not") - return - } - if stackReconcileCondition.Reason == "Skipped" && !stack.MustSkip() { - condition.SetStatus(metav1.ConditionFalse).SetMessage("Module is skipped but should not") - return - } - condition.SetMessage("All checks passed") - default: - condition.SetStatus(metav1.ConditionFalse).SetMessage("found multiple modules") - } - }() - } - - modules := make([]string, 0) - pendingModules := make([]string, 0) - for _, condition := range stack.Status.Conditions { - if condition.Type != "ModuleReconciliation" || condition.ObservedGeneration != stack.Generation { - continue - } - modules = append(modules, condition.Reason) - if condition.Status == metav1.ConditionFalse { - pendingModules = append(pendingModules, condition.Reason) - } - } - - sort.Strings(modules) - - stack.Status.Modules = modules - if len(pendingModules) > 0 { - return NewPendingError().WithMessage("Pending modules: %s", modules) - } - - return nil -} - -func Reconcile(ctx Context, stack *v1beta1.Stack) error { - errAlreadyExist := errors.New("namespace already exists") - if _, _, err := CreateOrUpdate(ctx, types.NamespacedName{ - Name: stack.Name, - }, - func(ns *corev1.Namespace) error { - _, stackCreatedByAgent := stack.GetLabels()[v1beta1.CreatedByAgentLabel] - if ns.ResourceVersion == "" || stackCreatedByAgent { - return nil - } - - return errAlreadyExist - }, core.WithController[*corev1.Namespace](ctx.GetScheme(), stack)); err != nil { - if !errors.Is(err, errAlreadyExist) { - return err - } - } - - if err := setModulesCondition(ctx, stack); err != nil { - return err - } - - if stack.MustSkip() { - stack.GetConditions().AppendOrReplace( - *v1beta1.NewCondition("Skipped", stack.Generation).SetMessage("Stack marked as skipped"), - v1beta1.ConditionTypeMatch("Skipped"), - ) - } else { - stack.GetConditions().Delete(v1beta1.ConditionTypeMatch("Skipped")) - } - - return nil -} - -func Clean(ctx Context, t *v1beta1.Stack) error { - logger := log.FromContext(ctx) - logger = logger.WithValues("stack", t.Name) - logger.Info("Clean stack") - - if err := deleteModules(ctx, t, logger); err != nil { - return err - } - - logger.Info("All modules removed") - - if err := deleteResources(ctx, t, logger); err != nil { - return err - } - - logger.Info("All dependencies removed") - - return nil -} - -type pendingDeletion struct { - GroupVersionKind schema.GroupVersionKind - Name string - JustDeleted bool -} - -func (p pendingDeletion) String() string { - return fmt.Sprintf("%s %s [deleted=%v]", p.GroupVersionKind, p.Name, p.JustDeleted) -} - -type pendingDeletions []pendingDeletion - -func (p pendingDeletions) String() string { - return strings.Join(collectionutils.Map(p, pendingDeletion.String), ", ") -} - -func deleteModules(ctx Context, stack *v1beta1.Stack, logger logr.Logger) error { - pendingModuleDeletions := pendingDeletions{} - for _, rtype := range ctx.GetScheme().AllKnownTypes() { - v := reflect.New(rtype).Interface() - module, ok := v.(v1beta1.Module) - if !ok { - continue - } - - gvk, err := apiutil.GVKForObject(module, ctx.GetScheme()) - if err != nil { - return err - } - - l := &unstructured.UnstructuredList{} - l.SetGroupVersionKind(gvk) - if err := ctx.GetAPIReader().List(ctx, l); err != nil { - return err - } - - items := collectionutils.Filter(l.Items, func(u unstructured.Unstructured) bool { - return u.Object["spec"].(map[string]any)["stack"].(string) == stack.Name - }) - - for _, item := range items { - pendingModuleDeletion := pendingDeletion{ - GroupVersionKind: gvk, - Name: item.GetName(), - } - if item.GetDeletionTimestamp().IsZero() { - logger.Info(fmt.Sprintf("Delete module %s [%s]", item.GetName(), gvk)) - if err := ctx.GetClient().Delete(ctx, &item); client.IgnoreNotFound(err) != nil { - return err - } - pendingModuleDeletion.JustDeleted = true - } - pendingModuleDeletions = append(pendingModuleDeletions, pendingModuleDeletion) - } - } - - if len(pendingModuleDeletions) > 0 { - return NewPendingError().WithMessage("Waiting for module deletion: %s", pendingModuleDeletions) - } - - return nil -} - -func deleteResources(ctx Context, stack *v1beta1.Stack, logger logr.Logger) error { - pendingResourceDeletions := pendingDeletions{} - for _, rtype := range ctx.GetScheme().AllKnownTypes() { - v := reflect.New(rtype).Interface() - resource, ok := v.(v1beta1.Resource) - if !ok { - continue - } - gvk, err := apiutil.GVKForObject(resource, ctx.GetScheme()) - if err != nil { - return err - } - - l := &unstructured.UnstructuredList{} - l.SetGroupVersionKind(gvk) - if err := ctx.GetAPIReader().List(ctx, l); err != nil { - return err - } - - items := collectionutils.Filter(l.Items, func(u unstructured.Unstructured) bool { - return u.Object["spec"].(map[string]any)["stack"].(string) == stack.Name - }) - - for _, item := range items { - pendingResourceDeletion := pendingDeletion{ - GroupVersionKind: gvk, - Name: item.GetName(), - } - if item.GetDeletionTimestamp().IsZero() { - pendingResourceDeletion.JustDeleted = true - logger.Info(fmt.Sprintf("Delete resource %s [%s]", item.GetName(), gvk)) - if err := ctx.GetClient().Delete(ctx, &item); client.IgnoreNotFound(err) != nil { - return err - } - } - pendingResourceDeletions = append(pendingResourceDeletions, pendingResourceDeletion) - } - } - - if len(pendingResourceDeletions) > 0 { - return NewPendingError().WithMessage("Waiting for resources deletion: %s", pendingResourceDeletions) - } - - return nil -} - -func init() { - Init( - WithSimpleIndex[*v1beta1.Stack](".spec.versionsFromFile", func(t *v1beta1.Stack) string { - return t.Spec.VersionsFromFile - }), - WithStdReconciler(Reconcile, - WithOwn[*v1beta1.Stack](&corev1.Namespace{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})), - WithRaw[*v1beta1.Stack](func(ctx Context, b *builder.Builder) error { - for _, rtype := range ctx.GetScheme().AllKnownTypes() { - v := reflect.New(rtype).Interface() - - switch v := v.(type) { - case v1beta1.Module: - u := &unstructured.Unstructured{} - gvk, err := apiutil.GVKForObject(v, ctx.GetScheme()) - if err != nil { - return err - } - u.SetGroupVersionKind(gvk) - - b.Watches(u, handler.EnqueueRequestsFromMapFunc(func(watchContext context.Context, object client.Object) []reconcile.Request { - return []reconcile.Request{{ - NamespacedName: types.NamespacedName{ - Name: object.(*unstructured.Unstructured).Object["spec"].(map[string]any)["stack"].(string), - }, - }} - })) - case v1beta1.Resource: - u := &unstructured.Unstructured{} - gvk, err := apiutil.GVKForObject(v, ctx.GetScheme()) - if err != nil { - return err - } - u.SetGroupVersionKind(gvk) - - b.Watches(u, handler.EnqueueRequestsFromMapFunc(func(watchContext context.Context, object client.Object) []reconcile.Request { - return []reconcile.Request{{ - NamespacedName: types.NamespacedName{ - Name: object.(*unstructured.Unstructured).Object["spec"].(map[string]any)["stack"].(string), - }, - }} - })) - } - } - - return nil - }), - // notes(gfyrag): Some resources need to be properly dropped before the stack is dropped - WithFinalizer[*v1beta1.Stack]("delete", Clean), - ), - ) -} diff --git a/components/operator/internal/resources/stargates/deployment.go b/components/operator/internal/resources/stargates/deployment.go deleted file mode 100644 index a13346e2f9..0000000000 --- a/components/operator/internal/resources/stargates/deployment.go +++ /dev/null @@ -1,68 +0,0 @@ -package stargates - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/applications" - "github.com/formancehq/operator/internal/resources/gateways" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/settings" - appsv1 "k8s.io/api/apps/v1" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func createDeployment(ctx core.Context, stack *v1beta1.Stack, stargate *v1beta1.Stargate, version string) error { - - env := make([]v1.EnvVar, 0) - - otlpEnv, err := settings.GetOTELEnvVars(ctx, stack.Name, core.LowerCamelCaseKind(ctx, stargate)) - if err != nil { - return err - } - env = append(env, otlpEnv...) - - gatewayEnv, err := gateways.EnvVarsIfEnabled(ctx, stack.Name) - if err != nil { - return err - } - env = append(env, gatewayEnv...) - - env = append(env, core.GetDevEnvVars(stack, stargate)...) - env = append(env, - core.Env("ORGANIZATION_ID", stargate.Spec.OrganizationID), - core.Env("STACK_ID", stargate.Spec.StackID), - core.Env("STARGATE_SERVER_URL", stargate.Spec.ServerURL), - core.Env("GATEWAY_URL", "http://gateway:8080"), - core.Env("STARGATE_AUTH_CLIENT_ID", stargate.Spec.Auth.ClientID), - core.Env("STARGATE_AUTH_CLIENT_SECRET", stargate.Spec.Auth.ClientSecret), - core.Env("STARGATE_AUTH_ISSUER_URL", stargate.Spec.Auth.Issuer), - ) - - image, err := registries.GetImage(ctx, stack, "stargate", version) - if err != nil { - return err - } - - return applications. - New(stargate, &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "stargate", - }, - Spec: appsv1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{{ - Name: "stargate", - Env: env, - Image: image, - Ports: []v1.ContainerPort{applications.StandardHTTPPort()}, - LivenessProbe: applications.DefaultLiveness("http"), - }}, - }, - }, - }, - }). - IsEE(). - Install(ctx) -} diff --git a/components/operator/internal/resources/stargates/init.go b/components/operator/internal/resources/stargates/init.go deleted file mode 100644 index 8aa358e8f3..0000000000 --- a/components/operator/internal/resources/stargates/init.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -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 stargates - -import ( - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - appsv1 "k8s.io/api/apps/v1" -) - -//+kubebuilder:rbac:groups=formance.com,resources=stargates,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=stargates/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=stargates/finalizers,verbs=update - -func Reconcile(ctx Context, stack *v1beta1.Stack, stargate *v1beta1.Stargate, version string) error { - if err := createDeployment(ctx, stack, stargate, version); err != nil { - return err - } - - return nil -} - -func init() { - Init( - WithModuleReconciler(Reconcile, - WithWatchSettings[*v1beta1.Stargate](), - WithOwn[*v1beta1.Stargate](&appsv1.Deployment{}), - WithOwn[*v1beta1.Stargate](&v1beta1.ResourceReference{}), - ), - ) -} diff --git a/components/operator/internal/resources/wallets/deployment.go b/components/operator/internal/resources/wallets/deployment.go deleted file mode 100644 index e234173a9e..0000000000 --- a/components/operator/internal/resources/wallets/deployment.go +++ /dev/null @@ -1,70 +0,0 @@ -package wallets - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/applications" - "github.com/formancehq/operator/internal/resources/authclients" - "github.com/formancehq/operator/internal/resources/auths" - "github.com/formancehq/operator/internal/resources/gateways" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/settings" - appsv1 "k8s.io/api/apps/v1" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func createDeployment(ctx core.Context, stack *v1beta1.Stack, wallets *v1beta1.Wallets, - authClient *v1beta1.AuthClient, version string) error { - env := make([]v1.EnvVar, 0) - otlpEnv, err := settings.GetOTELEnvVars(ctx, stack.Name, core.LowerCamelCaseKind(ctx, wallets)) - if err != nil { - return err - } - env = append(env, otlpEnv...) - - gatewayEnv, err := gateways.EnvVarsIfEnabled(ctx, stack.Name) - if err != nil { - return err - } - env = append(env, gatewayEnv...) - - env = append(env, core.GetDevEnvVars(stack, wallets)...) - if authClient != nil { - env = append(env, authclients.GetEnvVars(authClient)...) - } - - authEnvVars, err := auths.ProtectedEnvVars(ctx, stack, "wallets", wallets.Spec.Auth) - if err != nil { - return err - } - env = append(env, authEnvVars...) - - image, err := registries.GetImage(ctx, stack, "wallets", version) - if err != nil { - return err - } - - return applications. - New(wallets, &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "wallets", - }, - Spec: appsv1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{{ - Name: "wallets", - Args: []string{"serve"}, - Env: env, - Image: image, - Ports: []v1.ContainerPort{applications.StandardHTTPPort()}, - LivenessProbe: applications.DefaultLiveness("http"), - }}, - }, - }, - }, - }). - IsEE(). - Install(ctx) -} diff --git a/components/operator/internal/resources/wallets/init.go b/components/operator/internal/resources/wallets/init.go deleted file mode 100644 index c69d098c5e..0000000000 --- a/components/operator/internal/resources/wallets/init.go +++ /dev/null @@ -1,69 +0,0 @@ -/* -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 wallets - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/authclients" - "github.com/formancehq/operator/internal/resources/gatewayhttpapis" - appsv1 "k8s.io/api/apps/v1" -) - -//+kubebuilder:rbac:groups=formance.com,resources=wallets,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=wallets/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=wallets/finalizers,verbs=update - -func Reconcile(ctx Context, stack *v1beta1.Stack, wallets *v1beta1.Wallets, version string) error { - - hasAuth, err := HasDependency(ctx, wallets.Spec.Stack, &v1beta1.Auth{}) - if err != nil { - return err - } - var authClient *v1beta1.AuthClient - if hasAuth { - authClient, err = authclients.Create(ctx, stack, wallets, "wallets", func(spec *v1beta1.AuthClientSpec) { - spec.Scopes = []string{"ledger:read", "ledger:write"} - }) - if err != nil { - return err - } - } - - if err := createDeployment(ctx, stack, wallets, authClient, version); err != nil { - return err - } - - if err := gatewayhttpapis.Create(ctx, wallets, gatewayhttpapis.WithHealthCheckEndpoint("_healthcheck")); err != nil { - return err - } - - return nil -} - -func init() { - Init( - WithModuleReconciler(Reconcile, - WithWatchSettings[*v1beta1.Wallets](), - WithWatchDependency[*v1beta1.Wallets](&v1beta1.Auth{}), - WithOwn[*v1beta1.Wallets](&v1beta1.AuthClient{}), - WithOwn[*v1beta1.Wallets](&appsv1.Deployment{}), - WithOwn[*v1beta1.Wallets](&v1beta1.GatewayHTTPAPI{}), - WithOwn[*v1beta1.Wallets](&v1beta1.ResourceReference{}), - ), - ) -} diff --git a/components/operator/internal/resources/webhooks/deployment.go b/components/operator/internal/resources/webhooks/deployment.go deleted file mode 100644 index 973742e0d7..0000000000 --- a/components/operator/internal/resources/webhooks/deployment.go +++ /dev/null @@ -1,188 +0,0 @@ -package webhooks - -import ( - "fmt" - "strings" - - "github.com/formancehq/operator/internal/resources/brokers" - appsv1 "k8s.io/api/apps/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - . "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/applications" - "github.com/formancehq/operator/internal/resources/auths" - "github.com/formancehq/operator/internal/resources/databases" - "github.com/formancehq/operator/internal/resources/gateways" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/settings" - "github.com/pkg/errors" - v1 "k8s.io/api/core/v1" -) - -func deploymentEnvVars(ctx core.Context, stack *v1beta1.Stack, webhooks *v1beta1.Webhooks, database *v1beta1.Database) ([]v1.EnvVar, error) { - - brokerURI, err := settings.RequireURL(ctx, stack.Name, "broker", "dsn") - if err != nil { - return nil, err - } - if brokerURI == nil { - return nil, errors.New("missing broker configuration") - } - - env := make([]v1.EnvVar, 0) - otlpEnv, err := settings.GetOTELEnvVars(ctx, stack.Name, core.LowerCamelCaseKind(ctx, webhooks)) - if err != nil { - return nil, err - } - env = append(env, otlpEnv...) - - gatewayEnv, err := gateways.EnvVarsIfEnabled(ctx, stack.Name) - if err != nil { - return nil, err - } - env = append(env, gatewayEnv...) - - env = append(env, core.GetDevEnvVars(stack, webhooks)...) - - authEnvVars, err := auths.ProtectedEnvVars(ctx, stack, "webhooks", webhooks.Spec.Auth) - if err != nil { - return nil, err - } - - postgresEnvVar, err := databases.GetPostgresEnvVars(ctx, stack, database) - if err != nil { - return nil, err - } - - brokerEnvVar, err := brokers.GetBrokerEnvVars(ctx, brokerURI, stack.Name, "webhooks") - if err != nil { - return nil, err - } - - env = append(env, authEnvVars...) - env = append(env, postgresEnvVar...) - env = append(env, brokerEnvVar...) - env = append(env, core.Env("STORAGE_POSTGRES_CONN_STRING", "$(POSTGRES_URI)")) - - return env, nil -} - -func createAPIDeployment(ctx core.Context, stack *v1beta1.Stack, webhooks *v1beta1.Webhooks, database *v1beta1.Database, consumer *v1beta1.BrokerConsumer, version string, withWorker bool) error { - - image, err := registries.GetImage(ctx, stack, "webhooks", version) - if err != nil { - return err - } - - env, err := deploymentEnvVars(ctx, stack, webhooks, database) - if err != nil { - return err - } - - args := []string{"serve"} - - // notes(gfyrag): upgrade command introduced in version v2.0.0-rc.5 - if core.IsGreaterOrEqual(version, "v2.0.0-alpha") && core.IsLower(version, "v2.0.0-rc.5") { - args = append(args, "--auto-migrate") - } - if withWorker { - env = append(env, core.Env("WORKER", "true")) - - topics, err := brokers.GetTopicsEnvVars(ctx, stack, "KAFKA_TOPICS", consumer.Spec.Services...) - if err != nil { - return err - } - env = append(env, topics...) - } - - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - return applications. - New(webhooks, &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "webhooks", - }, - Spec: appsv1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - ServiceAccountName: serviceAccountName, - Containers: []v1.Container{{ - Name: "api", - Env: env, - Image: image, - Args: args, - Ports: []v1.ContainerPort{applications.StandardHTTPPort()}, - LivenessProbe: applications.DefaultLiveness("http"), - }}, - }, - }, - }, - }). - IsEE(). - Install(ctx) -} - -func createWorkerDeployment(ctx core.Context, stack *v1beta1.Stack, webhooks *v1beta1.Webhooks, database *v1beta1.Database, consumer *v1beta1.BrokerConsumer, version string) error { - - image, err := registries.GetImage(ctx, stack, "webhooks", version) - if err != nil { - return err - } - - env, err := deploymentEnvVars(ctx, stack, webhooks, database) - if err != nil { - return err - } - - env = append(env, core.Env("WORKER", "true")) - env = append(env, core.Env("KAFKA_TOPICS", strings.Join(Map(consumer.Spec.Services, func(from string) string { - return fmt.Sprintf("%s-%s", stack.Name, from) - }), " "))) - - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return err - } - - return applications. - New(webhooks, &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "webhooks-worker", - }, - Spec: appsv1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - ServiceAccountName: serviceAccountName, - Containers: []v1.Container{{ - Name: "worker", - Env: env, - Image: image, - Args: []string{"worker"}, - }}, - }, - }, - }, - }). - IsEE(). - Install(ctx) -} - -func createSingleDeployment(ctx core.Context, stack *v1beta1.Stack, webhooks *v1beta1.Webhooks, database *v1beta1.Database, consumer *v1beta1.BrokerConsumer, version string) error { - return createAPIDeployment(ctx, stack, webhooks, database, consumer, version, true) -} - -func createDualDeployment(ctx core.Context, stack *v1beta1.Stack, webhooks *v1beta1.Webhooks, database *v1beta1.Database, consumer *v1beta1.BrokerConsumer, version string) error { - if err := createAPIDeployment(ctx, stack, webhooks, database, consumer, version, false); err != nil { - return err - } - if err := createWorkerDeployment(ctx, stack, webhooks, database, consumer, version); err != nil { - return err - } - - return nil -} diff --git a/components/operator/internal/resources/webhooks/init.go b/components/operator/internal/resources/webhooks/init.go deleted file mode 100644 index 150af57b53..0000000000 --- a/components/operator/internal/resources/webhooks/init.go +++ /dev/null @@ -1,112 +0,0 @@ -/* -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 webhooks - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/brokerconsumers" - "github.com/formancehq/operator/internal/resources/databases" - "github.com/formancehq/operator/internal/resources/gatewayhttpapis" - "github.com/formancehq/operator/internal/resources/jobs" - "github.com/formancehq/operator/internal/resources/registries" - "github.com/formancehq/operator/internal/resources/settings" - "github.com/pkg/errors" - appsv1 "k8s.io/api/apps/v1" - batchv1 "k8s.io/api/batch/v1" -) - -//+kubebuilder:rbac:groups=formance.com,resources=webhooks,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=formance.com,resources=webhooks/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=formance.com,resources=webhooks/finalizers,verbs=update - -func Reconcile(ctx Context, stack *v1beta1.Stack, webhooks *v1beta1.Webhooks, version string) error { - database, err := databases.Create(ctx, stack, webhooks) - if err != nil { - return err - } - - consumer, err := brokerconsumers.CreateOrUpdateOnAllServices(ctx, webhooks) - if err != nil { - return err - } - - if err := gatewayhttpapis.Create(ctx, webhooks, gatewayhttpapis.WithHealthCheckEndpoint("_healthcheck")); err != nil { - return err - } - - if !database.Status.Ready { - return NewPendingError().WithMessage("database not ready") - } - - image, err := registries.GetImage(ctx, stack, "webhooks", version) - if err != nil { - return errors.Wrap(err, "resolving image") - } - - if IsGreaterOrEqual(version, "v2.0.0-rc.5") && databases.GetSavedModuleVersion(database) != version { - serviceAccountName, err := settings.GetAWSServiceAccount(ctx, stack.Name) - if err != nil { - return errors.Wrap(err, "resolving service account") - } - - migrateContainer, err := databases.MigrateDatabaseContainer(ctx, stack, image, database) - if err != nil { - return errors.Wrap(err, "creating migration container") - } - - if err := jobs.Handle(ctx, webhooks, "migrate", - migrateContainer, - jobs.WithServiceAccount(serviceAccountName), - ); err != nil { - return err - } - if err := databases.SaveModuleVersion(ctx, database, version); err != nil { - return errors.Wrap(err, "saving module version in database object") - } - } - - if consumer.Status.Ready { - if IsGreaterOrEqual(version, "v0.7.1") { - if err := createSingleDeployment(ctx, stack, webhooks, database, consumer, version); err != nil { - return err - } - } else { - if err := createDualDeployment(ctx, stack, webhooks, database, consumer, version); err != nil { - return err - } - } - } - - return nil -} - -func init() { - Init( - WithModuleReconciler(Reconcile, - WithOwn[*v1beta1.Webhooks](&v1beta1.BrokerConsumer{}), - WithOwn[*v1beta1.Webhooks](&appsv1.Deployment{}), - WithOwn[*v1beta1.Webhooks](&v1beta1.GatewayHTTPAPI{}), - WithOwn[*v1beta1.Webhooks](&batchv1.Job{}), - WithOwn[*v1beta1.Webhooks](&v1beta1.ResourceReference{}), - WithWatchSettings[*v1beta1.Webhooks](), - WithWatchDependency[*v1beta1.Webhooks](&v1beta1.Ledger{}), - WithWatchDependency[*v1beta1.Webhooks](&v1beta1.Payments{}), - databases.Watch[*v1beta1.Webhooks](), - ), - ) -} diff --git a/components/operator/internal/tests/auth_controller_test.go b/components/operator/internal/tests/auth_controller_test.go deleted file mode 100644 index 9b7b2e1cce..0000000000 --- a/components/operator/internal/tests/auth_controller_test.go +++ /dev/null @@ -1,197 +0,0 @@ -package tests_test - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/policy/v1" - "k8s.io/apimachinery/pkg/util/intstr" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -var _ = Describe("AuthController", func() { - Context("When creating a Auth object", func() { - var ( - stack *v1beta1.Stack - auth *v1beta1.Auth - databaseSettings *v1beta1.Settings - pdbSettings *v1beta1.Settings - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - databaseSettings = settings.New(uuid.NewString(), "postgres.*.uri", "postgresql://localhost", stack.Name) - pdbSettings = settings.New(uuid.NewString(), "deployments.*.pod-disruption-budget", "minAvailable=1", stack.Name) - auth = &v1beta1.Auth{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.AuthSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(Succeed()) - Expect(Create(databaseSettings)).To(Succeed()) - Expect(Create(pdbSettings)).To(Succeed()) - Expect(Create(auth)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(databaseSettings)).To(Succeed()) - Expect(Delete(pdbSettings)).To(Succeed()) - Expect(Delete(stack)).To(Succeed()) - }) - It("Should create resources", func() { - By("Should create a deployment", func() { - deployment := &appsv1.Deployment{} - Eventually(func() error { - return LoadResource(stack.Name, "auth", deployment) - }).Should(Succeed()) - Expect(deployment).To(BeControlledBy(auth)) - Expect(deployment.Spec.Template.Spec.Containers[0].Env).To(ContainElements( - core.Env("BASE_URL", "http://auth:8080"), - )) - }) - By("Should create a pdb", func() { - pdb := &v1.PodDisruptionBudget{} - Eventually(func() error { - return LoadResource(stack.Name, "auth", pdb) - }).Should(Succeed()) - Expect(pdb).To(BeControlledBy(auth)) - Expect(pdb.Spec.MinAvailable).NotTo(BeNil()) - Expect(*pdb.Spec.MinAvailable).To(Equal(intstr.FromInt32(1))) - }) - By("Should create a new GatewayHTTPAPI object", func() { - httpService := &v1beta1.GatewayHTTPAPI{} - Eventually(func() error { - return LoadResource("", core.GetObjectName(stack.Name, "auth"), httpService) - }).Should(Succeed()) - }) - By("Should set the status to ready", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", auth.Name, auth)).To(Succeed()) - return auth.Status.Ready - }).Should(BeTrue()) - }) - By("Should add an owner reference on the stack", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", auth.Name, auth)).To(Succeed()) - reference, err := core.HasOwnerReference(TestContext(), stack, auth) - g.Expect(err).To(BeNil()) - return reference - }).Should(BeTrue()) - }) - }) - Context("Then when disabling the stack", func() { - JustBeforeEach(func() { - Eventually(func(g Gomega) *v1beta1.Auth { - g.Expect(LoadResource("", auth.Name, auth)).To(Succeed()) - return auth - }).Should(BeReady()) - patch := client.MergeFrom(stack.DeepCopy()) - stack.Spec.Disabled = true - Expect(Patch(stack, patch)).To(Succeed()) - }) - It("Should remove all dependents objects except the Database object", func() { - By("It should remove the deployment", func() { - deployment := &appsv1.Deployment{} - Eventually(func() error { - return LoadResource(stack.Name, "auth", deployment) - }).Should(BeNotFound()) - }) - By("It should remove the GatewayHTTPAPI object", func() { - gatewayHTTPApi := &v1beta1.GatewayHTTPAPI{} - Eventually(func() error { - return LoadResource("", core.GetObjectName(stack.Name, "auth"), gatewayHTTPApi) - }).Should(BeNotFound()) - }) - }) - }) - Context("Then when create an AuthClient object", func() { - var ( - authClient *v1beta1.AuthClient - ) - JustBeforeEach(func() { - authClient = &v1beta1.AuthClient{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.AuthClientSpec{ - ID: "client0", - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Secret: "secret", - }, - } - Expect(Create(authClient)).To(Succeed()) - Eventually(func(g Gomega) []string { - g.Expect(LoadResource("", auth.Name, auth)).To(Succeed()) - return auth.Status.Clients - }).Should(ContainElements(authClient.Name)) - }) - JustAfterEach(func() { - Expect(Delete(authClient)).To(Succeed()) - }) - It("Should configure the config map with the auth client", func() { - cm := &corev1.ConfigMap{} - Expect(LoadResource(stack.Name, "auth-configuration", cm)).To(Succeed()) - Expect(cm.Data["config.yaml"]).To(MatchGoldenFile("auth-controller", "config-with-auth-client.yaml")) - }) - }) - Context("with a Gateway", func() { - var ( - gateway *v1beta1.Gateway - ) - BeforeEach(func() { - gateway = &v1beta1.Gateway{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.GatewaySpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - }) - JustBeforeEach(func() { - Expect(Create(gateway)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(gateway)).To(Succeed()) - }) - It("Should create a deployment with proper BASE_URL env var", func() { - deployment := &appsv1.Deployment{} - Eventually(func(g Gomega) []corev1.EnvVar { - g.Expect(LoadResource(stack.Name, "auth", deployment)).To(Succeed()) - return deployment.Spec.Template.Spec.Containers[0].Env - }).Should(ContainElements( - core.Env("BASE_URL", "http://gateway:8080/api/auth"), - )) - }) - Context("with an ingress", func() { - BeforeEach(func() { - gateway.Spec.Ingress = &v1beta1.GatewayIngress{ - Host: "example.net", - Scheme: "https", - } - }) - It("Should create a deployment with proper BASE_URL env var", func() { - deployment := &appsv1.Deployment{} - Eventually(func(g Gomega) []corev1.EnvVar { - g.Expect(LoadResource(stack.Name, "auth", deployment)).To(Succeed()) - return deployment.Spec.Template.Spec.Containers[0].Env - }).Should(ContainElements( - core.Env("BASE_URL", "https://example.net/api/auth"), - )) - }) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/authclient_controller_test.go b/components/operator/internal/tests/authclient_controller_test.go deleted file mode 100644 index 0fbfc41451..0000000000 --- a/components/operator/internal/tests/authclient_controller_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package tests_test - -import ( - "fmt" - - . "github.com/formancehq/operator/internal/tests/internal" - - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - corev1 "k8s.io/api/core/v1" -) - -var _ = Describe("AuthClientController", func() { - Context("When creating a AuthClient object", func() { - var ( - stack *v1beta1.Stack - authClient *v1beta1.AuthClient - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - authClient = &v1beta1.AuthClient{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.AuthClientSpec{ - ID: uuid.NewString(), - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Secret: uuid.NewString(), - }, - } - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(Succeed()) - Expect(Create(authClient)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(authClient)).To(Succeed()) - Expect(Delete(stack)).To(Succeed()) - }) - It("Should create a secret", func() { - secret := &corev1.Secret{} - Eventually(func() error { - return LoadResource(stack.Name, fmt.Sprintf("auth-client-%s", authClient.Name), secret) - }).Should(Succeed()) - }) - }) -}) diff --git a/components/operator/internal/tests/benthos_controller_test.go b/components/operator/internal/tests/benthos_controller_test.go deleted file mode 100644 index e79b5b7de3..0000000000 --- a/components/operator/internal/tests/benthos_controller_test.go +++ /dev/null @@ -1,122 +0,0 @@ -package tests_test - -import ( - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -var _ = Describe("BenthosController", func() { - - Context("When creating a Benthos", func() { - var ( - benthos *v1beta1.Benthos - broker *v1beta1.Broker - stack *v1beta1.Stack - brokerDSNSettings *v1beta1.Settings - elasticSearchDSNSettings *v1beta1.Settings - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - brokerDSNSettings = settings.New(uuid.NewString(), "broker.dsn", "nats://localhost:1234", stack.Name) - elasticSearchDSNSettings = settings.New(uuid.NewString(), "elasticsearch.dsn", "https://localhost", stack.Name) - broker = &v1beta1.Broker{ - ObjectMeta: v1.ObjectMeta{ - Name: stack.Name, - }, - Spec: v1beta1.BrokerSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - benthos = &v1beta1.Benthos{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.BenthosSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - }) - JustBeforeEach(func() { - Expect(Create(brokerDSNSettings)).To(BeNil()) - Expect(Create(stack)).To(Succeed()) - Expect(Create(elasticSearchDSNSettings)).To(Succeed()) - Expect(Create(broker)).To(Succeed()) - Expect(Create(benthos)).To(Succeed()) - }) - JustAfterEach(func() { - Expect(Delete(stack)).To(Succeed()) - Expect(Delete(elasticSearchDSNSettings)).To(Succeed()) - Expect(Delete(brokerDSNSettings)).To(Succeed()) - }) - It("Should create appropriate resources", func() { - By("Should create a deployment", func() { - t := &appsv1.Deployment{} - Eventually(func() error { - return Get(core.GetNamespacedResourceName(stack.Name, "benthos"), t) - }).Should(BeNil()) - }) - By("Should create a ConfigMap for templates configuration", func() { - t := &corev1.ConfigMap{} - Eventually(func() error { - return Get(core.GetNamespacedResourceName(stack.Name, "benthos-templates"), t) - }).Should(BeNil()) - }) - By("Should create a ConfigMap for resources configuration", func() { - t := &corev1.ConfigMap{} - Eventually(func() error { - return Get(core.GetNamespacedResourceName(stack.Name, "benthos-resources"), t) - }).Should(BeNil()) - }) - }) - Context("with audit enabled on stack", func() { - BeforeEach(func() { - stack.Spec.EnableAudit = true - }) - It("Should properly configure the service", func() { - By("should add a config map for the stream", func() { - Eventually(func() error { - cm := &corev1.ConfigMap{} - return LoadResource(stack.Name, "benthos-audit", cm) - }).Should(Succeed()) - }) - By("should add a cmd args to the deployment", func() { - t := &appsv1.Deployment{} - Eventually(func(g Gomega) []string { - g.Expect(LoadResource(stack.Name, "benthos", t)).To(Succeed()) - return t.Spec.Template.Spec.Containers[0].Command - }).Should(ContainElement("/audit/gateway_audit.yaml")) - }) - }) - Context("then disabling audit", func() { - JustBeforeEach(func() { - Eventually(func() error { - cm := &corev1.ConfigMap{} - return LoadResource(stack.Name, "benthos-audit", cm) - }).Should(Succeed()) - patch := client.MergeFrom(stack.DeepCopy()) - stack.Spec.EnableAudit = false - Expect(Patch(stack, patch)).To(Succeed()) - }) - It("should remove the associated config map", func() { - Eventually(func() error { - return LoadResource(stack.Name, "benthos-audit", &corev1.ConfigMap{}) - }).Should(BeNotFound()) - }) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/benthosstream_controller_test.go b/components/operator/internal/tests/benthosstream_controller_test.go deleted file mode 100644 index bf878631a5..0000000000 --- a/components/operator/internal/tests/benthosstream_controller_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package tests_test - -import ( - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - . "github.com/formancehq/operator/internal/tests/internal" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - corev1 "k8s.io/api/core/v1" -) - -var _ = Describe("StreamController", func() { - Context("When creating a BenthosStream", func() { - var ( - stream *v1beta1.BenthosStream - stack *v1beta1.Stack - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - Expect(Create(stack)).To(BeNil()) - stream = &v1beta1.BenthosStream{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.BenthosStreamSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - Expect(Create(stream)).To(Succeed()) - }) - It("Should create a ConfigMap", func() { - t := &corev1.ConfigMap{} - Eventually(func() error { - return Get(core.GetNamespacedResourceName(stack.Name, "stream-"+stream.Name), t) - }).Should(BeNil()) - }) - }) -}) diff --git a/components/operator/internal/tests/brokerconsumer_controller_test.go b/components/operator/internal/tests/brokerconsumer_controller_test.go deleted file mode 100644 index ee5fe6f8a9..0000000000 --- a/components/operator/internal/tests/brokerconsumer_controller_test.go +++ /dev/null @@ -1,109 +0,0 @@ -package tests_test - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -var _ = Describe("BrokerConsumer", func() { - Context("When creating a BrokerConsumer", func() { - var ( - brokerConsumer *v1beta1.BrokerConsumer - brokerNatsDSNSettings *v1beta1.Settings - stack *v1beta1.Stack - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - Expect(Create(stack)).To(BeNil()) - brokerNatsDSNSettings = settings.New(uuid.NewString(), "broker.dsn", "nats://localhost:1234", stack.Name) - Expect(Create(brokerNatsDSNSettings)).To(BeNil()) - brokerConsumer = &v1beta1.BrokerConsumer{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.BrokerConsumerSpec{ - Services: []string{"ledger"}, - QueriedBy: "orchestration", - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - Expect(Create(brokerConsumer)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(stack)).To(Succeed()) - Expect(Delete(brokerNatsDSNSettings)).To(Succeed()) - Expect(client.IgnoreNotFound(Delete(brokerConsumer))).To(Succeed()) - }) - It("Should create a BrokerTopic", func() { - t := &v1beta1.BrokerTopic{} - Eventually(func(g Gomega) *v1beta1.BrokerTopic { - g.Expect(Get(core.GetResourceName( - core.GetObjectName(stack.Name, brokerConsumer.Spec.Services[0])), t)).To(Succeed()) - return t - }).Should(BeOwnedBy(brokerConsumer)) - }) - Context("Then when the BrokerTopic is ready", func() { - t := &v1beta1.BrokerTopic{} - BeforeEach(func() { - Eventually(func(g Gomega) bool { - g.Expect(Get(core.GetResourceName( - core.GetObjectName(stack.Name, brokerConsumer.Spec.Services[0])), t)).To(Succeed()) - return t.Status.Ready - }).Should(BeTrue()) - }) - It("Should set the BrokerConsumer to ready status", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", brokerConsumer.Name, brokerConsumer)).To(Succeed()) - return brokerConsumer.Status.Ready - }).Should(BeTrue()) - }) - Context("Then create a new BrokerConsumer on the same service", func() { - brokerConsumer2 := &v1beta1.BrokerConsumer{} - BeforeEach(func() { - brokerConsumer2 = &v1beta1.BrokerConsumer{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.BrokerConsumerSpec{ - Services: []string{brokerConsumer.Spec.Services[0]}, - QueriedBy: "webhooks", - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - Expect(Create(brokerConsumer2)).To(Succeed()) - }) - AfterEach(func() { - Expect(client.IgnoreNotFound(Delete(brokerConsumer2))).To(Succeed()) - }) - It("Should be set to ready too", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", brokerConsumer2.Name, brokerConsumer2)).To(Succeed()) - - return brokerConsumer2.Status.Ready - }).Should(BeTrue()) - }) - Context("Then first BrokerConsumer object", func() { - BeforeEach(func() { - Expect(Delete(brokerConsumer)).To(Succeed()) - }) - It("Should remove the service from the queries of the topic", func() { - Eventually(func(g Gomega) *v1beta1.BrokerTopic { - topic := &v1beta1.BrokerTopic{} - g.Expect(Get(core.GetResourceName(core.GetObjectName(stack.Name, brokerConsumer.Spec.Services[0])), topic)).To(Succeed()) - return topic - }).ShouldNot(BeControlledBy(brokerConsumer)) - }) - }) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/brokertopic_controller_test.go b/components/operator/internal/tests/brokertopic_controller_test.go deleted file mode 100644 index edd7305c89..0000000000 --- a/components/operator/internal/tests/brokertopic_controller_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package tests_test - -import ( - "github.com/formancehq/operator/internal/resources/settings" - - . "github.com/formancehq/operator/internal/tests/internal" - - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" -) - -var _ = Describe("BrokerTopicController", func() { - Context("When creating a BrokerTopic", func() { - var ( - stack *v1beta1.Stack - brokerTopic *v1beta1.BrokerTopic - brokerDSNSettings *v1beta1.Settings - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: v1.ObjectMeta{ - Name: uuid.NewString(), - }, - Spec: v1beta1.StackSpec{}, - } - Expect(Create(stack)).To(BeNil()) - brokerDSNSettings = settings.New(uuid.NewString(), "broker.dsn", "nats://localhost:1234", stack.Name) - Expect(Create(brokerDSNSettings)).To(BeNil()) - brokerTopic = &v1beta1.BrokerTopic{ - ObjectMeta: v1.ObjectMeta{ - Name: uuid.NewString(), - }, - Spec: v1beta1.BrokerTopicSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Service: "ledger", - }, - } - // notes(gfyrag): add a "fake" owner reference to prevent automatic deletion - Expect(controllerutil.SetOwnerReference(brokerDSNSettings, brokerTopic, GetScheme())).To(Succeed()) - Expect(controllerutil.SetOwnerReference(stack, brokerTopic, GetScheme())).To(Succeed()) - Expect(Create(brokerTopic)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(stack)).To(Succeed()) - Expect(client.IgnoreNotFound(Delete(brokerTopic))).To(Succeed()) - Expect(Delete(brokerDSNSettings)).To(Succeed()) - }) - It("Should be set to ready status", func() { - t := &v1beta1.BrokerTopic{} - Eventually(func(g Gomega) bool { - g.Expect(Get(core.GetResourceName(brokerTopic.Name), t)).To(Succeed()) - return t.Status.Ready - }).Should(BeTrue()) - }) - Context("Then updating removing all owner references", func() { - BeforeEach(func() { - Eventually(func(g Gomega) bool { - t := &v1beta1.BrokerTopic{} - g.Expect(Get(core.GetResourceName(brokerTopic.Name), t)).To(Succeed()) - return t.Status.Ready - }).Should(BeTrue()) - - patch := client.MergeFrom(brokerTopic.DeepCopy()) - Expect(controllerutil.RemoveOwnerReference(brokerDSNSettings, brokerTopic, GetScheme())).To(Succeed()) - Expect(Patch(brokerTopic, patch)).To(Succeed()) - }) - It("Should trigger the deletion of the brokerTopic object", func() { - Eventually(func(g Gomega) error { - return LoadResource("", brokerTopic.Name, brokerTopic) - }).Should(BeNotFound()) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/database_controller_test.go b/components/operator/internal/tests/database_controller_test.go deleted file mode 100644 index 144c9f0cb9..0000000000 --- a/components/operator/internal/tests/database_controller_test.go +++ /dev/null @@ -1,217 +0,0 @@ -package tests_test - -import ( - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/resources/resourcereferences" - "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - batchv1 "k8s.io/api/batch/v1" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -var _ = Describe("DatabaseController", func() { - Context("When creating a Database", func() { - var ( - stack *v1beta1.Stack - database *v1beta1.Database - databaseSettings *v1beta1.Settings - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - databaseSettings = settings.New(uuid.NewString(), "postgres.*.uri", "postgresql://localhost", stack.Name) - database = &v1beta1.Database{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.DatabaseSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Service: "ledger", - }, - } - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(BeNil()) - Expect(Create(database)).To(Succeed()) - }) - JustAfterEach(func() { - Expect(client.IgnoreNotFound(Delete(database))).To(Succeed()) - Expect(client.IgnoreNotFound(Delete(stack))).To(Succeed()) - }) - shouldBeReady := func() { - d := &v1beta1.Database{} - Eventually(func(g Gomega) *v1beta1.Database { - g.Expect(LoadResource("", database.Name, d)).To(Succeed()) - return d - }).Should(BeReady()) - } - Context("With no settings", func() { - shouldReportAnError := func() { - d := &v1beta1.Database{} - Eventually(func(g Gomega) string { - g.Expect(LoadResource("", database.Name, d)).To(Succeed()) - return d.Status.Info - }).ShouldNot(BeEmpty()) - } - It("should report an error", shouldReportAnError) - Context("Then creating settings", func() { - JustBeforeEach(func() { - shouldReportAnError() - Expect(Create(databaseSettings)).Should(Succeed()) - DeferCleanup(func() { - Expect(Delete(databaseSettings)).To(Succeed()) - }) - }) - It("should eventually be properly reconciled", shouldBeReady) - }) - }) - Context("With correct settings", func() { - JustBeforeEach(func() { - Expect(Create(databaseSettings)).Should(Succeed()) - }) - JustAfterEach(func() { - Expect(Delete(databaseSettings)).To(Succeed()) - }) - It("Should be set to ready status", shouldBeReady) - Context("Then when deleting the Database object", func() { - JustBeforeEach(func() { - shouldBeReady() - clearDatabaseSettings := settings.New(uuid.NewString(), "clear-database", "true", stack.Name) - Expect(Create(clearDatabaseSettings)).To(Succeed()) - Expect(Delete(database)).To(Succeed()) - DeferCleanup(func() { - Expect(Delete(clearDatabaseSettings)).To(Succeed()) - }) - }) - It("Should delete the database", func() { - By("Should create a deletion job", func() { - Eventually(func() error { - return LoadResource(stack.Name, fmt.Sprintf("%s-drop-database", database.UID), &batchv1.Job{}) - }).Should(Succeed()) - }) - By("Should eventually be deleted", func() { - Eventually(func() error { - return LoadResource(stack.Name, database.Name, &v1beta1.Database{}) - }).Should(BeNotFound()) - }) - }) - }) - Context("With a settings preventing database cleaning", func() { - var clearDatabaseSettings *v1beta1.Settings - JustBeforeEach(func() { - shouldBeReady() - clearDatabaseSettings = settings.New(uuid.NewString(), "clear-database", "false", stack.Name) - Expect(Create(clearDatabaseSettings)).To(Succeed()) - Expect(Delete(database)).To(Succeed()) - DeferCleanup(func() { - Expect(Delete(clearDatabaseSettings)).To(Succeed()) - }) - }) - It("Should not delete the real database", func() { - By("Should not create a deletion job", func() { - Consistently(func() error { - return LoadResource(stack.Name, fmt.Sprintf("%s-drop-database", database.Spec.Service), &batchv1.Job{}) - }, "2s").Should(BeNotFound()) - }) - By("Should eventually be deleted", func() { - Eventually(func() error { - return LoadResource(stack.Name, database.Name, &v1beta1.Database{}) - }).Should(BeNotFound()) - }) - }) - }) - Context("Then when updating the DatabaseConfiguration object", func() { - JustBeforeEach(func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", database.Name, database)).To(Succeed()) - return database.Status.Ready - }).Should(BeTrue()) - - patch := client.MergeFrom(databaseSettings.DeepCopy()) - databaseSettings.Spec.Value = "postgresql://xxx" - Expect(Patch(databaseSettings, patch)).To(Succeed()) - }) - It("Should declare the Database object as out of sync", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", database.Name, database)).To(Succeed()) - - return database.Status.OutOfSync - }).Should(BeTrue()) - }) - }) - Context("using a secret for credentials", func() { - var ( - secret1 *v1.Secret - ) - BeforeEach(func() { - secret1 = &v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: uuid.NewString(), - Namespace: "default", - Labels: map[string]string{ - v1beta1.StackLabel: stack.Name, - }, - Annotations: map[string]string{ - resourcereferences.RewrittenResourceName: "postgres", - }, - }, - Data: map[string][]byte{ - "username": []byte("formance"), - "password": []byte("formance"), - }, - } - Expect(Create(secret1)).To(Succeed()) - databaseSettings.Spec.Value = "postgresql://xxx?secret=postgres" - }) - shouldCreateResourceReference := func() { - resourceReference := &v1beta1.ResourceReference{} - Eventually(func(g Gomega) error { - return LoadResource("", fmt.Sprintf("%s-postgres", database.Name), resourceReference) - }).Should(Succeed()) - } - It("Should create a secret reference", shouldCreateResourceReference) - Context("Then changing the secret", func() { - var secret2 *v1.Secret - JustBeforeEach(func() { - shouldCreateResourceReference() - secret2 = &v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: uuid.NewString(), - Namespace: "default", - Labels: map[string]string{ - v1beta1.StackLabel: stack.Name, - }, - Annotations: map[string]string{ - resourcereferences.RewrittenResourceName: "postgres2", - }, - }, - Data: map[string][]byte{ - "username": []byte("formance"), - "password": []byte("formance"), - }, - } - Expect(Create(secret2)).To(Succeed()) - patch := client.MergeFrom(databaseSettings.DeepCopy()) - databaseSettings.Spec.Value = "postgresql://xxx?secret=postgres2" - Expect(Patch(databaseSettings, patch)).To(Succeed()) - }) - It("Should create the new secret and remove the old one", func() { - shouldCreateResourceReference() - Eventually(func() error { - return LoadResource(stack.Name, fmt.Sprintf("%s-postgres", database.Name), secret1) - }).Should(BeNotFound()) - }) - }) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/gateway_controller_test.go b/components/operator/internal/tests/gateway_controller_test.go deleted file mode 100644 index 80da85c60e..0000000000 --- a/components/operator/internal/tests/gateway_controller_test.go +++ /dev/null @@ -1,257 +0,0 @@ -package tests_test - -import ( - "fmt" - - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/settings" - "github.com/google/uuid" - - . "github.com/formancehq/operator/internal/tests/internal" - - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/resources/gatewayhttpapis" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -var _ = Describe("GatewayController", func() { - Context("When creating a Gateway", func() { - var ( - stack *v1beta1.Stack - gateway *v1beta1.Gateway - httpAPI *v1beta1.GatewayHTTPAPI - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - gateway = &v1beta1.Gateway{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.GatewaySpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Ingress: &v1beta1.GatewayIngress{ - Host: "example.net", - Scheme: "https", - }, - }, - } - httpAPI = &v1beta1.GatewayHTTPAPI{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.GatewayHTTPAPISpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Name: "ledger", - Rules: []v1beta1.GatewayHTTPAPIRule{gatewayhttpapis.RuleSecured()}, - }, - } - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(BeNil()) - Expect(Create(httpAPI)).To(Succeed()) - Expect(Create(gateway)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(stack)).To(BeNil()) - Expect(Delete(httpAPI)).To(Succeed()) - }) - It("Should create resources", func() { - By("Should add an owner reference on the stack", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", gateway.Name, gateway)).To(Succeed()) - reference, err := core.HasOwnerReference(TestContext(), stack, gateway) - g.Expect(err).To(BeNil()) - return reference - }).Should(BeTrue()) - }) - By("Should create a deployment", func() { - Eventually(func() error { - return LoadResource(stack.Name, "gateway", &appsv1.Deployment{}) - }).Should(Succeed()) - }) - By("Should create a service", func() { - Eventually(func() error { - return LoadResource(stack.Name, "gateway", &corev1.Service{}) - }).Should(Succeed()) - }) - By("Should create a config map with the Caddyfile", func() { - Eventually(func(g Gomega) []string { - g.Expect(LoadResource("", gateway.Name, gateway)) - - return gateway.Status.SyncHTTPAPIs - }).Should(ContainElements(httpAPI.Spec.Name)) - - cm := &corev1.ConfigMap{} - Expect(LoadResource(stack.Name, "gateway", cm)).To(Succeed()) - Expect(cm.Data["Caddyfile"]).To( - MatchGoldenFile("gateway-controller", "configmap-with-ledger-only.yaml")) - }) - }) - Context("with a host defined", func() { - JustBeforeEach(func() { - patch := client.MergeFrom(gateway.DeepCopy()) - gateway.Spec.Ingress = &v1beta1.GatewayIngress{ - Host: "example.com", - Scheme: "https", - } - Expect(Patch(gateway, patch)).To(Succeed()) - }) - It("Should create an ingress", func() { - Eventually(func() error { - return LoadResource(stack.Name, "gateway", &networkingv1.Ingress{}) - }).Should(Succeed()) - }) - Context("Then removing the hostname from the gateway", func() { - var ingress *networkingv1.Ingress - JustBeforeEach(func() { - ingress = &networkingv1.Ingress{} - Eventually(func() error { - return LoadResource(stack.Name, "gateway", ingress) - }).Should(Succeed()) - patch := client.MergeFrom(gateway.DeepCopy()) - gateway.Spec.Ingress = nil - Expect(Patch(gateway, patch)).To(Succeed()) - }) - It("should delete the ingress", func() { - Eventually(func() error { - return LoadResource(stack.Name, "gateway", &networkingv1.Ingress{}) - }).Should(BeNotFound()) - }) - }) - Context("With a setting to configure ingress annotations", func() { - var ingressSetting *v1beta1.Settings - JustBeforeEach(func() { - ingressSetting = settings.New(uuid.NewString(), "gateway.ingress.annotations", "foo=bar", stack.Name) - Expect(Create(ingressSetting)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(ingressSetting)).To(Succeed()) - }) - It("Should create the ingress with correct annotations", func() { - Eventually(func(g Gomega) map[string]string { - i := &networkingv1.Ingress{} - g.Expect(LoadResource(stack.Name, "gateway", i)).To(Succeed()) - return i.Annotations - }).Should(HaveKeyWithValue("foo", "bar")) - }) - }) - }) - Context("Then adding a new HTTPService", func() { - var anotherHttpService *v1beta1.GatewayHTTPAPI - BeforeEach(func() { - anotherHttpService = &v1beta1.GatewayHTTPAPI{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.GatewayHTTPAPISpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Name: "another", - Rules: []v1beta1.GatewayHTTPAPIRule{ - { - Path: "/webhooks", - Methods: []string{"POST"}, - Secured: true, - }, - gatewayhttpapis.RuleSecured(), - }, - }, - } - Expect(Create(anotherHttpService)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(anotherHttpService)).To(Succeed()) - }) - It("Should trigger deployment gateway with the new service", func() { - Eventually(func(g Gomega) []string { - g.Expect(LoadResource("", gateway.Name, gateway)) - - return gateway.Status.SyncHTTPAPIs - }).Should(ContainElements(httpAPI.Spec.Name, anotherHttpService.Spec.Name)) - - cm := &corev1.ConfigMap{} - Expect(LoadResource(stack.Name, "gateway", cm)).To(Succeed()) - Expect(cm.Data["Caddyfile"]).To( - MatchGoldenFile("gateway-controller", "configmap-with-ledger-and-another-service.yaml")) - }) - }) - Context("With audit enabled", func() { - var ( - brokerNatsDSNSettings *v1beta1.Settings - consumer *v1beta1.BrokerConsumer - ) - BeforeEach(func() { - stack.Spec.EnableAudit = true - brokerNatsDSNSettings = settings.New(uuid.NewString(), "broker.dsn", "nats://localhost:1234", stack.Name) - consumer = &v1beta1.BrokerConsumer{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.BrokerConsumerSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Services: []string{"gateway"}, - }, - } - }) - JustBeforeEach(func() { - Expect(Create(brokerNatsDSNSettings)).To(BeNil()) - Expect(Create(consumer)).To(Succeed()) - }) - JustAfterEach(func() { - Expect(Delete(consumer)).To(Succeed()) - Expect(Delete(brokerNatsDSNSettings)).To(Succeed()) - }) - It("Should configure the service", func() { - By("Should create a topic", func() { - Eventually(func() error { - topic := &v1beta1.BrokerTopic{} - return LoadResource("", fmt.Sprintf("%s-gateway", stack.GetName()), topic) - }).Should(Succeed()) - }) - By("Should adapt the Caddyfile", func() { - cm := &corev1.ConfigMap{} - Eventually(func(g Gomega) string { - g.Expect(LoadResource(stack.Name, "gateway", cm)).To(Succeed()) - return cm.Data["Caddyfile"] - }).Should(MatchGoldenFile("gateway-controller", "configmap-with-audit.yaml")) - }) - }) - }) - Context("With otlp enabled", func() { - var otelTracesDSNSetting *v1beta1.Settings - JustBeforeEach(func() { - otelTracesDSNSetting = settings.New(uuid.NewString(), "opentelemetry.traces.dsn", "grpc://collector", stack.Name) - Expect(Create(otelTracesDSNSetting)).To(Succeed()) - }) - JustAfterEach(func() { - Expect(Delete(otelTracesDSNSetting)).To(Succeed()) - }) - It("Should adapt the service", func() { - By("Should adapt the Caddyfile", func() { - cm := &corev1.ConfigMap{} - Eventually(func(g Gomega) string { - g.Expect(LoadResource(stack.Name, "gateway", cm)).To(Succeed()) - return cm.Data["Caddyfile"] - }).Should(MatchGoldenFile("gateway-controller", "configmap-with-opentelemetry.yaml")) - }) - By("Should add env vars to the deployment", func() { - Eventually(func(g Gomega) []corev1.EnvVar { - d := &appsv1.Deployment{} - g.Expect(LoadResource(stack.Name, "gateway", d)).To(Succeed()) - return d.Spec.Template.Spec.Containers[0].Env - }).Should(ContainElements(corev1.EnvVar{ - Name: "OTEL_SERVICE_NAME", - Value: "gateway", - })) - }) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/gatewayhttpapi_controller_test.go b/components/operator/internal/tests/gatewayhttpapi_controller_test.go deleted file mode 100644 index f8220a0055..0000000000 --- a/components/operator/internal/tests/gatewayhttpapi_controller_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package tests_test - -import ( - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/resources/gatewayhttpapis" - "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - corev1 "k8s.io/api/core/v1" -) - -var _ = Describe("GatewayHTTPAPI", func() { - Context("When creating an GatewayHTTPAPI", func() { - var ( - stack *v1beta1.Stack - httpAPI *v1beta1.GatewayHTTPAPI - ) - BeforeEach(func() { - - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - httpAPI = &v1beta1.GatewayHTTPAPI{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.GatewayHTTPAPISpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Name: "ledger", - Rules: []v1beta1.GatewayHTTPAPIRule{gatewayhttpapis.RuleSecured()}, - }, - } - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(BeNil()) - Expect(Create(httpAPI)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(httpAPI)).To(Succeed()) - Expect(Delete(stack)).To(BeNil()) - }) - It("Should create a k8s service", func() { - service := &corev1.Service{} - Eventually(func() error { - return LoadResource(stack.Name, "ledger", service) - }).Should(BeNil()) - Expect(service).To(BeControlledBy(httpAPI)) - Expect(service.Spec.Selector).To(Equal(map[string]string{ - "app.kubernetes.io/name": httpAPI.Spec.Name, - })) - }) - Context("With user defined annotations", func() { - var ( - annotationsSettings *v1beta1.Settings - ) - JustBeforeEach(func() { - annotationsSettings = settings.New(uuid.NewString(), "services.*.annotations", "foo=bar", stack.Name) - Expect(Create(annotationsSettings)).To(Succeed()) - }) - JustAfterEach(func() { - Expect(Delete(annotationsSettings)).To(Succeed()) - }) - It("should add annotations to the service", func() { - Eventually(func(g Gomega) bool { - service := &corev1.Service{} - g.Expect(LoadResource(stack.Name, "ledger", service)).To(Succeed()) - g.Expect(service.Annotations).To(Equal(map[string]string{ - "foo": "bar", - })) - return true - }).Should(BeTrue()) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/internal/bootstrap.go b/components/operator/internal/tests/internal/bootstrap.go deleted file mode 100644 index 4c1846c1a0..0000000000 --- a/components/operator/internal/tests/internal/bootstrap.go +++ /dev/null @@ -1,229 +0,0 @@ -package internal - -import ( - "context" - "os" - "path/filepath" - osRuntime "runtime" - "time" - - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - _ "github.com/formancehq/operator/internal/resources" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - batchv1 "k8s.io/api/batch/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - controllerruntime "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - //+kubebuilder:scaffold:imports -) - -var ( - ctx context.Context - cancel func() - testEnv *envtest.Environment - restConfig *rest.Config - k8sClient client.Client - coreMgr core.Manager -) - -func GetScheme() *runtime.Scheme { - return scheme.Scheme -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - ctx, cancel = context.WithCancel(context.Background()) - - SetDefaultEventuallyTimeout(10 * time.Second) - - _, filename, _, _ := osRuntime.Caller(0) - - apiServer := envtest.APIServer{} - apiServer.Configure(). - Set("service-cluster-ip-range", "10.0.0.0/20") - - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join(filepath.Dir(filename), "..", "..", "..", "config", "crd", "bases"), - }, - ErrorIfCRDPathMissing: true, - ControlPlane: envtest.ControlPlane{ - APIServer: &apiServer, - }, - } - - var err error - restConfig, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(restConfig).NotTo(BeNil()) - - Expect(v1beta1.AddToScheme(scheme.Scheme)).To(Succeed()) - - k8sClient, err = client.New(restConfig, client.Options{ - Scheme: scheme.Scheme, - }) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - - ctx, cancel = context.WithCancel(context.Background()) - mgr, err := ctrl.NewManager(restConfig, ctrl.Options{ - Scheme: GetScheme(), - Metrics: server.Options{ - BindAddress: "0", - }, - Client: client.Options{ - Cache: &client.CacheOptions{ - Unstructured: true, - }, - }, - }) - Expect(err).ToNot(HaveOccurred()) - coreMgr = core.NewDefaultManager(mgr, core.Platform{ - Region: "testing", - Environment: "testing", - }) - - Expect(core.Setup(mgr, core.Platform{ - Region: "us-west-1", - Environment: "staging", - })).To(Succeed()) - - err = ctrl.NewControllerManagedBy(mgr). - For(&appsv1.Deployment{}). - WithOptions(controllerruntime.Options{ - MaxConcurrentReconciles: 100, - }). - Complete(reconcile.Func(func(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { - - deployment := &appsv1.Deployment{} - if err := mgr.GetClient().Get(ctx, types.NamespacedName{ - Namespace: request.Namespace, - Name: request.Name, - }, deployment); err != nil { - return reconcile.Result{}, err - } - deployment.Status.ObservedGeneration = deployment.Generation - deployment.Status.UpdatedReplicas = 1 - deployment.Status.AvailableReplicas = 1 - deployment.Status.Replicas = 1 - deployment.Status.ReadyReplicas = 1 - if err := mgr.GetClient().Status().Update(ctx, deployment); err != nil { - return reconcile.Result{}, err - } - - return reconcile.Result{}, nil - })) - Expect(err) - - err = ctrl.NewControllerManagedBy(mgr). - For(&batchv1.Job{}). - WithOptions(controllerruntime.Options{ - MaxConcurrentReconciles: 100, - }). - Complete(reconcile.Func(func(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { - - job := &batchv1.Job{} - if err := mgr.GetClient().Get(ctx, types.NamespacedName{ - Namespace: request.Namespace, - Name: request.Name, - }, job); err != nil { - if client.IgnoreNotFound(err) == nil { - return reconcile.Result{}, nil - } - return reconcile.Result{}, err - } - if !job.DeletionTimestamp.IsZero() { - patch := client.MergeFrom(job.DeepCopy()) - if controllerutil.RemoveFinalizer(job, "orphan") { - if err := mgr.GetClient().Patch(ctx, job, patch); err != nil { - return reconcile.Result{}, err - } - } - return reconcile.Result{}, nil - } - job.Status.Succeeded = 1 - - if err := mgr.GetClient().Status().Update(ctx, job); err != nil { - return reconcile.Result{}, err - } - - return reconcile.Result{}, nil - })) - Expect(err) - - go func() { - defer GinkgoRecover() - done = make(chan struct{}) - err := mgr.Start(ctx) - Expect(err).ToNot(HaveOccurred(), "failed to run manager") - close(done) - }() -}) - -var _ = AfterSuite(func() { - cancel() - if done != nil { - <-done - } - Expect(testEnv.Stop()) -}) - -var ( - done chan struct{} -) - -func Create(objects ...client.Object) error { - for _, object := range objects { - if err := k8sClient.Create(ctx, object); err != nil { - return err - } - } - return nil -} - -func Delete(objects ...client.Object) error { - for _, object := range objects { - if err := k8sClient.Delete(ctx, object); err != nil { - return err - } - } - return nil -} - -func Update(ob client.Object) error { - return k8sClient.Update(ctx, ob) -} - -func Patch(ob client.Object, patch client.Patch) error { - return k8sClient.Patch(ctx, ob, patch) -} - -func Get(key types.NamespacedName, ob client.Object) error { - return k8sClient.Get(ctx, key, ob) -} - -func List(list client.ObjectList, opts ...client.ListOption) error { - return k8sClient.List(ctx, list, opts...) -} - -func Client() client.Client { - return k8sClient -} - -func TestContext() core.Context { - return core.NewContext(coreMgr, ctx) -} diff --git a/components/operator/internal/tests/internal/errors.go b/components/operator/internal/tests/internal/errors.go deleted file mode 100644 index 609357e8c9..0000000000 --- a/components/operator/internal/tests/internal/errors.go +++ /dev/null @@ -1,7 +0,0 @@ -package internal - -import "fmt" - -func mismatchTypeError(expected, got any) error { - return fmt.Errorf("expected object of type %T, got %T", expected, got) -} diff --git a/components/operator/internal/tests/internal/matcher_be_controlled_by.go b/components/operator/internal/tests/internal/matcher_be_controlled_by.go deleted file mode 100644 index 102a45fe6a..0000000000 --- a/components/operator/internal/tests/internal/matcher_be_controlled_by.go +++ /dev/null @@ -1,13 +0,0 @@ -package internal - -import ( - gomegaTypes "github.com/onsi/gomega/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func BeControlledBy(owner client.Object) gomegaTypes.GomegaMatcher { - return BeOwnedBy(owner, func(matcher *beOwnedByMatcher) { - matcher.controller = true - matcher.blockOwnerDeletion = true - }) -} diff --git a/components/operator/internal/tests/internal/matcher_be_not_found.go b/components/operator/internal/tests/internal/matcher_be_not_found.go deleted file mode 100644 index 63f6723362..0000000000 --- a/components/operator/internal/tests/internal/matcher_be_not_found.go +++ /dev/null @@ -1,35 +0,0 @@ -package internal - -import ( - "fmt" - - gomegaTypes "github.com/onsi/gomega/types" - controllererrors "k8s.io/apimachinery/pkg/api/errors" -) - -type beNotFound struct{} - -func (b beNotFound) Match(actual interface{}) (success bool, err error) { - if actual == nil { - return false, nil - } - err, ok := actual.(error) - if !ok { - return false, fmt.Errorf("expected error type, got %T", actual) - } - return controllererrors.IsNotFound(err), nil -} - -func (b beNotFound) FailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("should be not found, got %v", actual) -} - -func (b beNotFound) NegatedFailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("should be found, got %v", actual) -} - -var _ gomegaTypes.GomegaMatcher = (*beNotFound)(nil) - -func BeNotFound() gomegaTypes.GomegaMatcher { - return &beNotFound{} -} diff --git a/components/operator/internal/tests/internal/matcher_be_owned_by.go b/components/operator/internal/tests/internal/matcher_be_owned_by.go deleted file mode 100644 index 1bb5eeb18f..0000000000 --- a/components/operator/internal/tests/internal/matcher_be_owned_by.go +++ /dev/null @@ -1,79 +0,0 @@ -package internal - -import ( - "fmt" - "reflect" - - "github.com/formancehq/go-libs/pointer" - gomegaTypes "github.com/onsi/gomega/types" - "github.com/pkg/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type beOwnedByOption func(matcher *beOwnedByMatcher) - -func WithBlockOwnerDeletion() beOwnedByOption { - return func(matcher *beOwnedByMatcher) { - matcher.blockOwnerDeletion = true - } -} - -type beOwnedByMatcher struct { - owner client.Object - controller bool - blockOwnerDeletion bool -} - -func (s beOwnedByMatcher) Match(actual interface{}) (success bool, err error) { - object, ok := actual.(client.Object) - if !ok { - return false, fmt.Errorf("expect object of type runtime.Object") - } - for _, reference := range object.GetOwnerReferences() { - groupVersionsKinds, _, err := Client().Scheme().ObjectKinds(s.owner) - if err != nil { - return false, errors.Wrap(err, "searching object kinds") - } - expectedOwnerReference := metav1.OwnerReference{ - APIVersion: groupVersionsKinds[0].GroupVersion().String(), - Kind: groupVersionsKinds[0].Kind, - Name: s.owner.GetName(), - UID: s.owner.GetUID(), - } - if s.controller { - expectedOwnerReference.Controller = pointer.For(true) - } - if s.blockOwnerDeletion { - expectedOwnerReference.BlockOwnerDeletion = pointer.For(true) - } - if reflect.DeepEqual(reference, expectedOwnerReference) { - return true, nil - } - } - return false, nil -} - -func (s beOwnedByMatcher) FailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("object %s should be owned by %s", - actual.(client.Object).GetName(), (any)(s.owner)) -} - -func (s beOwnedByMatcher) NegatedFailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("object %s should not be owned by %s", - actual.(client.Object).GetName(), (any)(s.owner)) -} - -var _ gomegaTypes.GomegaMatcher = (*beOwnedByMatcher)(nil) - -func BeOwnedBy(owner client.Object, opts ...beOwnedByOption) gomegaTypes.GomegaMatcher { - ret := &beOwnedByMatcher{ - owner: owner, - } - - for _, opt := range opts { - opt(ret) - } - - return ret -} diff --git a/components/operator/internal/tests/internal/matcher_be_ready.go b/components/operator/internal/tests/internal/matcher_be_ready.go deleted file mode 100644 index 50d552b322..0000000000 --- a/components/operator/internal/tests/internal/matcher_be_ready.go +++ /dev/null @@ -1,36 +0,0 @@ -package internal - -import ( - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - - gomegaTypes "github.com/onsi/gomega/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type beReadyMatcher struct{} - -func (s beReadyMatcher) Match(actual interface{}) (success bool, err error) { - object, ok := actual.(v1beta1.Object) - if !ok { - return false, fmt.Errorf("expect object of type core.Object") - } - return object.IsReady(), nil -} - -func (s beReadyMatcher) FailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("object %s should be ready", - actual.(client.Object).GetName()) -} - -func (s beReadyMatcher) NegatedFailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("object %s should not be ready", - actual.(client.Object).GetName()) -} - -var _ gomegaTypes.GomegaMatcher = (*beReadyMatcher)(nil) - -func BeReady() gomegaTypes.GomegaMatcher { - return &beReadyMatcher{} -} diff --git a/components/operator/internal/tests/internal/matcher_match_golden_file.go b/components/operator/internal/tests/internal/matcher_match_golden_file.go deleted file mode 100644 index a788d80cd6..0000000000 --- a/components/operator/internal/tests/internal/matcher_match_golden_file.go +++ /dev/null @@ -1,69 +0,0 @@ -package internal - -import ( - "fmt" - "os" - "path/filepath" - - "github.com/google/go-cmp/cmp" - gomegaTypes "github.com/onsi/gomega/types" - "github.com/pkg/errors" -) - -type matchGoldenFile struct { - paths []string -} - -func (c matchGoldenFile) Match(actual interface{}) (success bool, err error) { - - value, ok := actual.(string) - if !ok { - return false, errors.New("should receive a string") - } - - locationParts := []string{"testdata", "resources"} - locationParts = append(locationParts, c.paths[:len(c.paths)-1]...) - directory := filepath.Join(locationParts...) - path := filepath.Join(directory, c.paths[len(c.paths)-1]) - - updateTestData := os.Getenv("UPDATE_TEST_DATA") - isUpdating := updateTestData == "1" || updateTestData == "true" - if isUpdating { - if err := os.MkdirAll(directory, 0744); err != nil { - return false, errors.Wrapf(err, "creating directory %s", directory) - } - - if err := os.WriteFile(path, []byte(value), 0600); err != nil { - return false, errors.Wrapf(err, "writing file: %s", path) - } - - return true, nil - } - - data, err := os.ReadFile(path) - if err != nil { - return false, errors.Wrapf(err, "reading file: %s", path) - } - - if diff := cmp.Diff(string(data), value); diff != "" { - msg := fmt.Sprintf("Expected content for resource %s not matching", path) - msg += "\n" + diff - return false, errors.New(msg) - } - - return true, nil -} - -func (c matchGoldenFile) FailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("resource does not match resource at %s", filepath.Join(c.paths...)) -} - -func (c matchGoldenFile) NegatedFailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("resource should not match resource at %s", filepath.Join(c.paths...)) -} - -func MatchGoldenFile(paths ...string) gomegaTypes.GomegaMatcher { - return &matchGoldenFile{ - paths: paths, - } -} diff --git a/components/operator/internal/tests/internal/matcher_target_deployment.go b/components/operator/internal/tests/internal/matcher_target_deployment.go deleted file mode 100644 index e1e9e697b2..0000000000 --- a/components/operator/internal/tests/internal/matcher_target_deployment.go +++ /dev/null @@ -1,59 +0,0 @@ -package internal - -import ( - "fmt" - "reflect" - - gomegaTypes "github.com/onsi/gomega/types" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" -) - -type targetDeployment struct { - deployment *appsv1.Deployment -} - -func (t targetDeployment) Match(actual interface{}) (success bool, err error) { - service, ok := actual.(*corev1.Service) - if !ok { - return false, mismatchTypeError(&corev1.Service{}, actual) - } - selector := service.Spec.Selector - if !reflect.DeepEqual(t.deployment.Spec.Selector.MatchLabels, selector) { - return false, nil - } - if !reflect.DeepEqual(t.deployment.Spec.Template.Labels, selector) { - return false, nil - } - return true, nil -} - -func (t targetDeployment) FailureMessage(actual interface{}) (message string) { - service := actual.(*corev1.Service) - selector := service.Spec.Selector - if !reflect.DeepEqual(t.deployment.Spec.Selector.MatchLabels, selector) { - return fmt.Sprintf("expected .spec.selector to match %s, got %s", t.deployment.Spec.Selector.MatchLabels, selector) - } - if !reflect.DeepEqual(t.deployment.Spec.Template.Labels, selector) { - return fmt.Sprintf("expected .spec.selector to match %s, got %s", t.deployment.Spec.Template.Labels, selector) - } - return "" -} - -func (t targetDeployment) NegatedFailureMessage(actual interface{}) (message string) { - service := actual.(*corev1.Service) - selector := service.Spec.Selector - if !reflect.DeepEqual(t.deployment.Spec.Selector.MatchLabels, selector) { - return fmt.Sprintf("expected .spec.selector to not match %s, got %s", t.deployment.Spec.Selector.MatchLabels, selector) - } - if !reflect.DeepEqual(t.deployment.Spec.Template.Labels, selector) { - return fmt.Sprintf("expected .spec.selector to not match %s, got %s", t.deployment.Spec.Template.Labels, selector) - } - return "" -} - -func TargetDeployment(spec *appsv1.Deployment) gomegaTypes.GomegaMatcher { - return targetDeployment{ - deployment: spec, - } -} diff --git a/components/operator/internal/tests/internal/utils.go b/components/operator/internal/tests/internal/utils.go deleted file mode 100644 index 97f91b8efd..0000000000 --- a/components/operator/internal/tests/internal/utils.go +++ /dev/null @@ -1,21 +0,0 @@ -package internal - -import ( - "github.com/google/uuid" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func RandObjectMeta() metav1.ObjectMeta { - return metav1.ObjectMeta{ - Name: uuid.NewString(), - } -} - -func LoadResource(ns, name string, object client.Object) error { - return Get(types.NamespacedName{ - Namespace: ns, - Name: name, - }, object) -} diff --git a/components/operator/internal/tests/ledger_controller_test.go b/components/operator/internal/tests/ledger_controller_test.go deleted file mode 100644 index a3fa00f89a..0000000000 --- a/components/operator/internal/tests/ledger_controller_test.go +++ /dev/null @@ -1,382 +0,0 @@ -package tests_test - -import ( - "github.com/formancehq/go-libs/collectionutils" - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/ledgers" - "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - v1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" -) - -var _ = Describe("LedgerController", func() { - Context("When creating a Ledger", func() { - var ( - stack *v1beta1.Stack - ledger *v1beta1.Ledger - databaseSettings *v1beta1.Settings - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - databaseSettings = settings.New(uuid.NewString(), "postgres.*.uri", "postgresql://localhost", stack.Name) - ledger = &v1beta1.Ledger{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.LedgerSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(Succeed()) - Expect(Create(databaseSettings)).To(Succeed()) - Expect(Create(ledger)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(ledger)).To(Succeed()) - Expect(Delete(databaseSettings)).To(Succeed()) - Expect(Delete(stack)).To(Succeed()) - }) - It("Should add an owner reference on the stack", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", ledger.Name, ledger)).To(Succeed()) - reference, err := core.HasOwnerReference(TestContext(), stack, ledger) - g.Expect(err).To(BeNil()) - return reference - }).Should(BeTrue()) - }) - It("Should create a deployment", func() { - deployment := &appsv1.Deployment{} - Eventually(func() error { - return LoadResource(stack.Name, "ledger", deployment) - }).Should(Succeed()) - Expect(deployment).To(BeControlledBy(ledger)) - }) - It("Should create a new GatewayHTTPAPI object", func() { - httpService := &v1beta1.GatewayHTTPAPI{} - Eventually(func() error { - return LoadResource("", core.GetObjectName(stack.Name, "ledger"), httpService) - }).Should(Succeed()) - }) - It("Should create a new Database object", func() { - database := &v1beta1.Database{} - Eventually(func() error { - return LoadResource("", core.GetObjectName(stack.Name, "ledger"), database) - }).Should(Succeed()) - }) - Context("with monitoring enabled", func() { - var ( - otelTracesDSNSetting *v1beta1.Settings - ) - BeforeEach(func() { - otelTracesDSNSetting = settings.New(uuid.NewString(), "opentelemetry.traces.dsn", "grpc://collector", stack.Name) - Expect(Create(otelTracesDSNSetting)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(otelTracesDSNSetting)).To(Succeed()) - }) - It("Should add correct env vars to the deployment", func() { - Eventually(func(g Gomega) []corev1.EnvVar { - deployment := &appsv1.Deployment{} - g.Expect(Get(core.GetNamespacedResourceName(stack.Name, "ledger"), deployment)).To(Succeed()) - return deployment.Spec.Template.Spec.Containers[0].Env - }).Should(ContainElements(corev1.EnvVar{ - Name: "OTEL_SERVICE_NAME", - Value: "ledger", - })) - }) - }) - When("Updating the ledger image, deployment should roll up", func() { - var cp = &appsv1.Deployment{} - JustBeforeEach(func() { - Eventually(func(g Gomega) error { - return LoadResource(stack.Name, "ledger", cp) - }).Should(Succeed()) - - patch := client.MergeFrom(ledger.DeepCopy()) - ledger.Spec.Version = "v0.0.0-test" - Expect(Patch(ledger, patch)).To(Succeed()) - }) - It("Should update the generation deployment", func() { - deployment := &appsv1.Deployment{} - Eventually(func(g Gomega) string { - g.Expect(Get(core.GetNamespacedResourceName(stack.Name, "ledger"), deployment)).To(Succeed()) - return deployment.Spec.Template.Spec.Containers[0].Image - }).Should(ContainSubstring("v0.0.0-test")) - Expect(deployment.Generation).ToNot(Equal(cp.Generation)) - }) - }) - Context("with a BrokerTopic object existing on the ledger service", func() { - deploymentShouldBeConfigured := func() { - deployment := &appsv1.Deployment{} - Eventually(func(g Gomega) bool { - g.Expect(Get(core.GetNamespacedResourceName(stack.Name, "ledger"), deployment)).To(Succeed()) - g.Expect(deployment.Spec.Template.Spec.Containers[0].Env). - Should(ContainElement(core.Env("BROKER", "nats"))) - return true - }).Should(BeTrue()) - } - var ( - brokerDSNSettings *v1beta1.Settings - brokerTopic *v1beta1.BrokerTopic - ) - JustBeforeEach(func() { - brokerDSNSettings = settings.New(uuid.NewString(), "broker.dsn", "nats://localhost:1234", stack.Name) - Expect(Create(brokerDSNSettings)).To(BeNil()) - brokerTopic = &v1beta1.BrokerTopic{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.BrokerTopicSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Service: "ledger", - }, - } - // notes(gfyrag): add "fake" owner reference to prevent auto deletion of topics - Expect(controllerutil.SetOwnerReference(databaseSettings, brokerTopic, GetScheme())) - Expect(controllerutil.SetOwnerReference(stack, brokerTopic, GetScheme())) - Expect(Create(brokerTopic)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(brokerDSNSettings)).To(Succeed()) - Expect(client.IgnoreNotFound(Delete(brokerTopic))).To(Succeed()) - }) - It("Should start the deployment with env var defined for publishing in the event bus", deploymentShouldBeConfigured) - Context("Then removing the BrokerTopic", func() { - JustBeforeEach(func() { - deploymentShouldBeConfigured() - Expect(Delete(brokerTopic)).To(Succeed()) - }) - It("Should restart the deployment without broker env vars", func() { - deployment := &appsv1.Deployment{} - Eventually(func(g Gomega) bool { - g.Expect(Get(core.GetNamespacedResourceName(stack.Name, "ledger"), deployment)).To(Succeed()) - g.Expect(deployment.Spec.Template.Spec.Containers[0].Env). - ShouldNot(ContainElements(core.Env("BROKER", "nats"))) - return true - }).Should(BeTrue()) - }) - }) - }) - Context("with multi ready deployment strategy", func() { - JustBeforeEach(func() { - Eventually(func() error { - return LoadResource(stack.Name, "ledger", &appsv1.Deployment{}) - }).Should(Succeed()) - patch := client.MergeFrom(ledger.DeepCopy()) - ledger.Spec.DeploymentStrategy = v1beta1.DeploymentStrategyMonoWriterMultipleReader - Expect(Patch(ledger, patch)).To(Succeed()) - }) - It("Should update resources", func() { - By("Should remove the original deployment", func() { - Eventually(func() error { - return LoadResource(stack.Name, "ledger", &appsv1.Deployment{}) - }).Should(BeNotFound()) - }) - By("Should create two applications, two services and a gateway", func() { - reader := &appsv1.Deployment{} - Eventually(func() error { - return LoadResource(stack.Name, "ledger-read", reader) - }).Should(Succeed()) - Expect(reader).To(BeControlledBy(ledger)) - - readerService := &corev1.Service{} - Eventually(func() error { - return LoadResource(stack.Name, "ledger-read", readerService) - }).Should(Succeed()) - Expect(readerService).To(BeControlledBy(ledger)) - Expect(readerService).To(TargetDeployment(reader)) - - writer := &appsv1.Deployment{} - Eventually(func() error { - return LoadResource(stack.Name, "ledger-write", writer) - }).Should(Succeed()) - Expect(writer).To(BeControlledBy(ledger)) - - writerService := &corev1.Service{} - Eventually(func() error { - return LoadResource(stack.Name, "ledger-write", writerService) - }).Should(Succeed()) - Expect(writerService).To(BeControlledBy(ledger)) - Expect(writerService).To(TargetDeployment(writer)) - - gateway := &appsv1.Deployment{} - Eventually(func() error { - return LoadResource(stack.Name, "ledger-gateway", gateway) - }).Should(Succeed()) - Expect(gateway).To(BeControlledBy(ledger)) - Expect(gateway.Spec.Template.Spec.SecurityContext).NotTo(BeNil()) - Expect(gateway.Spec.Template.Spec.Containers).To(HaveLen(1)) - Expect(gateway.Spec.Template.Spec.Containers[0].SecurityContext).NotTo(BeNil()) - Expect(gateway.Spec.Template.Spec.Containers[0].SecurityContext.Capabilities).NotTo(BeNil()) - Expect(gateway.Spec.Template.Spec.Containers[0].SecurityContext.Capabilities.Add).To(HaveLen(1)) - Expect(gateway.Spec.Template.Spec.Containers[0].SecurityContext.Capabilities.Add).To(ContainElements(corev1.Capability("NET_BIND_SERVICE"))) - }) - }) - It("Should update the strategy condition", func() { - Eventually(func(g Gomega) string { - g.Expect(LoadResource("", ledger.Name, ledger)).To(Succeed()) - g.Expect(ledger.Status.Conditions.Get(ledgers.ConditionTypeDeploymentStrategy)).ToNot(BeNil()) - return ledger.Status.Conditions.Get(ledgers.ConditionTypeDeploymentStrategy).Reason - }).Should(Equal(ledgers.ReasonLedgerMonoWriterMultipleReader)) - }) - It("Should delete the deployment", func() { - deployment := &appsv1.Deployment{} - Eventually(func(g Gomega) bool { - g.Expect(Get(core.GetNamespacedResourceName(stack.Name, "ledger"), deployment)).ToNot(Succeed()) - return true - }).Should(BeTrue()) - }) - When("Updating the deployment strategy to single", func() { - var cp *v1beta1.Ledger - JustBeforeEach(func() { - cp = ledger.DeepCopy() - patch := client.MergeFrom(ledger.DeepCopy()) - ledger.Spec.DeploymentStrategy = v1beta1.DeploymentStrategySingle - Expect(Patch(ledger, patch)).To(Succeed()) - }) - It("Should only have one ConditionDeploymentStrategy per generation", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", ledger.Name, ledger)).To(Succeed()) - g.Expect(ledger.Generation).ToNot(Equal(cp.Generation)) - data := collectionutils.Reduce( - collectionutils.Filter(ledger.Status.Conditions, func(condition v1beta1.Condition) bool { - return condition.Type == ledgers.ConditionTypeDeploymentStrategy - }), - func(acc map[int64]v1beta1.Conditions, condition v1beta1.Condition) map[int64]v1beta1.Conditions { - if _, ok := acc[condition.ObservedGeneration]; !ok { - acc[condition.ObservedGeneration] = append(v1beta1.Conditions{}, condition) - } - return acc - }, map[int64]v1beta1.Conditions{}, - ) - - for _, condition := range data { - g. - Expect(condition). - To(HaveLen(1)) - } - return true - - }).Should(BeTrue()) - }) - It("Should have the latest generation ConditionDeploymentStrategy", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", ledger.Name, ledger)).To(Succeed()) - g.Expect(ledger.Generation).ToNot(Equal(cp.Generation)) - return ledger.GetConditions().Check(v1beta1.AndConditions( - v1beta1.ConditionTypeMatch(ledgers.ConditionTypeDeploymentStrategy), - v1beta1.ConditionGenerationMatch(ledger.Generation), - )) - - }).Should(BeTrue()) - }) - }) - }) - Context("With Search enabled", func() { - var search *v1beta1.Search - BeforeEach(func() { - search = &v1beta1.Search{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.SearchSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - }) - JustBeforeEach(func() { - Expect(Create(search)).To(Succeed()) - }) - JustAfterEach(func() { - Expect(client.IgnoreNotFound(Delete(search))).To(Succeed()) - }) - checkResourcesExists := func() { - l := &v1beta1.BenthosStreamList{} - Eventually(func(g Gomega) int { - g.Expect(List(l)).To(Succeed()) - return len(collectionutils.Filter(l.Items, func(stream v1beta1.BenthosStream) bool { - return stream.Spec.Stack == stack.Name - })) - }).Should(BeNumerically(">", 0)) - - cronJob := &v1.CronJob{} - Eventually(func() error { - return Get(types.NamespacedName{ - Namespace: stack.Name, - Name: "reindex-ledger", - }, cronJob) - }).Should(BeNil()) - } - It("Should create appropriate resources", checkResourcesExists) - Context("Then when removing search", func() { - JustBeforeEach(func() { - checkResourcesExists() - Expect(Delete(search)).To(Succeed()) - }) - It("Should remove resources", func() { - l := &v1beta1.BenthosStreamList{} - Eventually(func(g Gomega) int { - g.Expect(List(l)).To(Succeed()) - return len(collectionutils.Filter(l.Items, func(stream v1beta1.BenthosStream) bool { - return stream.Spec.Stack == stack.Name - })) - }).Should(BeZero()) - Eventually(func() error { - return Get(types.NamespacedName{ - Namespace: stack.Name, - Name: "reindex-ledger", - }, &v1.CronJob{}) - }).Should(BeNotFound()) - }) - }) - }) - Context("With database connection pool settings", func() { - var connectionPoolSettings *v1beta1.Settings - BeforeEach(func() { - connectionPoolSettings = settings.New(uuid.NewString(), "modules.ledger.database.connection-pool", "max-idle=10, max-idle-time=10s, max-open=10", stack.Name) - }) - JustBeforeEach(func() { - Expect(Create(connectionPoolSettings)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(connectionPoolSettings)).To(Succeed()) - }) - It("Should configure the deployment with appropriate env vars", func() { - deployment := &appsv1.Deployment{} - Eventually(func(g Gomega) []corev1.EnvVar { - g.Expect(Get(core.GetNamespacedResourceName(stack.Name, "ledger"), deployment)).To(Succeed()) - return deployment.Spec.Template.Spec.Containers[0].Env - }).Should( - ContainElements( - corev1.EnvVar{ - Name: "POSTGRES_MAX_IDLE_CONNS", - Value: "10", - }, - corev1.EnvVar{ - Name: "POSTGRES_CONN_MAX_IDLE_TIME", - Value: "10s", - }, - corev1.EnvVar{ - Name: "POSTGRES_CONN_MAX_OPEN_CONNS", - Value: "10", - }, - ), - ) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/orchestration_controller_test.go b/components/operator/internal/tests/orchestration_controller_test.go deleted file mode 100644 index e85e4c791d..0000000000 --- a/components/operator/internal/tests/orchestration_controller_test.go +++ /dev/null @@ -1,133 +0,0 @@ -package tests_test - -import ( - "fmt" - - "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - appsv1 "k8s.io/api/apps/v1" - - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - core "github.com/formancehq/operator/internal/core" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Describe("OrchestrationController", func() { - Context("When creating a Orchestration object", func() { - var ( - stack *v1beta1.Stack - gateway *v1beta1.Gateway - auth *v1beta1.Auth - ledger *v1beta1.Ledger - orchestration *v1beta1.Orchestration - databaseSettings *v1beta1.Settings - brokerDSNSettings *v1beta1.Settings - temporalDSNSettings *v1beta1.Settings - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - databaseSettings = settings.New(uuid.NewString(), "postgres.*.uri", "postgresql://localhost", stack.Name) - brokerDSNSettings = settings.New(uuid.NewString(), "broker.dsn", "nats://localhost:1234", stack.Name) - temporalDSNSettings = settings.New(uuid.NewString(), "temporal.dsn", "temporal://localhost/namespace", stack.Name) - gateway = &v1beta1.Gateway{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.GatewaySpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Ingress: &v1beta1.GatewayIngress{}, - }, - } - auth = &v1beta1.Auth{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.AuthSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - ledger = &v1beta1.Ledger{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.LedgerSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - orchestration = &v1beta1.Orchestration{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.OrchestrationSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(Succeed()) - Expect(Create(databaseSettings)).To(Succeed()) - Expect(Create(temporalDSNSettings)).To(Succeed()) - Expect(Create(brokerDSNSettings)).To(BeNil()) - Expect(Create(gateway)).To(Succeed()) - Expect(Create(auth)).To(Succeed()) - Expect(Create(ledger)).To(Succeed()) - Expect(Create(orchestration)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(stack)).To(Succeed()) - Expect(Delete(databaseSettings)).To(Succeed()) - Expect(Delete(brokerDSNSettings)).To(Succeed()) - Expect(Delete(temporalDSNSettings)).To(Succeed()) - }) - It("Should create appropriate components", func() { - By("Should set the status to ready", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", orchestration.Name, orchestration)).To(Succeed()) - return orchestration.Status.Ready - }).Should(BeTrue()) - }) - By("Should add an owner reference on the stack", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", orchestration.Name, orchestration)).To(Succeed()) - reference, err := core.HasOwnerReference(TestContext(), stack, orchestration) - g.Expect(err).To(BeNil()) - return reference - }).Should(BeTrue()) - }) - By("Should create a deployment", func() { - deployment := &appsv1.Deployment{} - Eventually(func() error { - return LoadResource(stack.Name, "orchestration", deployment) - }).Should(Succeed()) - Expect(deployment).To(BeControlledBy(orchestration)) - Expect(deployment.Spec.Template.Spec.Containers[0].Env).To(ContainElements( - core.Env("WORKER", "true"), - core.Env("TOPICS", fmt.Sprintf("%s.ledger", stack.Name)), - )) - }) - By("Should create a new GatewayHTTPAPI object", func() { - httpService := &v1beta1.GatewayHTTPAPI{} - Eventually(func() error { - return LoadResource("", core.GetObjectName(stack.Name, "orchestration"), httpService) - }).Should(Succeed()) - }) - By("Should create a new AuthClient object", func() { - authClient := &v1beta1.AuthClient{} - Eventually(func() error { - return LoadResource("", core.GetObjectName(stack.Name, "orchestration"), authClient) - }).Should(Succeed()) - }) - By("Should create a new BrokerConsumer object", func() { - consumer := &v1beta1.BrokerConsumer{} - Eventually(func() error { - return LoadResource("", orchestration.Name+"-orchestration", consumer) - }).Should(Succeed()) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/payments_controller_test.go b/components/operator/internal/tests/payments_controller_test.go deleted file mode 100644 index 27a0e5f155..0000000000 --- a/components/operator/internal/tests/payments_controller_test.go +++ /dev/null @@ -1,143 +0,0 @@ -package tests_test - -import ( - "github.com/formancehq/go-libs/collectionutils" - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -var _ = Describe("PaymentsController", func() { - Context("When creating a Payments object", func() { - var ( - stack *v1beta1.Stack - payments *v1beta1.Payments - databaseSettings *v1beta1.Settings - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - payments = &v1beta1.Payments{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.PaymentsSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - databaseSettings = settings.New(uuid.NewString(), "postgres.*.uri", "postgresql://localhost", stack.Name) - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(Succeed()) - Expect(Create(databaseSettings)).To(Succeed()) - Expect(Create(payments)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(payments)).To(Succeed()) - Expect(Delete(databaseSettings)).To(Succeed()) - Expect(Delete(stack)).To(Succeed()) - }) - It("Should create resources", func() { - By("Should add an owner reference on the stack", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", payments.Name, payments)).To(Succeed()) - reference, err := core.HasOwnerReference(TestContext(), stack, payments) - g.Expect(err).To(BeNil()) - return reference - }).Should(BeTrue()) - }) - By("Should create a read deployment with a service", func() { - deployment := &appsv1.Deployment{} - Eventually(func() error { - return LoadResource(stack.Name, "payments-read", deployment) - }).Should(Succeed()) - Expect(deployment).To(BeControlledBy(payments)) - - service := &corev1.Service{} - Eventually(func() error { - return LoadResource(stack.Name, "payments-read", service) - }).Should(Succeed()) - Expect(service).To(BeControlledBy(payments)) - }) - By("Should create a connectors deployment with a service", func() { - deployment := &appsv1.Deployment{} - Eventually(func() error { - return LoadResource(stack.Name, "payments-connectors", deployment) - }).Should(Succeed()) - Expect(deployment).To(BeControlledBy(payments)) - - service := &corev1.Service{} - Eventually(func() error { - return LoadResource(stack.Name, "payments-connectors", service) - }).Should(Succeed()) - Expect(service).To(BeControlledBy(payments)) - }) - By("Should create a gateway", func() { - deployment := &appsv1.Deployment{} - Eventually(func() error { - return LoadResource(stack.Name, "payments", deployment) - }).Should(Succeed()) - Expect(deployment).To(BeControlledBy(payments)) - }) - By("Should create a new GatewayHTTPAPI object", func() { - httpService := &v1beta1.GatewayHTTPAPI{} - Eventually(func() error { - return LoadResource("", core.GetObjectName(stack.Name, "payments"), httpService) - }).Should(Succeed()) - }) - }) - Context("With Search enabled", func() { - var search *v1beta1.Search - BeforeEach(func() { - search = &v1beta1.Search{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.SearchSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - }) - JustBeforeEach(func() { - Expect(Create(search)).To(Succeed()) - }) - JustAfterEach(func() { - Expect(client.IgnoreNotFound(Delete(search))).To(Succeed()) - }) - checkStreamsExists := func() { - l := &v1beta1.BenthosStreamList{} - Eventually(func(g Gomega) int { - g.Expect(List(l)).To(Succeed()) - return len(collectionutils.Filter(l.Items, func(stream v1beta1.BenthosStream) bool { - return stream.Spec.Stack == stack.Name - })) - }).Should(BeNumerically(">", 0)) - } - It("Should create streams", checkStreamsExists) - Context("Then when removing search", func() { - JustBeforeEach(func() { - checkStreamsExists() - Expect(Delete(search)).To(Succeed()) - }) - It("Should remove streams", func() { - l := &v1beta1.BenthosStreamList{} - Eventually(func(g Gomega) int { - g.Expect(List(l)).To(Succeed()) - return len(collectionutils.Filter(l.Items, func(stream v1beta1.BenthosStream) bool { - return stream.Spec.Stack == stack.Name - })) - }).Should(BeZero()) - }) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/registries_test.go b/components/operator/internal/tests/registries_test.go deleted file mode 100644 index b80bcc0a8e..0000000000 --- a/components/operator/internal/tests/registries_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package tests - -import ( - "fmt" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" -) - -var _ = Describe("Registries", func() { - var ( - stack *v1beta1.Stack - databaseSettings *v1beta1.Settings - ledger *v1beta1.Ledger - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - } - databaseSettings = settings.New(uuid.NewString(), "postgres.*.uri", "postgresql://localhost", stack.Name) - ledger = &v1beta1.Ledger{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.LedgerSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(Succeed()) - Expect(Create(databaseSettings)).To(Succeed()) - Expect(Create(ledger)).To(Succeed()) - - DeferCleanup(func() { - Expect(Delete(ledger)).To(Succeed()) - Expect(Delete(databaseSettings)).To(Succeed()) - Expect(Delete(stack)).To(Succeed()) - }) - }) - Context("When overriding image in a settings", func() { - var ( - settings *v1beta1.Settings - registry = `"ghcr.io"` - organization = "formancehq" - ledgerpath = fmt.Sprintf("%s/%s", organization, "ledger") - imageRewrite = fmt.Sprintf("%s/%s", organization, "example") - ) - - BeforeEach(func() { - settings = &v1beta1.Settings{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.SettingsSpec{ - Stacks: []string{"*"}, - Key: "registries." + registry + ".images." + ledgerpath + ".rewrite", - Value: imageRewrite, - }, - } - Expect(Create(settings)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(settings)).To(Succeed()) - }) - It("Should have image re-written", func() { - deployment := &appsv1.Deployment{} - Eventually(func(g Gomega) error { - g.Expect(LoadResource(stack.Name, "ledger", deployment)).To(Succeed()) - g.Expect(deployment.Spec.Template.Spec.Containers).To(HaveLen(1)) - g.Expect(deployment.Spec.Template.Spec.Containers[0].Image).To(ContainSubstring(imageRewrite)) - return nil - }).Should(Succeed()) - Expect(deployment).To(BeControlledBy(ledger)) - }) - - }) -}) diff --git a/components/operator/internal/tests/resourcereferences_controller_test.go b/components/operator/internal/tests/resourcereferences_controller_test.go deleted file mode 100644 index 60036a3c07..0000000000 --- a/components/operator/internal/tests/resourcereferences_controller_test.go +++ /dev/null @@ -1,119 +0,0 @@ -package tests - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" -) - -var _ = Describe("ResourceReferenceController", func() { - var stack *v1beta1.Stack - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - } - Expect(Create(stack)).To(Succeed()) - }) - Context("With a secret created on default namespace", func() { - var secret *corev1.Secret - BeforeEach(func() { - secret = &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: uuid.NewString(), - Namespace: "default", - Labels: map[string]string{ - v1beta1.StackLabel: stack.Name, - }, - }, - } - Expect(Create(secret)).To(Succeed()) - }) - When("Creating a resource reference on a stack", func() { - var resourceReference *v1beta1.ResourceReference - BeforeEach(func() { - gvk, err := apiutil.GVKForObject(secret, GetScheme()) - Expect(err).To(BeNil()) - - resourceReference = &v1beta1.ResourceReference{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.ResourceReferenceSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Name: secret.Name, - GroupVersionKind: &metav1.GroupVersionKind{ - Group: gvk.Group, - Version: gvk.Version, - Kind: gvk.Kind, - }, - }, - } - Expect(Create(resourceReference)).To(Succeed()) - }) - shouldHaveReplicatedSecret := func() { - replicatedSecret := &corev1.Secret{} - Eventually(func() error { - return LoadResource(stack.Name, resourceReference.Spec.Name, replicatedSecret) - }).Should(Succeed()) - } - It("Should replicate the secret to the stack namespace", shouldHaveReplicatedSecret) - When("updating the original secret", func() { - BeforeEach(func() { - shouldHaveReplicatedSecret() - patch := client.MergeFrom(secret.DeepCopy()) - secret.Data = map[string][]byte{ - "foo": []byte("bar"), - } - secret.Annotations = map[string]string{ - "hello": "world", - } - Expect(Patch(secret, patch)).To(Succeed()) - }) - It("Should update the copied secret", func() { - replicatedSecret := &corev1.Secret{} - Eventually(func(g Gomega) bool { - g.Expect(LoadResource(stack.Name, resourceReference.Spec.Name, replicatedSecret)).To(Succeed()) - g.Expect(replicatedSecret.Data).To(Equal(secret.Data)) - g.Expect(replicatedSecret.Annotations).To(Equal(secret.Annotations)) - - return true - }).Should(BeTrue()) - }) - }) - Context("then when updating the referenced secret to a new one", func() { - var newSecret *corev1.Secret - BeforeEach(func() { - shouldHaveReplicatedSecret() - newSecret = &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: uuid.NewString(), - Namespace: "default", - Labels: map[string]string{ - v1beta1.StackLabel: stack.Name, - }, - }, - } - Expect(Create(newSecret)).To(Succeed()) - - patch := client.MergeFrom(resourceReference.DeepCopy()) - resourceReference.Spec.Name = newSecret.Name - Expect(Patch(resourceReference, patch)).To(Succeed()) - }) - It("should replicate the secret and remove the old one", func() { - By("Should replicate the new secret to the stack namespace", shouldHaveReplicatedSecret) - By("Should remove old replicated secret", func() { - Eventually(func() error { - return LoadResource(stack.Name, secret.Name, &corev1.Secret{}) - }).Should(BeNotFound()) - }) - }) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/searches_controller_test.go b/components/operator/internal/tests/searches_controller_test.go deleted file mode 100644 index 96ce7d86a2..0000000000 --- a/components/operator/internal/tests/searches_controller_test.go +++ /dev/null @@ -1,90 +0,0 @@ -package tests_test - -import ( - "fmt" - - "github.com/formancehq/operator/internal/core" - - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Describe("SearchesController", func() { - Context("When creating a Search object", func() { - var ( - stack *v1beta1.Stack - search *v1beta1.Search - elasticSearchDSNSetting *v1beta1.Settings - brokerDSNSettings *v1beta1.Settings - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - search = &v1beta1.Search{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.SearchSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - elasticSearchDSNSetting = settings.New(uuid.NewString(), "elasticsearch.dsn", "https://localhost", stack.Name) - brokerDSNSettings = settings.New(uuid.NewString(), "broker.dsn", "nats://localhost:1234", stack.Name) - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(Succeed()) - Expect(Create(elasticSearchDSNSetting)).To(Succeed()) - Expect(Create(brokerDSNSettings)).To(Succeed()) - Expect(Create(search)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(search)).To(Succeed()) - Expect(Delete(elasticSearchDSNSetting)).To(Succeed()) - Expect(Delete(stack)).To(Succeed()) - Expect(Delete(brokerDSNSettings)).To(Succeed()) - }) - It("Should create resources", func() { - By("Should add an owner reference on the stack", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", search.Name, search)).To(Succeed()) - reference, err := core.HasOwnerReference(TestContext(), stack, search) - g.Expect(err).To(BeNil()) - return reference - }).Should(BeTrue()) - }) - By("Should create a Benthos", func() { - benthos := &v1beta1.Benthos{} - Eventually(func() error { - return LoadResource(stack.Name, fmt.Sprintf("%s-benthos", stack.Name), benthos) - }).Should(Succeed()) - Expect(benthos).To(BeControlledBy(search)) - }) - }) - Context("Then when creating a SearchBatchingConfiguration object", func() { - var searchBatchingCountSettings *v1beta1.Settings - JustBeforeEach(func() { - searchBatchingCountSettings = settings.New(uuid.NewString(), "search.batching", "count=10", stack.Name) - Expect(Create(searchBatchingCountSettings)).To(Succeed()) - }) - JustAfterEach(func() { - Expect(Delete(searchBatchingCountSettings)).To(Succeed()) - }) - It("Should update the Benthos with the new batching configuration", func() { - benthos := &v1beta1.Benthos{} - Eventually(func(g Gomega) v1beta1.Batching { - g.Expect(LoadResource(stack.Name, fmt.Sprintf("%s-benthos", stack.Name), benthos)).To(Succeed()) - g.Expect(benthos.Spec.Batching).NotTo(BeNil()) - return *benthos.Spec.Batching - }).Should(Equal(v1beta1.Batching{ - Count: 10, - })) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/settings_controller_test.go b/components/operator/internal/tests/settings_controller_test.go deleted file mode 100644 index da4dadc6d9..0000000000 --- a/components/operator/internal/tests/settings_controller_test.go +++ /dev/null @@ -1,130 +0,0 @@ -package tests - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - helperSettings "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Describe("SettingsController", func() { - When("Creating a settings on specific stack", func() { - var ( - setting *v1beta1.Settings - stack *v1beta1.Stack - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - } - setting = &v1beta1.Settings{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.SettingsSpec{ - Stacks: []string{stack.Name}, - Key: uuid.NewString() + `.` + uuid.NewString(), - Value: uuid.NewString(), - }, - } - - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(Succeed()) - Expect(Create(setting)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(stack)).To(Succeed()) - Expect(Delete(setting)).To(Succeed()) - }) - It("Should create resources", func() { - By("Should have created the setting", func() { - Expect(LoadResource("", setting.Name, &v1beta1.Settings{})).To(Succeed()) - }) - By("Sould be able to retrieve the settings", func() { - str, err := helperSettings.Get(TestContext(), stack.Name, helperSettings.SplitKeywordWithDot(setting.Spec.Key)...) - Expect(err).To(BeNil()) - Expect(str).ToNot(BeNil()) - Expect(*str).To(Equal(setting.Spec.Value)) - }) - }) - }) - When("Creating a settings", func() { - var ( - setting *v1beta1.Settings - stack *v1beta1.Stack - ) - BeforeEach(func() { - setting = &v1beta1.Settings{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.SettingsSpec{ - Stacks: []string{"*"}, - Key: uuid.NewString() + `.` + uuid.NewString(), - Value: uuid.NewString(), - }, - } - - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - } - - }) - JustBeforeEach(func() { - Expect(Create(setting)).To(Succeed()) - Expect(Create(stack)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(setting)).To(Succeed()) - Expect(Delete(stack)).To(Succeed()) - }) - It("Should create resources", func() { - By("Should have created the setting", func() { - Expect(LoadResource("", setting.Name, &v1beta1.Settings{})).To(Succeed()) - }) - By("Sould be able to retrieve the settings", func() { - str, err := helperSettings.Get(TestContext(), stack.Name, helperSettings.SplitKeywordWithDot(setting.Spec.Key)...) - Expect(err).To(BeNil()) - Expect(str).ToNot(BeNil()) - Expect(*str).To(Equal(setting.Spec.Value)) - }) - }) - }) - When("Creating a settings with escaped key", func() { - var ( - setting *v1beta1.Settings - stack *v1beta1.Stack - ) - BeforeEach(func() { - setting = &v1beta1.Settings{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.SettingsSpec{ - Stacks: []string{"*"}, - Key: uuid.NewString() + `."example.net"`, - Value: uuid.NewString(), - }, - } - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - } - }) - JustBeforeEach(func() { - Expect(Create(setting)).To(Succeed()) - Expect(Create(stack)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(setting)).To(Succeed()) - Expect(Delete(stack)).To(Succeed()) - }) - It("Should create resources", func() { - By("Should create a settings", func() { - Expect(LoadResource("", setting.Name, &v1beta1.Settings{})).To(Succeed()) - }) - By("Sould be able to retrieve the settings", func() { - str, err := helperSettings.Get(TestContext(), stack.Name, helperSettings.SplitKeywordWithDot(setting.Spec.Key)...) - Expect(err).To(BeNil()) - Expect(str).ToNot(BeNil()) - Expect(*str).To(Equal(setting.Spec.Value)) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/stack_controller_test.go b/components/operator/internal/tests/stack_controller_test.go deleted file mode 100644 index 6ad8589a36..0000000000 --- a/components/operator/internal/tests/stack_controller_test.go +++ /dev/null @@ -1,247 +0,0 @@ -package tests_test - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - corev1 "k8s.io/api/core/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -var _ = Describe("StackController", func() { - Context("When creating a stack", func() { - var ( - stack *v1beta1.Stack - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(Succeed()) - }) - JustAfterEach(func() { - Expect(client.IgnoreNotFound(Delete(stack))).To(Succeed()) - }) - It("Should create resources", func() { - By("Should create a new namespace", func() { - Eventually(func() error { - return Get(core.GetResourceName(stack.Name), &corev1.Namespace{}) - }).Should(Succeed()) - }) - By("Should resolve to 'latest' version", func() { - version, err := core.GetModuleVersion(TestContext(), stack, &v1beta1.Ledger{}) - Expect(err).To(Succeed()) - Expect(version).To(Equal("latest")) - }) - By("Should be ready", func() { - Eventually(func() bool { - Expect(LoadResource("", stack.Name, stack)).To(Succeed()) - return stack.Status.Ready - }).Should(BeTrue()) - }) - }) - Context("with version specified", func() { - BeforeEach(func() { - stack.Spec.Version = "1234" - }) - It("should resolve a module to the specified version", func() { - version, err := core.GetModuleVersion(TestContext(), stack, &v1beta1.Ledger{}) - Expect(err).To(Succeed()) - Expect(version).To(Equal("1234")) - }) - }) - Context("with version file specified", func() { - var versions *v1beta1.Versions - BeforeEach(func() { - versions = &v1beta1.Versions{ - ObjectMeta: RandObjectMeta(), - Spec: map[string]string{}, - } - stack.Spec.VersionsFromFile = versions.Name - }) - JustBeforeEach(func() { - Expect(Create(versions)).To(Succeed()) - }) - JustAfterEach(func() { - Expect(Delete(versions)).To(Succeed()) - }) - Context("with no specific version", func() { - It("should resolve a module to 'latest'", func() { - version, err := core.GetModuleVersion(TestContext(), stack, &v1beta1.Ledger{}) - Expect(err).To(Succeed()) - Expect(version).To(Equal("latest")) - }) - }) - Context("with specific version for a module", func() { - BeforeEach(func() { - versions.Spec["ledger"] = "5678" - }) - It("should resolve to the correct version", func() { - Eventually(func(g Gomega) string { - version, err := core.GetModuleVersion(TestContext(), stack, &v1beta1.Ledger{}) - g.Expect(err).To(Succeed()) - return version - }).Should(Equal("5678")) - }) - }) - }) - Context("with a module", func() { - var ( - ledger *v1beta1.Ledger - ) - JustBeforeEach(func() { - ledger = &v1beta1.Ledger{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.LedgerSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - - Expect(Create(ledger)).To(Succeed()) - Eventually(func(g Gomega) *v1beta1.Ledger { - g.Expect(LoadResource("", ledger.Name, ledger)).To(Succeed()) - return ledger - }).Should(BeOwnedBy(stack)) - }) - JustAfterEach(func() { - Expect(client.IgnoreNotFound(Delete(ledger))).To(Succeed()) - }) - It("Should update resources", func() { - By("the stack should not be ready anymore", func() { - Eventually(func() bool { - Expect(LoadResource("", stack.Name, stack)).To(Succeed()) - - return stack.Status.Ready - }).Should(BeFalse()) - }) - By("ledger should not be ready", func() { - Eventually(func() bool { - Expect(LoadResource("", ledger.Name, ledger)).To(Succeed()) - return ledger.Status.Ready - }).Should(BeFalse()) - }) - }) - When("each module are ready", func() { - var databaseSettings *v1beta1.Settings - BeforeEach(func() { - databaseSettings = settings.New(uuid.NewString(), "postgres.*.uri", "postgresql://localhost", stack.Name) - Expect(Create(databaseSettings)).Should(Succeed()) - }) - JustBeforeEach(func() { - - database := &v1beta1.Database{} - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", stack.Name+"-ledger", database)).To(BeNil()) - return database.Status.Ready - }).Should(BeTrue()) - - Eventually(func() bool { - Expect(LoadResource("", ledger.Name, ledger)).To(Succeed()) - return ledger.Status.Ready - }).Should(BeTrue()) - }) - JustAfterEach(func() { - Expect(Delete(databaseSettings)).To(Succeed()) - }) - It("the stack should be ready", func() { - Eventually(func() bool { - err := LoadResource("", stack.Name, stack) - Expect(err).ToNot(HaveOccurred()) - return stack.Status.Ready - }).Should(BeTrue()) - }) - }) - When("deleting the stack", func() { - JustBeforeEach(func() { - Eventually(func() []string { - err := LoadResource("", stack.Name, stack) - Expect(err).ToNot(HaveOccurred()) - return stack.Finalizers - }).ShouldNot(BeEmpty()) - Expect(Delete(stack)).To(Succeed()) - }) - It("Should also delete the module", func() { - Eventually(func(g Gomega) error { - return LoadResource("", ledger.Name, ledger) - }).Should(BeNotFound()) - Eventually(func(g Gomega) error { - return LoadResource("", stack.Name+"-ledger", &v1beta1.Database{}) - }).Should(BeNotFound()) - Eventually(func(g Gomega) error { - return LoadResource("", stack.Name, stack) - }).Should(BeNotFound()) - }) - }) - }) - When("locked", func() { - BeforeEach(func() { - stack.Annotations = map[string]string{ - v1beta1.SkipLabel: "true", - } - }) - When("creating a module", func() { - var ( - ledger *v1beta1.Ledger - databaseSettings *v1beta1.Settings - ) - JustBeforeEach(func() { - ledger = &v1beta1.Ledger{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.LedgerSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - databaseSettings = settings.New(uuid.NewString(), "postgres.*.uri", "postgresql://localhost", stack.Name) - - Expect(Create(databaseSettings)).To(Succeed()) - Expect(Create(ledger)).To(Succeed()) - }) - JustAfterEach(func() { - Expect(client.IgnoreNotFound(Delete(ledger))).To(Succeed()) - Expect(Delete(databaseSettings)).To(Succeed()) - }) - It("Should not install the new module", func() { - Eventually(func(g Gomega) string { - g.Expect(LoadResource("", ledger.Name, ledger)).To(Succeed()) - g.Expect(ledger.Status.Conditions.Get("ReconciledWithStack")).ToNot(BeNil()) - return ledger.Status.Conditions.Get("ReconciledWithStack").Reason - }).Should(Equal("Skipped")) - }) - When("then unlocking the stack", func() { - JustBeforeEach(func() { - Eventually(func(g Gomega) string { - g.Expect(LoadResource("", ledger.Name, ledger)).To(Succeed()) - g.Expect(ledger.Status.Conditions.Get("ReconciledWithStack")).ToNot(BeNil()) - return ledger.Status.Conditions.Get("ReconciledWithStack").Reason - }).Should(Equal("Skipped")) - patch := client.MergeFrom(stack.DeepCopy()) - stack.Annotations = map[string]string{} - Expect(Patch(stack, patch)).To(Succeed()) - Eventually(func(g Gomega) map[string]string { - g.Expect(LoadResource("", stack.Name, stack)).To(Succeed()) - return ledger.Annotations - }).ShouldNot(HaveKey(v1beta1.SkipLabel)) - }) - It("Should install the module", func() { - Eventually(func(g Gomega) string { - g.Expect(LoadResource("", ledger.Name, ledger)).To(Succeed()) - g.Expect(ledger.Status.Conditions.Get("ReconciledWithStack")).ToNot(BeNil()) - return ledger.Status.Conditions.Get("ReconciledWithStack").Reason - }).Should(Equal("Spec")) - }) - }) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/stargate_controller_test.go b/components/operator/internal/tests/stargate_controller_test.go deleted file mode 100644 index 2d40ccbb60..0000000000 --- a/components/operator/internal/tests/stargate_controller_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package tests_test - -import ( - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - . "github.com/formancehq/operator/internal/tests/internal" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" -) - -var _ = Describe("StargateController", func() { - Context("When creating a Stargate object", func() { - var ( - stack *v1beta1.Stack - stargate *v1beta1.Stargate - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - stargate = &v1beta1.Stargate{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StargateSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - ServerURL: "server:8080", - OrganizationID: "orgID", - StackID: "stackID", - Auth: v1beta1.StargateAuthSpec{ - ClientID: "client0", - ClientSecret: "client0", - Issuer: "http://server:8081", - }, - }, - } - }) - JustBeforeEach(func() { - Expect(Create(stack)).To(Succeed()) - Expect(Create(stargate)).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(stargate)).To(Succeed()) - Expect(Delete(stack)).To(Succeed()) - }) - It("Should create resources", func() { - By("Should add an owner reference on the stack", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", stargate.Name, stargate)).To(Succeed()) - reference, err := core.HasOwnerReference(TestContext(), stack, stargate) - g.Expect(err).To(BeNil()) - return reference - }).Should(BeTrue()) - }) - By("Should create a deployment", func() { - deployment := &appsv1.Deployment{} - Eventually(func() error { - return LoadResource(stack.Name, "stargate", deployment) - }).Should(Succeed()) - Expect(deployment).To(BeControlledBy(stargate)) - }) - }) - }) -}) diff --git a/components/operator/internal/tests/suite_test.go b/components/operator/internal/tests/suite_test.go deleted file mode 100644 index 9caffa15a5..0000000000 --- a/components/operator/internal/tests/suite_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package tests_test - -import ( - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Controller Suite") -} diff --git a/components/operator/internal/tests/testdata/resources/auth-controller/config-with-auth-client.yaml b/components/operator/internal/tests/testdata/resources/auth-controller/config-with-auth-client.yaml deleted file mode 100644 index ca88a23efc..0000000000 --- a/components/operator/internal/tests/testdata/resources/auth-controller/config-with-auth-client.yaml +++ /dev/null @@ -1,9 +0,0 @@ -clients: - - id: client0 - public: false - redirectUris: [] - PostLogoutRedirectUris: [] - scopes: [] - secret: secret - secrets: - - secret diff --git a/components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-audit.yaml b/components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-audit.yaml deleted file mode 100644 index d9f8590708..0000000000 --- a/components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-audit.yaml +++ /dev/null @@ -1,52 +0,0 @@ -(cors) { - header { - Access-Control-Allow-Methods "GET,OPTIONS,PUT,POST,DELETE,HEAD,PATCH" - Access-Control-Allow-Headers content-type - Access-Control-Max-Age 100 - Access-Control-Allow-Origin * - } -} - -{ - - servers { - metrics - } - admin :3080 - - # Many directives manipulate the HTTP handler chain and the order in which - # those directives are evaluated matters. So the jwtauth directive must be - # ordered. - # c.f. https://caddyserver.com/docs/caddyfile/directives#directive-order - order versions after metrics -} - -:8080 { - log { - output stdout - } - handle /api/ledger* { - uri strip_prefix /api/ledger - import cors - reverse_proxy ledger:8080 { - header_up Host {upstream_hostport} - } - } - - handle /versions { - versions { - region "us-west-1" - env "staging" - endpoints { - ledger { - http://ledger:8080/_info http://ledger:8080/ - } - } - } - } - - # Respond 404 if service does not exists - handle /api/* { - respond "Not Found" 404 - } -} \ No newline at end of file diff --git a/components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-ledger-and-another-service.yaml b/components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-ledger-and-another-service.yaml deleted file mode 100644 index 42f74abdfe..0000000000 --- a/components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-ledger-and-another-service.yaml +++ /dev/null @@ -1,70 +0,0 @@ -(cors) { - header { - Access-Control-Allow-Methods "GET,OPTIONS,PUT,POST,DELETE,HEAD,PATCH" - Access-Control-Allow-Headers content-type - Access-Control-Max-Age 100 - Access-Control-Allow-Origin * - } -} - -{ - - servers { - metrics - } - admin :3080 - - # Many directives manipulate the HTTP handler chain and the order in which - # those directives are evaluated matters. So the jwtauth directive must be - # ordered. - # c.f. https://caddyserver.com/docs/caddyfile/directives#directive-order - order versions after metrics -} - -:8080 { - log { - output stdout - } - handle /api/another/webhooks* { - method POST - uri strip_prefix /api/another - import cors - reverse_proxy another:8080 { - header_up Host {upstream_hostport} - } - } - handle /api/another* { - uri strip_prefix /api/another - import cors - reverse_proxy another:8080 { - header_up Host {upstream_hostport} - } - } - handle /api/ledger* { - uri strip_prefix /api/ledger - import cors - reverse_proxy ledger:8080 { - header_up Host {upstream_hostport} - } - } - - handle /versions { - versions { - region "us-west-1" - env "staging" - endpoints { - another { - http://another:8080/_info http://another:8080/ - } - ledger { - http://ledger:8080/_info http://ledger:8080/ - } - } - } - } - - # Respond 404 if service does not exists - handle /api/* { - respond "Not Found" 404 - } -} \ No newline at end of file diff --git a/components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-ledger-only.yaml b/components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-ledger-only.yaml deleted file mode 100644 index d9f8590708..0000000000 --- a/components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-ledger-only.yaml +++ /dev/null @@ -1,52 +0,0 @@ -(cors) { - header { - Access-Control-Allow-Methods "GET,OPTIONS,PUT,POST,DELETE,HEAD,PATCH" - Access-Control-Allow-Headers content-type - Access-Control-Max-Age 100 - Access-Control-Allow-Origin * - } -} - -{ - - servers { - metrics - } - admin :3080 - - # Many directives manipulate the HTTP handler chain and the order in which - # those directives are evaluated matters. So the jwtauth directive must be - # ordered. - # c.f. https://caddyserver.com/docs/caddyfile/directives#directive-order - order versions after metrics -} - -:8080 { - log { - output stdout - } - handle /api/ledger* { - uri strip_prefix /api/ledger - import cors - reverse_proxy ledger:8080 { - header_up Host {upstream_hostport} - } - } - - handle /versions { - versions { - region "us-west-1" - env "staging" - endpoints { - ledger { - http://ledger:8080/_info http://ledger:8080/ - } - } - } - } - - # Respond 404 if service does not exists - handle /api/* { - respond "Not Found" 404 - } -} \ No newline at end of file diff --git a/components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-opentelemetry.yaml b/components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-opentelemetry.yaml deleted file mode 100644 index c8d88c2e0e..0000000000 --- a/components/operator/internal/tests/testdata/resources/gateway-controller/configmap-with-opentelemetry.yaml +++ /dev/null @@ -1,55 +0,0 @@ -(cors) { - header { - Access-Control-Allow-Methods "GET,OPTIONS,PUT,POST,DELETE,HEAD,PATCH" - Access-Control-Allow-Headers content-type - Access-Control-Max-Age 100 - Access-Control-Allow-Origin * - } -} - -{ - - servers { - metrics - } - admin :3080 - - # Many directives manipulate the HTTP handler chain and the order in which - # those directives are evaluated matters. So the jwtauth directive must be - # ordered. - # c.f. https://caddyserver.com/docs/caddyfile/directives#directive-order - order versions after metrics -} - -:8080 { - tracing { - span gateway - } - log { - output stdout - } - handle /api/ledger* { - uri strip_prefix /api/ledger - import cors - reverse_proxy ledger:8080 { - header_up Host {upstream_hostport} - } - } - - handle /versions { - versions { - region "us-west-1" - env "staging" - endpoints { - ledger { - http://ledger:8080/_info http://ledger:8080/ - } - } - } - } - - # Respond 404 if service does not exists - handle /api/* { - respond "Not Found" 404 - } -} \ No newline at end of file diff --git a/components/operator/internal/tests/wallets_controller_test.go b/components/operator/internal/tests/wallets_controller_test.go deleted file mode 100644 index acbb70c63d..0000000000 --- a/components/operator/internal/tests/wallets_controller_test.go +++ /dev/null @@ -1,113 +0,0 @@ -package tests_test - -import ( - v1beta1 "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/operator/internal/core" - "github.com/formancehq/operator/internal/resources/settings" - . "github.com/formancehq/operator/internal/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" -) - -var _ = Describe("WalletsController", func() { - Context("When creating a Wallets object", func() { - var ( - stack *v1beta1.Stack - gateway *v1beta1.Gateway - ledger *v1beta1.Ledger - wallets *v1beta1.Wallets - auth *v1beta1.Auth - databaseSettings *v1beta1.Settings - resourceLimitsSettings *v1beta1.Settings - resourceRequestsSettings *v1beta1.Settings - ) - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.StackSpec{}, - } - databaseSettings = settings.New(uuid.NewString(), "postgres.*.uri", "postgresql://localhost", stack.Name) - resourceLimitsSettings = settings.New(uuid.NewString(), - "deployments.*.containers.*.resource-requirements.limits", "cpu=500m", stack.Name) - resourceRequestsSettings = settings.New(uuid.NewString(), - "deployments.*.containers.*.resource-requirements.requests", "cpu=250m", stack.Name) - gateway = &v1beta1.Gateway{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.GatewaySpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - Ingress: &v1beta1.GatewayIngress{}, - }, - } - wallets = &v1beta1.Wallets{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.WalletsSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - ledger = &v1beta1.Ledger{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.LedgerSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - auth = &v1beta1.Auth{ - ObjectMeta: RandObjectMeta(), - Spec: v1beta1.AuthSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stack.Name, - }, - }, - } - }) - JustBeforeEach(func() { - Expect(Create( - stack, databaseSettings, resourceLimitsSettings, resourceRequestsSettings, - auth, gateway, ledger, wallets, - )).To(Succeed()) - }) - AfterEach(func() { - Expect(Delete(stack, databaseSettings, resourceLimitsSettings, resourceRequestsSettings)).To(Succeed()) - }) - It("Should create resources", func() { - By("Should add an owner reference on the stack", func() { - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("", wallets.Name, wallets)).To(Succeed()) - reference, err := core.HasOwnerReference(TestContext(), stack, wallets) - g.Expect(err).To(BeNil()) - return reference - }).Should(BeTrue()) - }) - By("Should create a deployment", func() { - deployment := &appsv1.Deployment{} - Eventually(func() error { - return LoadResource(stack.Name, "wallets", deployment) - }).Should(Succeed()) - Expect(deployment).To(BeControlledBy(wallets)) - By("should have set proper resource requirements", func() { - Expect(deployment.Spec.Template.Spec.Containers[0].Resources.Limits).NotTo(BeEmpty()) - Expect(deployment.Spec.Template.Spec.Containers[0].Resources.Requests).NotTo(BeEmpty()) - }) - }) - By("Should create a new GatewayHTTPAPI object", func() { - httpService := &v1beta1.GatewayHTTPAPI{} - Eventually(func() error { - return LoadResource("", core.GetObjectName(stack.Name, "wallets"), httpService) - }).Should(Succeed()) - }) - By("Should create a new AuthClient object", func() { - authClient := &v1beta1.AuthClient{} - Eventually(func() error { - return LoadResource("", core.GetObjectName(stack.Name, "wallets"), authClient) - }).Should(Succeed()) - }) - }) - }) -}) diff --git a/components/operator/pkg/client/formance.com/v1beta1/auth.go b/components/operator/pkg/client/formance.com/v1beta1/auth.go deleted file mode 100644 index c8eeea2ee6..0000000000 --- a/components/operator/pkg/client/formance.com/v1beta1/auth.go +++ /dev/null @@ -1,91 +0,0 @@ -package v1beta1 - -import ( - "context" - "github.com/formancehq/operator/api/formance.com/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -type AuthInterface interface { - List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.AuthList, error) - Get(ctx context.Context, name string, options metav1.GetOptions) (*v1beta1.Auth, error) - Create(ctx context.Context, Auth *v1beta1.Auth) (*v1beta1.Auth, error) - Update(ctx context.Context, Auth *v1beta1.Auth) (*v1beta1.Auth, error) - Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Delete(ctx context.Context, name string) error -} - -type AuthClient struct { - restClient rest.Interface -} - -func (c *AuthClient) List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.AuthList, error) { - result := v1beta1.AuthList{} - err := c.restClient. - Get(). - Resource("Auths"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *AuthClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.Auth, error) { - result := v1beta1.Auth{} - err := c.restClient. - Get(). - Resource("Auths"). - Name(name). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *AuthClient) Create(ctx context.Context, Auth *v1beta1.Auth) (*v1beta1.Auth, error) { - result := v1beta1.Auth{} - err := c.restClient. - Post(). - Resource("Auths"). - Body(Auth). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *AuthClient) Delete(ctx context.Context, name string) error { - return c.restClient. - Delete(). - Resource("Auths"). - Name(name). - Do(ctx). - Error() -} - -func (c *AuthClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.restClient. - Get(). - Resource("Auths"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch(ctx) -} - -func (c *AuthClient) Update(ctx context.Context, o *v1beta1.Auth) (*v1beta1.Auth, error) { - result := v1beta1.Auth{} - err := c.restClient. - Put(). - Resource("Auths"). - Name(o.Name). - Body(o). - Do(ctx). - Into(&result) - - return &result, err -} diff --git a/components/operator/pkg/client/formance.com/v1beta1/client.go b/components/operator/pkg/client/formance.com/v1beta1/client.go deleted file mode 100644 index 5a7371f83f..0000000000 --- a/components/operator/pkg/client/formance.com/v1beta1/client.go +++ /dev/null @@ -1,83 +0,0 @@ -package v1beta1 - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -func init() { - if err := v1beta1.AddToScheme(scheme.Scheme); err != nil { - panic(err) - } -} - -type Client struct { - rest.Interface -} - -func NewClient(restClient rest.Interface) *Client { - return &Client{ - Interface: restClient, - } -} - -func (c *Client) Stacks() StackInterface { - return &stackClient{ - restClient: c.Interface, - } -} - -func (c *Client) Auths() AuthInterface { - return &AuthClient{ - restClient: c.Interface, - } -} - -func (c *Client) Gateways() GatewayInterface { - return &gatewayClient{ - restClient: c.Interface, - } -} - -func (c *Client) Ledgers() LedgerInterface { - return &LedgerClient{ - restClient: c.Interface, - } -} - -func (c *Client) Orchestrations() OrchestrationInterface { - return &OrchestrationClient{ - restClient: c.Interface, - } -} - -func (c *Client) Payments() PaymentsInterface { - return &paymentsClient{ - restClient: c.Interface, - } -} - -func (c *Client) Reconciliations() ReconciliationInterface { - return &reconciliationClient{ - restClient: c.Interface, - } -} - -func (c *Client) Searches() SearchInterface { - return &SearchClient{ - restClient: c.Interface, - } -} - -func (c *Client) Wallets() WalletsInterface { - return &walletsClient{ - restClient: c.Interface, - } -} - -func (c *Client) Webhooks() WebhooksInterface { - return &webhooksClient{ - restClient: c.Interface, - } -} diff --git a/components/operator/pkg/client/formance.com/v1beta1/gateway.go b/components/operator/pkg/client/formance.com/v1beta1/gateway.go deleted file mode 100644 index efa6bbcb69..0000000000 --- a/components/operator/pkg/client/formance.com/v1beta1/gateway.go +++ /dev/null @@ -1,91 +0,0 @@ -package v1beta1 - -import ( - "context" - "github.com/formancehq/operator/api/formance.com/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -type GatewayInterface interface { - List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.GatewayList, error) - Get(ctx context.Context, name string, options metav1.GetOptions) (*v1beta1.Gateway, error) - Create(ctx context.Context, Gateway *v1beta1.Gateway) (*v1beta1.Gateway, error) - Update(ctx context.Context, Gateway *v1beta1.Gateway) (*v1beta1.Gateway, error) - Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Delete(ctx context.Context, name string) error -} - -type gatewayClient struct { - restClient rest.Interface -} - -func (c *gatewayClient) List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.GatewayList, error) { - result := v1beta1.GatewayList{} - err := c.restClient. - Get(). - Resource("Gateways"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *gatewayClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.Gateway, error) { - result := v1beta1.Gateway{} - err := c.restClient. - Get(). - Resource("Gateways"). - Name(name). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *gatewayClient) Create(ctx context.Context, Gateway *v1beta1.Gateway) (*v1beta1.Gateway, error) { - result := v1beta1.Gateway{} - err := c.restClient. - Post(). - Resource("Gateways"). - Body(Gateway). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *gatewayClient) Delete(ctx context.Context, name string) error { - return c.restClient. - Delete(). - Resource("Gateways"). - Name(name). - Do(ctx). - Error() -} - -func (c *gatewayClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.restClient. - Get(). - Resource("Gateways"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch(ctx) -} - -func (c *gatewayClient) Update(ctx context.Context, o *v1beta1.Gateway) (*v1beta1.Gateway, error) { - result := v1beta1.Gateway{} - err := c.restClient. - Put(). - Resource("Gateways"). - Name(o.Name). - Body(o). - Do(ctx). - Into(&result) - - return &result, err -} diff --git a/components/operator/pkg/client/formance.com/v1beta1/ledger.go b/components/operator/pkg/client/formance.com/v1beta1/ledger.go deleted file mode 100644 index 3537f21ba4..0000000000 --- a/components/operator/pkg/client/formance.com/v1beta1/ledger.go +++ /dev/null @@ -1,91 +0,0 @@ -package v1beta1 - -import ( - "context" - "github.com/formancehq/operator/api/formance.com/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -type LedgerInterface interface { - List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.LedgerList, error) - Get(ctx context.Context, name string, options metav1.GetOptions) (*v1beta1.Ledger, error) - Create(ctx context.Context, Ledger *v1beta1.Ledger) (*v1beta1.Ledger, error) - Update(ctx context.Context, Ledger *v1beta1.Ledger) (*v1beta1.Ledger, error) - Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Delete(ctx context.Context, name string) error -} - -type LedgerClient struct { - restClient rest.Interface -} - -func (c *LedgerClient) List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.LedgerList, error) { - result := v1beta1.LedgerList{} - err := c.restClient. - Get(). - Resource("Ledgers"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *LedgerClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.Ledger, error) { - result := v1beta1.Ledger{} - err := c.restClient. - Get(). - Resource("Ledgers"). - Name(name). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *LedgerClient) Create(ctx context.Context, Ledger *v1beta1.Ledger) (*v1beta1.Ledger, error) { - result := v1beta1.Ledger{} - err := c.restClient. - Post(). - Resource("Ledgers"). - Body(Ledger). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *LedgerClient) Delete(ctx context.Context, name string) error { - return c.restClient. - Delete(). - Resource("Ledgers"). - Name(name). - Do(ctx). - Error() -} - -func (c *LedgerClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.restClient. - Get(). - Resource("Ledgers"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch(ctx) -} - -func (c *LedgerClient) Update(ctx context.Context, o *v1beta1.Ledger) (*v1beta1.Ledger, error) { - result := v1beta1.Ledger{} - err := c.restClient. - Put(). - Resource("Ledgers"). - Name(o.Name). - Body(o). - Do(ctx). - Into(&result) - - return &result, err -} diff --git a/components/operator/pkg/client/formance.com/v1beta1/orchestration.go b/components/operator/pkg/client/formance.com/v1beta1/orchestration.go deleted file mode 100644 index 1333b491d2..0000000000 --- a/components/operator/pkg/client/formance.com/v1beta1/orchestration.go +++ /dev/null @@ -1,91 +0,0 @@ -package v1beta1 - -import ( - "context" - "github.com/formancehq/operator/api/formance.com/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -type OrchestrationInterface interface { - List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.OrchestrationList, error) - Get(ctx context.Context, name string, options metav1.GetOptions) (*v1beta1.Orchestration, error) - Create(ctx context.Context, Orchestration *v1beta1.Orchestration) (*v1beta1.Orchestration, error) - Update(ctx context.Context, Orchestration *v1beta1.Orchestration) (*v1beta1.Orchestration, error) - Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Delete(ctx context.Context, name string) error -} - -type OrchestrationClient struct { - restClient rest.Interface -} - -func (c *OrchestrationClient) List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.OrchestrationList, error) { - result := v1beta1.OrchestrationList{} - err := c.restClient. - Get(). - Resource("Orchestrations"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *OrchestrationClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.Orchestration, error) { - result := v1beta1.Orchestration{} - err := c.restClient. - Get(). - Resource("Orchestrations"). - Name(name). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *OrchestrationClient) Create(ctx context.Context, Orchestration *v1beta1.Orchestration) (*v1beta1.Orchestration, error) { - result := v1beta1.Orchestration{} - err := c.restClient. - Post(). - Resource("Orchestrations"). - Body(Orchestration). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *OrchestrationClient) Delete(ctx context.Context, name string) error { - return c.restClient. - Delete(). - Resource("Orchestrations"). - Name(name). - Do(ctx). - Error() -} - -func (c *OrchestrationClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.restClient. - Get(). - Resource("Orchestrations"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch(ctx) -} - -func (c *OrchestrationClient) Update(ctx context.Context, o *v1beta1.Orchestration) (*v1beta1.Orchestration, error) { - result := v1beta1.Orchestration{} - err := c.restClient. - Put(). - Resource("Orchestrations"). - Name(o.Name). - Body(o). - Do(ctx). - Into(&result) - - return &result, err -} diff --git a/components/operator/pkg/client/formance.com/v1beta1/payments.go b/components/operator/pkg/client/formance.com/v1beta1/payments.go deleted file mode 100644 index 60abe2222f..0000000000 --- a/components/operator/pkg/client/formance.com/v1beta1/payments.go +++ /dev/null @@ -1,91 +0,0 @@ -package v1beta1 - -import ( - "context" - "github.com/formancehq/operator/api/formance.com/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -type PaymentsInterface interface { - List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.PaymentsList, error) - Get(ctx context.Context, name string, options metav1.GetOptions) (*v1beta1.Payments, error) - Create(ctx context.Context, Payments *v1beta1.Payments) (*v1beta1.Payments, error) - Update(ctx context.Context, Payments *v1beta1.Payments) (*v1beta1.Payments, error) - Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Delete(ctx context.Context, name string) error -} - -type paymentsClient struct { - restClient rest.Interface -} - -func (c *paymentsClient) List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.PaymentsList, error) { - result := v1beta1.PaymentsList{} - err := c.restClient. - Get(). - Resource("Payments"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *paymentsClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.Payments, error) { - result := v1beta1.Payments{} - err := c.restClient. - Get(). - Resource("Payments"). - Name(name). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *paymentsClient) Create(ctx context.Context, Payments *v1beta1.Payments) (*v1beta1.Payments, error) { - result := v1beta1.Payments{} - err := c.restClient. - Post(). - Resource("Payments"). - Body(Payments). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *paymentsClient) Delete(ctx context.Context, name string) error { - return c.restClient. - Delete(). - Resource("Payments"). - Name(name). - Do(ctx). - Error() -} - -func (c *paymentsClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.restClient. - Get(). - Resource("Payments"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch(ctx) -} - -func (c *paymentsClient) Update(ctx context.Context, o *v1beta1.Payments) (*v1beta1.Payments, error) { - result := v1beta1.Payments{} - err := c.restClient. - Put(). - Resource("Payments"). - Name(o.Name). - Body(o). - Do(ctx). - Into(&result) - - return &result, err -} diff --git a/components/operator/pkg/client/formance.com/v1beta1/reconciliation.go b/components/operator/pkg/client/formance.com/v1beta1/reconciliation.go deleted file mode 100644 index eac8914007..0000000000 --- a/components/operator/pkg/client/formance.com/v1beta1/reconciliation.go +++ /dev/null @@ -1,91 +0,0 @@ -package v1beta1 - -import ( - "context" - "github.com/formancehq/operator/api/formance.com/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -type ReconciliationInterface interface { - List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.ReconciliationList, error) - Get(ctx context.Context, name string, options metav1.GetOptions) (*v1beta1.Reconciliation, error) - Create(ctx context.Context, Reconciliation *v1beta1.Reconciliation) (*v1beta1.Reconciliation, error) - Update(ctx context.Context, Reconciliation *v1beta1.Reconciliation) (*v1beta1.Reconciliation, error) - Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Delete(ctx context.Context, name string) error -} - -type reconciliationClient struct { - restClient rest.Interface -} - -func (c *reconciliationClient) List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.ReconciliationList, error) { - result := v1beta1.ReconciliationList{} - err := c.restClient. - Get(). - Resource("Reconciliations"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *reconciliationClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.Reconciliation, error) { - result := v1beta1.Reconciliation{} - err := c.restClient. - Get(). - Resource("Reconciliations"). - Name(name). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *reconciliationClient) Create(ctx context.Context, Reconciliation *v1beta1.Reconciliation) (*v1beta1.Reconciliation, error) { - result := v1beta1.Reconciliation{} - err := c.restClient. - Post(). - Resource("Reconciliations"). - Body(Reconciliation). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *reconciliationClient) Delete(ctx context.Context, name string) error { - return c.restClient. - Delete(). - Resource("Reconciliations"). - Name(name). - Do(ctx). - Error() -} - -func (c *reconciliationClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.restClient. - Get(). - Resource("Reconciliations"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch(ctx) -} - -func (c *reconciliationClient) Update(ctx context.Context, o *v1beta1.Reconciliation) (*v1beta1.Reconciliation, error) { - result := v1beta1.Reconciliation{} - err := c.restClient. - Put(). - Resource("Reconciliations"). - Name(o.Name). - Body(o). - Do(ctx). - Into(&result) - - return &result, err -} diff --git a/components/operator/pkg/client/formance.com/v1beta1/search.go b/components/operator/pkg/client/formance.com/v1beta1/search.go deleted file mode 100644 index 4134399507..0000000000 --- a/components/operator/pkg/client/formance.com/v1beta1/search.go +++ /dev/null @@ -1,91 +0,0 @@ -package v1beta1 - -import ( - "context" - "github.com/formancehq/operator/api/formance.com/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -type SearchInterface interface { - List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.SearchList, error) - Get(ctx context.Context, name string, options metav1.GetOptions) (*v1beta1.Search, error) - Create(ctx context.Context, Search *v1beta1.Search) (*v1beta1.Search, error) - Update(ctx context.Context, Search *v1beta1.Search) (*v1beta1.Search, error) - Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Delete(ctx context.Context, name string) error -} - -type SearchClient struct { - restClient rest.Interface -} - -func (c *SearchClient) List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.SearchList, error) { - result := v1beta1.SearchList{} - err := c.restClient. - Get(). - Resource("Searchs"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *SearchClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.Search, error) { - result := v1beta1.Search{} - err := c.restClient. - Get(). - Resource("Searchs"). - Name(name). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *SearchClient) Create(ctx context.Context, Search *v1beta1.Search) (*v1beta1.Search, error) { - result := v1beta1.Search{} - err := c.restClient. - Post(). - Resource("Searchs"). - Body(Search). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *SearchClient) Delete(ctx context.Context, name string) error { - return c.restClient. - Delete(). - Resource("Searchs"). - Name(name). - Do(ctx). - Error() -} - -func (c *SearchClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.restClient. - Get(). - Resource("Searchs"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch(ctx) -} - -func (c *SearchClient) Update(ctx context.Context, o *v1beta1.Search) (*v1beta1.Search, error) { - result := v1beta1.Search{} - err := c.restClient. - Put(). - Resource("Searchs"). - Name(o.Name). - Body(o). - Do(ctx). - Into(&result) - - return &result, err -} diff --git a/components/operator/pkg/client/formance.com/v1beta1/stack.go b/components/operator/pkg/client/formance.com/v1beta1/stack.go deleted file mode 100644 index a5bfacb41a..0000000000 --- a/components/operator/pkg/client/formance.com/v1beta1/stack.go +++ /dev/null @@ -1,106 +0,0 @@ -package v1beta1 - -import ( - "context" - "github.com/formancehq/operator/api/formance.com/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -type StackInterface interface { - List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.StackList, error) - Get(ctx context.Context, name string, options metav1.GetOptions) (*v1beta1.Stack, error) - Create(ctx context.Context, stack *v1beta1.Stack) (*v1beta1.Stack, error) - Update(ctx context.Context, stack *v1beta1.Stack) (*v1beta1.Stack, error) - Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, patchType types.PatchType, body any) (*v1beta1.Stack, error) - Delete(ctx context.Context, name string) error -} - -type stackClient struct { - restClient rest.Interface -} - -func (c *stackClient) List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.StackList, error) { - result := v1beta1.StackList{} - err := c.restClient. - Get(). - Resource("stacks"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *stackClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.Stack, error) { - result := v1beta1.Stack{} - err := c.restClient. - Get(). - Resource("stacks"). - Name(name). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *stackClient) Create(ctx context.Context, stack *v1beta1.Stack) (*v1beta1.Stack, error) { - result := v1beta1.Stack{} - err := c.restClient. - Post(). - Resource("stacks"). - Body(stack). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *stackClient) Delete(ctx context.Context, name string) error { - return c.restClient. - Delete(). - Resource("stacks"). - Name(name). - Do(ctx). - Error() -} - -func (c *stackClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.restClient. - Get(). - Resource("stacks"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch(ctx) -} - -func (c *stackClient) Update(ctx context.Context, o *v1beta1.Stack) (*v1beta1.Stack, error) { - result := v1beta1.Stack{} - err := c.restClient. - Put(). - Resource("stacks"). - Name(o.Name). - Body(o). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *stackClient) Patch(ctx context.Context, name string, patchType types.PatchType, body any) (*v1beta1.Stack, error) { - result := v1beta1.Stack{} - err := c.restClient. - Patch(patchType). - Resource("stacks"). - Name(name). - Body(body). - Do(ctx). - Into(&result) - - return &result, err -} diff --git a/components/operator/pkg/client/formance.com/v1beta1/versions.go b/components/operator/pkg/client/formance.com/v1beta1/versions.go deleted file mode 100644 index 5bb03b3b7d..0000000000 --- a/components/operator/pkg/client/formance.com/v1beta1/versions.go +++ /dev/null @@ -1,91 +0,0 @@ -package v1beta1 - -import ( - "context" - "github.com/formancehq/operator/api/formance.com/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -type VersionsInterface interface { - List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.VersionsList, error) - Get(ctx context.Context, name string, options metav1.GetOptions) (*v1beta1.Versions, error) - Create(ctx context.Context, Versions *v1beta1.Versions) (*v1beta1.Versions, error) - Update(ctx context.Context, Versions *v1beta1.Versions) (*v1beta1.Versions, error) - Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Delete(ctx context.Context, name string) error -} - -type VersionsClient struct { - restClient rest.Interface -} - -func (c *VersionsClient) List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.VersionsList, error) { - result := v1beta1.VersionsList{} - err := c.restClient. - Get(). - Resource("Versions"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *VersionsClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.Versions, error) { - result := v1beta1.Versions{} - err := c.restClient. - Get(). - Resource("Versions"). - Name(name). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *VersionsClient) Create(ctx context.Context, Versions *v1beta1.Versions) (*v1beta1.Versions, error) { - result := v1beta1.Versions{} - err := c.restClient. - Post(). - Resource("Versions"). - Body(Versions). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *VersionsClient) Delete(ctx context.Context, name string) error { - return c.restClient. - Delete(). - Resource("Versions"). - Name(name). - Do(ctx). - Error() -} - -func (c *VersionsClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.restClient. - Get(). - Resource("Versions"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch(ctx) -} - -func (c *VersionsClient) Update(ctx context.Context, o *v1beta1.Versions) (*v1beta1.Versions, error) { - result := v1beta1.Versions{} - err := c.restClient. - Put(). - Resource("Versions"). - Name(o.Name). - Body(o). - Do(ctx). - Into(&result) - - return &result, err -} diff --git a/components/operator/pkg/client/formance.com/v1beta1/wallets.go b/components/operator/pkg/client/formance.com/v1beta1/wallets.go deleted file mode 100644 index 7ecd6c321c..0000000000 --- a/components/operator/pkg/client/formance.com/v1beta1/wallets.go +++ /dev/null @@ -1,91 +0,0 @@ -package v1beta1 - -import ( - "context" - "github.com/formancehq/operator/api/formance.com/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -type WalletsInterface interface { - List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.WalletsList, error) - Get(ctx context.Context, name string, options metav1.GetOptions) (*v1beta1.Wallets, error) - Create(ctx context.Context, Wallets *v1beta1.Wallets) (*v1beta1.Wallets, error) - Update(ctx context.Context, Wallets *v1beta1.Wallets) (*v1beta1.Wallets, error) - Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Delete(ctx context.Context, name string) error -} - -type walletsClient struct { - restClient rest.Interface -} - -func (c *walletsClient) List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.WalletsList, error) { - result := v1beta1.WalletsList{} - err := c.restClient. - Get(). - Resource("Wallets"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *walletsClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.Wallets, error) { - result := v1beta1.Wallets{} - err := c.restClient. - Get(). - Resource("Wallets"). - Name(name). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *walletsClient) Create(ctx context.Context, Wallets *v1beta1.Wallets) (*v1beta1.Wallets, error) { - result := v1beta1.Wallets{} - err := c.restClient. - Post(). - Resource("Wallets"). - Body(Wallets). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *walletsClient) Delete(ctx context.Context, name string) error { - return c.restClient. - Delete(). - Resource("Wallets"). - Name(name). - Do(ctx). - Error() -} - -func (c *walletsClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.restClient. - Get(). - Resource("Wallets"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch(ctx) -} - -func (c *walletsClient) Update(ctx context.Context, o *v1beta1.Wallets) (*v1beta1.Wallets, error) { - result := v1beta1.Wallets{} - err := c.restClient. - Put(). - Resource("Wallets"). - Name(o.Name). - Body(o). - Do(ctx). - Into(&result) - - return &result, err -} diff --git a/components/operator/pkg/client/formance.com/v1beta1/webhooks.go b/components/operator/pkg/client/formance.com/v1beta1/webhooks.go deleted file mode 100644 index 119ea61f5e..0000000000 --- a/components/operator/pkg/client/formance.com/v1beta1/webhooks.go +++ /dev/null @@ -1,91 +0,0 @@ -package v1beta1 - -import ( - "context" - "github.com/formancehq/operator/api/formance.com/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" -) - -type WebhooksInterface interface { - List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.WebhooksList, error) - Get(ctx context.Context, name string, options metav1.GetOptions) (*v1beta1.Webhooks, error) - Create(ctx context.Context, Webhooks *v1beta1.Webhooks) (*v1beta1.Webhooks, error) - Update(ctx context.Context, Webhooks *v1beta1.Webhooks) (*v1beta1.Webhooks, error) - Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Delete(ctx context.Context, name string) error -} - -type webhooksClient struct { - restClient rest.Interface -} - -func (c *webhooksClient) List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.WebhooksList, error) { - result := v1beta1.WebhooksList{} - err := c.restClient. - Get(). - Resource("Webhooks"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *webhooksClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.Webhooks, error) { - result := v1beta1.Webhooks{} - err := c.restClient. - Get(). - Resource("Webhooks"). - Name(name). - VersionedParams(&opts, scheme.ParameterCodec). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *webhooksClient) Create(ctx context.Context, Webhooks *v1beta1.Webhooks) (*v1beta1.Webhooks, error) { - result := v1beta1.Webhooks{} - err := c.restClient. - Post(). - Resource("Webhooks"). - Body(Webhooks). - Do(ctx). - Into(&result) - - return &result, err -} - -func (c *webhooksClient) Delete(ctx context.Context, name string) error { - return c.restClient. - Delete(). - Resource("Webhooks"). - Name(name). - Do(ctx). - Error() -} - -func (c *webhooksClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.restClient. - Get(). - Resource("Webhooks"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch(ctx) -} - -func (c *webhooksClient) Update(ctx context.Context, o *v1beta1.Webhooks) (*v1beta1.Webhooks, error) { - result := v1beta1.Webhooks{} - err := c.restClient. - Put(). - Resource("Webhooks"). - Name(o.Name). - Body(o). - Do(ctx). - Into(&result) - - return &result, err -} diff --git a/components/operator/scratch.Dockerfile b/components/operator/scratch.Dockerfile deleted file mode 100644 index cd051b363c..0000000000 --- a/components/operator/scratch.Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM ghcr.io/formancehq/base:scratch -COPY operator /usr/bin/operator -ENV OTEL_SERVICE_NAME operator -ENTRYPOINT ["/usr/bin/operator"] diff --git a/components/operator/tools/kubectl-stacks/Earthfile b/components/operator/tools/kubectl-stacks/Earthfile deleted file mode 100644 index 17679680dd..0000000000 --- a/components/operator/tools/kubectl-stacks/Earthfile +++ /dev/null @@ -1,21 +0,0 @@ -VERSION 0.8 - -IMPORT github.com/formancehq/earthly:tags/v0.15.0 AS core -IMPORT ../../../.. AS stack -IMPORT ../../.. AS components - -FROM core+base-image - -sources: - FROM core+builder-image - WORKDIR /src - COPY (stack+sources/out --LOCATION=components/operator) components/operator - WORKDIR /src/components/operator/tools/kubectl-stacks - COPY go.* *.go . - SAVE ARTIFACT /src - -tidy: - FROM core+builder-image - COPY --pass-args (+sources/src) /src - WORKDIR /src/components/operator/tools/kubectl-stacks - DO --pass-args stack+GO_TIDY \ No newline at end of file diff --git a/components/operator/tools/kubectl-stacks/disable.go b/components/operator/tools/kubectl-stacks/disable.go deleted file mode 100644 index 9ded558648..0000000000 --- a/components/operator/tools/kubectl-stacks/disable.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/types" - "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/client-go/rest" -) - -func NewDisableCommand(configFlags *genericclioptions.ConfigFlags) *cobra.Command { - return &cobra.Command{ - Use: "disable ", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - client, err := getRestClient(configFlags) - if err != nil { - return err - } - - return disable(cmd, client, args[0]) - }, - } -} - -func disable(cmd *cobra.Command, client *rest.RESTClient, name string) error { - _, _ = fmt.Fprintf(cmd.OutOrStdout(), "Disable stack '%s'...\r\n", name) - content, err := json.Marshal(map[string]any{ - "spec": map[string]any{ - "disabled": true, - }, - }) - if err != nil { - panic(err) - } - - return client.Patch(types.MergePatchType). - Resource("Stacks"). - Name(name). - Body(content). - Do(cmd.Context()). - Error() -} diff --git a/components/operator/tools/kubectl-stacks/enable.go b/components/operator/tools/kubectl-stacks/enable.go deleted file mode 100644 index 9d40926d0d..0000000000 --- a/components/operator/tools/kubectl-stacks/enable.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/types" - "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/client-go/rest" -) - -func NewEnableCommand(configFlags *genericclioptions.ConfigFlags) *cobra.Command { - return &cobra.Command{ - Use: "enable ", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - client, err := getRestClient(configFlags) - if err != nil { - return err - } - - return enable(cmd, client, args[0]) - }, - } -} - -func enable(cmd *cobra.Command, client *rest.RESTClient, name string) error { - _, _ = fmt.Fprintf(cmd.OutOrStdout(), "Enable stack '%s'...\r\n", name) - content, err := json.Marshal(map[string]any{ - "spec": map[string]any{ - "disabled": false, - }, - }) - if err != nil { - panic(err) - } - - return client.Patch(types.MergePatchType). - Resource("Stacks"). - Name(name). - Body(content). - Do(cmd.Context()). - Error() -} diff --git a/components/operator/tools/kubectl-stacks/go.mod b/components/operator/tools/kubectl-stacks/go.mod deleted file mode 100644 index 1b5af2d4e9..0000000000 --- a/components/operator/tools/kubectl-stacks/go.mod +++ /dev/null @@ -1,85 +0,0 @@ -module github.com/formancehq/operator/tools/kubectl-stacks - -go 1.22.0 - -toolchain go1.22.7 - -require ( - github.com/formancehq/go-libs v1.7.1 - github.com/formancehq/operator v0.0.0-00010101000000-000000000000 - github.com/pterm/pterm v0.12.79 - github.com/spf13/cobra v1.8.1 - github.com/spf13/pflag v1.0.5 - k8s.io/apimachinery v0.29.1 - k8s.io/cli-runtime v0.29.1 - k8s.io/client-go v0.29.1 -) - -require ( - atomicgo.dev/cursor v0.2.0 // indirect - atomicgo.dev/keyboard v0.2.9 // indirect - atomicgo.dev/schedule v0.1.0 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/containerd/console v1.0.3 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch v5.7.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.8.0 // indirect - github.com/go-errors/errors v1.4.2 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/btree v1.0.1 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/gookit/color v1.5.4 // indirect - github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect - github.com/imdario/mergo v0.3.13 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect - github.com/lithammer/fuzzysearch v1.1.8 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/moby/term v0.5.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/peterbourgon/diskv v2.0.1+incompatible // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/rivo/uniseg v0.4.4 // indirect - github.com/xlab/treeprint v1.2.0 // indirect - github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect - golang.org/x/mod v0.21.0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/time v0.6.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.29.1 // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect - sigs.k8s.io/controller-runtime v0.17.1 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect - sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect -) - -replace github.com/formancehq/operator => ./../.. diff --git a/components/operator/tools/kubectl-stacks/go.sum b/components/operator/tools/kubectl-stacks/go.sum deleted file mode 100644 index 5f774ccc88..0000000000 --- a/components/operator/tools/kubectl-stacks/go.sum +++ /dev/null @@ -1,368 +0,0 @@ -atomicgo.dev/assert v0.0.2 h1:FiKeMiZSgRrZsPo9qn/7vmr7mCsh5SZyXY4YGYiYwrg= -atomicgo.dev/assert v0.0.2/go.mod h1:ut4NcI3QDdJtlmAxQULOmA13Gz6e2DWbSAS8RUOmNYQ= -atomicgo.dev/cursor v0.2.0 h1:H6XN5alUJ52FZZUkI7AlJbUc1aW38GWZalpYRPpoPOw= -atomicgo.dev/cursor v0.2.0/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU= -atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8= -atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ= -atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs= -atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= -github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= -github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= -github.com/MarvinJWendt/testza v0.2.10/go.mod h1:pd+VWsoGUiFtq+hRKSU1Bktnn+DMCSrDrXDpX2bG66k= -github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzXjB69adAhzZkI= -github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c= -github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE= -github.com/MarvinJWendt/testza v0.5.2 h1:53KDo64C1z/h/d/stCYCPY69bt/OSwjq5KpFNwi+zB4= -github.com/MarvinJWendt/testza v0.5.2/go.mod h1:xu53QFE5sCdjtMCKk8YMQ2MnymimEctc4n3EjyIYvEY= -github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= -github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= -github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= -github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= -github.com/formancehq/go-libs v1.7.1 h1:9D5cxKWFlVtdX5AYDXeUz1Nb9PdoEfQX0f/yeLsU324= -github.com/formancehq/go-libs v1.7.1/go.mod h1:pWTScpoyieF7OoJ6WVmXNG9NhDjbZbAmFqd7UOw85iI= -github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= -github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 h1:c5FlPPgxOn7kJz3VoPLkQYQXGBS3EklQ4Zfi57uOuqQ= -github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= -github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= -github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= -github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= -github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= -github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= -github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= -github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= -github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= -github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= -github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= -github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI= -github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg= -github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE= -github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEejaWgXU= -github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= -github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8= -github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= -github.com/pterm/pterm v0.12.79 h1:lH3yrYMhdpeqX9y5Ep1u7DejyHy7NSQg9qrBjF9dFT4= -github.com/pterm/pterm v0.12.79/go.mod h1:1v/gzOF1N0FsjbgTHZ1wVycRkKiatFvJSJC4IGaQAAo= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= -github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= -github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= -go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.29.1 h1:DAjwWX/9YT7NQD4INu49ROJuZAAAP/Ijki48GUPzxqw= -k8s.io/api v0.29.1/go.mod h1:7Kl10vBRUXhnQQI8YR/R327zXC8eJ7887/+Ybta+RoQ= -k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= -k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= -k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc= -k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= -k8s.io/cli-runtime v0.29.1 h1:By3WVOlEWYfyxhGko0f/IuAOLQcbBSMzwSaDren2JUs= -k8s.io/cli-runtime v0.29.1/go.mod h1:vjEY9slFp8j8UoMhV5AlO8uulX9xk6ogfIesHobyBDU= -k8s.io/client-go v0.29.1 h1:19B/+2NGEwnFLzt0uB5kNJnfTsbV8w6TgQRz9l7ti7A= -k8s.io/client-go v0.29.1/go.mod h1:TDG/psL9hdet0TI9mGyHJSgRkW3H9JZk2dNEUS7bRks= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.17.1 h1:V1dQELMGVk46YVXXQUbTFujU7u4DQj6YUj9Rb6cuzz8= -sigs.k8s.io/controller-runtime v0.17.1/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/components/operator/tools/kubectl-stacks/list.go b/components/operator/tools/kubectl-stacks/list.go deleted file mode 100644 index c0c4ab3bc4..0000000000 --- a/components/operator/tools/kubectl-stacks/list.go +++ /dev/null @@ -1,73 +0,0 @@ -package main - -import ( - "fmt" - "sort" - "text/tabwriter" - "time" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/spf13/cobra" - "k8s.io/cli-runtime/pkg/genericclioptions" -) - -func NewListCommand(configFlags *genericclioptions.ConfigFlags) *cobra.Command { - ret := &cobra.Command{ - Use: "list", - RunE: func(cmd *cobra.Command, args []string) error { - - client, err := getRestClient(configFlags) - if err != nil { - return err - } - - list := &v1beta1.StackList{} - if err := client.Get(). - Resource("Stacks"). - Do(cmd.Context()). - Into(list); err != nil { - return err - } - - stacks := list.Items - onlyEnabled, err := cmd.Flags().GetBool("only-enabled") - if err != nil { - return err - } - if onlyEnabled { - stacks = collectionutils.Filter(stacks, func(stack v1beta1.Stack) bool { - return !stack.Spec.Disabled - }) - } - - sort.Slice(stacks, func(i, j int) bool { - return stacks[i].CreationTimestamp.Before(&stacks[j].CreationTimestamp) - }) - - w := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 0, 1, ' ', 0) - _, _ = fmt.Fprintln(w, "Name\tCreated at\tReady\tLocked?") - for _, stack := range stacks { - _, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\r\n", stack.Name, - stack.CreationTimestamp.Time.Format(time.RFC3339), func() string { - if stack.Status.Ready { - return "yes" - } - return "no" - }(), - func() string { - if stack.GetAnnotations()[v1beta1.SkipLabel] == "true" { - return "yes" - } - return "" - }(), - ) - } - return w.Flush() - }, - } - - ret.Flags().Bool("only-enabled", false, "Filter only enabled stacks") - - return ret -} diff --git a/components/operator/tools/kubectl-stacks/lock.go b/components/operator/tools/kubectl-stacks/lock.go deleted file mode 100644 index 4245dcf4e0..0000000000 --- a/components/operator/tools/kubectl-stacks/lock.go +++ /dev/null @@ -1,71 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/types" - "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/client-go/rest" -) - -func NewLockCommand(configFlags *genericclioptions.ConfigFlags) *cobra.Command { - return &cobra.Command{ - Use: "lock []", - Args: cobra.RangeArgs(0, 1), - RunE: func(cmd *cobra.Command, args []string) error { - client, err := getRestClient(configFlags) - if err != nil { - return err - } - - if len(args) == 0 { - _, err := lockAllStacks(cmd, client) - return err - } else { - return lockStack(cmd, client, args[0]) - } - }, - } -} - -func lockAllStacks(cmd *cobra.Command, client *rest.RESTClient) (*v1beta1.StackList, error) { - list := &v1beta1.StackList{} - if err := client.Get(). - Resource("Stacks"). - Do(cmd.Context()). - Into(list); err != nil { - return nil, err - } - - for _, stack := range list.Items { - if err := lockStack(cmd, client, stack.Name); err != nil { - return nil, err - } - } - return list, nil -} - -func lockStack(cmd *cobra.Command, client *rest.RESTClient, name string) error { - - _, _ = fmt.Fprintf(cmd.OutOrStdout(), "Locking stack '%s'...\r\n", name) - - content, err := json.Marshal(map[string]any{ - "metadata": map[string]any{ - "annotations": map[string]any{ - v1beta1.SkipLabel: "true", - }, - }, - }) - if err != nil { - panic(err) - } - - return client.Patch(types.MergePatchType). - Resource("Stacks"). - Name(name). - Body(content). - Do(cmd.Context()). - Error() -} diff --git a/components/operator/tools/kubectl-stacks/main.go b/components/operator/tools/kubectl-stacks/main.go deleted file mode 100644 index 27b7ad2af5..0000000000 --- a/components/operator/tools/kubectl-stacks/main.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "fmt" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "os" -) - -// NewRootCommand provides a cobra command wrapping NamespaceOptions -func NewRootCommand() *cobra.Command { - cmd := &cobra.Command{ - SilenceUsage: true, - } - - configFlags := genericclioptions.NewConfigFlags(true) - configFlags.AddFlags(cmd.Flags()) - cmd.AddCommand( - NewLockCommand(configFlags), - NewUnlockCommand(configFlags), - NewListCommand(configFlags), - NewSetDebugCommand(configFlags), - NewDisableCommand(configFlags), - NewEnableCommand(configFlags), - NewUpgradeCommand(configFlags), - NewSettingsCommand(configFlags), - ) - - return cmd -} - -func getRestClient(configFlags *genericclioptions.ConfigFlags) (*rest.RESTClient, error) { - restConfig, err := configFlags.ToRESTConfig() - if err != nil { - return nil, err - } - restConfig.GroupVersion = &v1beta1.GroupVersion - restConfig.NegotiatedSerializer = scheme.Codecs.WithoutConversion() - restConfig.APIPath = "/apis" - - return rest.RESTClientFor(restConfig) -} - -func main() { - flags := pflag.NewFlagSet("kubectl-stacks", pflag.ExitOnError) - pflag.CommandLine = flags - - root := NewRootCommand() - if err := root.Execute(); err != nil { - _, _ = fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} - -func init() { - if err := v1beta1.AddToScheme(scheme.Scheme); err != nil { - panic(err) - } -} diff --git a/components/operator/tools/kubectl-stacks/set-debug.go b/components/operator/tools/kubectl-stacks/set-debug.go deleted file mode 100644 index 4a2edca2e2..0000000000 --- a/components/operator/tools/kubectl-stacks/set-debug.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/types" - "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/client-go/rest" -) - -func NewSetDebugCommand(configFlags *genericclioptions.ConfigFlags) *cobra.Command { - return &cobra.Command{ - Use: "set-debug on|off", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - client, err := getRestClient(configFlags) - if err != nil { - return err - } - - return setDebug(cmd, client, args[0], args[1] == "on") - }, - } -} - -func setDebug(cmd *cobra.Command, client *rest.RESTClient, name string, b bool) error { - _, _ = fmt.Fprintf(cmd.OutOrStdout(), "Setting debug on stack '%s'...\r\n", name) - content, err := json.Marshal(map[string]any{ - "spec": map[string]any{ - "debug": b, - }, - }) - if err != nil { - panic(err) - } - - return client.Patch(types.MergePatchType). - Resource("Stacks"). - Name(name). - Body(content). - Do(cmd.Context()). - Error() -} diff --git a/components/operator/tools/kubectl-stacks/settings.go b/components/operator/tools/kubectl-stacks/settings.go deleted file mode 100644 index a008f5829f..0000000000 --- a/components/operator/tools/kubectl-stacks/settings.go +++ /dev/null @@ -1,89 +0,0 @@ -package main - -import ( - "encoding/json" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/spf13/cobra" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/cli-runtime/pkg/genericclioptions" -) - -func NewSettingsCommand(configFlags *genericclioptions.ConfigFlags) *cobra.Command { - ret := &cobra.Command{ - Use: "settings", - } - - ret.AddCommand( - NewAddSettingsCommand(configFlags), - NewRmSettingsCommand(configFlags), - ) - - return ret -} - -func NewAddSettingsCommand(configFlags *genericclioptions.ConfigFlags) *cobra.Command { - ret := &cobra.Command{ - Use: "add ", - Short: "Create a new settings", - Args: cobra.ExactArgs(3), - RunE: func(cmd *cobra.Command, args []string) error { - client, err := getRestClient(configFlags) - if err != nil { - return err - } - - stacks, err := cmd.Flags().GetStringSlice("stacks") - if err != nil { - return err - } - - settings := v1beta1.Settings{ - ObjectMeta: v1.ObjectMeta{ - Name: args[0], - }, - Spec: v1beta1.SettingsSpec{ - Key: args[1], - Value: args[2], - Stacks: stacks, - }, - } - settings.SetGroupVersionKind(v1beta1.GroupVersion.WithKind("Settings")) - - data, err := json.Marshal(settings) - if err != nil { - return err - } - - return client.Post(). - Name(args[0]). - Resource("Settings"). - Body(data). - Do(cmd.Context()). - Error() - }, - } - - ret.Flags().StringSlice("stacks", []string{"*"}, "Select stacks on which the setting is applied") - - return ret -} - -func NewRmSettingsCommand(configFlags *genericclioptions.ConfigFlags) *cobra.Command { - return &cobra.Command{ - Use: "rm", - Short: "Delete a setting", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - client, err := getRestClient(configFlags) - if err != nil { - return err - } - - return client.Delete(). - Name(args[0]). - Resource("Settings"). - Do(cmd.Context()). - Error() - }, - } -} \ No newline at end of file diff --git a/components/operator/tools/kubectl-stacks/unlock.go b/components/operator/tools/kubectl-stacks/unlock.go deleted file mode 100644 index 40b149e755..0000000000 --- a/components/operator/tools/kubectl-stacks/unlock.go +++ /dev/null @@ -1,68 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/types" - "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/client-go/rest" -) - -func NewUnlockCommand(configFlags *genericclioptions.ConfigFlags) *cobra.Command { - return &cobra.Command{ - Use: "unlock []", - Args: cobra.RangeArgs(0, 1), - RunE: func(cmd *cobra.Command, args []string) error { - client, err := getRestClient(configFlags) - if err != nil { - return err - } - - if len(args) == 0 { - return unlockAllStacks(cmd, client) - } else { - return unlockStack(cmd, client, args[0]) - } - }, - } -} - -func unlockAllStacks(cmd *cobra.Command, client *rest.RESTClient) error { - list := &v1beta1.StackList{} - if err := client.Get(). - Resource("Stacks"). - Do(cmd.Context()). - Into(list); err != nil { - return err - } - - for _, stack := range list.Items { - if err := unlockStack(cmd, client, stack.Name); err != nil { - return err - } - } - return nil -} - -func unlockStack(cmd *cobra.Command, client *rest.RESTClient, name string) error { - _, _ = fmt.Fprintf(cmd.OutOrStdout(), "Unlocking stack '%s'...\r\n", name) - content, err := json.Marshal(map[string]any{ - "metadata": map[string]any{ - "annotations": map[string]any{ - v1beta1.SkipLabel: nil, - }, - }, - }) - if err != nil { - panic(err) - } - - return client.Patch(types.MergePatchType). - Resource("Stacks"). - Name(name). - Body(content). - Do(cmd.Context()). - Error() -} diff --git a/components/operator/tools/kubectl-stacks/upgrade.go b/components/operator/tools/kubectl-stacks/upgrade.go deleted file mode 100644 index e8024a90fc..0000000000 --- a/components/operator/tools/kubectl-stacks/upgrade.go +++ /dev/null @@ -1,104 +0,0 @@ -package main - -import ( - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/pterm/pterm" - "github.com/spf13/cobra" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/client-go/rest" - "time" -) - -func NewUpgradeCommand(configFlags *genericclioptions.ConfigFlags) *cobra.Command { - ret := &cobra.Command{ - Use: "upgrade", - Short: "Utility to control operator upgrade", - Long: ` - Upgrading operator with a lot of stacks can stress the k8s cluster. - This utility help to upgrade stacks smoothly. - `, - RunE: func(cmd *cobra.Command, args []string) error { - client, err := getRestClient(configFlags) - if err != nil { - return err - } - - return upgrade(cmd, client) - }, - } - ret.Flags().Bool("max", false, "Maximum number of stacks to concurrently upgrade") - - return ret -} - -func upgrade(cmd *cobra.Command, client *rest.RESTClient) error { - stackList, err := lockAllStacks(cmd, client) - if err != nil { - return err - } - defer func() { - if err := unlockAllStacks(cmd, client); err != nil { - panic(err) - } - }() - for _, stack := range stackList.Items { - pterm.Printfln(`Waiting for stack '%s' to be marked as skipped`, stack.Name) - if err := waitForStackSkipped(cmd, client, stack.Name, metav1.ConditionTrue); err != nil { - return err - } - } - - pterm.Println(` -All stacks has been locked, you can now upgrade the operator. -Press enter when you are ready`) - result, err := pterm.DefaultInteractiveConfirm.Show() - if err != nil { - return err - } - if result { - pterm.Println(`Will now upgrade stacks one by one`) - for _, stack := range stackList.Items { - pterm.Printfln(`Upgrade stack '%s'`, stack.Name) - if err := unlockStack(cmd, client, stack.Name); err != nil { - return err - } - - pterm.Printfln(`Waiting for stack '%s' to be unmarked as skipped`, stack.Name) - if err := waitForStackSkipped(cmd, client, stack.Name, metav1.ConditionFalse); err != nil { - return err - } - } - } - - return nil -} - -func waitForStackSkipped(cmd *cobra.Command, client *rest.RESTClient, name string, status metav1.ConditionStatus) error { - for { - stack := &v1beta1.Stack{} - if err := client.Get(). - Resource("Stacks"). - Name(name). - Do(cmd.Context()). - Into(stack); err != nil { - return err - } - skippedCondition := stack.Status.Conditions.Get("Skipped") - if status == metav1.ConditionTrue { - if skippedCondition != nil && skippedCondition.Status == status { - return nil - } - } else { - if skippedCondition == nil || skippedCondition.Status == status { - return nil - } - } - - select { - case <-cmd.Context().Done(): - return cmd.Context().Err() - case <-time.After(time.Second): - } - } -} diff --git a/components/operator/tools/utils/.goreleaser.yml b/components/operator/tools/utils/.goreleaser.yml deleted file mode 100644 index 5c99df3967..0000000000 --- a/components/operator/tools/utils/.goreleaser.yml +++ /dev/null @@ -1,39 +0,0 @@ -project_name: operator-utils -includes: - - from_file: - path: ./../../../../.goreleaser.default.yaml - -monorepo: - tag_prefix: v - dir: ./ - -builds: - - binary: operator-utils - id: operator-utils - ldflags: - - -X github.com/formancehq/operator-utils/cmd.BuildDate={{ .Date }} - - -X github.com/formancehq/operator-utils/cmd.Version=v{{ .Version }} - - -X github.com/formancehq/operator-utils/cmd.Commit={{ .ShortCommit }} - - -extldflags "-static" - env: - - CGO_ENABLED=0 - goos: - - linux - goarch: - - amd64 - - arm64 - -archives: - - id: "{{.ProjectName}}" - builds: - - operator-utils - format: tar.gz - name_template: "{{.ProjectName}}_{{.Os}}-{{.Arch}}" - - -release: - prerelease: auto - footer: | - ## What to do next? - - Read the [documentation](https://docs.formance.com/) - - Join our [Slack server](https://formance.com/slack) \ No newline at end of file diff --git a/components/operator/tools/utils/Earthfile b/components/operator/tools/utils/Earthfile deleted file mode 100644 index 52217e78d1..0000000000 --- a/components/operator/tools/utils/Earthfile +++ /dev/null @@ -1,52 +0,0 @@ -VERSION 0.8 - -IMPORT github.com/formancehq/earthly:tags/v0.15.0 AS core -IMPORT ../../../.. AS stack -IMPORT ../../.. AS components - -FROM core+base-image - -sources: - FROM core+builder-image - WORKDIR /src - WORKDIR /src/components/operator/tools/utils - COPY --dir cmd . - COPY go.* main.go . - SAVE ARTIFACT /src - -compile: - FROM core+builder-image - COPY (+sources/*) /src - WORKDIR /src/components/operator/tools/utils - DO --pass-args core+GO_COMPILE - -build-image: - FROM core+final-image - ENTRYPOINT ["/usr/bin/operator-utils"] - COPY --pass-args (+compile/main) /usr/bin/operator-utils - ARG REPOSITORY=ghcr.io - ARG tag=latest - DO --pass-args core+SAVE_IMAGE --COMPONENT=operator-utils --TAG=$tag - -lint: - FROM core+builder-image - COPY (+sources/*) /src - COPY --pass-args +tidy/go.* . - WORKDIR /src/components/operator/tools/utils - DO --pass-args stack+GO_LINT - SAVE ARTIFACT cmd AS LOCAL cmd - -pre-commit: - WAIT - BUILD --pass-args +tidy - END - BUILD --pass-args +lint - -tidy: - FROM core+builder-image - COPY --pass-args (+sources/src) /src - WORKDIR /src/components/operator/tools/utils - DO --pass-args stack+GO_TIDY - -release: - BUILD --pass-args stack+goreleaser --path=components/operator/tools/utils \ No newline at end of file diff --git a/components/operator/tools/utils/LICENSE b/components/operator/tools/utils/LICENSE deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/components/operator/tools/utils/build.Dockerfile b/components/operator/tools/utils/build.Dockerfile deleted file mode 100644 index 1c6c7bc8c3..0000000000 --- a/components/operator/tools/utils/build.Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM ghcr.io/formancehq/base:22.04 -COPY operator-utils /usr/bin/operator-utils -ENV OTEL_SERVICE_NAME operator-utils -ENTRYPOINT ["/usr/bin/operator-utils"] diff --git a/components/operator/tools/utils/cmd/database-create.go b/components/operator/tools/utils/cmd/database-create.go deleted file mode 100644 index 790fea471a..0000000000 --- a/components/operator/tools/utils/cmd/database-create.go +++ /dev/null @@ -1,27 +0,0 @@ -package cmd - -import ( - "github.com/formancehq/go-libs/bun/bunconnect" - "github.com/formancehq/go-libs/bun/bunmigrate" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -func NewDatabaseCreateCommand() *cobra.Command { - ret := &cobra.Command{ - Use: "create", - Short: "Handle database creation", - RunE: func(cmd *cobra.Command, args []string) error { - connectionOptions, err := bunconnect.ConnectionOptionsFromFlags(cmd) - if err != nil { - return errors.Wrap(err, "resolving connection params") - } - - return errors.Wrap( - bunmigrate.EnsureDatabaseExists(cmd.Context(), *connectionOptions), - "ensuring database exists", - ) - }, - } - return ret -} diff --git a/components/operator/tools/utils/cmd/database-drop.go b/components/operator/tools/utils/cmd/database-drop.go deleted file mode 100644 index 8b041bfcfd..0000000000 --- a/components/operator/tools/utils/cmd/database-drop.go +++ /dev/null @@ -1,27 +0,0 @@ -package cmd - -import ( - "github.com/formancehq/go-libs/bun/bunconnect" - "github.com/formancehq/go-libs/bun/bunmigrate" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -func NewDatabaseDropCommand() *cobra.Command { - ret := &cobra.Command{ - Use: "drop", - Short: "Handle database dropping", - RunE: func(cmd *cobra.Command, args []string) error { - connectionOptions, err := bunconnect.ConnectionOptionsFromFlags(cmd) - if err != nil { - return errors.Wrap(err, "resolving connection params") - } - - return errors.Wrap( - bunmigrate.EnsureDatabaseNotExists(cmd.Context(), *connectionOptions), - "ensuring database does not exists", - ) - }, - } - return ret -} diff --git a/components/operator/tools/utils/cmd/database.go b/components/operator/tools/utils/cmd/database.go deleted file mode 100644 index 17c38a7ccf..0000000000 --- a/components/operator/tools/utils/cmd/database.go +++ /dev/null @@ -1,17 +0,0 @@ -package cmd - -import ( - "github.com/formancehq/go-libs/bun/bunconnect" - "github.com/spf13/cobra" -) - -func NewDatabaseCommand() *cobra.Command { - ret := &cobra.Command{ - Use: "db", - Short: "Handle databases operations", - } - ret.AddCommand(NewDatabaseCreateCommand(), NewDatabaseDropCommand()) - bunconnect.AddFlags(ret.PersistentFlags()) - - return ret -} diff --git a/components/operator/tools/utils/cmd/root.go b/components/operator/tools/utils/cmd/root.go deleted file mode 100644 index f74c08dbc0..0000000000 --- a/components/operator/tools/utils/cmd/root.go +++ /dev/null @@ -1,41 +0,0 @@ -package cmd - -import ( - "fmt" - logging "github.com/formancehq/go-libs/logging" - "os" - - "github.com/formancehq/go-libs/service" - - "github.com/spf13/cobra" -) - -var rootCmd = &cobra.Command{ - Use: "utils", - Short: "A cli for operator operations", - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - logger := logging.NewDefaultLogger(cmd.OutOrStdout(), service.IsDebug(cmd), false) - logger.Infof("Starting application") - logger.Debugf("Environment variables:") - for _, v := range os.Environ() { - logger.Debugf(v) - } - cmd.SetContext(logging.ContextWithLogger(cmd.Context(), logger)) - return nil - }, -} - -func Execute() { - err := rootCmd.Execute() - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} - -func init() { - rootCmd.AddCommand(NewDatabaseCommand()) - rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") - - service.AddFlags(rootCmd.PersistentFlags()) -} diff --git a/components/operator/tools/utils/go.mod b/components/operator/tools/utils/go.mod deleted file mode 100644 index cd34b560fe..0000000000 --- a/components/operator/tools/utils/go.mod +++ /dev/null @@ -1,79 +0,0 @@ -module github.com/formancehq/operator/utils - -go 1.22 - -toolchain go1.22.6 - -require ( - github.com/formancehq/go-libs v1.5.0 - github.com/pkg/errors v0.9.1 - github.com/spf13/cobra v1.8.1 -) - -require ( - filippo.io/edwards25519 v1.1.0 // indirect - github.com/ThreeDotsLabs/watermill v1.3.5 // indirect - github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect - github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.28 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect - github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.4.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 // indirect - github.com/aws/smithy-go v1.20.4 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-chi/chi/v5 v5.1.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-sql-driver/mysql v1.8.1 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/lib/pq v1.10.9 // indirect - github.com/lithammer/shortuuid/v3 v3.0.7 // indirect - github.com/oklog/ulid v1.3.1 // indirect - github.com/riandyrn/otelchi v0.9.0 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect - github.com/uptrace/bun v1.2.1 // indirect - github.com/uptrace/bun/dialect/pgdialect v1.2.1 // indirect - github.com/uptrace/bun/extra/bunotel v1.2.1 // indirect - github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.1 // indirect - github.com/uptrace/opentelemetry-go-extra/otelsql v0.2.4 // indirect - github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.1 // indirect - github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect - github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/xo/dburl v0.23.2 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.28.0 // indirect - go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 // indirect - go.opentelemetry.io/otel/log v0.3.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - go.opentelemetry.io/otel/sdk v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.uber.org/dig v1.18.0 // indirect - go.uber.org/fx v1.22.2 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect - google.golang.org/grpc v1.64.1 // indirect - google.golang.org/protobuf v1.34.2 // indirect -) diff --git a/components/operator/tools/utils/go.sum b/components/operator/tools/utils/go.sum deleted file mode 100644 index feca11c73b..0000000000 --- a/components/operator/tools/utils/go.sum +++ /dev/null @@ -1,212 +0,0 @@ -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/ThreeDotsLabs/watermill v1.3.5 h1:50JEPEhMGZQMh08ct0tfO1PsgMOAOhV3zxK2WofkbXg= -github.com/ThreeDotsLabs/watermill v1.3.5/go.mod h1:O/u/Ptyrk5MPTxSeWM5vzTtZcZfxXfO9PK9eXTYiFZY= -github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8= -github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= -github.com/aws/aws-sdk-go-v2/config v1.27.28 h1:OTxWGW/91C61QlneCtnD62NLb4W616/NM1jA8LhJqbg= -github.com/aws/aws-sdk-go-v2/config v1.27.28/go.mod h1:uzVRVtJSU5EFv6Fu82AoVFKozJi2ZCY6WRCXj06rbvs= -github.com/aws/aws-sdk-go-v2/credentials v1.17.28 h1:m8+AHY/ND8CMHJnPoH7PJIRakWGa4gbfbxuY9TGTUXM= -github.com/aws/aws-sdk-go-v2/credentials v1.17.28/go.mod h1:6TF7dSc78ehD1SL6KpRIPKMA1GyyWflIkjqg+qmf4+c= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 h1:yjwoSyDZF8Jth+mUk5lSPJCkMC0lMy6FaCD51jm6ayE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12/go.mod h1:fuR57fAgMk7ot3WcNQfb6rSEn+SUffl7ri+aa8uKysI= -github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.4.16 h1:ArEu0pWBXA14uzHKVdvAiutAwRV87pcGa/M3Y0faWx0= -github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.4.16/go.mod h1:2v2sY9K3hdtQB8kwpOFqrQGXt/azV+AG5lLXZY78IKg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.5/go.mod h1:ZeDX1SnKsVlejeuz41GiajjZpRSWR7/42q/EyA/QEiM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 h1:SKvPgvdvmiTWoi0GAJ7AsJfOz3ngVkD/ERbs5pUnHNI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5/go.mod h1:20sz31hv/WsPa3HhU3hfrIet2kxM4Pe0r20eBZ20Tac= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.4 h1:iAckBT2OeEK/kBDyN/jDtpEExhjeeA/Im2q4X0rJZT8= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.4/go.mod h1:vmSqFK+BVIwVpDAGZB3CoCXHzurt4qBE8lf+I/kRTh0= -github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= -github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= -github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/cli v26.1.4+incompatible h1:I8PHdc0MtxEADqYJZvhBrW9bo8gawKwwenxRM7/rLu8= -github.com/docker/cli v26.1.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI= -github.com/docker/docker v27.2.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/formancehq/go-libs v1.5.0 h1:jOVET378uquKvQBnSaS8ClLFbk7fB1Lhy4xM0+RK74o= -github.com/formancehq/go-libs v1.5.0/go.mod h1:rnvi4Au1DCNephaBEVzcv64BZEEksXiyKjwo/wHG51Y= -github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= -github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= -github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8= -github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= -github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opencontainers/runc v1.1.14 h1:rgSuzbmgz5DUJjeSnw337TxDbRuqjs6iqQck/2weR6w= -github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA= -github.com/ory/dockertest/v3 v3.11.0 h1:OiHcxKAvSDUwsEVh2BjxQQc/5EHz9n0va9awCtNGuyA= -github.com/ory/dockertest/v3 v3.11.0/go.mod h1:VIPxS1gwT9NpPOrfD3rACs8Y9Z7yhzO4SB194iUDnUI= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/riandyrn/otelchi v0.9.0 h1:BuQxXR7/JF2yYOQl21Yyz5d52hns/96ecAaPUZiKQzc= -github.com/riandyrn/otelchi v0.9.0/go.mod h1:iX30kllzThsf8oEcEbl3GifPJZtN4cnCWUUc+UhE4yM= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= -github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= -github.com/uptrace/bun v1.2.1 h1:2ENAcfeCfaY5+2e7z5pXrzFKy3vS8VXvkCag6N2Yzfk= -github.com/uptrace/bun v1.2.1/go.mod h1:cNg+pWBUMmJ8rHnETgf65CEvn3aIKErrwOD6IA8e+Ec= -github.com/uptrace/bun/dialect/pgdialect v1.2.1 h1:ceP99r03u+s8ylaDE/RzgcajwGiC76Jz3nS2ZgyPQ4M= -github.com/uptrace/bun/dialect/pgdialect v1.2.1/go.mod h1:mv6B12cisvSc6bwKm9q9wcrr26awkZK8QXM+nso9n2U= -github.com/uptrace/bun/extra/bunotel v1.2.1 h1:5oTy3Jh7Q1bhCd5vnPszBmJgYouw+PuuZ8iSCm+uNCQ= -github.com/uptrace/bun/extra/bunotel v1.2.1/go.mod h1:SWW3HyjiXPYM36q0QSpdtTP8v21nWHnTCxu4lYkpO90= -github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.1 h1:sApVqiPa+lFhsIzREHhSOH2WctSNYaSet1dBC6L1OcM= -github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.1/go.mod h1:y5+uFBQU6m6ZUexR31pR0OTYDCrJ735Du/y3aAuYlzs= -github.com/uptrace/opentelemetry-go-extra/otelsql v0.2.4 h1:x3omFAG2XkvWFg1hvXRinY2ExAL1Aacl7W9ZlYjo6gc= -github.com/uptrace/opentelemetry-go-extra/otelsql v0.2.4/go.mod h1:qMKJr5fTnY0p7hqCQMNrAk62bCARWR5rAbTrGUFRuh4= -github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.1 h1:Suvl9fe12MM0oi8/rcGxlGd7XawNQawU369aHzZFFec= -github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.1/go.mod h1:aiX/F5+EYbY2ed2OQEYRXzMcNGvI9pip5gW2ZtBDers= -github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= -github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xo/dburl v0.23.2 h1:Fl88cvayrgE56JA/sqhNMLljCW/b7RmG1mMkKMZUFgA= -github.com/xo/dburl v0.23.2/go.mod h1:uazlaAQxj4gkshhfuuYyvwCBouOmNnG2aDxTCFZpmL4= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/contrib/propagators/b3 v1.28.0 h1:XR6CFQrQ/ttAYmTBX2loUEFGdk1h17pxYI8828dk/1Y= -go.opentelemetry.io/contrib/propagators/b3 v1.28.0/go.mod h1:DWRkzJONLquRz7OJPh2rRbZ7MugQj62rk7g6HRnEqh0= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 h1:EVSnY9JbEEW92bEkIYOVMw4q1WJxIAGoFTrtYOzWuRQ= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0/go.mod h1:Ea1N1QQryNXpCD0I1fdLibBAIpQuBkznMmkdKrapk1Y= -go.opentelemetry.io/otel/log v0.3.0 h1:kJRFkpUFYtny37NQzL386WbznUByZx186DpEMKhEGZs= -go.opentelemetry.io/otel/log v0.3.0/go.mod h1:ziCwqZr9soYDwGNbIL+6kAvQC+ANvjgG367HVcyR/ys= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= -go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= -go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= -go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= -google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/components/operator/tools/utils/main.go b/components/operator/tools/utils/main.go deleted file mode 100644 index d5694169dd..0000000000 --- a/components/operator/tools/utils/main.go +++ /dev/null @@ -1,11 +0,0 @@ -/* -Copyright © 2024 NAME HERE - -*/ -package main - -import "github.com/formancehq/operator/utils/cmd" - -func main() { - cmd.Execute() -} diff --git a/components/operator/tools/utils/scratch.Dockerfile b/components/operator/tools/utils/scratch.Dockerfile deleted file mode 100644 index 10b8b83018..0000000000 --- a/components/operator/tools/utils/scratch.Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM ghcr.io/formancehq/base:scratch -COPY operator-utils /usr/bin/operator-utils -ENV OTEL_SERVICE_NAME operator-utils -ENTRYPOINT ["/usr/bin/operator-utils"] diff --git a/ee/Earthfile b/ee/Earthfile deleted file mode 100644 index a154eaa1aa..0000000000 --- a/ee/Earthfile +++ /dev/null @@ -1,23 +0,0 @@ -VERSION 0.8 - -IMPORT github.com/formancehq/earthly:tags/v0.15.0 AS core -IMPORT .. AS stack - -deploy: - FROM core+base-image - ARG --required components - BUILD --pass-args ./$components+deploy - -deploy-staging: - FROM core+base-image - ARG --required components - BUILD --pass-args ./$components+deploy-staging - -run: - LOCALLY - ARG --required TARGET - BUILD ./agent+$TARGET - BUILD ./orchestration+$TARGET - BUILD ./reconciliation+$TARGET - BUILD ./wallets+$TARGET - \ No newline at end of file diff --git a/ee/LICENSE b/ee/LICENSE deleted file mode 100644 index 3421b159e6..0000000000 --- a/ee/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -This **Formance Enterprise Edition (EE) supplemental license (this “EE Supplemental License”)** governs the use of this software and documentation (collectively, the “EE Software”) by you and any entity you represent (collectively, “You”). If You have separately entered into the Formance, Inc. Enterprise Agreement (the “Enterprise Agreement”), then this EE Supplemental License hereby incorporates by reference the Enterprise Agreement and modifies the Enterprise Agreement solely to the extent set forth herein. If You have separately entered into the Formance, Inc. Subscription Agreement (the “Subscription Agreement”), then this EE Supplemental License hereby incorporates by reference the Agreement and modifies the Subscription Agreement solely to the extent set forth herein. If You have not entered into either the Enterprise Agreement or the Subscription Agreement, then You may use the EE Software solely as set forth in Section 2 below. - -In the event of a direct conflict between the terms of this EE Supplemental License and the terms of the Enterprise Agreement or the Subscription Agreement, as applicable, the terms of this EE Supplemental License will control. Except to the extent modified by this EE Supplemental License, the Enterprise Agreement or the Subscription Agreement, as applicable, remain in full force and effect in accordance with its terms. - -**By using the EE Software, You hereby agree to the below terms and conditions.** - -1. Notwithstanding any terms to the contrary in the Enterprise Agreement or Subscription Agreement, You may copy, modify and publish patches to the EE Software in a production environment (such copies, “Production Copies,” such modifications, “Production Modifications” and such patches, “Production Patches”) if and only if (a) You have agreed to, and are in full compliance with, the Enterprise Agreement or Subscription Agreement, as applicable, and (b) You have a valid license to the EE Software for the correct number of projects. You agree that Formance and/or its licensors (as applicable) will own all right, title and interest in and to all such Production Copies, Production Modifications and Production Patches. You may display and/or distribute such Production Copies, Production Modifications and Production Patches if and only if (i) You have a valid license to the EE Software for the correct number of projects and (ii) You are in compliance with the Enterprise Agreement or Subscription Agreement, as applicable. You hereby assign to Formance all right, title and interest in and to all Production Copies, Production Modifications and Production Patches, including all intellectual property rights embodied in or related to the foregoing. - -2. Notwithstanding the foregoing, You may copy and modify the EE Software solely for development and testing purposes (such copies, “Development Copies” and such modifications, “Development Modifications”) **with or without a license to the EE Software if your use is in compliance with this Section 2**. You agree that Formance and/or its licensors (as applicable) will own all right, title and interest in and to all Development Copies and Development Modifications and You hereby assign to Formance all right, title and interest in and to all Development Copies and Development Modifications, including all intellectual property rights embodied in or related to the foregoing. If You do not have a license to the EE Software, then You further agree as follows: - -**Other than as expressly set forth in this Section 2, You may not** (a) copy or modify the EE Software, (b) create derivative works of the EE Software, (c) remove or modify any notice of any patent, copyright, trademark, or other proprietary rights that appear on or in the EE Software, (d) reverse engineer, decompile, translate, disassemble, or discover the source code of all or any portion of the EE Software, (e) publicly display all or any part of the EE Software, (f) distribute, disclose, market, lease, publish, merge, resell, assign, loan, sublicense, rent, or transfer the EE Software to any third party, (g) use the EE Software for any dial-up, remote access, interactive, or other on-line or hosted service, or to provide a service bureau, time share, or other services to third parties, (h) merge the EE Software into another product, (i) disclose the results of any EE Software performance benchmarks or test results to any third party without Formance’s prior written consent, (j) use any trademarks, logos, service marks, trade names of Formance, or any portion thereof, without Formance’s prior written consent, (k) use the EE Software, or any portion thereof, in a manner that does not comply with applicable law, regulations, or governmental orders, or (l) use or store the EE Software on equipment not owned or controlled by Customer. - -THE EE SOFTWARE IS PROVIDED ON AN “AS IS” BASIS WITHOUT ANY REPRESENTATIONS, WARRANTIES, COVENANTS, OR CONDITIONS OF ANY KIND (EXPRESS OR IMPLIED, STATUTORY OR OTHERWISE), INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, TITLE, FITNESS FOR A PARTICULAR PURPOSE, OR NONINFRINGEMENT.  FURTHER, FORMANCE DOES NOT REPRESENT OR WARRANT THAT (A) THE ACCESS TO OR USE OF THE EE SOFTWARE WILL BE SECURE, TIMELY, UNINTERRUPTED, ERROR-FREE, OR OPERATE IN COMBINATION WITH ANY OTHER HARDWARE, SOFTWARE, SYSTEM, OR DATA, (B) THE EE SOFTWARE WILL MEET YOUR REQUIREMENTS OR EXPECTATIONS, OR OTHERWISE PRODUCE ANY PARTICULAR RESULTS, (C) ERRORS OR DEFECTS WILL BE CORRECTED, PATCHES OR WORKAROUNDS WILL BE PROVIDED, OR FORMANCE WILL DETECT ANY BUG IN THE EE SOFTWARE, (D) THE SOFTWARE IS FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS, OR (E) THIRD-PARTY DISRUPTIONS OR SECURITY BREACHES OF THE EE SOFTWARE WILL BE PREVENTED. - -FORMANCE WILL NOT BE LIABLE FOR ANY LOSS OF PROFITS OR ANY INDIRECT, SPECIAL, INCIDENTAL, RELIANCE, OR CONSEQUENTIAL DAMAGES OF ANY KIND, REGARDLESS OF THE FORM OF ACTION, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY, OR OTHERWISE, EVEN IF INFORMED OF THE POSSIBILITY OF SUCH DAMAGES IN ADVANCE. - -FORMANCE’S ENTIRE LIABILITY TO YOU FOR USE OF THE EE SOFTWARE WILL NOT EXCEED $100. - -3. You are not granted any other rights beyond what is expressly stated herein and in the Enterprise Agreement or Subscription Agreement, as applicable. - -4. This EE Supplemental License does not apply to Formance software that is distributed as part of the Formance Community Edition (CE) (the “CE Software”). \ No newline at end of file diff --git a/ee/agent/.earthly/values.yaml b/ee/agent/.earthly/values.yaml deleted file mode 100644 index f87c84dc41..0000000000 --- a/ee/agent/.earthly/values.yaml +++ /dev/null @@ -1,30 +0,0 @@ -global: - monitoring: - traces: - enabled: true - mode: grpc - exporter: otlp - endpoint: otel-collector-opentelemetry-collector.formance.svc.cluster.local - port: 4317 - insecure: true - logs: - format: "" -image: - pullPolicy: Always - -debug: true - -server: - address: "" - tls: - enabled: true - insecureSkipVerify: true - -agent: - id: "b7549a16-f74a-4815-ab1e-bb8ef1c3833b" - baseUrl: "" - production: true - # Authentication token - authentication: - mode: token - token: abcd diff --git a/ee/agent/.goreleaser.yml b/ee/agent/.goreleaser.yml deleted file mode 100644 index e44fc11bfe..0000000000 --- a/ee/agent/.goreleaser.yml +++ /dev/null @@ -1,37 +0,0 @@ -project_name: agent -includes: - - from_file: - path: ./../../.goreleaser.default.yaml -monorepo: - tag_prefix: v - dir: ./ - -builds: - - binary: agent - id: agent - ldflags: - - -X github.com/formancehq/stack/components/agent/cmd.BuildDate={{ .Date }} - - -X github.com/formancehq/stack/components/agent/cmd.Version=v{{ .Version }} - - -X github.com/formancehq/stack/components/agent/cmd.Commit={{ .ShortCommit }} - - -extldflags "-static" - env: - - CGO_ENABLED=0 - goos: - - linux - goarch: - - amd64 - - arm64 - -archives: - - id: "{{.ProjectName}}" - builds: - - agent - format: tar.gz - name_template: "{{.ProjectName}}_{{.Os}}-{{.Arch}}" - -release: - prerelease: auto - footer: | - ## What to do next? - - Read the [documentation](https://docs.formance.com/) - - Join our [Slack server](https://formance.com/slack) diff --git a/ee/agent/Earthfile b/ee/agent/Earthfile deleted file mode 100644 index f49888230c..0000000000 --- a/ee/agent/Earthfile +++ /dev/null @@ -1,156 +0,0 @@ -VERSION 0.8 - -IMPORT github.com/formancehq/earthly:tags/v0.15.0 AS core - -IMPORT ../.. AS stack -IMPORT ../../helm/libs AS helm-libs -IMPORT .. AS ee - -FROM core+base-image - -sources: - WORKDIR src - COPY (../../components/operator+sources/*) /src - WORKDIR /src/ee/agent - COPY go.* . - COPY --dir cmd internal tests . - COPY main.go . - SAVE ARTIFACT /src - -compile: - FROM core+builder-image - COPY (+sources/*) /src - WORKDIR /src/ee/agent - ARG VERSION=latest - DO --pass-args core+GO_COMPILE --VERSION=$VERSION - -build-image: - FROM core+final-image - ENTRYPOINT ["/bin/agent"] - COPY (+compile/main) /bin/agent - ARG REPOSITORY=ghcr.io - ARG tag=latest - DO core+SAVE_IMAGE --COMPONENT=agent --REPOSITORY=${REPOSITORY} --TAG=$tag - -lint: - FROM core+builder-image - COPY (+sources/*) /src - COPY --pass-args +tidy/go.* . - WORKDIR /src/ee/agent - DO --pass-args stack+GO_LINT - SAVE ARTIFACT cmd AS LOCAL cmd - SAVE ARTIFACT internal AS LOCAL internal - SAVE ARTIFACT main.go AS LOCAL main.go - -deploy: - COPY (+sources/*) /src - LET tag=$(tar cf - /src | sha1sum | awk '{print $1}') - WAIT - BUILD --pass-args +build-image --tag=$tag - END - FROM --pass-args core+vcluster-deployer-image - COPY helm helm - COPY .earthly .earthly - ARG --required user - RUN --secret tld helm upgrade --namespace formance-system \ - --create-namespace \ - --install \ - -f .earthly/values.yaml \ - --set image.tag=$tag \ - --set agent.baseUrl=https://$user.$tld \ - --set server.address=$user.$tld:443 \ - formance-membership-agent ./helm - -deploy-staging: - FROM --pass-args core+base-argocd - - ARG --required TAG - - ARG APPLICATION=staging-eu-west-1-hosting-regions - LET SERVER=argocd.internal.formance.cloud - - RUN --secret AUTH_TOKEN \ - argocd app set $APPLICATION \ - --parameter agent.image.tag=$TAG \ - --auth-token=$AUTH_TOKEN --server=$SERVER --grpc-web - - BUILD --pass-args core+deploy-staging - -pre-commit: - BUILD --pass-args +helm-validate - WAIT - BUILD --pass-args +tidy - END - BUILD --pass-args +lint - - -openapi: - RUN echo "not implemented" - -tidy: - FROM core+builder-image - COPY --pass-args (+sources/src) /src - WORKDIR /src/ee/agent - DO --pass-args stack+GO_TIDY - -generate: - FROM core+builder-image - DO --pass-args core+GO_INSTALL --package=go.uber.org/mock/mockgen@latest - COPY (+sources/*) /src - WORKDIR /src/ee/agent - RUN go generate -run mockgen ./... - SAVE ARTIFACT internal AS LOCAL internal - - -grpc-generate: - FROM core+grpc-base - LET protoName=agent.proto - COPY $protoName . - DO core+GRPC_GEN --protoName=$protoName - SAVE ARTIFACT generated AS LOCAL internal/generated - -tests: - FROM core+builder-image - RUN apk update && apk add bash - DO --pass-args core+GO_INSTALL --package=sigs.k8s.io/controller-runtime/tools/setup-envtest@v0.0.0-20240320141353-395cfc7486e6 - ENV ENVTEST_VERSION 1.28.0 - RUN setup-envtest use $ENVTEST_VERSION -p path - ENV KUBEBUILDER_ASSETS /root/.local/share/kubebuilder-envtest/k8s/$ENVTEST_VERSION-linux-$(go env GOHOSTARCH) - DO --pass-args core+GO_INSTALL --package=github.com/onsi/ginkgo/v2/ginkgo@v2.14.0 - COPY --pass-args +sources/* /src - COPY --pass-args ../../components/operator+manifests/config /src/components/operator/config - WORKDIR /src/ee/agent - COPY tests tests - COPY internal internal - ARG GOPROXY - ARG focus - - RUN --mount=type=cache,id=gomod,target=$GOPATH/pkg/mod \ - --mount=type=cache,id=gobuild,target=/root/.cache/go-build \ - go test ./internal/... - - RUN --mount=type=cache,id=gomod,target=$GOPATH/pkg/mod \ - --mount=type=cache,id=gobuild,target=/root/.cache/go-build \ - ginkgo --focus=$focus -p ./tests/... - -helm-validate: - FROM core+helm-base - WORKDIR /src - - COPY (helm-libs+sources/*) helm/libs/ - COPY --dir helm ee/agent/ - - WORKDIR /src/ee/agent/helm - RUN helm dependencies update - DO --pass-args core+HELM_VALIDATE - SAVE ARTIFACT /src/ee/agent/helm AS LOCAL helm - -helm-package: - FROM +helm-validate - RUN helm package . - SAVE ARTIFACT /src - - SAVE ARTIFACT . AS LOCAL helm - -release: - BUILD --pass-args stack+goreleaser --path=ee/agent \ No newline at end of file diff --git a/ee/agent/Taskfile.yaml b/ee/agent/Taskfile.yaml deleted file mode 100644 index a8d576919b..0000000000 --- a/ee/agent/Taskfile.yaml +++ /dev/null @@ -1,25 +0,0 @@ -version: '3' - -vars: - COMPONENT: - sh: cat go.mod |head -1|cut -d \ -f2|cut -d / -f 3 - -tasks: - tests: - cmds: - - go test -p 1 -coverpkg ./... -coverprofile coverage.out -covermode atomic ./... - lint: - cmds: - - golangci-lint run --fix --allow-parallel-runners --config ./../../.golangci.yml - build: - cmds: - - go build - - helm: - cmds: - - echo "ok" - - generate-client: - cmds: - - go generate - diff --git a/ee/agent/agent.proto b/ee/agent/agent.proto deleted file mode 100644 index 5e517f4ec2..0000000000 --- a/ee/agent/agent.proto +++ /dev/null @@ -1,144 +0,0 @@ -syntax = "proto3"; - -import "google/protobuf/struct.proto"; - -option go_package = "github.com/formancehq/membership/internal/grpc/generated"; - -package server; - -service Server { - rpc Connect(ConnectRequest) returns (stream Order) {} - rpc Join(stream Message) returns (stream Order) {} -} - -message ConnectRequest { - string id = 1; - map tags = 2; - string baseUrl = 3; - bool production = 4; -} - -message Order { - reserved 5; - oneof message { - Connected connected = 1; - Stack existingStack = 2; - DeletedStack deletedStack = 3; - Ping ping = 4; - DisabledStack disabledStack = 6; - EnabledStack enabledStack = 7; - } -} - -message Message { - oneof message { - StatusChanged statusChanged = 1; - Pong pong = 2; - - AddedVersion addedVersion = 3; - DeletedVersion deletedVersion = 4; - UpdatedVersion updatedVersion = 5; - - ModuleStatusChanged moduleStatusChanged = 6; - ModuleDeleted moduleDeleted = 7; - - DeletedStack stackDeleted = 8; - } -} - -message Connected {} - -message Ping {} - -message Pong {} - -message Stack { - string clusterName = 1; - string seed = 2; - AuthConfig authConfig = 3; - repeated AuthClient staticClients = 4; - StargateConfig stargateConfig = 5; - bool disabled = 6; - reserved 7; - string versions = 8; - bool enableAudit = 9; - map additionalLabels = 10; - map additionalAnnotations = 11; - repeated Module modules = 12; -} - -message Module { - string name = 1; -} - -enum StackStatus { - Progressing = 0; - Ready = 1; - Deleted = 2; - Disabled = 3; -} - -message VersionKind { - string version = 1; - string kind = 2; -} - -message ModuleStatusChanged { - string clusterName = 1; - google.protobuf.Struct status = 2; - VersionKind vk = 3; -} - -message ModuleDeleted { - string clusterName = 1; - VersionKind vk = 2; -} - -message StatusChanged { - string clusterName = 1; - StackStatus status = 2; - google.protobuf.Struct statuses = 3; - VersionKind vk = 4; -} - -message StargateConfig { - bool enabled = 1; - string url = 2; -} - -message DeletedStack { - string clusterName = 1; -} - -message DisabledStack { - string clusterName = 1; -} - -message EnabledStack { - string clusterName = 1; -} - -message AuthConfig { - string clientId = 1; - string clientSecret = 2; - string issuer = 3; -} - -message AuthClient { - bool public = 1; - string id = 2; -} - -message AddedVersion { - string name = 1; - map versions = 2; -} - -message UpdatedVersion { - string name = 1; - map versions = 2; -} - -message DeletedVersion { - string name = 1; -} \ No newline at end of file diff --git a/ee/agent/build.Dockerfile b/ee/agent/build.Dockerfile deleted file mode 100644 index 32807c0f5e..0000000000 --- a/ee/agent/build.Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM ghcr.io/formancehq/base:22.04 -COPY agent /usr/bin/agent -ENV OTEL_SERVICE_NAME agent -ENTRYPOINT ["/usr/bin/agent"] diff --git a/ee/agent/cmd/root.go b/ee/agent/cmd/root.go deleted file mode 100644 index e8f60e6972..0000000000 --- a/ee/agent/cmd/root.go +++ /dev/null @@ -1,206 +0,0 @@ -package cmd - -import ( - "crypto/tls" - "crypto/x509" - "fmt" - "net/url" - "path/filepath" - "time" - - "github.com/formancehq/go-libs/licence" - sharedlogging "github.com/formancehq/go-libs/logging" - "github.com/formancehq/go-libs/otlp/otlptraces" - "github.com/formancehq/go-libs/service" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/stack/components/agent/internal" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "go.uber.org/fx" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/credentials/insecure" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/util/homedir" -) - -var ( - ServiceName = "agent" - Version = "develop" - BuildDate = "-" - Commit = "-" -) - -const ( - kubeConfigFlag = "kube-config" - serverAddressFlag = "server-address" - tlsEnabledFlag = "tls-enabled" - tlsInsecureSkipVerifyFlag = "tls-insecure-skip-verify" - tlsCACertificateFlag = "tls-ca-cert" - idFlag = "id" - authenticationModeFlag = "authentication-mode" - authenticationTokenFlag = "authentication-token" - authenticationIssuerFlag = "authentication-issuer" - authenticationClientSecretFlag = "authentication-client-secret" - baseUrlFlag = "base-url" - productionFlag = "production" - resyncPeriodFlag = "resync-period" -) - -var rootCmd = &cobra.Command{ - SilenceUsage: true, - RunE: runAgent, -} - -func init() { - if err := v1beta1.AddToScheme(scheme.Scheme); err != nil { - panic(err) - } - - var kubeConfigFilePath string - if home := homedir.HomeDir(); home != "" { - kubeConfigFilePath = filepath.Join(home, ".kube", "config") - } - - service.AddFlags(rootCmd.PersistentFlags()) - otlptraces.AddFlags(rootCmd.PersistentFlags()) - licence.AddFlags(rootCmd.PersistentFlags()) - - rootCmd.Flags().String(kubeConfigFlag, kubeConfigFilePath, "") - rootCmd.Flags().String(serverAddressFlag, "localhost:8081", "") - rootCmd.Flags().Bool(tlsEnabledFlag, false, "") - rootCmd.Flags().Bool(tlsInsecureSkipVerifyFlag, false, "") - rootCmd.Flags().String(tlsCACertificateFlag, "", "") - rootCmd.Flags().String(idFlag, "", "") - rootCmd.Flags().String(authenticationModeFlag, "", "") - rootCmd.Flags().String(authenticationTokenFlag, "", "") - rootCmd.Flags().String(authenticationClientSecretFlag, "", "") - rootCmd.Flags().String(authenticationIssuerFlag, "", "") - rootCmd.Flags().String(baseUrlFlag, "", "") - rootCmd.Flags().Bool(productionFlag, false, "Is a production agent") - rootCmd.Flags().Duration(resyncPeriodFlag, 5*time.Minute, "Resync period of K8S resources") - rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") -} - -func Execute() { - service.Execute(rootCmd) -} - -func runAgent(cmd *cobra.Command, _ []string) error { - serverAddress, _ := cmd.Flags().GetString(serverAddressFlag) - if serverAddress == "" { - return errors.New("missing server address") - } - - agentID, _ := cmd.Flags().GetString(idFlag) - if agentID == "" { - return errors.New("missing id") - } - - credentials, err := createGRPCTransportCredentials(cmd) - if err != nil { - return err - } - - dialOptions := make([]grpc.DialOption, 0) - dialOptions = append(dialOptions, grpc.WithTransportCredentials(credentials)) - - baseUrlString, _ := cmd.Flags().GetString(baseUrlFlag) - if baseUrlString == "" { - return errors.New("missing base url") - } - - baseUrl, err := url.Parse(baseUrlString) - if err != nil { - return err - } - - authenticator, err := createAuthenticator(cmd) - if err != nil { - return err - } - - kubeConfig, _ := cmd.Flags().GetString(kubeConfigFlag) - - restConfig, err := internal.NewK8SConfig(kubeConfig) - if err != nil { - return err - } - - isProduction, _ := cmd.Flags().GetBool(productionFlag) - resyncPeriod, _ := cmd.Flags().GetDuration(resyncPeriodFlag) - - options := []fx.Option{ - fx.Supply(restConfig), - fx.NopLogger, - internal.NewModule(serverAddress, authenticator, internal.ClientInfo{ - ID: agentID, - BaseUrl: baseUrl, - Production: isProduction, - Version: Version, - }, resyncPeriod, dialOptions...), - otlptraces.FXModuleFromFlags(cmd), - licence.FXModuleFromFlags(cmd, ServiceName), - } - - return service.New(cmd.OutOrStdout(), options...).Run(cmd) -} - -func createAuthenticator(cmd *cobra.Command) (internal.Authenticator, error) { - var authenticator internal.Authenticator - authenticationMode, _ := cmd.Flags().GetString(authenticationModeFlag) - agentID, _ := cmd.Flags().GetString(idFlag) - - switch authenticationMode { - case "token": - - token, _ := cmd.Flags().GetString(authenticationTokenFlag) - if token == "" { - return nil, errors.New("missing authentication token") - } - authenticator = internal.TokenAuthenticator(token) - case "bearer": - clientSecret, _ := cmd.Flags().GetString(authenticationClientSecretFlag) - if clientSecret == "" { - return nil, errors.New("missing client secret") - } - issuer, _ := cmd.Flags().GetString(authenticationIssuerFlag) - if issuer == "" { - return nil, errors.New("missing issuer") - } - - authenticator = internal.BearerAuthenticator(issuer, agentID, clientSecret) - default: - return nil, errors.New("authentication mode not specified") - } - return authenticator, nil -} - -func createGRPCTransportCredentials(cmd *cobra.Command) (credentials.TransportCredentials, error) { - var credential credentials.TransportCredentials - tlsEnabled, _ := cmd.Flags().GetBool(tlsEnabledFlag) - if !tlsEnabled { - sharedlogging.FromContext(cmd.Context()).Infof("TLS not enabled") - credential = insecure.NewCredentials() - } else { - sharedlogging.FromContext(cmd.Context()).Infof("TLS enabled") - certPool := x509.NewCertPool() - ca, _ := cmd.Flags().GetString(tlsCACertificateFlag) - if ca != "" { - sharedlogging.FromContext(cmd.Context()).Infof("Load server certificate from config") - if !certPool.AppendCertsFromPEM([]byte(ca)) { - return nil, fmt.Errorf("failed to add server CA's certificate") - } - } - - tlsInsecure, _ := cmd.Flags().GetBool(tlsInsecureSkipVerifyFlag) - if tlsInsecure { - sharedlogging.FromContext(cmd.Context()).Infof("Disable certificate checks") - } - credential = credentials.NewTLS(&tls.Config{ - InsecureSkipVerify: tlsInsecure, - RootCAs: certPool, - }) - } - return credential, nil -} diff --git a/ee/agent/cmd/version.go b/ee/agent/cmd/version.go deleted file mode 100644 index 13e1d8989f..0000000000 --- a/ee/agent/cmd/version.go +++ /dev/null @@ -1,21 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -var versionCmd = &cobra.Command{ - Use: "version", - Short: "Get version", - Run: func(cmd *cobra.Command, args []string) { - fmt.Printf("Version: %s \n", Version) - fmt.Printf("Date: %s \n", BuildDate) - fmt.Printf("Commit: %s \n", Commit) - }, -} - -func init() { - rootCmd.AddCommand(versionCmd) -} diff --git a/ee/agent/go.mod b/ee/agent/go.mod deleted file mode 100644 index ada86304cd..0000000000 --- a/ee/agent/go.mod +++ /dev/null @@ -1,123 +0,0 @@ -module github.com/formancehq/stack/components/agent - -go 1.22.0 - -toolchain go1.22.7 - -require ( - github.com/alitto/pond v1.8.3 - github.com/formancehq/go-libs v1.7.1 - github.com/formancehq/operator v0.0.0-00010101000000-000000000000 - github.com/google/uuid v1.6.0 - github.com/joho/godotenv v1.5.1 - github.com/onsi/ginkgo/v2 v2.20.2 - github.com/onsi/gomega v1.34.2 - github.com/pkg/errors v0.9.1 - github.com/spf13/cobra v1.8.1 - github.com/stretchr/testify v1.9.0 - github.com/zitadel/oidc/v2 v2.12.2 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 - go.opentelemetry.io/otel v1.30.0 - go.opentelemetry.io/otel/trace v1.30.0 - go.uber.org/fx v1.22.2 - go.uber.org/mock v0.4.0 - golang.org/x/oauth2 v0.23.0 - google.golang.org/grpc v1.67.0 - google.golang.org/protobuf v1.34.2 - k8s.io/apiextensions-apiserver v0.29.0 - k8s.io/apimachinery v0.29.0 - k8s.io/client-go v0.29.0 - sigs.k8s.io/controller-runtime v0.17.1 -) - -require ( - github.com/ThreeDotsLabs/watermill v1.3.7 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch/v5 v5.8.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-chi/chi/v5 v5.1.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.20.2 // indirect - github.com/go-openapi/jsonreference v0.20.4 // indirect - github.com/go-openapi/swag v0.22.6 // indirect - github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/goccy/go-json v0.10.3 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v5 v5.2.1 // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 // indirect - github.com/gorilla/schema v1.4.1 // indirect - github.com/gorilla/securecookie v1.1.2 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect - github.com/lestrrat-go/blackmagic v1.0.2 // indirect - github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/jwx v1.2.30 // indirect - github.com/lestrrat-go/option v1.0.1 // indirect - github.com/lithammer/shortuuid/v3 v3.0.7 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/muhlemmer/gu v0.3.1 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/oklog/ulid v1.3.1 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/riandyrn/otelchi v0.10.0 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2 // indirect - github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0 // indirect - go.opentelemetry.io/otel/log v0.6.0 // indirect - go.opentelemetry.io/otel/metric v1.30.0 // indirect - go.opentelemetry.io/otel/sdk v1.30.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.uber.org/dig v1.18.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/mod v0.21.0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.25.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/square/go-jose.v2 v2.6.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.29.0 // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20231214164306-ab13479f8bf8 // indirect - k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect -) - -replace ( - github.com/formancehq/membership-api/client => ./client - github.com/formancehq/operator => ./../../components/operator - github.com/zitadel/oidc/v2 => github.com/formancehq/oidc/v2 v2.0.0-20230524073911-09bdd1dca291 - k8s.io/client-go v0.26.0 => k8s.io/client-go v0.25.4 -) diff --git a/ee/agent/go.sum b/ee/agent/go.sum deleted file mode 100644 index c09d3eb664..0000000000 --- a/ee/agent/go.sum +++ /dev/null @@ -1,302 +0,0 @@ -github.com/ThreeDotsLabs/watermill v1.3.7 h1:NV0PSTmuACVEOV4dMxRnmGXrmbz8U83LENOvpHekN7o= -github.com/ThreeDotsLabs/watermill v1.3.7/go.mod h1:lBnrLbxOjeMRgcJbv+UiZr8Ylz8RkJ4m6i/VN/Nk+to= -github.com/alitto/pond v1.8.3 h1:ydIqygCLVPqIX/USe5EaV/aSRXTRXDEI9JwuDdu+/xs= -github.com/alitto/pond v1.8.3/go.mod h1:CmvIIGd5jKLasGI3D87qDkQxjzChdKMmnXMg3fG6M6Q= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= -github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/formancehq/go-libs v1.7.1 h1:9D5cxKWFlVtdX5AYDXeUz1Nb9PdoEfQX0f/yeLsU324= -github.com/formancehq/go-libs v1.7.1/go.mod h1:pWTScpoyieF7OoJ6WVmXNG9NhDjbZbAmFqd7UOw85iI= -github.com/formancehq/oidc/v2 v2.0.0-20230524073911-09bdd1dca291 h1:wr0F5Vst5P2ghA3PnuLjg1u+USAdf/3OlIe21w5rgLM= -github.com/formancehq/oidc/v2 v2.0.0-20230524073911-09bdd1dca291/go.mod h1:vsFNrYCj2x0it0pYmIRVZ12HJ1VGaMVyGl7HLqw5p+Y= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= -github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= -github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= -github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= -github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= -github.com/go-openapi/swag v0.22.6 h1:dnqg1XfHXL9aBxSbktBqFR5CxVyVI+7fYWhAf1JOeTw= -github.com/go-openapi/swag v0.22.6/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= -github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= -github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 h1:c5FlPPgxOn7kJz3VoPLkQYQXGBS3EklQ4Zfi57uOuqQ= -github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= -github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= -github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= -github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= -github.com/jeremija/gosubmit v0.2.7/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= -github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= -github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= -github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= -github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.30 h1:VKIFrmjYn0z2J51iLPadqoHIVLzvWNa1kCsTqNDHYPA= -github.com/lestrrat-go/jwx v1.2.30/go.mod h1:vMxrwFhunGZ3qddmfmEm2+uced8MSI6QFWGTKygjSzQ= -github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= -github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8= -github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/muhlemmer/gu v0.3.1 h1:7EAqmFrW7n3hETvuAdmFmn4hS8W+z3LgKtrnow+YzNM= -github.com/muhlemmer/gu v0.3.1/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZkrdM= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= -github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= -github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= -github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= -github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/riandyrn/otelchi v0.10.0 h1:QMbR/FMDWBOkej6dfyWteYefUKqIFxnyrpaoWRJ9RPQ= -github.com/riandyrn/otelchi v0.10.0/go.mod h1:zBaX2FavWMlsvq4GqHit+QXxF1c5wIMZZFaYyW4+7FA= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= -github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2 h1:H8wwQwTe5sL6x30z71lUgNiwBdeCHQjrphCfLwqIHGo= -github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2/go.mod h1:/kR4beFhlz2g+V5ik8jW+3PMiMQAPt29y6K64NNY53c= -github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 h1:3/aHKUq7qaFMWxyQV0W2ryNgg8x8rVeKVA20KJUkfS0= -github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2/go.mod h1:Zit4b8AQXaXvA68+nzmbyDzqiyFRISyw1JiD5JqUBjw= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI= -go.opentelemetry.io/contrib/propagators/b3 v1.30.0 h1:vumy4r1KMyaoQRltX7cJ37p3nluzALX9nugCjNNefuY= -go.opentelemetry.io/contrib/propagators/b3 v1.30.0/go.mod h1:fRbvRsaeVZ82LIl3u0rIvusIel2UUf+JcaaIpy5taho= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 h1:umZgi92IyxfXd/l4kaDhnKgY8rnN/cZcF1LKc6I8OQ8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0/go.mod h1:4lVs6obhSVRb1EW5FhOuBTyiQhtRtAnnva9vD3yRfq8= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0 h1:kn1BudCgwtE7PxLqcZkErpD8GKqLZ6BSzeW9QihQJeM= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0/go.mod h1:ljkUDtAMdleoi9tIG1R6dJUpVwDcYjw3J2Q6Q/SuiC0= -go.opentelemetry.io/otel/log v0.6.0 h1:nH66tr+dmEgW5y+F9LanGJUBYPrRgP4g2EkmPE3LeK8= -go.opentelemetry.io/otel/log v0.6.0/go.mod h1:KdySypjQHhP069JX0z/t26VHwa8vSwzgaKmXtIB3fJM= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= -go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= -go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= -go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= -gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= -k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= -k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= -k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= -k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= -k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= -k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20231214164306-ab13479f8bf8 h1:yHNkNuLjht7iq95pO9QmbjOWCguvn8mDe3lT78nqPkw= -k8s.io/kube-openapi v0.0.0-20231214164306-ab13479f8bf8/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.17.1 h1:V1dQELMGVk46YVXXQUbTFujU7u4DQj6YUj9Rb6cuzz8= -sigs.k8s.io/controller-runtime v0.17.1/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/ee/agent/helm/.gitignore b/ee/agent/helm/.gitignore deleted file mode 100644 index 9d56f51c8c..0000000000 --- a/ee/agent/helm/.gitignore +++ /dev/null @@ -1 +0,0 @@ -values.staging.yaml diff --git a/ee/agent/helm/.helmignore b/ee/agent/helm/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/ee/agent/helm/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/ee/agent/helm/Chart.yaml b/ee/agent/helm/Chart.yaml deleted file mode 100644 index e75fd1fc04..0000000000 --- a/ee/agent/helm/Chart.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v2 -name: agent -description: Formance Membership Agent Helm Chart -home: "https://formance.com" -sources: -- "https://github.com/formancehq/membership-api" -maintainers: -- name: "Formance Team" - email: "support@formance.com" -icon: "https://avatars.githubusercontent.com/u/84325077?s=200&v=4" - -type: application -version: v2.1.0-beta.1 -appVersion: v2.1.0-beta.1 diff --git a/ee/agent/helm/README.md b/ee/agent/helm/README.md deleted file mode 100644 index d9f2697884..0000000000 --- a/ee/agent/helm/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# agent - -![Version: 0.2.0](https://img.shields.io/badge/Version-0.2.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: latest](https://img.shields.io/badge/AppVersion-latest-informational?style=flat-square) - -Formance Membership Agent Helm Chart - -**Homepage:** - -## Maintainers - -| Name | Email | Url | -| ---- | ------ | --- | -| Formance Team | | | - -## Source Code - -* - -## Values - -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| affinity | object | `{}` | | -| agent.authentication.clientID | string | `""` | | -| agent.authentication.clientSecret | string | `""` | | -| agent.authentication.issuer | string | `"https://app.formance.cloud/api"` | | -| agent.authentication.mode | string | `"bearer"` | | -| agent.baseUrl | string | `""` | | -| agent.id | string | `"b7549a16-f74a-4815-ab1e-bb8ef1c3833b"` | | -| agent.production | bool | `false` | | -| debug | bool | `false` | | -| fullnameOverride | string | `""` | | -| global.serviceName | string | `"agent"` | | -| image.pullPolicy | string | `"IfNotPresent"` | | -| image.repository | string | `"ghcr.io/formancehq/agent"` | | -| image.tag | string | `"v0.5.0"` | | -| imagePullSecrets | list | `[]` | | -| nameOverride | string | `""` | | -| nodeSelector | object | `{}` | | -| podAnnotations | object | `{}` | | -| podSecurityContext | object | `{}` | | -| resources.limits.cpu | string | `"100m"` | | -| resources.limits.memory | string | `"128Mi"` | | -| resources.requests.cpu | string | `"100m"` | | -| resources.requests.memory | string | `"128Mi"` | | -| securityContext | object | `{}` | | -| server.address | string | `"app.formance.cloud:443"` | | -| server.tls.enabled | bool | `true` | | -| server.tls.insecureSkipVerify | bool | `true` | | -| serviceAccount.annotations | object | `{}` | | -| tolerations | list | `[]` | | - ----------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) diff --git a/ee/agent/helm/templates/_helpers.tpl b/ee/agent/helm/templates/_helpers.tpl deleted file mode 100644 index 9d8e67386e..0000000000 --- a/ee/agent/helm/templates/_helpers.tpl +++ /dev/null @@ -1,14 +0,0 @@ -{{/* -Selector labels -*/}} -{{- define "agent.selectorLabels" -}} -app.kubernetes.io/name: {{ .Chart.Name }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{- define "agent.monitoring.logs" -}} -{{- if eq .Values.global.monitoring.logs.format "json" }} -- name: JSON_FORMATTING_LOGGER - value: "true" -{{- end }} -{{- end }} \ No newline at end of file diff --git a/ee/agent/helm/templates/clusterrole.yaml b/ee/agent/helm/templates/clusterrole.yaml deleted file mode 100644 index a7bc5c6825..0000000000 --- a/ee/agent/helm/templates/clusterrole.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ .Chart.Name }}-{{ .Release.Name }} -rules: -- apiGroups: - - formance.com - resources: - - "*" - verbs: - - "*" -- apiGroups: - - "apiextensions.k8s.io" - resources: - - customresourcedefinitions - verbs: - - "get" - - "list" diff --git a/ee/agent/helm/templates/clusterrolebinding.yaml b/ee/agent/helm/templates/clusterrolebinding.yaml deleted file mode 100644 index 281bb9fa27..0000000000 --- a/ee/agent/helm/templates/clusterrolebinding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ .Chart.Name }}-{{ .Release.Name }} -subjects: -- kind: ServiceAccount - name: {{ .Chart.Name }} - namespace: {{.Release.Namespace}} -roleRef: - kind: ClusterRole - name: {{ .Chart.Name }}-{{ .Release.Name }} - apiGroup: rbac.authorization.k8s.io diff --git a/ee/agent/helm/templates/deployment.yaml b/ee/agent/helm/templates/deployment.yaml deleted file mode 100644 index e7dac95f40..0000000000 --- a/ee/agent/helm/templates/deployment.yaml +++ /dev/null @@ -1,82 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Chart.Name }} -spec: - replicas: 1 - selector: - matchLabels: - {{- include "agent.selectorLabels" . | nindent 6 }} - strategy: - # Stop before recreate as each agent has an id and the server will not allow the connection if an agent is already connected - type: Recreate - template: - metadata: - {{- with .Values.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "agent.selectorLabels" . | nindent 8 }} - spec: - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: {{ .Chart.Name }} - securityContext: - {{- toYaml .Values.podSecurityContext | nindent 8 }} - containers: - - name: {{ .Chart.Name }} - securityContext: - {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - env: - - name: DEBUG - value: "{{.Values.debug}}" - - name: SERVER_ADDRESS - value: "{{.Values.server.address}}" - - name: TLS_ENABLED - value: "{{.Values.server.tls.enabled}}" - - name: TLS_INSECURE_SKIP_VERIFY - value: "{{.Values.server.tls.insecureSkipVerify}}" - - name: TLS_CA_CERT - value: "{{.Values.server.tls.ca}}" - - name: ID - value: "{{.Values.agent.id}}" - - name: TAG - value: "{{range $key, $value := .Values.agent.tags}}{{$key}}={{$value}} {{end}}" - - name: AUTHENTICATION_MODE - value: "{{ .Values.agent.authentication.mode }}" - {{- if eq .Values.agent.authentication.mode "token" }} - - name: AUTHENTICATION_TOKEN - value: "{{ .Values.agent.authentication.token }}" - {{- end }} - {{- if eq .Values.agent.authentication.mode "bearer" }} - - name: AUTHENTICATION_ISSUER - value: "{{ .Values.agent.authentication.issuer }}" - - name: AUTHENTICATION_CLIENT_ID - value: "{{ .Values.agent.authentication.clientID }}" - - name: AUTHENTICATION_CLIENT_SECRET - value: "{{ .Values.agent.authentication.clientSecret }}" - {{- end }} - - name: BASE_URL - value: "{{ .Values.agent.baseUrl }}" - - name: PRODUCTION - value: "{{ .Values.agent.production }}" - {{- include "agent.monitoring.logs" . | nindent 12 }} - resources: - {{- toYaml .Values.resources | nindent 12 }} - {{- with .Values.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} diff --git a/ee/agent/helm/templates/serviceaccount.yaml b/ee/agent/helm/templates/serviceaccount.yaml deleted file mode 100644 index 17bd73d0d5..0000000000 --- a/ee/agent/helm/templates/serviceaccount.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ .Chart.Name }} - {{- with .Values.serviceAccount.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} diff --git a/ee/agent/helm/values.yaml b/ee/agent/helm/values.yaml deleted file mode 100644 index fcde8b780b..0000000000 --- a/ee/agent/helm/values.yaml +++ /dev/null @@ -1,72 +0,0 @@ -global: - # This is not a global value shared over all charts, but a global value shared over all templates in this chart. - serviceName: agent - monitoring: - logs: - # format:Enum:{json, ""} - format: json - -image: - repository: ghcr.io/formancehq/agent - pullPolicy: IfNotPresent - # Overrides the image tag whose default is the chart appVersion. - tag: v2.1.0-beta.1 - -imagePullSecrets: [] -nameOverride: "" -fullnameOverride: "" - -serviceAccount: - # Annotations to add to the service account - annotations: {} - -podAnnotations: {} - -podSecurityContext: {} -# fsGroup: 2000 - -securityContext: - {} - # capabilities: - # drop: - # - ALL - # readOnlyRootFilesystem: true - # runAsNonRoot: true -# runAsUser: 1000 - -resources: - limits: - cpu: 100m - memory: 128Mi - requests: - cpu: 100m - memory: 128Mi - -nodeSelector: {} - -tolerations: [] - -affinity: {} - -debug: false - -server: - address: "app.formance.cloud:443" - tls: - enabled: true - insecureSkipVerify: true - -config: - monitoring: - serviceName: agent - -agent: - id: "b7549a16-f74a-4815-ab1e-bb8ef1c3833b" - baseUrl: "" - production: false - # Authentication token - authentication: - mode: bearer - issuer: https://app.formance.cloud/api - clientID: "" - clientSecret: "" diff --git a/ee/agent/internal/authenticator.go b/ee/agent/internal/authenticator.go deleted file mode 100644 index c59524ff0e..0000000000 --- a/ee/agent/internal/authenticator.go +++ /dev/null @@ -1,51 +0,0 @@ -package internal - -import ( - "context" - "net/http" - - oidcclient "github.com/zitadel/oidc/v2/pkg/client" - "golang.org/x/oauth2/clientcredentials" - "google.golang.org/grpc/metadata" -) - -type Authenticator interface { - authenticate(ctx context.Context) (metadata.MD, error) -} -type AuthenticatorFn func(ctx context.Context) (metadata.MD, error) - -func (fn AuthenticatorFn) authenticate(ctx context.Context) (metadata.MD, error) { - return fn(ctx) -} - -func TokenAuthenticator(token string) AuthenticatorFn { - return func(ctx context.Context) (metadata.MD, error) { - return metadata.New(map[string]string{"token": token}), nil - } -} - -func BearerAuthenticator(issuer, clientID, clientSecret string) AuthenticatorFn { - - return func(ctx context.Context) (metadata.MD, error) { - - discovery, err := oidcclient.Discover(issuer, http.DefaultClient) - if err != nil { - return nil, err - } - - config := clientcredentials.Config{ - ClientID: "region_" + clientID, - ClientSecret: clientSecret, - TokenURL: discovery.TokenEndpoint, - } - - token, err := config.Token(ctx) - if err != nil { - return nil, err - } - - return metadata.New(map[string]string{ - "bearer": token.AccessToken, - }), nil - } -} diff --git a/ee/agent/internal/generated/agent.pb.go b/ee/agent/internal/generated/agent.pb.go deleted file mode 100644 index 23fc4804d1..0000000000 --- a/ee/agent/internal/generated/agent.pb.go +++ /dev/null @@ -1,2047 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v4.24.4 -// source: agent.proto - -package generated - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - structpb "google.golang.org/protobuf/types/known/structpb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type StackStatus int32 - -const ( - StackStatus_Progressing StackStatus = 0 - StackStatus_Ready StackStatus = 1 - StackStatus_Deleted StackStatus = 2 - StackStatus_Disabled StackStatus = 3 -) - -// Enum value maps for StackStatus. -var ( - StackStatus_name = map[int32]string{ - 0: "Progressing", - 1: "Ready", - 2: "Deleted", - 3: "Disabled", - } - StackStatus_value = map[string]int32{ - "Progressing": 0, - "Ready": 1, - "Deleted": 2, - "Disabled": 3, - } -) - -func (x StackStatus) Enum() *StackStatus { - p := new(StackStatus) - *p = x - return p -} - -func (x StackStatus) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (StackStatus) Descriptor() protoreflect.EnumDescriptor { - return file_agent_proto_enumTypes[0].Descriptor() -} - -func (StackStatus) Type() protoreflect.EnumType { - return &file_agent_proto_enumTypes[0] -} - -func (x StackStatus) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use StackStatus.Descriptor instead. -func (StackStatus) EnumDescriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{0} -} - -type ConnectRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Tags map[string]string `protobuf:"bytes,2,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - BaseUrl string `protobuf:"bytes,3,opt,name=baseUrl,proto3" json:"baseUrl,omitempty"` - Production bool `protobuf:"varint,4,opt,name=production,proto3" json:"production,omitempty"` -} - -func (x *ConnectRequest) Reset() { - *x = ConnectRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ConnectRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ConnectRequest) ProtoMessage() {} - -func (x *ConnectRequest) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ConnectRequest.ProtoReflect.Descriptor instead. -func (*ConnectRequest) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{0} -} - -func (x *ConnectRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *ConnectRequest) GetTags() map[string]string { - if x != nil { - return x.Tags - } - return nil -} - -func (x *ConnectRequest) GetBaseUrl() string { - if x != nil { - return x.BaseUrl - } - return "" -} - -func (x *ConnectRequest) GetProduction() bool { - if x != nil { - return x.Production - } - return false -} - -type Order struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Message: - // - // *Order_Connected - // *Order_ExistingStack - // *Order_DeletedStack - // *Order_Ping - // *Order_DisabledStack - // *Order_EnabledStack - Message isOrder_Message `protobuf_oneof:"message"` -} - -func (x *Order) Reset() { - *x = Order{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Order) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Order) ProtoMessage() {} - -func (x *Order) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Order.ProtoReflect.Descriptor instead. -func (*Order) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{1} -} - -func (m *Order) GetMessage() isOrder_Message { - if m != nil { - return m.Message - } - return nil -} - -func (x *Order) GetConnected() *Connected { - if x, ok := x.GetMessage().(*Order_Connected); ok { - return x.Connected - } - return nil -} - -func (x *Order) GetExistingStack() *Stack { - if x, ok := x.GetMessage().(*Order_ExistingStack); ok { - return x.ExistingStack - } - return nil -} - -func (x *Order) GetDeletedStack() *DeletedStack { - if x, ok := x.GetMessage().(*Order_DeletedStack); ok { - return x.DeletedStack - } - return nil -} - -func (x *Order) GetPing() *Ping { - if x, ok := x.GetMessage().(*Order_Ping); ok { - return x.Ping - } - return nil -} - -func (x *Order) GetDisabledStack() *DisabledStack { - if x, ok := x.GetMessage().(*Order_DisabledStack); ok { - return x.DisabledStack - } - return nil -} - -func (x *Order) GetEnabledStack() *EnabledStack { - if x, ok := x.GetMessage().(*Order_EnabledStack); ok { - return x.EnabledStack - } - return nil -} - -type isOrder_Message interface { - isOrder_Message() -} - -type Order_Connected struct { - Connected *Connected `protobuf:"bytes,1,opt,name=connected,proto3,oneof"` -} - -type Order_ExistingStack struct { - ExistingStack *Stack `protobuf:"bytes,2,opt,name=existingStack,proto3,oneof"` -} - -type Order_DeletedStack struct { - DeletedStack *DeletedStack `protobuf:"bytes,3,opt,name=deletedStack,proto3,oneof"` -} - -type Order_Ping struct { - Ping *Ping `protobuf:"bytes,4,opt,name=ping,proto3,oneof"` -} - -type Order_DisabledStack struct { - DisabledStack *DisabledStack `protobuf:"bytes,6,opt,name=disabledStack,proto3,oneof"` -} - -type Order_EnabledStack struct { - EnabledStack *EnabledStack `protobuf:"bytes,7,opt,name=enabledStack,proto3,oneof"` -} - -func (*Order_Connected) isOrder_Message() {} - -func (*Order_ExistingStack) isOrder_Message() {} - -func (*Order_DeletedStack) isOrder_Message() {} - -func (*Order_Ping) isOrder_Message() {} - -func (*Order_DisabledStack) isOrder_Message() {} - -func (*Order_EnabledStack) isOrder_Message() {} - -type Message struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Message: - // - // *Message_StatusChanged - // *Message_Pong - // *Message_AddedVersion - // *Message_DeletedVersion - // *Message_UpdatedVersion - // *Message_ModuleStatusChanged - // *Message_ModuleDeleted - // *Message_StackDeleted - Message isMessage_Message `protobuf_oneof:"message"` -} - -func (x *Message) Reset() { - *x = Message{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Message) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Message) ProtoMessage() {} - -func (x *Message) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Message.ProtoReflect.Descriptor instead. -func (*Message) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{2} -} - -func (m *Message) GetMessage() isMessage_Message { - if m != nil { - return m.Message - } - return nil -} - -func (x *Message) GetStatusChanged() *StatusChanged { - if x, ok := x.GetMessage().(*Message_StatusChanged); ok { - return x.StatusChanged - } - return nil -} - -func (x *Message) GetPong() *Pong { - if x, ok := x.GetMessage().(*Message_Pong); ok { - return x.Pong - } - return nil -} - -func (x *Message) GetAddedVersion() *AddedVersion { - if x, ok := x.GetMessage().(*Message_AddedVersion); ok { - return x.AddedVersion - } - return nil -} - -func (x *Message) GetDeletedVersion() *DeletedVersion { - if x, ok := x.GetMessage().(*Message_DeletedVersion); ok { - return x.DeletedVersion - } - return nil -} - -func (x *Message) GetUpdatedVersion() *UpdatedVersion { - if x, ok := x.GetMessage().(*Message_UpdatedVersion); ok { - return x.UpdatedVersion - } - return nil -} - -func (x *Message) GetModuleStatusChanged() *ModuleStatusChanged { - if x, ok := x.GetMessage().(*Message_ModuleStatusChanged); ok { - return x.ModuleStatusChanged - } - return nil -} - -func (x *Message) GetModuleDeleted() *ModuleDeleted { - if x, ok := x.GetMessage().(*Message_ModuleDeleted); ok { - return x.ModuleDeleted - } - return nil -} - -func (x *Message) GetStackDeleted() *DeletedStack { - if x, ok := x.GetMessage().(*Message_StackDeleted); ok { - return x.StackDeleted - } - return nil -} - -type isMessage_Message interface { - isMessage_Message() -} - -type Message_StatusChanged struct { - StatusChanged *StatusChanged `protobuf:"bytes,1,opt,name=statusChanged,proto3,oneof"` -} - -type Message_Pong struct { - Pong *Pong `protobuf:"bytes,2,opt,name=pong,proto3,oneof"` -} - -type Message_AddedVersion struct { - AddedVersion *AddedVersion `protobuf:"bytes,3,opt,name=addedVersion,proto3,oneof"` -} - -type Message_DeletedVersion struct { - DeletedVersion *DeletedVersion `protobuf:"bytes,4,opt,name=deletedVersion,proto3,oneof"` -} - -type Message_UpdatedVersion struct { - UpdatedVersion *UpdatedVersion `protobuf:"bytes,5,opt,name=updatedVersion,proto3,oneof"` -} - -type Message_ModuleStatusChanged struct { - ModuleStatusChanged *ModuleStatusChanged `protobuf:"bytes,6,opt,name=moduleStatusChanged,proto3,oneof"` -} - -type Message_ModuleDeleted struct { - ModuleDeleted *ModuleDeleted `protobuf:"bytes,7,opt,name=moduleDeleted,proto3,oneof"` -} - -type Message_StackDeleted struct { - StackDeleted *DeletedStack `protobuf:"bytes,8,opt,name=stackDeleted,proto3,oneof"` -} - -func (*Message_StatusChanged) isMessage_Message() {} - -func (*Message_Pong) isMessage_Message() {} - -func (*Message_AddedVersion) isMessage_Message() {} - -func (*Message_DeletedVersion) isMessage_Message() {} - -func (*Message_UpdatedVersion) isMessage_Message() {} - -func (*Message_ModuleStatusChanged) isMessage_Message() {} - -func (*Message_ModuleDeleted) isMessage_Message() {} - -func (*Message_StackDeleted) isMessage_Message() {} - -type Connected struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *Connected) Reset() { - *x = Connected{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Connected) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Connected) ProtoMessage() {} - -func (x *Connected) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Connected.ProtoReflect.Descriptor instead. -func (*Connected) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{3} -} - -type Ping struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *Ping) Reset() { - *x = Ping{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Ping) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Ping) ProtoMessage() {} - -func (x *Ping) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Ping.ProtoReflect.Descriptor instead. -func (*Ping) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{4} -} - -type Pong struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *Pong) Reset() { - *x = Pong{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Pong) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Pong) ProtoMessage() {} - -func (x *Pong) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Pong.ProtoReflect.Descriptor instead. -func (*Pong) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{5} -} - -type Stack struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ClusterName string `protobuf:"bytes,1,opt,name=clusterName,proto3" json:"clusterName,omitempty"` - Seed string `protobuf:"bytes,2,opt,name=seed,proto3" json:"seed,omitempty"` - AuthConfig *AuthConfig `protobuf:"bytes,3,opt,name=authConfig,proto3" json:"authConfig,omitempty"` - StaticClients []*AuthClient `protobuf:"bytes,4,rep,name=staticClients,proto3" json:"staticClients,omitempty"` - StargateConfig *StargateConfig `protobuf:"bytes,5,opt,name=stargateConfig,proto3" json:"stargateConfig,omitempty"` - Disabled bool `protobuf:"varint,6,opt,name=disabled,proto3" json:"disabled,omitempty"` - Versions string `protobuf:"bytes,8,opt,name=versions,proto3" json:"versions,omitempty"` - EnableAudit bool `protobuf:"varint,9,opt,name=enableAudit,proto3" json:"enableAudit,omitempty"` - AdditionalLabels map[string]string `protobuf:"bytes,10,rep,name=additionalLabels,proto3" json:"additionalLabels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - AdditionalAnnotations map[string]string `protobuf:"bytes,11,rep,name=additionalAnnotations,proto3" json:"additionalAnnotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - Modules []*Module `protobuf:"bytes,12,rep,name=modules,proto3" json:"modules,omitempty"` -} - -func (x *Stack) Reset() { - *x = Stack{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Stack) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Stack) ProtoMessage() {} - -func (x *Stack) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Stack.ProtoReflect.Descriptor instead. -func (*Stack) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{6} -} - -func (x *Stack) GetClusterName() string { - if x != nil { - return x.ClusterName - } - return "" -} - -func (x *Stack) GetSeed() string { - if x != nil { - return x.Seed - } - return "" -} - -func (x *Stack) GetAuthConfig() *AuthConfig { - if x != nil { - return x.AuthConfig - } - return nil -} - -func (x *Stack) GetStaticClients() []*AuthClient { - if x != nil { - return x.StaticClients - } - return nil -} - -func (x *Stack) GetStargateConfig() *StargateConfig { - if x != nil { - return x.StargateConfig - } - return nil -} - -func (x *Stack) GetDisabled() bool { - if x != nil { - return x.Disabled - } - return false -} - -func (x *Stack) GetVersions() string { - if x != nil { - return x.Versions - } - return "" -} - -func (x *Stack) GetEnableAudit() bool { - if x != nil { - return x.EnableAudit - } - return false -} - -func (x *Stack) GetAdditionalLabels() map[string]string { - if x != nil { - return x.AdditionalLabels - } - return nil -} - -func (x *Stack) GetAdditionalAnnotations() map[string]string { - if x != nil { - return x.AdditionalAnnotations - } - return nil -} - -func (x *Stack) GetModules() []*Module { - if x != nil { - return x.Modules - } - return nil -} - -type Module struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *Module) Reset() { - *x = Module{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Module) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Module) ProtoMessage() {} - -func (x *Module) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Module.ProtoReflect.Descriptor instead. -func (*Module) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{7} -} - -func (x *Module) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type VersionKind struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` - Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` -} - -func (x *VersionKind) Reset() { - *x = VersionKind{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *VersionKind) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*VersionKind) ProtoMessage() {} - -func (x *VersionKind) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use VersionKind.ProtoReflect.Descriptor instead. -func (*VersionKind) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{8} -} - -func (x *VersionKind) GetVersion() string { - if x != nil { - return x.Version - } - return "" -} - -func (x *VersionKind) GetKind() string { - if x != nil { - return x.Kind - } - return "" -} - -type ModuleStatusChanged struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ClusterName string `protobuf:"bytes,1,opt,name=clusterName,proto3" json:"clusterName,omitempty"` - Status *structpb.Struct `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` - Vk *VersionKind `protobuf:"bytes,3,opt,name=vk,proto3" json:"vk,omitempty"` -} - -func (x *ModuleStatusChanged) Reset() { - *x = ModuleStatusChanged{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ModuleStatusChanged) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ModuleStatusChanged) ProtoMessage() {} - -func (x *ModuleStatusChanged) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ModuleStatusChanged.ProtoReflect.Descriptor instead. -func (*ModuleStatusChanged) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{9} -} - -func (x *ModuleStatusChanged) GetClusterName() string { - if x != nil { - return x.ClusterName - } - return "" -} - -func (x *ModuleStatusChanged) GetStatus() *structpb.Struct { - if x != nil { - return x.Status - } - return nil -} - -func (x *ModuleStatusChanged) GetVk() *VersionKind { - if x != nil { - return x.Vk - } - return nil -} - -type ModuleDeleted struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ClusterName string `protobuf:"bytes,1,opt,name=clusterName,proto3" json:"clusterName,omitempty"` - Vk *VersionKind `protobuf:"bytes,2,opt,name=vk,proto3" json:"vk,omitempty"` -} - -func (x *ModuleDeleted) Reset() { - *x = ModuleDeleted{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ModuleDeleted) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ModuleDeleted) ProtoMessage() {} - -func (x *ModuleDeleted) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ModuleDeleted.ProtoReflect.Descriptor instead. -func (*ModuleDeleted) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{10} -} - -func (x *ModuleDeleted) GetClusterName() string { - if x != nil { - return x.ClusterName - } - return "" -} - -func (x *ModuleDeleted) GetVk() *VersionKind { - if x != nil { - return x.Vk - } - return nil -} - -type StatusChanged struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ClusterName string `protobuf:"bytes,1,opt,name=clusterName,proto3" json:"clusterName,omitempty"` - Status StackStatus `protobuf:"varint,2,opt,name=status,proto3,enum=server.StackStatus" json:"status,omitempty"` - Statuses *structpb.Struct `protobuf:"bytes,3,opt,name=statuses,proto3" json:"statuses,omitempty"` - Vk *VersionKind `protobuf:"bytes,4,opt,name=vk,proto3" json:"vk,omitempty"` -} - -func (x *StatusChanged) Reset() { - *x = StatusChanged{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StatusChanged) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StatusChanged) ProtoMessage() {} - -func (x *StatusChanged) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StatusChanged.ProtoReflect.Descriptor instead. -func (*StatusChanged) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{11} -} - -func (x *StatusChanged) GetClusterName() string { - if x != nil { - return x.ClusterName - } - return "" -} - -func (x *StatusChanged) GetStatus() StackStatus { - if x != nil { - return x.Status - } - return StackStatus_Progressing -} - -func (x *StatusChanged) GetStatuses() *structpb.Struct { - if x != nil { - return x.Statuses - } - return nil -} - -func (x *StatusChanged) GetVk() *VersionKind { - if x != nil { - return x.Vk - } - return nil -} - -type StargateConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` - Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` -} - -func (x *StargateConfig) Reset() { - *x = StargateConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StargateConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StargateConfig) ProtoMessage() {} - -func (x *StargateConfig) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StargateConfig.ProtoReflect.Descriptor instead. -func (*StargateConfig) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{12} -} - -func (x *StargateConfig) GetEnabled() bool { - if x != nil { - return x.Enabled - } - return false -} - -func (x *StargateConfig) GetUrl() string { - if x != nil { - return x.Url - } - return "" -} - -type DeletedStack struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ClusterName string `protobuf:"bytes,1,opt,name=clusterName,proto3" json:"clusterName,omitempty"` -} - -func (x *DeletedStack) Reset() { - *x = DeletedStack{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeletedStack) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeletedStack) ProtoMessage() {} - -func (x *DeletedStack) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeletedStack.ProtoReflect.Descriptor instead. -func (*DeletedStack) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{13} -} - -func (x *DeletedStack) GetClusterName() string { - if x != nil { - return x.ClusterName - } - return "" -} - -type DisabledStack struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ClusterName string `protobuf:"bytes,1,opt,name=clusterName,proto3" json:"clusterName,omitempty"` -} - -func (x *DisabledStack) Reset() { - *x = DisabledStack{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DisabledStack) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DisabledStack) ProtoMessage() {} - -func (x *DisabledStack) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DisabledStack.ProtoReflect.Descriptor instead. -func (*DisabledStack) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{14} -} - -func (x *DisabledStack) GetClusterName() string { - if x != nil { - return x.ClusterName - } - return "" -} - -type EnabledStack struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ClusterName string `protobuf:"bytes,1,opt,name=clusterName,proto3" json:"clusterName,omitempty"` -} - -func (x *EnabledStack) Reset() { - *x = EnabledStack{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EnabledStack) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EnabledStack) ProtoMessage() {} - -func (x *EnabledStack) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EnabledStack.ProtoReflect.Descriptor instead. -func (*EnabledStack) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{15} -} - -func (x *EnabledStack) GetClusterName() string { - if x != nil { - return x.ClusterName - } - return "" -} - -type AuthConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ClientId string `protobuf:"bytes,1,opt,name=clientId,proto3" json:"clientId,omitempty"` - ClientSecret string `protobuf:"bytes,2,opt,name=clientSecret,proto3" json:"clientSecret,omitempty"` - Issuer string `protobuf:"bytes,3,opt,name=issuer,proto3" json:"issuer,omitempty"` -} - -func (x *AuthConfig) Reset() { - *x = AuthConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AuthConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AuthConfig) ProtoMessage() {} - -func (x *AuthConfig) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AuthConfig.ProtoReflect.Descriptor instead. -func (*AuthConfig) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{16} -} - -func (x *AuthConfig) GetClientId() string { - if x != nil { - return x.ClientId - } - return "" -} - -func (x *AuthConfig) GetClientSecret() string { - if x != nil { - return x.ClientSecret - } - return "" -} - -func (x *AuthConfig) GetIssuer() string { - if x != nil { - return x.Issuer - } - return "" -} - -type AuthClient struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Public bool `protobuf:"varint,1,opt,name=public,proto3" json:"public,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *AuthClient) Reset() { - *x = AuthClient{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AuthClient) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AuthClient) ProtoMessage() {} - -func (x *AuthClient) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AuthClient.ProtoReflect.Descriptor instead. -func (*AuthClient) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{17} -} - -func (x *AuthClient) GetPublic() bool { - if x != nil { - return x.Public - } - return false -} - -func (x *AuthClient) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type AddedVersion struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Versions map[string]string `protobuf:"bytes,2,rep,name=versions,proto3" json:"versions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *AddedVersion) Reset() { - *x = AddedVersion{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AddedVersion) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AddedVersion) ProtoMessage() {} - -func (x *AddedVersion) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AddedVersion.ProtoReflect.Descriptor instead. -func (*AddedVersion) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{18} -} - -func (x *AddedVersion) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *AddedVersion) GetVersions() map[string]string { - if x != nil { - return x.Versions - } - return nil -} - -type UpdatedVersion struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Versions map[string]string `protobuf:"bytes,2,rep,name=versions,proto3" json:"versions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *UpdatedVersion) Reset() { - *x = UpdatedVersion{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdatedVersion) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdatedVersion) ProtoMessage() {} - -func (x *UpdatedVersion) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdatedVersion.ProtoReflect.Descriptor instead. -func (*UpdatedVersion) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{19} -} - -func (x *UpdatedVersion) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *UpdatedVersion) GetVersions() map[string]string { - if x != nil { - return x.Versions - } - return nil -} - -type DeletedVersion struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *DeletedVersion) Reset() { - *x = DeletedVersion{} - if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeletedVersion) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeletedVersion) ProtoMessage() {} - -func (x *DeletedVersion) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeletedVersion.ProtoReflect.Descriptor instead. -func (*DeletedVersion) Descriptor() ([]byte, []int) { - return file_agent_proto_rawDescGZIP(), []int{20} -} - -func (x *DeletedVersion) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -var File_agent_proto protoreflect.FileDescriptor - -var file_agent_proto_rawDesc = []byte{ - 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0xc9, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x61, 0x67, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07, - 0x62, 0x61, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, - 0x61, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x64, - 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0xdd, 0x02, 0x0a, 0x05, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x31, 0x0a, 0x09, 0x63, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x48, - 0x00, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x35, 0x0a, 0x0d, - 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, - 0x63, 0x6b, 0x48, 0x00, 0x52, 0x0d, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, - 0x61, 0x63, 0x6b, 0x12, 0x3a, 0x0a, 0x0c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x53, 0x74, - 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x48, - 0x00, 0x52, 0x0c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, - 0x22, 0x0a, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x04, 0x70, - 0x69, 0x6e, 0x67, 0x12, 0x3d, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x53, - 0x74, 0x61, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x53, 0x74, 0x61, 0x63, - 0x6b, 0x48, 0x00, 0x52, 0x0d, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x53, 0x74, 0x61, - 0x63, 0x6b, 0x12, 0x3a, 0x0a, 0x0c, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x53, 0x74, 0x61, - 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x48, 0x00, - 0x52, 0x0c, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x42, 0x09, - 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, - 0x83, 0x04, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x0d, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0d, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x22, 0x0a, 0x04, 0x70, 0x6f, - 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x50, 0x6f, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x12, 0x3a, - 0x0a, 0x0c, 0x61, 0x64, 0x64, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x41, 0x64, - 0x64, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x64, - 0x64, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0e, 0x64, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0e, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0e, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x4f, - 0x0a, 0x13, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x48, 0x00, 0x52, 0x13, 0x6d, 0x6f, 0x64, 0x75, - 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, - 0x3d, 0x0a, 0x0d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, - 0x0d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x3a, - 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x74, - 0x61, 0x63, 0x6b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x0b, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x22, 0x06, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x22, 0x06, 0x0a, 0x04, 0x50, 0x6f, - 0x6e, 0x67, 0x22, 0xb5, 0x05, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b, - 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x73, 0x65, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x65, - 0x65, 0x64, 0x12, 0x32, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, - 0x12, 0x3e, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x67, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x67, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x67, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x41, 0x75, 0x64, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x75, 0x64, 0x69, 0x74, 0x12, 0x4f, 0x0a, 0x10, 0x61, 0x64, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0a, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, - 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x4c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x61, 0x64, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x5e, 0x0a, 0x15, 0x61, - 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, - 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, 0x0a, 0x07, 0x6d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x07, 0x6d, 0x6f, - 0x64, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x43, 0x0a, 0x15, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x48, 0x0a, 0x1a, 0x41, 0x64, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x22, 0x1c, 0x0a, 0x06, 0x4d, 0x6f, - 0x64, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3b, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0x8d, 0x01, 0x0a, 0x13, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x20, 0x0a, - 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x23, 0x0a, 0x02, 0x76, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x69, 0x6e, - 0x64, 0x52, 0x02, 0x76, 0x6b, 0x22, 0x56, 0x0a, 0x0d, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x02, 0x76, 0x6b, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x02, 0x76, 0x6b, 0x22, 0xb8, 0x01, - 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, - 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x13, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x33, - 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x02, 0x76, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x02, 0x76, 0x6b, 0x22, 0x3c, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x72, - 0x67, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x30, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x64, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x31, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x30, 0x0a, 0x0c, 0x45, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x64, 0x0a, - 0x0a, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69, - 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, - 0x75, 0x65, 0x72, 0x22, 0x34, 0x0a, 0x0a, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x9f, 0x01, 0x0a, 0x0c, 0x41, 0x64, - 0x64, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3e, - 0x0a, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x41, 0x64, 0x64, 0x65, 0x64, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3b, - 0x0a, 0x0d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa3, 0x01, 0x0a, 0x0e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3b, 0x0a, 0x0d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x24, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x2a, 0x44, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x63, 0x6b, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x61, 0x64, 0x79, - 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x10, 0x02, 0x12, - 0x0c, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, 0x03, 0x32, 0x6c, 0x0a, - 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x12, 0x16, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x00, 0x30, 0x01, 0x12, 0x2c, 0x0a, - 0x04, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x0f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x3a, 0x5a, 0x38, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, - 0x63, 0x65, 0x68, 0x71, 0x2f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x67, 0x65, - 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_agent_proto_rawDescOnce sync.Once - file_agent_proto_rawDescData = file_agent_proto_rawDesc -) - -func file_agent_proto_rawDescGZIP() []byte { - file_agent_proto_rawDescOnce.Do(func() { - file_agent_proto_rawDescData = protoimpl.X.CompressGZIP(file_agent_proto_rawDescData) - }) - return file_agent_proto_rawDescData -} - -var file_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 26) -var file_agent_proto_goTypes = []interface{}{ - (StackStatus)(0), // 0: server.StackStatus - (*ConnectRequest)(nil), // 1: server.ConnectRequest - (*Order)(nil), // 2: server.Order - (*Message)(nil), // 3: server.Message - (*Connected)(nil), // 4: server.Connected - (*Ping)(nil), // 5: server.Ping - (*Pong)(nil), // 6: server.Pong - (*Stack)(nil), // 7: server.Stack - (*Module)(nil), // 8: server.Module - (*VersionKind)(nil), // 9: server.VersionKind - (*ModuleStatusChanged)(nil), // 10: server.ModuleStatusChanged - (*ModuleDeleted)(nil), // 11: server.ModuleDeleted - (*StatusChanged)(nil), // 12: server.StatusChanged - (*StargateConfig)(nil), // 13: server.StargateConfig - (*DeletedStack)(nil), // 14: server.DeletedStack - (*DisabledStack)(nil), // 15: server.DisabledStack - (*EnabledStack)(nil), // 16: server.EnabledStack - (*AuthConfig)(nil), // 17: server.AuthConfig - (*AuthClient)(nil), // 18: server.AuthClient - (*AddedVersion)(nil), // 19: server.AddedVersion - (*UpdatedVersion)(nil), // 20: server.UpdatedVersion - (*DeletedVersion)(nil), // 21: server.DeletedVersion - nil, // 22: server.ConnectRequest.TagsEntry - nil, // 23: server.Stack.AdditionalLabelsEntry - nil, // 24: server.Stack.AdditionalAnnotationsEntry - nil, // 25: server.AddedVersion.VersionsEntry - nil, // 26: server.UpdatedVersion.VersionsEntry - (*structpb.Struct)(nil), // 27: google.protobuf.Struct -} -var file_agent_proto_depIdxs = []int32{ - 22, // 0: server.ConnectRequest.tags:type_name -> server.ConnectRequest.TagsEntry - 4, // 1: server.Order.connected:type_name -> server.Connected - 7, // 2: server.Order.existingStack:type_name -> server.Stack - 14, // 3: server.Order.deletedStack:type_name -> server.DeletedStack - 5, // 4: server.Order.ping:type_name -> server.Ping - 15, // 5: server.Order.disabledStack:type_name -> server.DisabledStack - 16, // 6: server.Order.enabledStack:type_name -> server.EnabledStack - 12, // 7: server.Message.statusChanged:type_name -> server.StatusChanged - 6, // 8: server.Message.pong:type_name -> server.Pong - 19, // 9: server.Message.addedVersion:type_name -> server.AddedVersion - 21, // 10: server.Message.deletedVersion:type_name -> server.DeletedVersion - 20, // 11: server.Message.updatedVersion:type_name -> server.UpdatedVersion - 10, // 12: server.Message.moduleStatusChanged:type_name -> server.ModuleStatusChanged - 11, // 13: server.Message.moduleDeleted:type_name -> server.ModuleDeleted - 14, // 14: server.Message.stackDeleted:type_name -> server.DeletedStack - 17, // 15: server.Stack.authConfig:type_name -> server.AuthConfig - 18, // 16: server.Stack.staticClients:type_name -> server.AuthClient - 13, // 17: server.Stack.stargateConfig:type_name -> server.StargateConfig - 23, // 18: server.Stack.additionalLabels:type_name -> server.Stack.AdditionalLabelsEntry - 24, // 19: server.Stack.additionalAnnotations:type_name -> server.Stack.AdditionalAnnotationsEntry - 8, // 20: server.Stack.modules:type_name -> server.Module - 27, // 21: server.ModuleStatusChanged.status:type_name -> google.protobuf.Struct - 9, // 22: server.ModuleStatusChanged.vk:type_name -> server.VersionKind - 9, // 23: server.ModuleDeleted.vk:type_name -> server.VersionKind - 0, // 24: server.StatusChanged.status:type_name -> server.StackStatus - 27, // 25: server.StatusChanged.statuses:type_name -> google.protobuf.Struct - 9, // 26: server.StatusChanged.vk:type_name -> server.VersionKind - 25, // 27: server.AddedVersion.versions:type_name -> server.AddedVersion.VersionsEntry - 26, // 28: server.UpdatedVersion.versions:type_name -> server.UpdatedVersion.VersionsEntry - 1, // 29: server.Server.Connect:input_type -> server.ConnectRequest - 3, // 30: server.Server.Join:input_type -> server.Message - 2, // 31: server.Server.Connect:output_type -> server.Order - 2, // 32: server.Server.Join:output_type -> server.Order - 31, // [31:33] is the sub-list for method output_type - 29, // [29:31] is the sub-list for method input_type - 29, // [29:29] is the sub-list for extension type_name - 29, // [29:29] is the sub-list for extension extendee - 0, // [0:29] is the sub-list for field type_name -} - -func init() { file_agent_proto_init() } -func file_agent_proto_init() { - if File_agent_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_agent_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ConnectRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Order); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Message); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Connected); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Ping); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Pong); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Stack); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Module); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VersionKind); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ModuleStatusChanged); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ModuleDeleted); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StatusChanged); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StargateConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeletedStack); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DisabledStack); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EnabledStack); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AuthConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AuthClient); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddedVersion); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdatedVersion); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_agent_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeletedVersion); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_agent_proto_msgTypes[1].OneofWrappers = []interface{}{ - (*Order_Connected)(nil), - (*Order_ExistingStack)(nil), - (*Order_DeletedStack)(nil), - (*Order_Ping)(nil), - (*Order_DisabledStack)(nil), - (*Order_EnabledStack)(nil), - } - file_agent_proto_msgTypes[2].OneofWrappers = []interface{}{ - (*Message_StatusChanged)(nil), - (*Message_Pong)(nil), - (*Message_AddedVersion)(nil), - (*Message_DeletedVersion)(nil), - (*Message_UpdatedVersion)(nil), - (*Message_ModuleStatusChanged)(nil), - (*Message_ModuleDeleted)(nil), - (*Message_StackDeleted)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_agent_proto_rawDesc, - NumEnums: 1, - NumMessages: 26, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_agent_proto_goTypes, - DependencyIndexes: file_agent_proto_depIdxs, - EnumInfos: file_agent_proto_enumTypes, - MessageInfos: file_agent_proto_msgTypes, - }.Build() - File_agent_proto = out.File - file_agent_proto_rawDesc = nil - file_agent_proto_goTypes = nil - file_agent_proto_depIdxs = nil -} diff --git a/ee/agent/internal/generated/agent_grpc.pb.go b/ee/agent/internal/generated/agent_grpc.pb.go deleted file mode 100644 index d5ab23d1d4..0000000000 --- a/ee/agent/internal/generated/agent_grpc.pb.go +++ /dev/null @@ -1,200 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v4.24.4 -// source: agent.proto - -package generated - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// ServerClient is the client API for Server service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type ServerClient interface { - Connect(ctx context.Context, in *ConnectRequest, opts ...grpc.CallOption) (Server_ConnectClient, error) - Join(ctx context.Context, opts ...grpc.CallOption) (Server_JoinClient, error) -} - -type serverClient struct { - cc grpc.ClientConnInterface -} - -func NewServerClient(cc grpc.ClientConnInterface) ServerClient { - return &serverClient{cc} -} - -func (c *serverClient) Connect(ctx context.Context, in *ConnectRequest, opts ...grpc.CallOption) (Server_ConnectClient, error) { - stream, err := c.cc.NewStream(ctx, &Server_ServiceDesc.Streams[0], "/server.Server/Connect", opts...) - if err != nil { - return nil, err - } - x := &serverConnectClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type Server_ConnectClient interface { - Recv() (*Order, error) - grpc.ClientStream -} - -type serverConnectClient struct { - grpc.ClientStream -} - -func (x *serverConnectClient) Recv() (*Order, error) { - m := new(Order) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -func (c *serverClient) Join(ctx context.Context, opts ...grpc.CallOption) (Server_JoinClient, error) { - stream, err := c.cc.NewStream(ctx, &Server_ServiceDesc.Streams[1], "/server.Server/Join", opts...) - if err != nil { - return nil, err - } - x := &serverJoinClient{stream} - return x, nil -} - -type Server_JoinClient interface { - Send(*Message) error - Recv() (*Order, error) - grpc.ClientStream -} - -type serverJoinClient struct { - grpc.ClientStream -} - -func (x *serverJoinClient) Send(m *Message) error { - return x.ClientStream.SendMsg(m) -} - -func (x *serverJoinClient) Recv() (*Order, error) { - m := new(Order) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// ServerServer is the server API for Server service. -// All implementations must embed UnimplementedServerServer -// for forward compatibility -type ServerServer interface { - Connect(*ConnectRequest, Server_ConnectServer) error - Join(Server_JoinServer) error - mustEmbedUnimplementedServerServer() -} - -// UnimplementedServerServer must be embedded to have forward compatible implementations. -type UnimplementedServerServer struct { -} - -func (UnimplementedServerServer) Connect(*ConnectRequest, Server_ConnectServer) error { - return status.Errorf(codes.Unimplemented, "method Connect not implemented") -} -func (UnimplementedServerServer) Join(Server_JoinServer) error { - return status.Errorf(codes.Unimplemented, "method Join not implemented") -} -func (UnimplementedServerServer) mustEmbedUnimplementedServerServer() {} - -// UnsafeServerServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to ServerServer will -// result in compilation errors. -type UnsafeServerServer interface { - mustEmbedUnimplementedServerServer() -} - -func RegisterServerServer(s grpc.ServiceRegistrar, srv ServerServer) { - s.RegisterService(&Server_ServiceDesc, srv) -} - -func _Server_Connect_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(ConnectRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(ServerServer).Connect(m, &serverConnectServer{stream}) -} - -type Server_ConnectServer interface { - Send(*Order) error - grpc.ServerStream -} - -type serverConnectServer struct { - grpc.ServerStream -} - -func (x *serverConnectServer) Send(m *Order) error { - return x.ServerStream.SendMsg(m) -} - -func _Server_Join_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(ServerServer).Join(&serverJoinServer{stream}) -} - -type Server_JoinServer interface { - Send(*Order) error - Recv() (*Message, error) - grpc.ServerStream -} - -type serverJoinServer struct { - grpc.ServerStream -} - -func (x *serverJoinServer) Send(m *Order) error { - return x.ServerStream.SendMsg(m) -} - -func (x *serverJoinServer) Recv() (*Message, error) { - m := new(Message) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// Server_ServiceDesc is the grpc.ServiceDesc for Server service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Server_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "server.Server", - HandlerType: (*ServerServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "Connect", - Handler: _Server_Connect_Handler, - ServerStreams: true, - }, - { - StreamName: "Join", - Handler: _Server_Join_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "agent.proto", -} diff --git a/ee/agent/internal/informer_modules.go b/ee/agent/internal/informer_modules.go deleted file mode 100644 index d8efb57fc6..0000000000 --- a/ee/agent/internal/informer_modules.go +++ /dev/null @@ -1,119 +0,0 @@ -package internal - -import ( - "reflect" - - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/stack/components/agent/internal/generated" - "google.golang.org/protobuf/types/known/structpb" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/client-go/tools/cache" -) - -func fromUnstructuredToModuleStatusChanged(unstructuredModule *unstructured.Unstructured, status *structpb.Struct) *generated.Message { - return &generated.Message{ - Message: &generated.Message_ModuleStatusChanged{ - ModuleStatusChanged: &generated.ModuleStatusChanged{ - ClusterName: unstructuredModule.GetName(), - Vk: &generated.VersionKind{ - Version: unstructuredModule.GetObjectKind().GroupVersionKind().Version, - Kind: unstructuredModule.GetObjectKind().GroupVersionKind().Kind, - }, - Status: status, - }, - }, - } -} - -type ModuleEventHandler struct { - logger logging.Logger - client MembershipClient -} - -func (h *ModuleEventHandler) AddFunc(obj interface{}) { - unstructuredModule := obj.(*unstructured.Unstructured) - - logger := h.logger.WithField("func", "Add").WithField("module", unstructuredModule.GetName()) - - status, err := getStatus(unstructuredModule) - if err != nil { - logger.Errorf("Unable to generate message module added: %s", err) - return - } - - if status == nil { - return - } - - message := fromUnstructuredToModuleStatusChanged(unstructuredModule, status) - if err := h.client.Send(message); err != nil { - logger.Errorf("Unable to send message module added: %s", err) - return - } - - logger.Infof("Detect module '%s' added", unstructuredModule.GetName()) -} - -func (h *ModuleEventHandler) UpdateFunc(oldObj, newObj any) { - - oldVersions := oldObj.(*unstructured.Unstructured) - newVersions := newObj.(*unstructured.Unstructured) - - logger := h.logger.WithField("func", "Update").WithField("module", newVersions.GetName()) - - oldStatus, err := getStatus(oldVersions) - if err != nil { - logger.Errorf("Unable to get status from old versions: %s", err) - } - newStatus, err := getStatus(newVersions) - if err != nil { - logger.Errorf("Unable to get status from new versions: %s", err) - return - } - - if newStatus == nil || reflect.DeepEqual(oldStatus, newStatus) { - return - } - - message := fromUnstructuredToModuleStatusChanged(newVersions, newStatus) - if err := h.client.Send(message); err != nil { - logger.Errorf("Unable to send message module update: %s", err) - return - } - logger.Infof("Detect module '%s' updated", newVersions.GetName()) -} - -func (h *ModuleEventHandler) DeleteFunc(obj interface{}) { - - unstructuredModule := obj.(*unstructured.Unstructured) - logger := h.logger.WithField("func", "Delete").WithField("module", unstructuredModule.GetName()) - - if err := h.client.Send(&generated.Message{ - Message: &generated.Message_ModuleDeleted{ - ModuleDeleted: &generated.ModuleDeleted{ - ClusterName: unstructuredModule.GetName(), - Vk: &generated.VersionKind{ - Version: unstructuredModule.GetObjectKind().GroupVersionKind().Version, - Kind: unstructuredModule.GetObjectKind().GroupVersionKind().Kind, - }, - }, - }, - }); err != nil { - logger.Errorf("Unable to send message module deleted: %s", err) - return - } - logger.Infof("Detect module '%s' deleted", unstructuredModule.GetName()) -} - -func NewModuleEventHandler(logger logging.Logger, membershipClient MembershipClient) cache.ResourceEventHandlerFuncs { - moduleEventHandler := &ModuleEventHandler{ - logger: logger, - client: membershipClient, - } - - return cache.ResourceEventHandlerFuncs{ - AddFunc: moduleEventHandler.AddFunc, - UpdateFunc: moduleEventHandler.UpdateFunc, - DeleteFunc: moduleEventHandler.DeleteFunc, - } -} diff --git a/ee/agent/internal/informer_modules_test.go b/ee/agent/internal/informer_modules_test.go deleted file mode 100644 index 669be41e38..0000000000 --- a/ee/agent/internal/informer_modules_test.go +++ /dev/null @@ -1,230 +0,0 @@ -package internal_test - -import ( - "encoding/json" - "testing" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/stack/components/agent/internal" - "github.com/google/uuid" - "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -func TestRestrictModuleStatus(t *testing.T) { - - type testCase struct { - incomingStatus map[string]interface{} - expectedStatus map[string]interface{} - expectError bool - } - conditions := func() []interface{} { - conditions := []v1beta1.Condition{} - - var count int64 = 0 - newCondition := func() v1beta1.Condition { - count++ - return v1beta1.Condition{ - Type: uuid.NewString(), - Reason: uuid.NewString(), - Message: uuid.NewString(), - Status: v1.ConditionStatus(uuid.NewString()), - ObservedGeneration: count, - LastTransitionTime: v1.Time{}, - } - } - - conditions = append(conditions, newCondition()) - conditions = append(conditions, newCondition()) - return collectionutils.Map(conditions, func(c v1beta1.Condition) interface{} { - b, err := json.Marshal(c) - if err != nil { - t.Fatal(err) - } - var m map[string]interface{} - if err := json.Unmarshal(b, &m); err != nil { - t.Fatal(err) - } - return m - }) - }() - testCases := []testCase{ - { - incomingStatus: map[string]interface{}{}, - expectedStatus: map[string]interface{}{}, - expectError: true, - }, - { - incomingStatus: map[string]interface{}{ - "key1": "value1", - "key2": "value2", - }, - expectedStatus: map[string]interface{}{ - "ready": false, - }, - }, - { - incomingStatus: map[string]interface{}{ - "info": "some info", - "ready": true, - }, - expectedStatus: map[string]interface{}{ - "info": "some info", - "ready": true, - }, - }, - { - incomingStatus: map[string]interface{}{ - "conditions": conditions, - }, - - expectedStatus: map[string]interface{}{ - "ready": false, - "conditions": conditions, - }, - }, - } - - for _, tc := range testCases { - tc := tc - t.Run("test", func(t *testing.T) { - t.Parallel() - - status, err := internal.Restrict[v1beta1.Status](tc.incomingStatus) - if tc.expectError { - require.Error(t, err) - return - } - require.NoError(t, err) - require.Equal(t, tc.expectedStatus, status) - }) - } -} - -func TestModuleAddFunc(t *testing.T) { - t.Parallel() - ctrl := gomock.NewController(t) - membershipClientMock := internal.NewMockMembershipClient(ctrl) - resourceInformer := internal.NewModuleEventHandler(logging.Testing(), membershipClientMock) - - module := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "name": uuid.NewString(), - }, - "status": map[string]interface{}{ - "ready": false, - }, - }, - } - - membershipClientMock.EXPECT().Send(gomock.Any()) - resourceInformer.AddFunc(module) - require.True(t, ctrl.Satisfied()) - -} - -func TestModuleDelete(t *testing.T) { - t.Parallel() - ctrl := gomock.NewController(t) - membershipClientMock := internal.NewMockMembershipClient(ctrl) - resourceInformer := internal.NewModuleEventHandler(logging.Testing(), membershipClientMock) - - module := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "name": uuid.NewString(), - }, - "status": map[string]interface{}{ - "ready": false, - }, - }, - } - - membershipClientMock.EXPECT().Send(gomock.Any()) - resourceInformer.DeleteFunc(module) - require.True(t, ctrl.Satisfied()) -} - -func TestModuleUpdateStatusNil(t *testing.T) { - t.Parallel() - ctrl := gomock.NewController(t) - membershipClientMock := internal.NewMockMembershipClient(ctrl) - resourceInformer := internal.NewModuleEventHandler(logging.Testing(), membershipClientMock) - - oldModule := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "name": uuid.NewString(), - }, - }, - } - - newModule := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "name": uuid.NewString(), - }, - }, - } - - resourceInformer.UpdateFunc(oldModule, newModule) - require.True(t, ctrl.Satisfied()) - -} -func TestModuleUpdateStatusChanged(t *testing.T) { - - type testCase struct { - isReady bool - wasReady bool - } - - testCases := []testCase{} - for _, a := range []bool{true, false} { - for _, b := range []bool{true, false} { - testCases = append(testCases, testCase{a, b}) - } - } - - for _, tc := range testCases { - tc := tc - t.Run("test", func(t *testing.T) { - t.Parallel() - ctrl := gomock.NewController(t) - membershipClientMock := internal.NewMockMembershipClient(ctrl) - resourceInformer := internal.NewModuleEventHandler(logging.Testing(), membershipClientMock) - - oldModule := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "name": uuid.NewString(), - }, - "status": map[string]interface{}{ - "ready": tc.wasReady, - }, - }, - } - - newModule := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "name": uuid.NewString(), - }, - "status": map[string]interface{}{ - "ready": tc.isReady, - }, - }, - } - if tc.isReady != tc.wasReady { - membershipClientMock.EXPECT().Send(gomock.Any()) - } - resourceInformer.UpdateFunc(oldModule, newModule) - require.True(t, ctrl.Satisfied()) - }) - } - -} diff --git a/ee/agent/internal/informer_stacks.go b/ee/agent/internal/informer_stacks.go deleted file mode 100644 index 316d1df238..0000000000 --- a/ee/agent/internal/informer_stacks.go +++ /dev/null @@ -1,123 +0,0 @@ -package internal - -import ( - "reflect" - - sharedlogging "github.com/formancehq/go-libs/logging" - "github.com/formancehq/stack/components/agent/internal/generated" - "google.golang.org/protobuf/types/known/structpb" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/client-go/tools/cache" -) - -type StackEventHandler struct { - logger sharedlogging.Logger - client MembershipClient -} - -func (h *StackEventHandler) sendStatus(stackName string, status *structpb.Struct) error { - if err := h.client.Send(&generated.Message{ - Message: &generated.Message_StatusChanged{ - StatusChanged: &generated.StatusChanged{ - ClusterName: stackName, - Statuses: status, - }, - }, - }); err != nil { - h.logger.Errorf("Unable to send stack status to server: %s", err) - return err - } - return nil -} - -func (h *StackEventHandler) AddFunc(obj interface{}) { - stack := obj.(*unstructured.Unstructured) - logger := h.logger.WithField("func", "Add").WithField("stack", stack.GetName()) - - status, err := getStatus(stack) - if err != nil { - logger.Errorf("Unable to generate message stack add: %s", err) - return - } - - if status == nil { - return - } - - if err := h.sendStatus(stack.GetName(), status); err != nil { - return - } - logger.Infof("Stack '%s' added", stack.GetName()) - -} - -func (h *StackEventHandler) UpdateFunc(oldObj, newObj interface{}) { - oldStack := oldObj.(*unstructured.Unstructured) - newStack := newObj.(*unstructured.Unstructured) - - logger := h.logger.WithField("func", "Update").WithField("stack", newStack.GetName()) - - oldStatus, err := getStatus(oldStack) - if err != nil { - logger.Errorf("Unable to get old stack status update: %s", err) - } - - newStatus, err := getStatus(newStack) - if err != nil { - logger.Errorf("Unable to get new stack status update: %s", err) - return - } - - oldDisabled, _, err := unstructured.NestedBool(oldStack.Object, "spec", "disabled") - if err != nil { - logger.Errorf("Unable to get new stack `spec.disabled` update: %s", err) - return - } - newDisabled, _, err := unstructured.NestedBool(newStack.Object, "spec", "disabled") - if err != nil { - logger.Errorf("Unable to get new stack `spec.disabled` update: %s", err) - return - } - - // There is no status - // The status has not changed and stack is not been disabled or enabled - if newStatus == nil || (reflect.DeepEqual(oldStatus, newStatus) && oldDisabled == newDisabled) { - return - } - - if err := h.sendStatus(newStack.GetName(), newStatus); err != nil { - return - } - logger.Infof("Stack '%s' updated", newStack.GetName()) - -} - -func (h *StackEventHandler) DeleteFunc(obj interface{}) { - stack := obj.(*unstructured.Unstructured) - logger := h.logger.WithField("func", "Delete").WithField("stack", stack.GetName()) - - if err := h.client.Send(&generated.Message{ - Message: &generated.Message_StackDeleted{ - StackDeleted: &generated.DeletedStack{ - ClusterName: stack.GetName(), - }, - }, - }); err != nil { - logger.Errorf("Unable to send stack delete to server: %s", err) - return - } - logger.Infof("Stack '%s' deleted", stack.GetName()) -} - -func NewStackEventHandler(logger sharedlogging.Logger, membershipClient MembershipClient) cache.ResourceEventHandlerFuncs { - stackEventHandler := &StackEventHandler{ - logger: logger, - client: membershipClient, - } - - return cache.ResourceEventHandlerFuncs{ - AddFunc: stackEventHandler.AddFunc, - UpdateFunc: stackEventHandler.UpdateFunc, - DeleteFunc: stackEventHandler.DeleteFunc, - } -} diff --git a/ee/agent/internal/informer_stacks_test.go b/ee/agent/internal/informer_stacks_test.go deleted file mode 100644 index 374960ab7a..0000000000 --- a/ee/agent/internal/informer_stacks_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package internal_test - -import ( - "fmt" - "testing" - - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/stack/components/agent/internal" - "github.com/google/uuid" - "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" -) - -func TestDeleteFunc(t *testing.T) { - t.Parallel() - ctrl := gomock.NewController(t) - membershipClientMock := internal.NewMockMembershipClient(ctrl) - resourceInformer := internal.NewStackEventHandler(logging.Testing(), membershipClientMock) - - stack := &v1beta1.Stack{ - ObjectMeta: v1.ObjectMeta{ - Name: uuid.NewString(), - }, - } - - membershipClientMock.EXPECT().Send(gomock.Any()) - unstructuredStack, err := runtime.DefaultUnstructuredConverter.ToUnstructured(stack) - if err != nil { - t.Fatalf("failed to convert stack to unstructured: %v", err) - } - - resourceInformer.DeleteFunc(&unstructured.Unstructured{ - Object: unstructuredStack, - }) - - require.True(t, ctrl.Satisfied()) -} - -func TestAddStack(t *testing.T) { - t.Parallel() - ctrl := gomock.NewController(t) - membershipClientMock := internal.NewMockMembershipClient(ctrl) - resourceInformer := internal.NewStackEventHandler(logging.Testing(), membershipClientMock) - - stack := &v1beta1.Stack{ - ObjectMeta: v1.ObjectMeta{ - Name: uuid.NewString(), - }, - Spec: v1beta1.StackSpec{ - Disabled: true, - }, - } - - membershipClientMock.EXPECT().Send(gomock.Any()) - unstructuredStack, err := runtime.DefaultUnstructuredConverter.ToUnstructured(stack) - if err != nil { - t.Fatalf("failed to convert stack to unstructured: %v", err) - } - resourceInformer.AddFunc(&unstructured.Unstructured{ - Object: unstructuredStack, - }) - - require.True(t, ctrl.Satisfied()) -} - -// We are watching .Status and .Spec fields of the stack resource. -// Simulating a change in the status or spec of the stack resource should trigger a call to the membership client. -func TestUpdateStatus(t *testing.T) { - type testCase struct { - isReady bool - isDisabled bool - - wasReady bool - wasDisabled bool - } - testCases := []testCase{} - - for _, b := range []bool{true, false} { - for _, c := range []bool{true, false} { - for _, d := range []bool{true, false} { - for _, e := range []bool{true, false} { - testCases = append(testCases, testCase{ - isReady: b, - isDisabled: c, - - wasReady: d, - wasDisabled: e, - }) - } - } - } - } - - for _, tc := range testCases { - tc := tc - t.Run(fmt.Sprintf("isReady: %t isDisabled: %t wasReady: %t wasDisabled: %t", tc.isReady, tc.isDisabled, tc.wasReady, tc.wasDisabled), func(t *testing.T) { - t.Parallel() - - ctrl := gomock.NewController(t) - membershipClientMock := internal.NewMockMembershipClient(ctrl) - resourceInformer := internal.NewStackEventHandler(logging.Testing(), membershipClientMock) - - oldStack := &v1beta1.Stack{ - ObjectMeta: v1.ObjectMeta{ - Name: uuid.NewString(), - }, - Spec: v1beta1.StackSpec{ - Disabled: tc.wasDisabled, - }, - Status: v1beta1.StackStatus{ - Status: v1beta1.Status{ - Ready: tc.wasReady, - }, - }, - } - - newStack := oldStack.DeepCopy() - newStack.Status.Ready = tc.isReady - newStack.Spec.Disabled = tc.isDisabled - - if tc.isReady != tc.wasReady || tc.isDisabled != tc.wasDisabled { - membershipClientMock.EXPECT().Send(gomock.Any()) - } - - unstructuredOldStack, err := runtime.DefaultUnstructuredConverter.ToUnstructured(oldStack) - if err != nil { - t.Fatalf("failed to convert old stack to unstructured: %v", err) - } - - unstructuredNewStack, err := runtime.DefaultUnstructuredConverter.ToUnstructured(newStack) - if err != nil { - t.Fatalf("failed to convert new stack to unstructured: %v", err) - } - resourceInformer.UpdateFunc(&unstructured.Unstructured{ - Object: unstructuredOldStack, - }, &unstructured.Unstructured{ - Object: unstructuredNewStack, - }) - - require.True(t, ctrl.Satisfied()) - }) - } -} diff --git a/ee/agent/internal/informer_versions.go b/ee/agent/internal/informer_versions.go deleted file mode 100644 index 78417bd8f6..0000000000 --- a/ee/agent/internal/informer_versions.go +++ /dev/null @@ -1,79 +0,0 @@ -package internal - -import ( - "reflect" - - sharedlogging "github.com/formancehq/go-libs/logging" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/stack/components/agent/internal/generated" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/tools/cache" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func convertUnstructured[T client.Object](v any) T { - var t T - t = reflect.New(reflect.TypeOf(t).Elem()).Interface().(T) - if err := runtime.DefaultUnstructuredConverter.FromUnstructured( - v.(*unstructured.Unstructured).Object, t); err != nil { - panic(err) - } - return t -} - -func VersionsEventHandler(logger sharedlogging.Logger, membershipClient MembershipClient) cache.ResourceEventHandler { - return cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - - version := convertUnstructured[*v1beta1.Versions](obj) - - logger.Infof("Detect versions '%s' added", version.Name) - if err := membershipClient.Send(&generated.Message{ - Message: &generated.Message_AddedVersion{ - AddedVersion: &generated.AddedVersion{ - Name: version.Name, - Versions: version.Spec, - }, - }, - }); err != nil { - logger.Errorf("Unable to send version update: %s", err) - } - }, - UpdateFunc: func(oldObj, newObj interface{}) { - - oldVersions := convertUnstructured[*v1beta1.Versions](oldObj) - newVersions := convertUnstructured[*v1beta1.Versions](newObj) - - if reflect.DeepEqual(oldVersions.Spec, newVersions.Spec) { - return - } - - logger.Infof("Detect versions '%s' modified", newVersions.Name) - if err := membershipClient.Send(&generated.Message{ - Message: &generated.Message_UpdatedVersion{ - UpdatedVersion: &generated.UpdatedVersion{ - Name: newVersions.Name, - Versions: newVersions.Spec, - }, - }, - }); err != nil { - logger.Errorf("Unable to send version update: %s", err) - } - }, - DeleteFunc: func(obj interface{}) { - version := convertUnstructured[*v1beta1.Versions](obj) - - logger.Infof("Detect versions '%s' as deleted", version.Name) - if err := membershipClient.Send(&generated.Message{ - Message: &generated.Message_DeletedVersion{ - DeletedVersion: &generated.DeletedVersion{ - Name: version.Name, - }, - }, - }); err != nil { - logger.Errorf("Unable to send version update: %s", err) - } - }, - } -} diff --git a/ee/agent/internal/k8s_client.go b/ee/agent/internal/k8s_client.go deleted file mode 100644 index 44eab9b5c2..0000000000 --- a/ee/agent/internal/k8s_client.go +++ /dev/null @@ -1,157 +0,0 @@ -package internal - -import ( - "context" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/go-libs/logging" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/dynamic/dynamicinformer" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type K8SClient interface { - Get(ctx context.Context, resource string, name string) (*unstructured.Unstructured, error) - Create(ctx context.Context, resource string, o *unstructured.Unstructured) error - Patch(ctx context.Context, resource, name string, body []byte) error - EnsureNotExists(ctx context.Context, resource, name string) error - EnsureNotExistsBySelector(ctx context.Context, resource string, selector labels.Selector) error - List(ctx context.Context, resource string, selector labels.Selector) ([]unstructured.Unstructured, error) -} - -type defaultK8SClient struct { - restClient *rest.RESTClient -} - -func (c defaultK8SClient) Get(ctx context.Context, resource string, name string) (*unstructured.Unstructured, error) { - u := &unstructured.Unstructured{} - if err := c.restClient.Get(). - Resource(resource). - Name(name). - Do(ctx). - Into(u); err != nil { - return nil, err - } - return u, nil -} - -func (c defaultK8SClient) Create(ctx context.Context, resource string, o *unstructured.Unstructured) error { - return c.restClient. - Post(). - Resource(resource). - Body(o). - Do(ctx). - Into(o) -} - -func (c defaultK8SClient) Patch(ctx context.Context, resource, name string, body []byte) error { - return c.restClient.Patch(types.MergePatchType). - Name(name). - Body(body). - Resource(resource). - Do(ctx). - Error() -} - -func (c defaultK8SClient) EnsureNotExists(ctx context.Context, resource, name string) error { - return client.IgnoreNotFound( - c.restClient.Delete(). - Resource(resource). - Name(name). - Do(ctx). - Error(), - ) -} - -func (c defaultK8SClient) EnsureNotExistsBySelector(ctx context.Context, resource string, selector labels.Selector) error { - logging.FromContext(ctx).Debugf("Deleting resources of type %s with selector %s", resource, selector.String()) - return client.IgnoreNotFound( - c.restClient.Delete(). - Resource(resource). - VersionedParams( - &metav1.ListOptions{ - LabelSelector: selector.String(), - }, scheme.ParameterCodec). - Do(ctx). - Error(), - ) -} - -func (c defaultK8SClient) List(ctx context.Context, resource string, add labels.Selector) ([]unstructured.Unstructured, error) { - list := &unstructured.UnstructuredList{} - if err := c.restClient.Get(). - Resource(resource). - VersionedParams(&metav1.ListOptions{ - LabelSelector: add.String(), - }, scheme.ParameterCodec). - Do(ctx). - Into(list); err != nil { - return nil, err - } - return list.Items, nil -} - -var _ K8SClient = (*defaultK8SClient)(nil) - -func NewDefaultK8SClient(restClient *rest.RESTClient) K8SClient { - return defaultK8SClient{ - restClient: restClient, - } -} - -type cachedK8SClient struct { - K8SClient - informerFactory dynamicinformer.DynamicSharedInformerFactory -} - -func (c cachedK8SClient) Get(ctx context.Context, resource string, name string) (*unstructured.Unstructured, error) { - ret, err := c.informerFactory.ForResource(schema.GroupVersionResource{ - Group: "formance.com", - Version: "v1beta1", - Resource: resource, - }). - Lister(). - Get(name) - if err != nil { - if errors.IsNotFound(err) { - return c.K8SClient.Get(ctx, resource, name) - } - return nil, err - } - logging.FromContext(ctx).Debugf("Cache hit for resource %s/%s", resource, name) - return ret.(*unstructured.Unstructured), nil -} - -func (c cachedK8SClient) List(_ context.Context, resource string, selector labels.Selector) ([]unstructured.Unstructured, error) { - ret, err := c.informerFactory.ForResource(schema.GroupVersionResource{ - Group: "formance.com", - Version: "v1beta1", - Resource: resource, - }). - Lister(). - List(selector) - if err != nil { - return nil, err - } - - return collectionutils.Map(ret, func(from runtime.Object) unstructured.Unstructured { - return *from.(*unstructured.Unstructured) - }), nil -} - -var _ K8SClient = (*defaultK8SClient)(nil) - -func NewCachedK8SClient(k8sClient K8SClient, informerFactory dynamicinformer.DynamicSharedInformerFactory) K8SClient { - return cachedK8SClient{ - K8SClient: k8sClient, - informerFactory: informerFactory, - } -} diff --git a/ee/agent/internal/k8s_client_test.go b/ee/agent/internal/k8s_client_test.go deleted file mode 100644 index f2458aacf3..0000000000 --- a/ee/agent/internal/k8s_client_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package internal - -import ( - "context" - "fmt" - "reflect" - "testing" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/google/uuid" - "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func TestEnsureNotExistBySelector(t *testing.T) { - test(t, func(ctx context.Context, testConfig *testConfig) { - k8sClient := NewDefaultK8SClient(testConfig.client) - - for gvk, rtype := range scheme.Scheme.AllKnownTypes() { - gvk := gvk - - object := reflect.New(rtype).Interface() - if _, ok := object.(v1beta1.Module); !ok { - continue - } - - t.Run(fmt.Sprintf("EnsureNotExistBySelector %s", gvk.Kind), func(t *testing.T) { - t.Parallel() - name := uuid.NewString() - module := unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": gvk.GroupVersion().String(), - "kind": gvk.Kind, - "metadata": map[string]interface{}{ - "name": name, - "labels": map[string]interface{}{ - "formance.com/created-by-agent": "true", - "formance.com/stack": name, - }, - }, - }, - } - - resources, err := testConfig.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) - require.NoError(t, err) - - require.NoError(t, testConfig.client.Post().Resource(resources.Resource.Resource).Body(&module).Do(ctx).Error()) - - require.NoError(t, k8sClient.EnsureNotExistsBySelector(ctx, resources.Resource.Resource, stackLabels(module.GetName()))) - require.NoError(t, client.IgnoreNotFound(testConfig.client.Get().Resource(resources.Resource.Resource).Name(module.GetName()).Do(ctx).Error())) - }) - - } - }) -} diff --git a/ee/agent/internal/membership_client.go b/ee/agent/internal/membership_client.go deleted file mode 100644 index d68e5abba4..0000000000 --- a/ee/agent/internal/membership_client.go +++ /dev/null @@ -1,246 +0,0 @@ -package internal - -import ( - "context" - "io" - "time" - - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/stack/components/agent/internal/generated" - - "github.com/pkg/errors" - "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" - "go.opentelemetry.io/otel/trace" - "google.golang.org/grpc" - "google.golang.org/grpc/metadata" -) - -const ( - metadataID = "id" - metadataBaseUrl = "baseUrl" - metadataProduction = "production" - metadataVersion = "version" - metadataCapabilities = "capabilities" - - capabilityEE = "EE" - capabilityModuleList = "MODULE_LIST" -) - -type membershipClient struct { - clientInfo ClientInfo - stopChan chan chan error - stopped chan struct{} - - serverClient generated.ServerClient - connectClient generated.Server_ConnectClient - connectContext context.Context - connectCancel func() - authenticator Authenticator - - orders chan *generated.Order - opts []grpc.DialOption - - address string - - messages chan *generated.Message -} - -func (c *membershipClient) connectMetadata(ctx context.Context, modules []string, eeModules []string) (metadata.MD, error) { - - md, err := c.authenticator.authenticate(ctx) - if err != nil { - return nil, errors.Wrap(err, "authenticating client") - } - - md.Append(metadataID, c.clientInfo.ID) - md.Append(metadataBaseUrl, c.clientInfo.BaseUrl.String()) - md.Append(metadataProduction, func() string { - if c.clientInfo.Production { - return "true" - } - return "false" - }()) - md.Append(metadataVersion, c.clientInfo.Version) - md.Append(metadataCapabilities, capabilityEE, capabilityModuleList) - md.Append(capabilityModuleList, modules...) - md.Append(capabilityEE, eeModules...) - - return md, nil -} - -func LoggingClientStreamInterceptor(l logging.Logger) grpc.StreamClientInterceptor { - return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { - span := trace.SpanFromContext(ctx) - - logging.FromContext(ctx). - WithField("traceId", span.SpanContext().TraceID()). - WithField("spanId", span.SpanContext().SpanID()). - WithField("method", method). - Infof("Starting stream") - return streamer(logging.ContextWithLogger(ctx, l), desc, cc, method, opts...) - } -} - -func (c *membershipClient) connect(ctx context.Context, modules []string, eeModules []string) error { - logging.FromContext(ctx).WithFields(map[string]any{ - "id": c.clientInfo.ID, - }).Infof("Establish connection to server") - c.connectContext, c.connectCancel = context.WithCancel(ctx) - - opts := append(c.opts, - grpc.WithChainStreamInterceptor( - LoggingClientStreamInterceptor(logging.FromContext(ctx)), - ), - grpc.WithStatsHandler(otelgrpc.NewClientHandler()), - ) - conn, err := grpc.Dial(c.address, opts...) - if err != nil { - return err - } - - c.serverClient = generated.NewServerClient(conn) - - md, err := c.connectMetadata(ctx, modules, eeModules) - if err != nil { - return err - } - connectContext := metadata.NewOutgoingContext(c.connectContext, md) - connectClient, err := c.serverClient.Join(connectContext) - if err != nil { - return err - } - c.connectClient = connectClient - - return nil -} - -func (c *membershipClient) Send(message *generated.Message) error { - select { - case <-c.stopped: - return errors.New("stopped") - case c.messages <- message: - return nil - } -} - -func (c *membershipClient) sendPong(ctx context.Context) { - if err := c.connectClient.SendMsg(&generated.Message{ - Message: &generated.Message_Pong{ - Pong: &generated.Pong{}, - }, - }); err != nil { - logging.FromContext(ctx).Errorf("Unable to send pong to server: %s", err) - if errors.Is(err, io.EOF) { - panic(err) - } - } -} - -func (c *membershipClient) Start(ctx context.Context) error { - - var ( - errCh = make(chan error, 1) - ) - go func() { - for { - msg := &generated.Order{} - if err := c.connectClient.RecvMsg(msg); err != nil { - if err == io.EOF { - select { - case <-c.stopped: - default: - errCh <- err - } - return - } - errCh <- err - return - } - - if msg.GetPing() != nil { - c.sendPong(ctx) - continue - } - - select { - case c.orders <- msg: - case <-ctx.Done(): - return - } - } - }() - go func() { - for { - select { - case <-time.After(5 * time.Second): - c.sendPong(ctx) - case <-ctx.Done(): - return - } - } - }() - - for { - select { - case <-ctx.Done(): - return ctx.Err() - case ch := <-c.stopChan: - close(c.stopped) - if err := c.connectClient.CloseSend(); err != nil { - ch <- err - //nolint:nilerr - return nil - } - c.connectCancel() - for { - msg := &generated.Order{} - if err := c.connectClient.RecvMsg(msg); err != nil { // Drain messages - break - } - } - - ch <- nil - return nil - case msg := <-c.messages: - if err := c.connectClient.SendMsg(msg); err != nil { - panic(err) - } - <-time.After(50 * time.Millisecond) - case err := <-errCh: - logging.FromContext(ctx).Errorf("Stream closed with error: %s", err) - return err - } - } -} - -func (c *membershipClient) Stop(ctx context.Context) error { - ch := make(chan error) - select { - case <-ctx.Done(): - return ctx.Err() - case c.stopChan <- ch: - select { - case <-ctx.Done(): - return ctx.Err() - case err := <-ch: - return err - } - } -} - -func (c *membershipClient) Orders() chan *generated.Order { - return c.orders -} - -func NewMembershipClient(authenticator Authenticator, clientInfo ClientInfo, address string, opts ...grpc.DialOption) *membershipClient { - return &membershipClient{ - stopChan: make(chan chan error), - authenticator: authenticator, - clientInfo: clientInfo, - opts: opts, - address: address, - orders: make(chan *generated.Order), - messages: make(chan *generated.Message), - stopped: make(chan struct{}), - } -} diff --git a/ee/agent/internal/membership_client_generated.go b/ee/agent/internal/membership_client_generated.go deleted file mode 100644 index 5820ec7902..0000000000 --- a/ee/agent/internal/membership_client_generated.go +++ /dev/null @@ -1,68 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: /src/ee/agent/internal/membership_listener.go -// -// Generated by this command: -// -// mockgen -source=/src/ee/agent/internal/membership_listener.go -destination=/src/ee/agent/internal/membership_client_generated.go -package=internal . MembershipClient -// - -// Package internal is a generated GoMock package. -package internal - -import ( - reflect "reflect" - - generated "github.com/formancehq/stack/components/agent/internal/generated" - gomock "go.uber.org/mock/gomock" -) - -// MockMembershipClient is a mock of MembershipClient interface. -type MockMembershipClient struct { - ctrl *gomock.Controller - recorder *MockMembershipClientMockRecorder -} - -// MockMembershipClientMockRecorder is the mock recorder for MockMembershipClient. -type MockMembershipClientMockRecorder struct { - mock *MockMembershipClient -} - -// NewMockMembershipClient creates a new mock instance. -func NewMockMembershipClient(ctrl *gomock.Controller) *MockMembershipClient { - mock := &MockMembershipClient{ctrl: ctrl} - mock.recorder = &MockMembershipClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockMembershipClient) EXPECT() *MockMembershipClientMockRecorder { - return m.recorder -} - -// Orders mocks base method. -func (m *MockMembershipClient) Orders() chan *generated.Order { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Orders") - ret0, _ := ret[0].(chan *generated.Order) - return ret0 -} - -// Orders indicates an expected call of Orders. -func (mr *MockMembershipClientMockRecorder) Orders() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Orders", reflect.TypeOf((*MockMembershipClient)(nil).Orders)) -} - -// Send mocks base method. -func (m *MockMembershipClient) Send(message *generated.Message) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Send", message) - ret0, _ := ret[0].(error) - return ret0 -} - -// Send indicates an expected call of Send. -func (mr *MockMembershipClientMockRecorder) Send(message any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockMembershipClient)(nil).Send), message) -} diff --git a/ee/agent/internal/membership_listener.go b/ee/agent/internal/membership_listener.go deleted file mode 100644 index f659a231e2..0000000000 --- a/ee/agent/internal/membership_listener.go +++ /dev/null @@ -1,446 +0,0 @@ -//nolint:nosnakecase -package internal - -import ( - "context" - "encoding/json" - "fmt" - "net/url" - "reflect" - "slices" - "strings" - "sync" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/trace" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/selection" - - "github.com/alitto/pond" - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/stack/components/agent/internal/generated" - "github.com/pkg/errors" - "k8s.io/apimachinery/pkg/api/equality" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -//go:generate mockgen -source=/src/ee/agent/internal/membership_listener.go -destination=/src/ee/agent/internal/membership_client_generated.go -package=internal . MembershipClient -type MembershipClient interface { - Orders() chan *generated.Order - Send(message *generated.Message) error -} - -type MembershipClientMock struct { - mu sync.Mutex - orders chan *generated.Order - messages []*generated.Message -} - -func (m MembershipClientMock) Orders() chan *generated.Order { - return m.orders -} - -func (m *MembershipClientMock) Send(message *generated.Message) error { - m.mu.Lock() - defer m.mu.Unlock() - - m.messages = append(m.messages, message) - return nil -} - -func (m *MembershipClientMock) GetMessages() []*generated.Message { - return m.messages -} - -func NewMembershipClientMock() *MembershipClientMock { - return &MembershipClientMock{ - orders: make(chan *generated.Order), - } -} - -type ClientInfo struct { - ID string - BaseUrl *url.URL - Production bool - Version string -} - -type membershipListener struct { - clientInfo ClientInfo - client K8SClient - - restMapper meta.RESTMapper - orders MembershipClient - wp *pond.WorkerPool -} - -func (c *membershipListener) Start(ctx context.Context) { - defer c.wp.StopAndWait() - for { - select { - case msg, ok := <-c.orders.Orders(): - if !ok { - return - } - - c.wp.Submit(func() { - ctx, span := otel.GetTracerProvider().Tracer("com.formance.agent").Start(ctx, "newOrder", trace.WithNewRoot()) - defer span.End() - logging.FromContext(ctx). - WithField("traceId", span.SpanContext().TraceID()). - WithField("spanId", span.SpanContext().SpanID()). - Infof("Got message from membership: %T", msg.GetMessage()) - switch msg := msg.Message.(type) { - case *generated.Order_ExistingStack: - span.SetName("syncExistingStack") - c.syncExistingStack(ctx, msg.ExistingStack) - case *generated.Order_DeletedStack: - span.SetName("deleteStack") - c.deleteStack(ctx, msg.DeletedStack) - case *generated.Order_DisabledStack: - span.SetName("disableStack") - c.disableStack(ctx, msg.DisabledStack) - case *generated.Order_EnabledStack: - span.SetName("enableStack") - c.enableStack(ctx, msg.EnabledStack) - } - }) - } - } -} - -func (c *membershipListener) syncExistingStack(ctx context.Context, membershipStack *generated.Stack) { - versions := membershipStack.Versions - if versions == "" { - versions = "default" - } - - metadata := c.generateMetadata(membershipStack) - - stack, err := c.createOrUpdate(ctx, v1beta1.GroupVersion.WithKind("Stack"), membershipStack.ClusterName, membershipStack.ClusterName, nil, map[string]any{ - "metadata": metadata, - "spec": map[string]any{ - "versionsFromFile": versions, - "disabled": membershipStack.Disabled, - "enableAudit": membershipStack.EnableAudit, - }, - }) - if err != nil { - logging.FromContext(ctx).Errorf("Unable to create stack cluster side: %s", err) - return - } - - c.syncModules(ctx, metadata, stack, membershipStack) - c.syncStargate(ctx, metadata, stack, membershipStack) - c.syncAuthClients(ctx, metadata, stack, membershipStack.StaticClients) - - logging.FromContext(ctx).Infof("Stack %s updated cluster side", stack.GetName()) -} - -func (c *membershipListener) generateMetadata(membershipStack *generated.Stack) map[string]any { - additionalLabels := map[string]any{} - for key, value := range membershipStack.AdditionalLabels { - additionalLabels["formance.com/"+key] = value - } - - additionalAnnotations := map[string]any{} - for key, value := range membershipStack.AdditionalAnnotations { - additionalAnnotations["formance.com/"+key] = value - } - - return map[string]any{ - "annotations": additionalAnnotations, - "labels": additionalLabels, - } - -} -func (c *membershipListener) syncModules(ctx context.Context, metadata map[string]any, stack *unstructured.Unstructured, membershipStack *generated.Stack) { - modules := collectionutils.Map(membershipStack.Modules, func(module *generated.Module) string { - return strings.ToLower(module.Name) - }) - logger := logging.FromContext(ctx).WithField("stack", membershipStack.ClusterName) - logger.Infof("Syncing modules for stack %s", membershipStack.Modules) - for gvk, rtype := range scheme.Scheme.AllKnownTypes() { - object := reflect.New(rtype).Interface() - if _, ok := object.(v1beta1.Module); !ok { - continue - } - - if gvk.Kind == "Stargate" { - continue - } - resources, err := c.restMapper.RESTMapping(gvk.GroupKind(), gvk.Version) - if err != nil { - logger.Errorf("Unable to get resources for %s: %s", gvk.Kind, err) - continue - } - singular, err := c.restMapper.ResourceSingularizer(resources.Resource.Resource) - if err != nil { - logger.Errorf("Unable to get singular for %s: %s", gvk.Kind, err) - continue - } - logger.Debugf("Resource: checking module resource %s, singular: %s", resources.Resource.Resource, singular) - if !slices.Contains(modules, singular) { - if err := c.deleteModule(ctx, logger, resources.Resource.Resource, stack.GetName()); err != nil { - logger.Errorf("Unable to get and delete module %s cluster side: %s", gvk.Kind, err) - } - continue - } - - switch gvk.Kind { - case "Auth": - if _, err := c.createOrUpdateStackDependency(ctx, stack.GetName(), stack.GetName(), stack, gvk, map[string]any{ - "metadata": metadata, - "spec": map[string]any{ - "delegatedOIDCServer": map[string]any{ - "issuer": membershipStack.AuthConfig.Issuer, - "clientID": membershipStack.AuthConfig.ClientId, - "clientSecret": membershipStack.AuthConfig.ClientSecret, - }, - }, - }); err != nil { - logger.Errorf("Unable to create module Auth cluster side: %s", err) - } - case "Gateway": - if _, err := c.createOrUpdateStackDependency(ctx, stack.GetName(), stack.GetName(), stack, gvk, map[string]any{ - "metadata": metadata, - "spec": map[string]any{ - "ingress": map[string]any{ - "host": fmt.Sprintf("%s.%s", stack.GetName(), c.clientInfo.BaseUrl.Host), - "scheme": c.clientInfo.BaseUrl.Scheme, - }, - }, - }); client.IgnoreNotFound(err) != nil { - logger.Errorf("Unable to create module Stargate cluster side: %s", err) - } - default: - if _, err := c.createOrUpdateStackDependency(ctx, stack.GetName(), stack.GetName(), stack, gvk, map[string]any{ - "metadata": metadata, - }); err != nil { - logger.Errorf("Unable to create module %s cluster side: %s", gvk.Kind, err) - } - } - - } -} - -func (c *membershipListener) deleteModule(ctx context.Context, logger logging.Logger, resource string, stackName string) error { - logger.Debugf("Deleting module %s", resource) - - return c.client.EnsureNotExistsBySelector(ctx, resource, stackLabels(stackName)) -} - -func (c *membershipListener) syncStargate(ctx context.Context, metadata map[string]any, stack *unstructured.Unstructured, membershipStack *generated.Stack) { - stargateName := fmt.Sprintf("%s-stargate", membershipStack.ClusterName) - if membershipStack.StargateConfig != nil && membershipStack.StargateConfig.Enabled { - parts := strings.Split(stack.GetName(), "-") - - if _, err := c.createOrUpdateStackDependency(ctx, stack.GetName(), stack.GetName(), stack, v1beta1.GroupVersion.WithKind("Stargate"), map[string]any{ - "metadata": metadata, - "spec": map[string]any{ - "organizationID": parts[0], - "stackID": parts[1], - "serverURL": membershipStack.StargateConfig.Url, - "auth": map[string]any{ - "issuer": membershipStack.AuthConfig.Issuer, - "clientID": membershipStack.AuthConfig.ClientId, - "clientSecret": membershipStack.AuthConfig.ClientSecret, - }, - }, - }); err != nil { - logging.FromContext(ctx).Errorf("Unable to create module Stargate cluster side: %s", err) - } - } else { - if err := c.client.EnsureNotExists(ctx, "Stargates", stargateName); err != nil { - logging.FromContext(ctx).Errorf("Unable to delete module Stargate cluster side: %s", err) - } - } -} - -func (c *membershipListener) syncAuthClients(ctx context.Context, metadata map[string]any, stack *unstructured.Unstructured, staticClients []*generated.AuthClient) { - expectedAuthClients := make([]*unstructured.Unstructured, 0) - for _, client := range staticClients { - authClient, err := c.createOrUpdateStackDependency(ctx, fmt.Sprintf("%s-%s", stack.GetName(), client.Id), stack.GetName(), - stack, v1beta1.GroupVersion.WithKind("AuthClient"), map[string]any{ - "metadata": metadata, - "spec": map[string]any{ - "id": client.Id, - "public": client.Public, - }, - }) - if err != nil { - logging.FromContext(ctx).Errorf("Unable to create AuthClient cluster side: %s", err) - continue - } - expectedAuthClients = append(expectedAuthClients, authClient) - } - - authClients, err := c.client.List(ctx, "AuthClients", stackLabels(stack.GetName())) - if err != nil { - logging.FromContext(ctx).Errorf("Unable to list AuthClient cluster side: %s", err) - return - } - - authClientsToDelete := collectionutils.Reduce(authClients, func(acc []string, item unstructured.Unstructured) []string { - for _, expectedClient := range expectedAuthClients { - if expectedClient.GetName() == item.GetName() { - return acc - } - } - return append(acc, item.GetName()) - }, []string{}) - - for _, name := range authClientsToDelete { - logging.FromContext(ctx).Infof("Deleting AuthClient %s", name) - if err := c.client.EnsureNotExists(ctx, "AuthClients", name); err != nil { - logging.FromContext(ctx).Errorf("Unable to delete AuthClient %s cluster side: %s", name, err) - } - } -} - -func (c *membershipListener) deleteStack(ctx context.Context, stack *generated.DeletedStack) { - if err := c.client.EnsureNotExists(ctx, "Stacks", stack.ClusterName); err != nil { - logging.FromContext(ctx).Errorf("Deleting cluster side: %s", err) - return - } - logging.FromContext(ctx).Infof("Stack %s deleted", stack.ClusterName) -} - -func (c *membershipListener) disableStack(ctx context.Context, stack *generated.DisabledStack) { - - if err := c.client.Patch(ctx, "Stacks", stack.ClusterName, []byte(`{"spec": {"disabled": true}}`)); err != nil { - logging.FromContext(ctx).Errorf("Disabling cluster side: %s", err) - return - } - - logging.FromContext(ctx).Infof("Stack %s disabled", stack.ClusterName) -} - -func (c *membershipListener) enableStack(ctx context.Context, stack *generated.EnabledStack) { - if err := c.client.Patch(ctx, "Stacks", stack.ClusterName, []byte(`{"spec": {"disabled": false}}`)); err != nil { - logging.FromContext(ctx).Errorf("Disabling cluster side: %s", err) - return - } - - logging.FromContext(ctx).Infof("Stack %s enabled", stack.ClusterName) -} - -func (c *membershipListener) createOrUpdate(ctx context.Context, gvk schema.GroupVersionKind, name string, stackName string, owner *metav1.OwnerReference, content map[string]any) (*unstructured.Unstructured, error) { - - logger := logging.FromContext(ctx).WithFields(map[string]any{ - "gvk": gvk, - }) - logger.Infof("creating object '%s'", name) - if content["metadata"] == nil { - content["metadata"] = map[string]any{} - } - - if content["metadata"].(map[string]any)["labels"] == nil { - content["metadata"].(map[string]any)["labels"] = map[string]any{} - } - - content["metadata"].(map[string]any)["labels"].(map[string]any)["formance.com/created-by-agent"] = "true" - content["metadata"].(map[string]any)["labels"].(map[string]any)["formance.com/stack"] = stackName - content["metadata"].(map[string]any)["name"] = name - - restMapping, err := c.restMapper.RESTMapping(gvk.GroupKind()) - if err != nil { - return nil, errors.Wrap(err, "getting rest mapping") - } - - u, err := c.client.Get(ctx, restMapping.Resource.Resource, name) - if err != nil { - if !apierrors.IsNotFound(err) { - return nil, errors.Wrap(err, "reading object") - } - - logger.Infof("Object not found, create a new one") - - u := &unstructured.Unstructured{} - u.SetUnstructuredContent(content) - u.SetGroupVersionKind(gvk) - u.SetName(name) - if owner != nil { - u.SetOwnerReferences([]metav1.OwnerReference{*owner}) - } - - if err := c.client.Create(ctx, restMapping.Resource.Resource, u); err != nil { - return nil, errors.Wrap(err, "creating object") - } - - return u, nil - - } - - if equality.Semantic.DeepDerivative(content, u.Object) { - logger.Infof("Object found and has expected content, skip it") - return u, nil - } - - logger.Infof("Object exists and content differ, patch it") - contentData, err := json.Marshal(content) - if err != nil { - return nil, err - } - - if err := c.client.Patch(ctx, restMapping.Resource.Resource, name, contentData); err != nil { - return nil, errors.Wrap(err, "patching object") - } - - return u, nil -} - -func (c *membershipListener) createOrUpdateStackDependency( - ctx context.Context, - name string, - stackName string, - stack *unstructured.Unstructured, - gvk schema.GroupVersionKind, - content map[string]any, -) (*unstructured.Unstructured, error) { - if _, ok := content["spec"]; !ok { - content["spec"] = map[string]any{} - } - content["spec"].(map[string]any)["stack"] = stack.GetName() - - return c.createOrUpdate(ctx, gvk, name, stackName, - &metav1.OwnerReference{ - APIVersion: "formance.com/v1beta1", - Kind: "Stack", - Name: stack.GetName(), - UID: stack.GetUID(), - }, content) -} - -func NewMembershipListener(client K8SClient, clientInfo ClientInfo, mapper meta.RESTMapper, - orders MembershipClient) *membershipListener { - return &membershipListener{ - client: client, - clientInfo: clientInfo, - restMapper: mapper, - orders: orders, - wp: pond.New(5, 5), - } -} - -func must[T any](t *T, err error) T { - if err != nil { - panic(err) - } - return *t -} - -func stackLabels(stackName string) labels.Selector { - return labels.NewSelector().Add( - must(labels.NewRequirement("formance.com/created-by-agent", selection.Equals, []string{"true"})), - must(labels.NewRequirement("formance.com/stack", selection.Equals, []string{stackName})), - ) -} diff --git a/ee/agent/internal/membership_listener_test.go b/ee/agent/internal/membership_listener_test.go deleted file mode 100644 index 1f2ea933d6..0000000000 --- a/ee/agent/internal/membership_listener_test.go +++ /dev/null @@ -1,208 +0,0 @@ -package internal - -import ( - "context" - "math/rand" - "path/filepath" - osRuntime "runtime" - "testing" - "time" - - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/stack/components/agent/internal/generated" - "github.com/google/uuid" - "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/api/meta" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" -) - -type testConfig struct { - restConfig *rest.Config - mapper meta.RESTMapper - client *rest.RESTClient -} - -func test(t *testing.T, fn func(context.Context, *testConfig)) { - _, filename, _, _ := osRuntime.Caller(0) - apiServer := envtest.APIServer{} - apiServer.Configure(). - Set("service-cluster-ip-range", "10.0.0.0/20") - - require.NoError(t, v1beta1.AddToScheme(scheme.Scheme)) - testEnv := &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join(filepath.Dir(filename), "..", "..", "..", "components", "operator", - "config", "crd", "bases"), - }, - ErrorIfCRDPathMissing: true, - ControlPlane: envtest.ControlPlane{ - APIServer: &apiServer, - }, - Scheme: scheme.Scheme, - } - - restConfig, err := testEnv.Start() - - require.NoError(t, err) - - restConfig.GroupVersion = &v1beta1.GroupVersion - restConfig.NegotiatedSerializer = scheme.Codecs.WithoutConversion() - restConfig.APIPath = "/apis" - - k8sClient, err := rest.RESTClientFor(restConfig) - require.NoError(t, err) - - mapper, err := CreateRestMapper(restConfig) - require.NoError(t, err) - - t.Cleanup( - func() { - require.NoError(t, testEnv.Stop()) - }, - ) - fn(logging.TestingContext(), &testConfig{ - restConfig: restConfig, - mapper: mapper, - client: k8sClient, - }) -} -func TestDeleteModule(t *testing.T) { - - type testCase struct { - name string - withLabels bool - } - - testCases := []testCase{ - { - name: "with labels", - withLabels: true, - }, - { - name: "without labels", - withLabels: false, - }, - } - test(t, func(ctx context.Context, testConfig *testConfig) { - t.Parallel() - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - stackName := uuid.NewString() - recon := v1beta1.Reconciliation{ - ObjectMeta: v1.ObjectMeta{ - Name: uuid.NewString(), - }, - } - if tc.withLabels { - recon.Labels = map[string]string{ - "formance.com/created-by-agent": "true", - "formance.com/stack": stackName, - } - } - - gvk := v1beta1.GroupVersion.WithKind("Reconciliation") - resources, err := testConfig.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) - require.NoError(t, err) - - require.NoError(t, testConfig.client.Post().Resource(resources.Resource.Resource).Body(&recon).Do(ctx).Error()) - orders := NewMembershipClientMock() - - membershipListener := NewMembershipListener(NewDefaultK8SClient(testConfig.client), ClientInfo{}, testConfig.mapper, orders) - - if tc.withLabels { - require.NoError(t, membershipListener.deleteModule(ctx, logging.Testing(), resources.Resource.Resource, stackName)) - require.Error(t, testConfig.client.Get().Resource(resources.Resource.Resource).Name(recon.Name).Do(ctx).Error()) - } - - if !tc.withLabels { - require.NoError(t, testConfig.client.Get().Resource(resources.Resource.Resource).Name(recon.Name).Do(ctx).Error()) - } - }) - } - }) -} - -func TestRetrieveModuleList(t *testing.T) { - t.Parallel() - test(t, func(ctx context.Context, testConfig *testConfig) { - modules, eeModules, err := retrieveModuleList(ctx, testConfig.restConfig) - require.NoError(t, err) - require.NotEmpty(t, modules) - require.NotEmpty(t, eeModules) - for _, module := range eeModules { - require.Contains(t, modules, module) - } - }) -} -func TestSyncAuthClients(t *testing.T) { - newStaticClient := func(stackName string) *v1beta1.AuthClient { - return &v1beta1.AuthClient{ - ObjectMeta: v1.ObjectMeta{ - Name: uuid.NewString(), - Labels: map[string]string{ - "formance.com/created-by-agent": "true", - "formance.com/stack": stackName, - }, - }, - } - - } - - letter := []rune("abcdefghijklmnopqrstuvwxyz") - rand := func(i int) string { - b := make([]rune, i) - for i := range b { - b[i] = letter[rand.Intn(len(letter))] - } - return string(b) - } - newGeneratedClient := func() *generated.AuthClient { - return &generated.AuthClient{ - Id: rand(4), - Public: true, - } - } - test(t, func(ctx context.Context, tc *testConfig) { - t.Parallel() - listener := NewMembershipListener(NewDefaultK8SClient(tc.client), ClientInfo{}, tc.mapper, NewMembershipClientMock()) - - stackName := uuid.NewString() + "-" + rand(4) - stackuid := uuid.NewString() - - authClientToRemove := []*v1beta1.AuthClient{ - newStaticClient(stackName), - newStaticClient(stackName), - newStaticClient(stackName), - } - - clients := []*generated.AuthClient{ - newGeneratedClient(), - newGeneratedClient(), - } - - stack := &unstructured.Unstructured{} - stack.SetName(stackName) - stack.SetUID(types.UID(stackuid)) - - for _, client := range authClientToRemove { - require.NoError(t, tc.client.Post().Resource("AuthClients").Body(client).Do(ctx).Error()) - } - - listener.syncAuthClients(ctx, map[string]any{}, stack, clients) - - clientsList := &v1beta1.AuthClientList{} - require.Eventually(t, func() bool { - require.NoError(t, tc.client.Get().Resource("AuthClients").Do(ctx).Into(clientsList)) - return len(clientsList.Items) == len(clients) - }, 5*time.Second, 500*time.Millisecond) - - }) -} diff --git a/ee/agent/internal/module.go b/ee/agent/internal/module.go deleted file mode 100644 index 5948633bdc..0000000000 --- a/ee/agent/internal/module.go +++ /dev/null @@ -1,228 +0,0 @@ -package internal - -import ( - "context" - "reflect" - "sort" - "time" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/pkg/errors" - "go.uber.org/fx" - "google.golang.org/grpc" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" - v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - apiextensionsv1client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/discovery" - "k8s.io/client-go/dynamic" - "k8s.io/client-go/dynamic/dynamicinformer" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "k8s.io/client-go/restmapper" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/tools/clientcmd" -) - -func NewDynamicSharedInformerFactory(client *dynamic.DynamicClient, resyncPeriod time.Duration) dynamicinformer.DynamicSharedInformerFactory { - return dynamicinformer.NewDynamicSharedInformerFactory(client, resyncPeriod) -} - -func runInformers(lc fx.Lifecycle, factory dynamicinformer.DynamicSharedInformerFactory) { - lc.Append(fx.Hook{ - OnStart: func(ctx context.Context) error { - stopCh := make(chan struct{}) - factory.Start(stopCh) - return nil - }, - OnStop: func(ctx context.Context) error { - factory.Shutdown() - return nil - }, - }) -} - -func NewK8SConfig(kubeConfigPath string) (*rest.Config, error) { - config, err := rest.InClusterConfig() - if err != nil { - logging.Info("Does not seems to be in cluster, trying to load k8s client from kube config file") - config, err = clientcmd.BuildConfigFromFlags("", kubeConfigPath) - if err != nil { - return nil, err - } - } - - config.GroupVersion = &v1beta1.GroupVersion - config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() - config.APIPath = "/apis" - - return config, nil -} - -func createInformer(factory dynamicinformer.DynamicSharedInformerFactory, resource string, handler cache.ResourceEventHandler) error { - informer := factory. - ForResource(schema.GroupVersionResource{ - Group: "formance.com", - Version: "v1beta1", - Resource: resource, - }). - Informer() - - _, err := informer.AddEventHandler(handler) - if err != nil { - return errors.Wrap(err, "unable to add event handler") - } - return nil -} - -func CreateVersionsInformer(factory dynamicinformer.DynamicSharedInformerFactory, - logger logging.Logger, client MembershipClient) error { - logger = logger.WithFields(map[string]any{ - "component": "versions", - }) - logger.Info("Creating informer") - return createInformer(factory, "versions", VersionsEventHandler(logger, client)) -} - -func CreateStacksInformer(factory dynamicinformer.DynamicSharedInformerFactory, - logger logging.Logger, client MembershipClient) error { - logger = logger.WithFields(map[string]any{ - "component": "stacks", - }) - logger.Info("Creating informer") - return createInformer(factory, "stacks", NewStackEventHandler(logger, client)) -} - -func CreateModulesInformers(factory dynamicinformer.DynamicSharedInformerFactory, - restMapper meta.RESTMapper, logger logging.Logger, client MembershipClient) error { - - for gvk, rtype := range scheme.Scheme.AllKnownTypes() { - object := reflect.New(rtype).Interface() - _, ok := object.(v1beta1.Module) - if !ok { - continue - } - - restMapping, err := restMapper.RESTMapping(gvk.GroupKind(), gvk.Version) - if err != nil { - return err - } - - logger = logger.WithFields(map[string]any{ - "component": restMapping.Resource.Resource, - }) - - logger.Info("Creating informer") - if err := createInformer(factory, restMapping.Resource.Resource, NewModuleEventHandler(logger, client)); err != nil { - return err - } - } - return nil -} - -func CreateRestMapper(config *rest.Config) (meta.RESTMapper, error) { - discovery := discovery.NewDiscoveryClientForConfigOrDie(config) - - groupResources, err := restmapper.GetAPIGroupResources(discovery) - if err != nil { - return nil, err - } - - return restmapper.NewDiscoveryRESTMapper(groupResources), nil -} - -func retrieveModuleList(ctx context.Context, config *rest.Config) (modules []string, eeModules []string, err error) { - config = rest.CopyConfig(config) - config.GroupVersion = &apiextensions.SchemeGroupVersion - - apiextensionsClient, err := apiextensionsv1client.NewForConfig(config) - if err != nil { - return - } - - crds, err := apiextensionsClient.CustomResourceDefinitions().List(ctx, metav1.ListOptions{ - LabelSelector: "formance.com/kind=module", - }) - if err != nil { - return - } - - modules = collectionutils.Map(crds.Items, func(item v1.CustomResourceDefinition) string { - return item.Status.AcceptedNames.Singular - }) - - eeModules = collectionutils.Reduce(crds.Items, func(acc []string, item v1.CustomResourceDefinition) []string { - if item.Labels["formance.com/is-ee"] == "true" { - return append(acc, item.Status.AcceptedNames.Singular) - } - return acc - }, []string{}) - - sort.Strings(modules) - sort.Strings(eeModules) - - return -} - -func runMembershipClient(lc fx.Lifecycle, membershipClient *membershipClient, logger logging.Logger, config *rest.Config) { - lc.Append(fx.Hook{ - OnStart: func(ctx context.Context) error { - modules, eeModules, err := retrieveModuleList(ctx, config) - if err != nil { - return err - } - - if err := membershipClient.connect(logging.ContextWithLogger(ctx, logger), modules, eeModules); err != nil { - return err - } - go func() { - if err := membershipClient.Start(logging.ContextWithLogger(ctx, logger)); err != nil { - panic(err) - } - }() - return nil - }, - OnStop: membershipClient.Stop, - }) -} - -func runMembershipListener(lc fx.Lifecycle, client *membershipListener, logger logging.Logger) { - lc.Append(fx.Hook{ - OnStart: func(ctx context.Context) error { - go client.Start(logging.ContextWithLogger(ctx, logger)) - return nil - }, - }) -} - -func NewModule(serverAddress string, authenticator Authenticator, clientInfo ClientInfo, resyncPeriod time.Duration, opts ...grpc.DialOption) fx.Option { - return fx.Options( - fx.Supply(clientInfo), - fx.Provide(rest.RESTClientFor), - fx.Provide(dynamic.NewForConfig), - fx.Provide(func(client *dynamic.DynamicClient) dynamicinformer.DynamicSharedInformerFactory { - return NewDynamicSharedInformerFactory(client, resyncPeriod) - }), - fx.Provide(func(restClient *rest.RESTClient, informerFactory dynamicinformer.DynamicSharedInformerFactory) K8SClient { - return NewCachedK8SClient(NewDefaultK8SClient(restClient), informerFactory) - }), - fx.Provide(CreateRestMapper), - fx.Provide(func() *membershipClient { - return NewMembershipClient(authenticator, clientInfo, serverAddress, opts...) - }), - fx.Provide(func(membershipClient *membershipClient) MembershipClient { - return membershipClient - }), - fx.Provide(NewMembershipListener), - fx.Invoke(CreateVersionsInformer), - fx.Invoke(CreateStacksInformer), - fx.Invoke(CreateModulesInformers), - fx.Invoke(runMembershipClient), - fx.Invoke(runMembershipListener), - fx.Invoke(runInformers), - ) -} diff --git a/ee/agent/internal/utils.go b/ee/agent/internal/utils.go deleted file mode 100644 index 4a54684963..0000000000 --- a/ee/agent/internal/utils.go +++ /dev/null @@ -1,63 +0,0 @@ -package internal - -import ( - "encoding/json" - "reflect" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/pkg/errors" - "google.golang.org/protobuf/types/known/structpb" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -func Restrict[T any](obj map[string]interface{}) (map[string]interface{}, error) { - if len(obj) == 0 { - return nil, errors.New("obj is empty") - } - - jsonBytes, err := json.Marshal(obj) - if err != nil { - return nil, err - } - - res := new(T) - err = json.Unmarshal(jsonBytes, &res) - if err != nil { - return nil, errors.Wrap(err, "unable to unmarshal json in"+reflect.TypeOf(res).String()) - } - - filtered, err := json.Marshal(res) - if err != nil { - return nil, err - } - - var tmp map[string]interface{} - if err := json.Unmarshal(filtered, &tmp); err != nil { - return nil, err - } - - return tmp, nil -} - -func getStatus(unstructuredModule *unstructured.Unstructured) (*structpb.Struct, error) { - status, found, err := unstructured.NestedMap(unstructuredModule.Object, "status") - if err != nil { - return nil, errors.Wrap(err, "unable to get status from unstructured") - } - - if !found { - return nil, nil - } - - status, err = Restrict[v1beta1.Status](status) - if err != nil { - return nil, errors.Wrap(err, "unable to restrict status according to v1beta1.StatusWithConditions") - } - - protoStatus, err := structpb.NewStruct(status) - if err != nil { - return nil, errors.Wrap(err, "unable to convert status to proto struct") - } - return protoStatus, nil - -} diff --git a/ee/agent/main.go b/ee/agent/main.go deleted file mode 100644 index 6eb91ac652..0000000000 --- a/ee/agent/main.go +++ /dev/null @@ -1,11 +0,0 @@ -package main - -import ( - "github.com/formancehq/stack/components/agent/cmd" - "github.com/joho/godotenv" -) - -func main() { - _ = godotenv.Load() - cmd.Execute() -} diff --git a/ee/agent/scratch.Dockerfile b/ee/agent/scratch.Dockerfile deleted file mode 100644 index 3c6d945484..0000000000 --- a/ee/agent/scratch.Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM ghcr.io/formancehq/base:scratch -COPY agent /usr/bin/agent -ENV OTEL_SERVICE_NAME agent -ENTRYPOINT ["/usr/bin/agent"] diff --git a/ee/agent/tests/informer_stacks_test.go b/ee/agent/tests/informer_stacks_test.go deleted file mode 100644 index f2c9deb8d0..0000000000 --- a/ee/agent/tests/informer_stacks_test.go +++ /dev/null @@ -1,348 +0,0 @@ -package tests - -import ( - "context" - "encoding/json" - "time" - - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/stack/components/agent/internal" - "github.com/formancehq/stack/components/agent/internal/generated" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/dynamic" -) - -var _ = Describe("Stacks informer", func() { - var ( - membershipClientMock *internal.MembershipClientMock - startListener func() - ) - BeforeEach(func() { - membershipClientMock = internal.NewMembershipClientMock() - dynamicClient, err := dynamic.NewForConfig(restConfig) - Expect(err).To(Succeed()) - - factory := internal.NewDynamicSharedInformerFactory(dynamicClient, 5*time.Minute) - Expect(internal.CreateStacksInformer(factory, logging.Testing(), membershipClientMock)).To(Succeed()) - startListener = func() { - stopCh := make(chan struct{}) - factory.Start(stopCh) - DeferCleanup(func() { - close(stopCh) - }) - } - }) - When("a stack is created on the cluster disabled", func() { - var stack *v1beta1.Stack - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: v1.ObjectMeta{ - Name: uuid.NewString(), - }, - Spec: v1beta1.StackSpec{ - Disabled: true, - }, - } - By("Creating a disabled stack", func() { - Expect(k8sClient.Post(). - Resource("Stacks"). - Body(stack). - Do(context.Background()). - Into(stack)).To(Succeed()) - }) - - By("Adding ready", func() { - stack.Status.Ready = true - patch, err := json.Marshal(struct { - Status v1beta1.StackStatus `json:"status"` - }{ - Status: stack.Status, - }) - Expect(err).To(Succeed()) - - Expect(k8sClient.Patch(types.MergePatchType). - Resource("Stacks"). - SubResource("status"). - Name(stack.Name). - Body(patch). - Do(context.Background()). - Error()).To(Succeed()) - }) - - startListener() - - DeferCleanup(func() { - Expect(k8sClient.Delete(). - Resource("Stacks"). - Name(stack.Name). - Do(context.Background()).Error()).To(Succeed()) - }) - }) - It("Should have sent a Status_Changed", func() { - Eventually(func() []*generated.Message { - for _, message := range membershipClientMock.GetMessages() { - if message.GetStatusChanged() != nil { - if _, ok := message.GetStatusChanged().GetStatuses().Fields["ready"]; ok { - isReady := message.GetStatusChanged().GetStatuses().Fields["ready"].GetBoolValue() - if isReady { - return membershipClientMock.GetMessages() - } - } - } - } - return nil - }).ShouldNot(BeEmpty()) - }) - When("The stack is ready", func() { - BeforeEach(func() { - stack.Status.Ready = true - patch, err := json.Marshal(struct { - Status v1beta1.StackStatus `json:"status,omitempty"` - }{ - Status: stack.Status, - }) - Expect(err).To(Succeed()) - Expect(k8sClient.Patch(types.MergePatchType). - Resource("Stacks"). - SubResource("status"). - Name(stack.Name). - Body(patch). - Do(context.Background()). - Error()).To(Succeed()) - }) - It("Should have sent a Status_Changed", func() { - Eventually(func() []*generated.Message { - for _, message := range membershipClientMock.GetMessages() { - if message.GetStatusChanged() != nil { - if _, ok := message.GetStatusChanged().GetStatuses().Fields["ready"]; ok { - isReady := message.GetStatusChanged().GetStatuses().Fields["ready"].GetBoolValue() - if isReady { - return membershipClientMock.GetMessages() - } - } - } - } - return nil - }).ShouldNot(BeEmpty()) - }) - }) - When("the stack is re-enabled", func() { - BeforeEach(func() { - By("setting the status ready", func() { - stack.Status.Ready = false - patch, err := json.Marshal(struct { - Status v1beta1.StackStatus `json:"status"` - }{ - Status: stack.Status, - }) - Expect(err).To(Succeed()) - - Expect(k8sClient.Patch(types.MergePatchType). - Resource("Stacks"). - SubResource("status"). - Name(stack.Name). - Body(patch). - Do(context.Background()). - Error()).To(Succeed()) - }) - By("Enabling the stack", func() { - stack.Spec.Disabled = false - path, err := json.Marshal(struct { - Spec v1beta1.StackSpec `json:"spec"` - }{ - Spec: stack.Spec, - }) - Expect(err).To(Succeed()) - Expect(k8sClient.Patch(types.MergePatchType). - Resource("Stacks"). - Name(stack.Name). - Body(path). - Do(context.Background()). - Error()).To(Succeed()) - }) - }) - It("should have sent a Status_Changed", func() { - Eventually(func() []*generated.Message { - for _, message := range membershipClientMock.GetMessages() { - if message.GetStatusChanged() != nil { - if _, ok := message.GetStatusChanged().GetStatuses().Fields["ready"]; ok { - isReady := message.GetStatusChanged().GetStatuses().Fields["ready"].GetBoolValue() - if !isReady { - return membershipClientMock.GetMessages() - } - } - } - } - return []*generated.Message{} - }).ShouldNot(BeEmpty()) - }) - When("the stack is reconcilled", func() { - BeforeEach(func() { - By("Setting the status ready", func() { - stack.Status.Ready = true - stack.Status.Modules = []string{} - patch, err := json.Marshal(struct { - Status v1beta1.StackStatus `json:"status"` - }{ - Status: stack.Status, - }) - Expect(err).To(Succeed()) - - Expect(k8sClient.Patch(types.MergePatchType). - Resource("Stacks"). - SubResource("status"). - Name(stack.Name). - Body(patch). - Do(context.Background()). - Error()).To(Succeed()) - }) - }) - It("should have sent a Status_Changed", func() { - Eventually(func() []*generated.Message { - for _, message := range membershipClientMock.GetMessages() { - if message.GetStatusChanged() != nil { - if _, ok := message.GetStatusChanged().GetStatuses().Fields["ready"]; ok { - isReady := message.GetStatusChanged().GetStatuses().Fields["ready"].GetBoolValue() - if isReady { - return membershipClientMock.GetMessages() - } - } - } - } - return nil - }).ShouldNot(BeEmpty()) - }) - }) - }) - - }) - When("Stack is created", func() { - var stack *v1beta1.Stack - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: v1.ObjectMeta{ - Name: uuid.NewString(), - }, - } - Expect(k8sClient.Post(). - Resource("Stacks"). - Body(stack). - Do(context.Background()). - Into(stack)).To(Succeed()) - - By("Disabling the status ready", func() { - stack.Status.Ready = false - patch, err := json.Marshal(struct { - Status v1beta1.StackStatus `json:"status"` - }{ - Status: stack.Status, - }) - Expect(err).To(Succeed()) - - Expect(k8sClient.Patch(types.MergePatchType). - Resource("Stacks"). - SubResource("status"). - Name(stack.Name). - Body(patch). - Do(context.Background()). - Error()).To(Succeed()) - }) - - startListener() - }) - AfterEach(func() { - Expect(k8sClient.Delete(). - Resource("Stacks"). - Name(stack.Name). - Do(context.Background()).Error()).To(Succeed()) - }) - It("should have sent a Status_Changed", func() { - Eventually(func() []*generated.Message { - for _, message := range membershipClientMock.GetMessages() { - if message.GetStatusChanged() != nil && message.GetStatusChanged().Status == generated.StackStatus_Progressing && stack.Name == message.GetStatusChanged().ClusterName { - if _, ok := message.GetStatusChanged().GetStatuses().Fields["ready"]; ok { - isReady := message.GetStatusChanged().GetStatuses().Fields["ready"].GetBoolValue() - if !isReady { - return membershipClientMock.GetMessages() - } - } - } - } - return nil - }).ShouldNot(BeEmpty()) - }) - When("all stack dependent are ready", func() { - BeforeEach(func() { - By("setting the status ready", func() { - stack.Status.Ready = true - patch, err := json.Marshal(struct { - Status v1beta1.StackStatus `json:"status"` - }{ - Status: stack.Status, - }) - Expect(err).To(Succeed()) - - Expect(k8sClient.Patch(types.MergePatchType). - Resource("Stacks"). - SubResource("status"). - Name(stack.Name). - Body(patch). - Do(context.Background()). - Error()).To(Succeed()) - }) - }) - It("should have sent a Status_Ready", func() { - Eventually(func() []*generated.Message { - for _, message := range membershipClientMock.GetMessages() { - if message.GetStatusChanged() != nil { - if _, ok := message.GetStatusChanged().GetStatuses().Fields["ready"]; ok { - isReady := message.GetStatusChanged().GetStatuses().Fields["ready"].GetBoolValue() - if isReady { - return membershipClientMock.GetMessages() - } - } - } - } - return nil - }).ShouldNot(BeEmpty()) - }) - }) - }) - When("Stack is deleted", func() { - var stack *v1beta1.Stack - BeforeEach(func() { - stack = &v1beta1.Stack{ - ObjectMeta: v1.ObjectMeta{ - Name: uuid.NewString(), - }, - } - Expect(k8sClient.Post(). - Resource("Stacks"). - Body(stack). - Do(context.Background()). - Into(stack)).To(Succeed()) - - startListener() - - Expect(k8sClient.Delete(). - Resource("Stacks"). - Name(stack.Name). - Do(context.Background()).Error()).To(Succeed()) - }) - It("should have sent a Stack_Deleted", func() { - Eventually(func() []*generated.Message { - for _, message := range membershipClientMock.GetMessages() { - if message.GetStackDeleted() != nil && message.GetStackDeleted().ClusterName == stack.Name { - return membershipClientMock.GetMessages() - } - } - return nil - }).ShouldNot(BeEmpty()) - }) - }) -}) diff --git a/ee/agent/tests/informers_modules_test.go b/ee/agent/tests/informers_modules_test.go deleted file mode 100644 index f08c933e3b..0000000000 --- a/ee/agent/tests/informers_modules_test.go +++ /dev/null @@ -1,199 +0,0 @@ -package tests - -import ( - "context" - "fmt" - "reflect" - "strings" - "time" - - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/stack/components/agent/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/dynamic" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -var _ = Describe("Informer modules", func() { - var ( - membershipClientMock *internal.MembershipClientMock - restMapper meta.RESTMapper - err error - ) - - BeforeEach(func() { - membershipClientMock = internal.NewMembershipClientMock() - restMapper, err = internal.CreateRestMapper(restConfig) - Expect(err).ToNot(HaveOccurred()) - }) - When("a module is created on the cluster", func() { - var ( - modules map[schema.GroupVersionKind]*unstructured.Unstructured - ) - BeforeEach(func() { - modules = map[schema.GroupVersionKind]*unstructured.Unstructured{} - for gvk, rtype := range scheme.Scheme.AllKnownTypes() { - object := reflect.New(rtype).Interface() - if _, ok := object.(v1beta1.Module); !ok { - continue - } - - restMapping, err := restMapper.RESTMapping(gvk.GroupKind(), gvk.Version) - Expect(err).ToNot(HaveOccurred()) - var ( - unstructuredObj *unstructured.Unstructured - resource string - ) - - resource = restMapping.Resource.Resource - name := uuid.NewString() - - unstructuredObj = &unstructured.Unstructured{ - Object: map[string]interface{}{}, - } - unstructuredObj.Object["apiVersion"] = gvk.GroupVersion().String() - unstructuredObj.Object["kind"] = gvk.Kind - unstructuredObj.Object["metadata"] = map[string]interface{}{ - "name": name, - "labels": map[string]interface{}{ - "formance.com/stack": name, - "formance.com/created-by-agent": "true", - }, - } - - By(fmt.Sprintf("Creating the module %s", gvk.Kind), func() { - Expect(k8sClient.Post(). - Resource(resource). - Body(unstructuredObj). - Name(name).Do(context.Background()).Error()).To(Succeed()) - - DeferCleanup(func() { - Expect(client.IgnoreNotFound(k8sClient.Delete().Resource(resource).Name(name).Do(context.Background()).Error())).To(Succeed()) - }) - }) - - By(fmt.Sprintf("Loading then updating status %s", gvk.Kind), func() { - Eventually(func() error { - return LoadResource(resource, name, unstructuredObj) - }).Should(Succeed()) - - /** - Those 2 a reset by LoadResource to empty - **/ - unstructuredObj.Object["apiVersion"] = gvk.GroupVersion().String() - unstructuredObj.Object["kind"] = gvk.Kind - /** **/ - - unstructuredObj.Object["status"] = map[string]interface{}{ - "info": uuid.NewString(), - } - - Expect(k8sClient.Put(). - Resource(resource). - SubResource("status"). - Name(name). - Body(unstructuredObj). - Do(context.Background()). - Error()).To(Succeed()) - }) - - modules[gvk] = unstructuredObj - } - }) - It("Should have been created", func() { - for gvk, rtype := range scheme.Scheme.AllKnownTypes() { - object := reflect.New(rtype).Interface() - if _, ok := object.(v1beta1.Module); !ok { - continue - } - - restMapping, err := restMapper.RESTMapping(gvk.GroupKind(), gvk.Version) - Expect(err).ToNot(HaveOccurred()) - - Expect(true).To(BeTrue()) - Eventually(func() error { - return LoadResource(restMapping.Resource.Resource, modules[gvk].GetName(), modules[gvk]) - }).Should(Succeed()) - } - }) - When("Listening to all modules", func() { - BeforeEach(func() { - dynamicClient, err := dynamic.NewForConfig(restConfig) - Expect(err).ToNot(HaveOccurred()) - factory := internal.NewDynamicSharedInformerFactory(dynamicClient, 5*time.Minute) - Expect(internal.CreateModulesInformers(factory, restMapper, logging.Testing(), membershipClientMock)).ToNot(HaveOccurred()) - - stopCh := make(chan struct{}) - factory.Start(stopCh) - DeferCleanup(func() { - close(stopCh) - }) - }) - It("Should have sent ModuleStatusChanged", func() { - for gvk, module := range modules { - By(fmt.Sprintf("Checking the module %s", gvk.Kind), func() { - Eventually(func(g Gomega) bool { - for _, message := range membershipClientMock.GetMessages() { - if msg := message.GetModuleStatusChanged(); msg != nil && - msg.Vk.Kind == gvk.Kind && - msg.Vk.Version == gvk.Version && - msg.ClusterName == module.GetName() { - - status, _, _ := unstructured.NestedMap(module.Object, "status") - - g.Expect(msg.Status.AsMap()["info"]).ToNot(BeNil()) - g.Expect(msg.Status.AsMap()["ready"]).To(BeFalse()) - - for k, value := range status { - g.Expect(msg.Status.AsMap()[k]).To(Equal(value)) - } - return true - } - } - return false - }).Should(BeTrue()) - }) - } - }) - When("A module is deleted", func() { - var moduleDeleted *unstructured.Unstructured - BeforeEach(func() { - for gvk, module := range modules { - if gvk.Kind != "Reconciliation" { - continue - } - By(fmt.Sprintf("Deleting the module %s", gvk.Kind), func() { - moduleDeleted = module - restMapping, err := restMapper.RESTMapping(gvk.GroupKind(), gvk.Version) - Expect(err).ToNot(HaveOccurred()) - - Expect(k8sClient.Delete().Resource(restMapping.Resource.Resource).Name(module.GetName()).Do(context.Background()).Error()).To(Succeed()) - }) - } - }) - It("Should have sent ModuleDeleted", func() { - By(fmt.Sprintf("Checking message received for %s", moduleDeleted.GetKind()), func() { - Eventually(func(g Gomega) bool { - for _, message := range membershipClientMock.GetMessages() { - if msg := message.GetModuleDeleted(); msg != nil && - msg.Vk.Kind == moduleDeleted.GetKind() && - msg.Vk.Version == strings.Split(moduleDeleted.GetAPIVersion(), "/")[1] && - msg.ClusterName == moduleDeleted.GetName() { - return true - } - } - return false - }).Should(BeTrue()) - }) - }) - }) - }) - }) -}) diff --git a/ee/agent/tests/internal/matcher_be_owned_by.go b/ee/agent/tests/internal/matcher_be_owned_by.go deleted file mode 100644 index fcfe448d0e..0000000000 --- a/ee/agent/tests/internal/matcher_be_owned_by.go +++ /dev/null @@ -1,74 +0,0 @@ -package internal - -import ( - "fmt" - "k8s.io/client-go/kubernetes/scheme" - "reflect" - - "github.com/formancehq/go-libs/pointer" - gomegaTypes "github.com/onsi/gomega/types" - "github.com/pkg/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type beOwnedByOption func(matcher *beOwnedByMatcher) - -type beOwnedByMatcher struct { - owner client.Object - controller bool - blockOwnerDeletion bool -} - -func (s beOwnedByMatcher) Match(actual interface{}) (success bool, err error) { - object, ok := actual.(client.Object) - if !ok { - return false, fmt.Errorf("expect object of type runtime.Object") - } - for _, reference := range object.GetOwnerReferences() { - groupVersionsKinds, _, err := scheme.Scheme.ObjectKinds(s.owner) - if err != nil { - return false, errors.Wrap(err, "searching object kinds") - } - expectedOwnerReference := metav1.OwnerReference{ - APIVersion: groupVersionsKinds[0].GroupVersion().String(), - Kind: groupVersionsKinds[0].Kind, - Name: s.owner.GetName(), - UID: s.owner.GetUID(), - } - if s.controller { - expectedOwnerReference.Controller = pointer.For(true) - } - if s.blockOwnerDeletion { - expectedOwnerReference.BlockOwnerDeletion = pointer.For(true) - } - if reflect.DeepEqual(reference, expectedOwnerReference) { - return true, nil - } - } - return false, nil -} - -func (s beOwnedByMatcher) FailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("object %s should be owned by %s", - actual.(client.Object).GetName(), (any)(s.owner)) -} - -func (s beOwnedByMatcher) NegatedFailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("object %s should not be owned by %s", - actual.(client.Object).GetName(), (any)(s.owner)) -} - -var _ gomegaTypes.GomegaMatcher = (*beOwnedByMatcher)(nil) - -func BeOwnedBy(owner client.Object, opts ...beOwnedByOption) gomegaTypes.GomegaMatcher { - ret := &beOwnedByMatcher{ - owner: owner, - } - - for _, opt := range opts { - opt(ret) - } - - return ret -} diff --git a/ee/agent/tests/internal/matcher_target_stack.go b/ee/agent/tests/internal/matcher_target_stack.go deleted file mode 100644 index 895cdcc9d9..0000000000 --- a/ee/agent/tests/internal/matcher_target_stack.go +++ /dev/null @@ -1,62 +0,0 @@ -package internal - -import ( - "encoding/json" - "fmt" - "github.com/formancehq/operator/api/formance.com/v1beta1" - gomegaTypes "github.com/onsi/gomega/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type targetStackMatcher struct { - stack *v1beta1.Stack -} - -func (s targetStackMatcher) Match(actual interface{}) (success bool, err error) { - object, ok := actual.(client.Object) - if !ok { - return false, fmt.Errorf("expect object of type client.Object") - } - - data, err := json.Marshal(object) - if err != nil { - return false, err - } - - asMap := make(map[string]any) - if err := json.Unmarshal(data, &asMap); err != nil { - return false, err - } - - if _, ok := asMap["spec"]; !ok { - return false, nil - } - - if _, ok := asMap["spec"].(map[string]any); !ok { - return false, nil - } - - if _, ok := asMap["spec"].(map[string]any)["stack"]; !ok { - return false, nil - } - - return true, nil -} - -func (s targetStackMatcher) FailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("object %s should target stack %s", - actual.(client.Object).GetName(), s.stack.GetName()) -} - -func (s targetStackMatcher) NegatedFailureMessage(actual interface{}) (message string) { - return fmt.Sprintf("object %s should not target stack %s", - actual.(client.Object).GetName(), s.stack.GetName()) -} - -var _ gomegaTypes.GomegaMatcher = (*targetStackMatcher)(nil) - -func TargetStack(stack *v1beta1.Stack) gomegaTypes.GomegaMatcher { - return &targetStackMatcher{ - stack: stack, - } -} diff --git a/ee/agent/tests/main_test.go b/ee/agent/tests/main_test.go deleted file mode 100644 index 0356917d3e..0000000000 --- a/ee/agent/tests/main_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package tests - -import ( - "path/filepath" - osRuntime "runtime" - "testing" - "time" - - "github.com/formancehq/stack/components/agent/internal" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/meta" - - "github.com/formancehq/operator/api/formance.com/v1beta1" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" -) - -var ( - testEnv *envtest.Environment - restConfig *rest.Config - k8sClient *rest.RESTClient - mapper meta.RESTMapper -) - -var _ = BeforeSuite(func() { - SetDefaultEventuallyTimeout(5 * time.Second) - - _, filename, _, _ := osRuntime.Caller(0) - - apiServer := envtest.APIServer{} - apiServer.Configure(). - Set("service-cluster-ip-range", "10.0.0.0/20") - - Expect(v1beta1.AddToScheme(scheme.Scheme)).To(Succeed()) - - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join(filepath.Dir(filename), "..", "..", "..", "components", "operator", - "config", "crd", "bases"), - }, - ErrorIfCRDPathMissing: true, - ControlPlane: envtest.ControlPlane{ - APIServer: &apiServer, - }, - Scheme: scheme.Scheme, - } - - var err error - restConfig, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(restConfig).NotTo(BeNil()) - - restConfig.GroupVersion = &v1beta1.GroupVersion - restConfig.NegotiatedSerializer = scheme.Codecs.WithoutConversion() - restConfig.APIPath = "/apis" - - k8sClient, err = rest.RESTClientFor(restConfig) - Expect(err).NotTo(HaveOccurred()) - - mapper, err = internal.CreateRestMapper(restConfig) - Expect(err).NotTo(HaveOccurred()) - -}) - -var _ = AfterSuite(func() { - if testEnv != nil { - Expect(testEnv.Stop()).To(BeNil()) - } -}) - -func TestAgent(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Agent Suite") -} diff --git a/ee/agent/tests/membership_listener_test.go b/ee/agent/tests/membership_listener_test.go deleted file mode 100644 index c5b34afefb..0000000000 --- a/ee/agent/tests/membership_listener_test.go +++ /dev/null @@ -1,300 +0,0 @@ -package tests - -import ( - "context" - "encoding/json" - "fmt" - "net/url" - "reflect" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/operator/api/formance.com/v1beta1" - "github.com/formancehq/stack/components/agent/internal" - "github.com/formancehq/stack/components/agent/internal/generated" - . "github.com/formancehq/stack/components/agent/tests/internal" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" -) - -var _ = Describe("Membership listener", func() { - var ( - membershipClient *internal.MembershipClientMock - clientInfo internal.ClientInfo - ) - BeforeEach(func() { - membershipClient = internal.NewMembershipClientMock() - clientInfo = internal.ClientInfo{ - BaseUrl: &url.URL{}, - } - listener := internal.NewMembershipListener(internal.NewDefaultK8SClient(k8sClient), clientInfo, mapper, membershipClient) - done := make(chan struct{}) - DeferCleanup(func() { - <-done - }) - go func() { - defer close(done) - listener.Start(context.Background()) - }() - - DeferCleanup(func() { - close(membershipClient.Orders()) - }) - }) - Context("When sending an existing stack from membership", func() { - var ( - membershipStack *generated.Stack - stack *v1beta1.Stack - ) - BeforeEach(func() { - stackName := uuid.NewString() - wrong := uuid.NewString() - By("Creating a wrong client", func() { - client := &v1beta1.AuthClient{ - ObjectMeta: metav1.ObjectMeta{ - Name: wrong, - Labels: map[string]string{ - "formance.com/created-by-agent": "true", - "formance.com/stack": stackName, - }, - }, - Spec: v1beta1.AuthClientSpec{ - StackDependency: v1beta1.StackDependency{ - Stack: stackName, - }, - ID: wrong, - Public: true, - }, - } - Expect(k8sClient.Post().Resource("AuthClients").Body(client).Do(context.Background()).Error()).To(BeNil()) - }) - - By("Creating a stack", func() { - modules := make([]*generated.Module, 0) - for gvk, rtype := range scheme.Scheme.AllKnownTypes() { - object := reflect.New(rtype).Interface() - if _, ok := object.(v1beta1.Module); !ok { - continue - } - - if gvk.Kind == "Stargate" { - continue - } - - modules = append(modules, &generated.Module{ - Name: gvk.Kind, - }) - } - - membershipStack = &generated.Stack{ - ClusterName: stackName, - AuthConfig: &generated.AuthConfig{ - ClientId: "clientid", - ClientSecret: "clientsecret", - Issuer: "http://example.net", - }, - AdditionalLabels: map[string]string{ - "foo": "bar", - "foo.foo": "bar", - "foo-foo": "bar", - }, - AdditionalAnnotations: map[string]string{ - "foo": "bar", - "foo.foo": "bar", - "foo-foo": "bar", - "foo_foo": "@bar", - }, - StaticClients: []*generated.AuthClient{ - { - Id: "clientid1", - Public: true, - }, - { - Id: "clientid2", - Public: true, - }, - }, - Modules: modules, - } - membershipClient.Orders() <- &generated.Order{ - Message: &generated.Order_ExistingStack{ - ExistingStack: membershipStack, - }, - } - stack = &v1beta1.Stack{} - Eventually(func() error { - return LoadResource("Stacks", membershipStack.ClusterName, stack) - }).Should(BeNil()) - }) - }) - It("Should have sync auth client", func() { - clients := &unstructured.UnstructuredList{} - Eventually(func(g Gomega) []unstructured.Unstructured { - g.Expect(k8sClient.Get().Resource("AuthClients").VersionedParams(&metav1.ListOptions{ - LabelSelector: "formance.com/created-by-agent=true,formance.com/stack=" + membershipStack.ClusterName, - }, scheme.ParameterCodec).Do(context.Background()).Into(clients)).To(Succeed()) - return clients.Items - }).Should(HaveLen(2)) - }) - When("Having an @ in labels", func() { - var patch []byte - var err error - BeforeEach(func() { - patch, err = json.Marshal(map[string]any{ - "metadata": map[string]any{ - "labels": map[string]any{ - "formance.com/owner-email": "example@example.net", - }, - }, - }) - Expect(err).To(BeNil()) - - }) - It("Should through an error", func() { - err := k8sClient.Patch(types.MergePatchType). - Resource("Stacks"). - Name(stack.Name). - Body(patch). - Do(context.Background()). - Error() - - Expect(err).To(HaveOccurred()) - }) - }) - It("Should have additional labels", func() { - Expect(stack.Labels).To(HaveKeyWithValue("formance.com/foo", "bar")) - Expect(stack.Labels).To(HaveKeyWithValue("formance.com/foo.foo", "bar")) - Expect(stack.Labels).To(HaveKeyWithValue("formance.com/foo-foo", "bar")) - }) - It("Should have additional annotations", func() { - Expect(stack.Annotations).To(HaveKeyWithValue("formance.com/foo", "bar")) - Expect(stack.Annotations).To(HaveKeyWithValue("formance.com/foo.foo", "bar")) - Expect(stack.Annotations).To(HaveKeyWithValue("formance.com/foo-foo", "bar")) - Expect(stack.Annotations).To(HaveKeyWithValue("formance.com/foo_foo", "@bar")) - }) - It("Should create all required crds cluster side", func() { - auth := &v1beta1.Auth{} - Eventually(func() error { - return LoadResource("Auths", membershipStack.ClusterName, auth) - }).Should(BeNil()) - Expect(auth).To(BeOwnedBy(stack)) - Expect(auth).To(TargetStack(stack)) - Expect(auth.Spec.DelegatedOIDCServer).NotTo(BeNil()) - Expect(auth.Spec.DelegatedOIDCServer.ClientSecret).To(Equal(membershipStack.AuthConfig.ClientSecret)) - Expect(auth.Spec.DelegatedOIDCServer.ClientID).To(Equal(membershipStack.AuthConfig.ClientId)) - Expect(auth.Spec.DelegatedOIDCServer.Issuer).To(Equal(membershipStack.AuthConfig.Issuer)) - - gateway := &v1beta1.Gateway{} - Eventually(func() error { - return LoadResource("Gateways", membershipStack.ClusterName, gateway) - }).Should(BeNil()) - Expect(gateway).To(BeOwnedBy(stack)) - Expect(gateway).To(TargetStack(stack)) - Expect(gateway.Spec.Ingress).NotTo(BeNil()) - Expect(gateway.Spec.Ingress.Host).To(Equal(fmt.Sprintf("%s.%s", stack.GetName(), clientInfo.BaseUrl.Host))) - Expect(gateway.Spec.Ingress.Scheme).To(Equal(clientInfo.BaseUrl.Scheme)) - - for gvk, rtype := range scheme.Scheme.AllKnownTypes() { - object := reflect.New(rtype).Interface() - if _, ok := object.(v1beta1.Module); !ok { - continue - } - - if gvk.Kind == "Stargate" { - continue - } - - restMapping, err := mapper.RESTMapping(gvk.GroupKind()) - Expect(err).To(BeNil()) - - u := &unstructured.Unstructured{} - Eventually(func() error { - return LoadResource(restMapping.Resource.Resource, membershipStack.ClusterName, u) - }).Should(Succeed()) - Expect(u).To(BeOwnedBy(stack)) - Expect(u).To(TargetStack(stack)) - } - }) - When("removing modules", func() { - var ( - modulesToRemove map[string]struct{} - ) - BeforeEach(func() { - - modulesToRemove = map[string]struct{}{} - modulesToRemove["Webhooks"] = struct{}{} - modulesToRemove["Search"] = struct{}{} - - membershipStack.Modules = collectionutils.Filter(membershipStack.Modules, func(module *generated.Module) bool { - _, exist := modulesToRemove[module.Name] - return !exist - }) - - membershipClient.Orders() <- &generated.Order{ - Message: &generated.Order_ExistingStack{ - ExistingStack: membershipStack, - }, - } - }) - It("modules should be removed", func() { - for moduleName := range modulesToRemove { - Eventually(func(g Gomega) error { - u := &unstructured.Unstructured{} - return LoadResource(moduleName, membershipStack.ClusterName, u) - }).Should(HaveOccurred()) - } - }) - }) - Context("then when disabling the stack", func() { - BeforeEach(func() { - membershipClient.Orders() <- &generated.Order{ - Message: &generated.Order_DisabledStack{ - DisabledStack: &generated.DisabledStack{ - ClusterName: membershipStack.ClusterName, - }, - }, - } - }) - shouldBeDisabled := func() { - stack := &v1beta1.Stack{} - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("Stacks", membershipStack.ClusterName, stack)).To(Succeed()) - return stack.Spec.Disabled - }).Should(BeTrue()) - } - It("Should disable the stack on the cluster", shouldBeDisabled) - Context("Then re enabling the stack", func() { - BeforeEach(func() { - shouldBeDisabled() - membershipClient.Orders() <- &generated.Order{ - Message: &generated.Order_EnabledStack{ - EnabledStack: &generated.EnabledStack{ - ClusterName: membershipStack.ClusterName, - }, - }, - } - }) - It("Should enable the stack on the cluster", func() { - stack := &v1beta1.Stack{} - Eventually(func(g Gomega) bool { - g.Expect(LoadResource("Stacks", membershipStack.ClusterName, stack)).To(Succeed()) - return stack.Spec.Disabled - }).Should(BeFalse()) - }) - }) - }) - }) -}) - -func LoadResource(resource, name string, into runtime.Object) error { - return k8sClient.Get(). - Resource(resource). - Name(name). - Do(context.Background()). - Into(into) -} diff --git a/ee/orchestration/.gitignore b/ee/orchestration/.gitignore deleted file mode 100644 index 7badf94b9a..0000000000 --- a/ee/orchestration/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.idea -vendor -orchestration diff --git a/ee/orchestration/.goreleaser.yml b/ee/orchestration/.goreleaser.yml deleted file mode 100644 index 5e5db91f76..0000000000 --- a/ee/orchestration/.goreleaser.yml +++ /dev/null @@ -1,37 +0,0 @@ -project_name: orchestration -includes: - - from_file: - path: ./../../.goreleaser.default.yaml -monorepo: - tag_prefix: v - dir: ./ - -builds: - - binary: orchestration - id: orchestration - ldflags: - - -X github.com/formancehq/orchestration/cmd.BuildDate={{ .Date }} - - -X github.com/formancehq/orchestration/cmd.Version=v{{ .Version }} - - -X github.com/formancehq/orchestration/cmd.Commit={{ .ShortCommit }} - - -extldflags "-static" - env: - - CGO_ENABLED=0 - goos: - - linux - goarch: - - amd64 - - arm64 - -archives: - - id: "{{.ProjectName}}" - builds: - - orchestration - format: tar.gz - name_template: "{{.ProjectName}}_{{.Os}}-{{.Arch}}" - -release: - prerelease: auto - footer: | - ## What to do next? - - Read the [documentation](https://docs.formance.com/) - - Join our [Slack server](https://formance.com/slack) \ No newline at end of file diff --git a/ee/orchestration/Earthfile b/ee/orchestration/Earthfile deleted file mode 100644 index ac58c5f9e9..0000000000 --- a/ee/orchestration/Earthfile +++ /dev/null @@ -1,100 +0,0 @@ -VERSION 0.8 - -IMPORT github.com/formancehq/earthly:tags/v0.15.0 AS core -IMPORT ../.. AS stack -IMPORT ../../releases AS releases -IMPORT .. AS ee - -FROM core+base-image - -sources: - WORKDIR src - COPY --pass-args (releases+sdk-generate/go) /src/releases/sdks/go - WORKDIR /src/ee/orchestration - COPY go.* . - COPY --dir pkg cmd internal . - COPY main.go . - SAVE ARTIFACT /src - -generate: - FROM core+builder-image - RUN apk update && apk add openjdk11 - DO --pass-args core+GO_INSTALL --package=go.uber.org/mock/mockgen@latest - COPY (+sources/*) /src - WORKDIR /src/ee/orchestration - DO --pass-args core+GO_GENERATE - SAVE ARTIFACT internal AS LOCAL internal - SAVE ARTIFACT pkg AS LOCAL pkg - SAVE ARTIFACT cmd AS LOCAL cmd - -compile: - FROM core+builder-image - COPY (+sources/*) /src - WORKDIR /src/ee/orchestration - ARG VERSION=latest - DO --pass-args core+GO_COMPILE --VERSION=$VERSION - -build-image: - FROM core+final-image - ENTRYPOINT ["/bin/orchestration"] - CMD ["serve"] - COPY (+compile/main) /bin/orchestration - ARG REPOSITORY=ghcr.io - ARG tag=latest - DO core+SAVE_IMAGE --COMPONENT=orchestration --REPOSITORY=${REPOSITORY} --TAG=$tag - -tests: - FROM core+builder-image - COPY (+sources/*) /src - WORKDIR /src/ee/orchestration - WITH DOCKER --pull=postgres:15-alpine - DO --pass-args core+GO_TESTS - END - -deploy: - COPY (+sources/*) /src - LET tag=$(tar cf - /src | sha1sum | awk '{print $1}') - WAIT - BUILD --pass-args +build-image --tag=$tag - END - FROM --pass-args core+vcluster-deployer-image - RUN kubectl patch Versions.formance.com default -p "{\"spec\":{\"orchestration\": \"${tag}\"}}" --type=merge - -deploy-staging: - BUILD --pass-args stack+deployer-module --MODULE=orchestration - -lint: - FROM core+builder-image - COPY (+sources/*) /src - COPY --pass-args +tidy/go.* . - WORKDIR /src/ee/orchestration - DO --pass-args stack+GO_LINT - SAVE ARTIFACT cmd AS LOCAL cmd - SAVE ARTIFACT internal AS LOCAL internal - SAVE ARTIFACT pkg AS LOCAL pkg - SAVE ARTIFACT main.go AS LOCAL main.go - -pre-commit: - WAIT - BUILD --pass-args +tidy - END - BUILD --pass-args +lint - -openapi: - FROM node:20-alpine - RUN apk update && apk add yq - RUN npm install -g openapi-merge-cli - WORKDIR /src/ee/orchestration - COPY --dir openapi openapi - RUN openapi-merge-cli --config ./openapi/openapi-merge.json - RUN yq -oy ./openapi.json > openapi.yaml - SAVE ARTIFACT ./openapi.yaml AS LOCAL ./openapi.yaml - -tidy: - FROM core+builder-image - COPY --pass-args (+sources/src) /src - WORKDIR /src/ee/orchestration - DO --pass-args stack+GO_TIDY - -release: - BUILD --pass-args stack+goreleaser --path=ee/orchestration \ No newline at end of file diff --git a/ee/orchestration/build.Dockerfile b/ee/orchestration/build.Dockerfile deleted file mode 100644 index 4a0070e0f9..0000000000 --- a/ee/orchestration/build.Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM ghcr.io/formancehq/base:22.04 -COPY orchestration /usr/bin/orchestration -ENV OTEL_SERVICE_NAME orchestration -ENTRYPOINT ["/usr/bin/orchestration"] -CMD ["serve"] diff --git a/ee/orchestration/cmd/root.go b/ee/orchestration/cmd/root.go deleted file mode 100644 index 1a162d6b41..0000000000 --- a/ee/orchestration/cmd/root.go +++ /dev/null @@ -1,132 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "net/http" - - "github.com/formancehq/go-libs/bun/bunmigrate" - "github.com/formancehq/go-libs/licence" - "github.com/formancehq/orchestration/internal/storage" - "github.com/uptrace/bun" - - "github.com/formancehq/go-libs/bun/bunconnect" - - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/go-libs/otlp" - "golang.org/x/oauth2" - "golang.org/x/oauth2/clientcredentials" - - "github.com/formancehq/orchestration/internal/triggers" - "github.com/formancehq/orchestration/internal/workflow" - - "github.com/formancehq/go-libs/publish" - "github.com/formancehq/orchestration/internal/temporalclient" - - "github.com/formancehq/go-libs/otlp/otlptraces" - "github.com/formancehq/go-libs/service" - _ "github.com/formancehq/orchestration/internal/workflow/stages/all" - "github.com/spf13/cobra" - "go.uber.org/fx" -) - -var ( - ServiceName = "orchestration" - Version = "develop" - BuildDate = "-" - Commit = "-" -) - -const ( - stackFlag = "stack" - stackURLFlag = "stack-url" - stackClientIDFlag = "stack-client-id" - stackClientSecretFlag = "stack-client-secret" - temporalAddressFlag = "temporal-address" - temporalNamespaceFlag = "temporal-namespace" - temporalSSLClientKeyFlag = "temporal-ssl-client-key" - temporalSSLClientCertFlag = "temporal-ssl-client-cert" - temporalTaskQueueFlag = "temporal-task-queue" - temporalInitSearchAttributes = "temporal-init-search-attributes" - temporalMaxParallelActivitiesFlag = "temporal-max-parallel-activities" - topicsFlag = "topics" - listenFlag = "listen" - workerFlag = "worker" -) - -func NewRootCommand() *cobra.Command { - cmd := &cobra.Command{} - - cobra.EnableTraverseRunHooks = true - - cmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") - cmd.AddCommand( - newServeCommand(), - newVersionCommand(), - newWorkerCommand(), - bunmigrate.NewDefaultCommand(func(cmd *cobra.Command, args []string, db *bun.DB) error { - return storage.Migrate(cmd.Context(), db) - }), - ) - - return cmd -} - -func Execute() { - service.Execute(NewRootCommand()) -} - -func commonOptions(cmd *cobra.Command) (fx.Option, error) { - connectionOptions, err := bunconnect.ConnectionOptionsFromFlags(cmd) - if err != nil { - return nil, err - } - - temporalAddress, _ := cmd.Flags().GetString(temporalAddressFlag) - temporalNamespace, _ := cmd.Flags().GetString(temporalNamespaceFlag) - temporalSSLClientKey, _ := cmd.Flags().GetString(temporalSSLClientKeyFlag) - temporalSSLClientCert, _ := cmd.Flags().GetString(temporalSSLClientCertFlag) - temporalTaskQueue, _ := cmd.Flags().GetString(temporalTaskQueueFlag) - temporalInitSearchAttributes, _ := cmd.Flags().GetBool(temporalInitSearchAttributes) - - return fx.Options( - otlptraces.FXModuleFromFlags(cmd), - temporalclient.NewModule( - temporalAddress, - temporalNamespace, - temporalSSLClientCert, - temporalSSLClientKey, - temporalInitSearchAttributes, - ), - bunconnect.Module(*connectionOptions, service.IsDebug(cmd)), - publish.FXModuleFromFlags(cmd, service.IsDebug(cmd)), - auth.FXModuleFromFlags(cmd), - licence.FXModuleFromFlags(cmd, ServiceName), - workflow.NewModule(temporalTaskQueue), - triggers.NewModule(temporalTaskQueue), - fx.Provide(func() *bunconnect.ConnectionOptions { - return connectionOptions - }), - fx.Provide(func() *http.Client { - httpClient := &http.Client{ - Transport: otlp.NewRoundTripper(http.DefaultTransport, service.IsDebug(cmd)), - } - - stackClientID, _ := cmd.Flags().GetString(stackClientIDFlag) - stackClientSecret, _ := cmd.Flags().GetString(stackClientSecretFlag) - stackURL, _ := cmd.Flags().GetString(stackURLFlag) - - if stackClientID == "" { - return httpClient - } - oauthConfig := clientcredentials.Config{ - ClientID: stackClientID, - ClientSecret: stackClientSecret, - TokenURL: fmt.Sprintf("%s/api/auth/oauth/token", stackURL), - Scopes: []string{"openid", "ledger:read", "ledger:write", "wallets:read", "wallets:write", "payments:read", "payments:write"}, - } - return oauthConfig.Client(context.WithValue(context.Background(), - oauth2.HTTPClient, httpClient)) - }), - ), nil -} diff --git a/ee/orchestration/cmd/serve.go b/ee/orchestration/cmd/serve.go deleted file mode 100644 index 4899339776..0000000000 --- a/ee/orchestration/cmd/serve.go +++ /dev/null @@ -1,102 +0,0 @@ -package cmd - -import ( - "context" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/go-libs/aws/iam" - "github.com/formancehq/go-libs/bun/bunconnect" - "github.com/formancehq/go-libs/licence" - "github.com/formancehq/go-libs/publish" - - "github.com/formancehq/go-libs/health" - "github.com/formancehq/go-libs/httpserver" - "github.com/formancehq/go-libs/service" - "github.com/formancehq/orchestration/internal/api" - v1 "github.com/formancehq/orchestration/internal/api/v1" - v2 "github.com/formancehq/orchestration/internal/api/v2" - "github.com/formancehq/orchestration/internal/storage" - "github.com/spf13/cobra" - "github.com/uptrace/bun" - "go.uber.org/fx" -) - -func healthCheckModule() fx.Option { - return fx.Options( - health.Module(), - health.ProvideHealthCheck(func() health.NamedCheck { - return health.NewNamedCheck("default", health.CheckFn(func(ctx context.Context) error { - return nil - })) - }), - ) -} - -func newServeCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "serve", - RunE: func(cmd *cobra.Command, args []string) error { - commonOptions, err := commonOptions(cmd) - if err != nil { - return err - } - - listen, _ := cmd.Flags().GetString(listenFlag) - - options := []fx.Option{ - commonOptions, - healthCheckModule(), - fx.Provide(func() api.ServiceInfo { - return api.ServiceInfo{ - Version: Version, - } - }), - v1.NewModule(), - v2.NewModule(), - fx.Invoke(func(lifecycle fx.Lifecycle, db *bun.DB) { - lifecycle.Append(fx.Hook{ - OnStart: func(ctx context.Context) error { - return storage.Migrate(ctx, db) - }, - }) - }), - api.NewModule(service.IsDebug(cmd)), - fx.Invoke(func(lc fx.Lifecycle, router *chi.Mux) { - lc.Append(httpserver.NewHook(router, httpserver.WithAddress(listen))) - }), - } - worker, _ := cmd.Flags().GetBool(workerFlag) - if worker { - options = append(options, workerOptions(cmd)) - } - - return service.New(cmd.OutOrStdout(), options...).Run(cmd) - }, - } - - cmd.Flags().Bool(workerFlag, false, "Enable worker mode") - cmd.Flags().String(listenFlag, ":8080", "Listening address") - cmd.Flags().Float64(temporalMaxParallelActivitiesFlag, 10, "Maximum number of parallel activities") - cmd.Flags().String(stackURLFlag, "", "Stack url") - cmd.Flags().String(stackClientIDFlag, "", "Stack client ID") - cmd.Flags().String(stackClientSecretFlag, "", "Stack client secret") - cmd.Flags().String(temporalAddressFlag, "", "Temporal server address") - cmd.Flags().String(temporalNamespaceFlag, "default", "Temporal namespace") - cmd.Flags().String(temporalSSLClientKeyFlag, "", "Temporal client key") - cmd.Flags().String(temporalSSLClientCertFlag, "", "Temporal client cert") - cmd.Flags().String(temporalTaskQueueFlag, "default", "Temporal task queue name") - cmd.Flags().Bool(temporalInitSearchAttributes, false, "Init temporal search attributes") - cmd.Flags().StringSlice(topicsFlag, []string{}, "Topics to listen") - cmd.Flags().String(stackFlag, "", "Stack") - - service.AddFlags(cmd.Flags()) - publish.AddFlags(ServiceName, cmd.Flags()) - auth.AddFlags(cmd.Flags()) - bunconnect.AddFlags(cmd.Flags()) - iam.AddFlags(cmd.Flags()) - licence.AddFlags(cmd.Flags()) - - return cmd -} diff --git a/ee/orchestration/cmd/version.go b/ee/orchestration/cmd/version.go deleted file mode 100644 index 58c77193d3..0000000000 --- a/ee/orchestration/cmd/version.go +++ /dev/null @@ -1,19 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -func newVersionCommand() *cobra.Command { - return &cobra.Command{ - Use: "version", - Short: "Get version", - Run: func(cmd *cobra.Command, args []string) { - fmt.Printf("Version: %s \n", Version) - fmt.Printf("Date: %s \n", BuildDate) - fmt.Printf("Commit: %s \n", Commit) - }, - } -} diff --git a/ee/orchestration/cmd/worker.go b/ee/orchestration/cmd/worker.go deleted file mode 100644 index 3873ffffe9..0000000000 --- a/ee/orchestration/cmd/worker.go +++ /dev/null @@ -1,87 +0,0 @@ -package cmd - -import ( - "net/http" - - "github.com/formancehq/go-libs/aws/iam" - "github.com/formancehq/go-libs/bun/bunconnect" - "github.com/formancehq/go-libs/licence" - "github.com/formancehq/go-libs/publish" - - "go.temporal.io/sdk/worker" - - "github.com/formancehq/orchestration/internal/triggers" - - sdk "github.com/formancehq/formance-sdk-go/v2" - "github.com/formancehq/go-libs/service" - "github.com/formancehq/orchestration/internal/temporalworker" - "github.com/spf13/cobra" - "go.uber.org/fx" -) - -func stackClientModule(cmd *cobra.Command) fx.Option { - stackURL, _ := cmd.Flags().GetString(stackURLFlag) - - return fx.Options( - fx.Provide(func(httpClient *http.Client) *sdk.Formance { - return sdk.New( - sdk.WithClient(httpClient), - sdk.WithServerURL(stackURL), - ) - }), - ) -} - -func workerOptions(cmd *cobra.Command) fx.Option { - - stack, _ := cmd.Flags().GetString(stackFlag) - temporalTaskQueue, _ := cmd.Flags().GetString(temporalTaskQueueFlag) - temporalMaxParallelActivities, _ := cmd.Flags().GetInt(temporalMaxParallelActivitiesFlag) - topics, _ := cmd.Flags().GetStringSlice(topicsFlag) - - return fx.Options( - stackClientModule(cmd), - temporalworker.NewWorkerModule(temporalTaskQueue, worker.Options{ - TaskQueueActivitiesPerSecond: float64(temporalMaxParallelActivities), - }), - triggers.NewListenerModule( - stack, - temporalTaskQueue, - topics, - ), - ) -} - -func newWorkerCommand() *cobra.Command { - ret := &cobra.Command{ - Use: "worker", - RunE: func(cmd *cobra.Command, args []string) error { - commonOptions, err := commonOptions(cmd) - if err != nil { - return err - } - - return service.New(cmd.OutOrStdout(), commonOptions, workerOptions(cmd)).Run(cmd) - }, - } - ret.Flags().Float64(temporalMaxParallelActivitiesFlag, 10, "Maximum number of parallel activities") - ret.Flags().String(stackURLFlag, "", "Stack url") - ret.Flags().String(stackClientIDFlag, "", "Stack client ID") - ret.Flags().String(stackClientSecretFlag, "", "Stack client secret") - ret.Flags().String(temporalAddressFlag, "", "Temporal server address") - ret.Flags().String(temporalNamespaceFlag, "default", "Temporal namespace") - ret.Flags().String(temporalSSLClientKeyFlag, "", "Temporal client key") - ret.Flags().String(temporalSSLClientCertFlag, "", "Temporal client cert") - ret.Flags().String(temporalTaskQueueFlag, "default", "Temporal task queue name") - ret.Flags().Bool(temporalInitSearchAttributes, false, "Init temporal search attributes") - ret.Flags().StringSlice(topicsFlag, []string{}, "Topics to listen") - ret.Flags().String(stackFlag, "", "Stack") - - publish.AddFlags(ServiceName, ret.Flags()) - bunconnect.AddFlags(ret.Flags()) - iam.AddFlags(ret.Flags()) - service.AddFlags(ret.Flags()) - licence.AddFlags(ret.Flags()) - - return ret -} diff --git a/ee/orchestration/deploy/auth/config.yaml b/ee/orchestration/deploy/auth/config.yaml deleted file mode 100644 index ebea3f290b..0000000000 --- a/ee/orchestration/deploy/auth/config.yaml +++ /dev/null @@ -1,8 +0,0 @@ ---- -clients: -- id: wallets - secrets: - - wallets -- id: orchestration - secrets: - - orchestration diff --git a/ee/orchestration/deploy/postgres/init-databases.sh b/ee/orchestration/deploy/postgres/init-databases.sh deleted file mode 100755 index db6561e818..0000000000 --- a/ee/orchestration/deploy/postgres/init-databases.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -set -e - -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - CREATE DATABASE auth; - CREATE DATABASE ledger; - CREATE DATABASE orchestration; - GRANT ALL PRIVILEGES ON DATABASE auth TO $POSTGRES_USER; - GRANT ALL PRIVILEGES ON DATABASE ledger TO $POSTGRES_USER; - GRANT ALL PRIVILEGES ON DATABASE orchestration TO $POSTGRES_USER; -EOSQL diff --git a/ee/orchestration/deploy/proxy/.gitignore b/ee/orchestration/deploy/proxy/.gitignore deleted file mode 100644 index 4e11a9d085..0000000000 --- a/ee/orchestration/deploy/proxy/.gitignore +++ /dev/null @@ -1 +0,0 @@ -caddy diff --git a/ee/orchestration/deploy/proxy/Caddyfile b/ee/orchestration/deploy/proxy/Caddyfile deleted file mode 100644 index c9177894f5..0000000000 --- a/ee/orchestration/deploy/proxy/Caddyfile +++ /dev/null @@ -1,14 +0,0 @@ -:8080 { - handle_path /api/ledger/* { - reverse_proxy ledger:3068 - } - handle_path /api/auth/* { - reverse_proxy auth:8080 - } - handle_path /api/orchestration/* { - reverse_proxy api:8080 - } - handle_path /api/wallets/* { - reverse_proxy wallets:8080 - } -} diff --git a/ee/orchestration/examples/delay.yaml b/ee/orchestration/examples/delay.yaml deleted file mode 100644 index e3013bbb4d..0000000000 --- a/ee/orchestration/examples/delay.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -stages: -- delay: - duration: 5s - # 'delay' can be used with a duration or a date - # until: diff --git a/ee/orchestration/examples/failing-workflow.yaml b/ee/orchestration/examples/failing-workflow.yaml deleted file mode 100644 index d333619914..0000000000 --- a/ee/orchestration/examples/failing-workflow.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -stages: -- send: - source: - account: - id: "user" - destination: - account: - id: "bank" - ledger: "default" - amount: - amount: "100" - asset: "EUR/2" diff --git a/ee/orchestration/examples/ledger-to-ledger.yaml b/ee/orchestration/examples/ledger-to-ledger.yaml deleted file mode 100644 index 85fe12c782..0000000000 --- a/ee/orchestration/examples/ledger-to-ledger.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -stages: -- send: - source: - account: - id: "${accountID1}" - ledger: "${ledger}" - destination: - account: - id: "${accountID2}" - ledger: "${ledger}" - amount: - amount: "${amount}" - asset: "EUR/2" diff --git a/ee/orchestration/examples/ledger-to-wallet.yaml b/ee/orchestration/examples/ledger-to-wallet.yaml deleted file mode 100644 index 814a7c4e4e..0000000000 --- a/ee/orchestration/examples/ledger-to-wallet.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -stages: -- send: - source: - account: - id: "${accountID}" - ledger: "${ledger}" - destination: - wallet: - id: "${walletID}" - amount: - amount: "${amount}" - asset: "EUR/2" diff --git a/ee/orchestration/examples/payin-to-wallet.yaml b/ee/orchestration/examples/payin-to-wallet.yaml deleted file mode 100644 index 1c8e15c565..0000000000 --- a/ee/orchestration/examples/payin-to-wallet.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -name: "Credit wallet from payment" -stages: -- send: - source: - payment: - id: "${paymentID}" - destination: - wallet: - id: "${walletID}" - amount: - amount: "${amount}" - asset: "EUR/2" diff --git a/ee/orchestration/examples/update-account-metadata.yaml b/ee/orchestration/examples/update-account-metadata.yaml deleted file mode 100644 index 3638723b4f..0000000000 --- a/ee/orchestration/examples/update-account-metadata.yaml +++ /dev/null @@ -1,8 +0,0 @@ ---- -stages: -- update: - account: - id: "${accountID}" - ledger: "${ledger}" - metadata: - foo: "${value}" diff --git a/ee/orchestration/examples/wait_event.yaml b/ee/orchestration/examples/wait_event.yaml deleted file mode 100644 index 0169a5f2e6..0000000000 --- a/ee/orchestration/examples/wait_event.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -stages: -- wait_event: - event: continue diff --git a/ee/orchestration/examples/wallet-to-payout.yaml b/ee/orchestration/examples/wallet-to-payout.yaml deleted file mode 100644 index 537c132f05..0000000000 --- a/ee/orchestration/examples/wallet-to-payout.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: "Debit wallet to stripe connected account" -stages: -- send: - source: - wallet: - id: "${walletID}" - balance: "${balance}" - destination: - payment: - psp: stripe - amount: - amount: "${amount}" - asset: "EUR/2" diff --git a/ee/orchestration/examples/workflow.yaml b/ee/orchestration/examples/workflow.yaml deleted file mode 100644 index 063672784b..0000000000 --- a/ee/orchestration/examples/workflow.yaml +++ /dev/null @@ -1,27 +0,0 @@ ---- -stages: -- send: - source: - payment: - id: "${paymentID}" - destination: - account: - id: "${temporaryAccount}" - ledger: "${ledger}" - amount: - amount: "${amount}" - asset: "EUR/2" -- wait_event: - event: processed -- send: - source: - account: - id: "${temporaryAccount}" - ledger: "${ledger}" - destination: - account: - id: "${user}" - ledger: "${ledger}" - amount: - amount: "${amount}" - asset: "EUR/2" diff --git a/ee/orchestration/go.mod b/ee/orchestration/go.mod deleted file mode 100644 index 6d3034bba2..0000000000 --- a/ee/orchestration/go.mod +++ /dev/null @@ -1,187 +0,0 @@ -module github.com/formancehq/orchestration - -go 1.22.0 - -toolchain go1.22.7 - -replace github.com/formancehq/formance-sdk-go/v2 => ../../releases/sdks/go - -require ( - github.com/ThreeDotsLabs/watermill v1.3.7 - github.com/expr-lang/expr v1.16.9 - github.com/formancehq/formance-sdk-go/v2 v2.0.0-00010101000000-000000000000 - github.com/formancehq/go-libs v1.7.1 - github.com/go-chi/chi/v5 v5.1.0 - github.com/go-playground/validator/v10 v10.22.1 - github.com/google/uuid v1.6.0 - github.com/iancoleman/strcase v0.3.0 - github.com/pkg/errors v0.9.1 - github.com/spf13/cobra v1.8.1 - github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.9.0 - github.com/uptrace/bun v1.2.3 - go.opentelemetry.io/otel v1.30.0 - go.opentelemetry.io/otel/trace v1.30.0 - go.temporal.io/api v1.39.0 - go.temporal.io/sdk v1.29.1 - go.temporal.io/sdk/contrib/opentelemetry v0.6.0 - go.uber.org/fx v1.22.2 - go.uber.org/mock v0.4.0 - golang.org/x/oauth2 v0.23.0 - gopkg.in/yaml.v3 v3.0.1 -) - -require ( - dario.cat/mergo v1.0.1 // indirect - filippo.io/edwards25519 v1.1.0 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/IBM/sarama v1.43.3 // indirect - github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect - github.com/ThreeDotsLabs/watermill-http/v2 v2.3.1 // indirect - github.com/ThreeDotsLabs/watermill-kafka/v3 v3.0.5 // indirect - github.com/ThreeDotsLabs/watermill-nats/v2 v2.1.1 // indirect - github.com/ajg/form v1.5.1 // indirect - github.com/aws/aws-msk-iam-sasl-signer-go v1.0.0 // indirect - github.com/aws/aws-sdk-go-v2 v1.31.0 // indirect - github.com/aws/aws-sdk-go-v2/config v1.27.36 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.34 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 // indirect - github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.4.18 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.23.0 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.31.0 // indirect - github.com/aws/smithy-go v1.21.0 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/containerd/continuity v0.4.3 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect - github.com/dnwe/otelsarama v0.0.0-20240308230250-9388d9d40bc0 // indirect - github.com/docker/cli v27.3.1+incompatible // indirect - github.com/docker/docker v27.3.1+incompatible // indirect - github.com/docker/go-connections v0.5.0 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/eapache/go-resiliency v1.7.0 // indirect - github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect - github.com/eapache/queue v1.1.0 // indirect - github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 // indirect - github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect - github.com/go-chi/chi v4.1.2+incompatible // indirect - github.com/go-chi/render v1.0.3 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-sql-driver/mysql v1.8.1 // indirect - github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/go-viper/mapstructure/v2 v2.2.1 // indirect - github.com/goccy/go-json v0.10.3 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v5 v5.2.1 // indirect - github.com/golang/mock v1.6.0 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/schema v1.4.1 // indirect - github.com/gorilla/securecookie v1.1.2 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-retryablehttp v0.7.7 // indirect - github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jcmturner/aescts/v2 v2.0.0 // indirect - github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect - github.com/jcmturner/gofork v1.7.6 // indirect - github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect - github.com/jcmturner/rpc/v2 v2.0.3 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/leodido/go-urn v1.4.0 // indirect - github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect - github.com/lestrrat-go/blackmagic v1.0.2 // indirect - github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/jwx v1.2.30 // indirect - github.com/lestrrat-go/option v1.0.1 // indirect - github.com/lib/pq v1.10.9 // indirect - github.com/lithammer/shortuuid/v3 v3.0.7 // indirect - github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/term v0.5.0 // indirect - github.com/muhlemmer/gu v0.3.1 // indirect - github.com/muhlemmer/httpforwarded v0.1.0 // indirect - github.com/nats-io/nats.go v1.37.0 // indirect - github.com/nats-io/nkeys v0.4.7 // indirect - github.com/nats-io/nuid v1.0.1 // indirect - github.com/nexus-rpc/sdk-go v0.0.10 // indirect - github.com/oklog/ulid v1.3.1 // indirect - github.com/onsi/ginkgo/v2 v2.20.2 // indirect - github.com/onsi/gomega v1.34.2 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/opencontainers/runc v1.1.14 // indirect - github.com/ory/dockertest/v3 v3.11.0 // indirect - github.com/pborman/uuid v1.2.1 // indirect - github.com/pierrec/lz4/v4 v4.1.21 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect - github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/riandyrn/otelchi v0.10.0 // indirect - github.com/robfig/cron v1.2.0 // indirect - github.com/rs/cors v1.11.1 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/stretchr/objx v0.5.2 // indirect - github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect - github.com/uptrace/bun/dialect/pgdialect v1.2.3 // indirect - github.com/uptrace/bun/extra/bunotel v1.2.3 // indirect - github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2 // indirect - github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2 // indirect - github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 // indirect - github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect - github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/xdg-go/pbkdf2 v1.0.0 // indirect - github.com/xdg-go/scram v1.1.2 // indirect - github.com/xdg-go/stringprep v1.0.4 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - github.com/xo/dburl v0.23.2 // indirect - github.com/zitadel/oidc/v2 v2.12.2 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0 // indirect - go.opentelemetry.io/otel/log v0.6.0 // indirect - go.opentelemetry.io/otel/metric v1.30.0 // indirect - go.opentelemetry.io/otel/sdk v1.30.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.uber.org/dig v1.18.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.25.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect -) diff --git a/ee/orchestration/go.sum b/ee/orchestration/go.sum deleted file mode 100644 index f29a6c2909..0000000000 --- a/ee/orchestration/go.sum +++ /dev/null @@ -1,555 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/IBM/sarama v1.43.3 h1:Yj6L2IaNvb2mRBop39N7mmJAHBVY3dTPncr3qGVkxPA= -github.com/IBM/sarama v1.43.3/go.mod h1:FVIRaLrhK3Cla/9FfRF5X9Zua2KpS3SYIXxhac1H+FQ= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/ThreeDotsLabs/watermill v1.3.7 h1:NV0PSTmuACVEOV4dMxRnmGXrmbz8U83LENOvpHekN7o= -github.com/ThreeDotsLabs/watermill v1.3.7/go.mod h1:lBnrLbxOjeMRgcJbv+UiZr8Ylz8RkJ4m6i/VN/Nk+to= -github.com/ThreeDotsLabs/watermill-http/v2 v2.3.1 h1:M0iYM5HsGcoxtiQqprRlYZNZnGk3w5LsE9RbC2R8myQ= -github.com/ThreeDotsLabs/watermill-http/v2 v2.3.1/go.mod h1:RwGHEzGsEEXC/rQNLWQqR83+WPlABgOgnv2kTB56Y4Y= -github.com/ThreeDotsLabs/watermill-kafka/v3 v3.0.5 h1:ud+4txnRgtr3kZXfXZ5+C7kVQEvsLc5HSNUEa0g+X1Q= -github.com/ThreeDotsLabs/watermill-kafka/v3 v3.0.5/go.mod h1:t4o+4A6GB+XC8WL3DandhzPwd265zQuyWMQC/I+WIOU= -github.com/ThreeDotsLabs/watermill-nats/v2 v2.1.1 h1:afAkAFzeooBRQvxElR+6xoigXKCukcZXnE9ACxhwlPI= -github.com/ThreeDotsLabs/watermill-nats/v2 v2.1.1/go.mod h1:stjbT+s4u/s5ime5jdIyvPyjBGwGeJewIN7jxH8gp4k= -github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/aws/aws-msk-iam-sasl-signer-go v1.0.0 h1:UyjtGmO0Uwl/K+zpzPwLoXzMhcN9xmnR2nrqJoBrg3c= -github.com/aws/aws-msk-iam-sasl-signer-go v1.0.0/go.mod h1:TJAXuFs2HcMib3sN5L0gUC+Q01Qvy3DemvA55WuC+iA= -github.com/aws/aws-sdk-go-v2 v1.31.0 h1:3V05LbxTSItI5kUqNwhJrrrY1BAXxXt0sN0l72QmG5U= -github.com/aws/aws-sdk-go-v2 v1.31.0/go.mod h1:ztolYtaEUtdpf9Wftr31CJfLVjOnD/CVRkKOOYgF8hA= -github.com/aws/aws-sdk-go-v2/config v1.27.36 h1:4IlvHh6Olc7+61O1ktesh0jOcqmq/4WG6C2Aj5SKXy0= -github.com/aws/aws-sdk-go-v2/config v1.27.36/go.mod h1:IiBpC0HPAGq9Le0Xxb1wpAKzEfAQ3XlYgJLYKEVYcfw= -github.com/aws/aws-sdk-go-v2/credentials v1.17.34 h1:gmkk1l/cDGSowPRzkdxYi8edw+gN4HmVK151D/pqGNc= -github.com/aws/aws-sdk-go-v2/credentials v1.17.34/go.mod h1:4R9OEV3tgFMsok4ZeFpExn7zQaZRa9MRGFYnI/xC/vs= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 h1:C/d03NAmh8C4BZXhuRNboF/DqhBkBCeDiJDcaqIT5pA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14/go.mod h1:7I0Ju7p9mCIdlrfS+JCgqcYD0VXz/N4yozsox+0o078= -github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.4.18 h1:k51348zRERIvv01FflXAOQj50NeUiZUGOEedT4Vg+UE= -github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.4.18/go.mod h1:uybY6ESdxsT2dpzwSmpDgZJ3ekCYwVe/ZFYfAaXUbtU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 h1:kYQ3H1u0ANr9KEKlGs/jTLrBFPo8P8NaH/w7A01NeeM= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18/go.mod h1:r506HmK5JDUh9+Mw4CfGJGSSoqIiLCndAuqXuhbv67Y= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 h1:Z7IdFUONvTcvS7YuhtVxN99v2cCoHRXOS4mTr0B/pUc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18/go.mod h1:DkKMmksZVVyat+Y+r1dEOgJEfUeA7UngIHWeKsi0yNc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 h1:QFASJGfT8wMXtuP3D5CRmMjARHv9ZmzFUMJznHDOY3w= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5/go.mod h1:QdZ3OmoIjSX+8D1OPAzPxDfjXASbBMDsz9qvtyIhtik= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 h1:Xbwbmk44URTiHNx6PNo0ujDE6ERlsCKJD3u1zfnzAPg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20/go.mod h1:oAfOFzUB14ltPZj1rWwRc3d/6OgD76R8KlvU3EqM9Fg= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.0 h1:fHySkG0IGj2nepgGJPmmhZYL9ndnsq1Tvc6MeuVQCaQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.0/go.mod h1:XRlMvmad0ZNL+75C5FYdMvbbLkd6qiqz6foR1nA1PXY= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.0 h1:cU/OeQPNReyMj1JEBgjE29aclYZYtXcsPMXbTkVGMFk= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.0/go.mod h1:FnvDM4sfa+isJ3kDXIzAB9GAwVSzFzSy97uZ3IsHo4E= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.0 h1:GNVxIHBTi2EgwCxpNiozhNasMOK+ROUA2Z3X+cSBX58= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.0/go.mod h1:yMWe0F+XG0DkRZK5ODZhG7BEFYhLXi2dqGsv6tX0cgI= -github.com/aws/smithy-go v1.21.0 h1:H7L8dtDRk0P1Qm6y0ji7MCYMQObJ5R9CRpyPhRUkLYA= -github.com/aws/smithy-go v1.21.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= -github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/dnwe/otelsarama v0.0.0-20240308230250-9388d9d40bc0 h1:R2zQhFwSCyyd7L43igYjDrH0wkC/i+QBPELuY0HOu84= -github.com/dnwe/otelsarama v0.0.0-20240308230250-9388d9d40bc0/go.mod h1:2MqLKYJfjs3UriXXF9Fd0Qmh/lhxi/6tHXkqtXxyIHc= -github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ= -github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= -github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA= -github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= -github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws= -github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= -github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 h1:S92OBrGuLLZsyM5ybUzgc/mPjIYk2AZqufieooe98uw= -github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05/go.mod h1:M9R1FoZ3y//hwwnJtO51ypFGwm8ZfpxPT/ZLtO1mcgQ= -github.com/expr-lang/expr v1.16.9 h1:WUAzmR0JNI9JCiF0/ewwHB1gmcGw5wW7nWt8gc6PpCI= -github.com/expr-lang/expr v1.16.9/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4= -github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw= -github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/formancehq/go-libs v1.7.1 h1:9D5cxKWFlVtdX5AYDXeUz1Nb9PdoEfQX0f/yeLsU324= -github.com/formancehq/go-libs v1.7.1/go.mod h1:pWTScpoyieF7OoJ6WVmXNG9NhDjbZbAmFqd7UOw85iI= -github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= -github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= -github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= -github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= -github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4= -github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= -github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= -github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= -github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= -github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= -github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= -github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 h1:c5FlPPgxOn7kJz3VoPLkQYQXGBS3EklQ4Zfi57uOuqQ= -github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= -github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= -github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= -github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= -github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= -github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= -github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= -github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= -github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= -github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= -github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs= -github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA= -github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= -github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= -github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= -github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= -github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= -github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= -github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= -github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= -github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= -github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= -github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= -github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= -github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= -github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= -github.com/jeremija/gosubmit v0.2.7/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= -github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= -github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= -github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= -github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= -github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.30 h1:VKIFrmjYn0z2J51iLPadqoHIVLzvWNa1kCsTqNDHYPA= -github.com/lestrrat-go/jwx v1.2.30/go.mod h1:vMxrwFhunGZ3qddmfmEm2+uced8MSI6QFWGTKygjSzQ= -github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= -github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8= -github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q= -github.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -github.com/muhlemmer/gu v0.3.1 h1:7EAqmFrW7n3hETvuAdmFmn4hS8W+z3LgKtrnow+YzNM= -github.com/muhlemmer/gu v0.3.1/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZkrdM= -github.com/muhlemmer/httpforwarded v0.1.0 h1:x4DLrzXdliq8mprgUMR0olDvHGkou5BJsK/vWUetyzY= -github.com/muhlemmer/httpforwarded v0.1.0/go.mod h1:yo9czKedo2pdZhoXe+yDkGVbU0TJ0q9oQ90BVoDEtw0= -github.com/nats-io/jwt/v2 v2.7.0 h1:J+ZnaaMGQi3xSB8iOhVM5ipiWCDrQvgEoitTwWFyOYw= -github.com/nats-io/jwt/v2 v2.7.0/go.mod h1:ZdWS1nZa6WMZfFwwgpEaqBV8EPGVgOTDHN/wTbz0Y5A= -github.com/nats-io/nats-server/v2 v2.10.20 h1:CXDTYNHeBiAKBTAIP2gjpgbWap2GhATnTLgP8etyvEI= -github.com/nats-io/nats-server/v2 v2.10.20/go.mod h1:hgcPnoUtMfxz1qVOvLZGurVypQ+Cg6GXVXjG53iHk+M= -github.com/nats-io/nats.go v1.37.0 h1:07rauXbVnnJvv1gfIyghFEo6lUcYRY0WXc3x7x0vUxE= -github.com/nats-io/nats.go v1.37.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= -github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI= -github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc= -github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/nexus-rpc/sdk-go v0.0.10 h1:7jEPUlsghxoD4OJ2H8YbFJ1t4wbxsUef7yZgBfyY3uA= -github.com/nexus-rpc/sdk-go v0.0.10/go.mod h1:TpfkM2Cw0Rlk9drGkoiSMpFqflKTiQLWUNyKJjF8mKQ= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= -github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= -github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= -github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opencontainers/runc v1.1.14 h1:rgSuzbmgz5DUJjeSnw337TxDbRuqjs6iqQck/2weR6w= -github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/ory/dockertest/v3 v3.11.0 h1:OiHcxKAvSDUwsEVh2BjxQQc/5EHz9n0va9awCtNGuyA= -github.com/ory/dockertest/v3 v3.11.0/go.mod h1:VIPxS1gwT9NpPOrfD3rACs8Y9Z7yhzO4SB194iUDnUI= -github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= -github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= -github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4= -github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/riandyrn/otelchi v0.10.0 h1:QMbR/FMDWBOkej6dfyWteYefUKqIFxnyrpaoWRJ9RPQ= -github.com/riandyrn/otelchi v0.10.0/go.mod h1:zBaX2FavWMlsvq4GqHit+QXxF1c5wIMZZFaYyW4+7FA= -github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= -github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= -github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= -github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= -github.com/uptrace/bun v1.2.3 h1:6KDc6YiNlXde38j9ATKufb8o7MS8zllhAOeIyELKrk0= -github.com/uptrace/bun v1.2.3/go.mod h1:8frYFHrO/Zol3I4FEjoXam0HoNk+t5k7aJRl3FXp0mk= -github.com/uptrace/bun/dialect/pgdialect v1.2.3 h1:YyCxxqeL0lgFWRZzKCOt6mnxUsjqITcxSo0mLqgwMUA= -github.com/uptrace/bun/dialect/pgdialect v1.2.3/go.mod h1:Vx9TscyEq1iN4tnirn6yYGwEflz0KG3rBZTBCLpKAjc= -github.com/uptrace/bun/extra/bundebug v1.2.3 h1:2QBykz9/u4SkN9dnraImDcbrMk2fUhuq2gL6hkh9qSc= -github.com/uptrace/bun/extra/bundebug v1.2.3/go.mod h1:bihsYJxXxWZXwc1R3qALTHvp+npE0ElgaCvcjzyPPdw= -github.com/uptrace/bun/extra/bunotel v1.2.3 h1:G19QpDE68TXw97x6NciB6nKVDuK0Wb2KgtyMqNIyqBI= -github.com/uptrace/bun/extra/bunotel v1.2.3/go.mod h1:jHRgTqLlX/Zj1KIDokCMDat6JwZHJyErOx0PQ10UFgQ= -github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2 h1:H8wwQwTe5sL6x30z71lUgNiwBdeCHQjrphCfLwqIHGo= -github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2/go.mod h1:/kR4beFhlz2g+V5ik8jW+3PMiMQAPt29y6K64NNY53c= -github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2 h1:ZjUj9BLYf9PEqBn8W/OapxhPjVRdC6CsXTdULHsyk5c= -github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2/go.mod h1:O8bHQfyinKwTXKkiKNGmLQS7vRsqRxIQTFZpYpHK3IQ= -github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 h1:3/aHKUq7qaFMWxyQV0W2ryNgg8x8rVeKVA20KJUkfS0= -github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2/go.mod h1:Zit4b8AQXaXvA68+nzmbyDzqiyFRISyw1JiD5JqUBjw= -github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= -github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= -github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= -github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= -github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xo/dburl v0.23.2 h1:Fl88cvayrgE56JA/sqhNMLljCW/b7RmG1mMkKMZUFgA= -github.com/xo/dburl v0.23.2/go.mod h1:uazlaAQxj4gkshhfuuYyvwCBouOmNnG2aDxTCFZpmL4= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zitadel/oidc/v2 v2.12.2 h1:3kpckg4rurgw7w7aLJrq7yvRxb2pkNOtD08RH42vPEs= -github.com/zitadel/oidc/v2 v2.12.2/go.mod h1:vhP26g1g4YVntcTi0amMYW3tJuid70nxqxf+kb6XKgg= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI= -go.opentelemetry.io/contrib/propagators/b3 v1.30.0 h1:vumy4r1KMyaoQRltX7cJ37p3nluzALX9nugCjNNefuY= -go.opentelemetry.io/contrib/propagators/b3 v1.30.0/go.mod h1:fRbvRsaeVZ82LIl3u0rIvusIel2UUf+JcaaIpy5taho= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 h1:umZgi92IyxfXd/l4kaDhnKgY8rnN/cZcF1LKc6I8OQ8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0/go.mod h1:4lVs6obhSVRb1EW5FhOuBTyiQhtRtAnnva9vD3yRfq8= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0 h1:kn1BudCgwtE7PxLqcZkErpD8GKqLZ6BSzeW9QihQJeM= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0/go.mod h1:ljkUDtAMdleoi9tIG1R6dJUpVwDcYjw3J2Q6Q/SuiC0= -go.opentelemetry.io/otel/log v0.6.0 h1:nH66tr+dmEgW5y+F9LanGJUBYPrRgP4g2EkmPE3LeK8= -go.opentelemetry.io/otel/log v0.6.0/go.mod h1:KdySypjQHhP069JX0z/t26VHwa8vSwzgaKmXtIB3fJM= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= -go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= -go.opentelemetry.io/otel/sdk/metric v1.30.0 h1:QJLT8Pe11jyHBHfSAgYH7kEmT24eX792jZO1bo4BXkM= -go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.temporal.io/api v1.39.0 h1:pbhcfvNDB7mllb8lIBqPcg+m6LMG/IhTpdiFxe+0mYk= -go.temporal.io/api v1.39.0/go.mod h1:1WwYUMo6lao8yl0371xWUm13paHExN5ATYT/B7QtFis= -go.temporal.io/sdk v1.29.1 h1:y+sUMbUhTU9rj50mwIZAPmcXCtgUdOWS9xHDYRYSgZ0= -go.temporal.io/sdk v1.29.1/go.mod h1:kp//DRvn3CqQVBCtjL51Oicp9wrZYB2s6row1UgzcKQ= -go.temporal.io/sdk/contrib/opentelemetry v0.6.0 h1:rNBArDj5iTUkcMwKocUShoAW59o6HdS7Nq4CTp4ldj8= -go.temporal.io/sdk/contrib/opentelemetry v0.6.0/go.mod h1:Lem8VrE2ks8P+FYcRM3UphPoBr+tfM3v/Kaf0qStzSg= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= -go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= -go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs= -gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/ee/orchestration/internal/api/backend.go b/ee/orchestration/internal/api/backend.go deleted file mode 100644 index 319e273efa..0000000000 --- a/ee/orchestration/internal/api/backend.go +++ /dev/null @@ -1,43 +0,0 @@ -package api - -import ( - "context" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/formancehq/orchestration/internal/triggers" - "github.com/formancehq/orchestration/internal/workflow" -) - -//go:generate mockgen -source backend.go -destination backend_generated.go -package api . Backend - -type Backend interface { - CreateTrigger(context context.Context, data triggers.TriggerData) (*triggers.Trigger, error) - AbortRun(ctx context.Context, id string) error - Create(ctx context.Context, config workflow.Config) (*workflow.Workflow, error) - DeleteWorkflow(ctx context.Context, id string) error - ListInstances(ctx context.Context, pagination workflow.ListInstancesQuery) (*bunpaginate.Cursor[workflow.Instance], error) - ListTriggers(ctx context.Context, query triggers.ListTriggersQuery) (*bunpaginate.Cursor[triggers.Trigger], error) - ListWorkflows(ctx context.Context, query bunpaginate.OffsetPaginatedQuery[any]) (*bunpaginate.Cursor[workflow.Workflow], error) - PostEvent(ctx context.Context, id string, event workflow.Event) error - GetInstance(ctx context.Context, id string) (*workflow.Instance, error) - ReadInstanceHistory(ctx context.Context, id string) ([]workflow.StageHistory, error) - ReadStageHistory(ctx context.Context, instanceID string, stage int) ([]*workflow.ActivityHistory, error) - ReadWorkflow(ctx context.Context, id string) (workflow.Workflow, error) - RunWorkflow(ctx context.Context, id string, input map[string]string) (*workflow.Instance, error) - Wait(ctx context.Context, id string) error - ListTriggersOccurrences(ctx context.Context, query triggers.ListTriggersOccurrencesQuery) (*bunpaginate.Cursor[triggers.Occurrence], error) - DeleteTrigger(ctx context.Context, triggerID string) error - GetTrigger(ctx context.Context, triggerID string) (*triggers.Trigger, error) - TestTrigger(ctx context.Context, triggerID string, data map[string]any) (*triggers.TestTriggerResult, error) -} - -func NewDefaultBackend(triggersManager *triggers.TriggerManager, workflowManager *workflow.WorkflowManager) Backend { - return struct { - *triggers.TriggerManager - *workflow.WorkflowManager - }{ - WorkflowManager: workflowManager, - TriggerManager: triggersManager, - } -} diff --git a/ee/orchestration/internal/api/backend_generated.go b/ee/orchestration/internal/api/backend_generated.go deleted file mode 100644 index 52e6da5610..0000000000 --- a/ee/orchestration/internal/api/backend_generated.go +++ /dev/null @@ -1,307 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: backend.go -// -// Generated by this command: -// -// mockgen -source backend.go -destination backend_generated.go -package api . Backend -// -// Package api is a generated GoMock package. -package api - -import ( - context "context" - reflect "reflect" - - triggers "github.com/formancehq/orchestration/internal/triggers" - workflow "github.com/formancehq/orchestration/internal/workflow" - bunpaginate "github.com/formancehq/go-libs/bun/bunpaginate" - gomock "go.uber.org/mock/gomock" -) - -// MockBackend is a mock of Backend interface. -type MockBackend struct { - ctrl *gomock.Controller - recorder *MockBackendMockRecorder -} - -// MockBackendMockRecorder is the mock recorder for MockBackend. -type MockBackendMockRecorder struct { - mock *MockBackend -} - -// NewMockBackend creates a new mock instance. -func NewMockBackend(ctrl *gomock.Controller) *MockBackend { - mock := &MockBackend{ctrl: ctrl} - mock.recorder = &MockBackendMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockBackend) EXPECT() *MockBackendMockRecorder { - return m.recorder -} - -// AbortRun mocks base method. -func (m *MockBackend) AbortRun(ctx context.Context, id string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AbortRun", ctx, id) - ret0, _ := ret[0].(error) - return ret0 -} - -// AbortRun indicates an expected call of AbortRun. -func (mr *MockBackendMockRecorder) AbortRun(ctx, id any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortRun", reflect.TypeOf((*MockBackend)(nil).AbortRun), ctx, id) -} - -// Create mocks base method. -func (m *MockBackend) Create(ctx context.Context, config workflow.Config) (*workflow.Workflow, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Create", ctx, config) - ret0, _ := ret[0].(*workflow.Workflow) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Create indicates an expected call of Create. -func (mr *MockBackendMockRecorder) Create(ctx, config any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockBackend)(nil).Create), ctx, config) -} - -// CreateTrigger mocks base method. -func (m *MockBackend) CreateTrigger(context context.Context, data triggers.TriggerData) (*triggers.Trigger, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateTrigger", context, data) - ret0, _ := ret[0].(*triggers.Trigger) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CreateTrigger indicates an expected call of CreateTrigger. -func (mr *MockBackendMockRecorder) CreateTrigger(context, data any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTrigger", reflect.TypeOf((*MockBackend)(nil).CreateTrigger), context, data) -} - -// DeleteTrigger mocks base method. -func (m *MockBackend) DeleteTrigger(ctx context.Context, triggerID string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteTrigger", ctx, triggerID) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteTrigger indicates an expected call of DeleteTrigger. -func (mr *MockBackendMockRecorder) DeleteTrigger(ctx, triggerID any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTrigger", reflect.TypeOf((*MockBackend)(nil).DeleteTrigger), ctx, triggerID) -} - -// DeleteWorkflow mocks base method. -func (m *MockBackend) DeleteWorkflow(ctx context.Context, id string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteWorkflow", ctx, id) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteWorkflow indicates an expected call of DeleteWorkflow. -func (mr *MockBackendMockRecorder) DeleteWorkflow(ctx, id any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWorkflow", reflect.TypeOf((*MockBackend)(nil).DeleteWorkflow), ctx, id) -} - -// GetInstance mocks base method. -func (m *MockBackend) GetInstance(ctx context.Context, id string) (*workflow.Instance, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetInstance", ctx, id) - ret0, _ := ret[0].(*workflow.Instance) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetInstance indicates an expected call of GetInstance. -func (mr *MockBackendMockRecorder) GetInstance(ctx, id any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInstance", reflect.TypeOf((*MockBackend)(nil).GetInstance), ctx, id) -} - -// GetTrigger mocks base method. -func (m *MockBackend) GetTrigger(ctx context.Context, triggerID string) (*triggers.Trigger, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTrigger", ctx, triggerID) - ret0, _ := ret[0].(*triggers.Trigger) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetTrigger indicates an expected call of GetTrigger. -func (mr *MockBackendMockRecorder) GetTrigger(ctx, triggerID any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrigger", reflect.TypeOf((*MockBackend)(nil).GetTrigger), ctx, triggerID) -} - -// ListInstances mocks base method. -func (m *MockBackend) ListInstances(ctx context.Context, pagination workflow.ListInstancesQuery) (*bunpaginate.Cursor[workflow.Instance], error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListInstances", ctx, pagination) - ret0, _ := ret[0].(*bunpaginate.Cursor[workflow.Instance]) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListInstances indicates an expected call of ListInstances. -func (mr *MockBackendMockRecorder) ListInstances(ctx, pagination any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListInstances", reflect.TypeOf((*MockBackend)(nil).ListInstances), ctx, pagination) -} - -// ListTriggers mocks base method. -func (m *MockBackend) ListTriggers(ctx context.Context, query triggers.ListTriggersQuery) (*bunpaginate.Cursor[triggers.Trigger], error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListTriggers", ctx, query) - ret0, _ := ret[0].(*bunpaginate.Cursor[triggers.Trigger]) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListTriggers indicates an expected call of ListTriggers. -func (mr *MockBackendMockRecorder) ListTriggers(ctx, query any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTriggers", reflect.TypeOf((*MockBackend)(nil).ListTriggers), ctx, query) -} - -// ListTriggersOccurrences mocks base method. -func (m *MockBackend) ListTriggersOccurrences(ctx context.Context, query triggers.ListTriggersOccurrencesQuery) (*bunpaginate.Cursor[triggers.Occurrence], error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListTriggersOccurrences", ctx, query) - ret0, _ := ret[0].(*bunpaginate.Cursor[triggers.Occurrence]) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListTriggersOccurrences indicates an expected call of ListTriggersOccurrences. -func (mr *MockBackendMockRecorder) ListTriggersOccurrences(ctx, query any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTriggersOccurrences", reflect.TypeOf((*MockBackend)(nil).ListTriggersOccurrences), ctx, query) -} - -// ListWorkflows mocks base method. -func (m *MockBackend) ListWorkflows(ctx context.Context, query bunpaginate.OffsetPaginatedQuery[any]) (*bunpaginate.Cursor[workflow.Workflow], error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListWorkflows", ctx, query) - ret0, _ := ret[0].(*bunpaginate.Cursor[workflow.Workflow]) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListWorkflows indicates an expected call of ListWorkflows. -func (mr *MockBackendMockRecorder) ListWorkflows(ctx, query any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListWorkflows", reflect.TypeOf((*MockBackend)(nil).ListWorkflows), ctx, query) -} - -// PostEvent mocks base method. -func (m *MockBackend) PostEvent(ctx context.Context, id string, event workflow.Event) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PostEvent", ctx, id, event) - ret0, _ := ret[0].(error) - return ret0 -} - -// PostEvent indicates an expected call of PostEvent. -func (mr *MockBackendMockRecorder) PostEvent(ctx, id, event any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PostEvent", reflect.TypeOf((*MockBackend)(nil).PostEvent), ctx, id, event) -} - -// ReadInstanceHistory mocks base method. -func (m *MockBackend) ReadInstanceHistory(ctx context.Context, id string) ([]workflow.StageHistory, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadInstanceHistory", ctx, id) - ret0, _ := ret[0].([]workflow.StageHistory) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ReadInstanceHistory indicates an expected call of ReadInstanceHistory. -func (mr *MockBackendMockRecorder) ReadInstanceHistory(ctx, id any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadInstanceHistory", reflect.TypeOf((*MockBackend)(nil).ReadInstanceHistory), ctx, id) -} - -// ReadStageHistory mocks base method. -func (m *MockBackend) ReadStageHistory(ctx context.Context, instanceID string, stage int) ([]*workflow.ActivityHistory, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadStageHistory", ctx, instanceID, stage) - ret0, _ := ret[0].([]*workflow.ActivityHistory) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ReadStageHistory indicates an expected call of ReadStageHistory. -func (mr *MockBackendMockRecorder) ReadStageHistory(ctx, instanceID, stage any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadStageHistory", reflect.TypeOf((*MockBackend)(nil).ReadStageHistory), ctx, instanceID, stage) -} - -// ReadWorkflow mocks base method. -func (m *MockBackend) ReadWorkflow(ctx context.Context, id string) (workflow.Workflow, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadWorkflow", ctx, id) - ret0, _ := ret[0].(workflow.Workflow) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ReadWorkflow indicates an expected call of ReadWorkflow. -func (mr *MockBackendMockRecorder) ReadWorkflow(ctx, id any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadWorkflow", reflect.TypeOf((*MockBackend)(nil).ReadWorkflow), ctx, id) -} - -// RunWorkflow mocks base method. -func (m *MockBackend) RunWorkflow(ctx context.Context, id string, input map[string]string) (*workflow.Instance, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RunWorkflow", ctx, id, input) - ret0, _ := ret[0].(*workflow.Instance) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// RunWorkflow indicates an expected call of RunWorkflow. -func (mr *MockBackendMockRecorder) RunWorkflow(ctx, id, input any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunWorkflow", reflect.TypeOf((*MockBackend)(nil).RunWorkflow), ctx, id, input) -} - -// TestTrigger mocks base method. -func (m *MockBackend) TestTrigger(ctx context.Context, triggerID string, data map[string]any) (*triggers.TestTriggerResult, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TestTrigger", ctx, triggerID, data) - ret0, _ := ret[0].(*triggers.TestTriggerResult) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// TestTrigger indicates an expected call of TestTrigger. -func (mr *MockBackendMockRecorder) TestTrigger(ctx, triggerID, data any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TestTrigger", reflect.TypeOf((*MockBackend)(nil).TestTrigger), ctx, triggerID, data) -} - -// Wait mocks base method. -func (m *MockBackend) Wait(ctx context.Context, id string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Wait", ctx, id) - ret0, _ := ret[0].(error) - return ret0 -} - -// Wait indicates an expected call of Wait. -func (mr *MockBackendMockRecorder) Wait(ctx, id any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Wait", reflect.TypeOf((*MockBackend)(nil).Wait), ctx, id) -} diff --git a/ee/orchestration/internal/api/handler_info.go b/ee/orchestration/internal/api/handler_info.go deleted file mode 100644 index 5ff4c4379b..0000000000 --- a/ee/orchestration/internal/api/handler_info.go +++ /dev/null @@ -1,17 +0,0 @@ -package api - -import ( - "net/http" - - "github.com/formancehq/go-libs/api" -) - -type ServiceInfo struct { - Version string `json:"version"` -} - -func getInfo(info ServiceInfo) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - api.RawOk(w, info) - } -} diff --git a/ee/orchestration/internal/api/module.go b/ee/orchestration/internal/api/module.go deleted file mode 100644 index 95f7578f3f..0000000000 --- a/ee/orchestration/internal/api/module.go +++ /dev/null @@ -1,26 +0,0 @@ -package api - -import ( - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/go-libs/health" - "github.com/go-chi/chi/v5" - "go.uber.org/fx" -) - -func TagVersion() fx.Annotation { - return fx.ResultTags(`group:"apiVersions"`) -} - -func NewModule(debug bool) fx.Option { - return fx.Options( - fx.Provide(fx.Annotate(func( - backend Backend, - info ServiceInfo, - healthController *health.HealthController, - authenticator auth.Authenticator, - versions ...Version) *chi.Mux { - return NewRouter(backend, info, healthController, authenticator, debug, versions...) - }, fx.ParamTags(``, ``, ``, ``, `group:"apiVersions"`))), - fx.Provide(NewDefaultBackend), - ) -} diff --git a/ee/orchestration/internal/api/module_test.go b/ee/orchestration/internal/api/module_test.go deleted file mode 100644 index bca42cdc31..0000000000 --- a/ee/orchestration/internal/api/module_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package api_test - -import ( - "net/http" - "net/http/httptest" - "testing" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/formancehq/go-libs/auth" - - "github.com/formancehq/go-libs/health" - "github.com/formancehq/orchestration/internal/api" - v1 "github.com/formancehq/orchestration/internal/api/v1" - v2 "github.com/formancehq/orchestration/internal/api/v2" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - "go.uber.org/fx" - "go.uber.org/fx/fxtest" - "go.uber.org/mock/gomock" -) - -func TestModule(t *testing.T) { - - ctrl := gomock.NewController(t) - backend := api.NewMockBackend(ctrl) - - var mux *chi.Mux - app := fxtest.New(t, - auth.Module(auth.ModuleConfig{Enabled: false}), - fx.Supply(&health.HealthController{}), - fx.Supply(api.ServiceInfo{}), - fx.Replace(fx.Annotate(backend, fx.As(new(api.Backend)))), - fx.NopLogger, - api.NewModule(testing.Verbose()), - v1.NewModule(), - v2.NewModule(), - fx.Populate(&mux), - ) - app.RequireStart() - - backend.EXPECT(). - ListWorkflows(gomock.Any(), gomock.Any()). - AnyTimes(). - Return(&sharedapi.Cursor[workflow.Workflow]{}, nil) - - req := httptest.NewRequest(http.MethodGet, "/workflows", nil) - rsp := httptest.NewRecorder() - mux.ServeHTTP(rsp, req) - require.Equal(t, http.StatusOK, rsp.Code) - - req = httptest.NewRequest(http.MethodGet, "/v2/workflows", nil) - rsp = httptest.NewRecorder() - mux.ServeHTTP(rsp, req) - require.Equal(t, http.StatusOK, rsp.Code) -} diff --git a/ee/orchestration/internal/api/router.go b/ee/orchestration/internal/api/router.go deleted file mode 100644 index 0701e736de..0000000000 --- a/ee/orchestration/internal/api/router.go +++ /dev/null @@ -1,63 +0,0 @@ -package api - -import ( - "fmt" - "net/http" - "sort" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/go-libs/health" - "github.com/go-chi/chi/v5/middleware" -) - -type Version struct { - Version int - Builder func(backend Backend, a auth.Authenticator, debug bool) *chi.Mux -} - -type versionsSlice []Version - -func (v versionsSlice) Len() int { - return len(v) -} - -func (v versionsSlice) Less(i, j int) bool { - return v[i].Version < v[j].Version -} - -func (v versionsSlice) Swap(i, j int) { - v[i], v[j] = v[j], v[i] -} - -func NewRouter( - backend Backend, - info ServiceInfo, - healthController *health.HealthController, - authenticator auth.Authenticator, - debug bool, - versions ...Version) *chi.Mux { - r := chi.NewRouter() - r.Use(middleware.Recoverer) - r.Use(func(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - handler.ServeHTTP(w, r) - }) - }) - r.Get("/_healthcheck", healthController.Check) - r.Get("/_info", getInfo(info)) - - sortedVersions := versionsSlice(versions) - sort.Stable(sortedVersions) - - for _, version := range sortedVersions[1:] { - prefix := fmt.Sprintf("/v%d", version.Version) - r.Handle(prefix+"/*", http.StripPrefix(prefix, version.Builder(backend, authenticator, debug))) - } - - r.Handle("/*", versions[0].Builder(backend, authenticator, debug)) // V1 has no prefix - - return r -} diff --git a/ee/orchestration/internal/api/v1/handler_abort_workflow_instance.go b/ee/orchestration/internal/api/v1/handler_abort_workflow_instance.go deleted file mode 100644 index 3669011a6c..0000000000 --- a/ee/orchestration/internal/api/v1/handler_abort_workflow_instance.go +++ /dev/null @@ -1,19 +0,0 @@ -package v1 - -import ( - "net/http" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" -) - -func abortWorkflowInstance(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if err := backend.AbortRun(r.Context(), instanceID(r)); err != nil { - api.InternalServerError(w, r, err) - return - } - api.NoContent(w) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_create_trigger.go b/ee/orchestration/internal/api/v1/handler_create_trigger.go deleted file mode 100644 index 7e568ccf0b..0000000000 --- a/ee/orchestration/internal/api/v1/handler_create_trigger.go +++ /dev/null @@ -1,40 +0,0 @@ -package v1 - -import ( - "encoding/json" - "net/http" - - "github.com/formancehq/orchestration/internal/api" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/triggers" - "github.com/pkg/errors" -) - -func createTrigger(backend api.Backend) func(writer http.ResponseWriter, request *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - - data := triggers.TriggerData{} - if err := json.NewDecoder(r.Body).Decode(&data); err != nil { - sharedapi.InternalServerError(w, r, err) - return - } - - trigger, err := backend.CreateTrigger(r.Context(), data) - if err != nil { - switch { - case errors.Is(err, triggers.ErrMissingWorkflowID), - errors.Is(err, triggers.ErrMissingEvent), - triggers.IsExprCompilationError(err): - sharedapi.BadRequest(w, "VALIDATION", err) - case errors.Is(err, triggers.ErrWorkflowNotExists): - sharedapi.NotFound(w, err) - default: - sharedapi.InternalServerError(w, r, err) - } - return - } - - sharedapi.Created(w, trigger) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_create_trigger_test.go b/ee/orchestration/internal/api/v1/handler_create_trigger_test.go deleted file mode 100644 index 80246d9968..0000000000 --- a/ee/orchestration/internal/api/v1/handler_create_trigger_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package v1 - -import ( - "bytes" - "context" - "fmt" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/orchestration/internal/api" - "github.com/go-chi/chi/v5" - - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestCreateTrigger(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - - w, err := m.Create(context.Background(), workflow.Config{}) - require.NoError(t, err) - - req := httptest.NewRequest(http.MethodPost, "/triggers", - bytes.NewBufferString(fmt.Sprintf(`{"workflowID": "%s", "event": "SAVED_PAYMENT"}`, w.ID))) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusCreated, rec.Result().StatusCode) - }) -} diff --git a/ee/orchestration/internal/api/v1/handler_create_workflow.go b/ee/orchestration/internal/api/v1/handler_create_workflow.go deleted file mode 100644 index e112db0c69..0000000000 --- a/ee/orchestration/internal/api/v1/handler_create_workflow.go +++ /dev/null @@ -1,50 +0,0 @@ -package v1 - -import ( - "encoding/json" - "net/http" - - "gopkg.in/yaml.v3" - - "github.com/formancehq/go-libs/api" - api2 "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/pkg/errors" -) - -func createWorkflow(m api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - config := workflow.Config{} - if r.Header.Get("Content-Type") == "text/vnd.yaml" { - payload := make(map[string]any) - if err := yaml.NewDecoder(r.Body).Decode(&payload); err != nil { - api.BadRequest(w, "VALIDATION", errors.Wrap(err, "unmarshalling yaml")) - return - } - - asJson, err := json.Marshal(payload) - if err != nil { - panic(err) - } - - if err := json.Unmarshal(asJson, &config); err != nil { - api.BadRequest(w, "VALIDATION", errors.Wrap(err, "unmarshalling workflow data")) - return - } - } else { - if err := json.NewDecoder(r.Body).Decode(&config); err != nil { - api.BadRequest(w, "VALIDATION", errors.Wrap(err, "unmarshalling json body")) - return - } - } - - workflow, err := m.Create(r.Context(), config) - if err != nil { - api.InternalServerError(w, r, errors.Wrap(err, "creating workflow")) - return - } - - api.Created(w, workflow) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_create_workflow_test.go b/ee/orchestration/internal/api/v1/handler_create_workflow_test.go deleted file mode 100644 index 6fe248d6f0..0000000000 --- a/ee/orchestration/internal/api/v1/handler_create_workflow_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package v1 - -import ( - "bytes" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/orchestration/internal/api" - "github.com/go-chi/chi/v5" - - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestCreateWorkflow(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - req := httptest.NewRequest(http.MethodPost, "/workflows", bytes.NewBufferString(`{"stages": []}`)) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusCreated, rec.Result().StatusCode) - }) -} diff --git a/ee/orchestration/internal/api/v1/handler_delete_trigger.go b/ee/orchestration/internal/api/v1/handler_delete_trigger.go deleted file mode 100644 index e86ce4d02b..0000000000 --- a/ee/orchestration/internal/api/v1/handler_delete_trigger.go +++ /dev/null @@ -1,28 +0,0 @@ -package v1 - -import ( - "database/sql" - "net/http" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/api" - "github.com/pkg/errors" -) - -func deleteTrigger(backend api.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if err := backend.DeleteTrigger(r.Context(), chi.URLParam(r, "triggerID")); err != nil { - switch { - case errors.Is(err, sql.ErrNoRows): - sharedapi.NotFound(w, err) - default: - sharedapi.InternalServerError(w, r, err) - } - return - } - - sharedapi.NoContent(w) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_delete_workflow.go b/ee/orchestration/internal/api/v1/handler_delete_workflow.go deleted file mode 100644 index 86f517850e..0000000000 --- a/ee/orchestration/internal/api/v1/handler_delete_workflow.go +++ /dev/null @@ -1,42 +0,0 @@ -package v1 - -import ( - "errors" - "net/http" - - "github.com/go-playground/validator/v10" - - "github.com/formancehq/go-libs/api" - api2 "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" -) - -var ( - ErrEmptyID = errors.New("ID is empty") -) - -func deleteWorkflow(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - id := workflowID(r) - - err := validator.New().Var(id, "required,uuid") - if err != nil { - api.BadRequest(w, "VALIDATION", err) - return - } - - err = backend.DeleteWorkflow(r.Context(), workflowID(r)) - - if errors.Is(err, workflow.ErrWorkflowNotFound) { - api.NotFound(w, err) - return - } - - if err != nil { - api.InternalServerError(w, r, err) - return - } - - api.NoContent(w) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_delete_workflow_test.go b/ee/orchestration/internal/api/v1/handler_delete_workflow_test.go deleted file mode 100644 index bfa09517a3..0000000000 --- a/ee/orchestration/internal/api/v1/handler_delete_workflow_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package v1 - -import ( - "bytes" - "fmt" - "net/http" - "net/http/httptest" - "testing" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/testing/api" - - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - - "github.com/uptrace/bun" -) - -func TestDeleteWorkflow(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - // Create a workflow - req := httptest.NewRequest(http.MethodPost, "/workflows", bytes.NewBufferString(`{"stages": []}`)) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusCreated, rec.Result().StatusCode) - - workflow := workflow.Workflow{} - sharedapi.ReadResponse(t, rec, &workflow) - - require.NotEmpty(t, workflow.ID) - - // Delete the workflow - req = httptest.NewRequest(http.MethodDelete, fmt.Sprintf("/workflows/%s/", workflow.ID), nil) - rec = httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusNoContent, rec.Result().StatusCode) - }) -} diff --git a/ee/orchestration/internal/api/v1/handler_get_trigger.go b/ee/orchestration/internal/api/v1/handler_get_trigger.go deleted file mode 100644 index 1a1492fb4c..0000000000 --- a/ee/orchestration/internal/api/v1/handler_get_trigger.go +++ /dev/null @@ -1,30 +0,0 @@ -package v1 - -import ( - "database/sql" - "net/http" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/api" - "github.com/pkg/errors" -) - -func getTrigger(backend api.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - trigger, err := backend.GetTrigger(r.Context(), chi.URLParam(r, "triggerID")) - if err != nil { - switch { - case errors.Is(err, sql.ErrNoRows): - sharedapi.NotFound(w, err) - return - default: - sharedapi.InternalServerError(w, r, err) - } - return - } - - sharedapi.Ok(w, trigger) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_list_instances.go b/ee/orchestration/internal/api/v1/handler_list_instances.go deleted file mode 100644 index 8ecc8751b6..0000000000 --- a/ee/orchestration/internal/api/v1/handler_list_instances.go +++ /dev/null @@ -1,28 +0,0 @@ -package v1 - -import ( - "net/http" - - "github.com/formancehq/orchestration/internal/workflow" - - api "github.com/formancehq/orchestration/internal/api" - - sharedapi "github.com/formancehq/go-libs/api" -) - -func listInstances(backend api.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - runs, err := backend.ListInstances(r.Context(), workflow.ListInstancesQuery{ - Options: workflow.ListInstancesOptions{ - WorkflowID: r.URL.Query().Get("workflowID"), - Running: sharedapi.QueryParamBool(r, "running"), - }, - }) - if err != nil { - sharedapi.InternalServerError(w, r, err) - return - } - sharedapi.Ok(w, runs.Data) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_list_instances_test.go b/ee/orchestration/internal/api/v1/handler_list_instances_test.go deleted file mode 100644 index 47a399d7b4..0000000000 --- a/ee/orchestration/internal/api/v1/handler_list_instances_test.go +++ /dev/null @@ -1,92 +0,0 @@ -package v1 - -import ( - "fmt" - "net/http" - "net/http/httptest" - "testing" - "time" - - "github.com/formancehq/go-libs/logging" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/testing/api" - - "github.com/google/uuid" - - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestListInstances(t *testing.T) { - ctx := logging.TestingContext() - - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - // Create a workflow with 10 instances - w := workflow.New(workflow.Config{}) - _, err := db.NewInsert().Model(&w).Exec(ctx) - require.NoError(t, err) - - for i := 0; i < 10; i++ { - instance := workflow.NewInstance(uuid.NewString(), w.ID) - if i > 5 { - instance.SetTerminated(time.Now()) - } - _, err := db.NewInsert().Model(&instance).Exec(ctx) - require.NoError(t, err) - } - - req := httptest.NewRequest(http.MethodGet, "/instances", nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - - instances := make([]workflow.Instance, 0) - sharedapi.ReadResponse(t, rec, &instances) - require.Len(t, instances, 10) - - // Retrieve only running instances - req = httptest.NewRequest(http.MethodGet, "/instances?running=true", nil) - rec = httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - sharedapi.ReadResponse(t, rec, &instances) - require.Len(t, instances, 6) - - // Delete the workflow - req = httptest.NewRequest(http.MethodDelete, fmt.Sprintf("/workflows/%s/", w.ID), nil) - rec = httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusNoContent, rec.Result().StatusCode) - - // Try to retrieve instances for all workflows - req = httptest.NewRequest(http.MethodGet, "/instances", nil) - rec = httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - instances = make([]workflow.Instance, 0) - sharedapi.ReadResponse(t, rec, &instances) - require.Len(t, instances, 0) - - // Try to retrieve instances for the deleted workflow - req = httptest.NewRequest(http.MethodGet, "/instances?workflowID="+w.ID, nil) - rec = httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - instances = make([]workflow.Instance, 0) - sharedapi.ReadResponse(t, rec, &instances) - require.Len(t, instances, 0) - }) -} diff --git a/ee/orchestration/internal/api/v1/handler_list_triggers.go b/ee/orchestration/internal/api/v1/handler_list_triggers.go deleted file mode 100644 index 4361da6ece..0000000000 --- a/ee/orchestration/internal/api/v1/handler_list_triggers.go +++ /dev/null @@ -1,44 +0,0 @@ -package v1 - -import ( - "net/http" - - "github.com/formancehq/go-libs/bun/bunpaginate" - "github.com/formancehq/orchestration/internal/triggers" - - "github.com/formancehq/orchestration/internal/api" - - sharedapi "github.com/formancehq/go-libs/api" -) - -func listTriggers(backend api.Backend) func(writer http.ResponseWriter, request *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - - query, err := bunpaginate.Extract[triggers.ListTriggersQuery](r, func() (*triggers.ListTriggersQuery, error) { - pageSize, err := bunpaginate.GetPageSize(r) - if err != nil { - return nil, err - } - - var name string = "" - name = r.URL.Query().Get("name") - - return &triggers.ListTriggersQuery{ - PageSize: pageSize, - Options: triggers.ListTriggerParams{Name: name}, - }, nil - }) - if err != nil { - sharedapi.BadRequest(w, "VALIDATION", err) - return - } - - triggers, err := backend.ListTriggers(r.Context(), *query) - if err != nil { - sharedapi.InternalServerError(w, r, err) - return - } - - sharedapi.Ok(w, triggers.Data) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_list_triggers_occurrences.go b/ee/orchestration/internal/api/v1/handler_list_triggers_occurrences.go deleted file mode 100644 index 6a1c0ee798..0000000000 --- a/ee/orchestration/internal/api/v1/handler_list_triggers_occurrences.go +++ /dev/null @@ -1,27 +0,0 @@ -package v1 - -import ( - "net/http" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/triggers" -) - -func listTriggersOccurrences(backend api.Backend) func(writer http.ResponseWriter, request *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - triggersOccurrences, err := backend.ListTriggersOccurrences(r.Context(), triggers.ListTriggersOccurrencesQuery{ - Options: triggers.ListTriggersOccurrencesOptions{ - TriggerID: chi.URLParam(r, "triggerID"), - }, - }) - if err != nil { - sharedapi.InternalServerError(w, r, err) - return - } - - sharedapi.Ok(w, triggersOccurrences.Data) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_list_workflows.go b/ee/orchestration/internal/api/v1/handler_list_workflows.go deleted file mode 100644 index 8c27b3a5bb..0000000000 --- a/ee/orchestration/internal/api/v1/handler_list_workflows.go +++ /dev/null @@ -1,24 +0,0 @@ -package v1 - -import ( - "net/http" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" -) - -func listWorkflows(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - workflows, err := backend.ListWorkflows(r.Context(), bunpaginate.OffsetPaginatedQuery[any]{}) - if err != nil { - api.InternalServerError(w, r, err) - return - } - - api.Ok(w, workflows.Data) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_post_event.go b/ee/orchestration/internal/api/v1/handler_post_event.go deleted file mode 100644 index 93223f214e..0000000000 --- a/ee/orchestration/internal/api/v1/handler_post_event.go +++ /dev/null @@ -1,28 +0,0 @@ -package v1 - -import ( - "encoding/json" - "net/http" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/workflow" -) - -func postEventToWorkflowInstance(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - event := workflow.Event{} - if err := json.NewDecoder(r.Body).Decode(&event); err != nil { - api.BadRequest(w, "VALIDATION", err) - return - } - - if err := backend.PostEvent(r.Context(), instanceID(r), event); err != nil { - api.InternalServerError(w, r, err) - return - } - - api.NoContent(w) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_read_instance.go b/ee/orchestration/internal/api/v1/handler_read_instance.go deleted file mode 100644 index 5e70fedb30..0000000000 --- a/ee/orchestration/internal/api/v1/handler_read_instance.go +++ /dev/null @@ -1,21 +0,0 @@ -package v1 - -import ( - "net/http" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" -) - -func readInstance(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - workflows, err := backend.GetInstance(r.Context(), instanceID(r)) - if err != nil { - api.InternalServerError(w, r, err) - return - } - - api.Ok(w, workflows) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_read_instance_history.go b/ee/orchestration/internal/api/v1/handler_read_instance_history.go deleted file mode 100644 index 11e3b9d67a..0000000000 --- a/ee/orchestration/internal/api/v1/handler_read_instance_history.go +++ /dev/null @@ -1,21 +0,0 @@ -package v1 - -import ( - "net/http" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" -) - -func readInstanceHistory(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - workflows, err := backend.ReadInstanceHistory(r.Context(), instanceID(r)) - if err != nil { - api.InternalServerError(w, r, err) - return - } - - api.Ok(w, workflows) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_read_instance_test.go b/ee/orchestration/internal/api/v1/handler_read_instance_test.go deleted file mode 100644 index 9e6d72ae3a..0000000000 --- a/ee/orchestration/internal/api/v1/handler_read_instance_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package v1 - -import ( - "context" - "fmt" - "net/http" - "net/http/httptest" - "testing" - "time" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/testing/api" - - "github.com/formancehq/go-libs/logging" - "github.com/google/uuid" - - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestGetInstance(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - w, err := m.Create(logging.TestingContext(), workflow.Config{ - Stages: []workflow.RawStage{}, - }) - require.NoError(t, err) - - instance := workflow.NewInstance(uuid.NewString(), w.ID) - _, err = db.NewInsert(). - Model(&instance). - Exec(logging.TestingContext()) - require.NoError(t, err) - - now := time.Now().Round(time.Nanosecond) - for i := 0; i < 10; i++ { - timestamp := now.Add(time.Second) - _, err := db.NewInsert().Model(&workflow.Stage{ - Number: i, - InstanceID: instance.ID, - StartedAt: now, - TerminatedAt: ×tamp, - }).Exec(context.TODO()) - require.NoError(t, err) - } - - req := httptest.NewRequest(http.MethodGet, - fmt.Sprintf("/instances/%s", instance.ID), nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - var retrievedInstance workflow.Instance - sharedapi.ReadResponse(t, rec, &retrievedInstance) - require.Len(t, retrievedInstance.Statuses, 10) - }) -} diff --git a/ee/orchestration/internal/api/v1/handler_read_stage_history.go b/ee/orchestration/internal/api/v1/handler_read_stage_history.go deleted file mode 100644 index da99eda12d..0000000000 --- a/ee/orchestration/internal/api/v1/handler_read_stage_history.go +++ /dev/null @@ -1,36 +0,0 @@ -package v1 - -import ( - "net/http" - "strconv" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/api" - api2 "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/pkg/errors" -) - -func readStageHistory(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - stageNumberAsString := chi.URLParam(r, "number") - stage, err := strconv.ParseInt(stageNumberAsString, 10, 64) - if err != nil { - w.WriteHeader(http.StatusNotFound) - return - } - workflows, err := backend.ReadStageHistory(r.Context(), instanceID(r), int(stage)) - if err != nil { - switch { - case errors.Is(err, workflow.ErrInstanceNotFound): - api.NotFound(w, err) - default: - api.InternalServerError(w, r, err) - } - return - } - - api.Ok(w, workflows) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_read_workflow.go b/ee/orchestration/internal/api/v1/handler_read_workflow.go deleted file mode 100644 index 6071858405..0000000000 --- a/ee/orchestration/internal/api/v1/handler_read_workflow.go +++ /dev/null @@ -1,21 +0,0 @@ -package v1 - -import ( - "net/http" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" -) - -func readWorkflow(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - workflow, err := backend.ReadWorkflow(r.Context(), workflowID(r)) - if err != nil { - api.InternalServerError(w, r, err) - return - } - - api.Ok(w, workflow) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_run_workflow.go b/ee/orchestration/internal/api/v1/handler_run_workflow.go deleted file mode 100644 index aa6040fcd3..0000000000 --- a/ee/orchestration/internal/api/v1/handler_run_workflow.go +++ /dev/null @@ -1,50 +0,0 @@ -package v1 - -import ( - "encoding/json" - "net/http" - "strings" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/workflow" -) - -func runWorkflow(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - input := make(map[string]string) - if r.ContentLength > 0 { - if err := json.NewDecoder(r.Body).Decode(&input); err != nil { - api.BadRequest(w, "VALIDATION", err) - return - } - } - instance, err := backend.RunWorkflow(r.Context(), workflowID(r), input) - if err != nil { - api.InternalServerError(w, r, err) - return - } - - if wait := strings.ToLower(r.URL.Query().Get("wait")); wait == "true" || wait == "1" { - ret := struct { - *workflow.Instance - Error string `json:"error,omitempty"` - }{ - Instance: instance, - } - if err := backend.Wait(r.Context(), instance.ID); err != nil { - ret.Error = err.Error() - } - ret.Instance, err = backend.GetInstance(r.Context(), instance.ID) - if err != nil { - panic(err) - } - - api.Created(w, ret) - return - } - - api.Created(w, instance) - } -} diff --git a/ee/orchestration/internal/api/v1/handler_run_workflow_test.go b/ee/orchestration/internal/api/v1/handler_run_workflow_test.go deleted file mode 100644 index 9b9d62f719..0000000000 --- a/ee/orchestration/internal/api/v1/handler_run_workflow_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package v1 - -import ( - "context" - "fmt" - "net/http" - "net/http/httptest" - "testing" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/testing/api" - - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestRunWorkflow(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - w, err := m.Create(context.TODO(), workflow.Config{ - Stages: []workflow.RawStage{}, - }) - require.NoError(t, err) - - req := httptest.NewRequest(http.MethodPost, fmt.Sprintf("/workflows/%s/instances", w.ID), nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusCreated, rec.Result().StatusCode) - }) -} - -func TestRunWorkflowWaitEvent(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - w, err := m.Create(context.TODO(), workflow.Config{ - Stages: []workflow.RawStage{ - map[string]map[string]any{ - "noop": {}, - }, - }, - }) - require.NoError(t, err) - - req := httptest.NewRequest(http.MethodPost, fmt.Sprintf("/workflows/%s/instances?wait=true", w.ID), nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusCreated, rec.Result().StatusCode) - instance := &workflow.Instance{} - sharedapi.ReadResponse(t, rec, instance) - }) -} diff --git a/ee/orchestration/internal/api/v1/main_test.go b/ee/orchestration/internal/api/v1/main_test.go deleted file mode 100644 index 224c7a08b8..0000000000 --- a/ee/orchestration/internal/api/v1/main_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package v1 - -import ( - "context" - "log" - "net/http" - "testing" - - "github.com/formancehq/go-libs/testing/docker" - "github.com/formancehq/go-libs/testing/utils" - - "github.com/formancehq/go-libs/bun/bundebug" - - "go.temporal.io/sdk/worker" - - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/go-libs/publish" - "github.com/formancehq/orchestration/internal/temporalworker" - "github.com/formancehq/orchestration/internal/workflow/stages" - chi "github.com/go-chi/chi/v5" - "github.com/google/uuid" - "go.temporal.io/sdk/testsuite" - - "github.com/formancehq/go-libs/bun/bunconnect" - - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/triggers" - - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/go-libs/testing/platform/pgtesting" - "github.com/formancehq/orchestration/internal/storage" - "github.com/formancehq/orchestration/internal/workflow" - flag "github.com/spf13/pflag" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func test(t *testing.T, fn func(router *chi.Mux, backend api.Backend, db *bun.DB)) { - t.Parallel() - - hooks := make([]bun.QueryHook, 0) - if testing.Verbose() { - hooks = append(hooks, bundebug.NewQueryHook()) - } - - database := srv.NewDatabase(t) - db, err := bunconnect.OpenSQLDB(logging.TestingContext(), bunconnect.ConnectionOptions{ - DatabaseSourceName: database.ConnString(), - }, hooks...) - require.NoError(t, err) - t.Cleanup(func() { - _ = db.Close() - }) - - taskQueue := uuid.NewString() - worker := temporalworker.New(logging.Testing(), devServer.Client(), taskQueue, - []temporalworker.DefinitionSet{ - workflow.NewWorkflows(false).DefinitionSet(), - temporalworker.NewDefinitionSet().Append(temporalworker.Definition{ - Name: "NoOp", - Func: (&stages.NoOp{}).GetWorkflow(), - }), - }, - []temporalworker.DefinitionSet{ - workflow.NewActivities(publish.NoOpPublisher, db).DefinitionSet(), - }, - worker.Options{}, - ) - - require.NoError(t, worker.Start()) - t.Cleanup(worker.Stop) - - require.NoError(t, storage.Migrate(context.Background(), db)) - workflowManager := workflow.NewManager(db, devServer.Client(), taskQueue, false) - expressionEvaluator := triggers.NewExpressionEvaluator(http.DefaultClient) - triggersManager := triggers.NewManager(db, expressionEvaluator) - backend := api.NewDefaultBackend(triggersManager, workflowManager) - router := newRouter(backend, auth.NewNoAuth(), testing.Verbose()) - fn(router, backend, db) -} - -var ( - srv *pgtesting.PostgresServer - devServer *testsuite.DevServer -) - -func TestMain(m *testing.M) { - flag.Parse() - - utils.WithTestMain(func(t *utils.TestingTForMain) int { - srv = pgtesting.CreatePostgresServer(t, docker.NewPool(t, logging.Testing())) - - var err error - devServer, err = testsuite.StartDevServer(logging.TestingContext(), testsuite.DevServerOptions{}) - if err != nil { - log.Fatal(err) - } - - t.Cleanup(func() { - require.NoError(t, devServer.Stop()) - }) - - return m.Run() - }) -} diff --git a/ee/orchestration/internal/api/v1/module.go b/ee/orchestration/internal/api/v1/module.go deleted file mode 100644 index 01760e467e..0000000000 --- a/ee/orchestration/internal/api/v1/module.go +++ /dev/null @@ -1,15 +0,0 @@ -package v1 - -import ( - "github.com/formancehq/orchestration/internal/api" - "go.uber.org/fx" -) - -func NewModule() fx.Option { - return fx.Options( - fx.Supply(fx.Annotate(api.Version{ - Version: 1, - Builder: newRouter, - }, api.TagVersion())), - ) -} diff --git a/ee/orchestration/internal/api/v1/router.go b/ee/orchestration/internal/api/v1/router.go deleted file mode 100644 index 30074175a1..0000000000 --- a/ee/orchestration/internal/api/v1/router.go +++ /dev/null @@ -1,65 +0,0 @@ -package v1 - -import ( - "net/http" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/service" - - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/orchestration/internal/api" -) - -func newRouter(backend api.Backend, authenticator auth.Authenticator, debug bool) *chi.Mux { - r := chi.NewRouter() - r.Group(func(r chi.Router) { - // Plug middleware to handle traces - r.Use(auth.Middleware(authenticator)) - r.Use(service.OTLPMiddleware("orchestration", debug)) - r.Route("/triggers", func(r chi.Router) { - r.Get("/", listTriggers(backend)) - r.Post("/", createTrigger(backend)) - r.Route("/{triggerID}", func(r chi.Router) { - r.Get("/", getTrigger(backend)) - r.Delete("/", deleteTrigger(backend)) - r.Get("/occurrences", listTriggersOccurrences(backend)) - }) - }) - r.Route("/workflows", func(r chi.Router) { - r.Get("/", listWorkflows(backend)) - r.Post("/", createWorkflow(backend)) - r.Route("/{workflowId}", func(r chi.Router) { - r.Delete("/", deleteWorkflow(backend)) - r.Get("/", readWorkflow(backend)) - r.Route("/instances", func(r chi.Router) { - r.Post("/", runWorkflow(backend)) - }) - }) - }) - r.Route("/instances", func(r chi.Router) { - r.Get("/", listInstances(backend)) - r.Route("/{instanceId}", func(r chi.Router) { - r.Get("/", readInstance(backend)) - r.Post("/events", postEventToWorkflowInstance(backend)) - r.Put("/abort", abortWorkflowInstance(backend)) - r.Get("/history", readInstanceHistory(backend)) - r.Route("/stages", func(r chi.Router) { - r.Route("/{number}", func(r chi.Router) { - r.Get("/history", readStageHistory(backend)) - }) - }) - }) - }) - }) - - return r -} - -func workflowID(r *http.Request) string { - return chi.URLParam(r, "workflowId") -} - -func instanceID(r *http.Request) string { - return chi.URLParam(r, "instanceId") -} diff --git a/ee/orchestration/internal/api/v2/handler_abort_workflow_instance.go b/ee/orchestration/internal/api/v2/handler_abort_workflow_instance.go deleted file mode 100644 index 0c164b85a9..0000000000 --- a/ee/orchestration/internal/api/v2/handler_abort_workflow_instance.go +++ /dev/null @@ -1,19 +0,0 @@ -package v2 - -import ( - "net/http" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" -) - -func abortWorkflowInstance(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if err := backend.AbortRun(r.Context(), instanceID(r)); err != nil { - api.InternalServerError(w, r, err) - return - } - api.NoContent(w) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_create_trigger.go b/ee/orchestration/internal/api/v2/handler_create_trigger.go deleted file mode 100644 index 04e4a5dc8b..0000000000 --- a/ee/orchestration/internal/api/v2/handler_create_trigger.go +++ /dev/null @@ -1,40 +0,0 @@ -package v2 - -import ( - "encoding/json" - "net/http" - - "github.com/formancehq/orchestration/internal/api" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/triggers" - "github.com/pkg/errors" -) - -func createTrigger(backend api.Backend) func(writer http.ResponseWriter, request *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - - data := triggers.TriggerData{} - if err := json.NewDecoder(r.Body).Decode(&data); err != nil { - sharedapi.InternalServerError(w, r, err) - return - } - - trigger, err := backend.CreateTrigger(r.Context(), data) - if err != nil { - switch { - case errors.Is(err, triggers.ErrMissingWorkflowID), - errors.Is(err, triggers.ErrMissingEvent), - triggers.IsExprCompilationError(err): - sharedapi.BadRequest(w, "VALIDATION", err) - case errors.Is(err, triggers.ErrWorkflowNotExists): - sharedapi.NotFound(w, err) - default: - sharedapi.InternalServerError(w, r, err) - } - return - } - - sharedapi.Created(w, trigger) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_create_trigger_test.go b/ee/orchestration/internal/api/v2/handler_create_trigger_test.go deleted file mode 100644 index 5b8f59afd8..0000000000 --- a/ee/orchestration/internal/api/v2/handler_create_trigger_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package v2 - -import ( - "bytes" - "context" - "fmt" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/orchestration/internal/api" - "github.com/go-chi/chi/v5" - - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestCreateTrigger(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - - w, err := m.Create(context.Background(), workflow.Config{}) - require.NoError(t, err) - - req := httptest.NewRequest(http.MethodPost, "/triggers", - bytes.NewBufferString(fmt.Sprintf(`{"workflowID": "%s", "event": "SAVED_PAYMENT"}`, w.ID))) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusCreated, rec.Result().StatusCode) - }) -} diff --git a/ee/orchestration/internal/api/v2/handler_create_workflow.go b/ee/orchestration/internal/api/v2/handler_create_workflow.go deleted file mode 100644 index 555e21b221..0000000000 --- a/ee/orchestration/internal/api/v2/handler_create_workflow.go +++ /dev/null @@ -1,50 +0,0 @@ -package v2 - -import ( - "encoding/json" - "net/http" - - "gopkg.in/yaml.v3" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/pkg/errors" -) - -func createWorkflow(m api.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - config := workflow.Config{} - if r.Header.Get("Content-Type") == "text/vnd.yaml" { - payload := make(map[string]any) - if err := yaml.NewDecoder(r.Body).Decode(&payload); err != nil { - sharedapi.BadRequest(w, "VALIDATION", errors.Wrap(err, "unmarshalling yaml")) - return - } - - asJson, err := json.Marshal(payload) - if err != nil { - panic(err) - } - - if err := json.Unmarshal(asJson, &config); err != nil { - sharedapi.BadRequest(w, "VALIDATION", errors.Wrap(err, "unmarshalling workflow data")) - return - } - } else { - if err := json.NewDecoder(r.Body).Decode(&config); err != nil { - sharedapi.BadRequest(w, "VALIDATION", errors.Wrap(err, "unmarshalling json body")) - return - } - } - - workflow, err := m.Create(r.Context(), config) - if err != nil { - sharedapi.InternalServerError(w, r, errors.Wrap(err, "creating workflow")) - return - } - - sharedapi.Created(w, workflow) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_create_workflow_test.go b/ee/orchestration/internal/api/v2/handler_create_workflow_test.go deleted file mode 100644 index 7a80f21c0a..0000000000 --- a/ee/orchestration/internal/api/v2/handler_create_workflow_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package v2 - -import ( - "bytes" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/orchestration/internal/api" - "github.com/go-chi/chi/v5" - - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestCreateWorkflow(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - req := httptest.NewRequest(http.MethodPost, "/workflows", bytes.NewBufferString(`{"stages": []}`)) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusCreated, rec.Result().StatusCode) - }) -} diff --git a/ee/orchestration/internal/api/v2/handler_delete_trigger.go b/ee/orchestration/internal/api/v2/handler_delete_trigger.go deleted file mode 100644 index 9a3e5a964f..0000000000 --- a/ee/orchestration/internal/api/v2/handler_delete_trigger.go +++ /dev/null @@ -1,28 +0,0 @@ -package v2 - -import ( - "database/sql" - "net/http" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/api" - "github.com/pkg/errors" -) - -func deleteTrigger(backend api.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if err := backend.DeleteTrigger(r.Context(), chi.URLParam(r, "triggerID")); err != nil { - switch { - case errors.Is(err, sql.ErrNoRows): - sharedapi.NotFound(w, err) - default: - sharedapi.InternalServerError(w, r, err) - } - return - } - - sharedapi.NoContent(w) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_delete_workflow.go b/ee/orchestration/internal/api/v2/handler_delete_workflow.go deleted file mode 100644 index 66f2054bb8..0000000000 --- a/ee/orchestration/internal/api/v2/handler_delete_workflow.go +++ /dev/null @@ -1,42 +0,0 @@ -package v2 - -import ( - "errors" - "net/http" - - "github.com/go-playground/validator/v10" - - "github.com/formancehq/go-libs/api" - api2 "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" -) - -var ( - ErrEmptyID = errors.New("ID is empty") -) - -func deleteWorkflow(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - id := workflowID(r) - - err := validator.New().Var(id, "required,uuid") - if err != nil { - api.BadRequest(w, "VALIDATION", err) - return - } - - err = backend.DeleteWorkflow(r.Context(), workflowID(r)) - - if errors.Is(err, workflow.ErrWorkflowNotFound) { - api.NotFound(w, err) - return - } - - if err != nil { - api.InternalServerError(w, r, err) - return - } - - api.NoContent(w) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_delete_workflow_test.go b/ee/orchestration/internal/api/v2/handler_delete_workflow_test.go deleted file mode 100644 index 5beb29a570..0000000000 --- a/ee/orchestration/internal/api/v2/handler_delete_workflow_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package v2 - -import ( - "bytes" - "fmt" - "net/http" - "net/http/httptest" - "testing" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/testing/api" - - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - - "github.com/uptrace/bun" -) - -func TestDeleteWorkflow(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - // Create a workflow - req := httptest.NewRequest(http.MethodPost, "/workflows", bytes.NewBufferString(`{"stages": []}`)) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusCreated, rec.Result().StatusCode) - - workflow := workflow.Workflow{} - sharedapi.ReadResponse(t, rec, &workflow) - - require.NotEmpty(t, workflow.ID) - - // Delete the workflow - req = httptest.NewRequest(http.MethodDelete, fmt.Sprintf("/workflows/%s/", workflow.ID), nil) - rec = httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusNoContent, rec.Result().StatusCode) - }) -} diff --git a/ee/orchestration/internal/api/v2/handler_get_trigger.go b/ee/orchestration/internal/api/v2/handler_get_trigger.go deleted file mode 100644 index 195ffff59c..0000000000 --- a/ee/orchestration/internal/api/v2/handler_get_trigger.go +++ /dev/null @@ -1,30 +0,0 @@ -package v2 - -import ( - "database/sql" - "net/http" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/api" - "github.com/pkg/errors" -) - -func getTrigger(backend api.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - trigger, err := backend.GetTrigger(r.Context(), chi.URLParam(r, "triggerID")) - if err != nil { - switch { - case errors.Is(err, sql.ErrNoRows): - sharedapi.NotFound(w, err) - return - default: - sharedapi.InternalServerError(w, r, err) - } - return - } - - sharedapi.Ok(w, trigger) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_list_instances.go b/ee/orchestration/internal/api/v2/handler_list_instances.go deleted file mode 100644 index 91b7facc84..0000000000 --- a/ee/orchestration/internal/api/v2/handler_list_instances.go +++ /dev/null @@ -1,42 +0,0 @@ -package v2 - -import ( - "net/http" - - "github.com/formancehq/go-libs/bun/bunpaginate" - "github.com/formancehq/orchestration/internal/workflow" - - api "github.com/formancehq/orchestration/internal/api" - - sharedapi "github.com/formancehq/go-libs/api" -) - -func listInstances(backend api.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - q, err := bunpaginate.Extract[workflow.ListInstancesQuery](r, func() (*workflow.ListInstancesQuery, error) { - pageSize, err := bunpaginate.GetPageSize(r) - if err != nil { - return nil, err - } - return &workflow.ListInstancesQuery{ - PageSize: pageSize, - Options: workflow.ListInstancesOptions{ - WorkflowID: r.URL.Query().Get("workflowID"), - Running: sharedapi.QueryParamBool(r, "running"), - }, - }, nil - }) - if err != nil { - sharedapi.BadRequest(w, "VALIDATION", err) - return - } - - runs, err := backend.ListInstances(r.Context(), *q) - if err != nil { - sharedapi.InternalServerError(w, r, err) - return - } - sharedapi.RenderCursor(w, *runs) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_list_instances_test.go b/ee/orchestration/internal/api/v2/handler_list_instances_test.go deleted file mode 100644 index 78792eceb1..0000000000 --- a/ee/orchestration/internal/api/v2/handler_list_instances_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package v2 - -import ( - "context" - "fmt" - "net/http" - "net/http/httptest" - "testing" - "time" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/testing/api" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/google/uuid" - - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestListInstances(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - // Create a workflow with 10 instances - w := workflow.New(workflow.Config{}) - _, err := db.NewInsert().Model(&w).Exec(context.TODO()) - require.NoError(t, err) - - for i := 0; i < 10; i++ { - instance := workflow.NewInstance(uuid.NewString(), w.ID) - if i > 5 { - instance.SetTerminated(time.Now()) - } - _, err := db.NewInsert().Model(&instance).Exec(context.TODO()) - require.NoError(t, err) - } - - req := httptest.NewRequest(http.MethodGet, "/instances", nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - - // Retrieve only running instances - instances := bunpaginate.Cursor[workflow.Instance]{} - sharedapi.ReadCursor(t, rec, &instances) - require.Len(t, instances.Data, 10) - - req = httptest.NewRequest(http.MethodGet, "/instances?running=true", nil) - rec = httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - sharedapi.ReadCursor(t, rec, &instances) - require.Len(t, instances.Data, 6) - - // Delete the workflow - req = httptest.NewRequest(http.MethodDelete, fmt.Sprintf("/workflows/%s/", w.ID), nil) - rec = httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusNoContent, rec.Result().StatusCode) - - // Try to retrieve instances for all workflows - req = httptest.NewRequest(http.MethodGet, "/instances", nil) - rec = httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - instances = bunpaginate.Cursor[workflow.Instance]{} - sharedapi.ReadCursor(t, rec, &instances) - require.Len(t, instances.Data, 0) - - // Try to retrieve instances for the deleted workflow - req = httptest.NewRequest(http.MethodGet, "/instances?workflowID="+w.ID, nil) - rec = httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - instances = bunpaginate.Cursor[workflow.Instance]{} - sharedapi.ReadCursor(t, rec, &instances) - require.Len(t, instances.Data, 0) - }) -} diff --git a/ee/orchestration/internal/api/v2/handler_list_triggers.go b/ee/orchestration/internal/api/v2/handler_list_triggers.go deleted file mode 100644 index 86ed83e014..0000000000 --- a/ee/orchestration/internal/api/v2/handler_list_triggers.go +++ /dev/null @@ -1,43 +0,0 @@ -package v2 - -import ( - "net/http" - - "github.com/formancehq/go-libs/bun/bunpaginate" - "github.com/formancehq/orchestration/internal/triggers" - - "github.com/formancehq/orchestration/internal/api" - - sharedapi "github.com/formancehq/go-libs/api" -) - -func listTriggers(backend api.Backend) func(writer http.ResponseWriter, request *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - query, err := bunpaginate.Extract[triggers.ListTriggersQuery](r, func() (*triggers.ListTriggersQuery, error) { - pageSize, err := bunpaginate.GetPageSize(r) - if err != nil { - return nil, err - } - - var name string = "" - name = r.URL.Query().Get("name") - - return &triggers.ListTriggersQuery{ - PageSize: pageSize, - Options: triggers.ListTriggerParams{Name: name}, - }, nil - }) - if err != nil { - sharedapi.BadRequest(w, "VALIDATION", err) - return - } - - triggers, err := backend.ListTriggers(r.Context(), *query) - if err != nil { - sharedapi.InternalServerError(w, r, err) - return - } - - sharedapi.RenderCursor(w, *triggers) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_list_triggers_occurrences.go b/ee/orchestration/internal/api/v2/handler_list_triggers_occurrences.go deleted file mode 100644 index d774345a0c..0000000000 --- a/ee/orchestration/internal/api/v2/handler_list_triggers_occurrences.go +++ /dev/null @@ -1,43 +0,0 @@ -package v2 - -import ( - "net/http" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/bun/bunpaginate" - "github.com/formancehq/orchestration/internal/triggers" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/api" -) - -func listTriggersOccurrences(backend api.Backend) func(writer http.ResponseWriter, request *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - - query, err := bunpaginate.Extract[triggers.ListTriggersOccurrencesQuery](r, func() (*triggers.ListTriggersOccurrencesQuery, error) { - pageSize, err := bunpaginate.GetPageSize(r) - if err != nil { - return nil, err - } - return &triggers.ListTriggersOccurrencesQuery{ - PageSize: pageSize, - Options: triggers.ListTriggersOccurrencesOptions{ - TriggerID: chi.URLParam(r, "triggerID"), - }, - }, nil - }) - if err != nil { - sharedapi.BadRequest(w, "VALIDATION", err) - return - } - - triggersOccurrences, err := backend.ListTriggersOccurrences(r.Context(), *query) - if err != nil { - sharedapi.InternalServerError(w, r, err) - return - } - - sharedapi.RenderCursor(w, *triggersOccurrences) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_list_workflows.go b/ee/orchestration/internal/api/v2/handler_list_workflows.go deleted file mode 100644 index 8d67c9cd44..0000000000 --- a/ee/orchestration/internal/api/v2/handler_list_workflows.go +++ /dev/null @@ -1,38 +0,0 @@ -package v2 - -import ( - "net/http" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - api2 "github.com/formancehq/orchestration/internal/api" - - sharedapi "github.com/formancehq/go-libs/api" -) - -func listWorkflows(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - query, err := bunpaginate.Extract[bunpaginate.OffsetPaginatedQuery[any]](r, func() (*bunpaginate.OffsetPaginatedQuery[any], error) { - pageSize, err := bunpaginate.GetPageSize(r) - if err != nil { - return nil, err - } - return &bunpaginate.OffsetPaginatedQuery[any]{ - PageSize: pageSize, - }, nil - }) - if err != nil { - sharedapi.BadRequest(w, "VALIDATION", err) - return - } - - workflows, err := backend.ListWorkflows(r.Context(), *query) - if err != nil { - sharedapi.InternalServerError(w, r, err) - return - } - - sharedapi.RenderCursor(w, *workflows) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_post_event.go b/ee/orchestration/internal/api/v2/handler_post_event.go deleted file mode 100644 index a0f75d4023..0000000000 --- a/ee/orchestration/internal/api/v2/handler_post_event.go +++ /dev/null @@ -1,28 +0,0 @@ -package v2 - -import ( - "encoding/json" - "net/http" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/workflow" -) - -func postEventToWorkflowInstance(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - event := workflow.Event{} - if err := json.NewDecoder(r.Body).Decode(&event); err != nil { - api.BadRequest(w, "VALIDATION", err) - return - } - - if err := backend.PostEvent(r.Context(), instanceID(r), event); err != nil { - api.InternalServerError(w, r, err) - return - } - - api.NoContent(w) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_read_instance.go b/ee/orchestration/internal/api/v2/handler_read_instance.go deleted file mode 100644 index 79c3aa4bcd..0000000000 --- a/ee/orchestration/internal/api/v2/handler_read_instance.go +++ /dev/null @@ -1,21 +0,0 @@ -package v2 - -import ( - "net/http" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" -) - -func readInstance(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - workflows, err := backend.GetInstance(r.Context(), instanceID(r)) - if err != nil { - api.InternalServerError(w, r, err) - return - } - - api.Ok(w, workflows) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_read_instance_history.go b/ee/orchestration/internal/api/v2/handler_read_instance_history.go deleted file mode 100644 index ca3a41d1e4..0000000000 --- a/ee/orchestration/internal/api/v2/handler_read_instance_history.go +++ /dev/null @@ -1,21 +0,0 @@ -package v2 - -import ( - "net/http" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" -) - -func readInstanceHistory(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - workflows, err := backend.ReadInstanceHistory(r.Context(), instanceID(r)) - if err != nil { - api.InternalServerError(w, r, err) - return - } - - api.Ok(w, workflows) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_read_instance_test.go b/ee/orchestration/internal/api/v2/handler_read_instance_test.go deleted file mode 100644 index 0dc82b0611..0000000000 --- a/ee/orchestration/internal/api/v2/handler_read_instance_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package v2 - -import ( - "context" - "fmt" - "net/http" - "net/http/httptest" - "testing" - "time" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/testing/api" - - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestGetInstance(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - w, err := m.Create(context.TODO(), workflow.Config{ - Stages: []workflow.RawStage{}, - }) - require.NoError(t, err) - - instance, err := m.RunWorkflow(context.TODO(), w.ID, map[string]string{}) - require.NoError(t, err) - - now := time.Now().Round(time.Nanosecond) - for i := 0; i < 10; i++ { - timestamp := now.Add(time.Second) - _, err := db.NewInsert().Model(&workflow.Stage{ - Number: i, - InstanceID: instance.ID, - StartedAt: now, - TerminatedAt: ×tamp, - }).Exec(context.TODO()) - require.NoError(t, err) - } - - req := httptest.NewRequest(http.MethodGet, - fmt.Sprintf("/instances/%s", instance.ID), nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - var retrievedInstance workflow.Instance - sharedapi.ReadResponse(t, rec, &retrievedInstance) - require.Len(t, retrievedInstance.Statuses, 10) - }) -} diff --git a/ee/orchestration/internal/api/v2/handler_read_stage_history.go b/ee/orchestration/internal/api/v2/handler_read_stage_history.go deleted file mode 100644 index 2f4e760821..0000000000 --- a/ee/orchestration/internal/api/v2/handler_read_stage_history.go +++ /dev/null @@ -1,36 +0,0 @@ -package v2 - -import ( - "net/http" - "strconv" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/pkg/errors" -) - -func readStageHistory(backend api.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - stageNumberAsString := chi.URLParam(r, "number") - stage, err := strconv.ParseInt(stageNumberAsString, 10, 64) - if err != nil { - w.WriteHeader(http.StatusNotFound) - return - } - workflows, err := backend.ReadStageHistory(r.Context(), instanceID(r), int(stage)) - if err != nil { - switch { - case errors.Is(err, workflow.ErrInstanceNotFound): - sharedapi.NotFound(w, err) - default: - sharedapi.InternalServerError(w, r, err) - } - return - } - - sharedapi.Ok(w, workflows) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_read_workflow.go b/ee/orchestration/internal/api/v2/handler_read_workflow.go deleted file mode 100644 index 1d7f430252..0000000000 --- a/ee/orchestration/internal/api/v2/handler_read_workflow.go +++ /dev/null @@ -1,21 +0,0 @@ -package v2 - -import ( - "net/http" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" -) - -func readWorkflow(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - workflow, err := backend.ReadWorkflow(r.Context(), workflowID(r)) - if err != nil { - api.InternalServerError(w, r, err) - return - } - - api.Ok(w, workflow) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_run_workflow.go b/ee/orchestration/internal/api/v2/handler_run_workflow.go deleted file mode 100644 index dc3a3c390f..0000000000 --- a/ee/orchestration/internal/api/v2/handler_run_workflow.go +++ /dev/null @@ -1,50 +0,0 @@ -package v2 - -import ( - "encoding/json" - "net/http" - "strings" - - api2 "github.com/formancehq/orchestration/internal/api" - - "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/workflow" -) - -func runWorkflow(backend api2.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - input := make(map[string]string) - if r.ContentLength > 0 { - if err := json.NewDecoder(r.Body).Decode(&input); err != nil { - api.BadRequest(w, "VALIDATION", err) - return - } - } - instance, err := backend.RunWorkflow(r.Context(), workflowID(r), input) - if err != nil { - api.InternalServerError(w, r, err) - return - } - - if wait := strings.ToLower(r.URL.Query().Get("wait")); wait == "true" || wait == "1" { - ret := struct { - *workflow.Instance - Error string `json:"error,omitempty"` - }{ - Instance: instance, - } - if err := backend.Wait(r.Context(), instance.ID); err != nil { - ret.Error = err.Error() - } - ret.Instance, err = backend.GetInstance(r.Context(), instance.ID) - if err != nil { - panic(err) - } - - api.Created(w, ret) - return - } - - api.Created(w, instance) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_run_workflow_test.go b/ee/orchestration/internal/api/v2/handler_run_workflow_test.go deleted file mode 100644 index fe4bbb6185..0000000000 --- a/ee/orchestration/internal/api/v2/handler_run_workflow_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package v2 - -import ( - "context" - "fmt" - "net/http" - "net/http/httptest" - "testing" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/testing/api" - - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestRunWorkflow(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - w, err := m.Create(context.TODO(), workflow.Config{ - Stages: []workflow.RawStage{}, - }) - require.NoError(t, err) - - req := httptest.NewRequest(http.MethodPost, fmt.Sprintf("/workflows/%s/instances", w.ID), nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusCreated, rec.Result().StatusCode) - }) -} - -func TestRunWorkflowWaitEvent(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - w, err := m.Create(context.TODO(), workflow.Config{ - Stages: []workflow.RawStage{ - map[string]map[string]any{ - "noop": {}, - }, - }, - }) - require.NoError(t, err) - - req := httptest.NewRequest(http.MethodPost, fmt.Sprintf("/workflows/%s/instances?wait=true", w.ID), nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusCreated, rec.Result().StatusCode) - instance := &workflow.Instance{} - sharedapi.ReadResponse(t, rec, instance) - }) -} diff --git a/ee/orchestration/internal/api/v2/handler_test_trigger.go b/ee/orchestration/internal/api/v2/handler_test_trigger.go deleted file mode 100644 index 21b0261558..0000000000 --- a/ee/orchestration/internal/api/v2/handler_test_trigger.go +++ /dev/null @@ -1,30 +0,0 @@ -package v2 - -import ( - "encoding/json" - "net/http" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/orchestration/internal/api" -) - -func testTrigger(backend api.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - data := make(map[string]any) - if err := json.NewDecoder(r.Body).Decode(&data); err != nil { - sharedapi.InternalServerError(w, r, err) - return - } - - o, err := backend.TestTrigger(r.Context(), chi.URLParam(r, "triggerID"), data) - if err != nil { - sharedapi.InternalServerError(w, r, err) - return - } - - sharedapi.Ok(w, o) - } -} diff --git a/ee/orchestration/internal/api/v2/handler_test_trigger_test.go b/ee/orchestration/internal/api/v2/handler_test_trigger_test.go deleted file mode 100644 index b861bf1292..0000000000 --- a/ee/orchestration/internal/api/v2/handler_test_trigger_test.go +++ /dev/null @@ -1,124 +0,0 @@ -package v2 - -import ( - "bytes" - "context" - "encoding/json" - "net/http" - "net/http/httptest" - "testing" - - "github.com/go-chi/chi/v5" - - sharedapi "github.com/formancehq/go-libs/testing/api" - - "github.com/formancehq/go-libs/pointer" - "github.com/formancehq/orchestration/internal/triggers" - - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func TestTestTrigger(t *testing.T) { - - type testCase struct { - name string - data triggers.TriggerData - expected triggers.TestTriggerResult - event map[string]any - } - - for _, testCase := range []testCase{ - { - name: "nominal", - data: triggers.TriggerData{}, - expected: triggers.TestTriggerResult{}, - }, - { - name: "with filter and variable", - event: map[string]any{ - "user": map[string]any{ - "role": "admin", - }, - }, - data: triggers.TriggerData{ - Filter: pointer.For("event.user.role == \"admin\""), - Vars: map[string]string{ - "role": "event.user.role", - }, - }, - expected: triggers.TestTriggerResult{ - Filter: &triggers.FilterEvaluationResult{ - Match: true, - }, - Variables: map[string]triggers.VariableEvaluationResult{ - "role": { - Value: "admin", - }, - }, - }, - }, - { - name: "error on filter", - data: triggers.TriggerData{ - Filter: pointer.For("a + b"), - }, - expected: triggers.TestTriggerResult{ - Filter: &triggers.FilterEvaluationResult{ - Match: false, - Error: "invalid operation: + (1:3)\n | a + b\n | ..^", - }, - }, - }, - { - name: "error on variables", - data: triggers.TriggerData{ - Vars: map[string]string{ - "test": "a + b", - }, - }, - expected: triggers.TestTriggerResult{ - Variables: map[string]triggers.VariableEvaluationResult{ - "test": { - Error: "invalid operation: + (1:3)\n | a + b\n | ..^", - }, - }, - }, - }, - } { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - test(t, func(router *chi.Mux, m api.Backend, db *bun.DB) { - - w, err := m.Create(context.Background(), workflow.Config{}) - require.NoError(t, err) - - testCase.data.WorkflowID = w.ID - testCase.data.Event = "XXX" - trigger, err := m.CreateTrigger(context.Background(), testCase.data) - require.NoError(t, err) - - payload := []byte("{}") - if testCase.event != nil { - payload, err = json.Marshal(testCase.event) - require.NoError(t, err) - } - - req := httptest.NewRequest(http.MethodPost, "/triggers/"+trigger.ID+"/test", - bytes.NewBuffer(payload)) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - - result := triggers.TestTriggerResult{} - sharedapi.ReadResponse(t, rec, &result) - - require.Equal(t, testCase.expected, result) - }) - }) - } -} diff --git a/ee/orchestration/internal/api/v2/main_test.go b/ee/orchestration/internal/api/v2/main_test.go deleted file mode 100644 index 57fd66fc0d..0000000000 --- a/ee/orchestration/internal/api/v2/main_test.go +++ /dev/null @@ -1,102 +0,0 @@ -package v2 - -import ( - "context" - "log" - "net/http" - "testing" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/testing/docker" - "github.com/formancehq/go-libs/testing/utils" - - "github.com/formancehq/go-libs/bun/bundebug" - - "go.temporal.io/sdk/worker" - - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/go-libs/publish" - "github.com/formancehq/orchestration/internal/temporalworker" - "github.com/formancehq/orchestration/internal/workflow/stages" - "github.com/google/uuid" - "go.temporal.io/sdk/testsuite" - - "github.com/formancehq/go-libs/bun/bunconnect" - - "github.com/formancehq/orchestration/internal/api" - "github.com/formancehq/orchestration/internal/triggers" - - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/go-libs/testing/platform/pgtesting" - "github.com/formancehq/orchestration/internal/storage" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/stretchr/testify/require" - "github.com/uptrace/bun" -) - -func test(t *testing.T, fn func(router *chi.Mux, backend api.Backend, db *bun.DB)) { - t.Parallel() - - hooks := make([]bun.QueryHook, 0) - if testing.Verbose() { - hooks = append(hooks, bundebug.NewQueryHook()) - } - - database := srv.NewDatabase(t) - db, err := bunconnect.OpenSQLDB(logging.TestingContext(), bunconnect.ConnectionOptions{ - DatabaseSourceName: database.ConnString(), - }, hooks...) - require.NoError(t, err) - t.Cleanup(func() { - _ = db.Close() - }) - - taskQueue := uuid.NewString() - worker := temporalworker.New(logging.Testing(), devServer.Client(), taskQueue, - []temporalworker.DefinitionSet{ - workflow.NewWorkflows(false).DefinitionSet(), - temporalworker.NewDefinitionSet().Append(temporalworker.Definition{ - Name: "NoOp", - Func: (&stages.NoOp{}).GetWorkflow(), - }), - }, - []temporalworker.DefinitionSet{ - workflow.NewActivities(publish.NoOpPublisher, db).DefinitionSet(), - }, - worker.Options{}, - ) - require.NoError(t, worker.Start()) - t.Cleanup(worker.Stop) - - require.NoError(t, storage.Migrate(context.Background(), db)) - workflowManager := workflow.NewManager(db, devServer.Client(), taskQueue, false) - expressionEvaluator := triggers.NewExpressionEvaluator(http.DefaultClient) - triggersManager := triggers.NewManager(db, expressionEvaluator) - backend := api.NewDefaultBackend(triggersManager, workflowManager) - router := newRouter(backend, auth.NewNoAuth(), testing.Verbose()) - fn(router, backend, db) -} - -var ( - devServer *testsuite.DevServer - srv *pgtesting.PostgresServer -) - -func TestMain(m *testing.M) { - utils.WithTestMain(func(t *utils.TestingTForMain) int { - srv = pgtesting.CreatePostgresServer(t, docker.NewPool(t, logging.Testing())) - - var err error - devServer, err = testsuite.StartDevServer(logging.TestingContext(), testsuite.DevServerOptions{}) - if err != nil { - log.Fatal(err) - } - - t.Cleanup(func() { - require.NoError(t, devServer.Stop()) - }) - - return m.Run() - }) -} diff --git a/ee/orchestration/internal/api/v2/module.go b/ee/orchestration/internal/api/v2/module.go deleted file mode 100644 index 09d62be105..0000000000 --- a/ee/orchestration/internal/api/v2/module.go +++ /dev/null @@ -1,15 +0,0 @@ -package v2 - -import ( - "github.com/formancehq/orchestration/internal/api" - "go.uber.org/fx" -) - -func NewModule() fx.Option { - return fx.Options( - fx.Supply(fx.Annotate(api.Version{ - Version: 2, - Builder: newRouter, - }, api.TagVersion())), - ) -} diff --git a/ee/orchestration/internal/api/v2/router.go b/ee/orchestration/internal/api/v2/router.go deleted file mode 100644 index 42be174a3e..0000000000 --- a/ee/orchestration/internal/api/v2/router.go +++ /dev/null @@ -1,66 +0,0 @@ -package v2 - -import ( - "net/http" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/service" - - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/orchestration/internal/api" -) - -func newRouter(backend api.Backend, authenticator auth.Authenticator, debug bool) *chi.Mux { - r := chi.NewRouter() - r.Group(func(r chi.Router) { - // Plug middleware to handle traces - r.Use(auth.Middleware(authenticator)) - r.Use(service.OTLPMiddleware("orchestration", debug)) - r.Route("/triggers", func(r chi.Router) { - r.Get("/", listTriggers(backend)) - r.Post("/", createTrigger(backend)) - r.Route("/{triggerID}", func(r chi.Router) { - r.Get("/", getTrigger(backend)) - r.Delete("/", deleteTrigger(backend)) - r.Get("/occurrences", listTriggersOccurrences(backend)) - r.Post("/test", testTrigger(backend)) - }) - }) - r.Route("/workflows", func(r chi.Router) { - r.Get("/", listWorkflows(backend)) - r.Post("/", createWorkflow(backend)) - r.Route("/{workflowId}", func(r chi.Router) { - r.Delete("/", deleteWorkflow(backend)) - r.Get("/", readWorkflow(backend)) - r.Route("/instances", func(r chi.Router) { - r.Post("/", runWorkflow(backend)) - }) - }) - }) - r.Route("/instances", func(r chi.Router) { - r.Get("/", listInstances(backend)) - r.Route("/{instanceId}", func(r chi.Router) { - r.Get("/", readInstance(backend)) - r.Post("/events", postEventToWorkflowInstance(backend)) - r.Put("/abort", abortWorkflowInstance(backend)) - r.Get("/history", readInstanceHistory(backend)) - r.Route("/stages", func(r chi.Router) { - r.Route("/{number}", func(r chi.Router) { - r.Get("/history", readStageHistory(backend)) - }) - }) - }) - }) - }) - - return r -} - -func workflowID(r *http.Request) string { - return chi.URLParam(r, "workflowId") -} - -func instanceID(r *http.Request) string { - return chi.URLParam(r, "instanceId") -} diff --git a/ee/orchestration/internal/schema/duration.go b/ee/orchestration/internal/schema/duration.go deleted file mode 100644 index 0df1f3464c..0000000000 --- a/ee/orchestration/internal/schema/duration.go +++ /dev/null @@ -1,27 +0,0 @@ -package schema - -import ( - "fmt" - "time" -) - -type Duration time.Duration - -func (d Duration) MarshalJSON() ([]byte, error) { - return []byte(fmt.Sprintf(`"%s"`, time.Duration(d).String())), nil -} - -func (d *Duration) UnmarshalJSON(data []byte) error { - - if data[0] != '"' || data[len(data)-1] != '"' { - return fmt.Errorf("invalid duration") - } - data = data[1 : len(data)-1] - - duration, err := time.ParseDuration(string(data)) - if err != nil { - return err - } - *d = Duration(duration) - return nil -} diff --git a/ee/orchestration/internal/schema/map.go b/ee/orchestration/internal/schema/map.go deleted file mode 100644 index ec8e7d8c61..0000000000 --- a/ee/orchestration/internal/schema/map.go +++ /dev/null @@ -1,316 +0,0 @@ -package schema - -import ( - "fmt" - "math/big" - "reflect" - "regexp" - "strconv" - "strings" - - "github.com/formancehq/go-libs/time" - - "github.com/formancehq/orchestration/internal/workflow/stages" - "github.com/pkg/errors" -) - -type Context struct { - Variables map[string]string -} - -type fieldResolveError struct { - name string - err error -} - -func (err *fieldResolveError) Error() string { - return fmt.Sprintf("resolving field '%s': %s", err.name, err.err) -} - -func interpolate(ctx Context, v string) string { - r := regexp.MustCompile(`\$\{[^\}]+\}`) - return r.ReplaceAllStringFunc(v, func(key string) string { - key = strings.TrimPrefix(key, "${") - key = strings.TrimSuffix(key, "}") - return ctx.Variables[key] - }) -} - -func mapObjectField(ctx Context, raw any, spec reflect.Value, fieldTag tag) error { - switch spec.Kind() { - case reflect.Map: - if raw == nil { - return nil - } - vRaw := reflect.ValueOf(raw) - if vRaw.Kind() != reflect.Map { - return fmt.Errorf("expecting map, got type: %T", raw) - } - - spec.Set(reflect.MakeMap(spec.Type())) - for _, key := range vRaw.MapKeys() { - value := vRaw.MapIndex(key) - targetValue := reflect.New(spec.Type().Elem()).Elem() - if err := mapObjectField(ctx, value.Interface(), targetValue, tag{}); err != nil { - return err - } - spec.SetMapIndex(key, targetValue) - } - case reflect.Pointer: - if raw == nil { - return nil - } - if _, isBigInt := spec.Interface().(*big.Int); isBigInt { - switch json := raw.(type) { - case string: - interpolated := interpolate(ctx, json) - if interpolated == "" { - interpolated = fieldTag.defaultValue - if interpolated == "" { - return nil - } - } - bigIntValue, ok := big.NewInt(0).SetString(interpolated, 10) - if !ok { - return fmt.Errorf("unable to parse '%s' as big int", interpolated) - } - spec.Set(reflect.ValueOf(bigIntValue)) - case float64: - spec.Set(reflect.ValueOf(big.NewInt(int64(json)))) - case nil: - defaultValue := fieldTag.defaultValue - if defaultValue == "" { - return nil - } - bigIntValue, ok := big.NewInt(0).SetString(defaultValue, 10) - if !ok { - panic(fmt.Errorf("unable to parse '%s' as big int", defaultValue)) - } - spec.Set(reflect.ValueOf(bigIntValue)) - default: - return fmt.Errorf("expected big int or interpolated string but was %T", json) - } - return nil - } - spec.Set(reflect.New(spec.Type().Elem())) - return mapObjectField(ctx, raw, spec.Elem(), fieldTag) - case reflect.String: - switch json := raw.(type) { - case string: - interpolated := interpolate(ctx, json) - if interpolated == "" { - interpolated = fieldTag.defaultValue - } - spec.SetString(interpolated) - case nil: - spec.SetString(fieldTag.defaultValue) - default: - return fmt.Errorf("expected string but was %T", json) - } - return nil - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - switch json := raw.(type) { - case string: - interpolated := interpolate(ctx, json) - if interpolated == "" { - interpolated = fieldTag.defaultValue - if interpolated == "" { - return nil - } - } - uint64Value, err := strconv.ParseUint(interpolated, 10, 64) - if err != nil { - return fmt.Errorf("unable to resolve field '%s' to uint value", spec.Type().Name()) - } - spec.SetUint(uint64Value) - case float64: - spec.SetUint(uint64(json)) - case nil: - defaultValue := fieldTag.defaultValue - if defaultValue == "" { - return nil - } - uint64Value, err := strconv.ParseUint(defaultValue, 10, 64) - if err != nil { - return fmt.Errorf("unable to resolve field '%s' to uint value", spec.Type().Name()) - } - spec.SetUint(uint64Value) - default: - return fmt.Errorf("expected uint or interpolated string but was %T", json) - } - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - if _, isDuration := spec.Interface().(Duration); isDuration { - switch json := raw.(type) { - case string: - interpolated := interpolate(ctx, json) - if interpolated == "" { - interpolated = fieldTag.defaultValue - if interpolated == "" { - return nil - } - } - duration, err := time.ParseDuration(interpolated) - if err != nil { - return fmt.Errorf("unable to resolve field '%s' to duration value", spec.Type().Name()) - } - spec.SetInt(int64(duration)) - case nil: - defaultValue := fieldTag.defaultValue - if defaultValue == "" { - return nil - } - duration, err := time.ParseDuration(defaultValue) - if err != nil { - return fmt.Errorf("unable to resolve field '%s' to duration value", spec.Type().Name()) - } - spec.SetInt(int64(duration)) - default: - return fmt.Errorf("expected uint or interpolated string but was %T", json) - } - return nil - } - switch json := raw.(type) { - case string: - interpolated := interpolate(ctx, json) - if interpolated == "" { - interpolated = fieldTag.defaultValue - if interpolated == "" { - return nil - } - } - int64Value, err := strconv.ParseInt(interpolated, 10, 64) - if err != nil { - return fmt.Errorf("unable to resolve field '%s' to int value", spec.Type().Name()) - } - spec.SetInt(int64Value) - case float64: - spec.SetInt(int64(json)) - case nil: - defaultValue := fieldTag.defaultValue - if defaultValue == "" { - return nil - } - int64Value, err := strconv.ParseInt(defaultValue, 10, 64) - if err != nil { - return fmt.Errorf("unable to resolve field '%s' to int value", spec.Type().Name()) - } - spec.SetInt(int64Value) - default: - return fmt.Errorf("expected uint or interpolated string but was %T", json) - } - case reflect.Bool: - switch json := raw.(type) { - case string: - interpolated := strings.ToLower(interpolate(ctx, json)) - if interpolated != "true" && interpolated != "false" { - return fmt.Errorf("unable to resolve field '%s' to bool value", spec.Type().Name()) - } - spec.SetBool(interpolated == "true") - case bool: - spec.SetBool(json) - case nil: - defaultValue := strings.ToLower(fieldTag.defaultValue) - if defaultValue != "true" && defaultValue != "false" { - return fmt.Errorf("unable to resolve field '%s' to bool value", spec.Type().Name()) - } - spec.SetBool(defaultValue == "true") - default: - return fmt.Errorf("expected uint or interpolated string but was %T", json) - } - case reflect.Float64, reflect.Float32: - switch json := raw.(type) { - case string: - interpolated := strings.ToLower(interpolate(ctx, json)) - float64Value, err := strconv.ParseFloat(interpolated, 64) - if err != nil { - return fmt.Errorf("expected float64 or interpolated string but was %T", json) - } - spec.SetFloat(float64Value) - case float64: - spec.SetFloat(json) - case nil: - defaultValue := fieldTag.defaultValue - if defaultValue == "" { - return nil - } - value, err := strconv.ParseFloat(defaultValue, 64) - if err != nil { - return fmt.Errorf("unable to resolve field '%s' to uint value", spec.Type().Name()) - } - spec.SetFloat(value) - default: - return fmt.Errorf("expected uint or interpolated string but was %T", json) - } - case reflect.Struct: - if _, isDate := spec.Interface().(time.Time); isDate { - switch json := raw.(type) { - case string: - interpolated := interpolate(ctx, json) - if interpolated == "" { - interpolated = fieldTag.defaultValue - } - if interpolated != "" { - date, err := time.ParseTime(interpolated) - if err != nil { - return fmt.Errorf("expected date as rfc3339 format") - } - spec.Set(reflect.ValueOf(date)) - } - case nil: - if fieldTag.defaultValue != "" { - date, err := time.ParseTime(fieldTag.defaultValue) - if err != nil { - return fmt.Errorf("expected date as rfc3339 format") - } - spec.Set(reflect.ValueOf(date)) - } - default: - return fmt.Errorf("expected string but was %T", json) - } - return nil - } - asMap, ok := raw.(map[string]any) - if !ok { - return fmt.Errorf("expected map but was %T", raw) - } - if err := mapObject(ctx, asMap, spec); err != nil { - return err - } - } - return nil -} - -func mapObject(ctx Context, raw map[string]any, spec reflect.Value) error { - specType := spec.Type() - specFieldsCount := specType.NumField() - for i := 0; i < specFieldsCount; i++ { - specFieldType := specType.Field(i) - specField := spec.Field(i) - - if specFieldType.Anonymous { - if err := mapObject(ctx, raw, specField); err != nil { - return err - } - continue - } - - jsonKey := strings.Split(specFieldType.Tag.Get("json"), ",")[0] - - if err := mapObjectField(ctx, raw[jsonKey], specField, parseTag(specFieldType.Tag.Get("spec"))); err != nil { - return &fieldResolveError{ - name: specFieldType.Name, - err: err, - } - } - } - return nil -} - -func Resolve(ctx Context, data map[string]any, name string) (stages.Stage, error) { - schema := stages.Get(name) - if schema == nil { - return nil, errors.New("unable to resolve schema " + name) - } - schema = reflect.New(reflect.TypeOf(schema)).Interface().(stages.Stage) - return schema, mapObject(ctx, data, reflect.ValueOf(schema).Elem()) -} diff --git a/ee/orchestration/internal/schema/tag.go b/ee/orchestration/internal/schema/tag.go deleted file mode 100644 index ab9951f7b9..0000000000 --- a/ee/orchestration/internal/schema/tag.go +++ /dev/null @@ -1,21 +0,0 @@ -package schema - -import ( - "strings" -) - -type tag struct { - defaultValue string -} - -func parseTag(tagValue string) tag { - parts := strings.Split(tagValue, ",") - ret := tag{} - for _, part := range parts { - switch { - case strings.HasPrefix(part, "default:"): - ret.defaultValue = strings.TrimPrefix(part, "default:") - } - } - return ret -} diff --git a/ee/orchestration/internal/schema/validation.go b/ee/orchestration/internal/schema/validation.go deleted file mode 100644 index 21be254554..0000000000 --- a/ee/orchestration/internal/schema/validation.go +++ /dev/null @@ -1,56 +0,0 @@ -package schema - -import ( - "reflect" - "strings" - - "github.com/formancehq/orchestration/internal/workflow/stages" - "github.com/go-playground/validator/v10" -) - -var validate = validator.New() - -func ValidateRequirements(schema stages.Stage) error { - return validate.Struct(schema) -} - -func reportOneOfError(sl validator.StructLevel, value reflect.Value) { - choices := make([]string, 0) - for i := 0; i < value.Type().NumField(); i++ { - jsonTag := value.Type().Field(i).Tag.Get("json") - choices = append(choices, strings.Split(jsonTag, ",")[0]) - } - for i := 0; i < value.Type().NumField(); i++ { - sl.ReportError( - value.Field(i).Interface(), - strings.Split(value.Type().Field(i).Tag.Get("json"), ",")[0], - value.Field(i).Type().Name(), - strings.Join(choices, " or "), - "", - ) - } -} - -func oneOf(sl validator.StructLevel) { - object := sl.Current().Interface() - valueOfObject := reflect.ValueOf(object) - defined := false - for i := 0; i < valueOfObject.Type().NumField(); i++ { - if !valueOfObject.Field(i).IsZero() { - if defined { - reportOneOfError(sl, valueOfObject) - return - } - defined = true - } - } - if !defined { - reportOneOfError(sl, valueOfObject) - } -} - -func RegisterOneOf(to ...any) { - for _, v := range to { - validate.RegisterStructValidation(oneOf, v) - } -} diff --git a/ee/orchestration/internal/storage/main_test.go b/ee/orchestration/internal/storage/main_test.go deleted file mode 100644 index a60f296bd8..0000000000 --- a/ee/orchestration/internal/storage/main_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package storage - -import ( - "testing" - - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/go-libs/testing/docker" - "github.com/formancehq/go-libs/testing/utils" - - "github.com/formancehq/go-libs/testing/platform/pgtesting" -) - -var srv *pgtesting.PostgresServer - -func TestMain(m *testing.M) { - utils.WithTestMain(func(t *utils.TestingTForMain) int { - srv = pgtesting.CreatePostgresServer(t, docker.NewPool(t, logging.Testing())) - - return m.Run() - }) -} diff --git a/ee/orchestration/internal/storage/migrations.go b/ee/orchestration/internal/storage/migrations.go deleted file mode 100644 index 53f845a918..0000000000 --- a/ee/orchestration/internal/storage/migrations.go +++ /dev/null @@ -1,175 +0,0 @@ -package storage - -import ( - "context" - - "github.com/formancehq/go-libs/migrations" - "github.com/uptrace/bun" -) - -var _migrations = []migrations.Migration{ - { - Up: func(tx bun.Tx) error { - if _, err := tx.Exec(` - create table "workflows" ( - config jsonb, - id varchar not null, - created_at timestamp default now(), - updated_at timestamp default now(), - primary key (id) - ); - create table "workflow_instances" ( - workflow_id varchar references workflows (id), - id varchar, - created_at timestamp default now(), - updated_at timestamp default now(), - primary key (id) - ); - create table "workflow_instance_stage_statuses" ( - instance_id varchar references workflow_instances (id), - stage int, - started_at timestamp default now(), - terminated_at timestamp default null, - error varchar, - primary key (instance_id, stage) - ); - `); err != nil { - return err - } - return nil - }, - }, - { - Up: func(tx bun.Tx) error { - if _, err := tx.Exec(` - alter table "workflow_instances" add column terminated bool; - alter table "workflow_instances" add column terminated_at timestamp default null; - `); err != nil { - return err - } - return nil - }, - }, - { - Up: func(tx bun.Tx) error { - if _, err := tx.Exec(` - alter table "workflow_instances" add column error varchar; - `); err != nil { - return err - } - return nil - }, - }, - { - Up: func(tx bun.Tx) error { - if _, err := tx.Exec(` - alter table "workflows" add column if not exists deleted_at timestamp default null; - `); err != nil { - return err - } - return nil - }, - }, - { - Up: func(tx bun.Tx) error { - if _, err := tx.Exec(` - create table triggers ( - id varchar primary key, - workflow_id varchar references workflows(id), - filter varchar null, - event varchar not null, - vars jsonb, - created_at timestamp not null default now(), - deleted_at timestamp default null - ); - create table triggers_occurrences ( - workflow_instance_id varchar references workflow_instances(id), - trigger_id varchar references triggers(id), - event_id varchar not null, - date timestamp not null default now(), - event jsonb not null, - primary key (trigger_id, event_id) - ); - `); err != nil { - return err - } - return nil - }, - }, - { - Up: func(tx bun.Tx) error { - if _, err := tx.Exec(` - alter table "workflow_instance_stage_statuses" - drop constraint workflow_instance_stage_statuses_pkey; - - alter table "workflow_instance_stage_statuses" - add column temporal_run_id varchar; - - update "workflow_instance_stage_statuses" - set temporal_run_id = ''; - - alter table "workflow_instance_stage_statuses" - add primary key (instance_id, stage, temporal_run_id); - `); err != nil { - return err - } - return nil - }, - }, - { - Up: func(tx bun.Tx) error { - if _, err := tx.Exec(` - alter table "triggers_occurrences" - add column error varchar; - `); err != nil { - return err - } - return nil - }, - }, - { - Up: func(tx bun.Tx) error { - if _, err := tx.Exec(` - alter table "triggers_occurrences" - drop constraint triggers_occurrences_pkey; - - alter table "triggers_occurrences" - drop column event_id; - - alter table "triggers_occurrences" - add column id varchar; - - update "triggers_occurrences" - set id = gen_random_uuid(); - - alter table "triggers_occurrences" - add primary key (id); - `); err != nil { - return err - } - return nil - }, - }, - { - Up: func(tx bun.Tx) error { - if _, err := tx.Exec(` - alter table "triggers" - add column name varchar; - `); err != nil { - return err - } - return nil - }, - }, -} - -func Migrate(ctx context.Context, db *bun.DB) error { - return MigrateUntil(ctx, db, len(_migrations)) -} - -func MigrateUntil(ctx context.Context, db *bun.DB, until int) error { - migrator := migrations.NewMigrator() - migrator.RegisterMigrations(_migrations[:until]...) - - return migrator.Up(ctx, db) -} diff --git a/ee/orchestration/internal/storage/migrations_test.go b/ee/orchestration/internal/storage/migrations_test.go deleted file mode 100644 index 9ccdd088c1..0000000000 --- a/ee/orchestration/internal/storage/migrations_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package storage - -import ( - "testing" - - "github.com/formancehq/go-libs/bun/bundebug" - "github.com/uptrace/bun" - - "github.com/formancehq/go-libs/bun/bunconnect" - "github.com/formancehq/go-libs/logging" - "github.com/stretchr/testify/require" -) - -func TestMigrationsAddTemporalRunIDAsCompoundPrimaryKeyOnStages(t *testing.T) { - db := srv.NewDatabase(t) - - hooks := make([]bun.QueryHook, 0) - if testing.Verbose() { - hooks = append(hooks, bundebug.NewQueryHook()) - } - - bunDB, err := bunconnect.OpenSQLDB(logging.TestingContext(), db.ConnectionOptions(), hooks...) - require.NoError(t, err) - defer func() { - require.NoError(t, bunDB.Close()) - }() - require.NoError(t, MigrateUntil(logging.TestingContext(), bunDB, 5)) - - _, err = bunDB.Exec(` - insert into workflows(config, id) - values ('{}'::jsonb, '1'); - - insert into workflow_instances(workflow_id, id) - values ('1', '1'); - - insert into workflow_instance_stage_statuses(instance_id, stage) - values('1', 0); - `) - require.NoError(t, err) - - // The migration 6 will update primary key of the table `workflow_instance_stage_statuses` - // Since we insert some data before, this test ensure the schema is not breaking after the migration - require.NoError(t, Migrate(logging.TestingContext(), bunDB)) -} diff --git a/ee/orchestration/internal/temporalclient/client_module.go b/ee/orchestration/internal/temporalclient/client_module.go deleted file mode 100644 index 021de2e5c7..0000000000 --- a/ee/orchestration/internal/temporalclient/client_module.go +++ /dev/null @@ -1,105 +0,0 @@ -package temporalclient - -import ( - "context" - "crypto/tls" - "time" - - "go.temporal.io/api/enums/v1" - "go.temporal.io/api/operatorservice/v1" - - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/orchestration/internal/triggers" - "github.com/formancehq/orchestration/internal/workflow" - "go.temporal.io/api/serviceerror" - "go.temporal.io/sdk/client" - "go.temporal.io/sdk/contrib/opentelemetry" - "go.temporal.io/sdk/interceptor" - "go.uber.org/fx" -) - -func NewModule(address, namespace string, certStr string, key string, initSearchAttributes bool) fx.Option { - return fx.Options( - fx.Provide(func(logger logging.Logger) (client.Options, error) { - - var cert *tls.Certificate - if key != "" && certStr != "" { - clientCert, err := tls.X509KeyPair([]byte(certStr), []byte(key)) - if err != nil { - return client.Options{}, err - } - cert = &clientCert - } - - tracingInterceptor, err := opentelemetry.NewTracingInterceptor(opentelemetry.TracerOptions{ - Tracer: workflow.Tracer, - }) - if err != nil { - return client.Options{}, err - } - - options := client.Options{ - Namespace: namespace, - HostPort: address, - Interceptors: []interceptor.ClientInterceptor{tracingInterceptor}, - Logger: newLogger(logger), - } - if cert != nil { - options.ConnectionOptions = client.ConnectionOptions{ - TLS: &tls.Config{Certificates: []tls.Certificate{*cert}}, - } - } - return options, nil - }), - fx.Provide(client.Dial), - fx.Invoke(func(lifecycle fx.Lifecycle, c client.Client) { - lifecycle.Append(fx.Hook{ - OnStart: func(ctx context.Context) error { - if initSearchAttributes { - return createSearchAttributes(ctx, c, namespace) - } - return nil - }, - OnStop: func(ctx context.Context) error { - c.Close() - return nil - }, - }) - }), - ) -} - -func createSearchAttributes(ctx context.Context, c client.Client, namespace string) error { - _, err := c.OperatorService().AddSearchAttributes(logging.TestingContext(), &operatorservice.AddSearchAttributesRequest{ - SearchAttributes: map[string]enums.IndexedValueType{ - workflow.SearchAttributeWorkflowID: enums.INDEXED_VALUE_TYPE_TEXT, - triggers.SearchAttributeTriggerID: enums.INDEXED_VALUE_TYPE_TEXT, - }, - Namespace: namespace, - }) - if err != nil { - if _, ok := err.(*serviceerror.AlreadyExists); !ok { - return err - } - } - // Search attributes are created asynchronously, so poll the list, until it is ready - for { - ret, err := c.OperatorService().ListSearchAttributes(ctx, &operatorservice.ListSearchAttributesRequest{ - Namespace: namespace, - }) - if err != nil { - panic(err) - } - - if ret.CustomAttributes[workflow.SearchAttributeWorkflowID] != enums.INDEXED_VALUE_TYPE_UNSPECIFIED && - ret.CustomAttributes[triggers.SearchAttributeTriggerID] != enums.INDEXED_VALUE_TYPE_UNSPECIFIED { - return nil - } - - select { - case <-ctx.Done(): - return ctx.Err() - case <-time.After(500 * time.Millisecond): - } - } -} diff --git a/ee/orchestration/internal/temporalclient/logger.go b/ee/orchestration/internal/temporalclient/logger.go deleted file mode 100644 index 5d27fbd0c5..0000000000 --- a/ee/orchestration/internal/temporalclient/logger.go +++ /dev/null @@ -1,42 +0,0 @@ -package temporalclient - -import ( - "github.com/formancehq/go-libs/logging" - "go.temporal.io/sdk/log" -) - -func keyvalsToMap(keyvals ...interface{}) map[string]any { - ret := make(map[string]any) - for i := 0; i < len(keyvals); i += 2 { - ret[keyvals[i].(string)] = keyvals[i+1] - } - return ret -} - -type logger struct { - logger logging.Logger -} - -func (l logger) Debug(msg string, keyvals ...interface{}) { - l.logger.WithFields(keyvalsToMap(keyvals...)).Debugf(msg) -} - -func (l logger) Info(msg string, keyvals ...interface{}) { - l.logger.WithFields(keyvalsToMap(keyvals...)).Infof(msg) -} - -func (l logger) Warn(msg string, keyvals ...interface{}) { - l.logger.WithFields(keyvalsToMap(keyvals...)).Errorf(msg) -} - -func (l logger) Error(msg string, keyvals ...interface{}) { - l.logger.WithFields(keyvalsToMap(keyvals...)).Errorf(msg) -} - -var _ log.Logger = (*logger)(nil) - -func newLogger(l logging.Logger) *logger { - return &logger{ - logger: l, - } -} diff --git a/ee/orchestration/internal/temporalworker/module.go b/ee/orchestration/internal/temporalworker/module.go deleted file mode 100644 index e36227db6f..0000000000 --- a/ee/orchestration/internal/temporalworker/module.go +++ /dev/null @@ -1,86 +0,0 @@ -package temporalworker - -import ( - "context" - - "github.com/formancehq/go-libs/logging" - - temporalworkflow "go.temporal.io/sdk/workflow" - - "go.temporal.io/sdk/activity" - "go.temporal.io/sdk/client" - "go.temporal.io/sdk/worker" - "go.uber.org/fx" -) - -type Definition struct { - Func any - Name string -} - -type DefinitionSet []Definition - -func NewDefinitionSet() DefinitionSet { - return DefinitionSet{} -} - -func (d DefinitionSet) Append(definition Definition) DefinitionSet { - d = append(d, definition) - - return d -} - -func New(logger logging.Logger, c client.Client, taskQueue string, workflows, activities []DefinitionSet, options worker.Options) worker.Worker { - options.BackgroundActivityContext = logging.ContextWithLogger(context.Background(), logger) - worker := worker.New(c, taskQueue, options) - - for _, set := range workflows { - for _, workflow := range set { - worker.RegisterWorkflowWithOptions(workflow.Func, temporalworkflow.RegisterOptions{ - Name: workflow.Name, - }) - } - } - - for _, set := range activities { - for _, act := range set { - worker.RegisterActivityWithOptions(act.Func, activity.RegisterOptions{ - Name: act.Name, - }) - } - } - - return worker -} - -func NewWorkerModule(taskQueue string, options worker.Options) fx.Option { - return fx.Options( - fx.Provide( - fx.Annotate(func(logger logging.Logger, c client.Client, workflows, activities []DefinitionSet) worker.Worker { - return New(logger, c, taskQueue, workflows, activities, options) - }, fx.ParamTags(``, ``, `group:"workflows"`, `group:"activities"`)), - ), - fx.Invoke(func(lc fx.Lifecycle, w worker.Worker) { - willStop := false - lc.Append(fx.Hook{ - OnStart: func(ctx context.Context) error { - go func() { - err := w.Run(worker.InterruptCh()) - if err != nil { - // If the worker is started/stopped fast, the Run method can return an error - if !willStop { - panic(err) - } - } - }() - return nil - }, - OnStop: func(ctx context.Context) error { - willStop = true - w.Stop() - return nil - }, - }) - }), - ) -} diff --git a/ee/orchestration/internal/triggers/activities.go b/ee/orchestration/internal/triggers/activities.go deleted file mode 100644 index c1d0b23bd1..0000000000 --- a/ee/orchestration/internal/triggers/activities.go +++ /dev/null @@ -1,140 +0,0 @@ -package triggers - -import ( - "context" - "strings" - - "github.com/formancehq/orchestration/internal/temporalworker" - - "github.com/ThreeDotsLabs/watermill/message" - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/go-libs/pointer" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/formancehq/orchestration/pkg/events" - "github.com/uptrace/bun" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" -) - -type Activities struct { - db *bun.DB - manager *workflow.WorkflowManager - expressionEvaluator *expressionEvaluator - publisher message.Publisher -} - -func (a Activities) processTrigger(ctx context.Context, request ProcessEventRequest, trigger Trigger) bool { - ctx, span := workflow.Tracer.Start(ctx, "Triggers:CheckRequirements", trace.WithAttributes( - attribute.String("trigger-id", trigger.ID), - )) - defer span.End() - - if trigger.Filter != nil && *trigger.Filter != "" { - - ok, err := a.expressionEvaluator.evalFilter(request.Event.Payload, *trigger.Filter) - if err != nil { - span.SetAttributes( - attribute.String("filter-error", err.Error()), - ) - } - span.SetAttributes( - attribute.String("filter", *trigger.Filter), - attribute.Bool("match", ok), - ) - - if !ok { - return false - } - } - - return true -} - -func (a Activities) ListTriggers(ctx context.Context, request ProcessEventRequest) ([]Trigger, error) { - ret := make([]Trigger, 0) - - triggers := make([]Trigger, 0) - if err := a.db.NewSelect(). - Model(&triggers). - Relation("Workflow"). - Where("trigger.deleted_at is null"). - Where("event = ?", request.Event.Type). - Scan(ctx); err != nil { - return nil, err - } - - span := trace.SpanFromContext(ctx) - span.SetAttributes(attribute.String("found-triggers", strings.Join(collectionutils.Map(triggers, Trigger.GetID), ", "))) - - for _, trigger := range triggers { - if a.processTrigger(trace.ContextWithSpan(ctx, span), request, trigger) { - ret = append(ret, trigger) - } - } - - return ret, nil -} - -func (a Activities) EvalTriggerVariables(ctx context.Context, trigger Trigger, request ProcessEventRequest) (map[string]string, error) { - return a.expressionEvaluator.evalVariables(request.Event.Payload, trigger.Vars) -} - -func (a Activities) InsertTriggerOccurrence(ctx context.Context, occurrence Occurrence) error { - _, err := a.db.NewInsert(). - Model(pointer.For(occurrence)). - Exec(ctx) - return err -} - -func (a Activities) SendEventForTriggerTermination(ctx context.Context, occurrence Occurrence) error { - if occurrence.Error == nil || *occurrence.Error == "" { - return a.publisher.Publish(events.TopicOrchestration, - events.NewMessage(ctx, events.SucceededTrigger, events.SucceededTriggerPayload{ - ID: occurrence.ID, - WorkflowInstanceID: *occurrence.WorkflowInstanceID, - TriggerID: occurrence.TriggerID, - })) - } else { - return a.publisher.Publish(events.TopicOrchestration, - events.NewMessage(ctx, events.FailedTrigger, events.FailedTriggerPayload{ - ID: occurrence.ID, - TriggerID: occurrence.TriggerID, - Error: *occurrence.Error, - })) - } -} - -func (a Activities) DefinitionSet() temporalworker.DefinitionSet { - return temporalworker.NewDefinitionSet(). - Append(temporalworker.Definition{ - Func: a.EvalTriggerVariables, - Name: "EvalTriggerVariables", - }). - Append(temporalworker.Definition{ - Func: a.InsertTriggerOccurrence, - Name: "InsertTriggerOccurrence", - }). - Append(temporalworker.Definition{ - Func: a.ListTriggers, - Name: "ListTriggers", - }). - Append(temporalworker.Definition{ - Func: a.SendEventForTriggerTermination, - Name: "SendEventForTriggerTermination", - }) -} - -func NewActivities(db *bun.DB, manager *workflow.WorkflowManager, - expressionEvaluator *expressionEvaluator, publisher message.Publisher) Activities { - return Activities{ - db: db, - manager: manager, - expressionEvaluator: expressionEvaluator, - publisher: publisher, - } -} - -var EvalTriggerVariables = Activities{}.EvalTriggerVariables -var SendEventForTriggerTermination = Activities{}.SendEventForTriggerTermination -var ListTriggersActivity = Activities{}.ListTriggers -var InsertTriggerOccurrence = Activities{}.InsertTriggerOccurrence diff --git a/ee/orchestration/internal/triggers/expression.go b/ee/orchestration/internal/triggers/expression.go deleted file mode 100644 index f5e181d05a..0000000000 --- a/ee/orchestration/internal/triggers/expression.go +++ /dev/null @@ -1,152 +0,0 @@ -package triggers - -import ( - "encoding/json" - "fmt" - "net/http" - - "go.temporal.io/sdk/temporal" - - "github.com/formancehq/go-libs/collectionutils" - - "github.com/expr-lang/expr" - "github.com/formancehq/go-libs/api" - "github.com/pkg/errors" -) - -type expressionEvaluator struct { - httpClient *http.Client -} - -func (h *expressionEvaluator) link(params ...any) (any, error) { - if len(params) != 2 { - return nil, temporal.NewNonRetryableApplicationError( - fmt.Sprintf("expect two arguments, got %d", len(params)), - "APPLICATION", - fmt.Errorf("expect two arguments, got %d", len(params)), - ) - } - - data, _ := json.Marshal(params[0]) - - type object struct { - Links []api.Link `json:"links"` - } - o := &object{} - if err := json.Unmarshal(data, o); err != nil { - return nil, err - } - - rel, ok := params[1].(string) - if !ok { - return nil, errors.New("second parameter must be a string") - } - - filteredLinks := collectionutils.Filter(o.Links, func(link api.Link) bool { - return link.Name == rel - }) - - switch len(filteredLinks) { - case 0: - return nil, temporal.NewNonRetryableApplicationError( - fmt.Sprintf("link '%s' not defined for object", rel), - "APPLICATION", - fmt.Errorf("link '%s' not defined for object", rel), - ) - case 1: - rsp, err := h.httpClient.Get(filteredLinks[0].URI) - if err != nil { - return nil, errors.Wrapf(err, "reading resource: %s", filteredLinks[0].URI) - } - if rsp.StatusCode >= 400 { - return nil, fmt.Errorf("unexpected status code when reading resource: %d", rsp.StatusCode) - } - - apiResponse := api.BaseResponse[map[string]any]{} - if err := json.NewDecoder(rsp.Body).Decode(&apiResponse); err != nil { - return nil, errors.Wrap(err, "decoding response") - } - - return apiResponse.Data, nil - default: - return nil, temporal.NewNonRetryableApplicationError( - fmt.Sprintf("multiple link '%s' found for object", rel), - "APPLICATION", - fmt.Errorf("multiple link '%s' found for object", rel), - ) - } -} - -func (h *expressionEvaluator) eval(rawObject any, e string) (any, error) { - p, err := expr.Compile(e, expr.Function("link", h.link)) - if err != nil { - return "", err - } - - ret, err := expr.Run(p, map[string]any{ - "event": rawObject, - }) - if err != nil { - if err := errors.Unwrap(err); err != nil { - return nil, err - } - return nil, err - } - - return ret, nil -} - -func (h *expressionEvaluator) evalFilter(event any, filter string) (bool, error) { - ret, err := h.eval(event, filter) - if err != nil { - return false, err - } - - switch ret := ret.(type) { - case bool: - return ret, nil - default: - return false, nil - } -} - -func (h *expressionEvaluator) evalVariable(rawObject any, e string) (string, error) { - ret, err := h.eval(rawObject, e) - if err != nil { - return "", err - } - - switch ret.(type) { - case float64, float32: - data, err := json.Marshal(ret) - if err != nil { - return "", err - } - return string(data), nil - default: - return fmt.Sprint(ret), nil - } -} - -func (h *expressionEvaluator) evalVariables(rawObject any, vars map[string]string) (map[string]string, error) { - results := make(map[string]string) - for k, v := range vars { - var err error - results[k], err = h.evalVariable(rawObject, v) - if err != nil { - return nil, err - } - } - - return results, nil -} - -func NewExpressionEvaluator(httpClient *http.Client) *expressionEvaluator { - return &expressionEvaluator{ - httpClient: httpClient, - } -} - -func NewDefaultExpressionEvaluator() *expressionEvaluator { - return NewExpressionEvaluator(http.DefaultClient) -} diff --git a/ee/orchestration/internal/triggers/listener.go b/ee/orchestration/internal/triggers/listener.go deleted file mode 100644 index 2a6d99ae03..0000000000 --- a/ee/orchestration/internal/triggers/listener.go +++ /dev/null @@ -1,117 +0,0 @@ -package triggers - -import ( - "encoding/json" - "fmt" - "runtime/debug" - - "go.temporal.io/api/enums/v1" - - "github.com/formancehq/orchestration/internal/workflow" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" - - "github.com/formancehq/go-libs/pointer" - "go.temporal.io/api/serviceerror" - - "github.com/formancehq/go-libs/logging" - - "github.com/ThreeDotsLabs/watermill/message" - "github.com/formancehq/go-libs/publish" - "github.com/pkg/errors" - "go.temporal.io/sdk/client" -) - -// Quick hack to filter already processed events -func getWorkflowIDFromEvent(event publish.EventMessage) *string { - switch event.Type { - case "SAVED_PAYMENT", "SAVED_ACCOUNT": - data, err := json.Marshal(event.Payload) - if err != nil { - panic(err) - } - - type object struct { - ID string `json:"id"` - } - o := &object{} - if err := json.Unmarshal(data, o); err != nil { - panic(err) - } - - return pointer.For(o.ID) - default: - return nil - } -} - -func handleMessage(temporalClient client.Client, taskIDPrefix, taskQueue string, msg *message.Message) error { - - defer func() { - if e := recover(); e != nil { - fmt.Println(e) - debug.PrintStack() - } - }() - - var event *publish.EventMessage - span, event, err := publish.UnmarshalMessage(msg) - if err != nil { - logging.FromContext(msg.Context()).Error(err.Error()) - return err - } - - ctx, span := workflow.Tracer.Start(msg.Context(), "Trigger:HandleEvent", - trace.WithLinks(trace.Link{ - SpanContext: span.SpanContext(), - }), - trace.WithAttributes( - attribute.String("event-id", msg.UUID), - attribute.Bool("duplicate", false), - attribute.String("event-type", event.Type), - attribute.String("event-payload", string(msg.Payload)), - ), - ) - defer span.End() - defer func() { - if err != nil { - span.RecordError(err) - } - }() - - options := client.StartWorkflowOptions{ - TaskQueue: taskQueue, - } - if ik := getWorkflowIDFromEvent(*event); ik != nil { - options.ID = taskIDPrefix + "-" + *ik - options.WorkflowIDReusePolicy = enums.WORKFLOW_ID_REUSE_POLICY_REJECT_DUPLICATE - options.WorkflowExecutionErrorWhenAlreadyStarted = true - } - - _, err = temporalClient.ExecuteWorkflow(ctx, options, RunTrigger, ProcessEventRequest{ - Event: *event, - }) - if err != nil { - _, ok := err.(*serviceerror.WorkflowExecutionAlreadyStarted) - if ok { - span.SetAttributes(attribute.Bool("duplicate", true)) - err = nil - return nil - } - } - - return errors.Wrap(err, "executing workflow") -} - -func registerListener(r *message.Router, s message.Subscriber, temporalClient client.Client, - taskIDPrefix, taskQueue string, topics []string) { - for _, topic := range topics { - r.AddNoPublisherHandler(fmt.Sprintf("listen-%s-events", topic), topic, s, func(msg *message.Message) error { - if err := handleMessage(temporalClient, taskIDPrefix, taskQueue, msg); err != nil { - logging.Errorf("Error executing workflow: %s", err) - return err - } - return nil - }) - } -} diff --git a/ee/orchestration/internal/triggers/main_test.go b/ee/orchestration/internal/triggers/main_test.go deleted file mode 100644 index 38755f2c67..0000000000 --- a/ee/orchestration/internal/triggers/main_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package triggers - -import ( - "testing" - - "github.com/formancehq/go-libs/testing/docker" - "github.com/formancehq/go-libs/testing/utils" - "github.com/stretchr/testify/require" - - "github.com/formancehq/go-libs/logging" - "go.temporal.io/sdk/testsuite" - - "github.com/formancehq/go-libs/testing/platform/pgtesting" -) - -var ( - srv *pgtesting.PostgresServer - devServer *testsuite.DevServer -) - -func TestMain(m *testing.M) { - utils.WithTestMain(func(t *utils.TestingTForMain) int { - srv = pgtesting.CreatePostgresServer(t, docker.NewPool(t, logging.Testing())) - - var err error - devServer, err = testsuite.StartDevServer(logging.TestingContext(), testsuite.DevServerOptions{}) - require.NoError(t, err) - - t.Cleanup(func() { - require.NoError(t, devServer.Stop()) - }) - - return m.Run() - }) -} diff --git a/ee/orchestration/internal/triggers/manager.go b/ee/orchestration/internal/triggers/manager.go deleted file mode 100644 index 60c002fb43..0000000000 --- a/ee/orchestration/internal/triggers/manager.go +++ /dev/null @@ -1,181 +0,0 @@ -package triggers - -import ( - "context" - "database/sql" - "time" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/formancehq/orchestration/internal/workflow" - "github.com/pkg/errors" - "github.com/uptrace/bun" -) - -var ErrWorkflowNotExists = errors.New("workflow does not exists") - -type VariableEvaluationResult struct { - Value string `json:"value,omitempty"` - Error string `json:"error,omitempty"` -} - -type FilterEvaluationResult struct { - Match bool `json:"match"` - Error string `json:"error,omitempty"` -} - -type TestTriggerResult struct { - Filter *FilterEvaluationResult `json:"filter"` - Variables map[string]VariableEvaluationResult `json:"variables"` -} - -type TriggerManager struct { - db *bun.DB - expressionEvaluator *expressionEvaluator -} - -func (m *TriggerManager) ListTriggers(ctx context.Context, paramsQuery ListTriggersQuery) (*bunpaginate.Cursor[Trigger], error) { - q := m.db.NewSelect() - - return bunpaginate.UsingOffset[ListTriggerParams, Trigger](ctx, q, bunpaginate.OffsetPaginatedQuery[ListTriggerParams](paramsQuery), - func(query *bun.SelectQuery) *bun.SelectQuery { - - if paramsQuery.Options.Name != "" { - query = query.Where("Name ILIKE '%?%';", paramsQuery.Options.Name) - } - return query.Where("deleted_at is null") - }) -} - -func (m *TriggerManager) TestTrigger(ctx context.Context, triggerID string, event map[string]any) (*TestTriggerResult, error) { - trigger := &Trigger{} - err := m.db.NewSelect(). - Model(trigger). - Where("deleted_at is null"). - Where("id = ?", triggerID). - Scan(ctx) - if err != nil { - return nil, err - } - - ret := TestTriggerResult{} - if filter := trigger.Filter; filter != nil { - ret.Filter = &FilterEvaluationResult{} - ret.Filter.Match, err = m.expressionEvaluator.evalFilter(event, *filter) - if err != nil { - ret.Filter.Error = err.Error() - } - } - if (ret.Filter == nil || ret.Filter.Match) && len(trigger.Vars) > 0 { - ret.Variables = map[string]VariableEvaluationResult{} - for key, expr := range trigger.Vars { - v := VariableEvaluationResult{} - v.Value, err = m.expressionEvaluator.evalVariable(event, expr) - if err != nil { - v.Error = err.Error() - } - ret.Variables[key] = v - } - } - - return &ret, nil -} - -func (m *TriggerManager) GetTrigger(ctx context.Context, triggerID string) (*Trigger, error) { - ret := &Trigger{} - err := m.db.NewSelect(). - Model(ret). - Where("deleted_at is null"). - Where("id = ?", triggerID). - Scan(ctx) - if err != nil { - return nil, err - } - - return ret, nil -} - -func (m *TriggerManager) DeleteTrigger(ctx context.Context, triggerID string) error { - updated, err := m.db.NewUpdate(). - Model(&Trigger{}). - Where("deleted_at is null"). - Where("id = ?", triggerID). - Set("deleted_at = ?", time.Now()). - Exec(ctx) - rowsAffected, err := updated.RowsAffected() - if err != nil { - panic(err) - } - if rowsAffected == 0 { - return sql.ErrNoRows - } - return err -} - -func (m *TriggerManager) CreateTrigger(ctx context.Context, data TriggerData) (*Trigger, error) { - - if err := data.Validate(); err != nil { - return nil, errors.Wrap(err, "validating data") - } - - exists, err := m.db.NewSelect(). - Model(&workflow.Workflow{}). - Where("deleted_at is null"). - Where("id = ?", data.WorkflowID). - Exists(ctx) - if err != nil { - return nil, err - } - - if !exists { - return nil, ErrWorkflowNotExists - } - - trigger, err := NewTrigger(data) - if err != nil { - return nil, err - } - - _, err = m.db.NewInsert(). - Model(trigger). - Exec(ctx) - - if err != nil { - return nil, err - } - - return trigger, nil -} - -func (m *TriggerManager) ListTriggersOccurrences(ctx context.Context, q ListTriggersOccurrencesQuery) (*bunpaginate.Cursor[Occurrence], error) { - query := m.db.NewSelect() - - return bunpaginate.UsingOffset[ListTriggersOccurrencesOptions, Occurrence](ctx, query, bunpaginate.OffsetPaginatedQuery[ListTriggersOccurrencesOptions](q), - func(query *bun.SelectQuery) *bun.SelectQuery { - query = query.Relation("WorkflowInstance") - - if q.Options.TriggerID != "" { - query = query.Where("trigger_id = ?", q.Options.TriggerID) - } - - return query - }) -} - -func NewManager(db *bun.DB, expressionEvaluator *expressionEvaluator) *TriggerManager { - return &TriggerManager{ - db: db, - expressionEvaluator: expressionEvaluator, - } -} - -type ListTriggerParams struct { - Name string -} -type ListTriggersQuery bunpaginate.OffsetPaginatedQuery[ListTriggerParams] - -type ListTriggersOccurrencesOptions struct { - TriggerID string -} - -type ListTriggersOccurrencesQuery bunpaginate.OffsetPaginatedQuery[ListTriggersOccurrencesOptions] diff --git a/ee/orchestration/internal/triggers/module.go b/ee/orchestration/internal/triggers/module.go deleted file mode 100644 index f2f440bd0f..0000000000 --- a/ee/orchestration/internal/triggers/module.go +++ /dev/null @@ -1,46 +0,0 @@ -package triggers - -import ( - "net/http" - "strings" - - "github.com/formancehq/orchestration/internal/temporalworker" - - "github.com/ThreeDotsLabs/watermill/message" - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/uptrace/bun" - "go.temporal.io/sdk/client" - "go.uber.org/fx" -) - -func NewModule(taskQueue string) fx.Option { - return fx.Options( - fx.Provide(NewManager), - fx.Provide(func(httpClient *http.Client) *expressionEvaluator { - return NewExpressionEvaluator(httpClient) - }), - fx.Provide(func() *triggerWorkflow { - return NewWorkflow(taskQueue, true) - }), - fx.Provide(fx.Annotate(func(workflow *triggerWorkflow) temporalworker.DefinitionSet { - return workflow.DefinitionSet() - }, fx.ResultTags(`group:"workflows"`))), - fx.Provide(func(db *bun.DB, manager *workflow.WorkflowManager, - expressionEvaluator *expressionEvaluator, publisher message.Publisher) Activities { - return NewActivities(db, manager, expressionEvaluator, publisher) - }), - fx.Provide(fx.Annotate(func(activities Activities) temporalworker.DefinitionSet { - return activities.DefinitionSet() - }, fx.ResultTags(`group:"activities"`))), - ) -} - -func NewListenerModule(taskIDPrefix, taskQueue string, topics []string) fx.Option { - return fx.Options( - fx.Invoke(func(logger logging.Logger, r *message.Router, s message.Subscriber, temporalClient client.Client) { - logger.Infof("Listening events from topics: %s", strings.Join(topics, ",")) - registerListener(r, s, temporalClient, taskIDPrefix, taskQueue, topics) - }), - ) -} diff --git a/ee/orchestration/internal/triggers/trigger.go b/ee/orchestration/internal/triggers/trigger.go deleted file mode 100644 index f8898224aa..0000000000 --- a/ee/orchestration/internal/triggers/trigger.go +++ /dev/null @@ -1,121 +0,0 @@ -package triggers - -import ( - "fmt" - "time" - - "github.com/formancehq/orchestration/internal/workflow" - - "github.com/formancehq/go-libs/publish" - - "github.com/expr-lang/expr" - "github.com/google/uuid" - "github.com/pkg/errors" - "github.com/uptrace/bun" -) - -var ( - ErrMissingEvent = errors.New("missing event") - ErrMissingWorkflowID = errors.New("missing workflow id") -) - -type ExprCompilationError struct { - err error - expr string -} - -func (e ExprCompilationError) Unwrap() error { - return e.err -} - -func (e ExprCompilationError) Error() string { - return fmt.Sprintf("error compiling expression '%s': %s", e.expr, e.err) -} - -func (e ExprCompilationError) Is(err error) bool { - _, ok := err.(ExprCompilationError) - return ok -} - -func IsExprCompilationError(err error) bool { - return errors.Is(err, ExprCompilationError{}) -} - -func newExprCompilationError(expr string, err error) ExprCompilationError { - return ExprCompilationError{ - err: err, - expr: expr, - } -} - -type TriggerData struct { - Name string `json:"name" bun:"name,type:varchar"` - Event string `json:"event" bun:"event,type:varchar"` - Filter *string `json:"filter,omitempty" bun:"filter,type:varchar"` - WorkflowID string `json:"workflowID" bun:"workflow_id,type:varchar"` - Workflow *workflow.Workflow `json:"workflow" bun:"rel:belongs-to,join:workflow_id=id"` - Vars map[string]string `json:"vars,omitempty" bun:"vars,type:jsonb"` -} - -func (t TriggerData) Validate() error { - if t.Event == "" { - return ErrMissingEvent - } - if t.WorkflowID == "" { - return ErrMissingWorkflowID - } - if t.Filter != nil && *t.Filter != "" { - _, err := expr.Compile(*t.Filter) - if err != nil { - return newExprCompilationError(*t.Filter, err) - } - } - for _, e := range t.Vars { - _, err := expr.Compile(e) - if err != nil { - return newExprCompilationError(e, err) - } - } - return nil -} - -type Trigger struct { - bun.BaseModel `bun:"triggers"` - TriggerData - - ID string `json:"id" bun:"id,type:varchar,pk"` - CreatedAt time.Time `json:"createdAt" bun:"created_at"` -} - -func (t Trigger) GetID() string { - return t.ID -} - -func NewTrigger(data TriggerData) (*Trigger, error) { - return &Trigger{ - TriggerData: data, - ID: uuid.NewString(), - CreatedAt: time.Now().Round(time.Microsecond).UTC(), - }, nil -} - -type Occurrence struct { - bun.BaseModel `bun:"triggers_occurrences"` - - ID string `json:"id" bun:"id,pk"` - TriggerID string `json:"triggerID" bun:"trigger_id"` - WorkflowInstanceID *string `json:"workflowInstanceID,omitempty" bun:"workflow_instance_id"` - WorkflowInstance *workflow.Instance `json:"workflowInstance,omitempty" bun:"rel:belongs-to,join:workflow_instance_id=id"` - Date time.Time `json:"date" bun:"date"` - Event publish.EventMessage `json:"event" bun:"event"` - Error *string `json:"error,omitempty" bun:"error"` -} - -func NewTriggerOccurrence(triggerID string, event publish.EventMessage, at time.Time) Occurrence { - return Occurrence{ - ID: uuid.NewString(), - TriggerID: triggerID, - Date: at, - Event: event, - } -} diff --git a/ee/orchestration/internal/triggers/trigger_test.go b/ee/orchestration/internal/triggers/trigger_test.go deleted file mode 100644 index 18b383ce5a..0000000000 --- a/ee/orchestration/internal/triggers/trigger_test.go +++ /dev/null @@ -1,177 +0,0 @@ -package triggers - -import ( - "math" - "net/http" - "net/http/httptest" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestFilters(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - object map[string]any - filter string - shouldBeOk bool - } - - testCases := []testCase{ - { - name: "nominal", - object: map[string]any{ - "a": map[string]any{ - "b": map[string]any{ - "c": 3, - }, - }, - }, - filter: "event.a.b.c == 3", - shouldBeOk: true, - }, - { - name: "comparison with $gt and float", - object: map[string]any{ - "a": map[string]any{ - "b": map[string]any{ - "c": math.Pi, - }, - }, - }, - filter: "event.a.b.c > 3", - shouldBeOk: true, - }, - { - name: "comparison with $lt and float", - object: map[string]any{ - "a": map[string]any{ - "b": map[string]any{ - "c": 3.14, - }, - }, - }, - filter: "event.a.b.c < 3.14", - }, - } - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - - e := NewExpressionEvaluator(http.DefaultClient) - - ok, err := e.evalFilter(tc.object, tc.filter) - require.NoError(t, err) - require.Equal(t, tc.shouldBeOk, ok) - }) - } -} - -func TestEvalVariables(t *testing.T) { - - type testCase struct { - name string - rawObject any - variables map[string]string - expectedResult map[string]string - } - - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{"data": {"role": "admin"}}`)) - })) - t.Cleanup(srv.Close) - - for _, testCase := range []testCase{ - { - name: "nominal", - rawObject: map[string]any{ - "metadata": map[string]any{ - "psp": "stripe", - }, - }, - variables: map[string]string{ - "psp": "event.metadata.psp", - }, - expectedResult: map[string]string{ - "psp": "stripe", - }, - }, - { - name: "using links", - rawObject: map[string]any{ - "links": []map[string]any{ - { - "name": "source_account", - "uri": srv.URL, - }, - }, - }, - variables: map[string]string{ - "role": `link(event, "source_account").role`, - }, - expectedResult: map[string]string{ - "role": "admin", - }, - }, - { - name: "using float", - rawObject: map[string]any{ - "amount": float64(1200000), - }, - variables: map[string]string{ - "amount": "event.amount", - }, - expectedResult: map[string]string{ - "amount": "1200000", - }, - }, - { - name: "using bool", - rawObject: map[string]any{ - "test": true, - }, - variables: map[string]string{ - "test": "event.test", - }, - expectedResult: map[string]string{ - "test": "true", - }, - }, - { - name: "using integer", - rawObject: map[string]any{ - "amount": int64(1200000), - }, - variables: map[string]string{ - "amount": "event.amount", - }, - expectedResult: map[string]string{ - "amount": "1200000", - }, - }, - { - name: "concat string", - rawObject: map[string]any{ - "foo": "XXX", - }, - variables: map[string]string{ - "ret": `event.foo + "-YYY"`, - }, - expectedResult: map[string]string{ - "ret": "XXX-YYY", - }, - }, - } { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - e := NewExpressionEvaluator(http.DefaultClient) - evaluated, err := e.evalVariables(testCase.rawObject, testCase.variables) - require.NoError(t, err) - require.Equal(t, testCase.expectedResult, evaluated) - }) - } -} diff --git a/ee/orchestration/internal/triggers/workflow_trigger.go b/ee/orchestration/internal/triggers/workflow_trigger.go deleted file mode 100644 index bc58b21c87..0000000000 --- a/ee/orchestration/internal/triggers/workflow_trigger.go +++ /dev/null @@ -1,140 +0,0 @@ -package triggers - -import ( - "time" - - "go.temporal.io/api/enums/v1" - - "github.com/formancehq/orchestration/internal/temporalworker" - - "github.com/formancehq/go-libs/pointer" - "github.com/formancehq/orchestration/internal/workflow" - - "github.com/formancehq/go-libs/publish" - temporalworkflow "go.temporal.io/sdk/workflow" -) - -const SearchAttributeTriggerID = "OrchestrationTriggerID" - -type ProcessEventRequest struct { - Event publish.EventMessage `json:"ledger"` -} - -type triggerWorkflow struct { - taskQueue string - includeSearchAttributes bool -} - -func (w triggerWorkflow) RunTrigger(ctx temporalworkflow.Context, req ProcessEventRequest) error { - - triggers := make([]Trigger, 0) - err := temporalworkflow.ExecuteActivity( - temporalworkflow.WithActivityOptions(ctx, temporalworkflow.ActivityOptions{ - StartToCloseTimeout: 10 * time.Second, - }), - ListTriggersActivity, - req, - ).Get(ctx, &triggers) - if err != nil { - return err - } - - for _, trigger := range triggers { - searchAttributes := map[string]any{} - if w.includeSearchAttributes { - searchAttributes[SearchAttributeTriggerID] = trigger.ID - } - - if err := temporalworkflow.ExecuteChildWorkflow( - temporalworkflow.WithChildOptions(ctx, temporalworkflow.ChildWorkflowOptions{ - TaskQueue: w.taskQueue, - ParentClosePolicy: enums.PARENT_CLOSE_POLICY_ABANDON, - SearchAttributes: searchAttributes, - }), - ExecuteTrigger, - req, - trigger).GetChildWorkflowExecution().Get(ctx, nil); err != nil { - return err - } - } - - return nil -} - -func (w triggerWorkflow) ExecuteTrigger(ctx temporalworkflow.Context, req ProcessEventRequest, trigger Trigger) error { - - vars := make(map[string]string) - occurrence := NewTriggerOccurrence(trigger.ID, req.Event, temporalworkflow.Now(ctx)) - err := temporalworkflow.ExecuteActivity( - temporalworkflow.WithActivityOptions(ctx, temporalworkflow.ActivityOptions{ - StartToCloseTimeout: 10 * time.Second, - }), - EvalTriggerVariables, - trigger, - req, - ).Get(ctx, &vars) - if err != nil { - occurrence.Error = pointer.For(err.Error()) - } else { - instance := &workflow.Instance{} - if err := temporalworkflow.ExecuteChildWorkflow( - temporalworkflow.WithChildOptions(ctx, temporalworkflow.ChildWorkflowOptions{ - TaskQueue: w.taskQueue, - }), - workflow.Initiate, - workflow.Input{ - Workflow: *trigger.Workflow, - Variables: vars, - }).Get(ctx, instance); err != nil { - return err - } - - occurrence.WorkflowInstanceID = pointer.For(instance.ID) - } - - err = temporalworkflow.ExecuteActivity( - temporalworkflow.WithActivityOptions(ctx, temporalworkflow.ActivityOptions{ - StartToCloseTimeout: 10 * time.Second, - }), - InsertTriggerOccurrence, - occurrence, - ).Get(ctx, nil) - if err != nil { - return err - } - - err = temporalworkflow.ExecuteActivity( - temporalworkflow.WithActivityOptions(ctx, temporalworkflow.ActivityOptions{ - StartToCloseTimeout: 10 * time.Second, - }), - SendEventForTriggerTermination, - occurrence, - ).Get(ctx, nil) - if err != nil { - return err - } - - return nil -} - -func (w triggerWorkflow) DefinitionSet() temporalworker.DefinitionSet { - return temporalworker.NewDefinitionSet(). - Append(temporalworker.Definition{ - Func: w.RunTrigger, - Name: "RunTrigger", - }). - Append(temporalworker.Definition{ - Func: w.ExecuteTrigger, - Name: "ExecuteTrigger", - }) -} - -func NewWorkflow(taskQueue string, includeSearchAttributes bool) *triggerWorkflow { - return &triggerWorkflow{ - taskQueue: taskQueue, - includeSearchAttributes: includeSearchAttributes, - } -} - -var ExecuteTrigger = triggerWorkflow{}.ExecuteTrigger -var RunTrigger = triggerWorkflow{}.RunTrigger diff --git a/ee/orchestration/internal/triggers/workflow_trigger_test.go b/ee/orchestration/internal/triggers/workflow_trigger_test.go deleted file mode 100644 index 98336f7f52..0000000000 --- a/ee/orchestration/internal/triggers/workflow_trigger_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package triggers - -import ( - "testing" - "time" - - worker "go.temporal.io/sdk/worker" - - "github.com/formancehq/go-libs/bun/bundebug" - "github.com/uptrace/bun" - - "github.com/formancehq/go-libs/bun/bunconnect" - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/orchestration/internal/storage" - "github.com/formancehq/orchestration/internal/temporalworker" - "github.com/formancehq/orchestration/internal/workflow" - "github.com/formancehq/orchestration/internal/workflow/stages" - "go.temporal.io/sdk/client" - - "github.com/formancehq/go-libs/publish" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestWorkflow(t *testing.T) { - t.Parallel() - - hooks := make([]bun.QueryHook, 0) - if testing.Verbose() { - hooks = append(hooks, bundebug.NewQueryHook()) - } - - database := srv.NewDatabase(t) - db, err := bunconnect.OpenSQLDB(logging.TestingContext(), bunconnect.ConnectionOptions{ - DatabaseSourceName: database.ConnString(), - }, hooks...) - require.NoError(t, err) - t.Cleanup(func() { - _ = db.Close() - }) - require.NoError(t, storage.Migrate(logging.TestingContext(), db)) - - taskQueue := uuid.NewString() - workflowManager := workflow.NewManager(db, devServer.Client(), taskQueue, false) - - worker := temporalworker.New(logging.Testing(), devServer.Client(), taskQueue, - []temporalworker.DefinitionSet{ - NewWorkflow(taskQueue, false).DefinitionSet(), - workflow.NewWorkflows(false).DefinitionSet(), - temporalworker.NewDefinitionSet().Append(temporalworker.Definition{ - Name: "NoOp", - Func: (&stages.NoOp{}).GetWorkflow(), - }), - }, - []temporalworker.DefinitionSet{ - workflow.NewActivities(publish.NoOpPublisher, db).DefinitionSet(), - NewActivities(db, workflowManager, NewDefaultExpressionEvaluator(), publish.NoOpPublisher).DefinitionSet(), - }, - worker.Options{}, - ) - require.NoError(t, worker.Start()) - t.Cleanup(worker.Stop) - - req := ProcessEventRequest{ - Event: publish.EventMessage{ - Type: "NEW_TRANSACTION", - Date: time.Now().Round(time.Second).UTC(), - }, - } - - workflow := workflow.New(workflow.Config{ - Stages: []workflow.RawStage{{ - "noop": map[string]any{}, - }}, - }) - _, err = db. - NewInsert(). - Model(&workflow). - Exec(logging.TestingContext()) - require.NoError(t, err) - - trigger := Trigger{ - TriggerData: TriggerData{ - Event: "NEW_TRANSACTION", - WorkflowID: workflow.ID, - }, - ID: uuid.NewString(), - } - _, err = db.NewInsert().Model(&trigger).Exec(logging.TestingContext()) - require.NoError(t, err) - - ret, err := devServer.Client(). - ExecuteWorkflow(logging.TestingContext(), client.StartWorkflowOptions{ - TaskQueue: taskQueue, - }, RunTrigger, req) - require.NoError(t, err) - require.NoError(t, ret.Get(logging.TestingContext(), nil)) -} diff --git a/ee/orchestration/internal/workflow/activities.go b/ee/orchestration/internal/workflow/activities.go deleted file mode 100644 index b06d487cec..0000000000 --- a/ee/orchestration/internal/workflow/activities.go +++ /dev/null @@ -1,153 +0,0 @@ -package workflow - -import ( - "context" - - "github.com/ThreeDotsLabs/watermill/message" - "github.com/formancehq/orchestration/internal/temporalworker" - "github.com/formancehq/orchestration/pkg/events" - "github.com/uptrace/bun" - "go.temporal.io/sdk/activity" -) - -type Activities struct { - publisher message.Publisher - db *bun.DB -} - -func (a Activities) SendWorkflowStartedEvent(ctx context.Context, instance Instance) error { - return a.publisher.Publish(events.TopicOrchestration, - events.NewMessage(ctx, events.StartedWorkflow, events.StartedWorkflowPayload{ - ID: instance.WorkflowID, - InstanceID: instance.ID, - })) -} - -func (a Activities) SendWorkflowTerminationEvent(ctx context.Context, instance Instance) error { - if instance.Error == "" { - return a.publisher.Publish(events.TopicOrchestration, - events.NewMessage(ctx, events.SucceededWorkflow, events.SucceededWorkflowPayload{ - ID: instance.WorkflowID, - InstanceID: instance.ID, - })) - } else { - return a.publisher.Publish(events.TopicOrchestration, - events.NewMessage(ctx, events.FailedWorkflow, events.FailedWorkflowPayload{ - ID: instance.WorkflowID, - InstanceID: instance.ID, - Error: instance.Error, - })) - } -} - -func (a Activities) SendWorkflowStageStartedEvent(ctx context.Context, instance Instance, stage Stage) error { - return a.publisher.Publish(events.TopicOrchestration, - events.NewMessage(ctx, events.StartedWorkflowStage, events.StartedWorkflowStagePayload{ - ID: instance.WorkflowID, - InstanceID: instance.ID, - Number: stage.Number, - })) -} - -func (a Activities) SendWorkflowStageTerminationEvent(ctx context.Context, instance Instance, stage Stage) error { - if stage.Error == nil { - return a.publisher.Publish(events.TopicOrchestration, - events.NewMessage(ctx, events.SucceededWorkflowStage, events.SucceededWorkflowStagePayload{ - ID: instance.WorkflowID, - InstanceID: instance.ID, - Number: stage.Number, - })) - } else { - return a.publisher.Publish(events.TopicOrchestration, - events.NewMessage(ctx, events.FailedWorkflowStage, events.FailedWorkflowStagePayload{ - ID: instance.WorkflowID, - InstanceID: instance.ID, - Number: stage.Number, - Error: *stage.Error, - })) - } -} - -func (a Activities) InsertNewInstance(ctx context.Context, workflowID string) (*Instance, error) { - instance := NewInstance(activity.GetInfo(ctx).WorkflowExecution.ID, workflowID) - if _, err := a.db. - NewInsert(). - Model(&instance). - Exec(ctx); err != nil { - return nil, err - } - - return &instance, nil -} - -func (a Activities) UpdateInstance(ctx context.Context, instance *Instance) error { - _, dbErr := a.db.NewUpdate(). - Model(instance). - WherePK(). - Exec(ctx) - return dbErr -} - -func (a Activities) InsertNewStage(ctx context.Context, instance Instance, ind int) (*Stage, error) { - stage := NewStage(instance.ID, activity.GetInfo(ctx).WorkflowExecution.RunID, ind) - if _, err := a.db.NewInsert(). - Model(&stage). - Exec(ctx); err != nil { - return nil, err - } - - return &stage, nil -} - -func (a Activities) UpdateStage(ctx context.Context, stage Stage) error { - _, err := a.db.NewUpdate(). - Model(&stage). - WherePK(). - Exec(ctx) - return err -} - -func (a Activities) DefinitionSet() temporalworker.DefinitionSet { - return temporalworker.NewDefinitionSet(). - Append(temporalworker.Definition{ - Func: a.InsertNewInstance, - Name: "InsertNewInstance", - }).Append(temporalworker.Definition{ - Func: a.InsertNewStage, - Name: "InsertNewStage", - }).Append(temporalworker.Definition{ - Func: a.SendWorkflowStageStartedEvent, - Name: "SendWorkflowStageStartedEvent", - }).Append(temporalworker.Definition{ - Func: a.SendWorkflowStageTerminationEvent, - Name: "SendWorkflowStageTerminationEvent", - }).Append(temporalworker.Definition{ - Func: a.SendWorkflowStartedEvent, - Name: "SendWorkflowStartedEvent", - }).Append(temporalworker.Definition{ - Func: a.SendWorkflowTerminationEvent, - Name: "SendWorkflowTerminationEvent", - }).Append(temporalworker.Definition{ - Func: a.UpdateStage, - Name: "UpdateStage", - }).Append(temporalworker.Definition{ - Func: a.UpdateInstance, - Name: "UpdateInstance", - }) -} - -var SendWorkflowTerminationEventActivity = Activities{}.SendWorkflowTerminationEvent -var SendWorkflowStartedEventActivity = Activities{}.SendWorkflowStartedEvent -var SendWorkflowStageStartedEventActivity = Activities{}.SendWorkflowStageStartedEvent -var SendWorkflowStageTerminationEventActivity = Activities{}.SendWorkflowStageTerminationEvent -var InsertNewInstanceActivity = Activities{}.InsertNewInstance -var UpdateInstanceActivity = Activities{}.UpdateInstance -var InsertNewStageActivity = Activities{}.InsertNewStage -var UpdateStageActivity = Activities{}.UpdateStage - -func NewActivities(publisher message.Publisher, db *bun.DB) Activities { - return Activities{ - publisher: publisher, - db: db, - } -} diff --git a/ee/orchestration/internal/workflow/activities/activity.go b/ee/orchestration/internal/workflow/activities/activity.go deleted file mode 100644 index 1e035bf30b..0000000000 --- a/ee/orchestration/internal/workflow/activities/activity.go +++ /dev/null @@ -1,88 +0,0 @@ -package activities - -import ( - "context" - "fmt" - - sdk "github.com/formancehq/formance-sdk-go/v2" - "github.com/formancehq/go-libs/pointer" - "github.com/formancehq/orchestration/internal/temporalworker" - "github.com/pkg/errors" - "go.temporal.io/sdk/activity" - "go.temporal.io/sdk/temporal" - "go.temporal.io/sdk/workflow" -) - -type Activities struct { - client *sdk.Formance -} - -func (a Activities) DefinitionSet() temporalworker.DefinitionSet { - return temporalworker.NewDefinitionSet(). - Append(temporalworker.Definition{ - Name: "GetAccount", - Func: a.GetAccount, - }). - Append(temporalworker.Definition{ - Name: "AddAccountMetadata", - Func: a.AddAccountMetadata, - }). - Append(temporalworker.Definition{ - Name: "CreateTransaction", - Func: a.CreateTransaction, - }). - Append(temporalworker.Definition{ - Name: "StripeTransfer", - Func: a.StripeTransfer, - }). - Append(temporalworker.Definition{ - Name: "GetPayment", - Func: a.GetPayment, - }). - Append(temporalworker.Definition{ - Name: "ConfirmHold", - Func: a.ConfirmHold, - }). - Append(temporalworker.Definition{ - Name: "CreditWallet", - Func: a.CreditWallet, - }). - Append(temporalworker.Definition{ - Name: "DebitWallet", - Func: a.DebitWallet, - }). - Append(temporalworker.Definition{ - Name: "GetWallet", - Func: a.GetWallet, - }). - Append(temporalworker.Definition{ - Name: "ListWallets", - Func: a.ListWallets, - }). - Append(temporalworker.Definition{ - Name: "VoidHold", - Func: a.VoidHold, - }) -} - -func New(client *sdk.Formance) Activities { - return Activities{ - client: client, - } -} - -func executeActivity(ctx workflow.Context, activity any, ret any, request any) error { - if err := workflow.ExecuteActivity(ctx, activity, request).Get(ctx, ret); err != nil { - var timeoutError *temporal.TimeoutError - if errors.As(err, &timeoutError) { - return errors.New(timeoutError.Message()) - } - return err - } - return nil -} - -func getIK(ctx context.Context) *string { - activityInfo := activity.GetInfo(ctx) - return pointer.For(fmt.Sprintf("%s-%s", activityInfo.WorkflowExecution.RunID, activityInfo.ActivityID)) -} diff --git a/ee/orchestration/internal/workflow/activities/activity_account_get.go b/ee/orchestration/internal/workflow/activities/activity_account_get.go deleted file mode 100644 index d9f7bfaff0..0000000000 --- a/ee/orchestration/internal/workflow/activities/activity_account_get.go +++ /dev/null @@ -1,49 +0,0 @@ -package activities - -import ( - "context" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "go.temporal.io/sdk/temporal" - "go.temporal.io/sdk/workflow" -) - -type GetAccountRequest struct { - Ledger string `json:"ledger"` - ID string `json:"id"` -} - -func (a Activities) GetAccount(ctx context.Context, request GetAccountRequest) (*shared.AccountResponse, error) { - response, err := a.client.Ledger.V1.GetAccount( - ctx, - operations.GetAccountRequest{ - Address: request.ID, - Ledger: request.Ledger, - }, - ) - if err != nil { - switch err := err.(type) { - case *sdkerrors.ErrorResponse: - return nil, temporal.NewApplicationError(err.ErrorMessage, string(err.ErrorCode), err.Details) - default: - return nil, err - } - } - - return response.AccountResponse, nil -} - -var GetAccountActivity = Activities{}.GetAccount - -func GetAccount(ctx workflow.Context, ledger, id string) (*shared.AccountWithVolumesAndBalances, error) { - ret := &shared.AccountResponse{} - if err := executeActivity(ctx, GetAccountActivity, ret, GetAccountRequest{ - Ledger: ledger, - ID: id, - }); err != nil { - return nil, err - } - return &ret.Data, nil -} diff --git a/ee/orchestration/internal/workflow/activities/activity_ledger_add_account_metadata.go b/ee/orchestration/internal/workflow/activities/activity_ledger_add_account_metadata.go deleted file mode 100644 index 15ab303fae..0000000000 --- a/ee/orchestration/internal/workflow/activities/activity_ledger_add_account_metadata.go +++ /dev/null @@ -1,44 +0,0 @@ -package activities - -import ( - "context" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - "go.temporal.io/sdk/temporal" - "go.temporal.io/sdk/workflow" -) - -type AddAccountMetadataRequest struct { - Ledger string `json:"ledger"` - Account string `json:"account"` - Metadata map[string]string `json:"metadata"` -} - -func (a Activities) AddAccountMetadata(ctx context.Context, request AddAccountMetadataRequest) error { - _, err := a.client.Ledger.V2.AddMetadataToAccount( - ctx, - operations.V2AddMetadataToAccountRequest{ - RequestBody: request.Metadata, - Address: request.Account, - Ledger: request.Ledger, - IdempotencyKey: getIK(ctx), - }, - ) - if err != nil { - switch err := err.(type) { - case *sdkerrors.V2ErrorResponse: - return temporal.NewApplicationError(err.ErrorMessage, string(err.ErrorCode), err.Details) - default: - return err - } - } - - return nil -} - -var AddAccountMetadataActivity = Activities{}.AddAccountMetadata - -func AddAccountMetadata(ctx workflow.Context, request AddAccountMetadataRequest) error { - return executeActivity(ctx, AddAccountMetadataActivity, nil, request) -} diff --git a/ee/orchestration/internal/workflow/activities/activity_ledger_create_transaction.go b/ee/orchestration/internal/workflow/activities/activity_ledger_create_transaction.go deleted file mode 100644 index a6a2735623..0000000000 --- a/ee/orchestration/internal/workflow/activities/activity_ledger_create_transaction.go +++ /dev/null @@ -1,78 +0,0 @@ -package activities - -import ( - "context" - stdtime "time" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - "github.com/formancehq/go-libs/time" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "go.temporal.io/sdk/temporal" - "go.temporal.io/sdk/workflow" -) - -// CreateTransactionResponse - OK -type CreateTransactionResponse struct { - Data []shared.Transaction `json:"data"` -} - -type CreateTransactionRequest struct { - Ledger string `pathParam:"style=simple,explode=false,name=ledger"` - Data PostTransaction `request:"mediaType=application/json"` -} - -type PostTransaction struct { - Metadata map[string]string `json:"metadata,omitempty"` - Postings []shared.V2Posting `json:"postings,omitempty"` - Reference *string `json:"reference,omitempty"` - Script *shared.V2PostTransactionScript `json:"script,omitempty"` - Timestamp *time.Time `json:"timestamp,omitempty"` -} - -func (a Activities) CreateTransaction(ctx context.Context, request CreateTransactionRequest) (*shared.V2CreateTransactionResponse, error) { - - response, err := a.client.Ledger.V2.CreateTransaction( - ctx, - operations.V2CreateTransactionRequest{ - V2PostTransaction: shared.V2PostTransaction{ - Metadata: request.Data.Metadata, - Postings: request.Data.Postings, - Reference: request.Data.Reference, - Script: request.Data.Script, - Timestamp: func() *stdtime.Time { - if request.Data.Timestamp == nil { - return nil - } - return &request.Data.Timestamp.Time - }(), - }, - Ledger: request.Ledger, - IdempotencyKey: getIK(ctx), - }, - ) - if err != nil { - switch err := err.(type) { - case *sdkerrors.V2ErrorResponse: - return nil, temporal.NewApplicationError(err.ErrorMessage, string(err.ErrorCode), err.Details) - default: - return nil, err - } - } - - return response.V2CreateTransactionResponse, nil -} - -var CreateTransactionActivity = Activities{}.CreateTransaction - -func CreateTransaction(ctx workflow.Context, ledger string, request PostTransaction) (*shared.V2Transaction, error) { - tx := &shared.V2CreateTransactionResponse{} - if err := executeActivity(ctx, CreateTransactionActivity, tx, CreateTransactionRequest{ - Ledger: ledger, - Data: request, - }); err != nil { - return nil, err - } - return &tx.Data, nil -} diff --git a/ee/orchestration/internal/workflow/activities/activity_payment_stripe_transfer.go b/ee/orchestration/internal/workflow/activities/activity_payment_stripe_transfer.go deleted file mode 100644 index 816a154a95..0000000000 --- a/ee/orchestration/internal/workflow/activities/activity_payment_stripe_transfer.go +++ /dev/null @@ -1,56 +0,0 @@ -package activities - -import ( - "context" - "math/big" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "go.temporal.io/sdk/activity" - "go.temporal.io/sdk/workflow" -) - -type StripeTransferRequest struct { - Amount *big.Int `json:"amount,omitempty"` - Asset *string `json:"asset,omitempty"` - ConnectorID *string `json:"connectorID,omitempty"` - Destination *string `json:"destination,omitempty"` - // A set of key/value pairs that you can attach to a transfer object. - // It can be useful for storing additional information about the transfer in a structured format. - // - Metadata map[string]string `json:"metadata"` - WaitingValidation *bool `default:"false" json:"waitingValidation"` -} - -func (a Activities) StripeTransfer(ctx context.Context, request StripeTransferRequest) error { - validated := true - if request.WaitingValidation != nil && *request.WaitingValidation { - validated = false - } - - activityInfo := activity.GetInfo(ctx) - provider := shared.ConnectorStripe - ti := shared.TransferInitiationRequest{ - Amount: request.Amount, - Asset: *request.Asset, - DestinationAccountID: *request.Destination, - Description: "Stripe Transfer", - ConnectorID: request.ConnectorID, - Provider: &provider, - Type: shared.TransferInitiationRequestTypeTransfer, - Reference: activityInfo.WorkflowExecution.ID + activityInfo.ActivityID, - Validated: validated, - } - - _, err := a.client.Payments.V1.CreateTransferInitiation(ctx, ti) - if err != nil { - return err - } - - return nil -} - -var StripeTransferActivity = Activities{}.StripeTransfer - -func StripeTransfer(ctx workflow.Context, request StripeTransferRequest) error { - return executeActivity(ctx, StripeTransferActivity, nil, request) -} diff --git a/ee/orchestration/internal/workflow/activities/activity_payments_get.go b/ee/orchestration/internal/workflow/activities/activity_payments_get.go deleted file mode 100644 index 1d579594b7..0000000000 --- a/ee/orchestration/internal/workflow/activities/activity_payments_get.go +++ /dev/null @@ -1,39 +0,0 @@ -package activities - -import ( - "context" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "go.temporal.io/sdk/workflow" -) - -type GetPaymentRequest struct { - ID string `json:"id"` -} - -func (a Activities) GetPayment(ctx context.Context, request GetPaymentRequest) (*shared.PaymentResponse, error) { - response, err := a.client.Payments.V1.GetPayment( - ctx, - operations.GetPaymentRequest{ - PaymentID: request.ID, - }, - ) - if err != nil { - return nil, err - } - - return response.PaymentResponse, nil -} - -var GetPaymentActivity = Activities{}.GetPayment - -func GetPayment(ctx workflow.Context, id string) (*shared.Payment, error) { - ret := &shared.PaymentResponse{} - if err := executeActivity(ctx, GetPaymentActivity, ret, GetPaymentRequest{ - ID: id, - }); err != nil { - return nil, err - } - return &ret.Data, nil -} diff --git a/ee/orchestration/internal/workflow/activities/activity_wallet_confirm_hold.go b/ee/orchestration/internal/workflow/activities/activity_wallet_confirm_hold.go deleted file mode 100644 index c325ef9e24..0000000000 --- a/ee/orchestration/internal/workflow/activities/activity_wallet_confirm_hold.go +++ /dev/null @@ -1,44 +0,0 @@ -package activities - -import ( - "context" - "fmt" - "net/http" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "go.temporal.io/sdk/workflow" -) - -type ConfirmHoldRequest struct { - ID string `json:"id"` -} - -func (a Activities) ConfirmHold(ctx context.Context, request ConfirmHoldRequest) error { - response, err := a.client.Wallets.V1.ConfirmHold( - ctx, - operations.ConfirmHoldRequest{ - ConfirmHoldRequest: &shared.ConfirmHoldRequest{}, - HoldID: request.ID, - IdempotencyKey: getIK(ctx), - }, - ) - if err != nil { - return err - } - - switch response.StatusCode { - case http.StatusNoContent: - return nil - default: - return fmt.Errorf("unexpected status code: %d", response.StatusCode) - } -} - -var ConfirmHoldActivity = Activities{}.ConfirmHold - -func ConfirmHold(ctx workflow.Context, id string) error { - return executeActivity(ctx, ConfirmHoldActivity, nil, ConfirmHoldRequest{ - ID: id, - }) -} diff --git a/ee/orchestration/internal/workflow/activities/activity_wallet_credit.go b/ee/orchestration/internal/workflow/activities/activity_wallet_credit.go deleted file mode 100644 index 2b0b7f2abf..0000000000 --- a/ee/orchestration/internal/workflow/activities/activity_wallet_credit.go +++ /dev/null @@ -1,65 +0,0 @@ -package activities - -import ( - "context" - stdtime "time" - - "github.com/formancehq/go-libs/time" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "go.temporal.io/sdk/workflow" -) - -type CreditWalletRequest struct { - ID string `json:"id"` - Data *CreditWalletRequestPayload `json:"data"` -} - -type CreditWalletRequestPayload struct { - Amount shared.Monetary `json:"amount"` - // The balance to credit - Balance *string `json:"balance,omitempty"` - // Metadata associated with the wallet. - Metadata map[string]string `json:"metadata"` - Reference *string `json:"reference,omitempty"` - Sources []shared.Subject `json:"sources"` - Timestamp *time.Time `json:"timestamp,omitempty"` -} - -func (a Activities) CreditWallet(ctx context.Context, request CreditWalletRequest) error { - _, err := a.client.Wallets.V1.CreditWallet( - ctx, - operations.CreditWalletRequest{ - CreditWalletRequest: &shared.CreditWalletRequest{ - Amount: request.Data.Amount, - Balance: request.Data.Balance, - Metadata: request.Data.Metadata, - Reference: request.Data.Reference, - Sources: request.Data.Sources, - Timestamp: func() *stdtime.Time { - if request.Data.Timestamp == nil { - return nil - } - return &request.Data.Timestamp.Time - }(), - }, - ID: request.ID, - IdempotencyKey: getIK(ctx), - }, - ) - if err != nil { - return err - } - - return nil -} - -var CreditWalletActivity = Activities{}.CreditWallet - -func CreditWallet(ctx workflow.Context, id string, request *CreditWalletRequestPayload) error { - return executeActivity(ctx, CreditWalletActivity, nil, CreditWalletRequest{ - ID: id, - Data: request, - }) -} diff --git a/ee/orchestration/internal/workflow/activities/activity_wallet_debit.go b/ee/orchestration/internal/workflow/activities/activity_wallet_debit.go deleted file mode 100644 index 06651951e4..0000000000 --- a/ee/orchestration/internal/workflow/activities/activity_wallet_debit.go +++ /dev/null @@ -1,80 +0,0 @@ -package activities - -import ( - "context" - stdtime "time" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - "github.com/pkg/errors" - - "github.com/formancehq/go-libs/time" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "go.temporal.io/sdk/temporal" - "go.temporal.io/sdk/workflow" -) - -type DebitWalletRequest struct { - ID string `json:"id"` - Data *DebitWalletRequestPayload `json:"data"` -} - -type DebitWalletRequestPayload struct { - Amount shared.Monetary `json:"amount"` - Balances []string `json:"balances,omitempty"` - Description *string `json:"description,omitempty"` - Destination *shared.Subject `json:"destination,omitempty"` - // Metadata associated with the wallet. - Metadata map[string]string `json:"metadata"` - // Set to true to create a pending hold. If false, the wallet will be debited immediately. - Pending *bool `json:"pending,omitempty"` - // cannot be used in conjunction with `pending` property - Timestamp *time.Time `json:"timestamp,omitempty"` -} - -func (a Activities) DebitWallet(ctx context.Context, request DebitWalletRequest) (*shared.DebitWalletResponse, error) { - response, err := a.client.Wallets.V1.DebitWallet( - ctx, - operations.DebitWalletRequest{ - DebitWalletRequest: &shared.DebitWalletRequest{ - Amount: request.Data.Amount, - Balances: request.Data.Balances, - Description: request.Data.Description, - Destination: request.Data.Destination, - Metadata: request.Data.Metadata, - Pending: request.Data.Pending, - Timestamp: func() *stdtime.Time { - if request.Data.Timestamp == nil { - return nil - } - return &request.Data.Timestamp.Time - }(), - }, - ID: request.ID, - IdempotencyKey: getIK(ctx), - }, - ) - if err != nil { - walletErrorResponse := &sdkerrors.WalletsErrorResponse{} - if errors.As(err, &walletErrorResponse) { - return nil, temporal.NewApplicationError(walletErrorResponse.ErrorMessage, string(walletErrorResponse.ErrorCode)) - } - return nil, err - } - - return response.DebitWalletResponse, nil -} - -var DebitWalletActivity = Activities{}.DebitWallet - -func DebitWallet(ctx workflow.Context, id string, request *DebitWalletRequestPayload) (*shared.Hold, error) { - ret := &shared.DebitWalletResponse{} - if err := executeActivity(ctx, DebitWalletActivity, ret, DebitWalletRequest{ - ID: id, - Data: request, - }); err != nil { - return nil, err - } - return &ret.Data, nil -} diff --git a/ee/orchestration/internal/workflow/activities/activity_wallet_get.go b/ee/orchestration/internal/workflow/activities/activity_wallet_get.go deleted file mode 100644 index b9a72f990b..0000000000 --- a/ee/orchestration/internal/workflow/activities/activity_wallet_get.go +++ /dev/null @@ -1,39 +0,0 @@ -package activities - -import ( - "context" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "go.temporal.io/sdk/workflow" -) - -type GetWalletRequest struct { - ID string `json:"id"` -} - -func (a Activities) GetWallet(ctx context.Context, request GetWalletRequest) (*shared.GetWalletResponse, error) { - response, err := a.client.Wallets.V1.GetWallet( - ctx, - operations.GetWalletRequest{ - ID: request.ID, - }, - ) - if err != nil { - return nil, err - } - - return response.GetWalletResponse, nil -} - -var GetWalletActivity = Activities{}.GetWallet - -func GetWallet(ctx workflow.Context, id string) (*shared.WalletWithBalances, error) { - ret := &shared.GetWalletResponse{} - if err := executeActivity(ctx, GetWalletActivity, ret, GetWalletRequest{ - ID: id, - }); err != nil { - return nil, err - } - return &ret.Data, nil -} diff --git a/ee/orchestration/internal/workflow/activities/activity_wallet_list.go b/ee/orchestration/internal/workflow/activities/activity_wallet_list.go deleted file mode 100644 index 0bd8a1bb51..0000000000 --- a/ee/orchestration/internal/workflow/activities/activity_wallet_list.go +++ /dev/null @@ -1,39 +0,0 @@ -package activities - -import ( - "context" - - "github.com/formancehq/go-libs/pointer" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "go.temporal.io/sdk/workflow" -) - -type ListWalletsRequest struct { - Name string `json:"name"` -} - -func (a Activities) ListWallets(ctx context.Context, request ListWalletsRequest) (*shared.ListWalletsResponse, error) { - response, err := a.client.Wallets.V1.ListWallets( - ctx, - operations.ListWalletsRequest{ - Name: pointer.For(request.Name), - }, - ) - if err != nil { - return nil, err - } - - return response.ListWalletsResponse, nil -} - -var ListWalletsActivity = Activities{}.ListWallets - -func ListWallets(ctx workflow.Context, request ListWalletsRequest) (*shared.ListWalletsResponse, error) { - ret := &shared.ListWalletsResponse{} - if err := executeActivity(ctx, ListWalletsActivity, ret, request); err != nil { - return nil, err - } - return ret, nil -} diff --git a/ee/orchestration/internal/workflow/activities/activity_wallet_void_hold.go b/ee/orchestration/internal/workflow/activities/activity_wallet_void_hold.go deleted file mode 100644 index 56a8a0031e..0000000000 --- a/ee/orchestration/internal/workflow/activities/activity_wallet_void_hold.go +++ /dev/null @@ -1,35 +0,0 @@ -package activities - -import ( - "context" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "go.temporal.io/sdk/workflow" -) - -type VoidHoldRequest struct { - ID string `json:"id"` -} - -func (a Activities) VoidHold(ctx context.Context, request VoidHoldRequest) error { - _, err := a.client.Wallets.V1.VoidHold( - ctx, - operations.VoidHoldRequest{ - HoldID: request.ID, - IdempotencyKey: getIK(ctx), - }, - ) - if err != nil { - return err - } - - return nil -} - -var VoidHoldActivity = Activities{}.VoidHold - -func VoidHold(ctx workflow.Context, id string) error { - return executeActivity(ctx, VoidHoldActivity, nil, VoidHoldRequest{ - ID: id, - }) -} diff --git a/ee/orchestration/internal/workflow/activities_test.go b/ee/orchestration/internal/workflow/activities_test.go deleted file mode 100644 index 31c913a9b5..0000000000 --- a/ee/orchestration/internal/workflow/activities_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package workflow - -import ( - "testing" - - "github.com/formancehq/go-libs/bun/bundebug" - "github.com/uptrace/bun" - - "github.com/formancehq/go-libs/bun/bunconnect" - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/go-libs/publish" - "github.com/stretchr/testify/require" - "go.temporal.io/sdk/testsuite" -) - -func TestActivities(t *testing.T) { - - hooks := make([]bun.QueryHook, 0) - if testing.Verbose() { - hooks = append(hooks, bundebug.NewQueryHook()) - } - - database := srv.NewDatabase(t) - db, err := bunconnect.OpenSQLDB(logging.TestingContext(), bunconnect.ConnectionOptions{ - DatabaseSourceName: database.ConnString(), - }, hooks...) - require.NoError(t, err) - t.Cleanup(func() { - _ = db.Close() - }) - - publisher := publish.InMemory() - activities := NewActivities(publisher, db) - - testSuite := &testsuite.WorkflowTestSuite{} - env := testSuite.NewTestActivityEnvironment() - env.RegisterActivity(activities.SendWorkflowTerminationEvent) - _, err = env.ExecuteActivity(SendWorkflowTerminationEventActivity, NewInstance("vvv", "xxx")) - require.NoError(t, err) - require.NotEmpty(t, publisher.AllMessages()) -} diff --git a/ee/orchestration/internal/workflow/config.go b/ee/orchestration/internal/workflow/config.go deleted file mode 100644 index 90b0b9ba0d..0000000000 --- a/ee/orchestration/internal/workflow/config.go +++ /dev/null @@ -1,133 +0,0 @@ -package workflow - -import ( - "fmt" - "time" - - "github.com/formancehq/orchestration/internal/schema" - "github.com/pkg/errors" - "go.temporal.io/sdk/temporal" - "go.temporal.io/sdk/workflow" -) - -type RawStage map[string]map[string]any - -type Config struct { - Name string `json:"name"` - Stages []RawStage `json:"stages"` -} - -func (c *Config) runStage(ctx workflow.Context, s Stage, stage RawStage, variables map[string]string) (err error) { - var ( - name string - value map[string]any - ) - for name, value = range stage { - } - - stageSchema, err := schema.Resolve(schema.Context{ - Variables: variables, - }, value, name) - if err != nil { - return err - } - - if err := schema.ValidateRequirements(stageSchema); err != nil { - return err - } - - err = workflow.ExecuteChildWorkflow( - workflow.WithChildOptions(ctx, workflow.ChildWorkflowOptions{ - WorkflowID: s.TemporalWorkflowID(), - }), - stageSchema.GetWorkflow(), - stageSchema, - ).Get(ctx, nil) - if err != nil { - var appError *temporal.ApplicationError - if errors.As(err, &appError) { - return errors.New(appError.Message()) - } - var canceledError *temporal.CanceledError - if errors.As(err, &canceledError) { - return canceledError - } - return err - } - - return nil -} - -func (c *Config) run(ctx workflow.Context, instance Instance, variables map[string]string) (err error) { - - logger := workflow.GetLogger(ctx) - for ind, rawStage := range c.Stages { - logger.Info("run stage", "index", ind, "workflowID", instance.ID) - - stage := Stage{} - err := workflow.ExecuteActivity(workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ - StartToCloseTimeout: 10 * time.Second, - }), InsertNewStageActivity, instance, ind).Get(ctx, &stage) - if err != nil { - return err - } - - err = workflow.ExecuteActivity(workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ - StartToCloseTimeout: 10 * time.Second, - }), SendWorkflowStageStartedEventActivity, instance, stage).Get(ctx, nil) - if err != nil { - return err - } - - runError := c.runStage(ctx, stage, rawStage, variables) - if runError != nil { - logger.Debug("error running stage", "error", runError) - } - stage.SetTerminated(runError, workflow.Now(ctx).Round(time.Nanosecond)) - - err = workflow.ExecuteActivity(workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ - StartToCloseTimeout: 10 * time.Second, - }), UpdateStageActivity, stage).Get(ctx, nil) - if err != nil { - return err - } - - err = workflow.ExecuteActivity(workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ - StartToCloseTimeout: 10 * time.Second, - }), SendWorkflowStageTerminationEventActivity, instance, stage).Get(ctx, nil) - if err != nil { - return err - } - - logger.Info("stage terminated", "index", ind, "workflowID", stage.InstanceID) - - if runError != nil { - return runError - } - } - - return nil -} - -func (c *Config) Validate() error { - for _, rawStage := range c.Stages { - if len(rawStage) == 0 { - return fmt.Errorf("empty specification") - } - if len(rawStage) > 1 { - return fmt.Errorf("a specification should have only one name") - } - var ( - name string - value map[string]any - ) - for name, value = range rawStage { - } - - _, err := schema.Resolve(schema.Context{}, value, name) - if err != nil { - return err - } - } - return nil -} diff --git a/ee/orchestration/internal/workflow/input.go b/ee/orchestration/internal/workflow/input.go deleted file mode 100644 index 67e6dcc89e..0000000000 --- a/ee/orchestration/internal/workflow/input.go +++ /dev/null @@ -1,6 +0,0 @@ -package workflow - -type Input struct { - Workflow Workflow `json:"workflow"` - Variables map[string]string `json:"variables"` -} diff --git a/ee/orchestration/internal/workflow/instance.go b/ee/orchestration/internal/workflow/instance.go deleted file mode 100644 index 09236ec0ee..0000000000 --- a/ee/orchestration/internal/workflow/instance.go +++ /dev/null @@ -1,41 +0,0 @@ -package workflow - -import ( - "time" - - "github.com/uptrace/bun" -) - -type Instance struct { - bun.BaseModel `bun:"table:workflow_instances,alias:u"` - WorkflowID string `json:"workflowID"` - ID string `json:"id" bun:"id,pk"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - Terminated bool `json:"terminated"` - TerminatedAt *time.Time `json:"terminatedAt,omitempty"` - //TODO: change JSON tag from status to statuses - Statuses []Stage `json:"status,omitempty" bun:"rel:has-many,join:id=instance_id"` - Error string `json:"error,omitempty"` -} - -func (i *Instance) SetTerminated(at time.Time) { - i.Terminated = true - i.TerminatedAt = &at -} - -func (i *Instance) SetTerminatedWithError(at time.Time, err error) { - i.SetTerminated(at) - i.Error = err.Error() -} - -func NewInstance(id, workflowID string) Instance { - now := time.Now().Round(time.Nanosecond) - return Instance{ - BaseModel: bun.BaseModel{}, - WorkflowID: workflowID, - ID: id, - CreatedAt: now, - UpdatedAt: now, - } -} diff --git a/ee/orchestration/internal/workflow/main_test.go b/ee/orchestration/internal/workflow/main_test.go deleted file mode 100644 index 7f6af1fb90..0000000000 --- a/ee/orchestration/internal/workflow/main_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package workflow - -import ( - "context" - "testing" - - "github.com/formancehq/go-libs/testing/docker" - "github.com/formancehq/go-libs/testing/utils" - "github.com/stretchr/testify/require" - - "github.com/formancehq/go-libs/logging" - "go.temporal.io/sdk/testsuite" - - "github.com/formancehq/go-libs/testing/platform/pgtesting" -) - -var ( - srv *pgtesting.PostgresServer - devServer *testsuite.DevServer -) - -func TestMain(m *testing.M) { - utils.WithTestMain(func(t *utils.TestingTForMain) int { - srv = pgtesting.CreatePostgresServer(t, docker.NewPool(t, logging.Testing())) - - var err error - devServer, err = testsuite.StartDevServer(context.Background(), testsuite.DevServerOptions{}) - require.NoError(t, err) - - t.Cleanup(func() { - require.NoError(t, devServer.Stop()) - }) - - return m.Run() - }) -} diff --git a/ee/orchestration/internal/workflow/manager.go b/ee/orchestration/internal/workflow/manager.go deleted file mode 100644 index a1c3222bca..0000000000 --- a/ee/orchestration/internal/workflow/manager.go +++ /dev/null @@ -1,400 +0,0 @@ -package workflow - -import ( - "context" - "database/sql" - "encoding/json" - "fmt" - "time" - - "github.com/formancehq/go-libs/pointer" - - enums "go.temporal.io/api/enums/v1" - history "go.temporal.io/api/history/v1" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/pkg/errors" - "github.com/uptrace/bun" - "go.temporal.io/api/serviceerror" - "go.temporal.io/sdk/client" -) - -var ( - ErrInstanceNotFound = errors.New("Instance not found") - ErrWorkflowNotFound = errors.New("Workflow not found") -) - -const ( - EventSignalName = "event" -) - -type Event struct { - Name string `json:"name"` -} - -type WorkflowManager struct { - db *bun.DB - temporalClient client.Client - taskQueue string - includeSearchAttributes bool -} - -func (m *WorkflowManager) Create(ctx context.Context, config Config) (*Workflow, error) { - - if err := config.Validate(); err != nil { - return nil, err - } - - workflow := New(config) - - if _, err := m.db. - NewInsert(). - Model(&workflow). - Exec(ctx); err != nil { - return nil, err - } - - return &workflow, nil -} - -func (m *WorkflowManager) DeleteWorkflow(ctx context.Context, id string) error { - - var workflow Workflow - - res, err := m.db.NewUpdate().Model(&workflow).Where("id = ?", id).Set("deleted_at = ?", time.Now()).Exec(ctx) - - if err != nil { - return err - } - - r, err := res.RowsAffected() - if err != nil { - return err - } - if r == 0 { - return ErrWorkflowNotFound - } - - return nil -} - -func (m *WorkflowManager) RunWorkflow(ctx context.Context, id string, variables map[string]string) (*Instance, error) { - - workflow := Workflow{} - if err := m.db.NewSelect(). - Where("id = ?", id). - Model(&workflow). - Scan(ctx); err != nil { - return nil, err - } - - searchAttributes := map[string]any{} - if m.includeSearchAttributes { - searchAttributes["OrchestrationWorkflowID"] = workflow.ID - } - - run, err := m.temporalClient.ExecuteWorkflow(ctx, client.StartWorkflowOptions{ - TaskQueue: m.taskQueue, - SearchAttributes: searchAttributes, - }, Initiate, Input{ - Workflow: workflow, - Variables: variables, - }) - if err != nil { - return nil, err - } - - instance := &Instance{} - if err := run.Get(ctx, instance); err != nil { - return nil, err - } - - return instance, nil -} - -func (m *WorkflowManager) Wait(ctx context.Context, instanceID string) error { - if err := m.temporalClient. - GetWorkflow(ctx, instanceID, ""). - Get(ctx, nil); err != nil { - if errors.Is(err, &serviceerror.NotFound{}) { - return ErrInstanceNotFound - } - return errors.Unwrap(err) - } - return nil -} - -func (m *WorkflowManager) ListWorkflows(ctx context.Context, query bunpaginate.OffsetPaginatedQuery[any]) (*bunpaginate.Cursor[Workflow], error) { - sb := m.db.NewSelect() - - return bunpaginate.UsingOffset[any, Workflow](ctx, sb, query, - func(query *bun.SelectQuery) *bun.SelectQuery { - return query.Where("deleted_at IS NULL") - }) -} - -func (m *WorkflowManager) ReadWorkflow(ctx context.Context, id string) (Workflow, error) { - var workflow Workflow - if err := m.db.NewSelect(). - Model(&workflow). - Where("id = ?", id). - Scan(ctx); err != nil { - return Workflow{}, err - } - return workflow, nil -} - -func (m *WorkflowManager) PostEvent(ctx context.Context, instanceID string, event Event) error { - stage := Stage{} - if err := m.db.NewSelect(). - Model(&stage). - Where("instance_id = ?", instanceID). - Limit(1). - OrderExpr("stage desc"). - Scan(ctx); err != nil { - return errors.Wrap(err, "retrieving workflow") - } - - err := m.temporalClient.SignalWorkflow(ctx, stage.TemporalWorkflowID(), "", EventSignalName, event) - if err != nil { - return errors.Wrap(err, "sending signal to server") - } - - return nil -} - -func (m *WorkflowManager) AbortRun(ctx context.Context, instanceID string) error { - instance := Instance{} - if err := m.db.NewSelect(). - Model(&instance). - Where("id = ?", instanceID). - Scan(ctx); err != nil { - return errors.Wrap(err, "retrieving workflow execution") - } - - return m.temporalClient.CancelWorkflow(ctx, instanceID, "") -} - -func (m *WorkflowManager) ListInstances(ctx context.Context, pagination ListInstancesQuery) (*bunpaginate.Cursor[Instance], error) { - query := m.db.NewSelect() - - return bunpaginate.UsingOffset[ListInstancesOptions, Instance](ctx, query, bunpaginate.OffsetPaginatedQuery[ListInstancesOptions](pagination), - func(query *bun.SelectQuery) *bun.SelectQuery { - query = query. - Join("JOIN workflows ON workflows.id = u.workflow_id"). - Where("workflows.deleted_at IS NULL") - - if pagination.Options.WorkflowID != "" { - query = query.Where("workflows.id = ?", pagination.Options.WorkflowID) - } - if pagination.Options.Running { - query = query.Where("u.terminated = false") - } - - return query - }) -} - -type StageHistory struct { - Name string `json:"name"` - Input map[string]any `json:"input"` - Error string `json:"error,omitempty"` - Terminated bool `json:"terminated"` - StartedAt time.Time `json:"startedAt"` - TerminatedAt *time.Time `json:"terminatedAt,omitempty"` -} - -func (m *WorkflowManager) ReadInstanceHistory(ctx context.Context, instanceID string) ([]StageHistory, error) { - - historyIterator := m.temporalClient.GetWorkflowHistory(ctx, instanceID+"-main", "", - false, enums.HISTORY_EVENT_FILTER_TYPE_ALL_EVENT) - ret := make([]StageHistory, 0) - for historyIterator.HasNext() { - event, err := historyIterator.Next() - if err != nil { - return nil, err - } - switch event.EventType { - case enums.EVENT_TYPE_START_CHILD_WORKFLOW_EXECUTION_INITIATED: - attributes := event.Attributes.(*history.HistoryEvent_StartChildWorkflowExecutionInitiatedEventAttributes) - input := make(map[string]any) - if err := json.Unmarshal(attributes.StartChildWorkflowExecutionInitiatedEventAttributes.Input.Payloads[0].Data, &input); err != nil { - panic(err) - } - stageHistory := StageHistory{ - Name: attributes.StartChildWorkflowExecutionInitiatedEventAttributes.WorkflowType.Name, - Input: input, - StartedAt: event.EventTime.AsTime(), - } - - for historyIterator.HasNext() { - event, err = historyIterator.Next() - if err != nil { - return nil, err - } - switch event.EventType { - case enums.EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_TERMINATED: - case enums.EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_FAILED: - attributes := event.Attributes.(*history.HistoryEvent_ChildWorkflowExecutionFailedEventAttributes). - ChildWorkflowExecutionFailedEventAttributes - stageHistory.Error = attributes.Failure.Message - case enums.EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_COMPLETED: - case enums.EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_TIMED_OUT: - stageHistory.Error = "timeout" - case enums.EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_CANCELED: - stageHistory.Error = "canceled" - default: - continue - } - stageHistory.TerminatedAt = pointer.For(event.EventTime.AsTime()) - stageHistory.Terminated = true - break - } - ret = append(ret, stageHistory) - } - } - return ret, nil -} - -type ActivityHistory struct { - Name string `json:"name"` - Input map[string]any `json:"input"` - Output map[string]any `json:"output,omitempty"` - Error string `json:"error,omitempty"` - Terminated bool `json:"terminated"` - StartedAt time.Time `json:"startedAt"` - TerminatedAt *time.Time `json:"terminatedAt,omitempty"` - LastFailure string `json:"lastFailure,omitempty"` - Attempt int `json:"attempt"` - NextExecution *time.Time `json:"nextExecution,omitempty"` -} - -func (m *WorkflowManager) ReadStageHistory(ctx context.Context, instanceID string, stage int) ([]*ActivityHistory, error) { - stageID := fmt.Sprintf("%s-%d", instanceID, stage) - described, err := m.temporalClient.DescribeWorkflowExecution(ctx, stageID, "") - if err != nil { - if _, ok := err.(*serviceerror.NotFound); ok { - return nil, ErrInstanceNotFound - } - panic(err) - } - - historyIterator := m.temporalClient.GetWorkflowHistory(ctx, stageID, "", - false, enums.HISTORY_EVENT_FILTER_TYPE_ALL_EVENT) - ret := make([]*ActivityHistory, 0) - for historyIterator.HasNext() { - event, err := historyIterator.Next() - if err != nil { - return nil, err - } - switch event.EventType { - case enums.EVENT_TYPE_ACTIVITY_TASK_SCHEDULED: - activityTaskScheduledEventAttributes := event.Attributes.(*history.HistoryEvent_ActivityTaskScheduledEventAttributes).ActivityTaskScheduledEventAttributes - input := make(map[string]any) - if err := json.Unmarshal(activityTaskScheduledEventAttributes.Input.Payloads[0].Data, &input); err != nil { - panic(err) - } - - activityHistory := &ActivityHistory{ - Name: activityTaskScheduledEventAttributes.ActivityType.Name, - Input: map[string]any{ - activityTaskScheduledEventAttributes.ActivityType.Name: input, - }, - StartedAt: event.EventTime.AsTime(), - Attempt: 1, - } - - ret = append(ret, activityHistory) - - if len(described.PendingActivities) > 0 && - activityTaskScheduledEventAttributes.ActivityId == described.PendingActivities[0].ActivityId { - pendingActivity := described.PendingActivities[0] - if pendingActivity.LastFailure != nil { - activityHistory.LastFailure = pendingActivity.LastFailure.Message - } - activityHistory.Attempt = int(pendingActivity.Attempt) - activityHistory.NextExecution = pointer.For(pendingActivity.ScheduledTime.AsTime()) - return ret, nil - } - - for historyIterator.HasNext() { - event, err = historyIterator.Next() - if err != nil { - return nil, err - } - switch event.EventType { - case enums.EVENT_TYPE_ACTIVITY_TASK_CANCELED: - activityHistory.Error = "cancelled" - case enums.EVENT_TYPE_ACTIVITY_TASK_COMPLETED: - result := event.Attributes.(*history.HistoryEvent_ActivityTaskCompletedEventAttributes).ActivityTaskCompletedEventAttributes.Result - if result != nil && len(result.Payloads) > 0 { - output := make(map[string]any) - if err := json.Unmarshal(result.Payloads[0].Data, &output); err != nil { - panic(err) - } - - // notes(gfyrag): keep compat with format from ledger v1 (since we have moved to ledger v2 api) - // maybe we should define proper boundaries on activities, independent of the formance sdk - // to avoid breaking histories - switch activityTaskScheduledEventAttributes.ActivityType.Name { - case "CreateTransaction": - switch tx := output["data"].(type) { - case map[string]any: - tx["txid"] = tx["id"] - output["data"] = []any{tx} - } - } - - activityHistory.Output = map[string]any{ - activityTaskScheduledEventAttributes.ActivityType.Name: output, - } - } - case enums.EVENT_TYPE_ACTIVITY_TASK_TIMED_OUT: - activityHistory.Error = "timeout" - case enums.EVENT_TYPE_ACTIVITY_TASK_FAILED: - activityHistory.Error = event.Attributes.(*history.HistoryEvent_ActivityTaskFailedEventAttributes). - ActivityTaskFailedEventAttributes.Failure.Message - default: - continue - } - activityHistory.TerminatedAt = pointer.For(event.EventTime.AsTime()) - activityHistory.Terminated = true - break - } - } - } - return ret, nil -} - -func (m *WorkflowManager) GetInstance(ctx context.Context, instanceID string) (*Instance, error) { - occurrence := Instance{} - err := m.db.NewSelect(). - Model(&occurrence). - Relation("Statuses"). - Where("id = ?", instanceID). - Scan(ctx) - if err != nil { - if err == sql.ErrNoRows { - return nil, ErrInstanceNotFound - } - return nil, err - } - return &occurrence, nil -} - -func NewManager(db *bun.DB, temporalClient client.Client, taskQueue string, includeSearchAttributes bool) *WorkflowManager { - return &WorkflowManager{ - db: db, - temporalClient: temporalClient, - taskQueue: taskQueue, - includeSearchAttributes: includeSearchAttributes, - } -} - -type ListInstancesOptions struct { - WorkflowID string - Running bool -} - -type ListInstancesQuery bunpaginate.OffsetPaginatedQuery[ListInstancesOptions] diff --git a/ee/orchestration/internal/workflow/manager_test.go b/ee/orchestration/internal/workflow/manager_test.go deleted file mode 100644 index edaf2f6403..0000000000 --- a/ee/orchestration/internal/workflow/manager_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package workflow - -import ( - "testing" - "time" - - "github.com/formancehq/go-libs/bun/bundebug" - "github.com/uptrace/bun" - "go.temporal.io/sdk/worker" - - "github.com/formancehq/go-libs/logging" - "github.com/formancehq/go-libs/publish" - "github.com/formancehq/orchestration/internal/temporalworker" - "github.com/formancehq/orchestration/internal/workflow/stages" - "github.com/google/uuid" - - "github.com/formancehq/go-libs/bun/bunconnect" - - "github.com/formancehq/orchestration/internal/storage" - "github.com/stretchr/testify/require" -) - -func TestConfig(t *testing.T) { - t.Parallel() - - hooks := make([]bun.QueryHook, 0) - if testing.Verbose() { - hooks = append(hooks, bundebug.NewQueryHook()) - } - - database := srv.NewDatabase(t) - db, err := bunconnect.OpenSQLDB(logging.TestingContext(), bunconnect.ConnectionOptions{ - DatabaseSourceName: database.ConnString(), - }, hooks...) - require.NoError(t, err) - t.Cleanup(func() { - _ = db.Close() - }) - require.NoError(t, storage.Migrate(logging.TestingContext(), db)) - - taskQueue := uuid.NewString() - worker := temporalworker.New(logging.Testing(), devServer.Client(), taskQueue, - []temporalworker.DefinitionSet{ - NewWorkflows(false).DefinitionSet(), - temporalworker.NewDefinitionSet().Append(temporalworker.Definition{ - Name: "NoOp", - Func: (&stages.NoOp{}).GetWorkflow(), - }), - }, - []temporalworker.DefinitionSet{ - NewActivities(publish.NoOpPublisher, db).DefinitionSet(), - }, - worker.Options{}, - ) - require.NoError(t, worker.Start()) - t.Cleanup(worker.Stop) - - manager := NewManager(db, devServer.Client(), taskQueue, false) - - config := Config{ - Stages: []RawStage{ - { - "noop": map[string]any{}, - }, - }, - } - w, err := manager.Create(logging.TestingContext(), config) - require.NoError(t, err) - - i, err := manager.RunWorkflow(logging.TestingContext(), w.ID, map[string]string{}) - require.NoError(t, err) - - require.Eventually(t, func() bool { - updatedInstance, err := manager.GetInstance(logging.TestingContext(), i.ID) - require.NoError(t, err) - return len(updatedInstance.Statuses) == 1 - }, 2*time.Second, 100*time.Millisecond) -} diff --git a/ee/orchestration/internal/workflow/module.go b/ee/orchestration/internal/workflow/module.go deleted file mode 100644 index bb2a7e88eb..0000000000 --- a/ee/orchestration/internal/workflow/module.go +++ /dev/null @@ -1,46 +0,0 @@ -package workflow - -import ( - "github.com/formancehq/orchestration/internal/temporalworker" - "github.com/formancehq/orchestration/internal/workflow/activities" - "github.com/formancehq/orchestration/internal/workflow/stages" - "github.com/iancoleman/strcase" - "github.com/uptrace/bun" - "go.temporal.io/sdk/client" - "go.uber.org/fx" -) - -func NewModule(taskQueue string) fx.Option { - ret := []fx.Option{ - fx.Provide(func(db *bun.DB, temporalClient client.Client) *WorkflowManager { - return NewManager(db, temporalClient, taskQueue, true) - }), - fx.Provide(func() *Workflows { - return NewWorkflows(true) - }), - fx.Provide(activities.New), - fx.Provide(NewActivities), - fx.Provide(fx.Annotate(func(a activities.Activities) temporalworker.DefinitionSet { - return a.DefinitionSet() - }, fx.ResultTags(`group:"activities"`))), - fx.Provide(fx.Annotate(func(a Activities) temporalworker.DefinitionSet { - return a.DefinitionSet() - }, fx.ResultTags(`group:"activities"`))), - fx.Provide(fx.Annotate(func(workflow *Workflows) temporalworker.DefinitionSet { - return workflow.DefinitionSet() - }, fx.ResultTags(`group:"workflows"`))), - } - - set := temporalworker.NewDefinitionSet() - for name, schema := range stages.All() { - set = set.Append(temporalworker.Definition{ - Name: "Run" + strcase.ToCamel(name), - Func: schema.GetWorkflow(), - }) - } - ret = append(ret, fx.Supply( - fx.Annotate(set, fx.ResultTags(`group:"workflows"`)), - )) - - return fx.Options(ret...) -} diff --git a/ee/orchestration/internal/workflow/run.go b/ee/orchestration/internal/workflow/run.go deleted file mode 100644 index 6eb9034dc7..0000000000 --- a/ee/orchestration/internal/workflow/run.go +++ /dev/null @@ -1,100 +0,0 @@ -package workflow - -import ( - "time" - - "github.com/formancehq/orchestration/internal/temporalworker" - - "go.temporal.io/api/enums/v1" - "go.temporal.io/sdk/workflow" -) - -const SearchAttributeWorkflowID = "OrchestrationWorkflowID" - -type Workflows struct { - includeSearchAttributes bool -} - -func (w Workflows) Initiate(ctx workflow.Context, input Input) (*Instance, error) { - instance := &Instance{} - err := workflow.ExecuteActivity(workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ - StartToCloseTimeout: 10 * time.Second, - }), InsertNewInstanceActivity, input.Workflow.ID).Get(ctx, instance) - if err != nil { - return nil, err - } - - err = workflow.ExecuteActivity(workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ - StartToCloseTimeout: 10 * time.Second, - }), SendWorkflowStartedEventActivity, instance).Get(ctx, nil) - if err != nil { - return nil, err - } - - searchAttributes := map[string]any{} - if w.includeSearchAttributes { - searchAttributes = map[string]interface{}{ - SearchAttributeWorkflowID: input.Workflow.ID, - } - } - - if err := workflow.ExecuteChildWorkflow( - workflow.WithChildOptions(ctx, workflow.ChildWorkflowOptions{ - ParentClosePolicy: enums.PARENT_CLOSE_POLICY_ABANDON, - WorkflowID: workflow.GetInfo(ctx).WorkflowExecution.ID + "-main", - SearchAttributes: searchAttributes, - }), - Run, - input, - *instance, - ).GetChildWorkflowExecution().Get(ctx, nil); err != nil { - return nil, err - } - - return instance, nil -} - -func (w Workflows) Run(ctx workflow.Context, i Input, instance Instance) error { - err := i.Workflow.Config.run(ctx, instance, i.Variables) - if err != nil { - instance.SetTerminatedWithError(workflow.Now(ctx), err) - } else { - instance.SetTerminated(workflow.Now(ctx)) - } - - err = workflow.ExecuteActivity(workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ - StartToCloseTimeout: 10 * time.Second, - }), UpdateInstanceActivity, instance).Get(ctx, nil) - if err != nil { - return err - } - - err = workflow.ExecuteActivity(workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ - StartToCloseTimeout: 10 * time.Second, - }), SendWorkflowTerminationEventActivity, instance).Get(ctx, nil) - if err != nil { - return err - } - - return nil -} - -func (w Workflows) DefinitionSet() temporalworker.DefinitionSet { - return temporalworker.NewDefinitionSet(). - Append(temporalworker.Definition{ - Func: w.Run, - Name: "Run", - }).Append(temporalworker.Definition{ - Func: w.Initiate, - Name: "Initiate", - }) -} - -var Initiate = Workflows{}.Initiate -var Run = Workflows{}.Run - -func NewWorkflows(includeSearchAttributes bool) *Workflows { - return &Workflows{ - includeSearchAttributes: includeSearchAttributes, - } -} diff --git a/ee/orchestration/internal/workflow/stage.go b/ee/orchestration/internal/workflow/stage.go deleted file mode 100644 index 582b400257..0000000000 --- a/ee/orchestration/internal/workflow/stage.go +++ /dev/null @@ -1,41 +0,0 @@ -package workflow - -import ( - "fmt" - "time" - - "github.com/formancehq/go-libs/pointer" - - "github.com/uptrace/bun" -) - -type Stage struct { - bun.BaseModel `bun:"table:workflow_instance_stage_statuses"` - Number int `json:"stage" bun:"stage,pk"` - InstanceID string `json:"instanceID" bun:"instance_id,pk"` - TemporalRunID string `json:"temporalRunID" bun:"temporal_run_id,pk"` - StartedAt time.Time `json:"startedAt" bun:"started_at"` - TerminatedAt *time.Time `json:"terminatedAt,omitempty" bun:"terminated_at"` - Error *string `json:"error,omitempty" bun:"error"` -} - -func (s *Stage) SetTerminated(err error, date time.Time) { - s.TerminatedAt = &date - if err != nil { - s.Error = pointer.For(err.Error()) - } -} - -func (s *Stage) TemporalWorkflowID() string { - return fmt.Sprintf("%s-%d", s.InstanceID, s.Number) -} - -func NewStage(instanceID, temporalRunID string, number int) Stage { - return Stage{ - BaseModel: bun.BaseModel{}, - TemporalRunID: temporalRunID, - Number: number, - InstanceID: instanceID, - StartedAt: time.Now(), - } -} diff --git a/ee/orchestration/internal/workflow/stages/all/all.go b/ee/orchestration/internal/workflow/stages/all/all.go deleted file mode 100644 index 997e68fdd6..0000000000 --- a/ee/orchestration/internal/workflow/stages/all/all.go +++ /dev/null @@ -1,8 +0,0 @@ -package all - -import ( - _ "github.com/formancehq/orchestration/internal/workflow/stages/delay" - _ "github.com/formancehq/orchestration/internal/workflow/stages/send" - _ "github.com/formancehq/orchestration/internal/workflow/stages/update" - _ "github.com/formancehq/orchestration/internal/workflow/stages/wait_event" -) diff --git a/ee/orchestration/internal/workflow/stages/delay/delay.go b/ee/orchestration/internal/workflow/stages/delay/delay.go deleted file mode 100644 index 1665daf1e1..0000000000 --- a/ee/orchestration/internal/workflow/stages/delay/delay.go +++ /dev/null @@ -1,21 +0,0 @@ -package delay - -import ( - "github.com/formancehq/go-libs/time" - "github.com/formancehq/orchestration/internal/schema" - "github.com/formancehq/orchestration/internal/workflow/stages" -) - -type Delay struct { - Duration *schema.Duration `json:"duration,omitempty"` - Until *time.Time `json:"until,omitempty"` -} - -func (d Delay) GetWorkflow() any { - return RunDelay -} - -func init() { - schema.RegisterOneOf(Delay{}) - stages.Register("delay", Delay{}) -} diff --git a/ee/orchestration/internal/workflow/stages/delay/run.go b/ee/orchestration/internal/workflow/stages/delay/run.go deleted file mode 100644 index 8446c6f3cc..0000000000 --- a/ee/orchestration/internal/workflow/stages/delay/run.go +++ /dev/null @@ -1,17 +0,0 @@ -package delay - -import ( - "github.com/formancehq/go-libs/time" - "go.temporal.io/sdk/workflow" -) - -func RunDelay(ctx workflow.Context, delay Delay) error { - var duration time.Duration - switch { - case delay.Duration != nil: - duration = time.Duration(*delay.Duration) - case delay.Until != nil: - duration = time.Until(*delay.Until) - } - return workflow.Sleep(ctx, duration) -} diff --git a/ee/orchestration/internal/workflow/stages/delay/run_test.go b/ee/orchestration/internal/workflow/stages/delay/run_test.go deleted file mode 100644 index 6d54e1ed52..0000000000 --- a/ee/orchestration/internal/workflow/stages/delay/run_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package delay - -import ( - "testing" - - "github.com/formancehq/go-libs/time" - - "github.com/formancehq/orchestration/internal/schema" - "github.com/formancehq/orchestration/internal/workflow/stages/internal/stagestesting" -) - -func TestDelaySchema(t *testing.T) { - now := time.Now().Round(time.Second).UTC() - stagestesting.TestSchemas(t, "delay", []stagestesting.SchemaTestCase{ - { - Name: "valid case using until property", - Data: map[string]any{ - "until": now.Format(time.RFC3339Nano), - }, - ExpectedResolved: Delay{ - Until: &now, - }, - ExpectedValidationError: false, - }, - { - Name: "valid case using duration", - Data: map[string]any{ - "duration": "10s", - }, - ExpectedValidationError: false, - ExpectedResolved: Delay{ - Duration: (*schema.Duration)(ptr(time.Second * 10)), - }, - }, - { - Name: "invalid case, missing until or duration", - Data: map[string]any{}, - ExpectedResolved: Delay{}, - ExpectedValidationError: true, - }, - { - Name: "invalid case, both until and duration specified", - Data: map[string]any{ - "until": now.Format(time.RFC3339Nano), - "duration": "10s", - }, - ExpectedResolved: Delay{ - Duration: (*schema.Duration)(ptr(time.Second * 10)), - Until: &now, - }, - ExpectedValidationError: true, - }, - }...) -} - -func ptr[T any](v T) *T { - return &v -} - -var testCases = []stagestesting.WorkflowTestCase[Delay]{ - { - Stage: Delay{ - Until: ptr(time.Now().Add(time.Second)), - }, - Name: "delay-until", - }, - { - Stage: Delay{ - Duration: (*schema.Duration)(ptr(time.Second)), - }, - Name: "delay-duration", - }, -} - -func TestDelay(t *testing.T) { - stagestesting.RunWorkflows(t, testCases...) -} diff --git a/ee/orchestration/internal/workflow/stages/internal/context.go b/ee/orchestration/internal/workflow/stages/internal/context.go deleted file mode 100644 index 37d70ac3de..0000000000 --- a/ee/orchestration/internal/workflow/stages/internal/context.go +++ /dev/null @@ -1,32 +0,0 @@ -package internal - -import ( - "time" - - "go.temporal.io/sdk/temporal" - "go.temporal.io/sdk/workflow" -) - -const ( - ErrorCodeValidation = "VALIDATION" - ErrorCodeConflict = "CONFLICT" - ErrorCodeNoScript = "NO_SCRIPT" - ErrorCodeCompilationFailed = "COMPILATION_FAILED" -) - -func InfiniteRetryContext(ctx workflow.Context) workflow.Context { - return workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ - StartToCloseTimeout: 60 * time.Second, - RetryPolicy: &temporal.RetryPolicy{ - InitialInterval: time.Second, - BackoffCoefficient: 2, - MaximumInterval: 100 * time.Second, - NonRetryableErrorTypes: []string{ - ErrorCodeValidation, - ErrorCodeConflict, - ErrorCodeNoScript, - ErrorCodeCompilationFailed, - }, - }, - }) -} diff --git a/ee/orchestration/internal/workflow/stages/internal/stagestesting/schema.go b/ee/orchestration/internal/workflow/stages/internal/stagestesting/schema.go deleted file mode 100644 index cc9d10fe09..0000000000 --- a/ee/orchestration/internal/workflow/stages/internal/stagestesting/schema.go +++ /dev/null @@ -1,53 +0,0 @@ -package stagestesting - -import ( - "reflect" - "testing" - - "github.com/formancehq/orchestration/internal/schema" - "github.com/stretchr/testify/require" -) - -type SchemaTestCase struct { - Data map[string]any - ExpectedResolveError bool - ExpectedResolved any - ExpectedValidationError bool - Name string - Variables map[string]string -} - -func TestSchema(t *testing.T, stageName string, testCase SchemaTestCase) { - t.Run(testCase.Name, func(t *testing.T) { - t.Parallel() - - variables := testCase.Variables - if variables == nil { - variables = map[string]string{} - } - s, err := schema.Resolve(schema.Context{ - Variables: variables, - }, testCase.Data, stageName) - if !testCase.ExpectedResolveError { - require.NoError(t, err, "resolving schema") - require.Equal(t, testCase.ExpectedResolved, reflect.ValueOf(s).Elem().Interface()) - } else { - require.Error(t, err, "resolving schema") - return - } - - err = schema.ValidateRequirements(s) - if testCase.ExpectedValidationError { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) -} - -func TestSchemas(t *testing.T, stageName string, testCases ...SchemaTestCase) { - t.Parallel() - for _, testCase := range testCases { - TestSchema(t, stageName, testCase) - } -} diff --git a/ee/orchestration/internal/workflow/stages/internal/stagestesting/workflow.go b/ee/orchestration/internal/workflow/stages/internal/stagestesting/workflow.go deleted file mode 100644 index 4841ae8b4c..0000000000 --- a/ee/orchestration/internal/workflow/stages/internal/stagestesting/workflow.go +++ /dev/null @@ -1,57 +0,0 @@ -package stagestesting - -import ( - "testing" - "time" - - "github.com/formancehq/orchestration/internal/workflow/stages" - "github.com/stretchr/testify/require" - "go.temporal.io/sdk/testsuite" -) - -type MockedActivity struct { - Activity any - Args []any - Returns []any -} - -type DelayedCallback struct { - Fn func(environment *testsuite.TestWorkflowEnvironment) func() - Duration time.Duration -} - -type WorkflowTestCase[T stages.Stage] struct { - Stage T - MockedActivities []MockedActivity - DelayedCallbacks []DelayedCallback - Name string -} - -func RunWorkflowTest[T stages.Stage](t *testing.T, testCase WorkflowTestCase[T]) { - t.Run(testCase.Name, func(t *testing.T) { - t.Parallel() - - testSuite := &testsuite.WorkflowTestSuite{} - - env := testSuite.NewTestWorkflowEnvironment() - for _, ma := range testCase.MockedActivities { - env.OnActivity(ma.Activity, ma.Args...).Return(ma.Returns...) - } - for _, callback := range testCase.DelayedCallbacks { - env.RegisterDelayedCallback(callback.Fn(env), callback.Duration) - } - - var stage T - env.ExecuteWorkflow(stage.GetWorkflow(), testCase.Stage) - require.True(t, env.IsWorkflowCompleted()) - require.NoError(t, env.GetWorkflowError()) - }) -} - -func RunWorkflows[T stages.Stage](t *testing.T, testCases ...WorkflowTestCase[T]) { - t.Parallel() - - for _, testCase := range testCases { - RunWorkflowTest(t, testCase) - } -} diff --git a/ee/orchestration/internal/workflow/stages/noop.go b/ee/orchestration/internal/workflow/stages/noop.go deleted file mode 100644 index ee862971b2..0000000000 --- a/ee/orchestration/internal/workflow/stages/noop.go +++ /dev/null @@ -1,20 +0,0 @@ -package stages - -import ( - "go.temporal.io/sdk/workflow" -) - -type NoOp struct { -} - -func (n NoOp) GetWorkflow() any { - return RunNoOp -} - -func RunNoOp(ctx workflow.Context, p NoOp) error { - return nil -} - -func init() { - Register("noop", NoOp{}) -} diff --git a/ee/orchestration/internal/workflow/stages/schema.go b/ee/orchestration/internal/workflow/stages/schema.go deleted file mode 100644 index 2efd3d2e6c..0000000000 --- a/ee/orchestration/internal/workflow/stages/schema.go +++ /dev/null @@ -1,19 +0,0 @@ -package stages - -var stages = map[string]Stage{} - -type Stage interface { - GetWorkflow() any -} - -func Register(name string, stage Stage) { - stages[name] = stage -} - -func All() map[string]Stage { - return stages -} - -func Get(name string) Stage { - return stages[name] -} diff --git a/ee/orchestration/internal/workflow/stages/send/run.go b/ee/orchestration/internal/workflow/stages/send/run.go deleted file mode 100644 index be4e03e74b..0000000000 --- a/ee/orchestration/internal/workflow/stages/send/run.go +++ /dev/null @@ -1,446 +0,0 @@ -package send - -import ( - "fmt" - "reflect" - "strings" - - "github.com/formancehq/go-libs/time" - - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/go-libs/metadata" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "github.com/formancehq/orchestration/internal/workflow/activities" - "github.com/formancehq/orchestration/internal/workflow/stages/internal" - "github.com/pkg/errors" - "go.temporal.io/sdk/temporal" - "go.temporal.io/sdk/workflow" -) - -const ( - internalLedger = "orchestration-000-internal" - moveToLedgerMetadata = "orchestration/move-to-ledger" - moveFromLedgerMetadata = "orchestration/move-from-ledger" -) - -func extractFormanceAccountID[V any](metadataKey string, metadata map[string]V) (string, error) { - formanceAccountID, ok := metadata[metadataKey] - if !ok { - return "", fmt.Errorf("expected '%s' metadata containing formance account ID", metadataKey) - } - if reflect.ValueOf(formanceAccountID).IsZero() { - return "", errors.New("formance account ID empty") - } - return fmt.Sprint(formanceAccountID), nil -} - -func justError[T any](v T, err error) error { - return err -} - -func getWalletFromReference(ctx workflow.Context, ref WalletReference) (*shared.Wallet, error) { - if ref.ID != "" { - walletSource, err := activities.GetWallet(internal.InfiniteRetryContext(ctx), ref.ID) - if err != nil { - return nil, err - } - return &shared.Wallet{ - CreatedAt: walletSource.CreatedAt, - ID: walletSource.ID, - Ledger: walletSource.Ledger, - Metadata: walletSource.Metadata, - Name: walletSource.Name, - }, nil - } else { - wallets, err := activities.ListWallets(internal.InfiniteRetryContext(ctx), activities.ListWalletsRequest{ - Name: ref.Name, - }) - if err != nil { - return nil, err - } - switch len(wallets.Cursor.Data) { - case 0: - return nil, errors.New("wallet not found") - case 1: - return &wallets.Cursor.Data[0], nil - default: - return nil, errors.New("found multiple wallets with the same name") - } - } -} - -func RunSend(ctx workflow.Context, send Send) (err error) { - defer func() { - if e := recover(); e != nil { - err = errors.WithStack(fmt.Errorf("%s", e)) - } - }() - amount := send.Amount - metadata := send.Metadata - if metadata == nil { - metadata = map[string]string{} - } - switch { - case send.Source.Account != nil && send.Destination.Account != nil: - return runAccountToAccount(ctx, send.Timestamp, send.Source.Account, send.Destination.Account, amount, metadata) - case send.Source.Account != nil && send.Destination.Payment != nil: - return runAccountToPayment(ctx, send.Timestamp, send.Source.Account, send.Destination.Payment, amount, metadata) - case send.Source.Account != nil && send.Destination.Wallet != nil: - return runAccountToWallet(ctx, send.Timestamp, send.Source.Account, send.Destination.Wallet, amount, metadata) - case send.Source.Wallet != nil && send.Destination.Account != nil: - return runWalletToAccount(ctx, send.Timestamp, send.Source.Wallet, send.Destination.Account, amount, send.Metadata) - case send.Source.Wallet != nil && send.Destination.Payment != nil: - return runWalletToPayment(ctx, send.Timestamp, send.Source.Wallet, send.Destination.Payment, amount, metadata) - case send.Source.Wallet != nil && send.Destination.Wallet != nil: - return runWalletToWallet(ctx, send.Timestamp, send.Source.Wallet, send.Destination.Wallet, amount, metadata) - case send.Source.Payment != nil && send.Destination.Account != nil: - return runPaymentToAccount(ctx, send.Timestamp, send.Source.Payment, send.Destination.Account, amount, metadata) - case send.Source.Payment != nil && send.Destination.Wallet != nil: - return runPaymentToWallet(ctx, send.Timestamp, send.Source.Payment, send.Destination.Wallet, amount, metadata) - case send.Source.Payment != nil && send.Destination.Payment != nil: - return errors.New("send from payment to payment is not supported") - } - panic("should not happen") -} - -func runPaymentToWallet(ctx workflow.Context, timestamp *time.Time, source *PaymentSource, destination *WalletSource, amount *shared.Monetary, m metadata.Metadata) error { - payment, err := savePayment(ctx, timestamp, source.ID, m) - if err != nil { - return err - } - if amount == nil { - amount = &shared.Monetary{ - Amount: payment.InitialAmount, - Asset: payment.Asset, - } - } - return runAccountToWallet(ctx, timestamp, &LedgerAccountSource{ - ID: paymentAccountName(source.ID), - Ledger: internalLedger, - }, destination, amount, m) -} - -func paymentAccountName(paymentID string) string { - paymentID = strings.ReplaceAll(paymentID, "-", "_") - return fmt.Sprintf("payment:%s", paymentID) -} - -func savePayment(ctx workflow.Context, timestamp *time.Time, paymentID string, m metadata.Metadata) (*shared.Payment, error) { - payment, err := activities.GetPayment(internal.InfiniteRetryContext(ctx), paymentID) - if err != nil { - return nil, errors.Wrapf(err, "retrieving payment: %s", paymentID) - } - reference := paymentAccountName(paymentID) - _, err = activities.CreateTransaction(internal.InfiniteRetryContext(ctx), internalLedger, activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: payment.InitialAmount, - Asset: payment.Asset, - Destination: paymentAccountName(paymentID), - Source: "world", - }}, - Timestamp: timestamp, - Metadata: m, - Reference: &reference, - }) - if err != nil { - applicationError := &temporal.ApplicationError{} - if errors.As(err, &applicationError) { - if applicationError.Type() != "CONFLICT" { - return nil, err - } - } else { - return nil, err - } - } - return payment, nil -} - -func runPaymentToAccount(ctx workflow.Context, timestamp *time.Time, source *PaymentSource, destination *LedgerAccountDestination, amount *shared.Monetary, m metadata.Metadata) error { - payment, err := savePayment(ctx, timestamp, source.ID, m) - if err != nil { - return err - } - if amount == nil { - amount = &shared.Monetary{ - Amount: payment.InitialAmount, - Asset: payment.Asset, - } - } - return runAccountToAccount(ctx, timestamp, &LedgerAccountSource{ - ID: paymentAccountName(source.ID), - Ledger: internalLedger, - }, destination, amount, m) -} - -func runWalletToWallet(ctx workflow.Context, timestamp *time.Time, source *WalletSource, destination *WalletDestination, amount *shared.Monetary, m metadata.Metadata) error { - if amount == nil { - return errors.New("amount must be specified") - } - sourceWallet, err := getWalletFromReference(ctx, source.WalletReference) - if err != nil { - return err - } - destinationWallet, err := getWalletFromReference(ctx, destination.WalletReference) - if err != nil { - return err - } - if sourceWallet.Ledger == destinationWallet.Ledger { - mainBalance := "main" - sourceSubject := shared.WalletSubject{ - Balance: &mainBalance, - Identifier: sourceWallet.ID, - Type: "WALLET", - } - return activities.CreditWallet(internal.InfiniteRetryContext(ctx), destinationWallet.ID, &activities.CreditWalletRequestPayload{ - Amount: *amount, - Balance: &destination.Balance, - Metadata: m, - Sources: []shared.Subject{{WalletSubject: &sourceSubject}}, - Timestamp: timestamp, - }) - } - - if err := justError(activities.DebitWallet(internal.InfiniteRetryContext(ctx), sourceWallet.ID, &activities.DebitWalletRequestPayload{ - Amount: *amount, - Balances: []string{source.Balance}, - Timestamp: timestamp, - Metadata: collectionutils.MergeMaps(m, map[string]string{ - moveToLedgerMetadata: destinationWallet.Ledger, - }), - })); err != nil { - return err - } - - return activities.CreditWallet(internal.InfiniteRetryContext(ctx), destinationWallet.ID, &activities.CreditWalletRequestPayload{ - Amount: *amount, - Balance: &destination.Balance, - Timestamp: timestamp, - Metadata: collectionutils.MergeMaps(m, map[string]string{ - moveFromLedgerMetadata: sourceWallet.Ledger, - }), - }) -} - -func runWalletToPayment(ctx workflow.Context, timestamp *time.Time, source *WalletSource, destination *PaymentDestination, amount *shared.Monetary, m metadata.Metadata) error { - if amount == nil { - return errors.New("amount must be specified") - } - if destination.PSP != "stripe" { - return errors.New("only stripe actually supported") - } - sourceWallet, err := getWalletFromReference(ctx, source.WalletReference) - if err != nil { - return errors.Wrapf(err, "reading account: %s", source.ID) - } - - formanceAccountID, err := extractFormanceAccountID(destination.Metadata, sourceWallet.Metadata) - if err != nil { - return err - } - - if err := activities.StripeTransfer(internal.InfiniteRetryContext(ctx), activities.StripeTransferRequest{ - Amount: amount.Amount, - Asset: &amount.Asset, - Destination: &formanceAccountID, - WaitingValidation: &destination.WaitingValidation, - ConnectorID: destination.ConnectorID, - Metadata: m, - }); err != nil { - return err - } - - return justError(activities.DebitWallet(internal.InfiniteRetryContext(ctx), sourceWallet.ID, &activities.DebitWalletRequestPayload{ - Amount: *amount, - Balances: []string{source.Balance}, - Metadata: m, - Timestamp: timestamp, - })) -} - -func runWalletToAccount(ctx workflow.Context, timestamp *time.Time, source *WalletSource, destination *LedgerAccountDestination, amount *shared.Monetary, m metadata.Metadata) error { - if amount == nil { - return errors.New("amount must be specified") - } - sourceWallet, err := getWalletFromReference(ctx, source.WalletReference) - if err != nil { - return err - } - if sourceWallet.Ledger == destination.Ledger { - return justError(activities.DebitWallet(internal.InfiniteRetryContext(ctx), sourceWallet.ID, &activities.DebitWalletRequestPayload{ - Amount: *amount, - Destination: &shared.Subject{ - LedgerAccountSubject: &shared.LedgerAccountSubject{ - Identifier: destination.ID, - Type: "ACCOUNT", - }, - }, - Timestamp: timestamp, - Balances: []string{source.Balance}, - Metadata: m, - })) - } - - if err := justError(activities.DebitWallet(internal.InfiniteRetryContext(ctx), sourceWallet.ID, &activities.DebitWalletRequestPayload{ - Amount: *amount, - Balances: []string{source.Balance}, - Timestamp: timestamp, - Metadata: collectionutils.MergeMaps(m, map[string]string{ - moveToLedgerMetadata: destination.Ledger, - }), - })); err != nil { - return err - } - - return justError(activities.CreateTransaction(internal.InfiniteRetryContext(ctx), destination.Ledger, activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: amount.Amount, - Asset: amount.Asset, - Destination: destination.ID, - Source: "world", - }}, - Timestamp: timestamp, - Metadata: collectionutils.MergeMaps(m, map[string]string{ - moveFromLedgerMetadata: sourceWallet.Ledger, - }), - })) -} - -func runAccountToWallet(ctx workflow.Context, timestamp *time.Time, source *LedgerAccountSource, destination *WalletDestination, amount *shared.Monetary, m metadata.Metadata) error { - if amount == nil { - return errors.New("amount must be specified") - } - destinationWallet, err := getWalletFromReference(ctx, destination.WalletReference) - if err != nil { - return err - } - if destinationWallet.Ledger == source.Ledger { - return activities.CreditWallet(internal.InfiniteRetryContext(ctx), destinationWallet.ID, &activities.CreditWalletRequestPayload{ - Amount: *amount, - Sources: []shared.Subject{{ - LedgerAccountSubject: &shared.LedgerAccountSubject{ - Identifier: source.ID, - Type: "ACCOUNT", - }, - }}, - Timestamp: timestamp, - Balance: &destination.Balance, - Metadata: m, - }) - } - - if err := justError(activities.CreateTransaction(internal.InfiniteRetryContext(ctx), source.Ledger, activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: amount.Amount, - Asset: amount.Asset, - Destination: "world", - Source: source.ID, - }}, - Timestamp: timestamp, - Metadata: collectionutils.MergeMaps( - m, - map[string]string{ - moveToLedgerMetadata: destinationWallet.Ledger, - }, - ), - })); err != nil { - return err - } - - return activities.CreditWallet(internal.InfiniteRetryContext(ctx), destinationWallet.ID, &activities.CreditWalletRequestPayload{ - Amount: *amount, - Sources: []shared.Subject{{ - LedgerAccountSubject: &shared.LedgerAccountSubject{ - Identifier: "world", - Type: "ACCOUNT", - }, - }}, - Timestamp: timestamp, - Balance: &destination.Balance, - Metadata: collectionutils.MergeMaps(m, map[string]string{ - moveFromLedgerMetadata: source.Ledger, - }), - }) -} - -func runAccountToAccount(ctx workflow.Context, timestamp *time.Time, source *LedgerAccountSource, destination *LedgerAccountDestination, amount *shared.Monetary, m metadata.Metadata) error { - if amount == nil { - return errors.New("amount must be specified") - } - if source.Ledger == destination.Ledger { - return justError(activities.CreateTransaction(internal.InfiniteRetryContext(ctx), destination.Ledger, activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: amount.Amount, - Asset: amount.Asset, - Destination: destination.ID, - Source: source.ID, - }}, - Timestamp: timestamp, - Metadata: m, - })) - } - if err := justError(activities.CreateTransaction(internal.InfiniteRetryContext(ctx), source.Ledger, activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: amount.Amount, - Asset: amount.Asset, - Destination: "world", - Source: source.ID, - }}, - Timestamp: timestamp, - Metadata: collectionutils.MergeMaps(m, map[string]string{ - moveToLedgerMetadata: destination.Ledger, - }), - })); err != nil { - return err - } - return justError(activities.CreateTransaction(internal.InfiniteRetryContext(ctx), destination.Ledger, activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: amount.Amount, - Asset: amount.Asset, - Destination: destination.ID, - Source: "world", - }}, - Timestamp: timestamp, - Metadata: collectionutils.MergeMaps(m, map[string]string{ - moveFromLedgerMetadata: source.Ledger, - }), - })) -} - -func runAccountToPayment(ctx workflow.Context, timestamp *time.Time, source *LedgerAccountSource, destination *PaymentDestination, amount *shared.Monetary, m metadata.Metadata) error { - if amount == nil { - return errors.New("amount must be specified") - } - if destination.PSP != "stripe" { - return errors.New("only stripe actually supported") - } - account, err := activities.GetAccount(internal.InfiniteRetryContext(ctx), source.Ledger, source.ID) - if err != nil { - return errors.Wrapf(err, "reading account: %s", source.ID) - } - formanceAccountID, err := extractFormanceAccountID(destination.Metadata, account.Metadata) - if err != nil { - return err - } - - if err := activities.StripeTransfer(internal.InfiniteRetryContext(ctx), activities.StripeTransferRequest{ - Amount: amount.Amount, - Asset: &amount.Asset, - Destination: &formanceAccountID, - WaitingValidation: &destination.WaitingValidation, - ConnectorID: destination.ConnectorID, - Metadata: m, - }); err != nil { - return err - } - return justError(activities.CreateTransaction(internal.InfiniteRetryContext(ctx), source.Ledger, activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: amount.Amount, - Asset: amount.Asset, - Destination: "world", - Source: source.ID, - }}, - Timestamp: timestamp, - Metadata: m, - })) -} diff --git a/ee/orchestration/internal/workflow/stages/send/run_test.go b/ee/orchestration/internal/workflow/stages/send/run_test.go deleted file mode 100644 index e66d117a7a..0000000000 --- a/ee/orchestration/internal/workflow/stages/send/run_test.go +++ /dev/null @@ -1,1447 +0,0 @@ -package send - -import ( - "math/big" - "testing" - - "github.com/formancehq/go-libs/time" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "github.com/formancehq/go-libs/pointer" - "github.com/formancehq/orchestration/internal/workflow/activities" - "github.com/formancehq/orchestration/internal/workflow/stages/internal/stagestesting" - "github.com/stretchr/testify/mock" - "go.temporal.io/sdk/temporal" -) - -func TestSendSchemaValidation(t *testing.T) { - now := time.Now().Round(time.Millisecond).UTC() - stagestesting.TestSchemas(t, "send", []stagestesting.SchemaTestCase{ - { - Name: "twice destination", - Data: map[string]any{ - "source": map[string]any{ - "account": map[string]any{ - "id": "bar", - }, - }, - "destination": map[string]any{ - "wallet": map[string]any{ - "id": "foo", - }, - "account": map[string]any{ - "id": "foo", - }, - }, - "amount": map[string]any{ - "amount": float64(100), - "asset": "USD", - }, - }, - ExpectedResolved: Send{ - Source: Source{ - Account: &LedgerAccountSource{ - ID: "bar", - Ledger: "default", - }, - }, - Destination: Destination{ - Wallet: &WalletDestination{ - WalletReference: WalletReference{ - ID: "foo", - }, - Balance: "main", - }, - Account: &LedgerAccountSource{ - ID: "foo", - Ledger: "default", - }, - }, - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - ExpectedValidationError: true, - }, - { - Name: "invalid wallet reference", - Data: map[string]any{ - "source": map[string]any{ - "account": map[string]any{ - "id": "bar", - }, - }, - "destination": map[string]any{ - "wallet": map[string]any{}, - }, - "amount": map[string]any{ - "amount": float64(100), - "asset": "USD", - }, - }, - ExpectedResolved: Send{ - Source: Source{ - Account: &LedgerAccountSource{ - ID: "bar", - Ledger: "default", - }, - }, - Destination: Destination{ - Wallet: &WalletDestination{ - Balance: "main", - }, - }, - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - ExpectedValidationError: true, - }, - { - Name: "valid case with variables", - Data: map[string]any{ - "source": map[string]any{ - "payment": map[string]any{ - "id": "${paymentID}", - "psp": "test", - }, - }, - "destination": map[string]any{ - "account": map[string]any{ - "id": "test:${var1}:test:${var2}:test:${var3}:test", - "ledger": "default", - }, - }, - "amount": map[string]any{ - "amount": "${amount}", - "asset": "EUR/2", - }, - }, - Variables: map[string]string{ - "paymentID": "test", - "var1": "001", - "var2": "003", - "var3": "f5649", - "amount": "2819", - }, - ExpectedResolved: Send{ - Source: Source{ - Payment: &PaymentSource{ - ID: "test", - }, - }, - Destination: Destination{ - Account: &LedgerAccountDestination{ - ID: "test:001:test:003:test:f5649:test", - Ledger: "default", - }, - }, - Amount: &shared.Monetary{ - Amount: big.NewInt(2819), - Asset: "EUR/2", - }, - }, - }, - { - Name: "valid case", - Data: map[string]any{ - "source": map[string]any{ - "account": map[string]any{ - "id": "bar", - }, - }, - "destination": map[string]any{ - "wallet": map[string]any{ - "id": "foo", - }, - }, - "amount": map[string]any{ - "amount": float64(100), - "asset": "USD", - }, - }, - ExpectedResolved: Send{ - Source: Source{ - Account: &LedgerAccountSource{ - ID: "bar", - Ledger: "default", - }, - }, - Destination: Destination{ - Wallet: &WalletSource{ - WalletReference: WalletReference{ - ID: "foo", - }, - Balance: "main", - }, - }, - Amount: &shared.Monetary{ - Asset: "USD", - Amount: big.NewInt(100), - }, - }, - }, - { - Name: "use metadata", - Data: map[string]any{ - "source": map[string]any{ - "account": map[string]any{ - "id": "bar", - }, - }, - "destination": map[string]any{ - "wallet": map[string]any{ - "id": "foo", - }, - }, - "amount": map[string]any{ - "amount": float64(100), - "asset": "USD", - }, - "metadata": map[string]string{ - "foo": "bar", - }, - }, - ExpectedResolved: Send{ - Source: Source{ - Account: &LedgerAccountSource{ - ID: "bar", - Ledger: "default", - }, - }, - Destination: Destination{ - Wallet: &WalletSource{ - WalletReference: WalletReference{ - ID: "foo", - }, - Balance: "main", - }, - }, - Amount: &shared.Monetary{ - Asset: "USD", - Amount: big.NewInt(100), - }, - Metadata: map[string]string{ - "foo": "bar", - }, - }, - }, - { - Name: "use timestamp", - Data: map[string]any{ - "source": map[string]any{ - "account": map[string]any{ - "id": "bar", - }, - }, - "destination": map[string]any{ - "wallet": map[string]any{ - "id": "foo", - }, - }, - "amount": map[string]any{ - "amount": float64(100), - "asset": "USD", - }, - "timestamp": now.Format(time.RFC3339Nano), - }, - ExpectedResolved: Send{ - Source: Source{ - Account: &LedgerAccountSource{ - ID: "bar", - Ledger: "default", - }, - }, - Destination: Destination{ - Wallet: &WalletSource{ - WalletReference: WalletReference{ - ID: "foo", - }, - Balance: "main", - }, - }, - Amount: &shared.Monetary{ - Asset: "USD", - Amount: big.NewInt(100), - }, - Timestamp: &now, - }, - }, - { - Name: "use timestamp as variable", - Data: map[string]any{ - "source": map[string]any{ - "account": map[string]any{ - "id": "bar", - }, - }, - "destination": map[string]any{ - "wallet": map[string]any{ - "id": "foo", - }, - }, - "amount": map[string]any{ - "amount": float64(100), - "asset": "USD", - }, - "timestamp": "${timestamp}", - }, - Variables: map[string]string{ - "timestamp": now.Format(time.RFC3339Nano), - }, - ExpectedResolved: Send{ - Source: Source{ - Account: &LedgerAccountSource{ - ID: "bar", - Ledger: "default", - }, - }, - Destination: Destination{ - Wallet: &WalletSource{ - WalletReference: WalletReference{ - ID: "foo", - }, - Balance: "main", - }, - }, - Amount: &shared.Monetary{ - Asset: "USD", - Amount: big.NewInt(100), - }, - Timestamp: &now, - }, - }, - }...) -} - -var ( - paymentToWallet = stagestesting.WorkflowTestCase[Send]{ - Name: "payment to wallet", - Stage: Send{ - Source: NewSource().WithPayment(&PaymentSource{ - ID: "payment1", - }), - Destination: NewDestination().WithWallet(&WalletDestination{ - WalletReference: WalletReference{ - ID: "wallet1", - }, - Balance: "main", - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.GetPaymentActivity, - Args: []any{mock.Anything, activities.GetPaymentRequest{ - ID: "payment1", - }}, - Returns: []any{ - &shared.PaymentResponse{ - Data: shared.Payment{ - InitialAmount: big.NewInt(100), - Asset: "USD", - Status: shared.PaymentStatusSucceeded, - Scheme: shared.PaymentSchemeUnknown, - Type: shared.PaymentTypeOther, - }, - }, nil, - }, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: internalLedger, - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: paymentAccountName("payment1"), - Source: "world", - }}, - Reference: pointer.For(paymentAccountName("payment1")), - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: internalLedger, - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: "world", - Source: paymentAccountName("payment1"), - }}, - Metadata: map[string]string{ - moveToLedgerMetadata: "default", - }, - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - { - Activity: activities.GetWalletActivity, - Args: []any{mock.Anything, activities.GetWalletRequest{ - ID: "wallet1", - }}, - Returns: []any{ - &shared.GetWalletResponse{ - Data: shared.WalletWithBalances{ - ID: "wallet1", - Ledger: "default", - }, - }, nil, - }, - }, - { - Activity: activities.CreditWalletActivity, - Args: []any{ - mock.Anything, activities.CreditWalletRequest{ - ID: "wallet1", - Data: &activities.CreditWalletRequestPayload{ - Amount: shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - Sources: []shared.Subject{{ - LedgerAccountSubject: &shared.LedgerAccountSubject{ - Identifier: "world", - Type: "ACCOUNT", - }, - Type: shared.SubjectTypeAccount, - }}, - Balance: pointer.For("main"), - Metadata: map[string]string{ - moveFromLedgerMetadata: internalLedger, - }, - }, - }, - }, - Returns: []any{nil}, - }, - }, - } - paymentToWalletByName = stagestesting.WorkflowTestCase[Send]{ - Name: "payment to wallet by name", - Stage: Send{ - Source: NewSource().WithPayment(&PaymentSource{ - ID: "payment1", - }), - Destination: NewDestination().WithWallet(&WalletDestination{ - WalletReference: WalletReference{ - Name: "user:1", - }, - Balance: "main", - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.GetPaymentActivity, - Args: []any{mock.Anything, activities.GetPaymentRequest{ - ID: "payment1", - }}, - Returns: []any{ - &shared.PaymentResponse{ - Data: shared.Payment{ - InitialAmount: big.NewInt(100), - Asset: "USD", - Status: shared.PaymentStatusSucceeded, - Scheme: shared.PaymentSchemeUnknown, - Type: shared.PaymentTypeOther, - }, - }, nil, - }, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: internalLedger, - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: paymentAccountName("payment1"), - Source: "world", - }}, - Reference: pointer.For(paymentAccountName("payment1")), - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: internalLedger, - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: "world", - Source: paymentAccountName("payment1"), - }}, - Metadata: map[string]string{ - moveToLedgerMetadata: "default", - }, - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - { - Activity: activities.ListWalletsActivity, - Args: []any{mock.Anything, activities.ListWalletsRequest{ - Name: "user:1", - }}, - Returns: []any{ - &shared.ListWalletsResponse{ - Cursor: shared.ListWalletsResponseCursor{ - Data: []shared.Wallet{{ - ID: "wallet1", - Ledger: "default", - }}, - }, - }, nil, - }, - }, - { - Activity: activities.CreditWalletActivity, - Args: []any{ - mock.Anything, activities.CreditWalletRequest{ - ID: "wallet1", - Data: &activities.CreditWalletRequestPayload{ - Amount: shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - Sources: []shared.Subject{{ - LedgerAccountSubject: &shared.LedgerAccountSubject{ - Identifier: "world", - Type: "ACCOUNT", - }, - Type: shared.SubjectTypeAccount, - }}, - Balance: pointer.For("main"), - Metadata: map[string]string{ - moveFromLedgerMetadata: internalLedger, - }, - }, - }, - }, - Returns: []any{nil}, - }, - }, - } - paymentToAccount = stagestesting.WorkflowTestCase[Send]{ - Name: "payment to account", - Stage: Send{ - Source: NewSource().WithPayment(&PaymentSource{ - ID: "payment1", - }), - Destination: NewDestination().WithAccount(&LedgerAccountDestination{ - ID: "foo", - Ledger: "default", - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.GetPaymentActivity, - Args: []any{mock.Anything, activities.GetPaymentRequest{ - ID: "payment1", - }}, - Returns: []any{ - &shared.PaymentResponse{ - Data: shared.Payment{ - InitialAmount: big.NewInt(100), - Asset: "USD", - Status: shared.PaymentStatusSucceeded, - Scheme: shared.PaymentSchemeUnknown, - Type: shared.PaymentTypeOther, - }, - }, nil, - }, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: internalLedger, - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: paymentAccountName("payment1"), - Source: "world", - }}, - Reference: pointer.For(paymentAccountName("payment1")), - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: internalLedger, - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: "world", - Source: paymentAccountName("payment1"), - }}, - Metadata: map[string]string{ - moveToLedgerMetadata: "default", - }, - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: "default", - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: "foo", - Source: "world", - }}, - Metadata: map[string]string{ - moveFromLedgerMetadata: internalLedger, - }, - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - }, - } - paymentToAccountWithAlreadyUsedPayment = stagestesting.WorkflowTestCase[Send]{ - Name: "payment to account with already used payment", - Stage: Send{ - Source: NewSource().WithPayment(&PaymentSource{ - ID: "payment1", - }), - Destination: NewDestination().WithAccount(&LedgerAccountDestination{ - ID: "foo", - Ledger: "default", - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.GetPaymentActivity, - Args: []any{mock.Anything, activities.GetPaymentRequest{ - ID: "payment1", - }}, - Returns: []any{ - &shared.PaymentResponse{ - Data: shared.Payment{ - InitialAmount: big.NewInt(100), - Asset: "USD", - Status: shared.PaymentStatusSucceeded, - Scheme: shared.PaymentSchemeUnknown, - Type: shared.PaymentTypeOther, - }, - }, nil, - }, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: internalLedger, - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: paymentAccountName("payment1"), - Source: "world", - }}, - Reference: pointer.For(paymentAccountName("payment1")), - }, - }, - }, - Returns: []any{nil, temporal.NewApplicationError("", "CONFLICT", "")}, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: internalLedger, - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: "world", - Source: paymentAccountName("payment1"), - }}, - Metadata: map[string]string{ - moveToLedgerMetadata: "default", - }, - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: "default", - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: "foo", - Source: "world", - }}, - Metadata: map[string]string{ - moveFromLedgerMetadata: internalLedger, - }, - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - }, - } - accountToAccount = stagestesting.WorkflowTestCase[Send]{ - Name: "account to account", - Stage: Send{ - Source: NewSource().WithAccount(&LedgerAccountSource{ - ID: "foo", - Ledger: "default", - }), - Destination: NewDestination().WithAccount(&LedgerAccountDestination{ - ID: "bar", - Ledger: "default", - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - Metadata: map[string]string{ - "foo": "bar", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: "default", - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: "bar", - Source: "foo", - }}, - Metadata: map[string]string{ - "foo": "bar", - }, - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - }, - } - accountToAccountMixedLedger = stagestesting.WorkflowTestCase[Send]{ - Name: "account to account mixed ledger", - Stage: Send{ - Source: NewSource().WithAccount(&LedgerAccountSource{ - ID: "account1", - Ledger: "ledger1", - }), - Destination: NewDestination().WithAccount(&LedgerAccountDestination{ - ID: "account2", - Ledger: "ledger2", - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: "ledger1", - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: "world", - Source: "account1", - }}, - Metadata: map[string]string{ - moveToLedgerMetadata: "ledger2", - }, - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: "ledger2", - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: "account2", - Source: "world", - }}, - Metadata: map[string]string{ - moveFromLedgerMetadata: "ledger1", - }, - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - }, - } - accountToWallet = stagestesting.WorkflowTestCase[Send]{ - Name: "account to wallet", - Stage: Send{ - Source: NewSource().WithAccount(&LedgerAccountSource{ - ID: "foo", - Ledger: "default", - }), - Destination: NewDestination().WithWallet(&WalletDestination{ - WalletReference: WalletReference{ - ID: "bar", - }, - Balance: "main", - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.GetWalletActivity, - Args: []any{mock.Anything, activities.GetWalletRequest{ - ID: "bar", - }}, - Returns: []any{&shared.GetWalletResponse{ - Data: shared.WalletWithBalances{ - ID: "bar", - Ledger: "default", - }, - }, nil}, - }, - { - Activity: activities.CreditWalletActivity, - Args: []any{ - mock.Anything, activities.CreditWalletRequest{ - ID: "bar", - Data: &activities.CreditWalletRequestPayload{ - Amount: shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - Sources: []shared.Subject{{ - LedgerAccountSubject: &shared.LedgerAccountSubject{ - Identifier: "foo", - Type: "ACCOUNT", - }, - Type: shared.SubjectTypeAccount, - }}, - Balance: pointer.For("main"), - Metadata: map[string]string{}, - }, - }, - }, - Returns: []any{nil}, - }, - }, - } - accountToWalletMixedLedger = stagestesting.WorkflowTestCase[Send]{ - Name: "account to wallet mixed ledger", - Stage: Send{ - Source: NewSource().WithAccount(&LedgerAccountSource{ - ID: "account1", - Ledger: "ledger1", - }), - Destination: NewDestination().WithWallet(&WalletDestination{ - WalletReference: WalletReference{ - ID: "wallet", - }, - Balance: "main", - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.GetWalletActivity, - Args: []any{mock.Anything, activities.GetWalletRequest{ - ID: "wallet", - }}, - Returns: []any{&shared.GetWalletResponse{ - Data: shared.WalletWithBalances{ - Ledger: "ledger2", - ID: "wallet", - }, - }, nil}, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: "ledger1", - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: "world", - Source: "account1", - }}, - Metadata: map[string]string{ - moveToLedgerMetadata: "ledger2", - }, - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - { - Activity: activities.CreditWalletActivity, - Args: []any{ - mock.Anything, activities.CreditWalletRequest{ - ID: "wallet", - Data: &activities.CreditWalletRequestPayload{ - Amount: shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - Sources: []shared.Subject{{ - LedgerAccountSubject: &shared.LedgerAccountSubject{ - Identifier: "world", - Type: "ACCOUNT", - }, - Type: shared.SubjectTypeAccount, - }}, - Balance: pointer.For("main"), - Metadata: map[string]string{ - moveFromLedgerMetadata: "ledger1", - }, - }, - }, - }, - Returns: []any{nil}, - }, - }, - } - accountToPayment = stagestesting.WorkflowTestCase[Send]{ - Name: "account to payment", - Stage: Send{ - Source: NewSource().WithAccount(&LedgerAccountSource{ - ID: "foo", - Ledger: "default", - }), - Destination: NewDestination().WithPayment(&PaymentDestination{ - PSP: "stripe", - Metadata: "stripeConnectID", - ConnectorID: nil, - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.GetAccountActivity, - Args: []any{mock.Anything, activities.GetAccountRequest{ - Ledger: "default", - ID: "foo", - }}, - Returns: []any{&shared.AccountResponse{ - Data: shared.AccountWithVolumesAndBalances{ - Address: "foo", - Metadata: map[string]any{ - "stripeConnectID": "abcd", - }, - }, - }, nil}, - }, - { - Activity: activities.StripeTransferActivity, - Args: []any{ - mock.Anything, activities.StripeTransferRequest{ - Amount: big.NewInt(100), - Asset: pointer.For("USD"), - Destination: pointer.For("abcd"), - ConnectorID: nil, - WaitingValidation: pointer.For(false), - Metadata: map[string]string{}, - }, - }, - Returns: []any{nil}, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: "default", - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: "world", - Source: "foo", - }}, - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - }, - } - walletToAccount = stagestesting.WorkflowTestCase[Send]{ - Name: "wallet to account", - Stage: Send{ - Source: NewSource().WithWallet(&WalletSource{ - WalletReference: WalletReference{ - ID: "foo", - }, - Balance: "main", - }), - Destination: NewDestination().WithAccount(&LedgerAccountDestination{ - ID: "bar", - Ledger: "default", - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.GetWalletActivity, - Args: []any{mock.Anything, activities.GetWalletRequest{ - ID: "foo", - }}, - Returns: []any{&shared.GetWalletResponse{ - Data: shared.WalletWithBalances{ - ID: "foo", - Metadata: map[string]string{ - "stripeConnectID": "abcd", - }, - Ledger: "default", - }, - }, nil}, - }, - { - Activity: activities.DebitWalletActivity, - Args: []any{ - mock.Anything, activities.DebitWalletRequest{ - ID: "foo", - Data: &activities.DebitWalletRequestPayload{ - Amount: shared.Monetary{ - Asset: "USD", - Amount: big.NewInt(100), - }, - Destination: &shared.Subject{ - LedgerAccountSubject: &shared.LedgerAccountSubject{ - Identifier: "bar", - Type: "ACCOUNT", - }, - Type: shared.SubjectTypeAccount, - }, - Balances: []string{"main"}, - }, - }, - }, - Returns: []any{nil, nil}, - }, - }, - } - walletToAccountMixedLedger = stagestesting.WorkflowTestCase[Send]{ - Name: "wallet to account mixed ledger", - Stage: Send{ - Source: NewSource().WithWallet(&WalletSource{ - WalletReference: WalletReference{ - ID: "wallet", - }, - Balance: "main", - }), - Destination: NewDestination().WithAccount(&LedgerAccountDestination{ - ID: "account", - Ledger: "ledger2", - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.GetWalletActivity, - Args: []any{mock.Anything, activities.GetWalletRequest{ - ID: "wallet", - }}, - Returns: []any{&shared.GetWalletResponse{ - Data: shared.WalletWithBalances{ - ID: "wallet", - Ledger: "ledger1", - }, - }, nil}, - }, - { - Activity: activities.DebitWalletActivity, - Args: []any{ - mock.Anything, activities.DebitWalletRequest{ - ID: "wallet", - Data: &activities.DebitWalletRequestPayload{ - Amount: shared.Monetary{ - Asset: "USD", - Amount: big.NewInt(100), - }, - Balances: []string{"main"}, - Metadata: map[string]string{ - moveToLedgerMetadata: "ledger2", - }, - }, - }, - }, - Returns: []any{nil, nil}, - }, - { - Activity: activities.CreateTransactionActivity, - Args: []any{ - mock.Anything, activities.CreateTransactionRequest{ - Ledger: "ledger2", - Data: activities.PostTransaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD", - Destination: "account", - Source: "world", - }}, - Metadata: map[string]string{ - moveFromLedgerMetadata: "ledger1", - }, - }, - }, - }, - Returns: []any{&shared.V2CreateTransactionResponse{ - Data: shared.V2Transaction{}, - }, nil}, - }, - }, - } - walletToWallet = stagestesting.WorkflowTestCase[Send]{ - Name: "wallet to wallet", - Stage: Send{ - Source: NewSource().WithWallet(&WalletSource{ - WalletReference: WalletReference{ - ID: "foo", - }, - Balance: "main", - }), - Destination: NewDestination().WithWallet(&WalletDestination{ - WalletReference: WalletReference{ - ID: "bar", - }, - Balance: "main", - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.GetWalletActivity, - Args: []any{mock.Anything, activities.GetWalletRequest{ - ID: "foo", - }}, - Returns: []any{&shared.GetWalletResponse{ - Data: shared.WalletWithBalances{ - ID: "foo", - Ledger: "default", - }, - }, nil}, - }, - { - Activity: activities.GetWalletActivity, - Args: []any{mock.Anything, activities.GetWalletRequest{ - ID: "bar", - }}, - Returns: []any{&shared.GetWalletResponse{ - Data: shared.WalletWithBalances{ - Ledger: "default", - ID: "bar", - }, - }, nil}, - }, - { - Activity: activities.CreditWalletActivity, - Args: []any{ - mock.Anything, activities.CreditWalletRequest{ - ID: "bar", - Data: &activities.CreditWalletRequestPayload{ - Amount: shared.Monetary{ - Asset: "USD", - Amount: big.NewInt(100), - }, - Sources: []shared.Subject{{ - WalletSubject: &shared.WalletSubject{ - Type: "WALLET", - Identifier: "foo", - Balance: pointer.For("main"), - }, - Type: shared.SubjectTypeWallet, - }}, - Balance: pointer.For("main"), - Metadata: map[string]string{}, - }, - }, - }, - Returns: []any{nil}, - }, - }, - } - walletToWalletMixedLedger = stagestesting.WorkflowTestCase[Send]{ - Name: "wallet to wallet mixed ledger", - Stage: Send{ - Source: NewSource().WithWallet(&WalletSource{ - WalletReference: WalletReference{ - ID: "wallet1", - }, - Balance: "main", - }), - Destination: NewDestination().WithWallet(&WalletDestination{ - WalletReference: WalletReference{ - ID: "wallet2", - }, - Balance: "main", - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.GetWalletActivity, - Args: []any{mock.Anything, activities.GetWalletRequest{ - ID: "wallet1", - }}, - Returns: []any{&shared.GetWalletResponse{ - Data: shared.WalletWithBalances{ - Ledger: "ledger1", - ID: "wallet1", - }, - }, nil}, - }, - { - Activity: activities.GetWalletActivity, - Args: []any{mock.Anything, activities.GetWalletRequest{ - ID: "wallet2", - }}, - Returns: []any{&shared.GetWalletResponse{ - Data: shared.WalletWithBalances{ - Ledger: "ledger2", - ID: "wallet2", - }, - }, nil}, - }, - { - Activity: activities.DebitWalletActivity, - Args: []any{ - mock.Anything, activities.DebitWalletRequest{ - ID: "wallet1", - Data: &activities.DebitWalletRequestPayload{ - Amount: shared.Monetary{ - Asset: "USD", - Amount: big.NewInt(100), - }, - Metadata: map[string]string{ - moveToLedgerMetadata: "ledger2", - }, - Balances: []string{"main"}, - }, - }, - }, - Returns: []any{nil, nil}, - }, - { - Activity: activities.CreditWalletActivity, - Args: []any{ - mock.Anything, activities.CreditWalletRequest{ - ID: "wallet2", - Data: &activities.CreditWalletRequestPayload{ - Amount: shared.Monetary{ - Asset: "USD", - Amount: big.NewInt(100), - }, - Balance: pointer.For("main"), - Metadata: map[string]string{ - moveFromLedgerMetadata: "ledger1", - }, - }, - }, - }, - Returns: []any{nil}, - }, - }, - } - walletToPayment = stagestesting.WorkflowTestCase[Send]{ - Name: "wallet to payment", - Stage: Send{ - Source: NewSource().WithWallet(&WalletSource{ - WalletReference: WalletReference{ - ID: "foo", - }, - Balance: "main", - }), - Destination: NewDestination().WithPayment(&PaymentDestination{ - PSP: "stripe", - Metadata: "stripeConnectID", - ConnectorID: nil, - }), - Amount: &shared.Monetary{ - Amount: big.NewInt(100), - Asset: "USD", - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.GetWalletActivity, - Args: []any{mock.Anything, activities.GetWalletRequest{ - ID: "foo", - }}, - Returns: []any{&shared.GetWalletResponse{ - Data: shared.WalletWithBalances{ - ID: "foo", - Metadata: map[string]string{ - "stripeConnectID": "abcd", - }, - }, - }, nil}, - }, - { - Activity: activities.StripeTransferActivity, - Args: []any{ - mock.Anything, activities.StripeTransferRequest{ - Amount: big.NewInt(100), - Asset: pointer.For("USD"), - Destination: pointer.For("abcd"), - ConnectorID: nil, - WaitingValidation: pointer.For(false), - Metadata: map[string]string{}, - }, - }, - Returns: []any{nil}, - }, - { - Activity: activities.DebitWalletActivity, - Args: []any{ - mock.Anything, activities.DebitWalletRequest{ - ID: "foo", - Data: &activities.DebitWalletRequestPayload{ - Amount: shared.Monetary{ - Asset: "USD", - Amount: big.NewInt(100), - }, - Balances: []string{"main"}, - Metadata: map[string]string{}, - }, - }, - }, - Returns: []any{nil, nil}, - }, - }, - } -) - -var testCases = []stagestesting.WorkflowTestCase[Send]{ - paymentToWallet, - paymentToWalletByName, - paymentToAccount, - paymentToAccountWithAlreadyUsedPayment, - accountToAccount, - accountToAccountMixedLedger, - accountToWallet, - accountToWalletMixedLedger, - accountToPayment, - walletToAccount, - walletToAccountMixedLedger, - walletToWallet, - walletToWalletMixedLedger, - walletToPayment, -} - -func TestSend(t *testing.T) { - stagestesting.RunWorkflows(t, testCases...) -} diff --git a/ee/orchestration/internal/workflow/stages/send/send.go b/ee/orchestration/internal/workflow/stages/send/send.go deleted file mode 100644 index 22bc8584d3..0000000000 --- a/ee/orchestration/internal/workflow/stages/send/send.go +++ /dev/null @@ -1,106 +0,0 @@ -package send - -import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "github.com/formancehq/go-libs/metadata" - "github.com/formancehq/go-libs/time" - "github.com/formancehq/orchestration/internal/schema" - "github.com/formancehq/orchestration/internal/workflow/stages" -) - -type WalletReference struct { - ID string `json:"id"` - Name string `json:"name"` -} - -type WalletSource struct { - WalletReference - Balance string `json:"balance" spec:"default:main" validate:"required"` -} - -type WalletDestination = WalletSource - -type LedgerAccountSource struct { - ID string `json:"id" validate:"required"` - Ledger string `json:"ledger" spec:"default:default" validate:"required"` -} - -type LedgerAccountDestination = LedgerAccountSource - -type PaymentSource struct { - ID string `json:"id" validate:"required"` -} - -type PaymentDestination struct { - PSP string `json:"psp"` - Metadata string `json:"metadata" spec:"default:formanceAccountID"` - WaitingValidation bool `json:"waitingValidation" spec:"default:false"` - ConnectorID *string `json:"connectorId,omitempty"` -} - -type Source struct { - Wallet *WalletSource `json:"wallet,omitempty"` - Account *LedgerAccountSource `json:"account,omitempty"` - Payment *PaymentSource `json:"payment,omitempty"` -} - -func NewSource() *Source { - return &Source{} -} - -func (s Source) WithWallet(src *WalletSource) Source { - s.Wallet = src - return s -} - -func (s Source) WithPayment(src *PaymentSource) Source { - s.Payment = src - return s -} - -func (s Source) WithAccount(src *LedgerAccountSource) Source { - s.Account = src - return s -} - -type Destination struct { - Wallet *WalletDestination `json:"wallet,omitempty"` - Account *LedgerAccountDestination `json:"account,omitempty"` - Payment *PaymentDestination `json:"payment,omitempty"` -} - -func NewDestination() *Destination { - return &Destination{} -} - -func (s Destination) WithWallet(src *WalletDestination) Destination { - s.Wallet = src - return s -} - -func (s Destination) WithPayment(src *PaymentDestination) Destination { - s.Payment = src - return s -} - -func (s Destination) WithAccount(src *LedgerAccountDestination) Destination { - s.Account = src - return s -} - -type Send struct { - Source Source `json:"source"` - Destination Destination `json:"destination"` - Amount *shared.Monetary `json:"amount,omitempty"` - Metadata metadata.Metadata `json:"metadata,omitempty"` - Timestamp *time.Time `json:"timestamp"` -} - -func (s Send) GetWorkflow() any { - return RunSend -} - -func init() { - schema.RegisterOneOf(&Source{}, &Destination{}, &WalletReference{}) - stages.Register("send", Send{}) -} diff --git a/ee/orchestration/internal/workflow/stages/update/run.go b/ee/orchestration/internal/workflow/stages/update/run.go deleted file mode 100644 index 7f5d925e19..0000000000 --- a/ee/orchestration/internal/workflow/stages/update/run.go +++ /dev/null @@ -1,20 +0,0 @@ -package send - -import ( - "github.com/formancehq/orchestration/internal/workflow/activities" - "github.com/formancehq/orchestration/internal/workflow/stages/internal" - "go.temporal.io/sdk/workflow" -) - -func RunUpdate(ctx workflow.Context, update Update) (err error) { - switch { - case update.Account != nil: - return activities.AddAccountMetadata(internal.InfiniteRetryContext(ctx), activities.AddAccountMetadataRequest{ - Ledger: update.Account.Ledger, - Account: update.Account.ID, - Metadata: update.Account.Metadata, - }) - default: - panic("invalid update specification") - } -} diff --git a/ee/orchestration/internal/workflow/stages/update/run_test.go b/ee/orchestration/internal/workflow/stages/update/run_test.go deleted file mode 100644 index cb5d984507..0000000000 --- a/ee/orchestration/internal/workflow/stages/update/run_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package send - -import ( - "testing" - - "github.com/formancehq/orchestration/internal/workflow/activities" - "github.com/stretchr/testify/mock" - - "github.com/formancehq/orchestration/internal/workflow/stages/internal/stagestesting" -) - -func TestUpdateSchemaValidation(t *testing.T) { - stagestesting.TestSchemas(t, "update", []stagestesting.SchemaTestCase{ - { - Name: "nominal", - Data: map[string]any{ - "account": map[string]interface{}{ - "id": "merchant:${merchantID}", - "ledger": "demo", - "metadata": map[string]string{ - "formanceAccountID": "${paymentAccountID}", - }, - }, - }, - ExpectedResolved: Update{ - Account: &AccountUpdate{ - ID: "merchant:1234", - Ledger: "demo", - Metadata: map[string]string{ - "formanceAccountID": "ABCD", - }, - }, - }, - Variables: map[string]string{ - "merchantID": "1234", - "paymentAccountID": "ABCD", - }, - }, - }...) -} - -func TestUpdate(t *testing.T) { - stagestesting.RunWorkflows(t, - stagestesting.WorkflowTestCase[Update]{ - Stage: Update{ - Account: &AccountUpdate{ - ID: "abcd", - Ledger: "default", - Metadata: map[string]string{ - "foo": "bar", - }, - }, - }, - MockedActivities: []stagestesting.MockedActivity{ - { - Activity: activities.AddAccountMetadataActivity, - Args: []any{mock.Anything, activities.AddAccountMetadataRequest{ - Account: "abcd", - Ledger: "default", - Metadata: map[string]string{ - "foo": "bar", - }, - }}, - Returns: []any{nil}, - }, - }, - Name: "nominal", - }, - ) -} diff --git a/ee/orchestration/internal/workflow/stages/update/update.go b/ee/orchestration/internal/workflow/stages/update/update.go deleted file mode 100644 index 62e17479cc..0000000000 --- a/ee/orchestration/internal/workflow/stages/update/update.go +++ /dev/null @@ -1,25 +0,0 @@ -package send - -import ( - "github.com/formancehq/orchestration/internal/schema" - "github.com/formancehq/orchestration/internal/workflow/stages" -) - -type AccountUpdate struct { - ID string `json:"id" validate:"required"` - Ledger string `json:"ledger" validate:"required" spec:"default:main"` - Metadata map[string]string `json:"metadata" validate:"required"` -} - -type Update struct { - Account *AccountUpdate `json:"account,omitempty"` -} - -func (s Update) GetWorkflow() any { - return RunUpdate -} - -func init() { - schema.RegisterOneOf(&Update{}) - stages.Register("update", Update{}) -} diff --git a/ee/orchestration/internal/workflow/stages/wait_event/run.go b/ee/orchestration/internal/workflow/stages/wait_event/run.go deleted file mode 100644 index fd4220805f..0000000000 --- a/ee/orchestration/internal/workflow/stages/wait_event/run.go +++ /dev/null @@ -1,22 +0,0 @@ -package wait_event - -import ( - internalWorkflow "github.com/formancehq/orchestration/internal/workflow" - "go.temporal.io/sdk/workflow" -) - -func RunWaitEvent(ctx workflow.Context, waitEvent WaitEvent) error { - channel := workflow.GetSignalChannel(ctx, internalWorkflow.EventSignalName) - return workflow.Await(ctx, func() bool { - var signal internalWorkflow.Event - ok := channel.ReceiveAsync(&signal) - if !ok { - return false - } - if signal.Name != waitEvent.Event { - workflow.GetLogger(ctx).Debug("receive unexpected event", "event", signal.Name) - return false - } - return true - }) -} diff --git a/ee/orchestration/internal/workflow/stages/wait_event/wait_event.go b/ee/orchestration/internal/workflow/stages/wait_event/wait_event.go deleted file mode 100644 index f0cb786091..0000000000 --- a/ee/orchestration/internal/workflow/stages/wait_event/wait_event.go +++ /dev/null @@ -1,17 +0,0 @@ -package wait_event - -import ( - "github.com/formancehq/orchestration/internal/workflow/stages" -) - -type WaitEvent struct { - Event string `json:"event" validate:"required"` -} - -func (w WaitEvent) GetWorkflow() any { - return RunWaitEvent -} - -func init() { - stages.Register("wait_event", WaitEvent{}) -} diff --git a/ee/orchestration/internal/workflow/stages/wait_event/wait_event_test.go b/ee/orchestration/internal/workflow/stages/wait_event/wait_event_test.go deleted file mode 100644 index 7eed168c1d..0000000000 --- a/ee/orchestration/internal/workflow/stages/wait_event/wait_event_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package wait_event - -import ( - "testing" - "time" - - "github.com/formancehq/orchestration/internal/workflow" - "github.com/formancehq/orchestration/internal/workflow/stages/internal/stagestesting" - "go.temporal.io/sdk/testsuite" -) - -func TestWaitEventSchemaValidation(t *testing.T) { - stagestesting.TestSchemas(t, "wait_event", []stagestesting.SchemaTestCase{ - { - Data: map[string]any{ - "wait_event": map[string]any{}, - }, - ExpectedResolved: WaitEvent{}, - ExpectedValidationError: true, - }, - { - Name: "valid case", - Data: map[string]any{ - "event": "test", - }, - ExpectedResolved: WaitEvent{ - Event: "test", - }, - ExpectedValidationError: false, - }, - }...) -} - -func TestWaitEvent(t *testing.T) { - stagestesting.RunWorkflows(t, []stagestesting.WorkflowTestCase[WaitEvent]{ - { - Stage: WaitEvent{ - Event: "test", - }, - DelayedCallbacks: []stagestesting.DelayedCallback{{ - Fn: func(environment *testsuite.TestWorkflowEnvironment) func() { - return func() { - environment.SignalWorkflow(workflow.EventSignalName, workflow.Event{ - Name: "test", - }) - } - }, - Duration: 100 * time.Millisecond, - }}, - Name: "nominal", - }, - }...) -} diff --git a/ee/orchestration/internal/workflow/tracer.go b/ee/orchestration/internal/workflow/tracer.go deleted file mode 100644 index 6d6bcca886..0000000000 --- a/ee/orchestration/internal/workflow/tracer.go +++ /dev/null @@ -1,7 +0,0 @@ -package workflow - -import ( - "go.opentelemetry.io/otel" -) - -var Tracer = otel.Tracer("runner") diff --git a/ee/orchestration/internal/workflow/workflow.go b/ee/orchestration/internal/workflow/workflow.go deleted file mode 100644 index 66cb1eac23..0000000000 --- a/ee/orchestration/internal/workflow/workflow.go +++ /dev/null @@ -1,27 +0,0 @@ -package workflow - -import ( - "time" - - "github.com/google/uuid" - "github.com/uptrace/bun" -) - -type Workflow struct { - bun.BaseModel `bun:"table:workflows"` - ID string `json:"id" bun:",pk"` - Config Config `json:"config"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - DeletedAt *time.Time `json:"deletedAt"` -} - -func New(config Config) Workflow { - now := time.Now().Round(time.Nanosecond) - return Workflow{ - ID: uuid.NewString(), - Config: config, - CreatedAt: now, - UpdatedAt: now, - } -} diff --git a/ee/orchestration/main.go b/ee/orchestration/main.go deleted file mode 100644 index 4d6df937a5..0000000000 --- a/ee/orchestration/main.go +++ /dev/null @@ -1,9 +0,0 @@ -package main - -import ( - "github.com/formancehq/orchestration/cmd" -) - -func main() { - cmd.Execute() -} diff --git a/ee/orchestration/openapi.yaml b/ee/orchestration/openapi.yaml deleted file mode 100644 index 0431574f4e..0000000000 --- a/ee/orchestration/openapi.yaml +++ /dev/null @@ -1,3361 +0,0 @@ -openapi: 3.0.3 -info: - title: Formance Simple orchestration Service API - version: 0.1.0 -paths: - /_info: - get: - summary: Get server info - operationId: getServerInfo - tags: - - orchestration.v1 - responses: - "200": - description: Server information - content: - application/json: - schema: - $ref: '#/components/schemas/ServerInfo' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - /triggers: - get: - summary: List triggers - operationId: listTriggers - description: List triggers - tags: - - orchestration.v1 - parameters: - - name: name - in: query - description: search by name - required: false - schema: - type: string - responses: - "200": - description: List of triggers - content: - application/json: - schema: - $ref: '#/components/schemas/ListTriggersResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - post: - summary: Create trigger - operationId: createTrigger - description: Create trigger - tags: - - orchestration.v1 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/TriggerData' - responses: - "201": - description: Created trigger - content: - application/json: - schema: - $ref: '#/components/schemas/CreateTriggerResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /triggers/{triggerID}: - parameters: - - name: triggerID - description: The trigger id - in: path - schema: - type: string - required: true - get: - summary: Read trigger - operationId: readTrigger - description: Read trigger - tags: - - orchestration.v1 - responses: - "200": - description: A specific trigger - content: - application/json: - schema: - $ref: '#/components/schemas/ReadTriggerResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - delete: - summary: Delete trigger - operationId: deleteTrigger - description: Read trigger - tags: - - orchestration.v1 - responses: - "204": - description: Trigger deleted - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /triggers/{triggerID}/occurrences: - parameters: - - name: triggerID - description: The trigger id - in: path - schema: - type: string - required: true - get: - summary: List triggers occurrences - operationId: listTriggersOccurrences - description: List triggers occurrences - tags: - - orchestration.v1 - responses: - "200": - description: List of triggers occurrences - content: - application/json: - schema: - $ref: '#/components/schemas/ListTriggersOccurrencesResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - /workflows: - get: - summary: List registered workflows - operationId: listWorkflows - description: List registered workflows - tags: - - orchestration.v1 - responses: - "200": - description: List of workflows - content: - application/json: - schema: - $ref: '#/components/schemas/ListWorkflowsResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - post: - summary: Create workflow - operationId: createWorkflow - description: Create a workflow - tags: - - orchestration.v1 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/CreateWorkflowRequest' - responses: - "201": - description: Created workflow - content: - application/json: - schema: - $ref: '#/components/schemas/CreateWorkflowResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /workflows/{flowId}: - parameters: - - in: path - description: The flow id - name: flowId - schema: - type: string - example: xxx - required: true - get: - summary: Get a flow by id - tags: - - orchestration.v1 - description: Get a flow by id - operationId: getWorkflow - responses: - "200": - description: The workflow - content: - application/json: - schema: - $ref: '#/components/schemas/GetWorkflowResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - delete: - summary: Delete a flow by id - tags: - - orchestration.v1 - description: Delete a flow by id - operationId: deleteWorkflow - responses: - "204": - description: No content - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /workflows/{workflowID}/instances: - parameters: - - in: path - description: The flow id - name: workflowID - schema: - type: string - example: xxx - required: true - post: - description: Run workflow - summary: Run workflow - operationId: runWorkflow - parameters: - - in: query - name: wait - required: false - description: Wait end of the workflow before return - schema: - type: boolean - tags: - - orchestration.v1 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/RunWorkflowRequest' - responses: - "201": - description: The workflow instance - content: - application/json: - schema: - $ref: '#/components/schemas/RunWorkflowResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /instances: - get: - description: List instances of a workflow - summary: List instances of a workflow - operationId: listInstances - parameters: - - in: query - description: A workflow id - name: workflowID - schema: - type: string - example: xxx - required: false - - in: query - description: Filter running instances - name: running - schema: - type: boolean - example: true - required: false - tags: - - orchestration.v1 - responses: - "200": - description: List of workflow instances - content: - application/json: - schema: - $ref: '#/components/schemas/ListRunsResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - /instances/{instanceID}: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - get: - summary: Get a workflow instance by id - description: Get a workflow instance by id - operationId: getInstance - tags: - - orchestration.v1 - responses: - "200": - description: The workflow instance - content: - application/json: - schema: - $ref: '#/components/schemas/GetWorkflowInstanceResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - /instances/{instanceID}/events: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - post: - summary: Send an event to a running workflow - description: Send an event to a running workflow - operationId: sendEvent - tags: - - orchestration.v1 - requestBody: - content: - application/json: - schema: - type: object - required: - - name - properties: - name: - type: string - responses: - "204": - description: No content - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /instances/{instanceID}/abort: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - put: - summary: Cancel a running workflow - description: Cancel a running workflow - operationId: cancelEvent - tags: - - orchestration.v1 - responses: - "204": - description: No content - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /instances/{instanceID}/history: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - get: - summary: Get a workflow instance history by id - description: Get a workflow instance history by id - operationId: getInstanceHistory - tags: - - orchestration.v1 - responses: - "200": - description: The workflow instance history - content: - application/json: - schema: - $ref: '#/components/schemas/GetWorkflowInstanceHistoryResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - /instances/{instanceID}/stages/{number}/history: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - - in: path - description: The stage number - name: number - schema: - type: integer - example: 0 - required: true - get: - summary: Get a workflow instance stage history - description: Get a workflow instance stage history - operationId: getInstanceStageHistory - tags: - - orchestration.v1 - responses: - "200": - description: The workflow instance stage history - content: - application/json: - schema: - $ref: '#/components/schemas/GetWorkflowInstanceHistoryStageResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - /v2/_info: - get: - summary: Get server info - operationId: v2GetServerInfo - x-speakeasy-name-override: GetServerInfo - tags: - - orchestration.v2 - responses: - "200": - description: Server information - content: - application/json: - schema: - $ref: '#/components/schemas/V2ServerInfo' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - /v2/triggers: - get: - summary: List triggers - operationId: v2ListTriggers - description: List triggers - x-speakeasy-name-override: ListTriggers - tags: - - orchestration.v2 - parameters: - - $ref: '#/components/parameters/Cursor' - - $ref: '#/components/parameters/PageSize' - - name: name - in: query - description: search by name - required: false - schema: - type: string - responses: - "200": - description: List of triggers - content: - application/json: - schema: - $ref: '#/components/schemas/V2ListTriggersResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - post: - summary: Create trigger - operationId: v2CreateTrigger - description: Create trigger - x-speakeasy-name-override: CreateTrigger - tags: - - orchestration.v2 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/V2TriggerData' - responses: - "201": - description: Created trigger - content: - application/json: - schema: - $ref: '#/components/schemas/V2CreateTriggerResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/triggers/{triggerID}: - parameters: - - name: triggerID - description: The trigger id - in: path - schema: - type: string - required: true - get: - summary: Read trigger - operationId: v2ReadTrigger - description: Read trigger - x-speakeasy-name-override: ReadTrigger - tags: - - orchestration.v2 - responses: - "200": - description: A specific trigger - content: - application/json: - schema: - $ref: '#/components/schemas/V2ReadTriggerResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - delete: - summary: Delete trigger - operationId: v2DeleteTrigger - description: Read trigger - x-speakeasy-name-override: DeleteTrigger - tags: - - orchestration.v2 - responses: - "204": - description: Trigger deleted - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/triggers/{triggerID}/test: - parameters: - - name: triggerID - description: The trigger id - in: path - schema: - type: string - required: true - post: - summary: Test trigger - operationId: testTrigger - description: Test trigger - x-speakeasy-name-override: TestTrigger - tags: - - orchestration.v2 - requestBody: - content: - application/json: - schema: - type: object - additionalProperties: true - responses: - "200": - description: Test a trigger - content: - application/json: - schema: - $ref: '#/components/schemas/V2TestTriggerResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/triggers/{triggerID}/occurrences: - parameters: - - name: triggerID - description: The trigger id - in: path - schema: - type: string - required: true - get: - summary: List triggers occurrences - operationId: v2ListTriggersOccurrences - description: List triggers occurrences - x-speakeasy-name-override: ListTriggersOccurrences - tags: - - orchestration.v2 - parameters: - - $ref: '#/components/parameters/Cursor' - - $ref: '#/components/parameters/PageSize' - responses: - "200": - description: List of triggers occurrences - content: - application/json: - schema: - $ref: '#/components/schemas/V2ListTriggersOccurrencesResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - /v2/workflows: - get: - summary: List registered workflows - operationId: v2ListWorkflows - description: List registered workflows - x-speakeasy-name-override: ListWorkflows - tags: - - orchestration.v2 - parameters: - - $ref: '#/components/parameters/Cursor' - - $ref: '#/components/parameters/PageSize' - responses: - "200": - description: List of workflows - content: - application/json: - schema: - $ref: '#/components/schemas/V2ListWorkflowsResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - post: - summary: Create workflow - operationId: v2CreateWorkflow - description: Create a workflow - x-speakeasy-name-override: CreateWorkflow - tags: - - orchestration.v2 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/V2CreateWorkflowRequest' - responses: - "201": - description: Created workflow - content: - application/json: - schema: - $ref: '#/components/schemas/V2CreateWorkflowResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/workflows/{flowId}: - parameters: - - in: path - description: The flow id - name: flowId - schema: - type: string - example: xxx - required: true - get: - summary: Get a flow by id - tags: - - orchestration.v2 - description: Get a flow by id - operationId: v2GetWorkflow - x-speakeasy-name-override: GetWorkflow - responses: - "200": - description: The workflow - content: - application/json: - schema: - $ref: '#/components/schemas/V2GetWorkflowResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - delete: - summary: Delete a flow by id - tags: - - orchestration.v2 - description: Delete a flow by id - operationId: v2DeleteWorkflow - x-speakeasy-name-override: DeleteWorkflow - responses: - "204": - description: No content - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/workflows/{workflowID}/instances: - parameters: - - in: path - description: The flow id - name: workflowID - schema: - type: string - example: xxx - required: true - post: - description: Run workflow - summary: Run workflow - operationId: v2RunWorkflow - x-speakeasy-name-override: RunWorkflow - parameters: - - in: query - name: wait - required: false - description: Wait end of the workflow before return - schema: - type: boolean - tags: - - orchestration.v2 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/V2RunWorkflowRequest' - responses: - "201": - description: The workflow instance - content: - application/json: - schema: - $ref: '#/components/schemas/V2RunWorkflowResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/instances: - get: - description: List instances of a workflow - summary: List instances of a workflow - operationId: v2ListInstances - x-speakeasy-name-override: ListInstances - parameters: - - $ref: '#/components/parameters/Cursor' - - $ref: '#/components/parameters/PageSize' - - in: query - description: A workflow id - name: workflowID - schema: - type: string - example: xxx - required: false - - in: query - description: Filter running instances - name: running - schema: - type: boolean - example: true - required: false - tags: - - orchestration.v2 - responses: - "200": - description: List of workflow instances - content: - application/json: - schema: - $ref: '#/components/schemas/V2ListRunsResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - /v2/instances/{instanceID}: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - get: - summary: Get a workflow instance by id - description: Get a workflow instance by id - operationId: v2GetInstance - x-speakeasy-name-override: GetInstance - tags: - - orchestration.v2 - responses: - "200": - description: The workflow instance - content: - application/json: - schema: - $ref: '#/components/schemas/V2GetWorkflowInstanceResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - /v2/instances/{instanceID}/events: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - post: - summary: Send an event to a running workflow - description: Send an event to a running workflow - operationId: v2SendEvent - x-speakeasy-name-override: SendEvent - tags: - - orchestration.v2 - requestBody: - content: - application/json: - schema: - type: object - required: - - name - properties: - name: - type: string - responses: - "204": - description: No content - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/instances/{instanceID}/abort: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - put: - summary: Cancel a running workflow - description: Cancel a running workflow - operationId: v2CancelEvent - x-speakeasy-name-override: CancelEvent - tags: - - orchestration.v2 - responses: - "204": - description: No content - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/instances/{instanceID}/history: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - get: - summary: Get a workflow instance history by id - description: Get a workflow instance history by id - operationId: v2GetInstanceHistory - x-speakeasy-name-override: GetInstanceHistory - tags: - - orchestration.v2 - responses: - "200": - description: The workflow instance history - content: - application/json: - schema: - $ref: '#/components/schemas/V2GetWorkflowInstanceHistoryResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - /v2/instances/{instanceID}/stages/{number}/history: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - - in: path - description: The stage number - name: number - schema: - type: integer - example: 0 - required: true - get: - summary: Get a workflow instance stage history - description: Get a workflow instance stage history - operationId: v2GetInstanceStageHistory - x-speakeasy-name-override: GetInstanceStageHistory - tags: - - orchestration.v2 - responses: - "200": - description: The workflow instance stage history - content: - application/json: - schema: - $ref: '#/components/schemas/V2GetWorkflowInstanceHistoryStageResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read -components: - schemas: - ServerInfo: - type: object - required: - - version - properties: - version: - type: string - Error: - type: object - required: - - errorCode - - errorMessage - properties: - errorCode: - type: string - enum: - - VALIDATION - - NOT_FOUND - - INTERNAL - errorMessage: - type: string - WorkflowConfig: - type: object - required: - - stages - properties: - name: - type: string - stages: - type: array - items: - type: object - additionalProperties: {} - Workflow: - type: object - required: - - config - - createdAt - - updatedAt - - id - properties: - config: - $ref: '#/components/schemas/WorkflowConfig' - createdAt: - type: string - format: date-time - updatedAt: - type: string - format: date-time - id: - type: string - StageStatus: - type: object - required: - - stage - - instanceID - - startedAt - properties: - stage: - type: number - instanceID: - type: string - startedAt: - type: string - format: date-time - terminatedAt: - type: string - format: date-time - error: - type: string - WorkflowInstance: - type: object - required: - - workflowID - - id - - createdAt - - updatedAt - - terminated - properties: - workflowID: - type: string - id: - type: string - createdAt: - type: string - format: date-time - updatedAt: - type: string - format: date-time - status: - type: array - items: - $ref: '#/components/schemas/StageStatus' - terminated: - type: boolean - terminatedAt: - type: string - format: date-time - error: - type: string - WorkflowInstanceHistoryStage: - type: object - required: - - name - - input - - startedAt - - terminated - - attempt - properties: - name: - type: string - input: - $ref: '#/components/schemas/WorkflowInstanceHistoryStageInput' - output: - $ref: '#/components/schemas/WorkflowInstanceHistoryStageOutput' - error: - type: string - terminated: - type: boolean - startedAt: - type: string - format: date-time - terminatedAt: - type: string - format: date-time - lastFailure: - type: string - attempt: - type: integer - nextExecution: - type: string - format: date-time - WorkflowInstanceHistory: - type: object - required: - - name - - input - - terminated - - startedAt - properties: - name: - type: string - input: - $ref: '#/components/schemas/Stage' - error: - type: string - terminated: - type: boolean - startedAt: - type: string - format: date-time - terminatedAt: - type: string - format: date-time - WorkflowInstanceHistoryList: - type: array - items: - $ref: '#/components/schemas/WorkflowInstanceHistory' - WorkflowInstanceHistoryStageList: - type: array - items: - $ref: '#/components/schemas/WorkflowInstanceHistoryStage' - ListWorkflowsResponse: - type: object - properties: - data: - items: - $ref: '#/components/schemas/Workflow' - type: array - required: - - data - TriggerData: - type: object - required: - - event - - workflowID - properties: - event: - type: string - workflowID: - type: string - filter: - type: string - vars: - type: object - additionalProperties: true - name: - type: string - Trigger: - allOf: - - $ref: '#/components/schemas/TriggerData' - - type: object - required: - - id - - createdAt - properties: - id: - type: string - createdAt: - type: string - format: date-time - TriggerOccurrence: - type: object - required: - - triggerID - - date - - event - properties: - date: - type: string - format: date-time - workflowInstanceID: - type: string - workflowInstance: - $ref: '#/components/schemas/WorkflowInstance' - triggerID: - type: string - event: - type: object - additionalProperties: true - error: - type: string - ListTriggersOccurrencesResponse: - type: object - properties: - data: - items: - $ref: '#/components/schemas/TriggerOccurrence' - type: array - required: - - data - ListTriggersResponse: - type: object - properties: - data: - items: - $ref: '#/components/schemas/Trigger' - type: array - required: - - data - CreateWorkflowRequest: - $ref: '#/components/schemas/WorkflowConfig' - CreateWorkflowResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Workflow' - CreateTriggerResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Trigger' - RunWorkflowRequest: - type: object - additionalProperties: - type: string - RunWorkflowResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/WorkflowInstance' - ListRunsResponse: - required: - - data - properties: - data: - items: - $ref: '#/components/schemas/WorkflowInstance' - type: array - GetWorkflowResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Workflow' - GetWorkflowInstanceResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/WorkflowInstance' - GetWorkflowInstanceHistoryResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/WorkflowInstanceHistoryList' - GetWorkflowInstanceHistoryStageResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/WorkflowInstanceHistoryStageList' - StageSendSourceWallet: - type: object - required: - - id - properties: - id: - type: string - balance: - type: string - StageSendDestinationWallet: - $ref: '#/components/schemas/StageSendSourceWallet' - StageSendSourceAccount: - type: object - required: - - id - properties: - id: - type: string - ledger: - type: string - StageSendDestinationAccount: - $ref: '#/components/schemas/StageSendSourceAccount' - StageSendSourcePayment: - type: object - required: - - id - properties: - id: - type: string - StageSendDestinationPayment: - type: object - required: - - psp - properties: - psp: - type: string - StageSendSource: - type: object - properties: - wallet: - $ref: '#/components/schemas/StageSendSourceWallet' - account: - $ref: '#/components/schemas/StageSendSourceAccount' - payment: - $ref: '#/components/schemas/StageSendSourcePayment' - StageSendDestination: - type: object - properties: - wallet: - $ref: '#/components/schemas/StageSendDestinationWallet' - account: - $ref: '#/components/schemas/StageSendDestinationAccount' - payment: - $ref: '#/components/schemas/StageSendDestinationPayment' - StageSend: - type: object - properties: - amount: - $ref: '#/components/schemas/Monetary' - destination: - $ref: '#/components/schemas/StageSendDestination' - source: - $ref: '#/components/schemas/StageSendSource' - metadata: - type: object - additionalProperties: - type: string - timestamp: - type: string - format: date-time - StageDelay: - type: object - properties: - until: - type: string - format: date-time - duration: - type: string - StageWaitEvent: - type: object - required: - - event - properties: - event: - type: string - UpdateAccount: - type: object - properties: - id: - type: string - metadata: - type: object - additionalProperties: - type: string - ledger: - type: string - required: - - id - - ledger - - metadata - Update: - type: object - properties: - account: - $ref: '#/components/schemas/UpdateAccount' - Stage: - anyOf: - - $ref: '#/components/schemas/StageSend' - - $ref: '#/components/schemas/StageDelay' - - $ref: '#/components/schemas/StageWaitEvent' - - $ref: '#/components/schemas/Update' - StripeTransferRequest: - type: object - properties: - connectorID: - type: string - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - asset: - type: string - example: USD - destination: - type: string - example: acct_1Gqj58KZcSIg2N2q - waitingValidation: - type: boolean - example: false - default: false - metadata: - type: object - description: | - A set of key/value pairs that you can attach to a transfer object. - It can be useful for storing additional information about the transfer in a structured format. - example: - order_id: "6735" - ActivityStripeTransfer: - $ref: '#/components/schemas/StripeTransferRequest' - ActivityListWallets: - type: object - properties: - name: - type: string - ListWalletsResponse: - type: object - required: - - cursor - properties: - cursor: - allOf: - - $ref: '#/components/schemas/Cursor' - - properties: - data: - items: - $ref: '#/components/schemas/Wallet' - type: array - type: object - required: - - data - Wallet: - type: object - required: - - name - - id - - metadata - - createdAt - - ledger - properties: - id: - type: string - format: uuid - description: The unique ID of the wallet. - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - name: - type: string - createdAt: - type: string - format: date-time - ledger: - type: string - Cursor: - type: object - required: - - pageSize - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: "" - ActivityGetAccount: - type: object - required: - - id - - ledger - properties: - id: - type: string - ledger: - type: string - ActivityAddAccountMetadata: - type: object - properties: - id: - type: string - ledger: - type: string - metadata: - type: object - additionalProperties: - type: string - required: - - id - - ledger - - metadata - ActivityCreateTransaction: - type: object - properties: - ledger: - type: string - data: - $ref: '#/components/schemas/PostTransaction' - ActivityRevertTransaction: - type: object - required: - - id - - ledger - properties: - ledger: - type: string - id: - type: string - ActivityGetPayment: - type: object - required: - - id - properties: - id: - type: string - ActivityConfirmHold: - type: object - required: - - id - properties: - id: - type: string - ActivityCreditWallet: - type: object - properties: - id: - type: string - data: - $ref: '#/components/schemas/CreditWalletRequest' - CreditWalletRequest: - type: object - required: - - amount - - sources - - metadata - properties: - amount: - $ref: '#/components/schemas/Monetary' - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - reference: - type: string - sources: - type: array - items: - $ref: '#/components/schemas/Subject' - balance: - type: string - description: The balance to credit - timestamp: - type: string - format: date-time - example: - amount: - asset: USD/2 - amount: 100 - metadata: - key: "" - sources: [] - LedgerAccountSubject: - type: object - required: - - type - - identifier - properties: - type: - type: string - identifier: - type: string - WalletSubject: - type: object - required: - - type - - identifier - properties: - type: - type: string - identifier: - type: string - balance: - type: string - Subject: - discriminator: - propertyName: type - mapping: - ACCOUNT: '#/components/schemas/LedgerAccountSubject' - WALLET: '#/components/schemas/WalletSubject' - oneOf: - - $ref: '#/components/schemas/LedgerAccountSubject' - - $ref: '#/components/schemas/WalletSubject' - ActivityDebitWallet: - type: object - properties: - id: - type: string - data: - $ref: '#/components/schemas/DebitWalletRequest' - DebitWalletRequest: - type: object - required: - - amount - - metadata - properties: - amount: - $ref: '#/components/schemas/Monetary' - pending: - type: boolean - description: Set to true to create a pending hold. If false, the wallet will be debited immediately. - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - description: - type: string - destination: - $ref: '#/components/schemas/Subject' - balances: - type: array - items: - type: string - description: A targeted balance (use '*' for all) - timestamp: - type: string - format: date-time - description: cannot be used in conjunction with `pending` property - example: - amount: - asset: USD/2 - amount: 100 - metadata: - key: "" - pending: true - ActivityGetWallet: - type: object - required: - - id - properties: - id: - type: string - ActivityVoidHold: - type: object - required: - - id - properties: - id: - type: string - ActivityGetAccountOutput: - $ref: '#/components/schemas/AccountResponse' - ActivityCreateTransactionOutput: - $ref: '#/components/schemas/CreateTransactionResponse' - CreateTransactionResponse: - properties: - data: - $ref: '#/components/schemas/Transaction' - type: object - required: - - data - Transaction: - type: object - properties: - timestamp: - type: string - format: date-time - postings: - type: array - items: - $ref: '#/components/schemas/Posting' - reference: - type: string - example: ref:001 - metadata: - $ref: '#/components/schemas/Metadata' - id: - type: integer - format: bigint - minimum: 0 - reverted: - type: boolean - required: - - postings - - timestamp - - id - - metadata - - reverted - ActivityRevertTransactionOutput: - $ref: '#/components/schemas/RevertTransactionResponse' - RevertTransactionResponse: - $ref: '#/components/schemas/CreateTransactionResponse' - ActivityGetPaymentOutput: - $ref: '#/components/schemas/PaymentResponse' - PaymentResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Payment' - Payment: - type: object - required: - - id - - reference - - connectorID - - sourceAccountID - - destinationAccountID - - type - - status - - initialAmount - - scheme - - asset - - createdAt - - raw - - adjustments - - metadata - properties: - id: - type: string - example: XXX - reference: - type: string - sourceAccountID: - type: string - destinationAccountID: - type: string - connectorID: - type: string - provider: - $ref: '#/components/schemas/Connector' - type: - type: string - enum: - - PAY-IN - - PAYOUT - - TRANSFER - - OTHER - status: - $ref: '#/components/schemas/PaymentStatus' - initialAmount: - type: integer - format: bigint - minimum: 0 - example: 100 - scheme: - type: string - enum: - - visa - - mastercard - - amex - - diners - - discover - - jcb - - unionpay - - sepa debit - - sepa credit - - sepa - - apple pay - - google pay - - a2a - - ach debit - - ach - - rtp - - unknown - - other - asset: - type: string - example: USD - createdAt: - type: string - format: date-time - raw: - type: object - nullable: true - adjustments: - type: array - items: - $ref: '#/components/schemas/PaymentAdjustment' - metadata: - $ref: '#/components/schemas/PaymentMetadata' - Connector: - type: string - enum: - - STRIPE - - DUMMY-PAY - - WISE - - MODULR - - CURRENCY-CLOUD - - BANKING-CIRCLE - - MANGOPAY - - MONEYCORP - PaymentAdjustment: - type: object - required: - - status - - amount - - date - - raw - - absolute - properties: - status: - $ref: '#/components/schemas/PaymentStatus' - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - date: - type: string - format: date-time - raw: - type: object - absolute: - type: boolean - PaymentStatus: - type: string - enum: - - PENDING - - ACTIVE - - TERMINATED - - FAILED - - SUCCEEDED - - CANCELLED - PaymentMetadata: - type: object - properties: - key: - type: string - nullable: true - ActivityDebitWalletOutput: - $ref: '#/components/schemas/DebitWalletResponse' - DebitWalletResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Hold' - Hold: - type: object - required: - - id - - walletID - - metadata - - description - properties: - id: - type: string - format: uuid - description: The unique ID of the hold. - walletID: - type: string - description: The ID of the wallet the hold is associated with. - metadata: - type: object - description: Metadata associated with the hold. - additionalProperties: - type: string - description: - type: string - destination: - $ref: '#/components/schemas/Subject' - ActivityGetWalletOutput: - $ref: '#/components/schemas/GetWalletResponse' - GetWalletResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/WalletWithBalances' - WalletWithBalances: - type: object - required: - - name - - id - - metadata - - createdAt - - balances - - ledger - properties: - id: - type: string - format: uuid - description: The unique ID of the wallet. - metadata: - type: object - description: Metadata associated with the wallet. - additionalProperties: - type: string - name: - type: string - createdAt: - type: string - format: date-time - balances: - type: object - required: - - main - properties: - main: - $ref: '#/components/schemas/AssetHolder' - ledger: - type: string - AssetHolder: - type: object - required: - - assets - properties: - assets: - type: object - additionalProperties: - type: integer - format: bigint - WorkflowInstanceHistoryStageInput: - type: object - properties: - GetAccount: - $ref: '#/components/schemas/ActivityGetAccount' - AddAccountMetadata: - $ref: '#/components/schemas/ActivityAddAccountMetadata' - CreateTransaction: - $ref: '#/components/schemas/ActivityCreateTransaction' - RevertTransaction: - $ref: '#/components/schemas/ActivityRevertTransaction' - StripeTransfer: - $ref: '#/components/schemas/ActivityStripeTransfer' - GetPayment: - $ref: '#/components/schemas/ActivityGetPayment' - ConfirmHold: - $ref: '#/components/schemas/ActivityConfirmHold' - CreditWallet: - $ref: '#/components/schemas/ActivityCreditWallet' - DebitWallet: - $ref: '#/components/schemas/ActivityDebitWallet' - GetWallet: - $ref: '#/components/schemas/ActivityGetWallet' - VoidHold: - $ref: '#/components/schemas/ActivityVoidHold' - ListWallets: - $ref: '#/components/schemas/ActivityListWallets' - WorkflowInstanceHistoryStageOutput: - type: object - properties: - GetAccount: - $ref: '#/components/schemas/ActivityGetAccountOutput' - CreateTransaction: - $ref: '#/components/schemas/ActivityCreateTransactionOutput' - RevertTransaction: - $ref: '#/components/schemas/ActivityRevertTransactionOutput' - GetPayment: - $ref: '#/components/schemas/ActivityGetPaymentOutput' - DebitWallet: - $ref: '#/components/schemas/ActivityDebitWalletOutput' - GetWallet: - $ref: '#/components/schemas/ActivityGetWalletOutput' - ListWallets: - $ref: '#/components/schemas/ListWalletsResponse' - Monetary: - type: object - required: - - asset - - amount - properties: - asset: - type: string - description: The asset of the monetary value. - amount: - type: integer - format: bigint - description: The amount of the monetary value. - PostTransaction: - type: object - required: - - metadata - properties: - timestamp: - type: string - format: date-time - postings: - type: array - items: - $ref: '#/components/schemas/Posting' - script: - type: object - properties: - plain: - type: string - example: | - vars { - account $user - } - send [COIN 10] ( - source = @world - destination = $user - ) - vars: - type: object - properties: {} - additionalProperties: true - example: - user: users:042 - required: - - plain - reference: - type: string - example: ref:001 - metadata: - $ref: '#/components/schemas/Metadata' - Metadata: - type: object - additionalProperties: - type: string - example: - admin: "true" - Posting: - type: object - properties: - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - asset: - type: string - example: COIN - destination: - type: string - example: users:002 - source: - type: string - example: users:001 - required: - - amount - - asset - - destination - - source - AccountResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Account' - ReadTriggerResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Trigger' - Account: - type: object - required: - - address - - metadata - properties: - address: - type: string - example: users:001 - metadata: - type: object - properties: {} - additionalProperties: - type: string - example: - admin: "true" - volumes: - $ref: '#/components/schemas/Volumes' - effectiveVolumes: - $ref: '#/components/schemas/Volumes' - Volume: - type: object - properties: - input: - type: integer - format: bigint - output: - type: integer - format: bigint - balance: - type: integer - format: bigint - required: - - input - - output - example: - input: 100 - output: 20 - balance: 80 - Volumes: - type: object - additionalProperties: - $ref: '#/components/schemas/Volume' - example: - USD: - input: 100 - output: 10 - balance: 90 - EUR: - input: 100 - output: 10 - balance: 90 - V2ServerInfo: - type: object - required: - - version - properties: - version: - type: string - V2Error: - type: object - required: - - errorCode - - errorMessage - properties: - errorCode: - type: string - enum: - - VALIDATION - - NOT_FOUND - - INTERNAL - errorMessage: - type: string - V2WorkflowConfig: - type: object - required: - - stages - properties: - name: - type: string - stages: - type: array - items: - type: object - additionalProperties: {} - V2Workflow: - type: object - required: - - config - - createdAt - - updatedAt - - id - properties: - config: - $ref: '#/components/schemas/V2WorkflowConfig' - createdAt: - type: string - format: date-time - updatedAt: - type: string - format: date-time - id: - type: string - V2StageStatus: - type: object - required: - - stage - - instanceID - - startedAt - properties: - stage: - type: number - instanceID: - type: string - startedAt: - type: string - format: date-time - terminatedAt: - type: string - format: date-time - error: - type: string - V2WorkflowInstance: - type: object - required: - - workflowID - - id - - createdAt - - updatedAt - - terminated - properties: - workflowID: - type: string - id: - type: string - createdAt: - type: string - format: date-time - updatedAt: - type: string - format: date-time - status: - type: array - items: - $ref: '#/components/schemas/V2StageStatus' - terminated: - type: boolean - terminatedAt: - type: string - format: date-time - error: - type: string - V2WorkflowInstanceHistoryStage: - type: object - required: - - name - - input - - startedAt - - terminated - - attempt - properties: - name: - type: string - input: - $ref: '#/components/schemas/V2WorkflowInstanceHistoryStageInput' - output: - $ref: '#/components/schemas/V2WorkflowInstanceHistoryStageOutput' - error: - type: string - terminated: - type: boolean - startedAt: - type: string - format: date-time - terminatedAt: - type: string - format: date-time - lastFailure: - type: string - attempt: - type: integer - nextExecution: - type: string - format: date-time - V2WorkflowInstanceHistory: - type: object - required: - - name - - input - - terminated - - startedAt - properties: - name: - type: string - input: - $ref: '#/components/schemas/V2Stage' - error: - type: string - terminated: - type: boolean - startedAt: - type: string - format: date-time - terminatedAt: - type: string - format: date-time - V2WorkflowInstanceHistoryList: - type: array - items: - $ref: '#/components/schemas/V2WorkflowInstanceHistory' - V2WorkflowInstanceHistoryStageList: - type: array - items: - $ref: '#/components/schemas/V2WorkflowInstanceHistoryStage' - V2ListWorkflowsResponse: - type: object - properties: - cursor: - type: object - required: - - pageSize - - hasMore - - data - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: "" - data: - type: array - items: - $ref: '#/components/schemas/V2Workflow' - required: - - cursor - V2TriggerData: - type: object - required: - - event - - workflowID - properties: - event: - type: string - workflowID: - type: string - filter: - type: string - vars: - type: object - additionalProperties: true - name: - type: string - V2Trigger: - allOf: - - $ref: '#/components/schemas/V2TriggerData' - - type: object - required: - - id - - createdAt - properties: - id: - type: string - createdAt: - type: string - format: date-time - V2TriggerOccurrence: - type: object - required: - - triggerID - - date - - event - properties: - date: - type: string - format: date-time - workflowInstanceID: - type: string - workflowInstance: - $ref: '#/components/schemas/V2WorkflowInstance' - triggerID: - type: string - error: - type: string - event: - type: object - additionalProperties: true - V2ListTriggersOccurrencesResponse: - type: object - properties: - cursor: - type: object - required: - - pageSize - - hasMore - - data - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: "" - data: - type: array - items: - $ref: '#/components/schemas/V2TriggerOccurrence' - required: - - cursor - V2ListTriggersResponse: - type: object - properties: - cursor: - type: object - required: - - pageSize - - hasMore - - data - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: "" - data: - type: array - items: - $ref: '#/components/schemas/V2Trigger' - required: - - cursor - V2CreateWorkflowRequest: - $ref: '#/components/schemas/V2WorkflowConfig' - V2CreateWorkflowResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Workflow' - V2CreateTriggerResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Trigger' - V2RunWorkflowRequest: - type: object - additionalProperties: - type: string - V2RunWorkflowResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2WorkflowInstance' - V2ListRunsResponse: - type: object - properties: - cursor: - type: object - required: - - pageSize - - hasMore - - data - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: "" - data: - type: array - items: - $ref: '#/components/schemas/V2WorkflowInstance' - required: - - cursor - V2GetWorkflowResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Workflow' - V2GetWorkflowInstanceResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2WorkflowInstance' - V2GetWorkflowInstanceHistoryResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2WorkflowInstanceHistoryList' - V2GetWorkflowInstanceHistoryStageResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2WorkflowInstanceHistoryStageList' - V2StageSendSourceWallet: - type: object - required: - - id - properties: - id: - type: string - balance: - type: string - V2StageSendDestinationWallet: - $ref: '#/components/schemas/V2StageSendSourceWallet' - V2StageSendSourceAccount: - type: object - required: - - id - properties: - id: - type: string - ledger: - type: string - V2StageSendDestinationAccount: - $ref: '#/components/schemas/V2StageSendSourceAccount' - V2StageSendSourcePayment: - type: object - required: - - id - properties: - id: - type: string - V2StageSendDestinationPayment: - type: object - required: - - psp - properties: - psp: - type: string - V2StageSendSource: - type: object - properties: - wallet: - $ref: '#/components/schemas/V2StageSendSourceWallet' - account: - $ref: '#/components/schemas/V2StageSendSourceAccount' - payment: - $ref: '#/components/schemas/V2StageSendSourcePayment' - V2StageSendDestination: - type: object - properties: - wallet: - $ref: '#/components/schemas/V2StageSendDestinationWallet' - account: - $ref: '#/components/schemas/V2StageSendDestinationAccount' - payment: - $ref: '#/components/schemas/V2StageSendDestinationPayment' - V2StageSend: - type: object - properties: - amount: - $ref: '#/components/schemas/V2Monetary' - destination: - $ref: '#/components/schemas/V2StageSendDestination' - source: - $ref: '#/components/schemas/V2StageSendSource' - metadata: - type: object - additionalProperties: - type: string - timestamp: - type: string - format: date-time - V2StageDelay: - type: object - properties: - until: - type: string - format: date-time - duration: - type: string - V2StageWaitEvent: - type: object - required: - - event - properties: - event: - type: string - V2UpdateAccount: - type: object - properties: - id: - type: string - metadata: - type: object - additionalProperties: - type: string - ledger: - type: string - required: - - id - - ledger - - metadata - V2Update: - type: object - properties: - account: - $ref: '#/components/schemas/V2UpdateAccount' - V2Stage: - anyOf: - - $ref: '#/components/schemas/V2StageSend' - - $ref: '#/components/schemas/V2StageDelay' - - $ref: '#/components/schemas/V2StageWaitEvent' - - $ref: '#/components/schemas/V2Update' - V2StripeTransferRequest: - type: object - properties: - connectorID: - type: string - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - asset: - type: string - example: USD - destination: - type: string - example: acct_1Gqj58KZcSIg2N2q - waitingValidation: - type: boolean - example: false - default: false - metadata: - type: object - description: | - A set of key/value pairs that you can attach to a transfer object. - It can be useful for storing additional information about the transfer in a structured format. - example: - order_id: "6735" - V2ActivityStripeTransfer: - $ref: '#/components/schemas/V2StripeTransferRequest' - V2ActivityListWallets: - type: object - properties: - name: - type: string - V2ListWalletsResponse: - type: object - required: - - cursor - properties: - cursor: - allOf: - - $ref: '#/components/schemas/V2Cursor' - - properties: - data: - items: - $ref: '#/components/schemas/V2Wallet' - type: array - type: object - required: - - data - V2Wallet: - type: object - required: - - name - - id - - metadata - - createdAt - - ledger - properties: - id: - type: string - format: uuid - description: The unique ID of the wallet. - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - name: - type: string - createdAt: - type: string - format: date-time - ledger: - type: string - V2Cursor: - type: object - required: - - pageSize - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: "" - V2ActivityGetAccount: - type: object - required: - - id - - ledger - properties: - id: - type: string - ledger: - type: string - V2ActivityAddAccountMetadata: - type: object - properties: - id: - type: string - ledger: - type: string - metadata: - type: object - additionalProperties: - type: string - required: - - id - - ledger - - metadata - V2ActivityCreateTransaction: - type: object - properties: - ledger: - type: string - data: - $ref: '#/components/schemas/V2PostTransaction' - V2ActivityGetPayment: - type: object - required: - - id - properties: - id: - type: string - V2ActivityConfirmHold: - type: object - required: - - id - properties: - id: - type: string - V2ActivityCreditWallet: - type: object - properties: - id: - type: string - data: - $ref: '#/components/schemas/V2CreditWalletRequest' - V2CreditWalletRequest: - type: object - required: - - amount - - sources - - metadata - properties: - amount: - $ref: '#/components/schemas/V2Monetary' - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - reference: - type: string - sources: - type: array - items: - $ref: '#/components/schemas/V2Subject' - balance: - type: string - description: The balance to credit - timestamp: - type: string - format: date-time - example: - amount: - asset: USD/2 - amount: 100 - metadata: - key: "" - sources: [] - V2LedgerAccountSubject: - type: object - required: - - type - - identifier - properties: - type: - type: string - identifier: - type: string - V2WalletSubject: - type: object - required: - - type - - identifier - properties: - type: - type: string - identifier: - type: string - balance: - type: string - V2Subject: - discriminator: - propertyName: type - mapping: - ACCOUNT: '#/components/schemas/V2LedgerAccountSubject' - WALLET: '#/components/schemas/V2WalletSubject' - oneOf: - - $ref: '#/components/schemas/V2LedgerAccountSubject' - - $ref: '#/components/schemas/V2WalletSubject' - V2ActivityDebitWallet: - type: object - properties: - id: - type: string - data: - $ref: '#/components/schemas/V2DebitWalletRequest' - V2DebitWalletRequest: - type: object - required: - - amount - - metadata - properties: - amount: - $ref: '#/components/schemas/V2Monetary' - pending: - type: boolean - description: Set to true to create a pending hold. If false, the wallet will be debited immediately. - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - description: - type: string - destination: - $ref: '#/components/schemas/V2Subject' - balances: - type: array - items: - type: string - description: A targeted balance (use '*' for all) - timestamp: - type: string - format: date-time - description: cannot be used in conjunction with `pending` property - example: - amount: - asset: USD/2 - amount: 100 - metadata: - key: "" - pending: true - V2ActivityGetWallet: - type: object - required: - - id - properties: - id: - type: string - V2ActivityVoidHold: - type: object - required: - - id - properties: - id: - type: string - V2ActivityGetAccountOutput: - $ref: '#/components/schemas/V2AccountResponse' - V2ActivityCreateTransactionOutput: - $ref: '#/components/schemas/V2CreateTransactionResponse' - V2CreateTransactionResponse: - properties: - data: - type: array - items: - $ref: '#/components/schemas/V2Transaction' - type: object - required: - - data - V2Transaction: - type: object - properties: - timestamp: - type: string - format: date-time - postings: - type: array - items: - $ref: '#/components/schemas/V2Posting' - reference: - type: string - example: ref:001 - metadata: - $ref: '#/components/schemas/V2Metadata' - txid: - type: integer - format: bigint - minimum: 0 - required: - - postings - - timestamp - - txid - - metadata - V2ActivityGetPaymentOutput: - $ref: '#/components/schemas/V2PaymentResponse' - V2PaymentResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Payment' - V2Payment: - type: object - required: - - id - - reference - - connectorID - - sourceAccountID - - destinationAccountID - - type - - status - - initialAmount - - scheme - - asset - - createdAt - - raw - - adjustments - - metadata - properties: - id: - type: string - example: XXX - reference: - type: string - sourceAccountID: - type: string - destinationAccountID: - type: string - connectorID: - type: string - provider: - $ref: '#/components/schemas/V2Connector' - type: - type: string - enum: - - PAY-IN - - PAYOUT - - TRANSFER - - OTHER - status: - $ref: '#/components/schemas/V2PaymentStatus' - initialAmount: - type: integer - format: bigint - minimum: 0 - example: 100 - scheme: - type: string - enum: - - visa - - mastercard - - amex - - diners - - discover - - jcb - - unionpay - - sepa debit - - sepa credit - - sepa - - apple pay - - google pay - - a2a - - ach debit - - ach - - rtp - - unknown - - other - asset: - type: string - example: USD - createdAt: - type: string - format: date-time - raw: - type: object - nullable: true - adjustments: - type: array - items: - $ref: '#/components/schemas/V2PaymentAdjustment' - metadata: - $ref: '#/components/schemas/V2PaymentMetadata' - V2Connector: - type: string - enum: - - STRIPE - - DUMMY-PAY - - WISE - - MODULR - - CURRENCY-CLOUD - - BANKING-CIRCLE - - MANGOPAY - - MONEYCORP - V2PaymentAdjustment: - type: object - required: - - status - - amount - - date - - raw - - absolute - properties: - status: - $ref: '#/components/schemas/V2PaymentStatus' - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - date: - type: string - format: date-time - raw: - type: object - absolute: - type: boolean - V2PaymentStatus: - type: string - enum: - - PENDING - - ACTIVE - - TERMINATED - - FAILED - - SUCCEEDED - - CANCELLED - V2PaymentMetadata: - type: object - properties: - key: - type: string - nullable: true - V2ActivityDebitWalletOutput: - $ref: '#/components/schemas/V2DebitWalletResponse' - V2DebitWalletResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Hold' - V2Hold: - type: object - required: - - id - - walletID - - metadata - - description - properties: - id: - type: string - format: uuid - description: The unique ID of the hold. - walletID: - type: string - description: The ID of the wallet the hold is associated with. - metadata: - type: object - description: Metadata associated with the hold. - additionalProperties: - type: string - description: - type: string - destination: - $ref: '#/components/schemas/V2Subject' - V2ActivityGetWalletOutput: - $ref: '#/components/schemas/V2GetWalletResponse' - V2GetWalletResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2WalletWithBalances' - V2WalletWithBalances: - type: object - required: - - name - - id - - metadata - - createdAt - - balances - - ledger - properties: - id: - type: string - format: uuid - description: The unique ID of the wallet. - metadata: - type: object - description: Metadata associated with the wallet. - additionalProperties: - type: string - name: - type: string - createdAt: - type: string - format: date-time - balances: - type: object - required: - - main - properties: - main: - $ref: '#/components/schemas/V2AssetHolder' - ledger: - type: string - V2AssetHolder: - type: object - required: - - assets - properties: - assets: - type: object - additionalProperties: - type: integer - format: bigint - V2WorkflowInstanceHistoryStageInput: - type: object - properties: - GetAccount: - $ref: '#/components/schemas/V2ActivityGetAccount' - AddAccountMetadata: - $ref: '#/components/schemas/V2ActivityAddAccountMetadata' - CreateTransaction: - $ref: '#/components/schemas/V2ActivityCreateTransaction' - StripeTransfer: - $ref: '#/components/schemas/V2ActivityStripeTransfer' - GetPayment: - $ref: '#/components/schemas/V2ActivityGetPayment' - ConfirmHold: - $ref: '#/components/schemas/V2ActivityConfirmHold' - CreditWallet: - $ref: '#/components/schemas/V2ActivityCreditWallet' - DebitWallet: - $ref: '#/components/schemas/V2ActivityDebitWallet' - GetWallet: - $ref: '#/components/schemas/V2ActivityGetWallet' - VoidHold: - $ref: '#/components/schemas/V2ActivityVoidHold' - ListWallets: - $ref: '#/components/schemas/V2ActivityListWallets' - V2WorkflowInstanceHistoryStageOutput: - type: object - properties: - GetAccount: - $ref: '#/components/schemas/V2ActivityGetAccountOutput' - CreateTransaction: - $ref: '#/components/schemas/V2ActivityCreateTransactionOutput' - GetPayment: - $ref: '#/components/schemas/V2ActivityGetPaymentOutput' - DebitWallet: - $ref: '#/components/schemas/V2ActivityDebitWalletOutput' - GetWallet: - $ref: '#/components/schemas/V2ActivityGetWalletOutput' - ListWallets: - $ref: '#/components/schemas/V2ListWalletsResponse' - V2Monetary: - type: object - required: - - asset - - amount - properties: - asset: - type: string - description: The asset of the monetary value. - amount: - type: integer - format: bigint - description: The amount of the monetary value. - V2PostTransaction: - type: object - required: - - metadata - properties: - timestamp: - type: string - format: date-time - postings: - type: array - items: - $ref: '#/components/schemas/V2Posting' - script: - type: object - properties: - plain: - type: string - example: | - vars { - account $user - } - send [COIN 10] ( - source = @world - destination = $user - ) - vars: - type: object - properties: {} - additionalProperties: true - example: - user: users:042 - required: - - plain - reference: - type: string - example: ref:001 - metadata: - $ref: '#/components/schemas/V2Metadata' - V2Metadata: - type: object - additionalProperties: - type: string - example: - admin: "true" - V2Posting: - type: object - properties: - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - asset: - type: string - example: COIN - destination: - type: string - example: users:002 - source: - type: string - example: users:001 - required: - - amount - - asset - - destination - - source - V2AccountResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Account' - V2ReadTriggerResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Trigger' - V2Account: - type: object - required: - - address - - metadata - properties: - address: - type: string - example: users:001 - metadata: - type: object - properties: {} - additionalProperties: - type: string - example: - admin: "true" - volumes: - $ref: '#/components/schemas/V2Volumes' - effectiveVolumes: - $ref: '#/components/schemas/V2Volumes' - V2Volume: - type: object - properties: - input: - type: integer - format: bigint - output: - type: integer - format: bigint - balance: - type: integer - format: bigint - required: - - input - - output - example: - input: 100 - output: 20 - balance: 80 - V2Volumes: - type: object - additionalProperties: - $ref: '#/components/schemas/V2Volume' - example: - USD: - input: 100 - output: 10 - balance: 90 - EUR: - input: 100 - output: 10 - balance: 90 - V2TestTriggerResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2TriggerTest' - V2TriggerTest: - type: object - properties: - filter: - type: object - properties: - match: - type: boolean - error: - type: string - variables: - type: object - additionalProperties: - type: object - properties: - value: - type: string - error: - type: string - responses: - ErrorResponse: - description: General error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - V2ErrorResponse: - description: General error - content: - application/json: - schema: - $ref: '#/components/schemas/V2Error' - parameters: - Cursor: - name: cursor - in: query - description: | - Parameter used in pagination requests. - Set to the value of next for the next page of results. - Set to the value of previous for the previous page of results. - No other parameters can be set when this parameter is set. - schema: - type: string - example: aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== - PageSize: - name: pageSize - in: query - description: | - The maximum number of results to return per page. - example: 100 - schema: - type: integer - format: int64 - minimum: 1 - maximum: 1000 diff --git a/ee/orchestration/openapi/openapi-merge.json b/ee/orchestration/openapi/openapi-merge.json deleted file mode 100644 index 14511edede..0000000000 --- a/ee/orchestration/openapi/openapi-merge.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "inputs": [ - { - "inputFile": "./v1.yaml" - }, - { - "inputFile": "./v2.yaml" - } - ], - "output": "./../openapi.json" -} diff --git a/ee/orchestration/openapi/v1.yaml b/ee/orchestration/openapi/v1.yaml deleted file mode 100644 index 9f1aa06e76..0000000000 --- a/ee/orchestration/openapi/v1.yaml +++ /dev/null @@ -1,1592 +0,0 @@ -openapi: 3.0.3 -info: - title: Formance Simple orchestration Service API - version: 0.1.0 -paths: - /_info: - get: - summary: Get server info - operationId: getServerInfo - tags: - - orchestration.v1 - responses: - '200': - description: Server information - content: - application/json: - schema: - $ref: '#/components/schemas/ServerInfo' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - /triggers: - get: - summary: List triggers - operationId: listTriggers - description: List triggers - tags: - - orchestration.v1 - parameters: - - name: name - in: query - description: search by name - required: false - schema: - type: string - responses: - '200': - description: List of triggers - content: - application/json: - schema: - $ref: '#/components/schemas/ListTriggersResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - post: - summary: Create trigger - operationId: createTrigger - description: Create trigger - tags: - - orchestration.v1 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/TriggerData' - responses: - '201': - description: Created trigger - content: - application/json: - schema: - $ref: '#/components/schemas/CreateTriggerResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /triggers/{triggerID}: - parameters: - - name: triggerID - description: The trigger id - in: path - schema: - type: string - required: true - get: - summary: Read trigger - operationId: readTrigger - description: Read trigger - tags: - - orchestration.v1 - responses: - '200': - description: A specific trigger - content: - application/json: - schema: - $ref: '#/components/schemas/ReadTriggerResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - delete: - summary: Delete trigger - operationId: deleteTrigger - description: Read trigger - tags: - - orchestration.v1 - responses: - '204': - description: Trigger deleted - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /triggers/{triggerID}/occurrences: - parameters: - - name: triggerID - description: The trigger id - in: path - schema: - type: string - required: true - get: - summary: List triggers occurrences - operationId: listTriggersOccurrences - description: List triggers occurrences - tags: - - orchestration.v1 - responses: - '200': - description: List of triggers occurrences - content: - application/json: - schema: - $ref: '#/components/schemas/ListTriggersOccurrencesResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - /workflows: - get: - summary: List registered workflows - operationId: listWorkflows - description: List registered workflows - tags: - - orchestration.v1 - responses: - '200': - description: List of workflows - content: - application/json: - schema: - $ref: '#/components/schemas/ListWorkflowsResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - post: - summary: Create workflow - operationId: createWorkflow - description: Create a workflow - tags: - - orchestration.v1 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/CreateWorkflowRequest' - responses: - '201': - description: Created workflow - content: - application/json: - schema: - $ref: '#/components/schemas/CreateWorkflowResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /workflows/{flowId}: - parameters: - - in: path - description: The flow id - name: flowId - schema: - type: string - example: xxx - required: true - get: - summary: Get a flow by id - tags: - - orchestration.v1 - description: Get a flow by id - operationId: getWorkflow - responses: - '200': - description: The workflow - content: - application/json: - schema: - $ref: '#/components/schemas/GetWorkflowResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - delete: - summary: Delete a flow by id - tags: - - orchestration.v1 - description: Delete a flow by id - operationId: deleteWorkflow - responses: - '204': - description: No content - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /workflows/{workflowID}/instances: - parameters: - - in: path - description: The flow id - name: workflowID - schema: - type: string - example: xxx - required: true - post: - description: Run workflow - summary: Run workflow - operationId: runWorkflow - parameters: - - in: query - name: wait - required: false - description: Wait end of the workflow before return - schema: - type: boolean - tags: - - orchestration.v1 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/RunWorkflowRequest' - responses: - '201': - description: The workflow instance - content: - application/json: - schema: - $ref: '#/components/schemas/RunWorkflowResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /instances: - get: - description: List instances of a workflow - summary: List instances of a workflow - operationId: listInstances - parameters: - - in: query - description: A workflow id - name: workflowID - schema: - type: string - example: xxx - required: false - - in: query - description: Filter running instances - name: running - schema: - type: boolean - example: true - required: false - tags: - - orchestration.v1 - responses: - '200': - description: List of workflow instances - content: - application/json: - schema: - $ref: '#/components/schemas/ListRunsResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - /instances/{instanceID}: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - get: - summary: Get a workflow instance by id - description: Get a workflow instance by id - operationId: getInstance - tags: - - orchestration.v1 - responses: - '200': - description: The workflow instance - content: - application/json: - schema: - $ref: '#/components/schemas/GetWorkflowInstanceResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - /instances/{instanceID}/events: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - post: - summary: Send an event to a running workflow - description: Send an event to a running workflow - operationId: sendEvent - tags: - - orchestration.v1 - requestBody: - content: - application/json: - schema: - type: object - required: - - name - properties: - name: - type: string - responses: - '204': - description: No content - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /instances/{instanceID}/abort: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - put: - summary: Cancel a running workflow - description: Cancel a running workflow - operationId: cancelEvent - tags: - - orchestration.v1 - responses: - '204': - description: No content - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:write - /instances/{instanceID}/history: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - get: - summary: Get a workflow instance history by id - description: Get a workflow instance history by id - operationId: getInstanceHistory - tags: - - orchestration.v1 - responses: - '200': - description: The workflow instance history - content: - application/json: - schema: - $ref: '#/components/schemas/GetWorkflowInstanceHistoryResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read - /instances/{instanceID}/stages/{number}/history: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - - in: path - description: The stage number - name: number - schema: - type: integer - example: 0 - required: true - get: - summary: Get a workflow instance stage history - description: Get a workflow instance stage history - operationId: getInstanceStageHistory - tags: - - orchestration.v1 - responses: - '200': - description: The workflow instance stage history - content: - application/json: - schema: - $ref: '#/components/schemas/GetWorkflowInstanceHistoryStageResponse' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - orchestration:read -components: - schemas: - ServerInfo: - type: object - required: - - version - properties: - version: - type: string - Error: - type: object - required: - - errorCode - - errorMessage - properties: - errorCode: - type: string - enum: - - VALIDATION - - NOT_FOUND - - INTERNAL - errorMessage: - type: string - WorkflowConfig: - type: object - required: - - stages - properties: - name: - type: string - stages: - type: array - items: - type: object - additionalProperties: {} - Workflow: - type: object - required: - - config - - createdAt - - updatedAt - - id - properties: - config: - $ref: '#/components/schemas/WorkflowConfig' - createdAt: - type: string - format: date-time - updatedAt: - type: string - format: date-time - id: - type: string - StageStatus: - type: object - required: - - stage - - instanceID - - startedAt - properties: - stage: - type: number - instanceID: - type: string - startedAt: - type: string - format: date-time - terminatedAt: - type: string - format: date-time - error: - type: string - WorkflowInstance: - type: object - required: - - workflowID - - id - - createdAt - - updatedAt - - terminated - properties: - workflowID: - type: string - id: - type: string - createdAt: - type: string - format: date-time - updatedAt: - type: string - format: date-time - status: - type: array - items: - $ref: '#/components/schemas/StageStatus' - terminated: - type: boolean - terminatedAt: - type: string - format: date-time - error: - type: string - WorkflowInstanceHistoryStage: - type: object - required: - - name - - input - - startedAt - - terminated - - attempt - properties: - name: - type: string - input: - $ref: '#/components/schemas/WorkflowInstanceHistoryStageInput' - output: - $ref: '#/components/schemas/WorkflowInstanceHistoryStageOutput' - error: - type: string - terminated: - type: boolean - startedAt: - type: string - format: date-time - terminatedAt: - type: string - format: date-time - lastFailure: - type: string - attempt: - type: integer - nextExecution: - type: string - format: date-time - WorkflowInstanceHistory: - type: object - required: - - name - - input - - terminated - - startedAt - properties: - name: - type: string - input: - $ref: '#/components/schemas/Stage' - error: - type: string - terminated: - type: boolean - startedAt: - type: string - format: date-time - terminatedAt: - type: string - format: date-time - WorkflowInstanceHistoryList: - type: array - items: - $ref: '#/components/schemas/WorkflowInstanceHistory' - WorkflowInstanceHistoryStageList: - type: array - items: - $ref: '#/components/schemas/WorkflowInstanceHistoryStage' - ListWorkflowsResponse: - type: object - properties: - data: - items: - $ref: '#/components/schemas/Workflow' - type: array - required: - - data - TriggerData: - type: object - required: - - event - - workflowID - properties: - event: - type: string - workflowID: - type: string - filter: - type: string - vars: - type: object - additionalProperties: true - name: - type: string - Trigger: - allOf: - - $ref: '#/components/schemas/TriggerData' - - type: object - required: - - id - - createdAt - properties: - id: - type: string - createdAt: - type: string - format: date-time - TriggerOccurrence: - type: object - required: - - triggerID - - date - - event - properties: - date: - type: string - format: date-time - workflowInstanceID: - type: string - workflowInstance: - $ref: '#/components/schemas/WorkflowInstance' - triggerID: - type: string - event: - type: object - additionalProperties: true - error: - type: string - ListTriggersOccurrencesResponse: - type: object - properties: - data: - items: - $ref: '#/components/schemas/TriggerOccurrence' - type: array - required: - - data - ListTriggersResponse: - type: object - properties: - data: - items: - $ref: '#/components/schemas/Trigger' - type: array - required: - - data - CreateWorkflowRequest: - $ref: '#/components/schemas/WorkflowConfig' - CreateWorkflowResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Workflow' - CreateTriggerResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Trigger' - RunWorkflowRequest: - type: object - additionalProperties: - type: string - RunWorkflowResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/WorkflowInstance' - ListRunsResponse: - required: - - data - properties: - data: - items: - $ref: '#/components/schemas/WorkflowInstance' - type: array - GetWorkflowResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Workflow' - GetWorkflowInstanceResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/WorkflowInstance' - GetWorkflowInstanceHistoryResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/WorkflowInstanceHistoryList' - GetWorkflowInstanceHistoryStageResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/WorkflowInstanceHistoryStageList' - StageSendSourceWallet: - type: object - required: - - id - properties: - id: - type: string - balance: - type: string - StageSendDestinationWallet: - $ref: '#/components/schemas/StageSendSourceWallet' - StageSendSourceAccount: - type: object - required: - - id - properties: - id: - type: string - ledger: - type: string - StageSendDestinationAccount: - $ref: '#/components/schemas/StageSendSourceAccount' - StageSendSourcePayment: - type: object - required: - - id - properties: - id: - type: string - StageSendDestinationPayment: - type: object - required: - - psp - properties: - psp: - type: string - StageSendSource: - type: object - properties: - wallet: - $ref: '#/components/schemas/StageSendSourceWallet' - account: - $ref: '#/components/schemas/StageSendSourceAccount' - payment: - $ref: '#/components/schemas/StageSendSourcePayment' - StageSendDestination: - type: object - properties: - wallet: - $ref: '#/components/schemas/StageSendDestinationWallet' - account: - $ref: '#/components/schemas/StageSendDestinationAccount' - payment: - $ref: '#/components/schemas/StageSendDestinationPayment' - StageSend: - type: object - properties: - amount: - $ref: '#/components/schemas/Monetary' - destination: - $ref: '#/components/schemas/StageSendDestination' - source: - $ref: '#/components/schemas/StageSendSource' - metadata: - type: object - additionalProperties: - type: string - timestamp: - type: string - format: date-time - StageDelay: - type: object - properties: - until: - type: string - format: date-time - duration: - type: string - StageWaitEvent: - type: object - required: - - event - properties: - event: - type: string - UpdateAccount: - type: object - properties: - id: - type: string - metadata: - type: object - additionalProperties: - type: string - ledger: - type: string - required: - - id - - ledger - - metadata - Update: - type: object - properties: - account: - $ref: '#/components/schemas/UpdateAccount' - Stage: - anyOf: - - $ref: '#/components/schemas/StageSend' - - $ref: '#/components/schemas/StageDelay' - - $ref: '#/components/schemas/StageWaitEvent' - - $ref: '#/components/schemas/Update' - StripeTransferRequest: - type: object - properties: - connectorID: - type: string - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - asset: - type: string - example: USD - destination: - type: string - example: acct_1Gqj58KZcSIg2N2q - waitingValidation: - type: boolean - example: false - default: false - metadata: - type: object - description: > - A set of key/value pairs that you can attach to a transfer object. - - It can be useful for storing additional information about the - transfer in a structured format. - example: - order_id: '6735' - ActivityStripeTransfer: - $ref: '#/components/schemas/StripeTransferRequest' - ActivityListWallets: - type: object - properties: - name: - type: string - ListWalletsResponse: - type: object - required: - - cursor - properties: - cursor: - allOf: - - $ref: '#/components/schemas/Cursor' - - properties: - data: - items: - $ref: '#/components/schemas/Wallet' - type: array - type: object - required: - - data - Wallet: - type: object - required: - - name - - id - - metadata - - createdAt - - ledger - properties: - id: - type: string - format: uuid - description: The unique ID of the wallet. - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - name: - type: string - createdAt: - type: string - format: date-time - ledger: - type: string - Cursor: - type: object - required: - - pageSize - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: '' - ActivityGetAccount: - type: object - required: - - id - - ledger - properties: - id: - type: string - ledger: - type: string - ActivityAddAccountMetadata: - type: object - properties: - id: - type: string - ledger: - type: string - metadata: - type: object - additionalProperties: - type: string - required: - - id - - ledger - - metadata - ActivityCreateTransaction: - type: object - properties: - ledger: - type: string - data: - $ref: '#/components/schemas/PostTransaction' - ActivityRevertTransaction: - type: object - required: - - id - - ledger - properties: - ledger: - type: string - id: - type: string - ActivityGetPayment: - type: object - required: - - id - properties: - id: - type: string - ActivityConfirmHold: - type: object - required: - - id - properties: - id: - type: string - ActivityCreditWallet: - type: object - properties: - id: - type: string - data: - $ref: '#/components/schemas/CreditWalletRequest' - CreditWalletRequest: - type: object - required: - - amount - - sources - - metadata - properties: - amount: - $ref: '#/components/schemas/Monetary' - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - reference: - type: string - sources: - type: array - items: - $ref: '#/components/schemas/Subject' - balance: - type: string - description: The balance to credit - timestamp: - type: string - format: date-time - example: - amount: - asset: USD/2 - amount: 100 - metadata: - key: '' - sources: [] - LedgerAccountSubject: - type: object - required: - - type - - identifier - properties: - type: - type: string - identifier: - type: string - WalletSubject: - type: object - required: - - type - - identifier - properties: - type: - type: string - identifier: - type: string - balance: - type: string - Subject: - discriminator: - propertyName: type - mapping: - ACCOUNT: '#/components/schemas/LedgerAccountSubject' - WALLET: '#/components/schemas/WalletSubject' - oneOf: - - $ref: '#/components/schemas/LedgerAccountSubject' - - $ref: '#/components/schemas/WalletSubject' - ActivityDebitWallet: - type: object - properties: - id: - type: string - data: - $ref: '#/components/schemas/DebitWalletRequest' - DebitWalletRequest: - type: object - required: - - amount - - metadata - properties: - amount: - $ref: '#/components/schemas/Monetary' - pending: - type: boolean - description: >- - Set to true to create a pending hold. If false, the wallet will be - debited immediately. - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - description: - type: string - destination: - $ref: '#/components/schemas/Subject' - balances: - type: array - items: - type: string - description: A targeted balance (use '*' for all) - timestamp: - type: string - format: date-time - description: cannot be used in conjunction with `pending` property - example: - amount: - asset: USD/2 - amount: 100 - metadata: - key: '' - pending: true - ActivityGetWallet: - type: object - required: - - id - properties: - id: - type: string - ActivityVoidHold: - type: object - required: - - id - properties: - id: - type: string - ActivityGetAccountOutput: - $ref: '#/components/schemas/AccountResponse' - ActivityCreateTransactionOutput: - $ref: '#/components/schemas/CreateTransactionResponse' - CreateTransactionResponse: - properties: - data: - $ref: '#/components/schemas/Transaction' - type: object - required: - - data - Transaction: - type: object - properties: - timestamp: - type: string - format: date-time - postings: - type: array - items: - $ref: '#/components/schemas/Posting' - reference: - type: string - example: ref:001 - metadata: - $ref: '#/components/schemas/Metadata' - id: - type: integer - format: bigint - minimum: 0 - reverted: - type: boolean - required: - - postings - - timestamp - - id - - metadata - - reverted - ActivityRevertTransactionOutput: - $ref: '#/components/schemas/RevertTransactionResponse' - RevertTransactionResponse: - $ref: '#/components/schemas/CreateTransactionResponse' - ActivityGetPaymentOutput: - $ref: '#/components/schemas/PaymentResponse' - PaymentResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Payment' - Payment: - type: object - required: - - id - - reference - - connectorID - - sourceAccountID - - destinationAccountID - - type - - status - - initialAmount - - scheme - - asset - - createdAt - - raw - - adjustments - - metadata - properties: - id: - type: string - example: XXX - reference: - type: string - sourceAccountID: - type: string - destinationAccountID: - type: string - connectorID: - type: string - provider: - $ref: '#/components/schemas/Connector' - type: - type: string - enum: - - PAY-IN - - PAYOUT - - TRANSFER - - OTHER - status: - $ref: '#/components/schemas/PaymentStatus' - initialAmount: - type: integer - format: bigint - minimum: 0 - example: 100 - scheme: - type: string - enum: - - visa - - mastercard - - amex - - diners - - discover - - jcb - - unionpay - - sepa debit - - sepa credit - - sepa - - apple pay - - google pay - - a2a - - ach debit - - ach - - rtp - - unknown - - other - asset: - type: string - example: USD - createdAt: - type: string - format: date-time - raw: - type: object - nullable: true - adjustments: - type: array - items: - $ref: '#/components/schemas/PaymentAdjustment' - metadata: - $ref: '#/components/schemas/PaymentMetadata' - Connector: - type: string - enum: - - STRIPE - - DUMMY-PAY - - WISE - - MODULR - - CURRENCY-CLOUD - - BANKING-CIRCLE - - MANGOPAY - - MONEYCORP - PaymentAdjustment: - type: object - required: - - status - - amount - - date - - raw - - absolute - properties: - status: - $ref: '#/components/schemas/PaymentStatus' - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - date: - type: string - format: date-time - raw: - type: object - absolute: - type: boolean - PaymentStatus: - type: string - enum: - - PENDING - - ACTIVE - - TERMINATED - - FAILED - - SUCCEEDED - - CANCELLED - PaymentMetadata: - type: object - properties: - key: - type: string - nullable: true - ActivityDebitWalletOutput: - $ref: '#/components/schemas/DebitWalletResponse' - DebitWalletResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Hold' - Hold: - type: object - required: - - id - - walletID - - metadata - - description - properties: - id: - type: string - format: uuid - description: The unique ID of the hold. - walletID: - type: string - description: The ID of the wallet the hold is associated with. - metadata: - type: object - description: Metadata associated with the hold. - additionalProperties: - type: string - description: - type: string - destination: - $ref: '#/components/schemas/Subject' - ActivityGetWalletOutput: - $ref: '#/components/schemas/GetWalletResponse' - GetWalletResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/WalletWithBalances' - WalletWithBalances: - type: object - required: - - name - - id - - metadata - - createdAt - - balances - - ledger - properties: - id: - type: string - format: uuid - description: The unique ID of the wallet. - metadata: - type: object - description: Metadata associated with the wallet. - additionalProperties: - type: string - name: - type: string - createdAt: - type: string - format: date-time - balances: - type: object - required: - - main - properties: - main: - $ref: '#/components/schemas/AssetHolder' - ledger: - type: string - AssetHolder: - type: object - required: - - assets - properties: - assets: - type: object - additionalProperties: - type: integer - format: bigint - WorkflowInstanceHistoryStageInput: - type: object - properties: - GetAccount: - $ref: '#/components/schemas/ActivityGetAccount' - AddAccountMetadata: - $ref: '#/components/schemas/ActivityAddAccountMetadata' - CreateTransaction: - $ref: '#/components/schemas/ActivityCreateTransaction' - RevertTransaction: - $ref: '#/components/schemas/ActivityRevertTransaction' - StripeTransfer: - $ref: '#/components/schemas/ActivityStripeTransfer' - GetPayment: - $ref: '#/components/schemas/ActivityGetPayment' - ConfirmHold: - $ref: '#/components/schemas/ActivityConfirmHold' - CreditWallet: - $ref: '#/components/schemas/ActivityCreditWallet' - DebitWallet: - $ref: '#/components/schemas/ActivityDebitWallet' - GetWallet: - $ref: '#/components/schemas/ActivityGetWallet' - VoidHold: - $ref: '#/components/schemas/ActivityVoidHold' - ListWallets: - $ref: '#/components/schemas/ActivityListWallets' - WorkflowInstanceHistoryStageOutput: - type: object - properties: - GetAccount: - $ref: '#/components/schemas/ActivityGetAccountOutput' - CreateTransaction: - $ref: '#/components/schemas/ActivityCreateTransactionOutput' - RevertTransaction: - $ref: '#/components/schemas/ActivityRevertTransactionOutput' - GetPayment: - $ref: '#/components/schemas/ActivityGetPaymentOutput' - DebitWallet: - $ref: '#/components/schemas/ActivityDebitWalletOutput' - GetWallet: - $ref: '#/components/schemas/ActivityGetWalletOutput' - ListWallets: - $ref: '#/components/schemas/ListWalletsResponse' - Monetary: - type: object - required: - - asset - - amount - properties: - asset: - type: string - description: The asset of the monetary value. - amount: - type: integer - format: bigint - description: The amount of the monetary value. - PostTransaction: - type: object - required: - - metadata - properties: - timestamp: - type: string - format: date-time - postings: - type: array - items: - $ref: '#/components/schemas/Posting' - script: - type: object - properties: - plain: - type: string - example: "vars {\naccount $user\n}\nsend [COIN 10] (\n\tsource = @world\n\tdestination = $user\n)\n" - vars: - type: object - properties: {} - additionalProperties: true - example: - user: users:042 - required: - - plain - reference: - type: string - example: ref:001 - metadata: - $ref: '#/components/schemas/Metadata' - Metadata: - type: object - additionalProperties: - type: string - example: - admin: 'true' - Posting: - type: object - properties: - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - asset: - type: string - example: COIN - destination: - type: string - example: users:002 - source: - type: string - example: users:001 - required: - - amount - - asset - - destination - - source - AccountResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Account' - ReadTriggerResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Trigger' - Account: - type: object - required: - - address - - metadata - properties: - address: - type: string - example: users:001 - metadata: - type: object - properties: {} - additionalProperties: - type: string - example: - admin: 'true' - volumes: - $ref: '#/components/schemas/Volumes' - effectiveVolumes: - $ref: '#/components/schemas/Volumes' - Volume: - type: object - properties: - input: - type: integer - format: bigint - output: - type: integer - format: bigint - balance: - type: integer - format: bigint - required: - - input - - output - example: - input: 100 - output: 20 - balance: 80 - Volumes: - type: object - additionalProperties: - $ref: '#/components/schemas/Volume' - example: - USD: - input: 100 - output: 10 - balance: 90 - EUR: - input: 100 - output: 10 - balance: 90 - responses: - ErrorResponse: - description: General error - content: - application/json: - schema: - $ref: '#/components/schemas/Error' diff --git a/ee/orchestration/openapi/v2.yaml b/ee/orchestration/openapi/v2.yaml deleted file mode 100644 index f5949fbb51..0000000000 --- a/ee/orchestration/openapi/v2.yaml +++ /dev/null @@ -1,1771 +0,0 @@ -openapi: 3.0.3 -info: - title: Formance Simple orchestration Service API - version: 0.1.0 -paths: - /v2/_info: - get: - summary: Get server info - operationId: v2GetServerInfo - x-speakeasy-name-override: GetServerInfo - tags: - - orchestration.v2 - responses: - '200': - description: Server information - content: - application/json: - schema: - $ref: '#/components/schemas/V2ServerInfo' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - /v2/triggers: - get: - summary: List triggers - operationId: v2ListTriggers - description: List triggers - x-speakeasy-name-override: ListTriggers - tags: - - orchestration.v2 - parameters: - - $ref: '#/components/parameters/Cursor' - - $ref: '#/components/parameters/PageSize' - - name: name - in: query - description: search by name - required: false - schema: - type: string - responses: - '200': - description: List of triggers - content: - application/json: - schema: - $ref: '#/components/schemas/V2ListTriggersResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - post: - summary: Create trigger - operationId: v2CreateTrigger - description: Create trigger - x-speakeasy-name-override: CreateTrigger - tags: - - orchestration.v2 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/V2TriggerData' - responses: - '201': - description: Created trigger - content: - application/json: - schema: - $ref: '#/components/schemas/V2CreateTriggerResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/triggers/{triggerID}: - parameters: - - name: triggerID - description: The trigger id - in: path - schema: - type: string - required: true - get: - summary: Read trigger - operationId: v2ReadTrigger - description: Read trigger - x-speakeasy-name-override: ReadTrigger - tags: - - orchestration.v2 - responses: - '200': - description: A specific trigger - content: - application/json: - schema: - $ref: '#/components/schemas/V2ReadTriggerResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - delete: - summary: Delete trigger - operationId: v2DeleteTrigger - description: Read trigger - x-speakeasy-name-override: DeleteTrigger - tags: - - orchestration.v2 - responses: - '204': - description: Trigger deleted - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/triggers/{triggerID}/test: - parameters: - - name: triggerID - description: The trigger id - in: path - schema: - type: string - required: true - post: - summary: Test trigger - operationId: testTrigger - description: Test trigger - x-speakeasy-name-override: TestTrigger - tags: - - orchestration.v2 - requestBody: - content: - application/json: - schema: - type: object - additionalProperties: true - responses: - '200': - description: Test a trigger - content: - application/json: - schema: - $ref: '#/components/schemas/V2TestTriggerResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/triggers/{triggerID}/occurrences: - parameters: - - name: triggerID - description: The trigger id - in: path - schema: - type: string - required: true - get: - summary: List triggers occurrences - operationId: v2ListTriggersOccurrences - description: List triggers occurrences - x-speakeasy-name-override: ListTriggersOccurrences - tags: - - orchestration.v2 - parameters: - - $ref: '#/components/parameters/Cursor' - - $ref: '#/components/parameters/PageSize' - responses: - '200': - description: List of triggers occurrences - content: - application/json: - schema: - $ref: '#/components/schemas/V2ListTriggersOccurrencesResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - /v2/workflows: - get: - summary: List registered workflows - operationId: v2ListWorkflows - description: List registered workflows - x-speakeasy-name-override: ListWorkflows - tags: - - orchestration.v2 - parameters: - - $ref: '#/components/parameters/Cursor' - - $ref: '#/components/parameters/PageSize' - responses: - '200': - description: List of workflows - content: - application/json: - schema: - $ref: '#/components/schemas/V2ListWorkflowsResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - post: - summary: Create workflow - operationId: v2CreateWorkflow - description: Create a workflow - x-speakeasy-name-override: CreateWorkflow - tags: - - orchestration.v2 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/V2CreateWorkflowRequest' - responses: - '201': - description: Created workflow - content: - application/json: - schema: - $ref: '#/components/schemas/V2CreateWorkflowResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/workflows/{flowId}: - parameters: - - in: path - description: The flow id - name: flowId - schema: - type: string - example: xxx - required: true - get: - summary: Get a flow by id - tags: - - orchestration.v2 - description: Get a flow by id - operationId: v2GetWorkflow - x-speakeasy-name-override: GetWorkflow - responses: - '200': - description: The workflow - content: - application/json: - schema: - $ref: '#/components/schemas/V2GetWorkflowResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - delete: - summary: Delete a flow by id - tags: - - orchestration.v2 - description: Delete a flow by id - operationId: v2DeleteWorkflow - x-speakeasy-name-override: DeleteWorkflow - responses: - '204': - description: No content - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/workflows/{workflowID}/instances: - parameters: - - in: path - description: The flow id - name: workflowID - schema: - type: string - example: xxx - required: true - post: - description: Run workflow - summary: Run workflow - operationId: v2RunWorkflow - x-speakeasy-name-override: RunWorkflow - parameters: - - in: query - name: wait - required: false - description: Wait end of the workflow before return - schema: - type: boolean - tags: - - orchestration.v2 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/V2RunWorkflowRequest' - responses: - '201': - description: The workflow instance - content: - application/json: - schema: - $ref: '#/components/schemas/V2RunWorkflowResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/instances: - get: - description: List instances of a workflow - summary: List instances of a workflow - operationId: v2ListInstances - x-speakeasy-name-override: ListInstances - parameters: - - $ref: '#/components/parameters/Cursor' - - $ref: '#/components/parameters/PageSize' - - in: query - description: A workflow id - name: workflowID - schema: - type: string - example: xxx - required: false - - in: query - description: Filter running instances - name: running - schema: - type: boolean - example: true - required: false - tags: - - orchestration.v2 - responses: - '200': - description: List of workflow instances - content: - application/json: - schema: - $ref: '#/components/schemas/V2ListRunsResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - /v2/instances/{instanceID}: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - get: - summary: Get a workflow instance by id - description: Get a workflow instance by id - operationId: v2GetInstance - x-speakeasy-name-override: GetInstance - tags: - - orchestration.v2 - responses: - '200': - description: The workflow instance - content: - application/json: - schema: - $ref: '#/components/schemas/V2GetWorkflowInstanceResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - /v2/instances/{instanceID}/events: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - post: - summary: Send an event to a running workflow - description: Send an event to a running workflow - operationId: v2SendEvent - x-speakeasy-name-override: SendEvent - tags: - - orchestration.v2 - requestBody: - content: - application/json: - schema: - type: object - required: - - name - properties: - name: - type: string - responses: - '204': - description: No content - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/instances/{instanceID}/abort: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - put: - summary: Cancel a running workflow - description: Cancel a running workflow - operationId: v2CancelEvent - x-speakeasy-name-override: CancelEvent - tags: - - orchestration.v2 - responses: - '204': - description: No content - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:write - /v2/instances/{instanceID}/history: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - get: - summary: Get a workflow instance history by id - description: Get a workflow instance history by id - operationId: v2GetInstanceHistory - x-speakeasy-name-override: GetInstanceHistory - tags: - - orchestration.v2 - responses: - '200': - description: The workflow instance history - content: - application/json: - schema: - $ref: '#/components/schemas/V2GetWorkflowInstanceHistoryResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read - /v2/instances/{instanceID}/stages/{number}/history: - parameters: - - in: path - description: The instance id - name: instanceID - schema: - type: string - example: xxx - required: true - - in: path - description: The stage number - name: number - schema: - type: integer - example: 0 - required: true - get: - summary: Get a workflow instance stage history - description: Get a workflow instance stage history - operationId: v2GetInstanceStageHistory - x-speakeasy-name-override: GetInstanceStageHistory - tags: - - orchestration.v2 - responses: - '200': - description: The workflow instance stage history - content: - application/json: - schema: - $ref: '#/components/schemas/V2GetWorkflowInstanceHistoryStageResponse' - default: - $ref: '#/components/responses/V2ErrorResponse' - security: - - Authorization: - - orchestration:read -components: - parameters: - Cursor: - name: cursor - in: query - description: | - Parameter used in pagination requests. - Set to the value of next for the next page of results. - Set to the value of previous for the previous page of results. - No other parameters can be set when this parameter is set. - schema: - type: string - example: aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== - PageSize: - name: pageSize - in: query - description: | - The maximum number of results to return per page. - example: 100 - schema: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - schemas: - V2ServerInfo: - type: object - required: - - version - properties: - version: - type: string - V2Error: - type: object - required: - - errorCode - - errorMessage - properties: - errorCode: - type: string - enum: - - VALIDATION - - NOT_FOUND - - INTERNAL - errorMessage: - type: string - V2WorkflowConfig: - type: object - required: - - stages - properties: - name: - type: string - stages: - type: array - items: - type: object - additionalProperties: {} - V2Workflow: - type: object - required: - - config - - createdAt - - updatedAt - - id - properties: - config: - $ref: '#/components/schemas/V2WorkflowConfig' - createdAt: - type: string - format: date-time - updatedAt: - type: string - format: date-time - id: - type: string - V2StageStatus: - type: object - required: - - stage - - instanceID - - startedAt - properties: - stage: - type: number - instanceID: - type: string - startedAt: - type: string - format: date-time - terminatedAt: - type: string - format: date-time - error: - type: string - V2WorkflowInstance: - type: object - required: - - workflowID - - id - - createdAt - - updatedAt - - terminated - properties: - workflowID: - type: string - id: - type: string - createdAt: - type: string - format: date-time - updatedAt: - type: string - format: date-time - status: - type: array - items: - $ref: '#/components/schemas/V2StageStatus' - terminated: - type: boolean - terminatedAt: - type: string - format: date-time - error: - type: string - V2WorkflowInstanceHistoryStage: - type: object - required: - - name - - input - - startedAt - - terminated - - attempt - properties: - name: - type: string - input: - $ref: '#/components/schemas/V2WorkflowInstanceHistoryStageInput' - output: - $ref: '#/components/schemas/V2WorkflowInstanceHistoryStageOutput' - error: - type: string - terminated: - type: boolean - startedAt: - type: string - format: date-time - terminatedAt: - type: string - format: date-time - lastFailure: - type: string - attempt: - type: integer - nextExecution: - type: string - format: date-time - V2WorkflowInstanceHistory: - type: object - required: - - name - - input - - terminated - - startedAt - properties: - name: - type: string - input: - $ref: '#/components/schemas/V2Stage' - error: - type: string - terminated: - type: boolean - startedAt: - type: string - format: date-time - terminatedAt: - type: string - format: date-time - V2WorkflowInstanceHistoryList: - type: array - items: - $ref: '#/components/schemas/V2WorkflowInstanceHistory' - V2WorkflowInstanceHistoryStageList: - type: array - items: - $ref: '#/components/schemas/V2WorkflowInstanceHistoryStage' - V2ListWorkflowsResponse: - type: object - properties: - cursor: - type: object - required: - - pageSize - - hasMore - - data - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: '' - data: - type: array - items: - $ref: '#/components/schemas/V2Workflow' - required: - - cursor - V2TriggerData: - type: object - required: - - event - - workflowID - properties: - event: - type: string - workflowID: - type: string - filter: - type: string - vars: - type: object - additionalProperties: true - name: - type: string - V2Trigger: - allOf: - - $ref: '#/components/schemas/V2TriggerData' - - type: object - required: - - id - - createdAt - properties: - id: - type: string - createdAt: - type: string - format: date-time - V2TriggerOccurrence: - type: object - required: - - triggerID - - date - - event - properties: - date: - type: string - format: date-time - workflowInstanceID: - type: string - workflowInstance: - $ref: '#/components/schemas/V2WorkflowInstance' - triggerID: - type: string - error: - type: string - event: - type: object - additionalProperties: true - V2ListTriggersOccurrencesResponse: - type: object - properties: - cursor: - type: object - required: - - pageSize - - hasMore - - data - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: '' - data: - type: array - items: - $ref: '#/components/schemas/V2TriggerOccurrence' - required: - - cursor - V2ListTriggersResponse: - type: object - properties: - cursor: - type: object - required: - - pageSize - - hasMore - - data - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: '' - data: - type: array - items: - $ref: '#/components/schemas/V2Trigger' - required: - - cursor - V2CreateWorkflowRequest: - $ref: '#/components/schemas/V2WorkflowConfig' - V2CreateWorkflowResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Workflow' - V2CreateTriggerResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Trigger' - V2RunWorkflowRequest: - type: object - additionalProperties: - type: string - V2RunWorkflowResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2WorkflowInstance' - V2ListRunsResponse: - type: object - properties: - cursor: - type: object - required: - - pageSize - - hasMore - - data - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: '' - data: - type: array - items: - $ref: '#/components/schemas/V2WorkflowInstance' - required: - - cursor - V2GetWorkflowResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Workflow' - V2GetWorkflowInstanceResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2WorkflowInstance' - V2GetWorkflowInstanceHistoryResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2WorkflowInstanceHistoryList' - V2GetWorkflowInstanceHistoryStageResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2WorkflowInstanceHistoryStageList' - V2StageSendSourceWallet: - type: object - required: - - id - properties: - id: - type: string - balance: - type: string - V2StageSendDestinationWallet: - $ref: '#/components/schemas/V2StageSendSourceWallet' - V2StageSendSourceAccount: - type: object - required: - - id - properties: - id: - type: string - ledger: - type: string - V2StageSendDestinationAccount: - $ref: '#/components/schemas/V2StageSendSourceAccount' - V2StageSendSourcePayment: - type: object - required: - - id - properties: - id: - type: string - V2StageSendDestinationPayment: - type: object - required: - - psp - properties: - psp: - type: string - V2StageSendSource: - type: object - properties: - wallet: - $ref: '#/components/schemas/V2StageSendSourceWallet' - account: - $ref: '#/components/schemas/V2StageSendSourceAccount' - payment: - $ref: '#/components/schemas/V2StageSendSourcePayment' - V2StageSendDestination: - type: object - properties: - wallet: - $ref: '#/components/schemas/V2StageSendDestinationWallet' - account: - $ref: '#/components/schemas/V2StageSendDestinationAccount' - payment: - $ref: '#/components/schemas/V2StageSendDestinationPayment' - V2StageSend: - type: object - properties: - amount: - $ref: '#/components/schemas/V2Monetary' - destination: - $ref: '#/components/schemas/V2StageSendDestination' - source: - $ref: '#/components/schemas/V2StageSendSource' - metadata: - type: object - additionalProperties: - type: string - timestamp: - type: string - format: date-time - V2StageDelay: - type: object - properties: - until: - type: string - format: date-time - duration: - type: string - V2StageWaitEvent: - type: object - required: - - event - properties: - event: - type: string - V2UpdateAccount: - type: object - properties: - id: - type: string - metadata: - type: object - additionalProperties: - type: string - ledger: - type: string - required: - - id - - ledger - - metadata - V2Update: - type: object - properties: - account: - $ref: '#/components/schemas/V2UpdateAccount' - V2Stage: - anyOf: - - $ref: '#/components/schemas/V2StageSend' - - $ref: '#/components/schemas/V2StageDelay' - - $ref: '#/components/schemas/V2StageWaitEvent' - - $ref: '#/components/schemas/V2Update' - V2StripeTransferRequest: - type: object - properties: - connectorID: - type: string - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - asset: - type: string - example: USD - destination: - type: string - example: acct_1Gqj58KZcSIg2N2q - waitingValidation: - type: boolean - example: false - default: false - metadata: - type: object - description: > - A set of key/value pairs that you can attach to a transfer object. - - It can be useful for storing additional information about the - transfer in a structured format. - example: - order_id: '6735' - V2ActivityStripeTransfer: - $ref: '#/components/schemas/V2StripeTransferRequest' - V2ActivityListWallets: - type: object - properties: - name: - type: string - V2ListWalletsResponse: - type: object - required: - - cursor - properties: - cursor: - allOf: - - $ref: '#/components/schemas/V2Cursor' - - properties: - data: - items: - $ref: '#/components/schemas/V2Wallet' - type: array - type: object - required: - - data - V2Wallet: - type: object - required: - - name - - id - - metadata - - createdAt - - ledger - properties: - id: - type: string - format: uuid - description: The unique ID of the wallet. - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - name: - type: string - createdAt: - type: string - format: date-time - ledger: - type: string - V2Cursor: - type: object - required: - - pageSize - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: '' - V2ActivityGetAccount: - type: object - required: - - id - - ledger - properties: - id: - type: string - ledger: - type: string - V2ActivityAddAccountMetadata: - type: object - properties: - id: - type: string - ledger: - type: string - metadata: - type: object - additionalProperties: - type: string - required: - - id - - ledger - - metadata - V2ActivityCreateTransaction: - type: object - properties: - ledger: - type: string - data: - $ref: '#/components/schemas/V2PostTransaction' - V2ActivityGetPayment: - type: object - required: - - id - properties: - id: - type: string - V2ActivityConfirmHold: - type: object - required: - - id - properties: - id: - type: string - V2ActivityCreditWallet: - type: object - properties: - id: - type: string - data: - $ref: '#/components/schemas/V2CreditWalletRequest' - V2CreditWalletRequest: - type: object - required: - - amount - - sources - - metadata - properties: - amount: - $ref: '#/components/schemas/V2Monetary' - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - reference: - type: string - sources: - type: array - items: - $ref: '#/components/schemas/V2Subject' - balance: - type: string - description: The balance to credit - timestamp: - type: string - format: date-time - example: - amount: - asset: USD/2 - amount: 100 - metadata: - key: '' - sources: [] - V2LedgerAccountSubject: - type: object - required: - - type - - identifier - properties: - type: - type: string - identifier: - type: string - V2WalletSubject: - type: object - required: - - type - - identifier - properties: - type: - type: string - identifier: - type: string - balance: - type: string - V2Subject: - discriminator: - propertyName: type - mapping: - ACCOUNT: '#/components/schemas/V2LedgerAccountSubject' - WALLET: '#/components/schemas/V2WalletSubject' - oneOf: - - $ref: '#/components/schemas/V2LedgerAccountSubject' - - $ref: '#/components/schemas/V2WalletSubject' - V2ActivityDebitWallet: - type: object - properties: - id: - type: string - data: - $ref: '#/components/schemas/V2DebitWalletRequest' - V2DebitWalletRequest: - type: object - required: - - amount - - metadata - properties: - amount: - $ref: '#/components/schemas/V2Monetary' - pending: - type: boolean - description: >- - Set to true to create a pending hold. If false, the wallet will be - debited immediately. - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - description: - type: string - destination: - $ref: '#/components/schemas/V2Subject' - balances: - type: array - items: - type: string - description: A targeted balance (use '*' for all) - timestamp: - type: string - format: date-time - description: cannot be used in conjunction with `pending` property - example: - amount: - asset: USD/2 - amount: 100 - metadata: - key: '' - pending: true - V2ActivityGetWallet: - type: object - required: - - id - properties: - id: - type: string - V2ActivityVoidHold: - type: object - required: - - id - properties: - id: - type: string - V2ActivityGetAccountOutput: - $ref: '#/components/schemas/V2AccountResponse' - V2ActivityCreateTransactionOutput: - $ref: '#/components/schemas/V2CreateTransactionResponse' - V2CreateTransactionResponse: - properties: - data: - type: array - items: - $ref: '#/components/schemas/V2Transaction' - type: object - required: - - data - V2Transaction: - type: object - properties: - timestamp: - type: string - format: date-time - postings: - type: array - items: - $ref: '#/components/schemas/V2Posting' - reference: - type: string - example: ref:001 - metadata: - $ref: '#/components/schemas/V2Metadata' - txid: - type: integer - format: bigint - minimum: 0 - required: - - postings - - timestamp - - txid - - metadata - V2ActivityGetPaymentOutput: - $ref: '#/components/schemas/V2PaymentResponse' - V2PaymentResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Payment' - V2Payment: - type: object - required: - - id - - reference - - connectorID - - sourceAccountID - - destinationAccountID - - type - - status - - initialAmount - - scheme - - asset - - createdAt - - raw - - adjustments - - metadata - properties: - id: - type: string - example: XXX - reference: - type: string - sourceAccountID: - type: string - destinationAccountID: - type: string - connectorID: - type: string - provider: - $ref: '#/components/schemas/V2Connector' - type: - type: string - enum: - - PAY-IN - - PAYOUT - - TRANSFER - - OTHER - status: - $ref: '#/components/schemas/V2PaymentStatus' - initialAmount: - type: integer - format: bigint - minimum: 0 - example: 100 - scheme: - type: string - enum: - - visa - - mastercard - - amex - - diners - - discover - - jcb - - unionpay - - sepa debit - - sepa credit - - sepa - - apple pay - - google pay - - a2a - - ach debit - - ach - - rtp - - unknown - - other - asset: - type: string - example: USD - createdAt: - type: string - format: date-time - raw: - type: object - nullable: true - adjustments: - type: array - items: - $ref: '#/components/schemas/V2PaymentAdjustment' - metadata: - $ref: '#/components/schemas/V2PaymentMetadata' - V2Connector: - type: string - enum: - - STRIPE - - DUMMY-PAY - - WISE - - MODULR - - CURRENCY-CLOUD - - BANKING-CIRCLE - - MANGOPAY - - MONEYCORP - V2PaymentAdjustment: - type: object - required: - - status - - amount - - date - - raw - - absolute - properties: - status: - $ref: '#/components/schemas/V2PaymentStatus' - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - date: - type: string - format: date-time - raw: - type: object - absolute: - type: boolean - V2PaymentStatus: - type: string - enum: - - PENDING - - ACTIVE - - TERMINATED - - FAILED - - SUCCEEDED - - CANCELLED - V2PaymentMetadata: - type: object - properties: - key: - type: string - nullable: true - V2ActivityDebitWalletOutput: - $ref: '#/components/schemas/V2DebitWalletResponse' - V2DebitWalletResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Hold' - V2Hold: - type: object - required: - - id - - walletID - - metadata - - description - properties: - id: - type: string - format: uuid - description: The unique ID of the hold. - walletID: - type: string - description: The ID of the wallet the hold is associated with. - metadata: - type: object - description: Metadata associated with the hold. - additionalProperties: - type: string - description: - type: string - destination: - $ref: '#/components/schemas/V2Subject' - V2ActivityGetWalletOutput: - $ref: '#/components/schemas/V2GetWalletResponse' - V2GetWalletResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2WalletWithBalances' - V2WalletWithBalances: - type: object - required: - - name - - id - - metadata - - createdAt - - balances - - ledger - properties: - id: - type: string - format: uuid - description: The unique ID of the wallet. - metadata: - type: object - description: Metadata associated with the wallet. - additionalProperties: - type: string - name: - type: string - createdAt: - type: string - format: date-time - balances: - type: object - required: - - main - properties: - main: - $ref: '#/components/schemas/V2AssetHolder' - ledger: - type: string - V2AssetHolder: - type: object - required: - - assets - properties: - assets: - type: object - additionalProperties: - type: integer - format: bigint - V2WorkflowInstanceHistoryStageInput: - type: object - properties: - GetAccount: - $ref: '#/components/schemas/V2ActivityGetAccount' - AddAccountMetadata: - $ref: '#/components/schemas/V2ActivityAddAccountMetadata' - CreateTransaction: - $ref: '#/components/schemas/V2ActivityCreateTransaction' - StripeTransfer: - $ref: '#/components/schemas/V2ActivityStripeTransfer' - GetPayment: - $ref: '#/components/schemas/V2ActivityGetPayment' - ConfirmHold: - $ref: '#/components/schemas/V2ActivityConfirmHold' - CreditWallet: - $ref: '#/components/schemas/V2ActivityCreditWallet' - DebitWallet: - $ref: '#/components/schemas/V2ActivityDebitWallet' - GetWallet: - $ref: '#/components/schemas/V2ActivityGetWallet' - VoidHold: - $ref: '#/components/schemas/V2ActivityVoidHold' - ListWallets: - $ref: '#/components/schemas/V2ActivityListWallets' - V2WorkflowInstanceHistoryStageOutput: - type: object - properties: - GetAccount: - $ref: '#/components/schemas/V2ActivityGetAccountOutput' - CreateTransaction: - $ref: '#/components/schemas/V2ActivityCreateTransactionOutput' - GetPayment: - $ref: '#/components/schemas/V2ActivityGetPaymentOutput' - DebitWallet: - $ref: '#/components/schemas/V2ActivityDebitWalletOutput' - GetWallet: - $ref: '#/components/schemas/V2ActivityGetWalletOutput' - ListWallets: - $ref: '#/components/schemas/V2ListWalletsResponse' - V2Monetary: - type: object - required: - - asset - - amount - properties: - asset: - type: string - description: The asset of the monetary value. - amount: - type: integer - format: bigint - description: The amount of the monetary value. - V2PostTransaction: - type: object - required: - - metadata - properties: - timestamp: - type: string - format: date-time - postings: - type: array - items: - $ref: '#/components/schemas/V2Posting' - script: - type: object - properties: - plain: - type: string - example: "vars {\naccount $user\n}\nsend [COIN 10] (\n\tsource = @world\n\tdestination = $user\n)\n" - vars: - type: object - properties: {} - additionalProperties: true - example: - user: users:042 - required: - - plain - reference: - type: string - example: ref:001 - metadata: - $ref: '#/components/schemas/V2Metadata' - V2Metadata: - type: object - additionalProperties: - type: string - example: - admin: 'true' - V2Posting: - type: object - properties: - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - asset: - type: string - example: COIN - destination: - type: string - example: users:002 - source: - type: string - example: users:001 - required: - - amount - - asset - - destination - - source - V2AccountResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Account' - V2ReadTriggerResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2Trigger' - V2Account: - type: object - required: - - address - - metadata - properties: - address: - type: string - example: users:001 - metadata: - type: object - properties: {} - additionalProperties: - type: string - example: - admin: 'true' - volumes: - $ref: '#/components/schemas/V2Volumes' - effectiveVolumes: - $ref: '#/components/schemas/V2Volumes' - V2Volume: - type: object - properties: - input: - type: integer - format: bigint - output: - type: integer - format: bigint - balance: - type: integer - format: bigint - required: - - input - - output - example: - input: 100 - output: 20 - balance: 80 - V2Volumes: - type: object - additionalProperties: - $ref: '#/components/schemas/V2Volume' - example: - USD: - input: 100 - output: 10 - balance: 90 - EUR: - input: 100 - output: 10 - balance: 90 - V2TestTriggerResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/V2TriggerTest' - V2TriggerTest: - type: object - properties: - filter: - type: object - properties: - match: - type: boolean - error: - type: string - variables: - type: object - additionalProperties: - type: object - properties: - value: - type: string - error: - type: string - responses: - V2ErrorResponse: - description: General error - content: - application/json: - schema: - $ref: '#/components/schemas/V2Error' diff --git a/ee/orchestration/pkg/.gitkeep b/ee/orchestration/pkg/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/ee/orchestration/pkg/events/events.go b/ee/orchestration/pkg/events/events.go deleted file mode 100644 index ebaac86f57..0000000000 --- a/ee/orchestration/pkg/events/events.go +++ /dev/null @@ -1,79 +0,0 @@ -package events - -import ( - "context" - "time" - - "github.com/ThreeDotsLabs/watermill/message" - "github.com/formancehq/go-libs/publish" -) - -const ( - TopicOrchestration = "orchestration" - - SucceededWorkflow = "SUCCEEDED_WORKFLOW" - SucceededWorkflowStage = "SUCCEEDED_WORKFLOW_STAGE" - StartedWorkflow = "STARTED_WORKFLOW" - StartedWorkflowStage = "STARTED_WORKFLOW_STAGE" - FailedWorkflow = "FAILED_WORKFLOW" - FailedWorkflowStage = "FAILED_WORKFLOW_STAGE" - SucceededTrigger = "SUCCEEDED_TRIGGER" - FailedTrigger = "FAILED_TRIGGER" -) - -type SucceededWorkflowPayload struct { - ID string `json:"id"` - InstanceID string `json:"instanceID"` -} - -type StartedWorkflowPayload struct { - ID string `json:"id"` - InstanceID string `json:"instanceID"` -} - -type StartedWorkflowStagePayload struct { - ID string `json:"id"` - InstanceID string `json:"instanceID"` - Number int `json:"number"` -} - -type SucceededWorkflowStagePayload struct { - ID string `json:"id"` - InstanceID string `json:"instanceID"` - Number int `json:"number"` -} - -type FailedWorkflowPayload struct { - ID string `json:"id"` - InstanceID string `json:"instanceID"` - Error string `json:"error"` -} - -type FailedWorkflowStagePayload struct { - ID string `json:"id"` - InstanceID string `json:"instanceID"` - Number int `json:"number"` - Error string `json:"error"` -} - -type SucceededTriggerPayload struct { - ID string `json:"id"` - TriggerID string `json:"triggerID"` - WorkflowInstanceID string `json:"workflowInstanceID"` -} - -type FailedTriggerPayload struct { - ID string `json:"id"` - TriggerID string `json:"triggerID"` - Error string `json:"error"` -} - -func NewMessage(ctx context.Context, mtype string, payload any) *message.Message { - return publish.NewMessage(ctx, publish.EventMessage{ - Date: time.Now(), - App: "orchestration", - Version: "v2", - Type: mtype, - Payload: payload, - }) -} diff --git a/ee/orchestration/scratch.Dockerfile b/ee/orchestration/scratch.Dockerfile deleted file mode 100644 index a6c2a3e73d..0000000000 --- a/ee/orchestration/scratch.Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM ghcr.io/formancehq/base:scratch -COPY orchestration /usr/bin/orchestration -ENV OTEL_SERVICE_NAME orchestration -ENTRYPOINT ["/usr/bin/orchestration"] -CMD ["serve"] diff --git a/ee/reconciliation/.gitignore b/ee/reconciliation/.gitignore deleted file mode 100644 index 99eabe8920..0000000000 --- a/ee/reconciliation/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.DS_Store -.idea -vendor -.cloud/ressources/.terraform -.cloud/ressources/.terraform.lock.hcl -/.cloud/helm/charts/ -coverage.out -dist/ -.env -reconciliation diff --git a/ee/reconciliation/.goreleaser.yml b/ee/reconciliation/.goreleaser.yml deleted file mode 100644 index 6c955c54c9..0000000000 --- a/ee/reconciliation/.goreleaser.yml +++ /dev/null @@ -1,37 +0,0 @@ -project_name: reconciliation -includes: - - from_file: - path: ./../../.goreleaser.default.yaml -monorepo: - tag_prefix: v - dir: ./ - -builds: - - binary: reconciliation - id: reconciliation - ldflags: - - -X github.com/formancehq/reconciliation/cmd.BuildDate={{ .Date }} - - -X github.com/formancehq/reconciliation/cmd.Version=v{{ .Version }} - - -X github.com/formancehq/reconciliation/cmd.Commit={{ .ShortCommit }} - - -extldflags "-static" - env: - - CGO_ENABLED=0 - goos: - - linux - goarch: - - amd64 - - arm64 - -archives: - - id: "{{.ProjectName}}" - builds: - - reconciliation - format: tar.gz - name_template: "{{.ProjectName}}_{{.Os}}-{{.Arch}}" - -release: - prerelease: auto - footer: | - ## What to do next? - - Read the [documentation](https://docs.formance.com/) - - Join our [Slack server](https://formance.com/slack) \ No newline at end of file diff --git a/ee/reconciliation/Earthfile b/ee/reconciliation/Earthfile deleted file mode 100644 index cd3746ac8c..0000000000 --- a/ee/reconciliation/Earthfile +++ /dev/null @@ -1,82 +0,0 @@ -VERSION 0.8 - -IMPORT github.com/formancehq/earthly:tags/v0.15.0 AS core -IMPORT ../.. AS stack -IMPORT ../../releases AS releases -IMPORT .. AS ee - -FROM core+base-image - -sources: - WORKDIR src - COPY --pass-args (releases+sdk-generate/go) /src/releases/sdks/go - WORKDIR /src/ee/reconciliation - COPY go.* . - COPY --dir cmd internal . - COPY main.go . - SAVE ARTIFACT /src - -compile: - FROM core+builder-image - COPY (+sources/*) /src - WORKDIR /src/ee/reconciliation - ARG VERSION=latest - DO --pass-args core+GO_COMPILE --VERSION=$VERSION - -build-image: - FROM core+final-image - ENTRYPOINT ["/bin/reconciliation"] - CMD ["serve"] - COPY (+compile/main) /bin/reconciliation - ARG REPOSITORY=ghcr.io - ARG tag=latest - DO core+SAVE_IMAGE --COMPONENT=reconciliation --REPOSITORY=${REPOSITORY} --TAG=$tag - -tests: - FROM core+builder-image - COPY (+sources/*) /src - WORKDIR /src/ee/reconciliation - WITH DOCKER --pull=postgres:15-alpine - DO --pass-args core+GO_TESTS - END - -deploy: - COPY (+sources/*) /src - LET tag=$(tar cf - /src | sha1sum | awk '{print $1}') - WAIT - BUILD --pass-args +build-image --tag=$tag - END - FROM --pass-args core+vcluster-deployer-image - RUN kubectl patch Versions.formance.com default -p "{\"spec\":{\"reconciliation\": \"${tag}\"}}" --type=merge - -deploy-staging: - BUILD --pass-args stack+deployer-module --MODULE=reconciliation - -lint: - FROM core+builder-image - COPY (+sources/*) /src - COPY --pass-args +tidy/go.* . - WORKDIR /src/ee/reconciliation - DO --pass-args stack+GO_LINT - SAVE ARTIFACT cmd AS LOCAL cmd - SAVE ARTIFACT internal AS LOCAL internal - SAVE ARTIFACT main.go AS LOCAL main.go - -pre-commit: - WAIT - BUILD --pass-args +tidy - END - BUILD --pass-args +lint - -openapi: - COPY ./openapi.yaml . - SAVE ARTIFACT ./openapi.yaml - -tidy: - FROM core+builder-image - COPY --pass-args (+sources/src) /src - WORKDIR /src/ee/reconciliation - DO --pass-args stack+GO_TIDY - -release: - BUILD --pass-args stack+goreleaser --path=ee/reconciliation \ No newline at end of file diff --git a/ee/reconciliation/README.md b/ee/reconciliation/README.md deleted file mode 100644 index 686b033d44..0000000000 --- a/ee/reconciliation/README.md +++ /dev/null @@ -1 +0,0 @@ -# Formance Reconciliation \ No newline at end of file diff --git a/ee/reconciliation/build.Dockerfile b/ee/reconciliation/build.Dockerfile deleted file mode 100644 index 5bbe6459d4..0000000000 --- a/ee/reconciliation/build.Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM ghcr.io/formancehq/base:22.04 -COPY reconciliation /usr/bin/reconciliation -ENV OTEL_SERVICE_NAME reconciliation -ENTRYPOINT ["/usr/bin/reconciliation"] -CMD ["serve"] diff --git a/ee/reconciliation/cmd/migrate.go b/ee/reconciliation/cmd/migrate.go deleted file mode 100644 index a140244776..0000000000 --- a/ee/reconciliation/cmd/migrate.go +++ /dev/null @@ -1,21 +0,0 @@ -package cmd - -import ( - "github.com/formancehq/go-libs/bun/bunmigrate" - - storage "github.com/formancehq/reconciliation/internal/storage/migrations" - "github.com/spf13/cobra" - "github.com/uptrace/bun" -) - -var ( - autoMigrateFlag = "auto-migrate" -) - -func newMigrate() *cobra.Command { - return bunmigrate.NewDefaultCommand(Migrate) -} - -func Migrate(cmd *cobra.Command, args []string, db *bun.DB) error { - return storage.Migrate(cmd.Context(), db) -} diff --git a/ee/reconciliation/cmd/root.go b/ee/reconciliation/cmd/root.go deleted file mode 100644 index 55f4830972..0000000000 --- a/ee/reconciliation/cmd/root.go +++ /dev/null @@ -1,51 +0,0 @@ -package cmd - -import ( - "github.com/formancehq/go-libs/bun/bunmigrate" - "github.com/formancehq/go-libs/service" - "github.com/spf13/cobra" -) - -var ( - ServiceName = "reconciliation" - Version = "develop" - BuildDate = "-" - Commit = "-" -) - -const ( - stackURLFlag = "stack-url" - stackClientIDFlag = "stack-client-id" - stackClientSecretFlag = "stack-client-secret" - listenFlag = "listen" -) - -func NewRootCommand() *cobra.Command { - cmd := &cobra.Command{} - - cobra.EnableTraverseRunHooks = true - - serveCmd := newServeCommand(Version) - addAutoMigrateCommand(serveCmd) - cmd.AddCommand(serveCmd) - versionCmd := newVersionCommand() - cmd.AddCommand(versionCmd) - migrate := newMigrate() - cmd.AddCommand(migrate) - return cmd -} - -func Execute() { - service.Execute(NewRootCommand()) -} - -func addAutoMigrateCommand(cmd *cobra.Command) { - cmd.Flags().Bool(autoMigrateFlag, false, "Auto migrate database") - cmd.PreRunE = func(cmd *cobra.Command, args []string) error { - autoMigrate, _ := cmd.Flags().GetBool(autoMigrateFlag) - if autoMigrate { - return bunmigrate.Run(cmd, args, Migrate) - } - return nil - } -} diff --git a/ee/reconciliation/cmd/serve.go b/ee/reconciliation/cmd/serve.go deleted file mode 100644 index 22fe590ed9..0000000000 --- a/ee/reconciliation/cmd/serve.go +++ /dev/null @@ -1,113 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "net/http" - - "github.com/formancehq/go-libs/aws/iam" - - "github.com/formancehq/go-libs/bun/bunconnect" - "github.com/formancehq/go-libs/licence" - - sdk "github.com/formancehq/formance-sdk-go/v2" - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/go-libs/otlp" - "github.com/formancehq/go-libs/otlp/otlpmetrics" - "github.com/formancehq/go-libs/otlp/otlptraces" - "github.com/formancehq/go-libs/service" - "github.com/formancehq/reconciliation/internal/api" - "github.com/formancehq/reconciliation/internal/storage" - "github.com/spf13/cobra" - "go.uber.org/fx" - "golang.org/x/oauth2" - "golang.org/x/oauth2/clientcredentials" -) - -func stackClientModule(cmd *cobra.Command) fx.Option { - return fx.Options( - fx.Provide(func() *sdk.Formance { - stackClientID, _ := cmd.Flags().GetString(stackClientIDFlag) - stackClientSecret, _ := cmd.Flags().GetString(stackClientSecretFlag) - stackURL, _ := cmd.Flags().GetString(stackURLFlag) - - oauthConfig := clientcredentials.Config{ - ClientID: stackClientID, - ClientSecret: stackClientSecret, - TokenURL: fmt.Sprintf("%s/api/auth/oauth/token", stackURL), - Scopes: []string{"openid", "ledger:read", "ledger:write", "payments:read", "payments:write"}, - } - underlyingHTTPClient := &http.Client{ - Transport: otlp.NewRoundTripper(http.DefaultTransport, service.IsDebug(cmd)), - } - return sdk.New( - sdk.WithClient( - oauthConfig.Client(context.WithValue(context.Background(), - oauth2.HTTPClient, underlyingHTTPClient)), - ), - sdk.WithServerURL(stackURL), - ) - }), - ) -} - -func newServeCommand(version string) *cobra.Command { - cmd := &cobra.Command{ - Use: "serve", - RunE: runServer(version), - } - cmd.Flags().String(listenFlag, ":8080", "Listening address") - cmd.Flags().String(stackURLFlag, "", "Stack url") - cmd.Flags().String(stackClientIDFlag, "", "Stack client ID") - cmd.Flags().String(stackClientSecretFlag, "", "Stack client secret") - - otlpmetrics.AddFlags(cmd.Flags()) - otlptraces.AddFlags(cmd.Flags()) - auth.AddFlags(cmd.Flags()) - bunconnect.AddFlags(cmd.Flags()) - iam.AddFlags(cmd.Flags()) - service.AddFlags(cmd.Flags()) - licence.AddFlags(cmd.Flags()) - - return cmd -} - -func runServer(version string) func(cmd *cobra.Command, args []string) error { - return func(cmd *cobra.Command, args []string) error { - databaseOptions, err := prepareDatabaseOptions(cmd) - if err != nil { - return err - } - - options := make([]fx.Option, 0) - options = append(options, databaseOptions) - - options = append(options, - otlptraces.FXModuleFromFlags(cmd), - otlpmetrics.FXModuleFromFlags(cmd), - auth.FXModuleFromFlags(cmd), - ) - - listen, _ := cmd.Flags().GetString(listenFlag) - options = append(options, - stackClientModule(cmd), - api.HTTPModule(sharedapi.ServiceInfo{ - Version: version, - Debug: service.IsDebug(cmd), - }, listen), - licence.FXModuleFromFlags(cmd, ServiceName), - ) - - return service.New(cmd.OutOrStdout(), options...).Run(cmd) - } -} - -func prepareDatabaseOptions(cmd *cobra.Command) (fx.Option, error) { - connectionOptions, err := bunconnect.ConnectionOptionsFromFlags(cmd) - if err != nil { - return nil, err - } - - return storage.Module(*connectionOptions, service.IsDebug(cmd)), nil -} diff --git a/ee/reconciliation/cmd/version.go b/ee/reconciliation/cmd/version.go deleted file mode 100644 index 58c77193d3..0000000000 --- a/ee/reconciliation/cmd/version.go +++ /dev/null @@ -1,19 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -func newVersionCommand() *cobra.Command { - return &cobra.Command{ - Use: "version", - Short: "Get version", - Run: func(cmd *cobra.Command, args []string) { - fmt.Printf("Version: %s \n", Version) - fmt.Printf("Date: %s \n", BuildDate) - fmt.Printf("Commit: %s \n", Commit) - }, - } -} diff --git a/ee/reconciliation/go.mod b/ee/reconciliation/go.mod deleted file mode 100644 index e795e2a9f0..0000000000 --- a/ee/reconciliation/go.mod +++ /dev/null @@ -1,133 +0,0 @@ -module github.com/formancehq/reconciliation - -go 1.22.0 - -toolchain go1.22.7 - -require ( - github.com/formancehq/formance-sdk-go/v2 v2.0.0-00010101000000-000000000000 - github.com/formancehq/go-libs v1.7.1 - github.com/go-chi/chi/v5 v5.1.0 - github.com/golang/mock v1.6.0 - github.com/google/uuid v1.6.0 - github.com/jackc/pgconn v1.14.3 - github.com/pkg/errors v0.9.1 - github.com/spf13/cobra v1.8.1 - github.com/stretchr/testify v1.9.0 - github.com/uptrace/bun v1.2.3 - go.uber.org/fx v1.22.2 - golang.org/x/mod v0.19.0 - golang.org/x/oauth2 v0.23.0 - golang.org/x/sync v0.8.0 -) - -require ( - filippo.io/edwards25519 v1.1.0 // indirect - github.com/ThreeDotsLabs/watermill v1.3.7 // indirect - github.com/aws/aws-sdk-go-v2 v1.31.0 // indirect - github.com/aws/aws-sdk-go-v2/config v1.27.36 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.34 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 // indirect - github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.4.18 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.23.0 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.31.0 // indirect - github.com/aws/smithy-go v1.21.0 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect - github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-sql-driver/mysql v1.8.1 // indirect - github.com/goccy/go-json v0.10.3 // indirect - github.com/golang-jwt/jwt/v5 v5.2.1 // indirect - github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/schema v1.4.1 // indirect - github.com/gorilla/securecookie v1.1.2 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect - github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-retryablehttp v0.7.7 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgio v1.0.0 // indirect - github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.3.3 // indirect - github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect - github.com/lestrrat-go/blackmagic v1.0.2 // indirect - github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/jwx v1.2.30 // indirect - github.com/lestrrat-go/option v1.0.1 // indirect - github.com/lib/pq v1.10.9 // indirect - github.com/lithammer/shortuuid/v3 v3.0.7 // indirect - github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect - github.com/muhlemmer/gu v0.3.1 // indirect - github.com/muhlemmer/httpforwarded v0.1.0 // indirect - github.com/oklog/ulid v1.3.1 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect - github.com/riandyrn/otelchi v0.10.0 // indirect - github.com/rs/cors v1.11.1 // indirect - github.com/shirou/gopsutil/v4 v4.24.8 // indirect - github.com/shoenig/go-m1cpu v0.1.6 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/tklauser/go-sysconf v0.3.14 // indirect - github.com/tklauser/numcpus v0.8.0 // indirect - github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect - github.com/uptrace/bun/dialect/pgdialect v1.2.3 // indirect - github.com/uptrace/bun/extra/bunotel v1.2.3 // indirect - github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2 // indirect - github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2 // indirect - github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 // indirect - github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect - github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/xo/dburl v0.23.2 // indirect - github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zitadel/oidc/v2 v2.12.2 // indirect - go.opentelemetry.io/contrib/instrumentation/host v0.55.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect - go.opentelemetry.io/contrib/instrumentation/runtime v0.55.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.30.0 // indirect - go.opentelemetry.io/otel v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0 // indirect - go.opentelemetry.io/otel/log v0.6.0 // indirect - go.opentelemetry.io/otel/metric v1.30.0 // indirect - go.opentelemetry.io/otel/sdk v1.30.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.30.0 // indirect - go.opentelemetry.io/otel/trace v1.30.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.uber.org/dig v1.18.0 // indirect - go.uber.org/mock v0.4.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) - -replace github.com/formancehq/formance-sdk-go/v2 => ../../releases/sdks/go diff --git a/ee/reconciliation/go.sum b/ee/reconciliation/go.sum deleted file mode 100644 index 88f45c8a19..0000000000 --- a/ee/reconciliation/go.sum +++ /dev/null @@ -1,370 +0,0 @@ -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/ThreeDotsLabs/watermill v1.3.7 h1:NV0PSTmuACVEOV4dMxRnmGXrmbz8U83LENOvpHekN7o= -github.com/ThreeDotsLabs/watermill v1.3.7/go.mod h1:lBnrLbxOjeMRgcJbv+UiZr8Ylz8RkJ4m6i/VN/Nk+to= -github.com/aws/aws-sdk-go-v2 v1.31.0 h1:3V05LbxTSItI5kUqNwhJrrrY1BAXxXt0sN0l72QmG5U= -github.com/aws/aws-sdk-go-v2 v1.31.0/go.mod h1:ztolYtaEUtdpf9Wftr31CJfLVjOnD/CVRkKOOYgF8hA= -github.com/aws/aws-sdk-go-v2/config v1.27.36 h1:4IlvHh6Olc7+61O1ktesh0jOcqmq/4WG6C2Aj5SKXy0= -github.com/aws/aws-sdk-go-v2/config v1.27.36/go.mod h1:IiBpC0HPAGq9Le0Xxb1wpAKzEfAQ3XlYgJLYKEVYcfw= -github.com/aws/aws-sdk-go-v2/credentials v1.17.34 h1:gmkk1l/cDGSowPRzkdxYi8edw+gN4HmVK151D/pqGNc= -github.com/aws/aws-sdk-go-v2/credentials v1.17.34/go.mod h1:4R9OEV3tgFMsok4ZeFpExn7zQaZRa9MRGFYnI/xC/vs= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 h1:C/d03NAmh8C4BZXhuRNboF/DqhBkBCeDiJDcaqIT5pA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14/go.mod h1:7I0Ju7p9mCIdlrfS+JCgqcYD0VXz/N4yozsox+0o078= -github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.4.18 h1:k51348zRERIvv01FflXAOQj50NeUiZUGOEedT4Vg+UE= -github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.4.18/go.mod h1:uybY6ESdxsT2dpzwSmpDgZJ3ekCYwVe/ZFYfAaXUbtU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 h1:kYQ3H1u0ANr9KEKlGs/jTLrBFPo8P8NaH/w7A01NeeM= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18/go.mod h1:r506HmK5JDUh9+Mw4CfGJGSSoqIiLCndAuqXuhbv67Y= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 h1:Z7IdFUONvTcvS7YuhtVxN99v2cCoHRXOS4mTr0B/pUc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18/go.mod h1:DkKMmksZVVyat+Y+r1dEOgJEfUeA7UngIHWeKsi0yNc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 h1:QFASJGfT8wMXtuP3D5CRmMjARHv9ZmzFUMJznHDOY3w= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5/go.mod h1:QdZ3OmoIjSX+8D1OPAzPxDfjXASbBMDsz9qvtyIhtik= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 h1:Xbwbmk44URTiHNx6PNo0ujDE6ERlsCKJD3u1zfnzAPg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20/go.mod h1:oAfOFzUB14ltPZj1rWwRc3d/6OgD76R8KlvU3EqM9Fg= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.0 h1:fHySkG0IGj2nepgGJPmmhZYL9ndnsq1Tvc6MeuVQCaQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.0/go.mod h1:XRlMvmad0ZNL+75C5FYdMvbbLkd6qiqz6foR1nA1PXY= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.0 h1:cU/OeQPNReyMj1JEBgjE29aclYZYtXcsPMXbTkVGMFk= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.0/go.mod h1:FnvDM4sfa+isJ3kDXIzAB9GAwVSzFzSy97uZ3IsHo4E= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.0 h1:GNVxIHBTi2EgwCxpNiozhNasMOK+ROUA2Z3X+cSBX58= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.0/go.mod h1:yMWe0F+XG0DkRZK5ODZhG7BEFYhLXi2dqGsv6tX0cgI= -github.com/aws/smithy-go v1.21.0 h1:H7L8dtDRk0P1Qm6y0ji7MCYMQObJ5R9CRpyPhRUkLYA= -github.com/aws/smithy-go v1.21.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= -github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ= -github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= -github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 h1:S92OBrGuLLZsyM5ybUzgc/mPjIYk2AZqufieooe98uw= -github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05/go.mod h1:M9R1FoZ3y//hwwnJtO51ypFGwm8ZfpxPT/ZLtO1mcgQ= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/formancehq/go-libs v1.7.1 h1:9D5cxKWFlVtdX5AYDXeUz1Nb9PdoEfQX0f/yeLsU324= -github.com/formancehq/go-libs v1.7.1/go.mod h1:pWTScpoyieF7OoJ6WVmXNG9NhDjbZbAmFqd7UOw85iI= -github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= -github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= -github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= -github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= -github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= -github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= -github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 h1:c5FlPPgxOn7kJz3VoPLkQYQXGBS3EklQ4Zfi57uOuqQ= -github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= -github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= -github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= -github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= -github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= -github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= -github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= -github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w= -github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM= -github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= -github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= -github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= -github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag= -github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs= -github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA= -github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= -github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= -github.com/jeremija/gosubmit v0.2.7/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= -github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= -github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= -github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= -github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.30 h1:VKIFrmjYn0z2J51iLPadqoHIVLzvWNa1kCsTqNDHYPA= -github.com/lestrrat-go/jwx v1.2.30/go.mod h1:vMxrwFhunGZ3qddmfmEm2+uced8MSI6QFWGTKygjSzQ= -github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= -github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8= -github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts= -github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0= -github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -github.com/muhlemmer/gu v0.3.1 h1:7EAqmFrW7n3hETvuAdmFmn4hS8W+z3LgKtrnow+YzNM= -github.com/muhlemmer/gu v0.3.1/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZkrdM= -github.com/muhlemmer/httpforwarded v0.1.0 h1:x4DLrzXdliq8mprgUMR0olDvHGkou5BJsK/vWUetyzY= -github.com/muhlemmer/httpforwarded v0.1.0/go.mod h1:yo9czKedo2pdZhoXe+yDkGVbU0TJ0q9oQ90BVoDEtw0= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= -github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opencontainers/runc v1.1.14 h1:rgSuzbmgz5DUJjeSnw337TxDbRuqjs6iqQck/2weR6w= -github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA= -github.com/ory/dockertest/v3 v3.11.0 h1:OiHcxKAvSDUwsEVh2BjxQQc/5EHz9n0va9awCtNGuyA= -github.com/ory/dockertest/v3 v3.11.0/go.mod h1:VIPxS1gwT9NpPOrfD3rACs8Y9Z7yhzO4SB194iUDnUI= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= -github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4= -github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= -github.com/riandyrn/otelchi v0.10.0 h1:QMbR/FMDWBOkej6dfyWteYefUKqIFxnyrpaoWRJ9RPQ= -github.com/riandyrn/otelchi v0.10.0/go.mod h1:zBaX2FavWMlsvq4GqHit+QXxF1c5wIMZZFaYyW4+7FA= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= -github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shirou/gopsutil/v4 v4.24.8 h1:pVQjIenQkIhqO81mwTaXjTzOMT7d3TZkf43PlVFHENI= -github.com/shirou/gopsutil/v4 v4.24.8/go.mod h1:wE0OrJtj4dG+hYkxqDH3QiBICdKSf04/npcvLLc/oRg= -github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= -github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= -github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= -github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= -github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= -github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= -github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= -github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= -github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= -github.com/uptrace/bun v1.2.3 h1:6KDc6YiNlXde38j9ATKufb8o7MS8zllhAOeIyELKrk0= -github.com/uptrace/bun v1.2.3/go.mod h1:8frYFHrO/Zol3I4FEjoXam0HoNk+t5k7aJRl3FXp0mk= -github.com/uptrace/bun/dialect/pgdialect v1.2.3 h1:YyCxxqeL0lgFWRZzKCOt6mnxUsjqITcxSo0mLqgwMUA= -github.com/uptrace/bun/dialect/pgdialect v1.2.3/go.mod h1:Vx9TscyEq1iN4tnirn6yYGwEflz0KG3rBZTBCLpKAjc= -github.com/uptrace/bun/extra/bundebug v1.2.3 h1:2QBykz9/u4SkN9dnraImDcbrMk2fUhuq2gL6hkh9qSc= -github.com/uptrace/bun/extra/bundebug v1.2.3/go.mod h1:bihsYJxXxWZXwc1R3qALTHvp+npE0ElgaCvcjzyPPdw= -github.com/uptrace/bun/extra/bunotel v1.2.3 h1:G19QpDE68TXw97x6NciB6nKVDuK0Wb2KgtyMqNIyqBI= -github.com/uptrace/bun/extra/bunotel v1.2.3/go.mod h1:jHRgTqLlX/Zj1KIDokCMDat6JwZHJyErOx0PQ10UFgQ= -github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2 h1:H8wwQwTe5sL6x30z71lUgNiwBdeCHQjrphCfLwqIHGo= -github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2/go.mod h1:/kR4beFhlz2g+V5ik8jW+3PMiMQAPt29y6K64NNY53c= -github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2 h1:ZjUj9BLYf9PEqBn8W/OapxhPjVRdC6CsXTdULHsyk5c= -github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2/go.mod h1:O8bHQfyinKwTXKkiKNGmLQS7vRsqRxIQTFZpYpHK3IQ= -github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 h1:3/aHKUq7qaFMWxyQV0W2ryNgg8x8rVeKVA20KJUkfS0= -github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2/go.mod h1:Zit4b8AQXaXvA68+nzmbyDzqiyFRISyw1JiD5JqUBjw= -github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= -github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xo/dburl v0.23.2 h1:Fl88cvayrgE56JA/sqhNMLljCW/b7RmG1mMkKMZUFgA= -github.com/xo/dburl v0.23.2/go.mod h1:uazlaAQxj4gkshhfuuYyvwCBouOmNnG2aDxTCFZpmL4= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= -github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zitadel/oidc/v2 v2.12.2 h1:3kpckg4rurgw7w7aLJrq7yvRxb2pkNOtD08RH42vPEs= -github.com/zitadel/oidc/v2 v2.12.2/go.mod h1:vhP26g1g4YVntcTi0amMYW3tJuid70nxqxf+kb6XKgg= -go.opentelemetry.io/contrib/instrumentation/host v0.55.0 h1:V/Cy5A2ydwvyED4ewwXJ441R3QllG+U8tXXVOjPeX4Y= -go.opentelemetry.io/contrib/instrumentation/host v0.55.0/go.mod h1:fsY+EfHPwa1bQcxOUPv1FWaQXAwY+RliLRs6B6qgJes= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI= -go.opentelemetry.io/contrib/instrumentation/runtime v0.55.0 h1:GotCpbh7YkCHdFs+hYMdvAEyGsBZifFognqrOnBwyJM= -go.opentelemetry.io/contrib/instrumentation/runtime v0.55.0/go.mod h1:6b0AS55EEPj7qP44khqF5dqTUq+RkakDMShFaW1EcA4= -go.opentelemetry.io/contrib/propagators/b3 v1.30.0 h1:vumy4r1KMyaoQRltX7cJ37p3nluzALX9nugCjNNefuY= -go.opentelemetry.io/contrib/propagators/b3 v1.30.0/go.mod h1:fRbvRsaeVZ82LIl3u0rIvusIel2UUf+JcaaIpy5taho= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0 h1:WypxHH02KX2poqqbaadmkMYalGyy/vil4HE4PM4nRJc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0/go.mod h1:U79SV99vtvGSEBeeHnpgGJfTsnsdkWLpPN/CcHAzBSI= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0 h1:VrMAbeJz4gnVDg2zEzjHG4dEH86j4jO6VYB+NgtGD8s= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0/go.mod h1:qqN/uFdpeitTvm+JDqqnjm517pmQRYxTORbETHq5tOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 h1:umZgi92IyxfXd/l4kaDhnKgY8rnN/cZcF1LKc6I8OQ8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0/go.mod h1:4lVs6obhSVRb1EW5FhOuBTyiQhtRtAnnva9vD3yRfq8= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.30.0 h1:IyFlqNsi8VT/nwYlLJfdM0y1gavxGpEvnf6FtVfZ6X4= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.30.0/go.mod h1:bxiX8eUeKoAEQmbq/ecUT8UqZwCjZW52yJrXJUSozsk= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0 h1:kn1BudCgwtE7PxLqcZkErpD8GKqLZ6BSzeW9QihQJeM= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0/go.mod h1:ljkUDtAMdleoi9tIG1R6dJUpVwDcYjw3J2Q6Q/SuiC0= -go.opentelemetry.io/otel/log v0.6.0 h1:nH66tr+dmEgW5y+F9LanGJUBYPrRgP4g2EkmPE3LeK8= -go.opentelemetry.io/otel/log v0.6.0/go.mod h1:KdySypjQHhP069JX0z/t26VHwa8vSwzgaKmXtIB3fJM= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= -go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= -go.opentelemetry.io/otel/sdk/metric v1.30.0 h1:QJLT8Pe11jyHBHfSAgYH7kEmT24eX792jZO1bo4BXkM= -go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= -go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= -go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs= -gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/ee/reconciliation/internal/api/api_utils_test.go b/ee/reconciliation/internal/api/api_utils_test.go deleted file mode 100644 index 959930d807..0000000000 --- a/ee/reconciliation/internal/api/api_utils_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package api - -import ( - "testing" - - "github.com/formancehq/reconciliation/internal/api/backend" - gomock "github.com/golang/mock/gomock" -) - -func newTestingBackend(t *testing.T) (*backend.MockBackend, *backend.MockService) { - ctrl := gomock.NewController(t) - mockService := backend.NewMockService(ctrl) - backend := backend.NewMockBackend(ctrl) - backend. - EXPECT(). - GetService(). - MinTimes(0). - Return(mockService) - t.Cleanup(func() { - ctrl.Finish() - }) - return backend, mockService -} diff --git a/ee/reconciliation/internal/api/backend/backend.go b/ee/reconciliation/internal/api/backend/backend.go deleted file mode 100644 index 787cbfb8e5..0000000000 --- a/ee/reconciliation/internal/api/backend/backend.go +++ /dev/null @@ -1,41 +0,0 @@ -package backend - -import ( - "context" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/formancehq/reconciliation/internal/api/service" - "github.com/formancehq/reconciliation/internal/models" - "github.com/formancehq/reconciliation/internal/storage" -) - -//go:generate mockgen -source backend.go -destination backend_generated.go -package backend . Service -type Service interface { - Reconciliation(ctx context.Context, policyID string, req *service.ReconciliationRequest) (*models.Reconciliation, error) - GetReconciliation(ctx context.Context, id string) (*models.Reconciliation, error) - ListReconciliations(ctx context.Context, q storage.GetReconciliationsQuery) (*bunpaginate.Cursor[models.Reconciliation], error) - - CreatePolicy(ctx context.Context, req *service.CreatePolicyRequest) (*models.Policy, error) - DeletePolicy(ctx context.Context, id string) error - GetPolicy(ctx context.Context, id string) (*models.Policy, error) - ListPolicies(ctx context.Context, q storage.GetPoliciesQuery) (*bunpaginate.Cursor[models.Policy], error) -} - -type Backend interface { - GetService() Service -} - -type DefaultBackend struct { - service Service -} - -func (d DefaultBackend) GetService() Service { - return d.service -} - -func NewDefaultBackend(service Service) Backend { - return &DefaultBackend{ - service: service, - } -} diff --git a/ee/reconciliation/internal/api/backend/backend_generated.go b/ee/reconciliation/internal/api/backend/backend_generated.go deleted file mode 100644 index 82dfa7b4c8..0000000000 --- a/ee/reconciliation/internal/api/backend/backend_generated.go +++ /dev/null @@ -1,180 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: backend.go - -// Package backend is a generated GoMock package. -package backend - -import ( - context "context" - api "github.com/formancehq/go-libs/bun/bunpaginate" - reflect "reflect" - - service "github.com/formancehq/reconciliation/internal/api/service" - models "github.com/formancehq/reconciliation/internal/models" - storage "github.com/formancehq/reconciliation/internal/storage" - gomock "github.com/golang/mock/gomock" -) - -// MockService is a mock of Service interface. -type MockService struct { - ctrl *gomock.Controller - recorder *MockServiceMockRecorder -} - -// MockServiceMockRecorder is the mock recorder for MockService. -type MockServiceMockRecorder struct { - mock *MockService -} - -// NewMockService creates a new mock instance. -func NewMockService(ctrl *gomock.Controller) *MockService { - mock := &MockService{ctrl: ctrl} - mock.recorder = &MockServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockService) EXPECT() *MockServiceMockRecorder { - return m.recorder -} - -// CreatePolicy mocks base method. -func (m *MockService) CreatePolicy(ctx context.Context, req *service.CreatePolicyRequest) (*models.Policy, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreatePolicy", ctx, req) - ret0, _ := ret[0].(*models.Policy) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CreatePolicy indicates an expected call of CreatePolicy. -func (mr *MockServiceMockRecorder) CreatePolicy(ctx, req interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreatePolicy", reflect.TypeOf((*MockService)(nil).CreatePolicy), ctx, req) -} - -// DeletePolicy mocks base method. -func (m *MockService) DeletePolicy(ctx context.Context, id string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeletePolicy", ctx, id) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeletePolicy indicates an expected call of DeletePolicy. -func (mr *MockServiceMockRecorder) DeletePolicy(ctx, id interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePolicy", reflect.TypeOf((*MockService)(nil).DeletePolicy), ctx, id) -} - -// GetPolicy mocks base method. -func (m *MockService) GetPolicy(ctx context.Context, id string) (*models.Policy, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPolicy", ctx, id) - ret0, _ := ret[0].(*models.Policy) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPolicy indicates an expected call of GetPolicy. -func (mr *MockServiceMockRecorder) GetPolicy(ctx, id interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPolicy", reflect.TypeOf((*MockService)(nil).GetPolicy), ctx, id) -} - -// GetReconciliation mocks base method. -func (m *MockService) GetReconciliation(ctx context.Context, id string) (*models.Reconciliation, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetReconciliation", ctx, id) - ret0, _ := ret[0].(*models.Reconciliation) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetReconciliation indicates an expected call of GetReconciliation. -func (mr *MockServiceMockRecorder) GetReconciliation(ctx, id interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetReconciliation", reflect.TypeOf((*MockService)(nil).GetReconciliation), ctx, id) -} - -// ListPolicies mocks base method. -func (m *MockService) ListPolicies(ctx context.Context, q storage.GetPoliciesQuery) (*api.Cursor[models.Policy], error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListPolicies", ctx, q) - ret0, _ := ret[0].(*api.Cursor[models.Policy]) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListPolicies indicates an expected call of ListPolicies. -func (mr *MockServiceMockRecorder) ListPolicies(ctx, q interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListPolicies", reflect.TypeOf((*MockService)(nil).ListPolicies), ctx, q) -} - -// ListReconciliations mocks base method. -func (m *MockService) ListReconciliations(ctx context.Context, q storage.GetReconciliationsQuery) (*api.Cursor[models.Reconciliation], error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListReconciliations", ctx, q) - ret0, _ := ret[0].(*api.Cursor[models.Reconciliation]) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListReconciliations indicates an expected call of ListReconciliations. -func (mr *MockServiceMockRecorder) ListReconciliations(ctx, q interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListReconciliations", reflect.TypeOf((*MockService)(nil).ListReconciliations), ctx, q) -} - -// Reconciliation mocks base method. -func (m *MockService) Reconciliation(ctx context.Context, policyID string, req *service.ReconciliationRequest) (*models.Reconciliation, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Reconciliation", ctx, policyID, req) - ret0, _ := ret[0].(*models.Reconciliation) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Reconciliation indicates an expected call of Reconciliation. -func (mr *MockServiceMockRecorder) Reconciliation(ctx, policyID, req interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reconciliation", reflect.TypeOf((*MockService)(nil).Reconciliation), ctx, policyID, req) -} - -// MockBackend is a mock of Backend interface. -type MockBackend struct { - ctrl *gomock.Controller - recorder *MockBackendMockRecorder -} - -// MockBackendMockRecorder is the mock recorder for MockBackend. -type MockBackendMockRecorder struct { - mock *MockBackend -} - -// NewMockBackend creates a new mock instance. -func NewMockBackend(ctrl *gomock.Controller) *MockBackend { - mock := &MockBackend{ctrl: ctrl} - mock.recorder = &MockBackendMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockBackend) EXPECT() *MockBackendMockRecorder { - return m.recorder -} - -// GetService mocks base method. -func (m *MockBackend) GetService() Service { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetService") - ret0, _ := ret[0].(Service) - return ret0 -} - -// GetService indicates an expected call of GetService. -func (mr *MockBackendMockRecorder) GetService() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetService", reflect.TypeOf((*MockBackend)(nil).GetService)) -} diff --git a/ee/reconciliation/internal/api/module.go b/ee/reconciliation/internal/api/module.go deleted file mode 100644 index c86aa6ed21..0000000000 --- a/ee/reconciliation/internal/api/module.go +++ /dev/null @@ -1,66 +0,0 @@ -package api - -import ( - "context" - "errors" - "net/http" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/api" - "github.com/formancehq/go-libs/health" - "github.com/formancehq/go-libs/httpserver" - "github.com/formancehq/reconciliation/internal/api/backend" - "github.com/formancehq/reconciliation/internal/api/service" - "github.com/formancehq/reconciliation/internal/storage" - "go.uber.org/fx" -) - -const ( - ErrInvalidID = "INVALID_ID" - ErrMissingOrInvalidBody = "MISSING_OR_INVALID_BODY" - ErrValidation = "VALIDATION" -) - -func healthCheckModule() fx.Option { - return fx.Options( - health.Module(), - health.ProvideHealthCheck(func() health.NamedCheck { - return health.NewNamedCheck("default", health.CheckFn(func(ctx context.Context) error { - return nil - })) - }), - ) -} - -func HTTPModule(serviceInfo api.ServiceInfo, bind string) fx.Option { - return fx.Options( - healthCheckModule(), - fx.Invoke(func(m *chi.Mux, lc fx.Lifecycle) { - lc.Append(httpserver.NewHook(m, httpserver.WithAddress(bind))) - }), - fx.Provide(func(store *storage.Storage) service.Store { - return store - }), - fx.Supply(serviceInfo), - fx.Provide(fx.Annotate(service.NewSDKFormance, fx.As(new(service.SDKFormance)))), - fx.Provide(fx.Annotate(service.NewService, fx.As(new(backend.Service)))), - fx.Provide(backend.NewDefaultBackend), - fx.Provide(newRouter), - ) -} - -func handleServiceErrors(w http.ResponseWriter, r *http.Request, err error) { - switch { - case errors.Is(err, service.ErrValidation): - api.BadRequest(w, ErrValidation, err) - case errors.Is(err, service.ErrInvalidID): - api.BadRequest(w, ErrInvalidID, err) - case errors.Is(storage.ErrInvalidQuery, err): - api.BadRequest(w, ErrValidation, err) - case errors.Is(storage.ErrNotFound, err): - api.NotFound(w, err) - default: - api.InternalServerError(w, r, err) - } -} diff --git a/ee/reconciliation/internal/api/policy.go b/ee/reconciliation/internal/api/policy.go deleted file mode 100644 index f93ff4ad55..0000000000 --- a/ee/reconciliation/internal/api/policy.go +++ /dev/null @@ -1,118 +0,0 @@ -package api - -import ( - "encoding/json" - "fmt" - "net/http" - "time" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/api" - "github.com/formancehq/go-libs/bun/bunpaginate" - "github.com/formancehq/reconciliation/internal/api/backend" - "github.com/formancehq/reconciliation/internal/api/service" - "github.com/formancehq/reconciliation/internal/storage" -) - -type policyResponse struct { - ID string `json:"id"` - Name string `json:"name"` - CreatedAt time.Time `json:"createdAt"` - LedgerName string `json:"ledgerName"` - LedgerQuery map[string]interface{} `json:"ledgerQuery"` - PaymentsPoolID string `json:"paymentsPoolID"` -} - -func createPolicyHandler(b backend.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req service.CreatePolicyRequest - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - api.BadRequest(w, ErrMissingOrInvalidBody, err) - return - } - - policy, err := b.GetService().CreatePolicy(r.Context(), &req) - if err != nil { - handleServiceErrors(w, r, err) - return - } - - data := &policyResponse{ - ID: policy.ID.String(), - Name: policy.Name, - CreatedAt: policy.CreatedAt, - LedgerName: policy.LedgerName, - LedgerQuery: policy.LedgerQuery, - PaymentsPoolID: policy.PaymentsPoolID.String(), - } - - api.Created(w, data) - } -} - -func deletePolicyHandler(b backend.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - id := chi.URLParam(r, "policyID") - - err := b.GetService().DeletePolicy(r.Context(), id) - if err != nil { - handleServiceErrors(w, r, err) - return - } - - api.NoContent(w) - } -} - -func getPolicyHandler(b backend.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - id := chi.URLParam(r, "policyID") - - policy, err := b.GetService().GetPolicy(r.Context(), id) - if err != nil { - handleServiceErrors(w, r, err) - return - } - - data := &policyResponse{ - ID: policy.ID.String(), - Name: policy.Name, - CreatedAt: policy.CreatedAt, - LedgerName: policy.LedgerName, - LedgerQuery: policy.LedgerQuery, - PaymentsPoolID: policy.PaymentsPoolID.String(), - } - - api.Ok(w, data) - } -} - -func listPoliciesHandler(b backend.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - q := storage.GetPoliciesQuery{} - - if r.URL.Query().Get(QueryKeyCursor) != "" { - err := bunpaginate.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), &q) - if err != nil { - api.BadRequest(w, ErrValidation, fmt.Errorf("invalid '%s' query param", QueryKeyCursor)) - return - } - } else { - options, err := getPaginatedQueryOptionsPolicies(r) - if err != nil { - api.BadRequest(w, ErrValidation, err) - return - } - q = storage.NewGetPoliciesQuery(*options) - } - - cursor, err := b.GetService().ListPolicies(r.Context(), q) - if err != nil { - handleServiceErrors(w, r, err) - return - } - - api.RenderCursor(w, *cursor) - } -} diff --git a/ee/reconciliation/internal/api/policy_test.go b/ee/reconciliation/internal/api/policy_test.go deleted file mode 100644 index dc19065e5a..0000000000 --- a/ee/reconciliation/internal/api/policy_test.go +++ /dev/null @@ -1,374 +0,0 @@ -package api - -import ( - "bytes" - "encoding/json" - "errors" - "net/http" - "net/http/httptest" - "testing" - "time" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/reconciliation/internal/api/service" - "github.com/formancehq/reconciliation/internal/models" - "github.com/formancehq/reconciliation/internal/storage" - gomock "github.com/golang/mock/gomock" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestCreatePolicy(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - req *service.CreatePolicyRequest - invalidBody bool - expectedStatusCode int - serviceError error - expectedErrorCode string - } - - testCases := []testCase{ - { - name: "nominal", - req: &service.CreatePolicyRequest{ - Name: "test", - LedgerName: "test", - LedgerQuery: map[string]interface{}{}, - PaymentsPoolID: "00000000-0000-0000-0000-000000000000", - }, - }, - { - name: "missing body", - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrMissingOrInvalidBody, - }, - { - name: "invalid body", - invalidBody: true, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrMissingOrInvalidBody, - }, - { - name: "service error validation", - req: &service.CreatePolicyRequest{ - Name: "test", - LedgerName: "test", - LedgerQuery: map[string]interface{}{}, - PaymentsPoolID: "00000000-0000-0000-0000-000000000000", - }, - serviceError: service.ErrValidation, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrValidation, - }, - { - name: "service error invalid id", - req: &service.CreatePolicyRequest{ - Name: "test", - LedgerName: "test", - LedgerQuery: map[string]interface{}{}, - PaymentsPoolID: "00000000-0000-0000-0000-000000000000", - }, - serviceError: service.ErrInvalidID, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrInvalidID, - }, - { - name: "storage error not found", - req: &service.CreatePolicyRequest{ - Name: "test", - LedgerName: "test", - LedgerQuery: map[string]interface{}{}, - PaymentsPoolID: "00000000-0000-0000-0000-000000000000", - }, - serviceError: storage.ErrNotFound, - expectedStatusCode: http.StatusNotFound, - expectedErrorCode: sharedapi.ErrorCodeNotFound, - }, - { - name: "service error other error", - req: &service.CreatePolicyRequest{ - Name: "test", - LedgerName: "test", - LedgerQuery: map[string]interface{}{}, - PaymentsPoolID: "00000000-0000-0000-0000-000000000000", - }, - serviceError: errors.New("some error"), - expectedStatusCode: http.StatusInternalServerError, - expectedErrorCode: sharedapi.ErrorInternal, - }, - } - - for _, tc := range testCases { - testCase := tc - t.Run(testCase.name, func(t *testing.T) { - t.Parallel() - - if testCase.expectedStatusCode == 0 { - testCase.expectedStatusCode = http.StatusCreated - } - - var policyServiceResponse models.Policy - if testCase.req != nil { - policyServiceResponse = models.Policy{ - ID: uuid.New(), - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Name: testCase.req.Name, - LedgerName: testCase.req.LedgerName, - LedgerQuery: testCase.req.LedgerQuery, - PaymentsPoolID: uuid.MustParse(testCase.req.PaymentsPoolID), - } - } - - expectedPolicyResponse := &policyResponse{ - ID: policyServiceResponse.ID.String(), - Name: policyServiceResponse.Name, - CreatedAt: policyServiceResponse.CreatedAt, - LedgerName: policyServiceResponse.LedgerName, - LedgerQuery: policyServiceResponse.LedgerQuery, - PaymentsPoolID: policyServiceResponse.PaymentsPoolID.String(), - } - - backend, mockService := newTestingBackend(t) - if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { - mockService.EXPECT(). - CreatePolicy(gomock.Any(), testCase.req). - Return(&policyServiceResponse, nil) - } - if testCase.serviceError != nil { - mockService.EXPECT(). - CreatePolicy(gomock.Any(), testCase.req). - Return(nil, testCase.serviceError) - } - - router := newRouter(backend, sharedapi.ServiceInfo{ - Debug: testing.Verbose(), - }, auth.NewNoAuth(), nil) - - var body []byte - if testCase.invalidBody { - body = []byte("invalid") - } else if testCase.req != nil { - var err error - body, err = json.Marshal(testCase.req) - require.NoError(t, err) - } - - req := httptest.NewRequest(http.MethodPost, "/policies", bytes.NewReader(body)) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectedStatusCode, rec.Code) - if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { - var resp sharedapi.BaseResponse[policyResponse] - sharedapi.Decode(t, rec.Body, &resp) - require.Equal(t, expectedPolicyResponse, resp.Data) - } else { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} - -func TestDeletePolicy(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - policyID string - expectedStatusCode int - serviceError error - expectedErrorCode string - } - - testCases := []testCase{ - { - name: "nominal", - policyID: "00000000-0000-0000-0000-000000000000", - }, - { - name: "service error validation", - policyID: "00000000-0000-0000-0000-000000000000", - serviceError: service.ErrValidation, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrValidation, - }, - { - name: "service error invalid id", - policyID: "invalid", - serviceError: service.ErrInvalidID, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrInvalidID, - }, - { - name: "storage error not found", - policyID: "invalid", - serviceError: storage.ErrNotFound, - expectedStatusCode: http.StatusNotFound, - expectedErrorCode: sharedapi.ErrorCodeNotFound, - }, - { - name: "service error other error", - policyID: "00000000-0000-0000-0000-000000000000", - serviceError: errors.New("some error"), - expectedStatusCode: http.StatusInternalServerError, - expectedErrorCode: sharedapi.ErrorInternal, - }, - } - - for _, tc := range testCases { - testCase := tc - t.Run(testCase.name, func(t *testing.T) { - t.Parallel() - - if testCase.expectedStatusCode == 0 { - testCase.expectedStatusCode = http.StatusNoContent - } - - backend, mockService := newTestingBackend(t) - if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { - mockService.EXPECT(). - DeletePolicy(gomock.Any(), testCase.policyID). - Return(nil) - } - if testCase.serviceError != nil { - mockService.EXPECT(). - DeletePolicy(gomock.Any(), testCase.policyID). - Return(testCase.serviceError) - } - - router := newRouter(backend, sharedapi.ServiceInfo{ - Debug: testing.Verbose(), - }, auth.NewNoAuth(), nil) - - req := httptest.NewRequest(http.MethodDelete, "/policies/"+testCase.policyID, nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectedStatusCode, rec.Code) - if testCase.expectedStatusCode >= 300 || testCase.expectedStatusCode < 200 { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} - -func TestGetPolicy(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - policyID string - expectedStatusCode int - serviceError error - expectedErrorCode string - } - - testCases := []testCase{ - { - name: "nominal", - policyID: "00000000-0000-0000-0000-000000000000", - }, - { - name: "service error validation", - policyID: "00000000-0000-0000-0000-000000000000", - serviceError: service.ErrValidation, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrValidation, - }, - { - name: "service error invalid id", - policyID: "00000000-0000-0000-0000-000000000000", - serviceError: service.ErrInvalidID, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrInvalidID, - }, - { - name: "storage error not found", - policyID: "00000000-0000-0000-0000-000000000000", - serviceError: storage.ErrNotFound, - expectedStatusCode: http.StatusNotFound, - expectedErrorCode: sharedapi.ErrorCodeNotFound, - }, - { - name: "service error other error", - policyID: "00000000-0000-0000-0000-000000000000", - serviceError: errors.New("some error"), - expectedStatusCode: http.StatusInternalServerError, - expectedErrorCode: sharedapi.ErrorInternal, - }, - } - - for _, tc := range testCases { - testCase := tc - t.Run(testCase.name, func(t *testing.T) { - t.Parallel() - - if testCase.expectedStatusCode == 0 { - testCase.expectedStatusCode = http.StatusOK - } - - var policyServiceResponse models.Policy - if testCase.policyID != "" { - policyServiceResponse = models.Policy{ - ID: uuid.MustParse(testCase.policyID), - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Name: "test", - LedgerName: "test", - LedgerQuery: map[string]interface{}{}, - PaymentsPoolID: uuid.New(), - } - } - - expectedPolicyResponse := &policyResponse{ - ID: policyServiceResponse.ID.String(), - Name: policyServiceResponse.Name, - CreatedAt: policyServiceResponse.CreatedAt, - LedgerName: policyServiceResponse.LedgerName, - LedgerQuery: policyServiceResponse.LedgerQuery, - PaymentsPoolID: policyServiceResponse.PaymentsPoolID.String(), - } - - backend, mockService := newTestingBackend(t) - if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { - mockService.EXPECT(). - GetPolicy(gomock.Any(), testCase.policyID). - Return(&policyServiceResponse, nil) - } - if testCase.serviceError != nil { - mockService.EXPECT(). - GetPolicy(gomock.Any(), testCase.policyID). - Return(nil, testCase.serviceError) - } - - router := newRouter(backend, sharedapi.ServiceInfo{ - Debug: testing.Verbose(), - }, auth.NewNoAuth(), nil) - - req := httptest.NewRequest(http.MethodGet, "/policies/"+testCase.policyID, nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectedStatusCode, rec.Code) - if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { - var resp sharedapi.BaseResponse[policyResponse] - sharedapi.Decode(t, rec.Body, &resp) - require.Equal(t, expectedPolicyResponse, resp.Data) - } else { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} diff --git a/ee/reconciliation/internal/api/query.go b/ee/reconciliation/internal/api/query.go deleted file mode 100644 index 706dc39275..0000000000 --- a/ee/reconciliation/internal/api/query.go +++ /dev/null @@ -1,43 +0,0 @@ -package api - -import ( - "errors" - "net/http" - "strconv" - - "github.com/formancehq/go-libs/bun/bunpaginate" -) - -const ( - MaxPageSize = 100 - DefaultPageSize = bunpaginate.QueryDefaultPageSize - - QueryKeyCursor = "cursor" - QueryKeyPageSize = "pageSize" -) - -var ( - ErrInvalidPageSize = errors.New("invalid 'pageSize' query param") -) - -func getPageSize(r *http.Request) (uint64, error) { - pageSizeParam := r.URL.Query().Get(QueryKeyPageSize) - if pageSizeParam == "" { - return DefaultPageSize, nil - } - - var pageSize uint64 - var err error - if pageSizeParam != "" { - pageSize, err = strconv.ParseUint(pageSizeParam, 10, 32) - if err != nil { - return 0, ErrInvalidPageSize - } - } - - if pageSize > MaxPageSize { - return MaxPageSize, nil - } - - return pageSize, nil -} diff --git a/ee/reconciliation/internal/api/reconciliation.go b/ee/reconciliation/internal/api/reconciliation.go deleted file mode 100644 index 238fbfc971..0000000000 --- a/ee/reconciliation/internal/api/reconciliation.go +++ /dev/null @@ -1,130 +0,0 @@ -package api - -import ( - "encoding/json" - "errors" - "fmt" - "math/big" - "net/http" - "time" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/api" - "github.com/formancehq/go-libs/bun/bunpaginate" - "github.com/formancehq/reconciliation/internal/api/backend" - "github.com/formancehq/reconciliation/internal/api/service" - "github.com/formancehq/reconciliation/internal/storage" -) - -type reconciliationResponse struct { - ID string `json:"id"` - PolicyID string `json:"policyID"` - CreatedAt time.Time `json:"createdAt"` - ReconciledAtLedger time.Time `json:"reconciledAtLedger"` - ReconciledAtPayments time.Time `json:"reconciledAtPayments"` - Status string `json:"status"` - PaymentsBalances map[string]*big.Int `json:"paymentsBalances"` - LedgerBalances map[string]*big.Int `json:"ledgerBalances"` - DriftBalances map[string]*big.Int `json:"driftBalances"` - Error string `json:"error"` -} - -func reconciliationHandler(b backend.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req service.ReconciliationRequest - err := json.NewDecoder(r.Body).Decode(&req) - if err != nil { - api.BadRequest(w, ErrMissingOrInvalidBody, err) - return - } - - if err := req.Validate(); err != nil { - api.BadRequest(w, ErrValidation, err) - return - } - - policyID := chi.URLParam(r, "policyID") - if policyID == "" { - api.BadRequest(w, ErrValidation, errors.New("missing policyID")) - return - } - - res, err := b.GetService().Reconciliation(r.Context(), policyID, &req) - if err != nil { - handleServiceErrors(w, r, err) - return - } - - data := &reconciliationResponse{ - ID: res.ID.String(), - PolicyID: policyID, - CreatedAt: res.CreatedAt, - ReconciledAtLedger: res.ReconciledAtLedger, - ReconciledAtPayments: res.ReconciledAtPayments, - Status: res.Status.String(), - PaymentsBalances: res.PaymentsBalances, - LedgerBalances: res.LedgerBalances, - DriftBalances: res.DriftBalances, - Error: res.Error, - } - - api.Ok(w, data) - } -} - -func getReconciliationHandler(b backend.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - id := chi.URLParam(r, "reconciliationID") - - res, err := b.GetService().GetReconciliation(r.Context(), id) - if err != nil { - handleServiceErrors(w, r, err) - return - } - - data := &reconciliationResponse{ - ID: res.ID.String(), - PolicyID: res.PolicyID.String(), - CreatedAt: res.CreatedAt, - ReconciledAtLedger: res.ReconciledAtLedger, - ReconciledAtPayments: res.ReconciledAtPayments, - Status: res.Status.String(), - PaymentsBalances: res.PaymentsBalances, - LedgerBalances: res.LedgerBalances, - DriftBalances: res.DriftBalances, - Error: res.Error, - } - - api.Ok(w, data) - } -} - -func listReconciliationsHandler(b backend.Backend) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - q := storage.GetReconciliationsQuery{} - - if r.URL.Query().Get(QueryKeyCursor) != "" { - err := bunpaginate.UnmarshalCursor(r.URL.Query().Get(QueryKeyCursor), &q) - if err != nil { - api.BadRequest(w, ErrValidation, fmt.Errorf("invalid '%s' query param", QueryKeyCursor)) - return - } - } else { - options, err := getPaginatedQueryOptionsReconciliations(r) - if err != nil { - api.BadRequest(w, ErrValidation, err) - return - } - q = storage.NewGetReconciliationsQuery(*options) - } - - cursor, err := b.GetService().ListReconciliations(r.Context(), q) - if err != nil { - handleServiceErrors(w, r, err) - return - } - - api.RenderCursor(w, *cursor) - } -} diff --git a/ee/reconciliation/internal/api/reconciliation_test.go b/ee/reconciliation/internal/api/reconciliation_test.go deleted file mode 100644 index 93b430558a..0000000000 --- a/ee/reconciliation/internal/api/reconciliation_test.go +++ /dev/null @@ -1,471 +0,0 @@ -package api - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "math/big" - "net/http" - "net/http/httptest" - "testing" - "time" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/reconciliation/internal/api/service" - "github.com/formancehq/reconciliation/internal/models" - "github.com/formancehq/reconciliation/internal/storage" - gomock "github.com/golang/mock/gomock" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestReconciliation(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - policyID string - req *service.ReconciliationRequest - res *models.Reconciliation - invalidBody bool - expectedStatusCode int - serviceError error - expectedErrorCode string - } - - policyID := uuid.New() - testCases := []testCase{ - { - name: "nominal", - policyID: policyID.String(), - req: &service.ReconciliationRequest{ - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - }, - res: &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policyID, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - PaymentsBalances: map[string]*big.Int{}, - LedgerBalances: map[string]*big.Int{}, - Error: "", - }, - }, - { - name: "missing body", - policyID: policyID.String(), - res: &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policyID, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - PaymentsBalances: map[string]*big.Int{}, - LedgerBalances: map[string]*big.Int{}, - Error: "", - }, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrMissingOrInvalidBody, - }, - { - name: "invalid body", - policyID: policyID.String(), - req: &service.ReconciliationRequest{ - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - }, - res: &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policyID, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - PaymentsBalances: map[string]*big.Int{}, - LedgerBalances: map[string]*big.Int{}, - Error: "", - }, - invalidBody: true, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrMissingOrInvalidBody, - }, - { - name: "missing at ledger", - policyID: policyID.String(), - req: &service.ReconciliationRequest{ - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - }, - res: &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policyID, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - PaymentsBalances: map[string]*big.Int{}, - LedgerBalances: map[string]*big.Int{}, - Error: "", - }, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrValidation, - }, - { - name: "zero time.Time ledger", - policyID: policyID.String(), - req: &service.ReconciliationRequest{ - ReconciledAtLedger: time.Time{}, - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - }, - res: &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policyID, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtLedger: time.Time{}, - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - PaymentsBalances: map[string]*big.Int{}, - LedgerBalances: map[string]*big.Int{}, - Error: "", - }, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrValidation, - }, - { - name: "missing at payments", - policyID: policyID.String(), - req: &service.ReconciliationRequest{ - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - }, - res: &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policyID, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - PaymentsBalances: map[string]*big.Int{}, - LedgerBalances: map[string]*big.Int{}, - Error: "", - }, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrValidation, - }, - { - name: "zero time.Time ledger", - policyID: policyID.String(), - req: &service.ReconciliationRequest{ - ReconciledAtLedger: time.Time{}, - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - }, - res: &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policyID, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtLedger: time.Time{}, - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - PaymentsBalances: map[string]*big.Int{}, - LedgerBalances: map[string]*big.Int{}, - Error: "", - }, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrValidation, - }, - { - name: "service error validation", - policyID: policyID.String(), - req: &service.ReconciliationRequest{ - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - }, - res: &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policyID, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - PaymentsBalances: map[string]*big.Int{}, - LedgerBalances: map[string]*big.Int{}, - Error: "", - }, - serviceError: service.ErrValidation, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrValidation, - }, - { - name: "service error invalid id", - policyID: "invalid", - req: &service.ReconciliationRequest{ - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - }, - res: &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policyID, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - PaymentsBalances: map[string]*big.Int{}, - LedgerBalances: map[string]*big.Int{}, - Error: "", - }, - serviceError: service.ErrInvalidID, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrInvalidID, - }, - { - name: "service error invalid ID", - policyID: "invalid", - req: &service.ReconciliationRequest{ - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - }, - res: &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policyID, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - PaymentsBalances: map[string]*big.Int{}, - LedgerBalances: map[string]*big.Int{}, - Error: "", - }, - serviceError: service.ErrInvalidID, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrInvalidID, - }, - { - name: "storage error not found", - policyID: "invalid", - req: &service.ReconciliationRequest{ - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - }, - res: &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policyID, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - PaymentsBalances: map[string]*big.Int{}, - LedgerBalances: map[string]*big.Int{}, - Error: "", - }, - serviceError: storage.ErrNotFound, - expectedStatusCode: http.StatusNotFound, - expectedErrorCode: sharedapi.ErrorCodeNotFound, - }, - { - name: "service error other error", - policyID: policyID.String(), - req: &service.ReconciliationRequest{ - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - }, - res: &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policyID, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - PaymentsBalances: map[string]*big.Int{}, - LedgerBalances: map[string]*big.Int{}, - Error: "", - }, - serviceError: errors.New("some error"), - expectedStatusCode: http.StatusInternalServerError, - expectedErrorCode: sharedapi.ErrorInternal, - }, - } - - for _, tc := range testCases { - testCase := tc - t.Run(testCase.name, func(t *testing.T) { - t.Parallel() - - if testCase.expectedStatusCode == 0 { - testCase.expectedStatusCode = http.StatusOK - } - - expectedReconciliationResponse := &reconciliationResponse{ - ID: testCase.res.ID.String(), - PolicyID: testCase.res.PolicyID.String(), - CreatedAt: testCase.res.CreatedAt, - ReconciledAtLedger: testCase.res.ReconciledAtLedger, - ReconciledAtPayments: testCase.res.ReconciledAtPayments, - Status: testCase.res.Status.String(), - PaymentsBalances: testCase.res.PaymentsBalances, - LedgerBalances: testCase.res.LedgerBalances, - Error: testCase.res.Error, - } - - backend, mockService := newTestingBackend(t) - if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { - mockService.EXPECT(). - Reconciliation(gomock.Any(), testCase.policyID, testCase.req). - Return(testCase.res, nil) - } - if testCase.serviceError != nil { - mockService.EXPECT(). - Reconciliation(gomock.Any(), testCase.policyID, testCase.req). - Return(nil, testCase.serviceError) - } - - router := newRouter(backend, sharedapi.ServiceInfo{ - Debug: testing.Verbose(), - }, auth.NewNoAuth(), nil) - - var body []byte - if testCase.invalidBody { - body = []byte("invalid") - } else if testCase.req != nil { - var err error - body, err = json.Marshal(testCase.req) - require.NoError(t, err) - } - - req := httptest.NewRequest(http.MethodPost, fmt.Sprintf("/policies/%s/reconciliation", testCase.policyID), bytes.NewReader(body)) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectedStatusCode, rec.Code) - if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { - var resp sharedapi.BaseResponse[reconciliationResponse] - sharedapi.Decode(t, rec.Body, &resp) - require.Equal(t, expectedReconciliationResponse, resp.Data) - } else { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} - -func TestGetReconciliation(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - id uuid.UUID - serviceError error - expectedStatusCode int - expectedErrorCode string - } - - testCases := []testCase{ - { - name: "nominal", - id: uuid.New(), - }, - { - name: "service error validation", - id: uuid.New(), - serviceError: service.ErrValidation, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrValidation, - }, - { - name: "service error invalid id", - serviceError: service.ErrInvalidID, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrInvalidID, - }, - { - name: "storage error not found", - serviceError: storage.ErrNotFound, - expectedStatusCode: http.StatusNotFound, - expectedErrorCode: sharedapi.ErrorCodeNotFound, - }, - { - name: "service error other error", - id: uuid.New(), - serviceError: errors.New("some error"), - expectedStatusCode: http.StatusInternalServerError, - expectedErrorCode: sharedapi.ErrorInternal, - }, - } - - for _, tc := range testCases { - testCase := tc - t.Run(testCase.name, func(t *testing.T) { - t.Parallel() - - if testCase.expectedStatusCode == 0 { - testCase.expectedStatusCode = http.StatusOK - } - - getReconciliationResponse := &models.Reconciliation{ - ID: testCase.id, - PolicyID: uuid.New(), - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtLedger: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - ReconciledAtPayments: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Status: models.ReconciliationOK, - LedgerBalances: map[string]*big.Int{ - "USD/2": big.NewInt(100), - "EUR/2": big.NewInt(200), - }, - PaymentsBalances: map[string]*big.Int{ - "USD/2": big.NewInt(100), - "EUR/2": big.NewInt(200), - }, - Error: "", - } - - expectedReconciliationResponse := &reconciliationResponse{ - ID: getReconciliationResponse.ID.String(), - PolicyID: getReconciliationResponse.PolicyID.String(), - CreatedAt: getReconciliationResponse.CreatedAt, - ReconciledAtLedger: getReconciliationResponse.ReconciledAtLedger, - ReconciledAtPayments: getReconciliationResponse.ReconciledAtPayments, - Status: getReconciliationResponse.Status.String(), - PaymentsBalances: getReconciliationResponse.PaymentsBalances, - LedgerBalances: getReconciliationResponse.LedgerBalances, - Error: getReconciliationResponse.Error, - } - - backend, mockService := newTestingBackend(t) - if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { - mockService.EXPECT(). - GetReconciliation(gomock.Any(), testCase.id.String()). - Return(getReconciliationResponse, nil) - } - if testCase.serviceError != nil { - mockService.EXPECT(). - GetReconciliation(gomock.Any(), testCase.id.String()). - Return(nil, testCase.serviceError) - } - - router := newRouter(backend, sharedapi.ServiceInfo{ - Debug: testing.Verbose(), - }, auth.NewNoAuth(), nil) - - req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/reconciliations/%s", testCase.id.String()), nil) - rec := httptest.NewRecorder() - - router.ServeHTTP(rec, req) - - require.Equal(t, testCase.expectedStatusCode, rec.Code) - if testCase.expectedStatusCode < 300 && testCase.expectedStatusCode >= 200 { - var resp sharedapi.BaseResponse[reconciliationResponse] - sharedapi.Decode(t, rec.Body, &resp) - require.Equal(t, expectedReconciliationResponse, resp.Data) - } else { - err := sharedapi.ErrorResponse{} - sharedapi.Decode(t, rec.Body, &err) - require.EqualValues(t, testCase.expectedErrorCode, err.ErrorCode) - } - }) - } -} diff --git a/ee/reconciliation/internal/api/router.go b/ee/reconciliation/internal/api/router.go deleted file mode 100644 index bcd1832008..0000000000 --- a/ee/reconciliation/internal/api/router.go +++ /dev/null @@ -1,46 +0,0 @@ -package api - -import ( - "net/http" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/service" - - "github.com/formancehq/go-libs/api" - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/go-libs/health" - "github.com/formancehq/reconciliation/internal/api/backend" -) - -func newRouter( - b backend.Backend, - serviceInfo api.ServiceInfo, - authenticator auth.Authenticator, - healthController *health.HealthController) *chi.Mux { - r := chi.NewRouter() - r.Use(func(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - handler.ServeHTTP(w, r) - }) - }) - r.Get("/_healthcheck", healthController.Check) - r.Get("/_info", api.InfoHandler(serviceInfo)) - - r.Group(func(r chi.Router) { - r.Use(auth.Middleware(authenticator)) - r.Use(service.OTLPMiddleware("reconciliation", serviceInfo.Debug)) - - r.Get("/reconciliations/{reconciliationID}", getReconciliationHandler(b)) - r.Get("/reconciliations", listReconciliationsHandler(b)) - - r.Post("/policies", createPolicyHandler(b)) - r.Get("/policies", listPoliciesHandler(b)) - r.Delete("/policies/{policyID}", deletePolicyHandler(b)) - r.Get("/policies/{policyID}", getPolicyHandler(b)) - r.Post("/policies/{policyID}/reconciliation", reconciliationHandler(b)) - }) - - return r -} diff --git a/ee/reconciliation/internal/api/service/errors.go b/ee/reconciliation/internal/api/service/errors.go deleted file mode 100644 index e2e4779801..0000000000 --- a/ee/reconciliation/internal/api/service/errors.go +++ /dev/null @@ -1,39 +0,0 @@ -package service - -import ( - "errors" - "fmt" -) - -var ( - ErrValidation = errors.New("validation error") - ErrInvalidID = errors.New("invalid id") -) - -type storageError struct { - err error - msg string -} - -func (e *storageError) Error() string { - return fmt.Sprintf("%s: %s", e.msg, e.err) -} - -func (e *storageError) Is(err error) bool { - _, ok := err.(*storageError) - return ok -} - -func (e *storageError) Unwrap() error { - return e.err -} - -func newStorageError(err error, msg string) error { - if err == nil { - return nil - } - return &storageError{ - err: err, - msg: msg, - } -} diff --git a/ee/reconciliation/internal/api/service/policy.go b/ee/reconciliation/internal/api/service/policy.go deleted file mode 100644 index e8dc91027e..0000000000 --- a/ee/reconciliation/internal/api/service/policy.go +++ /dev/null @@ -1,87 +0,0 @@ -package service - -import ( - "context" - "time" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/formancehq/reconciliation/internal/models" - "github.com/formancehq/reconciliation/internal/storage" - "github.com/google/uuid" - "github.com/pkg/errors" -) - -type CreatePolicyRequest struct { - Name string `json:"name"` - LedgerName string `json:"ledgerName"` - LedgerQuery map[string]interface{} `json:"ledgerQuery"` - PaymentsPoolID string `json:"paymentsPoolID"` -} - -func (r *CreatePolicyRequest) Validate() error { - if r.Name == "" { - return errors.New("missing name") - } - - if r.LedgerName == "" { - return errors.New("missing ledgerName") - } - - if r.PaymentsPoolID == "" { - return errors.New("missing paymentsPoolId") - } - - return nil -} - -func (s *Service) CreatePolicy(ctx context.Context, req *CreatePolicyRequest) (*models.Policy, error) { - paymentPoolID, err := uuid.Parse(req.PaymentsPoolID) - if err != nil { - return nil, errors.Wrap(ErrInvalidID, err.Error()) - } - - policy := &models.Policy{ - ID: uuid.New(), - Name: req.Name, - CreatedAt: time.Now().UTC(), - LedgerName: req.LedgerName, - LedgerQuery: req.LedgerQuery, - PaymentsPoolID: paymentPoolID, - } - - err = s.store.CreatePolicy(ctx, policy) - if err != nil { - return nil, newStorageError(err, "creating policy") - } - - return policy, nil -} - -func (s *Service) DeletePolicy(ctx context.Context, id string) error { - pID, err := uuid.Parse(id) - if err != nil { - return errors.Wrap(ErrInvalidID, err.Error()) - } - - return newStorageError(s.store.DeletePolicy(ctx, pID), "deleting policy") -} - -func (s *Service) GetPolicy(ctx context.Context, id string) (*models.Policy, error) { - pID, err := uuid.Parse(id) - if err != nil { - return nil, errors.Wrap(ErrInvalidID, err.Error()) - } - - policy, err := s.store.GetPolicy(ctx, pID) - if err != nil { - return nil, newStorageError(err, "getting policy") - } - - return policy, nil -} - -func (s *Service) ListPolicies(ctx context.Context, q storage.GetPoliciesQuery) (*bunpaginate.Cursor[models.Policy], error) { - policies, err := s.store.ListPolicies(ctx, q) - return policies, newStorageError(err, "listing policies") -} diff --git a/ee/reconciliation/internal/api/service/reconciliation.go b/ee/reconciliation/internal/api/service/reconciliation.go deleted file mode 100644 index 3175b108b1..0000000000 --- a/ee/reconciliation/internal/api/service/reconciliation.go +++ /dev/null @@ -1,203 +0,0 @@ -package service - -import ( - "context" - "fmt" - "math/big" - "time" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/formancehq/reconciliation/internal/models" - "github.com/formancehq/reconciliation/internal/storage" - "github.com/google/uuid" - "github.com/pkg/errors" - "golang.org/x/sync/errgroup" -) - -type ReconciliationRequest struct { - ReconciledAtLedger time.Time `json:"reconciledAtLedger"` - ReconciledAtPayments time.Time `json:"reconciledAtPayments"` -} - -func (r *ReconciliationRequest) Validate() error { - if r.ReconciledAtLedger.IsZero() { - return errors.New("missing reconciledAtLedger") - } - - if r.ReconciledAtLedger.After(time.Now()) { - return errors.New("reconciledAtLedger must be in the past") - } - - if r.ReconciledAtPayments.IsZero() { - return errors.New("missing reconciledAtPayments") - } - - if r.ReconciledAtPayments.After(time.Now()) { - return errors.New("ReconciledAtPayments must be in the past") - } - - return nil -} - -func (s *Service) Reconciliation(ctx context.Context, policyID string, req *ReconciliationRequest) (*models.Reconciliation, error) { - id, err := uuid.Parse(policyID) - if err != nil { - return nil, errors.Wrap(ErrInvalidID, err.Error()) - } - - eg, ctxGroup := errgroup.WithContext(ctx) - policy, err := s.store.GetPolicy(ctx, id) - if err != nil { - return nil, newStorageError(err, "failed to get policy") - } - - var paymentsBalances map[string]*big.Int - eg.Go(func() error { - var err error - paymentsBalances, err = s.getPaymentPoolBalance(ctxGroup, policy.PaymentsPoolID.String(), req.ReconciledAtPayments) - return err - }) - - var ledgerBalances map[string]*big.Int - eg.Go(func() error { - var err error - ledgerBalances, err = s.getAccountsAggregatedBalance(ctxGroup, policy.LedgerName, policy.LedgerQuery, req.ReconciledAtLedger) - return err - }) - - if err := eg.Wait(); err != nil { - return nil, err - } - - ledgerBalances, paymentsBalances = harmonizeBalances(ledgerBalances, paymentsBalances) - - res := &models.Reconciliation{ - ID: uuid.New(), - PolicyID: policy.ID, - CreatedAt: time.Now().UTC(), - ReconciledAtLedger: req.ReconciledAtLedger, - ReconciledAtPayments: req.ReconciledAtPayments, - Status: models.ReconciliationOK, - PaymentsBalances: paymentsBalances, - LedgerBalances: ledgerBalances, - DriftBalances: make(map[string]*big.Int), - } - - var reconciliationError bool - if len(paymentsBalances) != len(ledgerBalances) { - res.Status = models.ReconciliationNotOK - res.Error = "different number of assets" - reconciliationError = true - return res, nil - } - - if !reconciliationError { - for asset, ledgerBalance := range ledgerBalances { - err := s.computeDrift(res, asset, ledgerBalance, paymentsBalances[asset]) - if err != nil { - res.Status = models.ReconciliationNotOK - if res.Error == "" { - res.Error = err.Error() - } else { - res.Error = res.Error + "; " + err.Error() - } - } - } - - for asset, paymentBalance := range paymentsBalances { - if _, ok := res.DriftBalances[asset]; ok { - // Already computed - continue - } - - err := s.computeDrift(res, asset, ledgerBalances[asset], paymentBalance) - if err != nil { - res.Status = models.ReconciliationNotOK - res.Error = res.Error + "; " + err.Error() - } - } - } - - if err := s.store.CreateReconciation(ctx, res); err != nil { - return nil, newStorageError(err, "failed to create reconciliation") - } - - return res, nil -} - -func (s *Service) computeDrift( - res *models.Reconciliation, - asset string, - ledgerBalance *big.Int, - paymentBalance *big.Int, -) error { - switch { - case ledgerBalance == nil && paymentBalance == nil: - // Not possible - return nil - case ledgerBalance == nil && paymentBalance != nil: - var balance big.Int - balance.Set(paymentBalance).Abs(&balance) - res.DriftBalances[asset] = &balance - return fmt.Errorf("missing asset %s in ledgerBalances", asset) - case ledgerBalance != nil && paymentBalance == nil: - var balance big.Int - balance.Set(ledgerBalance).Abs(&balance) - res.DriftBalances[asset] = &balance - res.DriftBalances[asset] = ledgerBalance - return fmt.Errorf("missing asset %s in paymentBalances", asset) - case ledgerBalance != nil && paymentBalance != nil: - var drift big.Int - drift.Set(paymentBalance).Add(&drift, ledgerBalance) - - var err error - switch drift.Cmp(big.NewInt(0)) { - case 0, 1: - default: - err = fmt.Errorf("balance drift for asset %s", asset) - } - - res.DriftBalances[asset] = drift.Abs(&drift) - return err - } - - return nil -} - -// Missing asset should be considered as asset with balance 0 -func harmonizeBalances(ledgerBalances, paymentsBalances map[string]*big.Int) (map[string]*big.Int, map[string]*big.Int) { - allAssets := make(map[string]struct{}) - for asset := range ledgerBalances { - allAssets[asset] = struct{}{} - } - for asset := range paymentsBalances { - allAssets[asset] = struct{}{} - } - - for asset := range allAssets { - if _, ok := ledgerBalances[asset]; !ok { - ledgerBalances[asset] = big.NewInt(0) - } - if _, ok := paymentsBalances[asset]; !ok { - paymentsBalances[asset] = big.NewInt(0) - } - } - - return ledgerBalances, paymentsBalances -} - -func (s *Service) GetReconciliation(ctx context.Context, id string) (*models.Reconciliation, error) { - rID, err := uuid.Parse(id) - if err != nil { - return nil, errors.Wrap(ErrInvalidID, err.Error()) - } - - reco, err := s.store.GetReconciliation(ctx, rID) - return reco, newStorageError(err, "getting reconciliation") -} - -func (s *Service) ListReconciliations(ctx context.Context, q storage.GetReconciliationsQuery) (*bunpaginate.Cursor[models.Reconciliation], error) { - reconciliations, err := s.store.ListReconciliations(ctx, q) - return reconciliations, newStorageError(err, "listing reconciliations") -} diff --git a/ee/reconciliation/internal/api/service/reconciliation_test.go b/ee/reconciliation/internal/api/service/reconciliation_test.go deleted file mode 100644 index 68a7e7eca4..0000000000 --- a/ee/reconciliation/internal/api/service/reconciliation_test.go +++ /dev/null @@ -1,281 +0,0 @@ -package service - -import ( - "context" - "math/big" - "testing" - "time" - - "github.com/formancehq/reconciliation/internal/models" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestReconciliation(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - ledgerVersion string - paymentsVersion string - ledgerBalances map[string]*big.Int - paymentsBalances map[string]*big.Int - expectedReco *models.Reconciliation - expectedError bool - } - - testCases := []testCase{ - { - name: "nominal with drift = 0", - ledgerVersion: "v2.0.0-beta.1", - paymentsVersion: "v1.0.0-rc.4", - ledgerBalances: map[string]*big.Int{ - "USD": big.NewInt(100), - "EUR": big.NewInt(200), - }, - paymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "EUR": big.NewInt(-200), - }, - expectedReco: &models.Reconciliation{ - ReconciledAtLedger: time.Time{}, - ReconciledAtPayments: time.Time{}, - Status: models.ReconciliationOK, - LedgerBalances: map[string]*big.Int{ - "USD": big.NewInt(100), - "EUR": big.NewInt(200), - }, - PaymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "EUR": big.NewInt(-200), - }, - DriftBalances: map[string]*big.Int{ - "USD": big.NewInt(0), - "EUR": big.NewInt(0), - }, - Error: "", - }, - }, - { - name: "nominal with drift >= 0", - ledgerVersion: "v2.0.0-beta.1", - paymentsVersion: "v1.0.0-rc.4", - ledgerBalances: map[string]*big.Int{ - "USD": big.NewInt(200), - "EUR": big.NewInt(300), - }, - paymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "EUR": big.NewInt(-200), - }, - expectedReco: &models.Reconciliation{ - ReconciledAtLedger: time.Time{}, - ReconciledAtPayments: time.Time{}, - Status: models.ReconciliationOK, - LedgerBalances: map[string]*big.Int{ - "USD": big.NewInt(200), - "EUR": big.NewInt(300), - }, - PaymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "EUR": big.NewInt(-200), - }, - DriftBalances: map[string]*big.Int{ - "USD": big.NewInt(100), - "EUR": big.NewInt(100), - }, - Error: "", - }, - }, - { - name: "nominal with drift < 0", - ledgerVersion: "v2.0.0-beta.1", - paymentsVersion: "v1.0.0-rc.4", - ledgerBalances: map[string]*big.Int{ - "USD": big.NewInt(100), - "EUR": big.NewInt(200), - }, - paymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "EUR": big.NewInt(-400), - }, - expectedReco: &models.Reconciliation{ - ReconciledAtLedger: time.Time{}, - ReconciledAtPayments: time.Time{}, - Status: models.ReconciliationNotOK, - LedgerBalances: map[string]*big.Int{ - "USD": big.NewInt(100), - "EUR": big.NewInt(200), - }, - PaymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "EUR": big.NewInt(-400), - }, - DriftBalances: map[string]*big.Int{ - "USD": big.NewInt(0), - "EUR": big.NewInt(200), - }, - Error: "balance drift for asset EUR", - }, - }, - { - name: "different length, no drift", - ledgerVersion: "v2.0.0-beta.1", - paymentsVersion: "v1.0.0-rc.4", - ledgerBalances: map[string]*big.Int{ - "EUR": big.NewInt(200), - }, - paymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "EUR": big.NewInt(-200), - }, - expectedReco: &models.Reconciliation{ - ReconciledAtLedger: time.Time{}, - ReconciledAtPayments: time.Time{}, - Status: models.ReconciliationNotOK, - LedgerBalances: map[string]*big.Int{ - "USD": big.NewInt(0), - "EUR": big.NewInt(200), - }, - PaymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "EUR": big.NewInt(-200), - }, - DriftBalances: map[string]*big.Int{ - "EUR": big.NewInt(0), - "USD": big.NewInt(100), - }, - Error: "balance drift for asset USD", - }, - }, - { - name: "same length, different asset and no drift", - ledgerVersion: "v2.0.0-beta.1", - paymentsVersion: "v1.0.0-rc.4", - ledgerBalances: map[string]*big.Int{ - "USD": big.NewInt(100), - "EUR": big.NewInt(200), - }, - paymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "DKK": big.NewInt(-200), - }, - expectedReco: &models.Reconciliation{ - ReconciledAtLedger: time.Time{}, - ReconciledAtPayments: time.Time{}, - Status: models.ReconciliationNotOK, - LedgerBalances: map[string]*big.Int{ - "USD": big.NewInt(100), - "EUR": big.NewInt(200), - "DKK": big.NewInt(0), - }, - PaymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "DKK": big.NewInt(-200), - "EUR": big.NewInt(0), - }, - DriftBalances: map[string]*big.Int{ - "USD": big.NewInt(0), - "EUR": big.NewInt(200), - "DKK": big.NewInt(200), - }, - Error: "balance drift for asset DKK", - }, - }, - { - name: "missing payments balance with ledger balance at 0", - ledgerVersion: "v2.0.0-beta.1", - paymentsVersion: "v1.0.0-rc.4", - ledgerBalances: map[string]*big.Int{ - "USD": big.NewInt(100), - "EUR": big.NewInt(0), - }, - paymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - }, - expectedReco: &models.Reconciliation{ - ReconciledAtLedger: time.Time{}, - ReconciledAtPayments: time.Time{}, - Status: models.ReconciliationOK, - LedgerBalances: map[string]*big.Int{ - "USD": big.NewInt(100), - "EUR": big.NewInt(0), - }, - PaymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "EUR": big.NewInt(0), - }, - DriftBalances: map[string]*big.Int{ - "USD": big.NewInt(0), - "EUR": big.NewInt(0), - }, - Error: "", - }, - }, - { - name: "missing ledger balance with payments balance at 0", - ledgerVersion: "v2.0.0-beta.1", - paymentsVersion: "v1.0.0-rc.4", - ledgerBalances: map[string]*big.Int{ - "USD": big.NewInt(100), - }, - paymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "EUR": big.NewInt(0), - }, - expectedReco: &models.Reconciliation{ - ReconciledAtLedger: time.Time{}, - ReconciledAtPayments: time.Time{}, - Status: models.ReconciliationOK, - LedgerBalances: map[string]*big.Int{ - "USD": big.NewInt(100), - "EUR": big.NewInt(0), - }, - PaymentsBalances: map[string]*big.Int{ - "USD": big.NewInt(-100), - "EUR": big.NewInt(0), - }, - DriftBalances: map[string]*big.Int{ - "USD": big.NewInt(0), - "EUR": big.NewInt(0), - }, - Error: "", - }, - }, - } - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - - s := NewService(newMockStore(), newMockSDKFormanceClient( - tc.ledgerVersion, - tc.ledgerBalances, - tc.paymentsVersion, - tc.paymentsBalances, - )) - - reco, err := s.Reconciliation(context.Background(), uuid.New().String(), &ReconciliationRequest{}) - if tc.expectedError { - require.Error(t, err) - return - } else { - require.NoError(t, err) - } - - require.Equal(t, tc.expectedReco.Status, reco.Status) - compareBalancesMap(t, tc.expectedReco.LedgerBalances, reco.LedgerBalances) - compareBalancesMap(t, tc.expectedReco.PaymentsBalances, reco.PaymentsBalances) - compareBalancesMap(t, tc.expectedReco.DriftBalances, reco.DriftBalances) - require.Equal(t, tc.expectedReco.Error, reco.Error) - }) - } -} - -func compareBalancesMap(t *testing.T, expected, actual map[string]*big.Int) { - require.Equal(t, len(expected), len(actual)) - for k, v := range expected { - require.Equal(t, v.Cmp(actual[k]), 0) - } -} diff --git a/ee/reconciliation/internal/api/service/service.go b/ee/reconciliation/internal/api/service/service.go deleted file mode 100644 index 0f52588c47..0000000000 --- a/ee/reconciliation/internal/api/service/service.go +++ /dev/null @@ -1,72 +0,0 @@ -package service - -import ( - "context" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - sdk "github.com/formancehq/formance-sdk-go/v2" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/reconciliation/internal/models" - "github.com/formancehq/reconciliation/internal/storage" - "github.com/google/uuid" -) - -type Store interface { - Ping() error - CreatePolicy(ctx context.Context, policy *models.Policy) error - DeletePolicy(ctx context.Context, id uuid.UUID) error - GetPolicy(ctx context.Context, id uuid.UUID) (*models.Policy, error) - ListPolicies(ctx context.Context, q storage.GetPoliciesQuery) (*bunpaginate.Cursor[models.Policy], error) - - CreateReconciation(ctx context.Context, reco *models.Reconciliation) error - GetReconciliation(ctx context.Context, id uuid.UUID) (*models.Reconciliation, error) - ListReconciliations(ctx context.Context, q storage.GetReconciliationsQuery) (*bunpaginate.Cursor[models.Reconciliation], error) -} - -type Service struct { - store Store - client SDKFormance -} - -func NewService(store Store, client SDKFormance) *Service { - return &Service{ - store: store, - client: client, - } -} - -type SDKFormance interface { - PaymentsgetServerInfo(ctx context.Context) (*operations.PaymentsgetServerInfoResponse, error) - GetPoolBalances(ctx context.Context, req operations.GetPoolBalancesRequest) (*operations.GetPoolBalancesResponse, error) - V2GetInfo(ctx context.Context) (*operations.V2GetInfoResponse, error) - V2GetBalancesAggregated(ctx context.Context, req operations.V2GetBalancesAggregatedRequest) (*operations.V2GetBalancesAggregatedResponse, error) -} - -type sdkFormanceClient struct { - client *sdk.Formance -} - -func NewSDKFormance(client *sdk.Formance) *sdkFormanceClient { - return &sdkFormanceClient{ - client: client, - } -} - -func (s *sdkFormanceClient) PaymentsgetServerInfo(ctx context.Context) (*operations.PaymentsgetServerInfoResponse, error) { - return s.client.Payments.V1.PaymentsgetServerInfo(ctx) -} - -func (s *sdkFormanceClient) GetPoolBalances(ctx context.Context, req operations.GetPoolBalancesRequest) (*operations.GetPoolBalancesResponse, error) { - return s.client.Payments.V1.GetPoolBalances(ctx, req) -} - -func (s *sdkFormanceClient) V2GetInfo(ctx context.Context) (*operations.V2GetInfoResponse, error) { - return s.client.Ledger.V2.GetInfo(ctx) -} - -func (s *sdkFormanceClient) V2GetBalancesAggregated(ctx context.Context, req operations.V2GetBalancesAggregatedRequest) (*operations.V2GetBalancesAggregatedResponse, error) { - return s.client.Ledger.V2.GetBalancesAggregated(ctx, req) -} - -var _ SDKFormance = (*sdkFormanceClient)(nil) diff --git a/ee/reconciliation/internal/api/service/service_test.go b/ee/reconciliation/internal/api/service/service_test.go deleted file mode 100644 index d2defdf07f..0000000000 --- a/ee/reconciliation/internal/api/service/service_test.go +++ /dev/null @@ -1,136 +0,0 @@ -package service - -import ( - "context" - "math/big" - "net/http" - "time" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "github.com/formancehq/reconciliation/internal/models" - "github.com/formancehq/reconciliation/internal/storage" - "github.com/google/uuid" -) - -type mockSDKFormanceClient struct { - ledgerVersion string - ledgerBalances map[string]*big.Int - paymentsVersion string - paymentsBalances map[string]*big.Int -} - -func newMockSDKFormanceClient( - ledgerVersion string, - ledgerBalances map[string]*big.Int, - paymentsVersion string, - paymentsBalances map[string]*big.Int, -) *mockSDKFormanceClient { - return &mockSDKFormanceClient{ - ledgerVersion: ledgerVersion, - ledgerBalances: ledgerBalances, - paymentsVersion: paymentsVersion, - paymentsBalances: paymentsBalances, - } -} - -func (s *mockSDKFormanceClient) PaymentsgetServerInfo(ctx context.Context) (*operations.PaymentsgetServerInfoResponse, error) { - return &operations.PaymentsgetServerInfoResponse{ - ServerInfo: &shared.ServerInfo{ - Version: s.paymentsVersion, - }, - StatusCode: http.StatusOK, - }, nil -} - -func (s *mockSDKFormanceClient) GetPoolBalances(ctx context.Context, req operations.GetPoolBalancesRequest) (*operations.GetPoolBalancesResponse, error) { - poolBalances := make([]shared.PoolBalance, 0, len(s.paymentsBalances)) - for assetCode, balance := range s.paymentsBalances { - poolBalances = append(poolBalances, shared.PoolBalance{ - Amount: balance, - Asset: assetCode, - }) - } - - return &operations.GetPoolBalancesResponse{ - PoolBalancesResponse: &shared.PoolBalancesResponse{ - Data: shared.PoolBalances{ - Balances: poolBalances, - }, - }, - StatusCode: http.StatusOK, - }, nil -} - -func (s *mockSDKFormanceClient) V2GetInfo(ctx context.Context) (*operations.V2GetInfoResponse, error) { - return &operations.V2GetInfoResponse{ - StatusCode: http.StatusOK, - V2ConfigInfoResponse: &shared.V2ConfigInfoResponse{ - Version: s.ledgerVersion, - }, - }, nil -} - -func (s *mockSDKFormanceClient) V2GetBalancesAggregated(ctx context.Context, req operations.V2GetBalancesAggregatedRequest) (*operations.V2GetBalancesAggregatedResponse, error) { - balances := make(map[string]*big.Int) - for assetCode, balance := range s.ledgerBalances { - balances[assetCode] = balance - } - - return &operations.V2GetBalancesAggregatedResponse{ - StatusCode: http.StatusOK, - V2AggregateBalancesResponse: &shared.V2AggregateBalancesResponse{ - Data: balances, - }, - }, nil -} - -type mockStore struct { -} - -func newMockStore() *mockStore { - return &mockStore{} -} - -func (s *mockStore) Ping() error { - return nil -} - -func (s *mockStore) CreatePolicy(ctx context.Context, policy *models.Policy) error { - return nil -} - -func (s *mockStore) DeletePolicy(ctx context.Context, id uuid.UUID) error { - return nil -} - -func (s *mockStore) GetPolicy(ctx context.Context, id uuid.UUID) (*models.Policy, error) { - return &models.Policy{ - ID: id, - CreatedAt: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), - Name: "test", - LedgerName: "default", - LedgerQuery: map[string]interface{}{}, - PaymentsPoolID: uuid.New(), - }, nil -} - -func (s *mockStore) ListPolicies(ctx context.Context, q storage.GetPoliciesQuery) (*bunpaginate.Cursor[models.Policy], error) { - return nil, nil -} - -func (s *mockStore) CreateReconciation(ctx context.Context, reco *models.Reconciliation) error { - return nil -} - -func (s *mockStore) GetReconciliation(ctx context.Context, id uuid.UUID) (*models.Reconciliation, error) { - return nil, nil -} - -func (s *mockStore) ListReconciliations(ctx context.Context, q storage.GetReconciliationsQuery) (*bunpaginate.Cursor[models.Reconciliation], error) { - return nil, nil -} - -var _ Store = (*mockStore)(nil) diff --git a/ee/reconciliation/internal/api/service/utils.go b/ee/reconciliation/internal/api/service/utils.go deleted file mode 100644 index 6676b3ae91..0000000000 --- a/ee/reconciliation/internal/api/service/utils.go +++ /dev/null @@ -1,117 +0,0 @@ -package service - -import ( - "context" - "errors" - "math/big" - "time" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "golang.org/x/mod/semver" -) - -type Version interface { - GetVersion() string -} - -func isVersionSupported( - version Version, - minSupportedVersion string, -) bool { - v := "v" + version.GetVersion() - if !semver.IsValid(v) { - // If semver is not valid, we assume it's a commit hash, so last version - return true - } - - switch semver.Compare(v, minSupportedVersion) { - case 0, 1: - // Higher or equal, nothing to do - return true - default: - return false - } -} - -func (s *Service) getAccountsAggregatedBalance(ctx context.Context, ledgerName string, ledgerAggregatedBalanceQuery map[string]interface{}, at time.Time) (map[string]*big.Int, error) { - infoResponse, err := s.client.V2GetInfo(ctx) - if err != nil { - return nil, err - } - - if infoResponse.StatusCode != 200 { - return nil, errors.New("failed to get ledger info") - } - - if !isVersionSupported(infoResponse.V2ConfigInfoResponse, "v2.0.0-beta.1") { - return nil, errors.New("ledger version not supported") - } - - balances, err := s.client.V2GetBalancesAggregated( - ctx, - operations.V2GetBalancesAggregatedRequest{ - RequestBody: ledgerAggregatedBalanceQuery, - Ledger: ledgerName, - Pit: &at, - }, - ) - if err != nil { - return nil, err - } - - if balances.StatusCode != 200 { - return nil, errors.New("failed to get aggregated balances") - } - - if balances.V2AggregateBalancesResponse == nil { - return nil, errors.New("no aggregated balance") - } - - balanceMap := make(map[string]*big.Int) - for asset, balance := range balances.V2AggregateBalancesResponse.Data { - balanceMap[asset] = balance - } - - return balanceMap, nil -} - -func (s *Service) getPaymentPoolBalance(ctx context.Context, paymentPoolID string, at time.Time) (map[string]*big.Int, error) { - response, err := s.client.PaymentsgetServerInfo(ctx) - if err != nil { - return nil, err - } - - if response.StatusCode != 200 { - return nil, errors.New("failed to get payments info") - } - - if !isVersionSupported(response.ServerInfo, "v1.0.0-rc.4") { - return nil, errors.New("payments version not supported") - } - - balances, err := s.client.GetPoolBalances( - ctx, - operations.GetPoolBalancesRequest{ - At: at, - PoolID: paymentPoolID, - }, - ) - if err != nil { - return nil, err - } - - if balances.StatusCode != 200 { - return nil, errors.New("failed to get pool balances") - } - - if balances.PoolBalancesResponse == nil { - return nil, errors.New("no pool balance") - } - - balanceMap := make(map[string]*big.Int) - for _, balance := range balances.PoolBalancesResponse.Data.Balances { - balanceMap[balance.GetAsset()] = balance.GetAmount() - } - - return balanceMap, nil -} diff --git a/ee/reconciliation/internal/api/service/utils_test.go b/ee/reconciliation/internal/api/service/utils_test.go deleted file mode 100644 index de5613c247..0000000000 --- a/ee/reconciliation/internal/api/service/utils_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package service - -import "testing" - -type testVersion struct { - version string -} - -func (v testVersion) GetVersion() string { - return v.version -} - -func TestIsVersionSupported(t *testing.T) { - t.Parallel() - - type testCase struct { - name string - version string - minSupportedVersion string - expectedResult bool - } - - testCases := []testCase{ - { - name: "commit hash", - version: "1234567890abcdef", - minSupportedVersion: "v1.0.0", - expectedResult: true, - }, - { - name: "higher version", - version: "1.0.1", - minSupportedVersion: "v1.0.0", - expectedResult: true, - }, - { - name: "equal version", - version: "1.0.0", - minSupportedVersion: "v1.0.0", - expectedResult: true, - }, - { - name: "lower version", - version: "0.9.0", - minSupportedVersion: "v1.0.0", - expectedResult: false, - }, - { - name: "versions with beta", - version: "2.0.0-beta.2", - minSupportedVersion: "v2.0.0-beta.1", - expectedResult: true, - }, - } - - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - - v := testVersion{version: tc.version} - result := isVersionSupported(v, tc.minSupportedVersion) - if result != tc.expectedResult { - t.Errorf("expected result %v, got %v", tc.expectedResult, result) - } - }) - } -} diff --git a/ee/reconciliation/internal/api/utils.go b/ee/reconciliation/internal/api/utils.go deleted file mode 100644 index 3ea4b12fb5..0000000000 --- a/ee/reconciliation/internal/api/utils.go +++ /dev/null @@ -1,56 +0,0 @@ -package api - -import ( - "io" - "net/http" - - "github.com/formancehq/go-libs/pointer" - "github.com/formancehq/go-libs/query" - "github.com/formancehq/reconciliation/internal/storage" -) - -func getQueryBuilder(r *http.Request) (query.Builder, error) { - data, err := io.ReadAll(r.Body) - if err != nil { - return nil, err - } - - if len(data) > 0 { - return query.ParseJSON(string(data)) - } - return nil, nil -} - -func getPaginatedQueryOptionsReconciliations(r *http.Request) (*storage.PaginatedQueryOptions[storage.ReconciliationsFilters], error) { - qb, err := getQueryBuilder(r) - if err != nil { - return nil, err - } - - pageSize, err := getPageSize(r) - if err != nil { - return nil, err - } - - filters := storage.ReconciliationsFilters{} - return pointer.For(storage.NewPaginatedQueryOptions(filters). - WithQueryBuilder(qb). - WithPageSize(pageSize)), nil -} - -func getPaginatedQueryOptionsPolicies(r *http.Request) (*storage.PaginatedQueryOptions[storage.PoliciesFilters], error) { - qb, err := getQueryBuilder(r) - if err != nil { - return nil, err - } - - pageSize, err := getPageSize(r) - if err != nil { - return nil, err - } - - filters := storage.PoliciesFilters{} - return pointer.For(storage.NewPaginatedQueryOptions(filters). - WithQueryBuilder(qb). - WithPageSize(pageSize)), nil -} diff --git a/ee/reconciliation/internal/models/policy.go b/ee/reconciliation/internal/models/policy.go deleted file mode 100644 index 44ad2f521f..0000000000 --- a/ee/reconciliation/internal/models/policy.go +++ /dev/null @@ -1,22 +0,0 @@ -package models - -import ( - "time" - - "github.com/google/uuid" - "github.com/uptrace/bun" -) - -type Policy struct { - bun.BaseModel `bun:"reconciliations.policy" json:"-"` - - // Policy Related fields - ID uuid.UUID `bun:",pk,nullzero" json:"id"` - CreatedAt time.Time `bun:",notnull" json:"createdAt"` - Name string `bun:",notnull" json:"name"` - - // Reconciliation Needed fields - LedgerName string `bun:",notnull" json:"ledgerName"` - LedgerQuery map[string]interface{} `bun:",type:jsonb,notnull" json:"ledgerQuery"` - PaymentsPoolID uuid.UUID `bun:",notnull" json:"paymentsPoolID"` -} diff --git a/ee/reconciliation/internal/models/reconciliation.go b/ee/reconciliation/internal/models/reconciliation.go deleted file mode 100644 index 2fc7d6f877..0000000000 --- a/ee/reconciliation/internal/models/reconciliation.go +++ /dev/null @@ -1,35 +0,0 @@ -package models - -import ( - "math/big" - "time" - - "github.com/google/uuid" - "github.com/uptrace/bun" -) - -type ReconciliationStatus string - -var ( - ReconciliationNotOK ReconciliationStatus = "NOT_OK" - ReconciliationOK ReconciliationStatus = "OK" -) - -func (r ReconciliationStatus) String() string { - return string(r) -} - -type Reconciliation struct { - bun.BaseModel `bun:"reconciliations.reconciliation" json:"-"` - - ID uuid.UUID `bun:",pk,nullzero" json:"id"` - PolicyID uuid.UUID `bun:",nullzero" json:"policyID"` - CreatedAt time.Time `bun:",nullzero" json:"createdAt"` - ReconciledAtLedger time.Time `bun:",nullzero" json:"reconciledAtLedger"` - ReconciledAtPayments time.Time `bun:",nullzero" json:"reconciledAtPayments"` - Status ReconciliationStatus `json:"status"` - LedgerBalances map[string]*big.Int `bun:",jsonb" json:"ledgerBalances"` - PaymentsBalances map[string]*big.Int `bun:",jsonb" json:"paymentsBalances"` - DriftBalances map[string]*big.Int `bun:",jsonb" json:"driftBalances"` - Error string `json:"error"` -} diff --git a/ee/reconciliation/internal/storage/error.go b/ee/reconciliation/internal/storage/error.go deleted file mode 100644 index 429d8e5f75..0000000000 --- a/ee/reconciliation/internal/storage/error.go +++ /dev/null @@ -1,30 +0,0 @@ -package storage - -import ( - "database/sql" - "errors" - "fmt" - - "github.com/jackc/pgconn" -) - -var ErrNotFound = errors.New("not found") -var ErrDuplicateKeyValue = errors.New("duplicate key value") -var ErrInvalidQuery = errors.New("invalid query") - -func e(msg string, err error) error { - if err == nil { - return nil - } - - var pgErr *pgconn.PgError - if errors.As(err, &pgErr) && pgErr.Code == "23505" { - return ErrDuplicateKeyValue - } - - if errors.Is(err, sql.ErrNoRows) { - return ErrNotFound - } - - return fmt.Errorf("%s: %w", msg, err) -} diff --git a/ee/reconciliation/internal/storage/migrations/migrations.go b/ee/reconciliation/internal/storage/migrations/migrations.go deleted file mode 100644 index 948fe56565..0000000000 --- a/ee/reconciliation/internal/storage/migrations/migrations.go +++ /dev/null @@ -1,76 +0,0 @@ -package migrations - -import ( - "context" - - "github.com/formancehq/go-libs/migrations" - "github.com/uptrace/bun" -) - -func Migrate(ctx context.Context, db *bun.DB) error { - migrator := migrations.NewMigrator() - registerMigrations(migrator) - - return migrator.Up(ctx, db) -} - -func registerMigrations(migrator *migrations.Migrator) { - migrator.RegisterMigrations( - migrations.Migration{ - Up: func(tx bun.Tx) error { - _, err := tx.Exec(` - CREATE SCHEMA IF NOT EXISTS reconciliations; - - CREATE TABLE IF NOT EXISTS reconciliations.policy ( - id uuid NOT NULL, - created_at timestamp with time zone NOT NULL, - name text NOT NULL, - ledger_name text NOT NULL, - ledger_query jsonb NOT NULL, - payments_pool_id uuid NOT NULL, - CONSTRAINT policy_pk PRIMARY KEY (id) - ); - - CREATE TABLE IF NOT EXISTS reconciliations.reconciliation ( - id uuid NOT NULL, - policy_id uuid NOT NULL, - created_at timestamp with time zone NOT NULL UNIQUE, - reconciled_at timestamp with time zone, - status text NOT NULL, - ledger_balances jsonb NOT NULL, - payments_balances jsonb NOT NULL, - error text, - CONSTRAINT reconciliation_pk PRIMARY KEY (id) - ); - - ALTER TABLE reconciliations.reconciliation DROP CONSTRAINT IF EXISTS reconciliation_policy_fk; - ALTER TABLE reconciliations.reconciliation ADD CONSTRAINT reconciliation_policy_fk - FOREIGN KEY (policy_id) - REFERENCES reconciliations.policy (id) - ON DELETE CASCADE - NOT DEFERRABLE - INITIALLY IMMEDIATE - ; - `) - return err - }, - }, - migrations.Migration{ - Up: func(tx bun.Tx) error { - _, err := tx.Exec(` - ALTER TABLE reconciliations.reconciliation RENAME COLUMN reconciled_at TO reconciled_at_ledger; - ALTER TABLE reconciliations.reconciliation ADD COLUMN reconciled_at_payments timestamp with time zone; - `) - return err - }, - }, - migrations.Migration{ - Up: func(tx bun.Tx) error { - _, err := tx.Exec(` - ALTER TABLE reconciliations.reconciliation ADD COLUMN drift_balances jsonb; - `) - return err - }, - }, - ) -} diff --git a/ee/reconciliation/internal/storage/module.go b/ee/reconciliation/internal/storage/module.go deleted file mode 100644 index a6b93fce88..0000000000 --- a/ee/reconciliation/internal/storage/module.go +++ /dev/null @@ -1,33 +0,0 @@ -package storage - -import ( - "context" - - "github.com/formancehq/go-libs/bun/bunconnect" - "github.com/formancehq/go-libs/logging" - "github.com/uptrace/bun" - "go.uber.org/fx" -) - -func Module(connectionOptions bunconnect.ConnectionOptions, debug bool) fx.Option { - return fx.Options( - fx.Provide(func() *bunconnect.ConnectionOptions { - return &connectionOptions - }), - bunconnect.Module(connectionOptions, debug), - fx.Provide(func(db *bun.DB) *Storage { - return NewStorage(db) - }), - fx.Invoke(func(lc fx.Lifecycle, repo *Storage) { - lc.Append(fx.Hook{ - OnStart: func(ctx context.Context) error { - logging.FromContext(ctx).Debug("Ping database...") - - // TODO: Check migrations state and panic if migrations are not applied - - return nil - }, - }) - }), - ) -} diff --git a/ee/reconciliation/internal/storage/ping.go b/ee/reconciliation/internal/storage/ping.go deleted file mode 100644 index 2832abb0b1..0000000000 --- a/ee/reconciliation/internal/storage/ping.go +++ /dev/null @@ -1,5 +0,0 @@ -package storage - -func (s *Storage) Ping() error { - return s.db.Ping() -} diff --git a/ee/reconciliation/internal/storage/policy.go b/ee/reconciliation/internal/storage/policy.go deleted file mode 100644 index 81b8fd70b0..0000000000 --- a/ee/reconciliation/internal/storage/policy.go +++ /dev/null @@ -1,133 +0,0 @@ -package storage - -import ( - "context" - - "github.com/formancehq/go-libs/bun/bunpaginate" - "github.com/formancehq/go-libs/query" - "github.com/formancehq/reconciliation/internal/models" - "github.com/google/uuid" - "github.com/pkg/errors" - "github.com/uptrace/bun" -) - -func (s *Storage) CreatePolicy(ctx context.Context, policy *models.Policy) error { - _, err := s.db.NewInsert(). - Model(policy). - Exec(ctx) - if err != nil { - return e("failed to create policy", err) - } - - return nil -} - -func (s *Storage) DeletePolicy(ctx context.Context, id uuid.UUID) error { - _, err := s.db.NewDelete(). - Model(&models.Policy{}). - Where("id = ?", id). - Exec(ctx) - if err != nil { - return e("failed to delete policy", err) - } - - return nil -} - -func (s *Storage) GetPolicy(ctx context.Context, id uuid.UUID) (*models.Policy, error) { - var policy models.Policy - err := s.db.NewSelect(). - Model(&policy). - Where("id = ?", id). - Scan(ctx) - if err != nil { - return nil, e("failed to get policy", err) - } - - return &policy, nil -} - -func (s *Storage) buildPolicyListQuery(selectQuery *bun.SelectQuery, q GetPoliciesQuery, where string, args []any) *bun.SelectQuery { - selectQuery = selectQuery. - Order("created_at DESC") - - if where != "" { - return selectQuery.Where(where, args...) - } - - return selectQuery -} - -// TODO(polo): add pagination from go libs -func (s *Storage) ListPolicies(ctx context.Context, q GetPoliciesQuery) (*bunpaginate.Cursor[models.Policy], error) { - var ( - where string - args []any - err error - ) - - if q.Options.QueryBuilder != nil { - where, args, err = s.policyQueryContext(q.Options.QueryBuilder, q) - if err != nil { - return nil, err - } - } - - return paginateWithOffset[PaginatedQueryOptions[PoliciesFilters], models.Policy](s, ctx, - (*bunpaginate.OffsetPaginatedQuery[PaginatedQueryOptions[PoliciesFilters]])(&q), - func(query *bun.SelectQuery) *bun.SelectQuery { - return s.buildPolicyListQuery(query, q, where, args) - }, - ) -} - -func (s *Storage) policyQueryContext(qb query.Builder, q GetPoliciesQuery) (string, []any, error) { - return qb.Build(query.ContextFn(func(key, operator string, value any) (string, []any, error) { - switch { - case key == "ledgerQuery": - if operator != "$match" { - return "", nil, errors.Wrap(ErrInvalidQuery, "'ledgerQuery' column can only be used with $match") - } - switch ledgerQuery := value.(type) { - case string: - return "ledger_query = ?", []any{ledgerQuery}, nil - default: - return "", nil, errors.Wrap(ErrInvalidQuery, "'ledgerQuery' column can only be used with string") - } - case key == "ledgerName": - if operator != "$match" { - return "", nil, errors.Wrap(ErrInvalidQuery, "'ledgerName' column can only be used with $match") - } - switch name := value.(type) { - case string: - return "ledger_name = ?", []any{name}, nil - default: - return "", nil, errors.Wrap(ErrInvalidQuery, "'ledgerName' column can only be used with string") - } - case key == "paymentsPoolID": - if operator != "$match" { - return "", nil, errors.Wrap(ErrInvalidQuery, "'paymentsPoolID' column can only be used with $match") - } - switch pID := value.(type) { - case string: - return "payments_pool_id = ?", []any{pID}, nil - default: - return "", nil, errors.Wrap(ErrInvalidQuery, "'paymentsPoolID' column can only be used with string") - } - default: - return "", nil, errors.Wrapf(ErrInvalidQuery, "unknown key '%s' when building query", key) - } - })) -} - -type PoliciesFilters struct{} - -type GetPoliciesQuery bunpaginate.OffsetPaginatedQuery[PaginatedQueryOptions[PoliciesFilters]] - -func NewGetPoliciesQuery(opts PaginatedQueryOptions[PoliciesFilters]) GetPoliciesQuery { - return GetPoliciesQuery{ - PageSize: opts.PageSize, - Order: bunpaginate.OrderAsc, - Options: opts, - } -} diff --git a/ee/reconciliation/internal/storage/reconciliations.go b/ee/reconciliation/internal/storage/reconciliations.go deleted file mode 100644 index dcbd50b1fd..0000000000 --- a/ee/reconciliation/internal/storage/reconciliations.go +++ /dev/null @@ -1,100 +0,0 @@ -package storage - -import ( - "context" - - "github.com/formancehq/go-libs/bun/bunpaginate" - "github.com/formancehq/go-libs/query" - "github.com/formancehq/reconciliation/internal/models" - "github.com/google/uuid" - "github.com/pkg/errors" - "github.com/uptrace/bun" -) - -func (s *Storage) CreateReconciation(ctx context.Context, reco *models.Reconciliation) error { - _, err := s.db.NewInsert(). - Model(reco). - Exec(ctx) - if err != nil { - return e("failed to create reconciliation", err) - } - - return nil -} - -func (s *Storage) GetReconciliation(ctx context.Context, id uuid.UUID) (*models.Reconciliation, error) { - var reco models.Reconciliation - err := s.db.NewSelect(). - Model(&reco). - Where("id = ?", id). - Scan(ctx) - if err != nil { - return nil, e("failed to get reconciliation", err) - } - - return &reco, nil -} - -func (s *Storage) buildReconciliationListQuery(selectQuery *bun.SelectQuery, q GetReconciliationsQuery, where string, args []any) *bun.SelectQuery { - selectQuery = selectQuery. - Order("created_at DESC") - - if where != "" { - return selectQuery.Where(where, args...) - } - - return selectQuery -} - -func (s *Storage) ListReconciliations(ctx context.Context, q GetReconciliationsQuery) (*bunpaginate.Cursor[models.Reconciliation], error) { - var ( - where string - args []any - err error - ) - - if q.Options.QueryBuilder != nil { - where, args, err = s.reconciliationQueryContext(q.Options.QueryBuilder, q) - if err != nil { - return nil, err - } - } - - return paginateWithOffset[PaginatedQueryOptions[ReconciliationsFilters], models.Reconciliation](s, ctx, - (*bunpaginate.OffsetPaginatedQuery[PaginatedQueryOptions[ReconciliationsFilters]])(&q), - func(query *bun.SelectQuery) *bun.SelectQuery { - return s.buildReconciliationListQuery(query, q, where, args) - }, - ) -} - -func (s *Storage) reconciliationQueryContext(qb query.Builder, q GetReconciliationsQuery) (string, []any, error) { - return qb.Build(query.ContextFn(func(key, operator string, value any) (string, []any, error) { - switch { - case key == "policyID": - if operator != "$match" { - return "", nil, errors.Wrap(ErrInvalidQuery, "'policyID' column can only be used with $match") - } - switch pID := value.(type) { - case string: - return "policy_id = ?", []any{pID}, nil - default: - return "", nil, errors.Wrap(ErrInvalidQuery, "'policyID' column can only be used with string") - } - default: - return "", nil, errors.Wrapf(ErrInvalidQuery, "unknown key '%s' when building query", key) - } - })) -} - -type ReconciliationsFilters struct{} - -type GetReconciliationsQuery bunpaginate.OffsetPaginatedQuery[PaginatedQueryOptions[ReconciliationsFilters]] - -func NewGetReconciliationsQuery(opts PaginatedQueryOptions[ReconciliationsFilters]) GetReconciliationsQuery { - return GetReconciliationsQuery{ - PageSize: opts.PageSize, - Order: bunpaginate.OrderAsc, - Options: opts, - } -} diff --git a/ee/reconciliation/internal/storage/store.go b/ee/reconciliation/internal/storage/store.go deleted file mode 100644 index 7578abb0cd..0000000000 --- a/ee/reconciliation/internal/storage/store.go +++ /dev/null @@ -1,17 +0,0 @@ -package storage - -import ( - "github.com/uptrace/bun" -) - -type Storage struct { - db *bun.DB -} - -func NewStorage(db *bun.DB) *Storage { - return &Storage{db: db} -} - -func (s *Storage) DB() *bun.DB { - return s.db -} diff --git a/ee/reconciliation/internal/storage/utils.go b/ee/reconciliation/internal/storage/utils.go deleted file mode 100644 index ae9ed64ca2..0000000000 --- a/ee/reconciliation/internal/storage/utils.go +++ /dev/null @@ -1,45 +0,0 @@ -package storage - -import ( - "context" - - "github.com/formancehq/go-libs/bun/bunpaginate" - "github.com/formancehq/go-libs/query" - "github.com/uptrace/bun" -) - -func paginateWithOffset[FILTERS any, RETURN any](s *Storage, ctx context.Context, - q *bunpaginate.OffsetPaginatedQuery[FILTERS], builders ...func(query *bun.SelectQuery) *bun.SelectQuery) (*bunpaginate.Cursor[RETURN], error) { - - query := s.db.NewSelect() - for _, builder := range builders { - query = query.Apply(builder) - } - - return bunpaginate.UsingOffset[FILTERS, RETURN](ctx, query, *q) -} - -type PaginatedQueryOptions[T any] struct { - QueryBuilder query.Builder `json:"qb"` - PageSize uint64 `json:"pageSize"` - Options T `json:"options"` -} - -func (opts PaginatedQueryOptions[T]) WithQueryBuilder(qb query.Builder) PaginatedQueryOptions[T] { - opts.QueryBuilder = qb - - return opts -} - -func (opts PaginatedQueryOptions[T]) WithPageSize(pageSize uint64) PaginatedQueryOptions[T] { - opts.PageSize = pageSize - - return opts -} - -func NewPaginatedQueryOptions[T any](options T) PaginatedQueryOptions[T] { - return PaginatedQueryOptions[T]{ - Options: options, - PageSize: bunpaginate.QueryDefaultPageSize, - } -} diff --git a/ee/reconciliation/main.go b/ee/reconciliation/main.go deleted file mode 100644 index 668a725a0e..0000000000 --- a/ee/reconciliation/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "github.com/formancehq/reconciliation/cmd" - -func main() { - cmd.Execute() -} diff --git a/ee/reconciliation/openapi.yaml b/ee/reconciliation/openapi.yaml deleted file mode 100644 index 498fc6d4df..0000000000 --- a/ee/reconciliation/openapi.yaml +++ /dev/null @@ -1,439 +0,0 @@ -openapi: 3.0.3 -info: - title: Reconciliation API - version: RECONCILIATION_VERSION -paths: - /_info: - get: - summary: Get server info - operationId: getServerInfo - tags: - - reconciliation.v1 - responses: - '200': - $ref: '#/components/responses/ServerInfo' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - reconciliation:read - /policies: - post: - summary: Create a policy - tags: - - reconciliation.v1 - operationId: createPolicy - description: Create a policy - requestBody: - $ref: '#/components/requestBodies/Policy' - responses: - '201': - $ref: '#/components/responses/Policy' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - reconciliation:write - get: - summary: List policies - operationId: listPolicies - tags: - - reconciliation.v1 - parameters: - - $ref: '#/components/parameters/PageSize' - - $ref: '#/components/parameters/Cursor' - responses: - '200': - $ref: '#/components/responses/Policies' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - reconciliation:read - /policies/{policyID}: - delete: - summary: Delete a policy - operationId: deletePolicy - tags: - - reconciliation.v1 - description: Delete a policy by its id. - parameters: - - $ref: '#/components/parameters/PolicyID' - responses: - '204': - $ref: '#/components/responses/NoContent' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - reconciliation:write - get: - summary: Get a policy - tags: - - reconciliation.v1 - operationId: getPolicy - parameters: - - $ref: '#/components/parameters/PolicyID' - responses: - '200': - $ref: '#/components/responses/Policy' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - reconciliation:read - /policies/{policyID}/reconciliation: - post: - summary: Reconcile using a policy - tags: - - reconciliation.v1 - operationId: reconcile - description: Reconcile using a policy - parameters: - - $ref: '#/components/parameters/PolicyID' - requestBody: - $ref: '#/components/requestBodies/Reconciliation' - responses: - '200': - $ref: '#/components/responses/Reconciliation' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - reconciliation:write - /reconciliations: - get: - summary: List reconciliations - operationId: listReconciliations - tags: - - reconciliation.v1 - parameters: - - $ref: '#/components/parameters/PageSize' - - $ref: '#/components/parameters/Cursor' - responses: - '200': - $ref: '#/components/responses/Reconciliations' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - reconciliation:read - /reconciliations/{reconciliationID}: - get: - summary: Get a reconciliation - tags: - - reconciliation.v1 - operationId: getReconciliation - parameters: - - $ref: '#/components/parameters/ReconciliationID' - responses: - '200': - $ref: '#/components/responses/Reconciliation' - default: - $ref: '#/components/responses/ErrorResponse' - security: - - Authorization: - - reconciliation:read -components: - parameters: - PageSize: - name: pageSize - in: query - description: | - The maximum number of results to return per page. - example: 100 - schema: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - Cursor: - name: cursor - in: query - description: | - Parameter used in pagination requests. Maximum page size is set to 15. - Set to the value of next for the next page of results. - Set to the value of previous for the previous page of results. - No other parameters can be set when this parameter is set. - schema: - type: string - example: aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== - PolicyID: - name: policyID - in: path - schema: - type: string - description: The policy ID. - example: XXX - required: true - ReconciliationID: - name: reconciliationID - in: path - schema: - type: string - description: The reconciliation ID. - example: XXX - required: true - responses: - NoContent: - description: No content - ServerInfo: - description: Server information - content: - application/json: - schema: - $ref: '#/components/schemas/ServerInfo' - Policies: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/PoliciesCursorResponse' - Policy: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/PolicyResponse' - Reconciliations: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/ReconciliationsCursorResponse' - Reconciliation: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/ReconciliationResponse' - ErrorResponse: - description: Error response - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - requestBodies: - Policy: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/PolicyRequest' - Reconciliation: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ReconciliationRequest' - schemas: - PoliciesCursorResponse: - type: object - required: - - cursor - properties: - cursor: - type: object - required: - - pageSize - - hasMore - - data - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: '' - data: - type: array - items: - $ref: '#/components/schemas/Policy' - ReconciliationsCursorResponse: - type: object - required: - - cursor - properties: - cursor: - type: object - required: - - pageSize - - hasMore - - data - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: '' - data: - type: array - items: - $ref: '#/components/schemas/Reconciliation' - ServerInfo: - type: object - required: - - version - properties: - version: - type: string - PolicyRequest: - type: object - required: - - name - - ledgerName - - ledgerQuery - - paymentsPoolID - properties: - name: - type: string - example: XXX - ledgerName: - type: string - example: default - ledgerQuery: - type: object - additionalProperties: true - paymentsPoolID: - type: string - example: XXX - PolicyResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Policy' - ReconciliationRequest: - type: object - required: - - reconciledAtLedger - - reconciledAtPayments - properties: - reconciledAtLedger: - type: string - format: date-time - example: '2021-01-01T00:00:00.000Z' - reconciledAtPayments: - type: string - format: date-time - example: '2021-01-01T00:00:00.000Z' - ReconciliationResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Reconciliation' - Policy: - type: object - required: - - id - - name - - createdAt - - ledgerName - - ledgerQuery - - paymentsPoolID - properties: - id: - type: string - example: XXX - name: - type: string - example: XXX - createdAt: - type: string - format: date-time - example: '2021-01-01T00:00:00.000Z' - ledgerName: - type: string - example: default - ledgerQuery: - type: object - additionalProperties: true - paymentsPoolID: - type: string - example: XXX - Reconciliation: - type: object - required: - - id - - policyID - - createdAt - - reconciledAtLedger - - reconciledAtPayments - - status - - paymentsBalances - - ledgerBalances - - driftBalances - properties: - id: - type: string - example: XXX - policyID: - type: string - example: XXX - createdAt: - type: string - format: date-time - example: '2021-01-01T00:00:00.000Z' - reconciledAtLedger: - type: string - format: date-time - example: '2021-01-01T00:00:00.000Z' - reconciledAtPayments: - type: string - format: date-time - example: '2021-01-01T00:00:00.000Z' - status: - type: string - example: COMPLETED - paymentsBalances: - type: object - additionalProperties: - type: integer - format: bigint - ledgerBalances: - type: object - additionalProperties: - type: integer - format: bigint - driftBalances: - type: object - additionalProperties: - type: integer - format: bigint - error: - type: string - ErrorResponse: - type: object - required: - - errorCode - - errorMessage - properties: - errorCode: - type: string - example: VALIDATION - errorMessage: - type: string - details: - type: string diff --git a/ee/reconciliation/scratch.Dockerfile b/ee/reconciliation/scratch.Dockerfile deleted file mode 100644 index 6af9d15298..0000000000 --- a/ee/reconciliation/scratch.Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM ghcr.io/formancehq/base:scratch -COPY reconciliation /usr/bin/reconciliation -ENV OTEL_SERVICE_NAME reconciliation -ENTRYPOINT ["/usr/bin/reconciliation"] -CMD ["serve"] diff --git a/ee/wallets/.gitignore b/ee/wallets/.gitignore deleted file mode 100644 index cbd864c43e..0000000000 --- a/ee/wallets/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -vendor -.idea -coverage.* -wallets diff --git a/ee/wallets/.goreleaser.yml b/ee/wallets/.goreleaser.yml deleted file mode 100644 index 37e1d806fa..0000000000 --- a/ee/wallets/.goreleaser.yml +++ /dev/null @@ -1,37 +0,0 @@ -project_name: wallets -includes: - - from_file: - path: ./../../.goreleaser.default.yaml -monorepo: - tag_prefix: v - dir: ./ - -builds: - - binary: wallets - id: wallets - ldflags: - - -X github.com/formancehq/wallets/cmd.BuildDate={{ .Date }} - - -X github.com/formancehq/wallets/cmd.Version=v{{ .Version }} - - -X github.com/formancehq/wallets/cmd.Commit={{ .ShortCommit }} - - -extldflags "-static" - env: - - CGO_ENABLED=0 - goos: - - linux - goarch: - - amd64 - - arm64 - -archives: - - id: "{{.ProjectName}}" - builds: - - wallets - format: tar.gz - name_template: "{{.ProjectName}}_{{.Os}}-{{.Arch}}" - -release: - prerelease: auto - footer: | - ## What to do next? - - Read the [documentation](https://docs.formance.com/) - - Join our [Slack server](https://formance.com/slack) \ No newline at end of file diff --git a/ee/wallets/Earthfile b/ee/wallets/Earthfile deleted file mode 100644 index 402bb653ac..0000000000 --- a/ee/wallets/Earthfile +++ /dev/null @@ -1,82 +0,0 @@ -VERSION 0.8 - -IMPORT github.com/formancehq/earthly:tags/v0.15.0 AS core -IMPORT ../.. AS stack -IMPORT ../../releases AS releases -IMPORT .. AS ee - -FROM core+base-image - -sources: - WORKDIR src - COPY --pass-args (releases+sdk-generate/go) /src/releases/sdks/go - WORKDIR /src/ee/wallets - COPY go.* . - COPY --dir pkg cmd . - COPY main.go . - SAVE ARTIFACT /src - -compile: - FROM core+builder-image - COPY (+sources/*) /src - WORKDIR /src/ee/wallets - ARG VERSION=latest - DO --pass-args core+GO_COMPILE --VERSION=$VERSION - -build-image: - FROM core+final-image - ENTRYPOINT ["/bin/wallets"] - CMD ["serve"] - COPY (+compile/main) /bin/wallets - ARG REPOSITORY=ghcr.io - ARG tag=latest - DO core+SAVE_IMAGE --COMPONENT=wallets --REPOSITORY=${REPOSITORY} --TAG=$tag - -tests: - FROM core+builder-image - COPY (+sources/*) /src - WORKDIR /src/ee/wallets - WITH DOCKER --pull=postgres:15-alpine - DO --pass-args core+GO_TESTS - END - -deploy: - COPY (+sources/*) /src - LET tag=$(tar cf - /src | sha1sum | awk '{print $1}') - WAIT - BUILD --pass-args +build-image --tag=$tag - END - FROM --pass-args core+vcluster-deployer-image - RUN kubectl patch Versions.formance.com default -p "{\"spec\":{\"wallets\": \"${tag}\"}}" --type=merge - -deploy-staging: - BUILD --pass-args stack+deployer-module --MODULE=wallets - -lint: - FROM core+builder-image - COPY (+sources/*) /src - COPY --pass-args +tidy/go.* . - WORKDIR /src/ee/wallets - DO --pass-args stack+GO_LINT - SAVE ARTIFACT cmd AS LOCAL cmd - SAVE ARTIFACT pkg AS LOCAL pkg - SAVE ARTIFACT main.go AS LOCAL main.go - -pre-commit: - WAIT - BUILD --pass-args +tidy - END - BUILD --pass-args +lint - -openapi: - COPY ./openapi.yaml . - SAVE ARTIFACT ./openapi.yaml - -tidy: - FROM core+builder-image - COPY --pass-args (+sources/src) /src - WORKDIR /src/ee/wallets - DO --pass-args stack+GO_TIDY - -release: - BUILD --pass-args stack+goreleaser --path=ee/wallets \ No newline at end of file diff --git a/ee/wallets/build.Dockerfile b/ee/wallets/build.Dockerfile deleted file mode 100644 index 44aec32521..0000000000 --- a/ee/wallets/build.Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM ghcr.io/formancehq/base:22.04 -COPY wallets /usr/bin/wallets -ENV OTEL_SERVICE_NAME wallets -ENTRYPOINT ["/usr/bin/wallets"] -CMD ["server"] diff --git a/ee/wallets/cmd/root.go b/ee/wallets/cmd/root.go deleted file mode 100644 index fea984494c..0000000000 --- a/ee/wallets/cmd/root.go +++ /dev/null @@ -1,29 +0,0 @@ -package cmd - -import ( - "github.com/formancehq/go-libs/service" - - "github.com/spf13/cobra" -) - -var ( - ServiceName = "wallets" - Version = "develop" - BuildDate = "-" - Commit = "-" -) - -func NewRootCommand() *cobra.Command { - cmd := &cobra.Command{} - - cobra.EnableTraverseRunHooks = true - - cmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") - serverCmd := newServeCommand() - cmd.AddCommand(serverCmd) - return cmd -} - -func Execute() { - service.Execute(NewRootCommand()) -} diff --git a/ee/wallets/cmd/serve.go b/ee/wallets/cmd/serve.go deleted file mode 100644 index e91e4e9378..0000000000 --- a/ee/wallets/cmd/serve.go +++ /dev/null @@ -1,101 +0,0 @@ -package cmd - -import ( - "context" - "net/http" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/go-libs/auth" - "github.com/formancehq/go-libs/licence" - "github.com/formancehq/go-libs/otlp" - "github.com/formancehq/go-libs/otlp/otlptraces" - "github.com/formancehq/go-libs/service" - wallet "github.com/formancehq/wallets/pkg" - "github.com/formancehq/wallets/pkg/api" - "github.com/spf13/cobra" - "go.uber.org/fx" - "golang.org/x/oauth2" - "golang.org/x/oauth2/clientcredentials" -) - -const ( - stackClientIDFlag = "stack-client-id" - stackClientSecretFlag = "stack-client-secret" - stackURLFlag = "stack-url" - ledgerNameFlag = "ledger" - accountPrefixFlag = "account-prefix" - listenFlag = "listen" -) - -func newServeCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "serve", - Aliases: []string{"server"}, - RunE: func(cmd *cobra.Command, args []string) error { - stackClientID, _ := cmd.Flags().GetString(stackClientIDFlag) - stackClientSecret, _ := cmd.Flags().GetString(stackClientSecretFlag) - stackURL, _ := cmd.Flags().GetString(stackURLFlag) - ledgerName, _ := cmd.Flags().GetString(ledgerNameFlag) - accountPrefix, _ := cmd.Flags().GetString(accountPrefixFlag) - listen, _ := cmd.Flags().GetString(listenFlag) - - options := []fx.Option{ - fx.Provide(func() (*http.Client, error) { - return GetHTTPClient( - cmd.Context(), - stackClientID, - stackClientSecret, - stackURL, - service.IsDebug(cmd), - ) - }), - wallet.Module( - stackURL, - ledgerName, - accountPrefix, - ), - api.Module(sharedapi.ServiceInfo{ - Version: Version, - Debug: service.IsDebug(cmd), - }, listen), - otlptraces.FXModuleFromFlags(cmd), - auth.FXModuleFromFlags(cmd), - licence.FXModuleFromFlags(cmd, ServiceName), - } - - return service.New(cmd.OutOrStdout(), options...).Run(cmd) - }, - } - cmd.Flags().String(stackClientIDFlag, "", "Client ID") - cmd.Flags().String(stackClientSecretFlag, "", "Client Secret") - cmd.Flags().String(stackURLFlag, "", "Token URL") - cmd.Flags().String(ledgerNameFlag, "wallets-002", "Target ledger") - cmd.Flags().String(accountPrefixFlag, "", "Account prefix flag") - cmd.Flags().String(listenFlag, ":8080", "Listen address") - - service.AddFlags(cmd.Flags()) - licence.AddFlags(cmd.Flags()) - auth.AddFlags(cmd.Flags()) - otlptraces.AddFlags(cmd.Flags()) - - return cmd -} - -func GetHTTPClient(ctx context.Context, clientID, clientSecret, stackURL string, debug bool) (*http.Client, error) { - httpClient := &http.Client{ - Transport: otlp.NewRoundTripper(http.DefaultTransport, debug), - } - - if clientID == "" { - return httpClient, nil - } - - clientCredentialsConfig := clientcredentials.Config{ - ClientID: clientID, - ClientSecret: clientSecret, - TokenURL: stackURL + "/api/auth/oauth/token", - Scopes: []string{"openid ledger:read ledger:write"}, - } - - return clientCredentialsConfig.Client(context.WithValue(ctx, oauth2.HTTPClient, httpClient)), nil -} diff --git a/ee/wallets/deploy/auth/config.yaml b/ee/wallets/deploy/auth/config.yaml deleted file mode 100644 index 1e306df360..0000000000 --- a/ee/wallets/deploy/auth/config.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -clients: -- id: auth - secrets: - - auth diff --git a/ee/wallets/deploy/postgres/init-databases.sh b/ee/wallets/deploy/postgres/init-databases.sh deleted file mode 100755 index ff1ccff949..0000000000 --- a/ee/wallets/deploy/postgres/init-databases.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -set -e - -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - CREATE DATABASE auth; - CREATE DATABASE ledger; - GRANT ALL PRIVILEGES ON DATABASE auth TO $POSTGRES_USER; - GRANT ALL PRIVILEGES ON DATABASE ledger TO $POSTGRES_USER; -EOSQL diff --git a/ee/wallets/deploy/proxy/.gitignore b/ee/wallets/deploy/proxy/.gitignore deleted file mode 100644 index 4e11a9d085..0000000000 --- a/ee/wallets/deploy/proxy/.gitignore +++ /dev/null @@ -1 +0,0 @@ -caddy diff --git a/ee/wallets/deploy/proxy/Caddyfile b/ee/wallets/deploy/proxy/Caddyfile deleted file mode 100644 index 2681d0b6cf..0000000000 --- a/ee/wallets/deploy/proxy/Caddyfile +++ /dev/null @@ -1,8 +0,0 @@ -:8080 { - handle_path /api/ledger/* { - reverse_proxy ledger:3068 - } - handle_path /api/auth/* { - reverse_proxy auth:8080 - } -} diff --git a/ee/wallets/go.mod b/ee/wallets/go.mod deleted file mode 100644 index e8f9661e59..0000000000 --- a/ee/wallets/go.mod +++ /dev/null @@ -1,94 +0,0 @@ -module github.com/formancehq/wallets - -go 1.22.0 - -toolchain go1.22.7 - -require ( - github.com/formancehq/formance-sdk-go/v2 v2.0.0-00010101000000-000000000000 - github.com/formancehq/go-libs v1.7.1 - github.com/formancehq/ledger v0.0.0-00010101000000-000000000000 - github.com/go-chi/chi/v5 v5.1.0 - github.com/go-chi/render v1.0.3 - github.com/google/uuid v1.6.0 - github.com/pkg/errors v0.9.1 - github.com/spf13/cobra v1.8.1 - github.com/stretchr/testify v1.9.0 - go.uber.org/fx v1.22.2 - golang.org/x/oauth2 v0.23.0 -) - -require ( - dario.cat/mergo v1.0.1 // indirect - github.com/ThreeDotsLabs/watermill v1.3.7 // indirect - github.com/ajg/form v1.5.1 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect - github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/goccy/go-json v0.10.3 // indirect - github.com/golang-jwt/jwt/v5 v5.2.1 // indirect - github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/schema v1.4.1 // indirect - github.com/gorilla/securecookie v1.1.2 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect - github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-retryablehttp v0.7.7 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect - github.com/lestrrat-go/blackmagic v1.0.2 // indirect - github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/jwx v1.2.30 // indirect - github.com/lestrrat-go/option v1.0.1 // indirect - github.com/lithammer/shortuuid/v3 v3.0.7 // indirect - github.com/muhlemmer/gu v0.3.1 // indirect - github.com/muhlemmer/httpforwarded v0.1.0 // indirect - github.com/oklog/ulid v1.3.1 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect - github.com/riandyrn/otelchi v0.10.0 // indirect - github.com/rs/cors v1.11.1 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect - github.com/uptrace/bun v1.2.3 // indirect - github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2 // indirect - github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 // indirect - github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect - github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/zitadel/oidc/v2 v2.12.2 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.30.0 // indirect - go.opentelemetry.io/otel v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0 // indirect - go.opentelemetry.io/otel/log v0.6.0 // indirect - go.opentelemetry.io/otel/metric v1.30.0 // indirect - go.opentelemetry.io/otel/sdk v1.30.0 // indirect - go.opentelemetry.io/otel/trace v1.30.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.uber.org/dig v1.18.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) - -replace github.com/formancehq/formance-sdk-go/v2 => ../../releases/sdks/go - -replace github.com/formancehq/ledger => github.com/formancehq/ledger v0.0.0-20240925161848-3cf78b93df02 diff --git a/ee/wallets/go.sum b/ee/wallets/go.sum deleted file mode 100644 index 5c4891b7fe..0000000000 --- a/ee/wallets/go.sum +++ /dev/null @@ -1,289 +0,0 @@ -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/ThreeDotsLabs/watermill v1.3.7 h1:NV0PSTmuACVEOV4dMxRnmGXrmbz8U83LENOvpHekN7o= -github.com/ThreeDotsLabs/watermill v1.3.7/go.mod h1:lBnrLbxOjeMRgcJbv+UiZr8Ylz8RkJ4m6i/VN/Nk+to= -github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/aws/aws-sdk-go-v2 v1.31.0 h1:3V05LbxTSItI5kUqNwhJrrrY1BAXxXt0sN0l72QmG5U= -github.com/aws/aws-sdk-go-v2 v1.31.0/go.mod h1:ztolYtaEUtdpf9Wftr31CJfLVjOnD/CVRkKOOYgF8hA= -github.com/aws/aws-sdk-go-v2/config v1.27.36 h1:4IlvHh6Olc7+61O1ktesh0jOcqmq/4WG6C2Aj5SKXy0= -github.com/aws/aws-sdk-go-v2/config v1.27.36/go.mod h1:IiBpC0HPAGq9Le0Xxb1wpAKzEfAQ3XlYgJLYKEVYcfw= -github.com/aws/aws-sdk-go-v2/credentials v1.17.34 h1:gmkk1l/cDGSowPRzkdxYi8edw+gN4HmVK151D/pqGNc= -github.com/aws/aws-sdk-go-v2/credentials v1.17.34/go.mod h1:4R9OEV3tgFMsok4ZeFpExn7zQaZRa9MRGFYnI/xC/vs= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 h1:C/d03NAmh8C4BZXhuRNboF/DqhBkBCeDiJDcaqIT5pA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14/go.mod h1:7I0Ju7p9mCIdlrfS+JCgqcYD0VXz/N4yozsox+0o078= -github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.4.18 h1:k51348zRERIvv01FflXAOQj50NeUiZUGOEedT4Vg+UE= -github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.4.18/go.mod h1:uybY6ESdxsT2dpzwSmpDgZJ3ekCYwVe/ZFYfAaXUbtU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 h1:kYQ3H1u0ANr9KEKlGs/jTLrBFPo8P8NaH/w7A01NeeM= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18/go.mod h1:r506HmK5JDUh9+Mw4CfGJGSSoqIiLCndAuqXuhbv67Y= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 h1:Z7IdFUONvTcvS7YuhtVxN99v2cCoHRXOS4mTr0B/pUc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18/go.mod h1:DkKMmksZVVyat+Y+r1dEOgJEfUeA7UngIHWeKsi0yNc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 h1:QFASJGfT8wMXtuP3D5CRmMjARHv9ZmzFUMJznHDOY3w= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5/go.mod h1:QdZ3OmoIjSX+8D1OPAzPxDfjXASbBMDsz9qvtyIhtik= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 h1:Xbwbmk44URTiHNx6PNo0ujDE6ERlsCKJD3u1zfnzAPg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20/go.mod h1:oAfOFzUB14ltPZj1rWwRc3d/6OgD76R8KlvU3EqM9Fg= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.0 h1:fHySkG0IGj2nepgGJPmmhZYL9ndnsq1Tvc6MeuVQCaQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.0/go.mod h1:XRlMvmad0ZNL+75C5FYdMvbbLkd6qiqz6foR1nA1PXY= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.0 h1:cU/OeQPNReyMj1JEBgjE29aclYZYtXcsPMXbTkVGMFk= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.0/go.mod h1:FnvDM4sfa+isJ3kDXIzAB9GAwVSzFzSy97uZ3IsHo4E= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.0 h1:GNVxIHBTi2EgwCxpNiozhNasMOK+ROUA2Z3X+cSBX58= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.0/go.mod h1:yMWe0F+XG0DkRZK5ODZhG7BEFYhLXi2dqGsv6tX0cgI= -github.com/aws/smithy-go v1.21.0 h1:H7L8dtDRk0P1Qm6y0ji7MCYMQObJ5R9CRpyPhRUkLYA= -github.com/aws/smithy-go v1.21.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= -github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ= -github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= -github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 h1:S92OBrGuLLZsyM5ybUzgc/mPjIYk2AZqufieooe98uw= -github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05/go.mod h1:M9R1FoZ3y//hwwnJtO51ypFGwm8ZfpxPT/ZLtO1mcgQ= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/formancehq/go-libs v1.7.1 h1:9D5cxKWFlVtdX5AYDXeUz1Nb9PdoEfQX0f/yeLsU324= -github.com/formancehq/go-libs v1.7.1/go.mod h1:pWTScpoyieF7OoJ6WVmXNG9NhDjbZbAmFqd7UOw85iI= -github.com/formancehq/ledger v0.0.0-20240925161848-3cf78b93df02 h1:0jB2JrN653A25DxUh4THjujWFZseMQqg5VMwGQxv7gc= -github.com/formancehq/ledger v0.0.0-20240925161848-3cf78b93df02/go.mod h1:sGscj1S3S2ndAzOPVFQFBuC72YF8t+OAm/hcqDcxpxI= -github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= -github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4= -github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= -github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= -github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= -github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= -github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 h1:c5FlPPgxOn7kJz3VoPLkQYQXGBS3EklQ4Zfi57uOuqQ= -github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= -github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= -github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= -github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= -github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= -github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= -github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= -github.com/jeremija/gosubmit v0.2.7/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= -github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= -github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= -github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= -github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.30 h1:VKIFrmjYn0z2J51iLPadqoHIVLzvWNa1kCsTqNDHYPA= -github.com/lestrrat-go/jwx v1.2.30/go.mod h1:vMxrwFhunGZ3qddmfmEm2+uced8MSI6QFWGTKygjSzQ= -github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= -github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8= -github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -github.com/muhlemmer/gu v0.3.1 h1:7EAqmFrW7n3hETvuAdmFmn4hS8W+z3LgKtrnow+YzNM= -github.com/muhlemmer/gu v0.3.1/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZkrdM= -github.com/muhlemmer/httpforwarded v0.1.0 h1:x4DLrzXdliq8mprgUMR0olDvHGkou5BJsK/vWUetyzY= -github.com/muhlemmer/httpforwarded v0.1.0/go.mod h1:yo9czKedo2pdZhoXe+yDkGVbU0TJ0q9oQ90BVoDEtw0= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= -github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opencontainers/runc v1.1.14 h1:rgSuzbmgz5DUJjeSnw337TxDbRuqjs6iqQck/2weR6w= -github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA= -github.com/ory/dockertest/v3 v3.11.0 h1:OiHcxKAvSDUwsEVh2BjxQQc/5EHz9n0va9awCtNGuyA= -github.com/ory/dockertest/v3 v3.11.0/go.mod h1:VIPxS1gwT9NpPOrfD3rACs8Y9Z7yhzO4SB194iUDnUI= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4= -github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= -github.com/riandyrn/otelchi v0.10.0 h1:QMbR/FMDWBOkej6dfyWteYefUKqIFxnyrpaoWRJ9RPQ= -github.com/riandyrn/otelchi v0.10.0/go.mod h1:zBaX2FavWMlsvq4GqHit+QXxF1c5wIMZZFaYyW4+7FA= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= -github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= -github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= -github.com/uptrace/bun v1.2.3 h1:6KDc6YiNlXde38j9ATKufb8o7MS8zllhAOeIyELKrk0= -github.com/uptrace/bun v1.2.3/go.mod h1:8frYFHrO/Zol3I4FEjoXam0HoNk+t5k7aJRl3FXp0mk= -github.com/uptrace/bun/dialect/pgdialect v1.2.3 h1:YyCxxqeL0lgFWRZzKCOt6mnxUsjqITcxSo0mLqgwMUA= -github.com/uptrace/bun/dialect/pgdialect v1.2.3/go.mod h1:Vx9TscyEq1iN4tnirn6yYGwEflz0KG3rBZTBCLpKAjc= -github.com/uptrace/bun/extra/bunotel v1.2.3 h1:G19QpDE68TXw97x6NciB6nKVDuK0Wb2KgtyMqNIyqBI= -github.com/uptrace/bun/extra/bunotel v1.2.3/go.mod h1:jHRgTqLlX/Zj1KIDokCMDat6JwZHJyErOx0PQ10UFgQ= -github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2 h1:H8wwQwTe5sL6x30z71lUgNiwBdeCHQjrphCfLwqIHGo= -github.com/uptrace/opentelemetry-go-extra/otellogrus v0.3.2/go.mod h1:/kR4beFhlz2g+V5ik8jW+3PMiMQAPt29y6K64NNY53c= -github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2 h1:ZjUj9BLYf9PEqBn8W/OapxhPjVRdC6CsXTdULHsyk5c= -github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.2/go.mod h1:O8bHQfyinKwTXKkiKNGmLQS7vRsqRxIQTFZpYpHK3IQ= -github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2 h1:3/aHKUq7qaFMWxyQV0W2ryNgg8x8rVeKVA20KJUkfS0= -github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.2/go.mod h1:Zit4b8AQXaXvA68+nzmbyDzqiyFRISyw1JiD5JqUBjw= -github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= -github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xo/dburl v0.23.2 h1:Fl88cvayrgE56JA/sqhNMLljCW/b7RmG1mMkKMZUFgA= -github.com/xo/dburl v0.23.2/go.mod h1:uazlaAQxj4gkshhfuuYyvwCBouOmNnG2aDxTCFZpmL4= -github.com/zitadel/oidc/v2 v2.12.2 h1:3kpckg4rurgw7w7aLJrq7yvRxb2pkNOtD08RH42vPEs= -github.com/zitadel/oidc/v2 v2.12.2/go.mod h1:vhP26g1g4YVntcTi0amMYW3tJuid70nxqxf+kb6XKgg= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI= -go.opentelemetry.io/contrib/propagators/b3 v1.30.0 h1:vumy4r1KMyaoQRltX7cJ37p3nluzALX9nugCjNNefuY= -go.opentelemetry.io/contrib/propagators/b3 v1.30.0/go.mod h1:fRbvRsaeVZ82LIl3u0rIvusIel2UUf+JcaaIpy5taho= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 h1:umZgi92IyxfXd/l4kaDhnKgY8rnN/cZcF1LKc6I8OQ8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0/go.mod h1:4lVs6obhSVRb1EW5FhOuBTyiQhtRtAnnva9vD3yRfq8= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0 h1:kn1BudCgwtE7PxLqcZkErpD8GKqLZ6BSzeW9QihQJeM= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.30.0/go.mod h1:ljkUDtAMdleoi9tIG1R6dJUpVwDcYjw3J2Q6Q/SuiC0= -go.opentelemetry.io/otel/log v0.6.0 h1:nH66tr+dmEgW5y+F9LanGJUBYPrRgP4g2EkmPE3LeK8= -go.opentelemetry.io/otel/log v0.6.0/go.mod h1:KdySypjQHhP069JX0z/t26VHwa8vSwzgaKmXtIB3fJM= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= -go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= -go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= -go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs= -gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/ee/wallets/main.go b/ee/wallets/main.go deleted file mode 100644 index 9d8aa11011..0000000000 --- a/ee/wallets/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "github.com/formancehq/wallets/cmd" - -func main() { - cmd.Execute() -} diff --git a/ee/wallets/openapi.yaml b/ee/wallets/openapi.yaml deleted file mode 100644 index c5169bd5b1..0000000000 --- a/ee/wallets/openapi.yaml +++ /dev/null @@ -1,1159 +0,0 @@ -openapi: 3.0.3 -info: - title: Formance Simple Wallets Service API - version: 0.1.0 -paths: - /_info: - get: - summary: Get server info - operationId: getServerInfo - tags: - - wallets.v1 - responses: - '200': - description: Server information - content: - application/json: - schema: - $ref: '#/components/schemas/ServerInfo' - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:read - /transactions: - get: - operationId: getTransactions - parameters: - - name: pageSize - in: query - description: The maximum number of results to return per page - example: 100 - schema: - type: integer - maximum: 1000 - minimum: 1 - default: 15 - - name: walletID - in: query - description: A wallet ID to filter on - example: wallet1 - schema: - type: string - - name: cursor - in: query - description: | - Parameter used in pagination requests. - Set to the value of next for the next page of results. - Set to the value of previous for the previous page of results. - No other parameters can be set when the cursor is set. - schema: - type: string - example: aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== - tags: - - wallets.v1 - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/GetTransactionsResponse' - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:read - /wallets: - get: - summary: List all wallets - operationId: listWallets - parameters: - - name: name - in: query - description: Filter on wallet name - example: wallet1 - schema: - type: string - - name: metadata - in: query - description: >- - Filter wallets by metadata key value pairs. Nested objects can be - used as seen in the example below. - style: deepObject - explode: true - schema: - type: object - properties: {} - additionalProperties: - type: string - example: - admin: 'true' - - name: pageSize - in: query - description: The maximum number of results to return per page - example: 100 - schema: - type: integer - maximum: 1000 - minimum: 1 - default: 15 - - name: cursor - in: query - description: | - Parameter used in pagination requests. - Set to the value of next for the next page of results. - Set to the value of previous for the previous page of results. - No other parameters can be set when the pagination token is set. - schema: - type: string - example: aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== - - name: expand - in: query - example: balances - schema: - type: string - items: - type: string - tags: - - wallets.v1 - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/ListWalletsResponse' - default: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:read - post: - summary: Create a new wallet - operationId: createWallet - tags: - - wallets.v1 - parameters: - - name: Idempotency-Key - in: header - description: Use an idempotency key - schema: - type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/CreateWalletRequest' - responses: - '201': - description: Wallet created - content: - application/json: - schema: - $ref: '#/components/schemas/CreateWalletResponse' - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:write - /wallets/{id}: - parameters: - - name: id - in: path - required: true - schema: - type: string - get: - summary: Get a wallet - operationId: getWallet - tags: - - wallets.v1 - responses: - '200': - description: Wallet - content: - application/json: - schema: - $ref: '#/components/schemas/GetWalletResponse' - '404': - description: Wallet not found - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:read - patch: - summary: Update a wallet - operationId: updateWallet - tags: - - wallets.v1 - parameters: - - name: Idempotency-Key - in: header - description: Use an idempotency key - schema: - type: string - requestBody: - content: - application/json: - schema: - type: object - required: - - metadata - properties: - metadata: - type: object - description: Custom metadata to attach to this wallet. - additionalProperties: - type: string - responses: - '204': - description: Wallet successfully updated - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:write - /wallets/{id}/summary: - parameters: - - name: id - in: path - required: true - schema: - type: string - get: - summary: Get wallet summary - operationId: getWalletSummary - tags: - - wallets.v1 - responses: - '200': - description: Wallet summary - content: - application/json: - schema: - $ref: '#/components/schemas/GetWalletSummaryResponse' - '404': - description: Wallet not found - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:read - /wallets/{id}/balances: - parameters: - - name: id - in: path - required: true - schema: - type: string - get: - summary: List balances of a wallet - operationId: listBalances - tags: - - wallets.v1 - responses: - '200': - description: Balances list - content: - application/json: - schema: - $ref: '#/components/schemas/ListBalancesResponse' - security: - - Authorization: - - wallets:read - post: - summary: Create a balance - operationId: createBalance - tags: - - wallets.v1 - parameters: - - name: Idempotency-Key - in: header - description: Use an idempotency key - schema: - type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/CreateBalanceRequest' - responses: - '201': - description: Created balance - content: - application/json: - schema: - $ref: '#/components/schemas/CreateBalanceResponse' - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:write - /wallets/{id}/balances/{balanceName}: - get: - parameters: - - name: id - in: path - required: true - schema: - type: string - - name: balanceName - in: path - required: true - schema: - type: string - summary: Get detailed balance - operationId: getBalance - tags: - - wallets.v1 - responses: - '200': - description: Balance summary - content: - application/json: - schema: - $ref: '#/components/schemas/GetBalanceResponse' - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:read - /wallets/{id}/debit: - parameters: - - name: id - in: path - required: true - schema: - type: string - - name: Idempotency-Key - in: header - description: Use an idempotency key - schema: - type: string - post: - summary: Debit a wallet - operationId: debitWallet - parameters: - - name: Idempotency-Key - in: header - description: Use an idempotency key - schema: - type: string - tags: - - wallets.v1 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/DebitWalletRequest' - responses: - '201': - description: Wallet successfully debited as a pending hold - content: - application/json: - schema: - $ref: '#/components/schemas/DebitWalletResponse' - '204': - description: Wallet successfully debited - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:write - /wallets/{id}/credit: - parameters: - - name: id - in: path - required: true - schema: - type: string - - name: Idempotency-Key - in: header - description: Use an idempotency key - schema: - type: string - post: - summary: Credit a wallet - operationId: creditWallet - parameters: - - name: Idempotency-Key - in: header - description: Use an idempotency key - schema: - type: string - tags: - - wallets.v1 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/CreditWalletRequest' - responses: - '204': - description: Wallet successfully credited - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:write - /holds: - get: - summary: Get all holds for a wallet - tags: - - wallets.v1 - operationId: getHolds - parameters: - - name: pageSize - in: query - description: The maximum number of results to return per page - example: 100 - schema: - type: integer - maximum: 1000 - minimum: 1 - default: 15 - - name: walletID - in: query - description: The wallet to filter on - example: wallet1 - schema: - type: string - - name: metadata - in: query - description: >- - Filter holds by metadata key value pairs. Nested objects can be used - as seen in the example below. - style: deepObject - schema: - type: object - properties: {} - additionalProperties: - type: string - example: - admin: 'true' - - name: cursor - in: query - description: | - Parameter used in pagination requests. - Set to the value of next for the next page of results. - Set to the value of previous for the previous page of results. - No other parameters can be set when the pagination token is set. - schema: - type: string - example: aHR0cHM6Ly9nLnBhZ2UvTmVrby1SYW1lbj9zaGFyZQ== - responses: - '200': - description: Holds - content: - application/json: - schema: - $ref: '#/components/schemas/GetHoldsResponse' - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:read - /holds/{holdID}: - get: - summary: Get a hold - tags: - - wallets.v1 - operationId: getHold - parameters: - - name: holdID - in: path - schema: - type: string - required: true - description: The hold ID - responses: - '200': - description: Holds - content: - application/json: - schema: - $ref: '#/components/schemas/GetHoldResponse' - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:read - /holds/{hold_id}/confirm: - post: - parameters: - - name: hold_id - in: path - required: true - schema: - type: string - - name: Idempotency-Key - in: header - description: Use an idempotency key - schema: - type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/ConfirmHoldRequest' - summary: Confirm a hold - tags: - - wallets.v1 - operationId: confirmHold - responses: - '204': - description: Hold successfully confirmed, funds moved back to initial destination - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:write - /holds/{hold_id}/void: - parameters: - - name: hold_id - in: path - required: true - schema: - type: string - - name: Idempotency-Key - in: header - description: Use an idempotency key - schema: - type: string - post: - summary: Cancel a hold - operationId: voidHold - tags: - - wallets.v1 - parameters: - - name: Idempotency-Key - in: header - description: Use an idempotency key - schema: - type: string - responses: - '204': - description: Hold successfully cancelled, funds returned to wallet - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - Authorization: - - wallets:write -components: - schemas: - Monetary: - type: object - required: - - asset - - amount - properties: - asset: - type: string - description: The asset of the monetary value. - amount: - type: integer - format: bigint - description: The amount of the monetary value. - Wallet: - type: object - required: - - name - - id - - metadata - - createdAt - - ledger - properties: - id: - type: string - format: uuid - description: The unique ID of the wallet. - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - name: - type: string - createdAt: - type: string - format: date-time - ledger: - type: string - balances: - type: object - required: - - main - properties: - main: - $ref: '#/components/schemas/AssetHolder' - WalletWithBalances: - type: object - required: - - name - - id - - metadata - - createdAt - - balances - - ledger - properties: - id: - type: string - format: uuid - description: The unique ID of the wallet. - metadata: - type: object - description: Metadata associated with the wallet. - additionalProperties: - type: string - name: - type: string - createdAt: - type: string - format: date-time - balances: - type: object - required: - - main - properties: - main: - $ref: '#/components/schemas/AssetHolder' - ledger: - type: string - Hold: - type: object - required: - - id - - walletID - - metadata - - description - properties: - id: - type: string - format: uuid - description: The unique ID of the hold. - walletID: - type: string - description: The ID of the wallet the hold is associated with. - metadata: - type: object - description: Metadata associated with the hold. - additionalProperties: - type: string - description: - type: string - destination: - $ref: '#/components/schemas/Subject' - ExpandedDebitHold: - allOf: - - $ref: '#/components/schemas/Hold' - - type: object - required: - - remaining - - originalAmount - properties: - remaining: - type: integer - description: Remaining amount on hold - example: 10 - format: bigint - originalAmount: - type: integer - description: Original amount on hold - example: 100 - format: bigint - ListWalletsResponse: - type: object - required: - - cursor - properties: - cursor: - allOf: - - $ref: '#/components/schemas/Cursor' - - properties: - data: - items: - $ref: '#/components/schemas/Wallet' - type: array - type: object - required: - - data - CreateWalletResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Wallet' - GetWalletResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/WalletWithBalances' - DebitWalletResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Hold' - AggregatedVolumes: - type: object - x-go-type: - type: AggregatedVolumes - additionalProperties: - $ref: '#/components/schemas/Volumes' - Posting: - type: object - properties: - amount: - type: integer - format: bigint - minimum: 0 - example: 100 - asset: - type: string - example: COIN - destination: - type: string - example: users:002 - source: - type: string - example: users:001 - required: - - amount - - asset - - destination - - source - Transaction: - type: object - properties: - ledger: - type: string - timestamp: - type: string - format: date-time - postings: - type: array - items: - $ref: '#/components/schemas/Posting' - reference: - type: string - example: ref:001 - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - id: - type: integer - format: int64 - minimum: 0 - preCommitVolumes: - $ref: '#/components/schemas/AggregatedVolumes' - postCommitVolumes: - $ref: '#/components/schemas/AggregatedVolumes' - required: - - postings - - timestamp - - id - - metadata - Cursor: - type: object - required: - - pageSize - properties: - pageSize: - type: integer - format: int64 - minimum: 1 - maximum: 1000 - example: 15 - hasMore: - type: boolean - example: false - previous: - type: string - example: YXVsdCBhbmQgYSBtYXhpbXVtIG1heF9yZXN1bHRzLol= - next: - type: string - example: '' - GetTransactionsResponse: - type: object - required: - - cursor - properties: - cursor: - allOf: - - $ref: '#/components/schemas/Cursor' - - properties: - data: - items: - $ref: '#/components/schemas/Transaction' - type: array - type: object - required: - - data - GetHoldsResponse: - type: object - required: - - cursor - properties: - cursor: - allOf: - - $ref: '#/components/schemas/Cursor' - - properties: - data: - items: - $ref: '#/components/schemas/Hold' - type: array - type: object - required: - - data - GetHoldResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/ExpandedDebitHold' - CreateWalletRequest: - type: object - required: - - name - - metadata - properties: - metadata: - type: object - description: Custom metadata to attach to this wallet. - additionalProperties: - type: string - name: - type: string - Volume: - type: object - properties: - input: - type: integer - format: bigint - output: - type: integer - format: bigint - balance: - type: integer - format: bigint - required: - - input - - output - - balance - example: - input: 100 - output: 20 - balance: 80 - Volumes: - type: object - additionalProperties: - $ref: '#/components/schemas/Volume' - example: - USD: - input: 100 - output: 10 - balance: 90 - EUR: - input: 100 - output: 10 - balance: 90 - ConfirmHoldRequest: - type: object - properties: - amount: - type: integer - format: bigint - example: 100 - description: Define the amount to transfer. - final: - type: boolean - example: true - description: >- - Define a final confirmation. Remaining funds will be returned to the - wallet. - LedgerAccountSubject: - type: object - required: - - type - - identifier - properties: - type: - type: string - identifier: - type: string - WalletSubject: - type: object - required: - - type - - identifier - properties: - type: - type: string - identifier: - type: string - balance: - type: string - Subject: - discriminator: - propertyName: type - mapping: - ACCOUNT: '#/components/schemas/LedgerAccountSubject' - WALLET: '#/components/schemas/WalletSubject' - oneOf: - - $ref: '#/components/schemas/LedgerAccountSubject' - - $ref: '#/components/schemas/WalletSubject' - CreditWalletRequest: - type: object - required: - - amount - properties: - amount: - $ref: '#/components/schemas/Monetary' - metadata: - type: object - nullable: true - additionalProperties: - type: string - description: Metadata associated with the wallet. - reference: - type: string - sources: - type: array - nullable: true - items: - $ref: '#/components/schemas/Subject' - balance: - type: string - description: The balance to credit - timestamp: - type: string - format: date-time - example: - amount: - asset: USD/2 - amount: 100 - metadata: - key: '' - sources: [] - DebitWalletRequest: - type: object - required: - - amount - - metadata - properties: - amount: - $ref: '#/components/schemas/Monetary' - pending: - type: boolean - description: >- - Set to true to create a pending hold. If false, the wallet will be - debited immediately. - metadata: - type: object - additionalProperties: - type: string - description: Metadata associated with the wallet. - description: - type: string - destination: - $ref: '#/components/schemas/Subject' - balances: - type: array - items: - type: string - description: A targeted balance (use '*' for all) - timestamp: - type: string - format: date-time - description: cannot be used in conjunction with `pending` property - example: - amount: - asset: USD/2 - amount: 100 - metadata: - key: '' - pending: true - ServerInfo: - type: object - required: - - version - properties: - version: - type: string - AssetHolder: - type: object - required: - - assets - properties: - assets: - type: object - additionalProperties: - type: integer - format: bigint - Balance: - type: object - required: - - name - properties: - name: - type: string - expiresAt: - type: string - format: date-time - nullable: true - priority: - type: integer - format: bigint - BalanceWithAssets: - allOf: - - $ref: '#/components/schemas/Balance' - - $ref: '#/components/schemas/AssetHolder' - GetWalletSummaryResponse: - type: object - required: - - balances - - availableFunds - - expiredFunds - - expirableFunds - - holdFunds - properties: - balances: - type: array - items: - $ref: '#/components/schemas/BalanceWithAssets' - availableFunds: - type: object - additionalProperties: - type: integer - format: bigint - expiredFunds: - type: object - additionalProperties: - type: integer - format: bigint - expirableFunds: - type: object - additionalProperties: - type: integer - format: bigint - holdFunds: - type: object - additionalProperties: - type: integer - format: bigint - ListBalancesResponse: - type: object - required: - - cursor - properties: - cursor: - allOf: - - $ref: '#/components/schemas/Cursor' - - properties: - data: - items: - $ref: '#/components/schemas/Balance' - type: array - type: object - required: - - data - GetBalanceResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/BalanceWithAssets' - CreateBalanceRequest: - $ref: '#/components/schemas/Balance' - CreateBalanceResponse: - type: object - required: - - data - properties: - data: - $ref: '#/components/schemas/Balance' - ErrorResponse: - type: object - required: - - errorCode - - errorMessage - properties: - errorCode: - type: string - enum: - - VALIDATION - - INTERNAL_ERROR - - INSUFFICIENT_FUND - - HOLD_CLOSED - errorMessage: - type: string diff --git a/ee/wallets/pkg/api/handler_balances_create.go b/ee/wallets/pkg/api/handler_balances_create.go deleted file mode 100644 index 29701c97df..0000000000 --- a/ee/wallets/pkg/api/handler_balances_create.go +++ /dev/null @@ -1,36 +0,0 @@ -package api - -import ( - "errors" - "net/http" - - wallet "github.com/formancehq/wallets/pkg" - "github.com/go-chi/render" -) - -func (m *MainHandler) createBalanceHandler(w http.ResponseWriter, r *http.Request) { - data := &wallet.CreateBalance{} - if r.ContentLength > 0 { - if err := render.Bind(r, data); err != nil { - badRequest(w, ErrorCodeValidation, err) - return - } - } - - balance, err := m.manager.CreateBalance(r.Context(), data) - if err != nil { - switch { - case errors.Is(err, wallet.ErrInvalidBalanceName): - fallthrough - case errors.Is(err, wallet.ErrReservedBalanceName): - fallthrough - case errors.Is(err, wallet.ErrBalanceAlreadyExists): - badRequest(w, ErrorCodeValidation, err) - default: - internalError(w, r, err) - } - return - } - - created(w, balance) -} diff --git a/ee/wallets/pkg/api/handler_balances_create_test.go b/ee/wallets/pkg/api/handler_balances_create_test.go deleted file mode 100644 index 82f10b62d6..0000000000 --- a/ee/wallets/pkg/api/handler_balances_create_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package api - -import ( - "context" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/go-libs/time" - - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func ptr[V any](v V) *V { - return &v -} - -type balanceCreateTestCase struct { - name string - request wallet.CreateBalance - expectedStatusCode int - expectedErrorCode string -} - -var balanceCreateTestCases = []balanceCreateTestCase{ - { - name: "nominal", - request: wallet.CreateBalance{ - Name: uuid.NewString(), - }, - }, - { - name: "with invalid name", - request: wallet.CreateBalance{ - Name: "!!!!!!!", - }, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrorCodeValidation, - }, - { - name: "with reserved name", - request: wallet.CreateBalance{ - Name: wallet.MainBalance, - }, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrorCodeValidation, - }, - { - name: "with expiration", - request: wallet.CreateBalance{ - Name: wallet.MainBalance, - ExpiresAt: ptr(time.Now().Add(10 * time.Second)), - }, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrorCodeValidation, - }, -} - -func TestBalancesCreate(t *testing.T) { - t.Parallel() - - for _, testCase := range balanceCreateTestCases { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - req := newRequest(t, http.MethodPost, "/wallets/"+walletID+"/balances", testCase.request) - rec := httptest.NewRecorder() - - var ( - targetedLedger string - targetedAccount string - appliedMetadata map[string]string - ) - testEnv := newTestEnv( - WithAddMetadataToAccount(func(ctx context.Context, ledger, account, ik string, metadata map[string]string) error { - targetedLedger = ledger - targetedAccount = account - appliedMetadata = metadata - return nil - }), - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - return &wallet.AccountWithVolumesAndBalances{}, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - expectedStatusCode := testCase.expectedStatusCode - if expectedStatusCode == 0 { - expectedStatusCode = http.StatusCreated - } - require.Equal(t, expectedStatusCode, rec.Result().StatusCode) - - if expectedStatusCode == http.StatusCreated { - balance := &wallet.Balance{} - readResponse(t, rec, balance) - require.Equal(t, testEnv.LedgerName(), targetedLedger) - require.Equal(t, targetedAccount, testEnv.Chart().GetBalanceAccount(walletID, balance.Name)) - require.Equal(t, balance.LedgerMetadata(walletID), appliedMetadata) - require.Equal(t, balance.Name, testCase.request.Name) - } else { - errorResponse := readErrorResponse(t, rec) - require.Equal(t, testCase.expectedErrorCode, errorResponse.ErrorCode) - } - }) - } -} diff --git a/ee/wallets/pkg/api/handler_balances_get.go b/ee/wallets/pkg/api/handler_balances_get.go deleted file mode 100644 index 33b967acc0..0000000000 --- a/ee/wallets/pkg/api/handler_balances_get.go +++ /dev/null @@ -1,24 +0,0 @@ -package api - -import ( - "errors" - "net/http" - - wallet "github.com/formancehq/wallets/pkg" - "github.com/go-chi/chi/v5" -) - -func (m *MainHandler) getBalanceHandler(w http.ResponseWriter, r *http.Request) { - balance, err := m.manager.GetBalance(r.Context(), chi.URLParam(r, "walletID"), chi.URLParam(r, "balanceName")) - if err != nil { - switch { - case errors.Is(err, wallet.ErrBalanceNotExists): - notFound(w) - default: - internalError(w, r, err) - } - return - } - - ok(w, balance) -} diff --git a/ee/wallets/pkg/api/handler_balances_get_test.go b/ee/wallets/pkg/api/handler_balances_get_test.go deleted file mode 100644 index 3f3d682bf9..0000000000 --- a/ee/wallets/pkg/api/handler_balances_get_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package api - -import ( - "context" - "encoding/json" - "math/big" - "net/http" - "net/http/httptest" - "testing" - - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func metadataWithExpectingTypesAfterUnmarshalling(m map[string]string) map[string]string { - data, err := json.Marshal(m) - if err != nil { - panic(err) - } - err = json.Unmarshal(data, &m) - if err != nil { - panic(err) - } - return m -} - -func TestGetBalance(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - balance := wallet.NewBalance(uuid.NewString(), nil) - assets := map[string]*big.Int{ - "USD": big.NewInt(50), - } - - req := newRequest(t, http.MethodGet, "/wallets/"+walletID+"/balances/"+balance.Name, nil) - rec := httptest.NewRecorder() - - var testEnv *testEnv - testEnv = newTestEnv( - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, testEnv.Chart().GetBalanceAccount(walletID, balance.Name), account) - - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: account, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(balance.LedgerMetadata(walletID)), - }, - Balances: assets, - }, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - - ret := wallet.ExpandedBalance{} - readResponse(t, rec, &ret) - require.EqualValues(t, wallet.ExpandedBalance{ - Balance: balance, - Assets: assets, - }, ret) -} - -func TestGetBalanceNotFound(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - - req := newRequest(t, http.MethodGet, "/wallets/"+walletID+"/balances/xxx", nil) - rec := httptest.NewRecorder() - - var testEnv *testEnv - testEnv = newTestEnv( - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: account, - }, - }, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusNotFound, rec.Result().StatusCode) -} diff --git a/ee/wallets/pkg/api/handler_balances_list.go b/ee/wallets/pkg/api/handler_balances_list.go deleted file mode 100644 index f4d4236c7d..0000000000 --- a/ee/wallets/pkg/api/handler_balances_list.go +++ /dev/null @@ -1,25 +0,0 @@ -package api - -import ( - "net/http" - - wallet "github.com/formancehq/wallets/pkg" - "github.com/go-chi/chi/v5" -) - -func (m *MainHandler) listBalancesHandler(w http.ResponseWriter, r *http.Request) { - query := readPaginatedRequest(r, func(r *http.Request) wallet.ListBalances { - return wallet.ListBalances{ - WalletID: chi.URLParam(r, "walletID"), - Metadata: getQueryMap(r.URL.Query(), "metadata"), - } - }) - - holds, err := m.manager.ListBalances(r.Context(), query) - if err != nil { - internalError(w, r, err) - return - } - - cursorFromListResponse(w, query, holds) -} diff --git a/ee/wallets/pkg/api/handler_balances_list_test.go b/ee/wallets/pkg/api/handler_balances_list_test.go deleted file mode 100644 index 550c443f79..0000000000 --- a/ee/wallets/pkg/api/handler_balances_list_test.go +++ /dev/null @@ -1,109 +0,0 @@ -package api - -import ( - "context" - "fmt" - "net/http" - "net/http/httptest" - "strconv" - "testing" - - sharedapi "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/formancehq/go-libs/pointer" - - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestBalancesList(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - var balances []wallet.Balance - for i := 0; i < 10; i++ { - balances = append(balances, wallet.NewBalance(uuid.NewString(), nil)) - } - const pageSize = 2 - numberOfPages := int64(len(balances) / pageSize) - - var testEnv *testEnv - testEnv = newTestEnv( - WithListAccounts(func(ctx context.Context, ledger string, query wallet.ListAccountsQuery) (*wallet.AccountsCursorResponseCursor, error) { - if query.Cursor != "" { - page, err := strconv.ParseInt(query.Cursor, 10, 64) - if err != nil { - panic(err) - } - - if page >= numberOfPages-1 { - return &wallet.AccountsCursorResponseCursor{ - Data: make([]wallet.AccountWithVolumesAndBalances, 0), - }, nil - } - hasMore := page < numberOfPages-1 - previous := fmt.Sprint(page - 1) - next := fmt.Sprint(page + 1) - accounts := make([]wallet.AccountWithVolumesAndBalances, 0) - for _, balance := range balances[page*pageSize : (page+1)*pageSize] { - accounts = append(accounts, wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetBalanceAccount(walletID, balance.Name), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(balance.LedgerMetadata(walletID)), - }, - }) - } - return &wallet.AccountsCursorResponseCursor{ - Data: accounts, - PageSize: pageSize, - HasMore: hasMore, - Previous: pointer.For(previous), - Next: pointer.For(next), - }, nil - } - - require.Equal(t, pageSize, query.Limit) - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, metadata.Metadata{ - wallet.MetadataKeyWalletBalance: wallet.TrueValue, - wallet.MetadataKeyWalletID: walletID, - }, query.Metadata) - - accounts := make([]wallet.AccountWithVolumesAndBalances, 0) - for _, balance := range balances[:pageSize] { - accounts = append(accounts, wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetBalanceAccount(walletID, balance.Name), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(balance.LedgerMetadata(walletID)), - }, - }) - } - return &wallet.AccountsCursorResponseCursor{ - PageSize: pageSize, - HasMore: true, - Next: pointer.For("1"), - Data: accounts, - }, nil - }), - ) - - req := newRequest(t, http.MethodGet, fmt.Sprintf("/wallets/%s/balances?pageSize=%d", walletID, pageSize), nil) - rec := httptest.NewRecorder() - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - cursor := &sharedapi.Cursor[wallet.Balance]{} - readCursor(t, rec, cursor) - require.Len(t, cursor.Data, pageSize) - require.EqualValues(t, cursor.Data, balances[:pageSize]) - - req = newRequest(t, http.MethodGet, fmt.Sprintf("/wallets/%s/balances?cursor=%s", walletID, cursor.Next), nil) - rec = httptest.NewRecorder() - testEnv.Router().ServeHTTP(rec, req) - cursor = &sharedapi.Cursor[wallet.Balance]{} - readCursor(t, rec, cursor) - require.Len(t, cursor.Data, pageSize) - require.EqualValues(t, cursor.Data, balances[pageSize:pageSize*2]) -} diff --git a/ee/wallets/pkg/api/handler_holds_confirm.go b/ee/wallets/pkg/api/handler_holds_confirm.go deleted file mode 100644 index 22276a94b0..0000000000 --- a/ee/wallets/pkg/api/handler_holds_confirm.go +++ /dev/null @@ -1,54 +0,0 @@ -package api - -import ( - "errors" - "math/big" - "net/http" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/api" - - wallet "github.com/formancehq/wallets/pkg" - "github.com/go-chi/render" -) - -type ConfirmHoldRequest struct { - Amount int64 `json:"amount"` - Final bool `json:"final"` -} - -func (c ConfirmHoldRequest) Bind(r *http.Request) error { - return nil -} - -func (m *MainHandler) confirmHoldHandler(w http.ResponseWriter, r *http.Request) { - data := &ConfirmHoldRequest{} - if r.ContentLength > 0 { - if err := render.Bind(r, data); err != nil { - badRequest(w, ErrorCodeValidation, err) - return - } - } - - err := m.manager.ConfirmHold(r.Context(), api.IdempotencyKeyFromRequest(r), wallet.ConfirmHold{ - HoldID: chi.URLParam(r, "holdID"), - Amount: big.NewInt(data.Amount), - Final: data.Final, - }) - if err != nil { - switch { - case errors.Is(err, wallet.ErrHoldNotFound): - notFound(w) - case errors.Is(err, wallet.ErrInsufficientFundError): - badRequest(w, ErrorCodeInsufficientFund, err) - case errors.Is(err, wallet.ErrClosedHold): - badRequest(w, ErrorCodeClosedHold, err) - default: - internalError(w, r, err) - } - return - } - - noContent(w) -} diff --git a/ee/wallets/pkg/api/handler_holds_confirm_test.go b/ee/wallets/pkg/api/handler_holds_confirm_test.go deleted file mode 100644 index c0faef0a0f..0000000000 --- a/ee/wallets/pkg/api/handler_holds_confirm_test.go +++ /dev/null @@ -1,255 +0,0 @@ -package api - -import ( - "context" - "math/big" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestHoldsConfirm(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - hold := wallet.NewDebitHold(walletID, wallet.NewLedgerAccountSubject("bank"), "USD", "", metadata.Metadata{}) - - req := newRequest(t, http.MethodPost, "/holds/"+hold.ID+"/confirm", nil) - rec := httptest.NewRecorder() - - var testEnv *testEnv - testEnv = newTestEnv( - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, testEnv.Chart().GetHoldAccount(hold.ID), account) - balances := map[string]*big.Int{ - "USD": big.NewInt(100), - } - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetHoldAccount(hold.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold.LedgerMetadata(testEnv.Chart())), - }, - Balances: balances, - }, nil - }), - WithCreateTransaction(func(ctx context.Context, name, ik string, postTransaction wallet.PostTransaction) (*shared.V2Transaction, error) { - compareJSON(t, wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildConfirmHoldScript(false, "USD"), - Vars: map[string]interface{}{ - "hold": testEnv.Chart().GetHoldAccount(hold.ID), - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - "dest": "bank", - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(nil)), - }, postTransaction) - return &shared.V2Transaction{}, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusNoContent, rec.Result().StatusCode) -} - -func TestHoldsPartialConfirm(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - hold := wallet.NewDebitHold(walletID, wallet.NewLedgerAccountSubject("bank"), "USD", "", metadata.Metadata{}) - - req := newRequest(t, http.MethodPost, "/holds/"+hold.ID+"/confirm", ConfirmHoldRequest{ - Amount: 50, - }) - rec := httptest.NewRecorder() - - var testEnv *testEnv - testEnv = newTestEnv( - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, testEnv.Chart().GetHoldAccount(hold.ID), account) - - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetHoldAccount(hold.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold.LedgerMetadata(testEnv.Chart())), - }, - Balances: map[string]*big.Int{ - "USD": big.NewInt(100), - }, - Volumes: map[string]shared.V2Volume{ - "USD": { - Input: big.NewInt(100), - }, - }, - }, nil - }), - WithCreateTransaction(func(ctx context.Context, name, ik string, postTransaction wallet.PostTransaction) (*shared.V2Transaction, error) { - compareJSON(t, wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildConfirmHoldScript(false, "USD"), - Vars: map[string]interface{}{ - "hold": testEnv.Chart().GetHoldAccount(hold.ID), - "amount": map[string]any{ - "amount": uint64(50), - "asset": "USD", - }, - "dest": "bank", - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(nil)), - }, postTransaction) - return &shared.V2Transaction{}, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusNoContent, rec.Result().StatusCode) -} - -func TestHoldsConfirmWithTooHighAmount(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - hold := wallet.NewDebitHold(walletID, wallet.NewLedgerAccountSubject("bank"), "USD", "", metadata.Metadata{}) - - req := newRequest(t, http.MethodPost, "/holds/"+hold.ID+"/confirm", ConfirmHoldRequest{ - Amount: 500, - }) - rec := httptest.NewRecorder() - - var testEnv *testEnv - testEnv = newTestEnv( - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, testEnv.Chart().GetHoldAccount(hold.ID), account) - - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetHoldAccount(hold.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold.LedgerMetadata(testEnv.Chart())), - }, - Balances: map[string]*big.Int{ - "USD": big.NewInt(100), - }, - Volumes: map[string]shared.V2Volume{ - "USD": { - Input: big.NewInt(100), - }, - }, - }, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusBadRequest, rec.Result().StatusCode) - errorResponse := readErrorResponse(t, rec) - require.Equal(t, ErrorCodeInsufficientFund, errorResponse.ErrorCode) -} - -func TestHoldsConfirmWithClosedHold(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - hold := wallet.NewDebitHold(walletID, wallet.NewLedgerAccountSubject("bank"), "USD", "", metadata.Metadata{}) - - req := newRequest(t, http.MethodPost, "/holds/"+hold.ID+"/confirm", ConfirmHoldRequest{}) - rec := httptest.NewRecorder() - - var testEnv *testEnv - testEnv = newTestEnv( - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, testEnv.Chart().GetHoldAccount(hold.ID), account) - - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetHoldAccount(hold.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold.LedgerMetadata(testEnv.Chart())), - }, - Balances: map[string]*big.Int{ - "USD": big.NewInt(0), - }, - Volumes: map[string]shared.V2Volume{ - "USD": { - Input: big.NewInt(100), - }, - }, - }, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusBadRequest, rec.Result().StatusCode) - errorResponse := readErrorResponse(t, rec) - require.Equal(t, ErrorCodeClosedHold, errorResponse.ErrorCode) -} - -func TestHoldsPartialConfirmWithFinal(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - hold := wallet.NewDebitHold(walletID, wallet.NewLedgerAccountSubject("bank"), - "USD", "", metadata.Metadata{}) - - req := newRequest(t, http.MethodPost, "/holds/"+hold.ID+"/confirm", ConfirmHoldRequest{ - Amount: 50, - Final: true, - }) - rec := httptest.NewRecorder() - - var testEnv *testEnv - testEnv = newTestEnv( - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, testEnv.Chart().GetHoldAccount(hold.ID), account) - - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetHoldAccount(hold.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold.LedgerMetadata(testEnv.Chart())), - }, - Balances: map[string]*big.Int{ - "USD": big.NewInt(100), - }, - Volumes: map[string]shared.V2Volume{ - "USD": { - Input: big.NewInt(100), - }, - }, - }, nil - }), - WithCreateTransaction(func(ctx context.Context, name, ik string, script wallet.PostTransaction) (*shared.V2Transaction, error) { - compareJSON(t, wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildConfirmHoldScript(true, "USD"), - Vars: map[string]interface{}{ - "hold": testEnv.Chart().GetHoldAccount(hold.ID), - "amount": map[string]any{ - "amount": uint64(50), - "asset": "USD", - }, - "dest": "bank", - "void_destination": testEnv.Chart().GetMainBalanceAccount(hold.WalletID), - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(nil)), - }, script) - return &shared.V2Transaction{}, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusNoContent, rec.Result().StatusCode) -} diff --git a/ee/wallets/pkg/api/handler_holds_get.go b/ee/wallets/pkg/api/handler_holds_get.go deleted file mode 100644 index 0e26b6aae8..0000000000 --- a/ee/wallets/pkg/api/handler_holds_get.go +++ /dev/null @@ -1,17 +0,0 @@ -package api - -import ( - "net/http" - - "github.com/go-chi/chi/v5" -) - -func (m *MainHandler) getHoldHandler(w http.ResponseWriter, r *http.Request) { - hold, err := m.manager.GetHold(r.Context(), chi.URLParam(r, "holdID")) - if err != nil { - internalError(w, r, err) - return - } - - ok(w, hold) -} diff --git a/ee/wallets/pkg/api/handler_holds_get_test.go b/ee/wallets/pkg/api/handler_holds_get_test.go deleted file mode 100644 index cbdcbec3d2..0000000000 --- a/ee/wallets/pkg/api/handler_holds_get_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package api - -import ( - "context" - "math/big" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestHoldsGet(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - hold := wallet.NewDebitHold(walletID, wallet.NewLedgerAccountSubject("bank"), - "USD", "", metadata.Metadata{}) - - req := newRequest(t, http.MethodGet, "/holds/"+hold.ID, nil) - rec := httptest.NewRecorder() - - var testEnv *testEnv - testEnv = newTestEnv( - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, testEnv.Chart().GetHoldAccount(hold.ID), account) - - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetHoldAccount(hold.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold.LedgerMetadata(testEnv.Chart())), - }, - Balances: map[string]*big.Int{ - "USD": big.NewInt(50), - }, - Volumes: map[string]shared.V2Volume{ - "USD": { - Input: big.NewInt(100), - }, - }, - }, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - - ret := wallet.ExpandedDebitHold{} - readResponse(t, rec, &ret) - require.EqualValues(t, wallet.ExpandedDebitHold{ - DebitHold: hold, - OriginalAmount: big.NewInt(100), - Remaining: big.NewInt(50), - }, ret) -} diff --git a/ee/wallets/pkg/api/handler_holds_list.go b/ee/wallets/pkg/api/handler_holds_list.go deleted file mode 100644 index 30d9286f73..0000000000 --- a/ee/wallets/pkg/api/handler_holds_list.go +++ /dev/null @@ -1,24 +0,0 @@ -package api - -import ( - "net/http" - - wallet "github.com/formancehq/wallets/pkg" -) - -func (m *MainHandler) listHoldsHandler(w http.ResponseWriter, r *http.Request) { - query := readPaginatedRequest(r, func(r *http.Request) wallet.ListHolds { - return wallet.ListHolds{ - WalletID: r.URL.Query().Get("walletID"), - Metadata: getQueryMap(r.URL.Query(), "metadata"), - } - }) - - holds, err := m.manager.ListHolds(r.Context(), query) - if err != nil { - internalError(w, r, err) - return - } - - cursorFromListResponse(w, query, holds) -} diff --git a/ee/wallets/pkg/api/handler_holds_list_test.go b/ee/wallets/pkg/api/handler_holds_list_test.go deleted file mode 100644 index 79e5190b35..0000000000 --- a/ee/wallets/pkg/api/handler_holds_list_test.go +++ /dev/null @@ -1,159 +0,0 @@ -package api - -import ( - "context" - "fmt" - "net/http" - "net/http/httptest" - "strconv" - "testing" - - sharedapi "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/formancehq/go-libs/pointer" - - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestHoldsList(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - - holds := make([]wallet.DebitHold, 0) - for i := 0; i < 10; i++ { - holds = append(holds, wallet.NewDebitHold(walletID, wallet.NewLedgerAccountSubject("bank"), - "USD", "", metadata.Metadata{})) - } - pageSize := 5 - - var testEnv *testEnv - testEnv = newTestEnv( - WithListAccounts(func(ctx context.Context, ledger string, query wallet.ListAccountsQuery) (*wallet.AccountsCursorResponseCursor, error) { - require.Equal(t, pageSize, query.Limit) - require.Equal(t, testEnv.LedgerName(), ledger) - require.EqualValues(t, metadata.Metadata{ - wallet.MetadataKeyWalletSpecType: wallet.HoldWallet, - }, query.Metadata) - - accounts := make([]wallet.AccountWithVolumesAndBalances, 0) - for _, hold := range holds[:pageSize] { - accounts = append(accounts, wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetMainBalanceAccount(hold.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold.LedgerMetadata(testEnv.Chart())), - }, - }) - } - - return &wallet.AccountsCursorResponseCursor{ - PageSize: 5, - HasMore: false, - Data: accounts, - }, nil - }), - ) - req := newRequest(t, http.MethodGet, fmt.Sprintf("/holds?pageSize=%d", pageSize), nil) - rec := httptest.NewRecorder() - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - cursor := &sharedapi.Cursor[wallet.DebitHold]{} - readCursor(t, rec, cursor) -} - -func TestHoldsListWithPagination(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - - holds := make([]wallet.DebitHold, 0) - for i := 0; i < 10; i++ { - holds = append(holds, wallet.NewDebitHold(walletID, wallet.NewLedgerAccountSubject("bank"), - "USD", "", metadata.Metadata{})) - } - const pageSize = 2 - numberOfPages := int64(len(holds) / pageSize) - - var testEnv *testEnv - testEnv = newTestEnv( - WithListAccounts(func(ctx context.Context, ledger string, query wallet.ListAccountsQuery) (*wallet.AccountsCursorResponseCursor, error) { - if query.Cursor != "" { - page, err := strconv.ParseInt(query.Cursor, 10, 64) - if err != nil { - panic(err) - } - - if page >= numberOfPages-1 { - return &wallet.AccountsCursorResponseCursor{}, nil - } - hasMore := page < numberOfPages-1 - previous := fmt.Sprint(page - 1) - next := fmt.Sprint(page + 1) - accounts := make([]wallet.AccountWithVolumesAndBalances, 0) - for _, hold := range holds[page*pageSize : (page+1)*pageSize] { - accounts = append(accounts, wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetMainBalanceAccount(hold.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold.LedgerMetadata(testEnv.Chart())), - }, - }) - } - - return &wallet.AccountsCursorResponseCursor{ - PageSize: pageSize, - HasMore: hasMore, - Previous: pointer.For(previous), - Next: pointer.For(next), - Data: accounts, - }, nil - } - - require.Equal(t, pageSize, query.Limit) - require.Equal(t, testEnv.LedgerName(), ledger) - require.EqualValues(t, metadata.Metadata{ - wallet.MetadataKeyWalletSpecType: wallet.HoldWallet, - wallet.MetadataKeyHoldWalletID: walletID, - }, query.Metadata) - - next := "1" - accounts := make([]wallet.AccountWithVolumesAndBalances, 0) - for _, hold := range holds[:pageSize] { - accounts = append(accounts, wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetMainBalanceAccount(hold.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold.LedgerMetadata(testEnv.Chart())), - }, - }) - } - - return &wallet.AccountsCursorResponseCursor{ - PageSize: pageSize, - HasMore: true, - Next: pointer.For(next), - Data: accounts, - }, nil - }), - ) - req := newRequest(t, http.MethodGet, fmt.Sprintf("/holds?walletID=%s&pageSize=%d", walletID, pageSize), nil) - rec := httptest.NewRecorder() - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - cursor := &sharedapi.Cursor[wallet.DebitHold]{} - readCursor(t, rec, cursor) - require.Len(t, cursor.Data, pageSize) - require.EqualValues(t, holds[:pageSize], cursor.Data) - - req = newRequest(t, http.MethodGet, fmt.Sprintf("/holds?walletID=%s&cursor=%s", walletID, cursor.Next), nil) - rec = httptest.NewRecorder() - testEnv.Router().ServeHTTP(rec, req) - - cursor = &sharedapi.Cursor[wallet.DebitHold]{} - readCursor(t, rec, cursor) - require.Len(t, cursor.Data, pageSize) - require.EqualValues(t, holds[pageSize:pageSize*2], cursor.Data) -} diff --git a/ee/wallets/pkg/api/handler_holds_void.go b/ee/wallets/pkg/api/handler_holds_void.go deleted file mode 100644 index d0baf9e6e7..0000000000 --- a/ee/wallets/pkg/api/handler_holds_void.go +++ /dev/null @@ -1,29 +0,0 @@ -package api - -import ( - "errors" - "net/http" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/api" - - wallet "github.com/formancehq/wallets/pkg" -) - -func (m *MainHandler) voidHoldHandler(w http.ResponseWriter, r *http.Request) { - err := m.manager.VoidHold(r.Context(), api.IdempotencyKeyFromRequest(r), wallet.VoidHold{ - HoldID: chi.URLParam(r, "holdID"), - }) - if err != nil { - switch { - case errors.Is(err, wallet.ErrClosedHold): - badRequest(w, ErrorCodeClosedHold, err) - default: - internalError(w, r, err) - } - return - } - - noContent(w) -} diff --git a/ee/wallets/pkg/api/handler_holds_void_test.go b/ee/wallets/pkg/api/handler_holds_void_test.go deleted file mode 100644 index c2a2ca4de2..0000000000 --- a/ee/wallets/pkg/api/handler_holds_void_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package api - -import ( - "context" - "math/big" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestHoldsVoid(t *testing.T) { - t.Parallel() - - walletID := uuid.NewString() - hold := wallet.NewDebitHold(walletID, wallet.NewLedgerAccountSubject("bank"), "USD", "", metadata.Metadata{}) - - req := newRequest(t, http.MethodPost, "/holds/"+hold.ID+"/void", nil) - rec := httptest.NewRecorder() - - var testEnv *testEnv - testEnv = newTestEnv( - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, testEnv.Chart().GetHoldAccount(hold.ID), account) - - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetHoldAccount(hold.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold.LedgerMetadata(testEnv.Chart())), - }, - Balances: map[string]*big.Int{ - "USD": big.NewInt(100), - }, - Volumes: map[string]shared.V2Volume{ - "USD": { - Input: big.NewInt(100), - }, - }, - }, nil - }), - WithCreateTransaction(func(ctx context.Context, name, ik string, script wallet.PostTransaction) (*shared.V2Transaction, error) { - compareJSON(t, wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildCancelHoldScript("USD"), - Vars: map[string]interface{}{ - "hold": testEnv.Chart().GetHoldAccount(hold.ID), - "dest": testEnv.Chart().GetMainBalanceAccount(hold.WalletID), - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(nil)), - }, script) - return &shared.V2Transaction{}, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusNoContent, rec.Result().StatusCode) -} diff --git a/ee/wallets/pkg/api/handler_transactions_list.go b/ee/wallets/pkg/api/handler_transactions_list.go deleted file mode 100644 index c9a6318124..0000000000 --- a/ee/wallets/pkg/api/handler_transactions_list.go +++ /dev/null @@ -1,22 +0,0 @@ -package api - -import ( - "net/http" - - wallet "github.com/formancehq/wallets/pkg" -) - -func (m *MainHandler) listTransactions(w http.ResponseWriter, r *http.Request) { - query := readPaginatedRequest[wallet.ListTransactions](r, func(r *http.Request) wallet.ListTransactions { - return wallet.ListTransactions{ - WalletID: r.URL.Query().Get("walletID"), - } - }) - transactions, err := m.manager.ListTransactions(r.Context(), query) - if err != nil { - internalError(w, r, err) - return - } - - cursorFromListResponse(w, query, transactions) -} diff --git a/ee/wallets/pkg/api/handler_transactions_list_test.go b/ee/wallets/pkg/api/handler_transactions_list_test.go deleted file mode 100644 index b1cce46b45..0000000000 --- a/ee/wallets/pkg/api/handler_transactions_list_test.go +++ /dev/null @@ -1,122 +0,0 @@ -package api - -import ( - "context" - "fmt" - "math/big" - "net/http" - "net/http/httptest" - "strconv" - "testing" - - "github.com/formancehq/go-libs/collectionutils" - - sharedapi "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "github.com/formancehq/go-libs/pointer" - - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestTransactionsList(t *testing.T) { - t.Parallel() - - w := wallet.NewWallet(uuid.NewString(), "default", metadata.Metadata{}) - - var transactions []shared.V2Transaction - for i := 0; i < 10; i++ { - transactions = append(transactions, shared.V2Transaction{ - Postings: []shared.V2Posting{{ - Amount: big.NewInt(100), - Asset: "USD/2", - Destination: "bank", - Source: "world", - }}, - Metadata: map[string]string{}, - }) - } - const pageSize = 2 - numberOfPages := int64(len(transactions) / pageSize) - - var testEnv *testEnv - testEnv = newTestEnv( - WithListTransactions(func(ctx context.Context, ledger string, query wallet.ListTransactionsQuery) (*shared.V2TransactionsCursorResponseCursor, error) { - if query.Cursor != "" { - page, err := strconv.ParseInt(query.Cursor, 10, 64) - if err != nil { - panic(err) - } - - if page >= numberOfPages-1 { - return &shared.V2TransactionsCursorResponseCursor{}, nil - } - hasMore := page < numberOfPages-1 - previous := fmt.Sprint(page - 1) - next := fmt.Sprint(page + 1) - - return &shared.V2TransactionsCursorResponseCursor{ - PageSize: pageSize, - HasMore: hasMore, - Previous: pointer.For(previous), - Next: pointer.For(next), - Data: collectionutils.Map(transactions[page*pageSize:(page+1)*pageSize], func(from shared.V2Transaction) shared.V2ExpandedTransaction { - return shared.V2ExpandedTransaction{ - ID: from.ID, - Metadata: from.Metadata, - PostCommitVolumes: nil, - Postings: from.Postings, - PreCommitVolumes: nil, - Reference: from.Reference, - Reverted: from.Reverted, - Timestamp: from.Timestamp, - } - }), - }, nil - } - - require.Equal(t, pageSize, query.Limit) - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, testEnv.Chart().GetMainBalanceAccount(w.ID), query.Account) - - return &shared.V2TransactionsCursorResponseCursor{ - PageSize: pageSize, - HasMore: true, - Next: pointer.For("1"), - Data: collectionutils.Map(transactions[:pageSize], func(from shared.V2Transaction) shared.V2ExpandedTransaction { - return shared.V2ExpandedTransaction{ - ID: from.ID, - Metadata: from.Metadata, - PostCommitVolumes: nil, - Postings: from.Postings, - PreCommitVolumes: nil, - Reference: from.Reference, - Reverted: from.Reverted, - Timestamp: from.Timestamp, - } - }), - }, nil - }), - ) - - req := newRequest(t, http.MethodGet, fmt.Sprintf("/transactions?pageSize=%d&walletID=%s", pageSize, w.ID), nil) - rec := httptest.NewRecorder() - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - cursor := &sharedapi.Cursor[shared.V2Transaction]{} - readCursor(t, rec, cursor) - require.Len(t, cursor.Data, pageSize) - require.EqualValues(t, transactions[:pageSize], cursor.Data) - - req = newRequest(t, http.MethodGet, fmt.Sprintf("/transactions?cursor=%s", cursor.Next), nil) - rec = httptest.NewRecorder() - testEnv.Router().ServeHTTP(rec, req) - cursor = &sharedapi.Cursor[shared.V2Transaction]{} - readCursor(t, rec, cursor) - require.Len(t, cursor.Data, pageSize) - require.EqualValues(t, transactions[pageSize:pageSize*2], cursor.Data) -} diff --git a/ee/wallets/pkg/api/handler_wallets_create.go b/ee/wallets/pkg/api/handler_wallets_create.go deleted file mode 100644 index 06d1d6bf07..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_create.go +++ /dev/null @@ -1,26 +0,0 @@ -package api - -import ( - "net/http" - - wallet "github.com/formancehq/wallets/pkg" - "github.com/go-chi/render" -) - -func (m *MainHandler) createWalletHandler(w http.ResponseWriter, r *http.Request) { - data := &wallet.CreateRequest{} - if r.ContentLength > 0 { - if err := render.Bind(r, data); err != nil { - badRequest(w, ErrorCodeValidation, err) - return - } - } - - wallet, err := m.manager.CreateWallet(r.Context(), data) - if err != nil { - internalError(w, r, err) - return - } - - created(w, wallet) -} diff --git a/ee/wallets/pkg/api/handler_wallets_create_test.go b/ee/wallets/pkg/api/handler_wallets_create_test.go deleted file mode 100644 index ad71a5953c..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_create_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package api - -import ( - "context" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestWalletsCreate(t *testing.T) { - t.Parallel() - - createWalletRequest := wallet.CreateRequest{ - PatchRequest: wallet.PatchRequest{ - Metadata: metadata.Metadata{ - "foo": "bar", - }, - }, - Name: uuid.NewString(), - } - - req := newRequest(t, http.MethodPost, "/wallets", createWalletRequest) - rec := httptest.NewRecorder() - - var ( - ledger string - account string - md map[string]string - ) - testEnv := newTestEnv( - WithAddMetadataToAccount(func(ctx context.Context, l, a, ik string, m map[string]string) error { - ledger = l - account = a - md = m - return nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusCreated, rec.Result().StatusCode) - wallet := &wallet.Wallet{} - readResponse(t, rec, wallet) - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, account, testEnv.Chart().GetMainBalanceAccount(wallet.ID)) - require.Equal(t, wallet.LedgerMetadata(), md) - require.Equal(t, wallet.Metadata, createWalletRequest.Metadata) - require.Equal(t, wallet.Name, createWalletRequest.Name) -} diff --git a/ee/wallets/pkg/api/handler_wallets_credit.go b/ee/wallets/pkg/api/handler_wallets_credit.go deleted file mode 100644 index 8d1ff8cf7f..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_credit.go +++ /dev/null @@ -1,50 +0,0 @@ -package api - -import ( - "errors" - "net/http" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/api" - - wallet "github.com/formancehq/wallets/pkg" - "github.com/go-chi/render" -) - -const ( - ErrorCodeInternal = "INTERNAL" - ErrorCodeInsufficientFund = "INSUFFICIENT_FUND" - ErrorCodeValidation = "VALIDATION" - ErrorCodeClosedHold = "HOLD_CLOSED" -) - -func (m *MainHandler) creditWalletHandler(w http.ResponseWriter, r *http.Request) { - data := &wallet.CreditRequest{} - if err := render.Bind(r, data); err != nil { - badRequest(w, ErrorCodeValidation, err) - return - } - - id := chi.URLParam(r, "walletID") - credit := wallet.Credit{ - WalletID: id, - CreditRequest: *data, - } - - err := m.manager.Credit(r.Context(), api.IdempotencyKeyFromRequest(r), credit) - if err != nil { - switch { - case errors.Is(err, wallet.ErrBalanceNotExists), - errors.Is(err, wallet.ErrNegativeAmount), - wallet.IsErrInvalidAccountName(err), - wallet.IsErrInvalidAsset(err): - badRequest(w, ErrorCodeValidation, err) - default: - internalError(w, r, err) - } - return - } - - noContent(w) -} diff --git a/ee/wallets/pkg/api/handler_wallets_credit_test.go b/ee/wallets/pkg/api/handler_wallets_credit_test.go deleted file mode 100644 index 1938778fcf..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_credit_test.go +++ /dev/null @@ -1,224 +0,0 @@ -package api - -import ( - "context" - "math/big" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/go-libs/time" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestWalletsCredit(t *testing.T) { - t.Parallel() - now := time.Now() - - type testCase struct { - name string - request wallet.CreditRequest - postTransactionResult shared.V2Transaction - expectedPostTransaction func(testEnv *testEnv, walletID string) wallet.PostTransaction - expectedStatusCode int - expectedErrorCode string - } - testCases := []testCase{ - { - name: "nominal", - request: wallet.CreditRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Metadata: metadata.Metadata{ - "foo": "bar", - }, - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildCreditWalletScript("world"), - Vars: map[string]interface{}{ - "destination": testEnv.chart.GetMainBalanceAccount(walletID), - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: wallet.TransactionMetadata(metadata.Metadata{ - "foo": "bar", - }), - } - }, - }, - { - name: "with source list", - request: wallet.CreditRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Sources: []wallet.Subject{ - wallet.NewLedgerAccountSubject("emitter1"), - wallet.NewWalletSubject("wallet1", ""), - }, - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildCreditWalletScript( - "emitter1", - testEnv.Chart().GetMainBalanceAccount("wallet1"), - ), - Vars: map[string]interface{}{ - "destination": testEnv.chart.GetMainBalanceAccount(walletID), - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: wallet.TransactionMetadata(nil), - } - }, - }, - { - name: "with secondary balance from source", - request: wallet.CreditRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Sources: []wallet.Subject{ - wallet.NewWalletSubject("emitter1", "secondary"), - }, - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildCreditWalletScript( - testEnv.Chart().GetBalanceAccount("emitter1", "secondary"), - ), - Vars: map[string]interface{}{ - "destination": testEnv.Chart().GetMainBalanceAccount(walletID), - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: wallet.TransactionMetadata(nil), - } - }, - }, - { - name: "with secondary balance as destination", - request: wallet.CreditRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Balance: "secondary", - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildCreditWalletScript("world"), - Vars: map[string]interface{}{ - "destination": testEnv.Chart().GetBalanceAccount(walletID, "secondary"), - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: wallet.TransactionMetadata(nil), - } - }, - }, - { - name: "with not existing secondary balance as destination", - request: wallet.CreditRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Balance: "not-existing", - }, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: ErrorCodeValidation, - }, - { - name: "with specified timestamp", - request: wallet.CreditRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Timestamp: &now, - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildCreditWalletScript("world"), - Vars: map[string]interface{}{ - "destination": testEnv.chart.GetMainBalanceAccount(walletID), - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: wallet.TransactionMetadata(nil), - Timestamp: &now, - } - }, - }, - } - - for _, testCase := range testCases { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - t.Parallel() - walletID := uuid.NewString() - secondaryBalance := wallet.NewBalance("secondary", nil) - - req := newRequest(t, http.MethodPost, "/wallets/"+walletID+"/credit", testCase.request) - rec := httptest.NewRecorder() - - var ( - testEnv *testEnv - postTransaction wallet.PostTransaction - ) - testEnv = newTestEnv( - WithCreateTransaction(func(ctx context.Context, ledger, ik string, p wallet.PostTransaction) (*shared.V2Transaction, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - postTransaction = p - return &testCase.postTransactionResult, nil - }), - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - if testEnv.Chart().GetBalanceAccount(walletID, secondaryBalance.Name) == account { - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: account, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(secondaryBalance.LedgerMetadata(walletID)), - }, - }, nil - } - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Metadata: map[string]string{}, - }, - }, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - expectedStatusCode := testCase.expectedStatusCode - if expectedStatusCode == 0 { - expectedStatusCode = http.StatusNoContent - } - - require.Equal(t, expectedStatusCode, rec.Result().StatusCode) - if expectedStatusCode == http.StatusNoContent { - if testCase.expectedPostTransaction != nil { - expectedScript := testCase.expectedPostTransaction(testEnv, walletID) - require.Equal(t, expectedScript, postTransaction) - } - } else { - errorResponse := readErrorResponse(t, rec) - require.Equal(t, ErrorCodeValidation, errorResponse.ErrorCode) - } - }) - } -} diff --git a/ee/wallets/pkg/api/handler_wallets_debit.go b/ee/wallets/pkg/api/handler_wallets_debit.go deleted file mode 100644 index 17c9cfc9fe..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_debit.go +++ /dev/null @@ -1,47 +0,0 @@ -package api - -import ( - "errors" - "net/http" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/api" - - wallet "github.com/formancehq/wallets/pkg" - "github.com/go-chi/render" -) - -func (m *MainHandler) debitWalletHandler(w http.ResponseWriter, r *http.Request) { - data := &wallet.DebitRequest{} - if err := render.Bind(r, data); err != nil { - badRequest(w, ErrorCodeValidation, err) - return - } - - hold, err := m.manager.Debit(r.Context(), api.IdempotencyKeyFromRequest(r), wallet.Debit{ - WalletID: chi.URLParam(r, "walletID"), - DebitRequest: *data, - }) - if err != nil { - switch { - case errors.Is(err, wallet.ErrInsufficientFundError): - badRequest(w, ErrorCodeInsufficientFund, wallet.ErrInsufficientFundError) - case errors.Is(err, wallet.ErrInvalidBalanceSpecified), - errors.Is(err, wallet.ErrNegativeAmount), - wallet.IsErrInvalidAccountName(err), - wallet.IsErrInvalidAsset(err): - badRequest(w, ErrorCodeValidation, wallet.ErrInvalidBalanceSpecified) - default: - internalError(w, r, err) - } - return - } - - if hold == nil { - noContent(w) - return - } - - created(w, hold) -} diff --git a/ee/wallets/pkg/api/handler_wallets_debit_test.go b/ee/wallets/pkg/api/handler_wallets_debit_test.go deleted file mode 100644 index 45796ac5f4..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_debit_test.go +++ /dev/null @@ -1,380 +0,0 @@ -package api - -import ( - "context" - "encoding/json" - "math/big" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/go-libs/time" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func compareJSON(t *testing.T, expected, actual any) { - data, err := json.Marshal(expected) - require.NoError(t, err) - - expectedAsMap := make(map[string]any) - require.NoError(t, json.Unmarshal(data, &expectedAsMap)) - - data, err = json.Marshal(actual) - require.NoError(t, err) - - actualAsMap := make(map[string]any) - require.NoError(t, json.Unmarshal(data, &actualAsMap)) - - require.Equal(t, expectedAsMap, actualAsMap) -} - -type testCase struct { - name string - request wallet.DebitRequest - postTransactionError *sdkerrors.WalletsErrorResponse - expectedPostTransaction func(testEnv *testEnv, walletID string, h *wallet.DebitHold) wallet.PostTransaction - expectedStatusCode int - expectedErrorCode string -} - -var now = time.Now() -var walletDebitTestCases = []testCase{ - { - name: "nominal", - request: wallet.DebitRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string, h *wallet.DebitHold) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildDebitWalletScript(map[string]map[string]string{}, testEnv.Chart().GetMainBalanceAccount(walletID)), - Vars: map[string]interface{}{ - "destination": wallet.DefaultDebitDest.Identifier, - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(nil)), - } - }, - }, - { - name: "using timestamp", - request: wallet.DebitRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Timestamp: &now, - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string, h *wallet.DebitHold) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildDebitWalletScript(map[string]map[string]string{}, testEnv.Chart().GetMainBalanceAccount(walletID)), - Vars: map[string]interface{}{ - "destination": wallet.DefaultDebitDest.Identifier, - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(nil)), - Timestamp: &now, - } - }, - }, - { - name: "with custom destination as ledger account", - request: wallet.DebitRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Destination: wallet.Ptr(wallet.NewLedgerAccountSubject("account1")), - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string, h *wallet.DebitHold) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildDebitWalletScript(map[string]map[string]string{}, testEnv.Chart().GetMainBalanceAccount(walletID)), - Vars: map[string]interface{}{ - "destination": "account1", - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(nil)), - } - }, - }, - { - name: "with custom destination as wallet", - request: wallet.DebitRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Destination: wallet.Ptr(wallet.NewWalletSubject("wallet1", "")), - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string, h *wallet.DebitHold) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildDebitWalletScript(map[string]map[string]string{}, testEnv.Chart().GetMainBalanceAccount(walletID)), - Vars: map[string]interface{}{ - "destination": testEnv.Chart().GetMainBalanceAccount("wallet1"), - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(nil)), - } - }, - }, - { - name: "with insufficient funds", - request: wallet.DebitRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - }, - postTransactionError: &sdkerrors.WalletsErrorResponse{ - ErrorCode: sdkerrors.SchemasWalletsErrorResponseErrorCodeInsufficientFund, - }, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: string(shared.ErrorsEnumInsufficientFund), - }, - { - name: "with debit hold", - request: wallet.DebitRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Pending: true, - Metadata: map[string]string{ - "foo": "bar", - }, - Description: "a first tx", - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string, h *wallet.DebitHold) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildDebitWalletScript(map[string]map[string]string{ - testEnv.Chart().GetHoldAccount(h.ID): h.LedgerMetadata(testEnv.Chart()), - }, testEnv.Chart().GetMainBalanceAccount(walletID)), - Vars: map[string]interface{}{ - "destination": testEnv.Chart().GetHoldAccount(h.ID), - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(metadata.Metadata{ - "foo": "bar", - })), - } - }, - expectedStatusCode: http.StatusCreated, - }, - { - name: "with custom balance as source", - request: wallet.DebitRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Balances: []string{"secondary"}, - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string, h *wallet.DebitHold) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildDebitWalletScript(map[string]map[string]string{}, testEnv.Chart().GetBalanceAccount(walletID, "secondary")), - Vars: map[string]interface{}{ - "destination": "world", - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(nil)), - } - }, - }, - { - name: "with wildcard balance as source", - request: wallet.DebitRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Balances: []string{"*"}, - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string, h *wallet.DebitHold) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildDebitWalletScript(map[string]map[string]string{}, testEnv.Chart().GetBalanceAccount(walletID, "coupon1"), testEnv.Chart().GetBalanceAccount(walletID, "coupon4"), testEnv.Chart().GetBalanceAccount(walletID, "coupon2"), testEnv.Chart().GetBalanceAccount(walletID, "main")), - Vars: map[string]interface{}{ - "destination": "world", - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(nil)), - } - }, - }, - { - name: "with wildcard plus another source", - request: wallet.DebitRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Balances: []string{"*", "secondary"}, - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string, h *wallet.DebitHold) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildDebitWalletScript(map[string]map[string]string{}, testEnv.Chart().GetBalanceAccount(walletID, "secondary")), - Vars: map[string]interface{}{ - "destination": "world", - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(nil)), - } - }, - expectedStatusCode: http.StatusBadRequest, - expectedErrorCode: string(sdkerrors.SchemasErrorCodeValidation), - }, - { - name: "with custom balance as destination", - request: wallet.DebitRequest{ - Amount: wallet.NewMonetary(big.NewInt(100), "USD"), - Destination: wallet.Ptr(wallet.NewWalletSubject("wallet1", "secondary")), - }, - expectedPostTransaction: func(testEnv *testEnv, walletID string, h *wallet.DebitHold) wallet.PostTransaction { - return wallet.PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: wallet.BuildDebitWalletScript(map[string]map[string]string{}, testEnv.Chart().GetMainBalanceAccount(walletID)), - Vars: map[string]interface{}{ - "destination": testEnv.Chart().GetBalanceAccount("wallet1", "secondary"), - "amount": map[string]any{ - "amount": uint64(100), - "asset": "USD", - }, - }, - }, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.TransactionMetadata(nil)), - } - }, - }, -} - -func TestWalletsDebit(t *testing.T) { - t.Parallel() - for _, testCase := range walletDebitTestCases { - testCase := testCase - t.Run(testCase.name, func(t *testing.T) { - t.Parallel() - walletID := uuid.NewString() - - req := newRequest(t, http.MethodPost, "/wallets/"+walletID+"/debit", testCase.request) - rec := httptest.NewRecorder() - - var ( - testEnv *testEnv - postTransaction wallet.PostTransaction - ) - testEnv = newTestEnv( - WithListAccounts(func(ctx context.Context, ledger string, query wallet.ListAccountsQuery) (*wallet.AccountsCursorResponseCursor, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, query.Metadata, wallet.BalancesMetadataFilter(walletID)) - - return &wallet.AccountsCursorResponseCursor{ - Data: []wallet.AccountWithVolumesAndBalances{ - { - Account: wallet.Account{ - Address: testEnv.Chart().GetBalanceAccount(walletID, "coupon2"), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.Balance{ - Name: "coupon2", - Priority: 10, - }.LedgerMetadata(walletID)), - }, - }, - { - Account: wallet.Account{ - Address: testEnv.Chart().GetBalanceAccount(walletID, "coupon1"), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.Balance{ - Name: "coupon1", - ExpiresAt: ptr(time.Now().Add(5 * time.Second)), - }.LedgerMetadata(walletID)), - }, - }, - { - Account: wallet.Account{ - Address: testEnv.Chart().GetBalanceAccount(walletID, "coupon3"), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.Balance{ - Name: "coupon3", - ExpiresAt: ptr(time.Now().Add(-time.Minute)), - }.LedgerMetadata(walletID)), - }, - }, - { - Account: wallet.Account{ - Address: testEnv.Chart().GetBalanceAccount(walletID, "coupon4"), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.Balance{ - Name: "coupon4", - }.LedgerMetadata(walletID)), - }, - }, - { - Account: wallet.Account{ - Address: testEnv.Chart().GetBalanceAccount(walletID, "main"), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallet.Balance{ - Name: "main", - }.LedgerMetadata(walletID)), - }, - }, - }, - }, nil - }), - WithCreateTransaction(func(ctx context.Context, ledger, ik string, p wallet.PostTransaction) (*shared.V2Transaction, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - postTransaction = p - if testCase.postTransactionError != nil { - return nil, testCase.postTransactionError - } - //nolint:nilnil - return nil, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - expectedStatusCode := testCase.expectedStatusCode - if expectedStatusCode == 0 { - expectedStatusCode = http.StatusNoContent - } - require.Equal(t, expectedStatusCode, rec.Result().StatusCode) - - var hold *wallet.DebitHold - switch expectedStatusCode { - case http.StatusCreated: - hold = &wallet.DebitHold{} - readResponse(t, rec, hold) - case http.StatusNoContent: - default: - errorResponse := readErrorResponse(t, rec) - require.Equal(t, testCase.expectedErrorCode, errorResponse.ErrorCode) - return - } - - if testCase.expectedPostTransaction != nil { - expectedPostTransaction := testCase.expectedPostTransaction(testEnv, walletID, hold) - compareJSON(t, expectedPostTransaction, postTransaction) - } - - if testCase.request.Pending { - require.Equal(t, walletID, hold.WalletID) - require.Equal(t, testCase.request.Amount.Asset, hold.Asset) - } - }) - } -} diff --git a/ee/wallets/pkg/api/handler_wallets_get.go b/ee/wallets/pkg/api/handler_wallets_get.go deleted file mode 100644 index a5dcc93ddb..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_get.go +++ /dev/null @@ -1,24 +0,0 @@ -package api - -import ( - "errors" - "net/http" - - wallet "github.com/formancehq/wallets/pkg" - "github.com/go-chi/chi/v5" -) - -func (m *MainHandler) getWalletHandler(wr http.ResponseWriter, r *http.Request) { - w, err := m.manager.GetWallet(r.Context(), chi.URLParam(r, "walletID")) - if err != nil { - switch { - case errors.Is(err, wallet.ErrWalletNotFound): - notFound(wr) - default: - internalError(wr, r, err) - } - return - } - - ok(wr, w) -} diff --git a/ee/wallets/pkg/api/handler_wallets_get_test.go b/ee/wallets/pkg/api/handler_wallets_get_test.go deleted file mode 100644 index 917a5d6cf6..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_get_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package api - -import ( - "context" - "math/big" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestWalletsGet(t *testing.T) { - t.Parallel() - - w := wallet.NewWallet(uuid.NewString(), "default", metadata.Metadata{}) - balances := map[string]*big.Int{ - "USD": big.NewInt(100), - } - - req := newRequest(t, http.MethodGet, "/wallets/"+w.ID, nil) - rec := httptest.NewRecorder() - - var testEnv *testEnv - testEnv = newTestEnv( - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, testEnv.Chart().GetMainBalanceAccount(w.ID), account) - - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: account, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(w.LedgerMetadata()), - }, - Balances: balances, - }, nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - walletWithBalances := wallet.Wallet{} - readResponse(t, rec, &walletWithBalances) - cp := w - cp.Balances = balances - require.Equal(t, cp, walletWithBalances) -} diff --git a/ee/wallets/pkg/api/handler_wallets_list.go b/ee/wallets/pkg/api/handler_wallets_list.go deleted file mode 100644 index 6eee169e2b..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_list.go +++ /dev/null @@ -1,24 +0,0 @@ -package api - -import ( - "net/http" - - wallet "github.com/formancehq/wallets/pkg" -) - -func (m *MainHandler) listWalletsHandler(w http.ResponseWriter, r *http.Request) { - query := readPaginatedRequest[wallet.ListWallets](r, func(r *http.Request) wallet.ListWallets { - return wallet.ListWallets{ - Metadata: getQueryMap(r.URL.Query(), "metadata"), - Name: r.URL.Query().Get("name"), - ExpandBalances: r.URL.Query().Get("expand") == "balances", - } - }) - response, err := m.manager.ListWallets(r.Context(), query) - if err != nil { - internalError(w, r, err) - return - } - - cursorFromListResponse(w, query, response) -} diff --git a/ee/wallets/pkg/api/handler_wallets_list_test.go b/ee/wallets/pkg/api/handler_wallets_list_test.go deleted file mode 100644 index fad5b89620..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_list_test.go +++ /dev/null @@ -1,194 +0,0 @@ -package api - -import ( - "context" - "fmt" - "net/http" - "net/http/httptest" - "strconv" - "testing" - - sharedapi "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/formancehq/go-libs/pointer" - - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestWalletsList(t *testing.T) { - t.Parallel() - - var wallets []wallet.Wallet - for i := 0; i < 10; i++ { - wallets = append(wallets, wallet.NewWallet(uuid.NewString(), "default", metadata.Metadata{})) - } - const pageSize = 2 - numberOfPages := int64(len(wallets) / pageSize) - - var testEnv *testEnv - testEnv = newTestEnv( - WithListAccounts(func(ctx context.Context, ledger string, query wallet.ListAccountsQuery) (*wallet.AccountsCursorResponseCursor, error) { - if query.Cursor != "" { - page, err := strconv.ParseInt(query.Cursor, 10, 64) - if err != nil { - panic(err) - } - - if page >= numberOfPages-1 { - return &wallet.AccountsCursorResponseCursor{}, nil - } - hasMore := page < numberOfPages-1 - previous := fmt.Sprint(page - 1) - next := fmt.Sprint(page + 1) - accounts := make([]wallet.AccountWithVolumesAndBalances, 0) - for _, w := range wallets[page*pageSize : (page+1)*pageSize] { - accounts = append(accounts, wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetMainBalanceAccount(w.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(w.LedgerMetadata()), - }, - }) - } - - return &wallet.AccountsCursorResponseCursor{ - PageSize: pageSize, - HasMore: hasMore, - Previous: pointer.For(previous), - Next: pointer.For(next), - Data: accounts, - }, nil - } - - require.Equal(t, pageSize, query.Limit) - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, metadata.Metadata{ - wallet.MetadataKeyWalletSpecType: wallet.PrimaryWallet, - }, query.Metadata) - - next := "1" - accounts := make([]wallet.AccountWithVolumesAndBalances, 0) - for _, w := range wallets[:pageSize] { - accounts = append(accounts, wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: testEnv.Chart().GetMainBalanceAccount(w.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(w.LedgerMetadata()), - }, - }) - } - - return &wallet.AccountsCursorResponseCursor{ - PageSize: pageSize, - HasMore: true, - Next: pointer.For(next), - Data: accounts, - }, nil - }), - ) - - req := newRequest(t, http.MethodGet, fmt.Sprintf("/wallets?pageSize=%d", pageSize), nil) - rec := httptest.NewRecorder() - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - cursor := &sharedapi.Cursor[wallet.Wallet]{} - readCursor(t, rec, cursor) - require.Len(t, cursor.Data, pageSize) - require.EqualValues(t, wallets[:pageSize], cursor.Data) - - req = newRequest(t, http.MethodGet, fmt.Sprintf("/wallets?cursor=%s", cursor.Next), nil) - rec = httptest.NewRecorder() - testEnv.Router().ServeHTTP(rec, req) - cursor = &sharedapi.Cursor[wallet.Wallet]{} - readCursor(t, rec, cursor) - require.Len(t, cursor.Data, pageSize) - require.EqualValues(t, cursor.Data, wallets[pageSize:pageSize*2]) -} - -func TestWalletsListByName(t *testing.T) { - t.Parallel() - - var wallets []wallet.Wallet - for i := 0; i < 10; i++ { - wallets = append(wallets, wallet.NewWallet(uuid.NewString(), "default", metadata.Metadata{})) - } - - var testEnv *testEnv - testEnv = newTestEnv( - WithListAccounts(func(ctx context.Context, ledger string, query wallet.ListAccountsQuery) (*wallet.AccountsCursorResponseCursor, error) { - require.Equal(t, defaultLimit, query.Limit) - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, metadata.Metadata{ - wallet.MetadataKeyWalletSpecType: wallet.PrimaryWallet, - wallet.MetadataKeyWalletName: wallets[1].Name, - }, query.Metadata) - - return &wallet.AccountsCursorResponseCursor{ - PageSize: defaultLimit, - HasMore: false, - Data: []wallet.AccountWithVolumesAndBalances{{ - Account: wallet.Account{ - Address: testEnv.Chart().GetMainBalanceAccount(wallets[1].ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallets[1].LedgerMetadata()), - }, - }}, - }, nil - }), - ) - - req := newRequest(t, http.MethodGet, fmt.Sprintf("/wallets?name=%s", wallets[1].Name), nil) - rec := httptest.NewRecorder() - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - cursor := &sharedapi.Cursor[wallet.Wallet]{} - readCursor(t, rec, cursor) - require.Len(t, cursor.Data, 1) - require.EqualValues(t, wallets[1], cursor.Data[0]) -} - -func TestWalletsListFilterMetadata(t *testing.T) { - t.Parallel() - - var wallets []wallet.Wallet - for i := 0; i < 10; i++ { - wallets = append(wallets, wallet.NewWallet(uuid.NewString(), "default", metadata.Metadata{ - "wallet": fmt.Sprint(i), - })) - } - - var testEnv *testEnv - testEnv = newTestEnv( - WithListAccounts(func(ctx context.Context, ledger string, query wallet.ListAccountsQuery) (*wallet.AccountsCursorResponseCursor, error) { - require.Equal(t, defaultLimit, query.Limit) - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, metadata.Metadata{ - wallet.MetadataKeyWalletSpecType: wallet.PrimaryWallet, - }.Merge(wallet.EncodeCustomMetadata(map[string]string{ - "wallet": "2", - })), query.Metadata) - - return &wallet.AccountsCursorResponseCursor{ - PageSize: defaultLimit, - Data: []wallet.AccountWithVolumesAndBalances{{ - Account: wallet.Account{ - Address: testEnv.Chart().GetMainBalanceAccount(wallets[2].ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(wallets[2].LedgerMetadata()), - }, - }}, - }, nil - }), - ) - - req := newRequest(t, http.MethodGet, "/wallets?metadata[wallet]=2", nil) - rec := httptest.NewRecorder() - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - cursor := &sharedapi.Cursor[wallet.Wallet]{} - readCursor(t, rec, cursor) - require.Len(t, cursor.Data, 1) - require.EqualValues(t, wallets[2], cursor.Data[0]) -} diff --git a/ee/wallets/pkg/api/handler_wallets_patch.go b/ee/wallets/pkg/api/handler_wallets_patch.go deleted file mode 100644 index d9c9b37bdf..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_patch.go +++ /dev/null @@ -1,34 +0,0 @@ -package api - -import ( - "errors" - "net/http" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/api" - - wallet "github.com/formancehq/wallets/pkg" - "github.com/go-chi/render" -) - -func (m *MainHandler) patchWalletHandler(w http.ResponseWriter, r *http.Request) { - data := &wallet.PatchRequest{} - if err := render.Bind(r, data); err != nil { - badRequest(w, ErrorCodeValidation, err) - return - } - - err := m.manager.UpdateWallet(r.Context(), chi.URLParam(r, "walletID"), api.IdempotencyKeyFromRequest(r), data) - if err != nil { - switch { - case errors.Is(err, wallet.ErrWalletNotFound): - notFound(w) - default: - internalError(w, r, err) - } - return - } - - noContent(w) -} diff --git a/ee/wallets/pkg/api/handler_wallets_patch_test.go b/ee/wallets/pkg/api/handler_wallets_patch_test.go deleted file mode 100644 index a5bc86d243..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_patch_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package api - -import ( - "context" - "net/http" - "net/http/httptest" - "testing" - "time" - - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestWalletsPatch(t *testing.T) { - t.Parallel() - - patchWalletRequest := wallet.PatchRequest{ - Metadata: metadata.Metadata{ - "role": "admin", - "foo": "baz", - }, - } - w := wallet.NewWallet(uuid.NewString(), "default", metadata.Metadata{ - "foo": "bar", - }) - - req := newRequest(t, http.MethodPatch, "/wallets/"+w.ID, patchWalletRequest) - rec := httptest.NewRecorder() - - var testEnv *testEnv - testEnv = newTestEnv( - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, testEnv.Chart().GetMainBalanceAccount(w.ID), account) - - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: account, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(w.LedgerMetadata()), - }, - }, nil - }), - WithAddMetadataToAccount(func(ctx context.Context, ledger, account, ik string, md map[string]string) error { - require.Equal(t, testEnv.LedgerName(), ledger) - require.Equal(t, testEnv.Chart().GetMainBalanceAccount(w.ID), account) - compareJSON(t, metadata.Metadata{ - wallet.MetadataKeyWalletID: w.ID, - wallet.MetadataKeyWalletName: w.Name, - wallet.MetadataKeyWalletSpecType: wallet.PrimaryWallet, - wallet.MetadataKeyBalanceName: wallet.MainBalance, - wallet.MetadataKeyWalletBalance: wallet.TrueValue, - wallet.MetadataKeyCreatedAt: w.CreatedAt.UTC().Format(time.RFC3339Nano), - }.Merge(wallet.EncodeCustomMetadata(map[string]string{ - "role": "admin", - "foo": "baz", - })), md) - return nil - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusNoContent, rec.Result().StatusCode) -} diff --git a/ee/wallets/pkg/api/handler_wallets_summary.go b/ee/wallets/pkg/api/handler_wallets_summary.go deleted file mode 100644 index 40efcfd3a4..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_summary.go +++ /dev/null @@ -1,17 +0,0 @@ -package api - -import ( - "net/http" - - "github.com/go-chi/chi/v5" -) - -func (m *MainHandler) walletSummaryHandler(w http.ResponseWriter, r *http.Request) { - summary, err := m.manager.GetWalletSummary(r.Context(), chi.URLParam(r, "walletID")) - if err != nil { - internalError(w, r, err) - return - } - - ok(w, summary) -} diff --git a/ee/wallets/pkg/api/handler_wallets_summary_test.go b/ee/wallets/pkg/api/handler_wallets_summary_test.go deleted file mode 100644 index 91618aa8c0..0000000000 --- a/ee/wallets/pkg/api/handler_wallets_summary_test.go +++ /dev/null @@ -1,181 +0,0 @@ -package api - -import ( - "context" - "math/big" - "net/http" - "net/http/httptest" - "testing" - - "github.com/formancehq/go-libs/time" - - "github.com/formancehq/go-libs/metadata" - wallet "github.com/formancehq/wallets/pkg" - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestWalletSummary(t *testing.T) { - t.Parallel() - - w := wallet.NewWallet(uuid.NewString(), "default", metadata.Metadata{}) - - req := newRequest(t, http.MethodGet, "/wallets/"+w.ID+"/summary", nil) - rec := httptest.NewRecorder() - - coupon1Balance := wallet.NewBalance("coupon1", ptr(time.Now().Add(-time.Minute).Round(time.Second).UTC())) - coupon2Balance := wallet.NewBalance("coupon2", ptr(time.Now().Add(time.Minute).Round(time.Second).UTC())) - hold1 := wallet.NewDebitHold(w.ID, wallet.NewLedgerAccountSubject("bank"), "USD", "", metadata.Metadata{}) - hold2 := wallet.NewDebitHold(w.ID, wallet.NewLedgerAccountSubject("bank"), "USD", "", metadata.Metadata{}) - - var testEnv *testEnv - testEnv = newTestEnv( - WithGetAccount(func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - require.Equal(t, testEnv.LedgerName(), ledger) - switch account { - case testEnv.Chart().GetMainBalanceAccount(w.ID): - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: account, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(w.LedgerMetadata()), - }, - Balances: map[string]*big.Int{ - "USD": big.NewInt(100), - }, - }, nil - case testEnv.Chart().GetBalanceAccount(w.ID, coupon1Balance.Name): - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: account, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(coupon1Balance.LedgerMetadata(w.ID)), - }, - Balances: map[string]*big.Int{ - "USD": big.NewInt(10), - }, - }, nil - case testEnv.Chart().GetBalanceAccount(w.ID, coupon2Balance.Name): - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: account, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(coupon2Balance.LedgerMetadata(w.ID)), - }, - Balances: map[string]*big.Int{ - "USD": big.NewInt(20), - }, - }, nil - case testEnv.Chart().GetHoldAccount(hold1.ID): - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: account, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold1.LedgerMetadata(testEnv.Chart())), - }, - Balances: map[string]*big.Int{ - "USD": big.NewInt(10), - }, - }, nil - case testEnv.Chart().GetHoldAccount(hold2.ID): - return &wallet.AccountWithVolumesAndBalances{ - Account: wallet.Account{ - Address: account, - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold2.LedgerMetadata(testEnv.Chart())), - }, - Balances: map[string]*big.Int{ - "USD": big.NewInt(20), - }, - }, nil - default: - require.Fail(t, "unexpected account query") - } - panic("should not happen") - }), - WithListAccounts(func(ctx context.Context, ledger string, query wallet.ListAccountsQuery) (*wallet.AccountsCursorResponseCursor, error) { - switch { - case query.Metadata[wallet.MetadataKeyWalletID] == w.ID: - return &wallet.AccountsCursorResponseCursor{ - Data: []wallet.AccountWithVolumesAndBalances{ - { - Account: wallet.Account{ - Address: testEnv.Chart().GetMainBalanceAccount(w.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(w.LedgerMetadata()), - }, - }, - { - Account: wallet.Account{ - Address: testEnv.Chart().GetBalanceAccount(w.ID, "coupon1"), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(coupon1Balance.LedgerMetadata(w.ID)), - }, - }, - { - Account: wallet.Account{ - Address: testEnv.Chart().GetBalanceAccount(w.ID, "coupon2"), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(coupon2Balance.LedgerMetadata(w.ID)), - }, - }, - }, - }, nil - case query.Metadata[wallet.MetadataKeyHoldWalletID] == w.ID: - return &wallet.AccountsCursorResponseCursor{ - Data: []wallet.AccountWithVolumesAndBalances{ - { - Account: wallet.Account{ - Address: testEnv.Chart().GetHoldAccount(hold1.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold1.LedgerMetadata(testEnv.Chart())), - }, - }, - { - Account: wallet.Account{ - Address: testEnv.Chart().GetHoldAccount(hold2.ID), - Metadata: metadataWithExpectingTypesAfterUnmarshalling(hold2.LedgerMetadata(testEnv.Chart())), - }, - }, - }, - }, nil - default: - require.Fail(t, "unexpected list accounts query") - } - panic("should not happen") - }), - ) - testEnv.Router().ServeHTTP(rec, req) - - require.Equal(t, http.StatusOK, rec.Result().StatusCode) - summary := wallet.Summary{} - readResponse(t, rec, &summary) - - require.Equal(t, wallet.Summary{ - Balances: []wallet.ExpandedBalance{ - { - Balance: wallet.Balance{ - Name: "main", - }, - Assets: map[string]*big.Int{ - "USD": big.NewInt(100), - }, - }, - { - Balance: coupon1Balance, - Assets: map[string]*big.Int{ - "USD": big.NewInt(10), - }, - }, - { - Balance: coupon2Balance, - Assets: map[string]*big.Int{ - "USD": big.NewInt(20), - }, - }, - }, - AvailableFunds: map[string]*big.Int{ - "USD": big.NewInt(120), - }, - ExpiredFunds: map[string]*big.Int{ - "USD": big.NewInt(10), - }, - ExpirableFunds: map[string]*big.Int{ - "USD": big.NewInt(20), - }, - HoldFunds: map[string]*big.Int{ - "USD": big.NewInt(30), - }, - }, summary) -} diff --git a/ee/wallets/pkg/api/main.go b/ee/wallets/pkg/api/main.go deleted file mode 100644 index fb8c712780..0000000000 --- a/ee/wallets/pkg/api/main.go +++ /dev/null @@ -1,15 +0,0 @@ -package api - -import ( - wallet "github.com/formancehq/wallets/pkg" -) - -type MainHandler struct { - manager *wallet.Manager -} - -func NewMainHandler(funding *wallet.Manager) *MainHandler { - return &MainHandler{ - manager: funding, - } -} diff --git a/ee/wallets/pkg/api/module.go b/ee/wallets/pkg/api/module.go deleted file mode 100644 index e27ad79320..0000000000 --- a/ee/wallets/pkg/api/module.go +++ /dev/null @@ -1,21 +0,0 @@ -package api - -import ( - sharedapi "github.com/formancehq/go-libs/api" - sharedhealth "github.com/formancehq/go-libs/health" - "github.com/formancehq/go-libs/httpserver" - "github.com/go-chi/chi/v5" - "go.uber.org/fx" -) - -func Module(serviceInfo sharedapi.ServiceInfo, listen string) fx.Option { - return fx.Module( - "api", - fx.Provide(NewRouter), - fx.Supply(serviceInfo), - sharedhealth.Module(), - fx.Invoke(func(lc fx.Lifecycle, router *chi.Mux) { - lc.Append(httpserver.NewHook(router, httpserver.WithAddress(listen))) - }), - ) -} diff --git a/ee/wallets/pkg/api/router.go b/ee/wallets/pkg/api/router.go deleted file mode 100644 index 883c038d48..0000000000 --- a/ee/wallets/pkg/api/router.go +++ /dev/null @@ -1,71 +0,0 @@ -package api - -import ( - "net/http" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/service" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/go-libs/auth" - sharedhealth "github.com/formancehq/go-libs/health" - wallet "github.com/formancehq/wallets/pkg" - "github.com/go-chi/chi/v5/middleware" -) - -func NewRouter( - manager *wallet.Manager, - healthController *sharedhealth.HealthController, - serviceInfo sharedapi.ServiceInfo, - authenticator auth.Authenticator, -) *chi.Mux { - r := chi.NewRouter() - - r.Use(func(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - handler.ServeHTTP(w, r) - }) - }) - - r.Get("/_healthcheck", healthController.Check) - r.Get("/_info", sharedapi.InfoHandler(serviceInfo)) - r.Group(func(r chi.Router) { - r.Use(auth.Middleware(authenticator)) - r.Use(service.OTLPMiddleware("wallets", serviceInfo.Debug)) - r.Use(middleware.AllowContentType("application/json")) - - main := NewMainHandler(manager) - - r.Route("/wallets", func(r chi.Router) { - r.Get("/", main.listWalletsHandler) - r.Post("/", main.createWalletHandler) - r.Route("/{walletID}", func(r chi.Router) { - r.Get("/summary", main.walletSummaryHandler) - r.Get("/", main.getWalletHandler) - r.Patch("/", main.patchWalletHandler) - r.Post("/debit", main.debitWalletHandler) - r.Post("/credit", main.creditWalletHandler) - r.Route("/balances", func(r chi.Router) { - r.Get("/", main.listBalancesHandler) - r.Post("/", main.createBalanceHandler) - r.Get("/{balanceName}", main.getBalanceHandler) - }) - }) - }) - r.Route("/transactions", func(r chi.Router) { - r.Get("/", main.listTransactions) - }) - r.Route("/holds", func(r chi.Router) { - r.Get("/", main.listHoldsHandler) - r.Route("/{holdID}", func(r chi.Router) { - r.Get("/", main.getHoldHandler) - r.Post("/confirm", main.confirmHoldHandler) - r.Post("/void", main.voidHoldHandler) - }) - }) - }) - - return r -} diff --git a/ee/wallets/pkg/api/utils.go b/ee/wallets/pkg/api/utils.go deleted file mode 100644 index efb46e45a3..0000000000 --- a/ee/wallets/pkg/api/utils.go +++ /dev/null @@ -1,121 +0,0 @@ -package api - -import ( - "encoding/json" - "io" - "net/http" - "strconv" - "strings" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - sharedapi "github.com/formancehq/go-libs/api" - sharedlogging "github.com/formancehq/go-libs/logging" - wallet "github.com/formancehq/wallets/pkg" -) - -const defaultLimit = 15 - -func notFound(w http.ResponseWriter) { - w.WriteHeader(http.StatusNotFound) -} - -func noContent(w http.ResponseWriter) { - w.WriteHeader(http.StatusNoContent) -} - -func badRequest(w http.ResponseWriter, code string, err error) { - w.WriteHeader(http.StatusBadRequest) - if err := json.NewEncoder(w).Encode(sharedapi.ErrorResponse{ - ErrorCode: code, - ErrorMessage: err.Error(), - }); err != nil { - panic(err) - } -} - -func internalError(w http.ResponseWriter, r *http.Request, err error) { - sharedlogging.FromContext(r.Context()).Error(err) - - w.WriteHeader(http.StatusInternalServerError) - if err := json.NewEncoder(w).Encode(sharedapi.ErrorResponse{ - ErrorCode: "INTERNAL_ERROR", - ErrorMessage: err.Error(), - }); err != nil { - panic(err) - } -} - -func created(w http.ResponseWriter, v any) { - w.WriteHeader(http.StatusCreated) - ok(w, v) -} - -func ok(w io.Writer, v any) { - if err := json.NewEncoder(w).Encode(sharedapi.BaseResponse[any]{ - Data: &v, - }); err != nil { - panic(err) - } -} - -func cursor[T any](w io.Writer, v bunpaginate.Cursor[T]) { - if err := json.NewEncoder(w).Encode(sharedapi.BaseResponse[T]{ - Cursor: &v, - }); err != nil { - panic(err) - } -} - -func cursorFromListResponse[T any, V any](w io.Writer, query wallet.ListQuery[V], response *wallet.ListResponse[T]) { - cursor(w, bunpaginate.Cursor[T]{ - PageSize: query.Limit, - HasMore: response.HasMore, - Previous: response.Previous, - Next: response.Next, - Data: response.Data, - }) -} - -func parsePaginationToken(r *http.Request) string { - return r.URL.Query().Get("cursor") -} - -func parsePageSize(r *http.Request) int { - pageSize := r.URL.Query().Get("pageSize") - if pageSize == "" { - return defaultLimit - } - - v, err := strconv.ParseInt(pageSize, 10, 32) - if err != nil { - panic(err) - } - return int(v) -} - -func readPaginatedRequest[T any](r *http.Request, f func(r *http.Request) T) wallet.ListQuery[T] { - var payload T - if f != nil { - payload = f(r) - } - return wallet.ListQuery[T]{ - Pagination: wallet.Pagination{ - Limit: parsePageSize(r), - PaginationToken: parsePaginationToken(r), - }, - Payload: payload, - } -} - -func getQueryMap(m map[string][]string, key string) map[string]string { - dicts := make(map[string]string) - for k, v := range m { - if i := strings.IndexByte(k, '['); i >= 1 && k[0:i] == key { - if j := strings.IndexByte(k[i+1:], ']'); j >= 1 { - dicts[k[i+1:][:j]] = v[0] - } - } - } - return dicts -} diff --git a/ee/wallets/pkg/api/utils_test.go b/ee/wallets/pkg/api/utils_test.go deleted file mode 100644 index 3863a783ad..0000000000 --- a/ee/wallets/pkg/api/utils_test.go +++ /dev/null @@ -1,176 +0,0 @@ -package api - -import ( - "bytes" - "context" - "encoding/json" - "io" - "net/http" - "net/http/httptest" - "reflect" - "testing" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/bun/bunpaginate" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - - sharedapi "github.com/formancehq/go-libs/api" - "github.com/formancehq/go-libs/auth" - sharedhealth "github.com/formancehq/go-libs/health" - wallet "github.com/formancehq/wallets/pkg" - "github.com/stretchr/testify/require" -) - -func readErrorResponse(t *testing.T, rec *httptest.ResponseRecorder) *sharedapi.ErrorResponse { - t.Helper() - ret := &sharedapi.ErrorResponse{} - require.NoError(t, json.NewDecoder(rec.Body).Decode(ret)) - return ret -} - -func readResponse[T any](t *testing.T, rec *httptest.ResponseRecorder, to T) { - t.Helper() - ret := &sharedapi.BaseResponse[T]{} - require.NoError(t, json.NewDecoder(rec.Body).Decode(ret)) - reflect.ValueOf(to).Elem().Set(reflect.ValueOf(*ret.Data).Elem()) -} - -func readCursor[T any](t *testing.T, rec *httptest.ResponseRecorder, to *bunpaginate.Cursor[T]) { - t.Helper() - ret := &sharedapi.BaseResponse[T]{} - require.NoError(t, json.NewDecoder(rec.Body).Decode(ret)) - reflect.ValueOf(to).Elem().Set(reflect.ValueOf(ret.Cursor).Elem()) -} - -func bufFromObject(t *testing.T, v any) *bytes.Buffer { - t.Helper() - data, err := json.Marshal(v) - require.NoError(t, err) - return bytes.NewBuffer(data) -} - -func newRequest(t *testing.T, method, path string, object any) *http.Request { - t.Helper() - var reader io.Reader - if object != nil { - reader = bufFromObject(t, object) - } - req := httptest.NewRequest(method, path, reader) - req.Header.Set("Content-Type", "application/json") - return req -} - -type testEnv struct { - router chi.Router - ledgerName string - chart *wallet.Chart -} - -func (e testEnv) Router() chi.Router { - return e.router -} - -func (e testEnv) LedgerName() string { - return e.ledgerName -} - -func (e testEnv) Chart() *wallet.Chart { - return e.chart -} - -func newTestEnv(opts ...Option) *testEnv { - ret := &testEnv{} - ledgerMock := NewLedgerMock(opts...) - ret.chart = wallet.NewChart("") - ret.ledgerName = "default" - manager := wallet.NewManager(ret.ledgerName, ledgerMock, ret.chart) - ret.router = NewRouter(manager, &sharedhealth.HealthController{}, sharedapi.ServiceInfo{ - Version: "latest", - Debug: testing.Verbose(), - }, auth.NewNoAuth()) - return ret -} - -type ( - addMetadataToAccountFn func(ctx context.Context, ledger, account, ik string, metadata map[string]string) error - getAccountFn func(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) - listAccountsFn func(ctx context.Context, ledger string, query wallet.ListAccountsQuery) (*wallet.AccountsCursorResponseCursor, error) - listTransactionsFn func(ctx context.Context, ledger string, query wallet.ListTransactionsQuery) (*shared.V2TransactionsCursorResponseCursor, error) - createTransactionFn func(ctx context.Context, ledger, ik string, postTransaction wallet.PostTransaction) (*shared.V2Transaction, error) -) - -type LedgerMock struct { - addMetadataToAccount addMetadataToAccountFn - getAccount getAccountFn - listAccounts listAccountsFn - listTransactions listTransactionsFn - createTransaction createTransactionFn -} - -func (l *LedgerMock) EnsureLedgerExists(ctx context.Context, name string) error { - return nil -} - -func (l *LedgerMock) AddMetadataToAccount(ctx context.Context, ledger, account, ik string, metadata map[string]string) error { - return l.addMetadataToAccount(ctx, ledger, account, ik, metadata) -} - -func (l *LedgerMock) GetAccount(ctx context.Context, ledger, account string) (*wallet.AccountWithVolumesAndBalances, error) { - return l.getAccount(ctx, ledger, account) -} - -func (l *LedgerMock) ListAccounts(ctx context.Context, ledger string, query wallet.ListAccountsQuery) (*wallet.AccountsCursorResponseCursor, error) { - return l.listAccounts(ctx, ledger, query) -} - -func (l *LedgerMock) CreateTransaction(ctx context.Context, ledger, ik string, postTransaction wallet.PostTransaction) (*shared.V2Transaction, error) { - return l.createTransaction(ctx, ledger, ik, postTransaction) -} - -func (l *LedgerMock) ListTransactions(ctx context.Context, ledger string, query wallet.ListTransactionsQuery) (*shared.V2TransactionsCursorResponseCursor, error) { - return l.listTransactions(ctx, ledger, query) -} - -var _ wallet.Ledger = &LedgerMock{} - -type Option func(mock *LedgerMock) - -func WithCreateTransaction(fn createTransactionFn) Option { - return func(mock *LedgerMock) { - mock.createTransaction = fn - } -} - -func WithAddMetadataToAccount(fn addMetadataToAccountFn) Option { - return func(mock *LedgerMock) { - mock.addMetadataToAccount = fn - } -} - -func WithGetAccount(fn getAccountFn) Option { - return func(mock *LedgerMock) { - mock.getAccount = fn - } -} - -func WithListAccounts(fn listAccountsFn) Option { - return func(mock *LedgerMock) { - mock.listAccounts = fn - } -} - -func WithListTransactions(fn listTransactionsFn) Option { - return func(mock *LedgerMock) { - mock.listTransactions = fn - } -} - -func NewLedgerMock(opts ...Option) *LedgerMock { - ret := &LedgerMock{} - for _, opt := range opts { - opt(ret) - } - return ret -} diff --git a/ee/wallets/pkg/balance.go b/ee/wallets/pkg/balance.go deleted file mode 100644 index 5bab2602d3..0000000000 --- a/ee/wallets/pkg/balance.go +++ /dev/null @@ -1,138 +0,0 @@ -package wallet - -import ( - "fmt" - "math/big" - "net/http" - "regexp" - "strconv" - - "github.com/go-chi/chi/v5" - - "github.com/formancehq/go-libs/time" -) - -var balanceNameRegex = regexp.MustCompile("[0-9A-Za-z_-]+") - -type CreateBalance struct { - WalletID string `json:"walletID"` - Name string `json:"name"` - ExpiresAt *time.Time `json:"expiresAt,omitempty"` - Priority int `json:"priority"` -} - -func (c *CreateBalance) Validate() error { - if !balanceNameRegex.MatchString(c.Name) { - return ErrInvalidBalanceName - } - if c.Name == MainBalance { - return ErrReservedBalanceName - } - return nil -} - -func (c *CreateBalance) Bind(r *http.Request) error { - c.WalletID = chi.URLParam(r, "walletID") - return nil -} - -type Balance struct { - Name string `json:"name,omitempty"` - ExpiresAt *time.Time `json:"expiresAt"` - Priority int `json:"priority"` -} - -func (b Balance) LedgerMetadata(walletID string) map[string]string { - m := map[string]string{ - MetadataKeyWalletID: walletID, - MetadataKeyWalletBalance: TrueValue, - MetadataKeyBalanceName: b.Name, - MetadataKeyBalanceExpiresAt: "", - MetadataKeyBalancePriority: fmt.Sprint(b.Priority), - } - if b.ExpiresAt != nil { - m[MetadataKeyBalanceExpiresAt] = b.ExpiresAt.Format(time.RFC3339Nano) - } - return m -} - -func NewBalance(name string, expiresAt *time.Time) Balance { - return Balance{ - Name: name, - ExpiresAt: expiresAt, - } -} - -type Balances []Balance - -func (b Balances) Len() int { - return len(b) -} - -func (b Balances) Less(i, j int) bool { - switch { - case b[i].Name == "main": - return false - case b[j].Name == "main": - return true - case b[i].ExpiresAt == nil && b[j].ExpiresAt != nil: - return false - case b[i].ExpiresAt != nil && b[j].ExpiresAt == nil: - return true - case b[i].ExpiresAt != nil && b[j].ExpiresAt != nil: - return b[i].ExpiresAt.Before(*b[j].ExpiresAt) - case b[i].ExpiresAt == nil && b[j].ExpiresAt == nil: - return b[i].Priority < b[j].Priority - } - panic("Should not happen") -} - -func (b Balances) Swap(i, j int) { - b[i], b[j] = b[j], b[i] -} - -func BalanceFromAccount(account interface { - MetadataOwner - GetAddress() string - GetBalances() map[string]*big.Int -}) Balance { - expiresAtRaw := GetMetadata(account, MetadataKeyBalanceExpiresAt) - var expiresAt *time.Time - if expiresAtRaw != "" { - parsedExpiresAt, err := time.ParseTime(expiresAtRaw) - if err != nil { - panic(err) - } - expiresAt = &parsedExpiresAt - } - var priority int64 - priorityRaw := GetMetadata(account, MetadataKeyBalancePriority) - if priorityRaw != "" { - var err error - priority, err = strconv.ParseInt(priorityRaw, 10, 64) - if err != nil { - panic(err) - } - } - return Balance{ - Name: GetMetadata(account, MetadataKeyBalanceName), - ExpiresAt: expiresAt, - Priority: int(priority), - } -} - -type ExpandedBalance struct { - Balance - Assets map[string]*big.Int `json:"assets"` -} - -func ExpandedBalanceFromAccount(account interface { - MetadataOwner - GetAddress() string - GetBalances() map[string]*big.Int -}) ExpandedBalance { - return ExpandedBalance{ - Balance: BalanceFromAccount(account), - Assets: account.GetBalances(), - } -} diff --git a/ee/wallets/pkg/chart.go b/ee/wallets/pkg/chart.go deleted file mode 100644 index d4ec6b036b..0000000000 --- a/ee/wallets/pkg/chart.go +++ /dev/null @@ -1,55 +0,0 @@ -package wallet - -import ( - "strings" -) - -const MainBalance = "main" - -type Address []string - -func (addr Address) String() string { - s := strings.Join(addr, ":") - s = strings.ReplaceAll(s, "-", "") - - return s -} - -type Chart struct { - Prefix string -} - -func NewChart(prefix string) *Chart { - return &Chart{Prefix: prefix} -} - -func (c *Chart) BasePath() Address { - addr := Address{} - - if c.Prefix != "" { - addr = append(addr, c.Prefix) - } - - addr = append(addr, "wallets") - - return addr -} - -func (c *Chart) GetMainBalanceAccount(walletID string) string { - return c.GetBalanceAccount(walletID, MainBalance) -} - -func (c *Chart) GetHoldAccount(holdID string) string { - addr := c.BasePath() - addr = append(addr, "holds") - addr = append(addr, holdID) - - return addr.String() -} - -func (c *Chart) GetBalanceAccount(walletID, balanceName string) string { - addr := c.BasePath() - addr = append(addr, walletID, balanceName) - - return addr.String() -} diff --git a/ee/wallets/pkg/credit.go b/ee/wallets/pkg/credit.go deleted file mode 100644 index 98478e2960..0000000000 --- a/ee/wallets/pkg/credit.go +++ /dev/null @@ -1,53 +0,0 @@ -package wallet - -import ( - "math/big" - "net/http" - - "github.com/formancehq/ledger/pkg/core/assets" - - "github.com/formancehq/go-libs/time" - - "github.com/formancehq/go-libs/metadata" -) - -var DefaultCreditSource = NewLedgerAccountSubject("world") - -type CreditRequest struct { - Amount Monetary `json:"amount"` - Metadata metadata.Metadata `json:"metadata"` - Sources Subjects `json:"sources"` - Reference string `json:"reference"` - Balance string `json:"balance"` - Timestamp *time.Time `json:"timestamp"` -} - -func (c *CreditRequest) Bind(r *http.Request) error { - return nil -} - -func (c CreditRequest) Validate() error { - if err := c.Sources.Validate(); err != nil { - return err - } - if c.Amount.Amount.Cmp(big.NewInt(0)) < 0 { - return ErrNegativeAmount - } - if !assets.IsValid(c.Amount.Asset) { - return newErrInvalidAsset(c.Amount.Asset) - } - - return nil -} - -type Credit struct { - CreditRequest - WalletID string `json:"walletID"` -} - -func (c Credit) destinationAccount(chart *Chart) string { - if c.Balance == "" { - return chart.GetMainBalanceAccount(c.WalletID) - } - return chart.GetBalanceAccount(c.WalletID, c.Balance) -} diff --git a/ee/wallets/pkg/debit.go b/ee/wallets/pkg/debit.go deleted file mode 100644 index 5e156adea3..0000000000 --- a/ee/wallets/pkg/debit.go +++ /dev/null @@ -1,70 +0,0 @@ -package wallet - -import ( - "math/big" - "net/http" - - "github.com/formancehq/go-libs/time" - "github.com/formancehq/ledger/pkg/core/assets" - - "github.com/formancehq/go-libs/metadata" -) - -var DefaultDebitDest = NewLedgerAccountSubject("world") - -type DebitRequest struct { - Amount Monetary `json:"amount"` - Pending bool `json:"pending"` - Metadata metadata.Metadata `json:"metadata"` - Description string `json:"description"` - Reference string `json:"reference"` - Destination *Subject `json:"destination"` - Balances []string `json:"balances"` - Timestamp *time.Time `json:"timestamp"` -} - -func (c *DebitRequest) Bind(r *http.Request) error { - return nil -} - -type Debit struct { - DebitRequest - WalletID string `json:"walletID"` -} - -func (d Debit) newHold() DebitHold { - md := d.Metadata - if md == nil { - md = metadata.Metadata{} - } - return NewDebitHold( - d.WalletID, - d.getDestination(), - d.Amount.Asset, - d.Description, - md, - ) -} - -func (d Debit) getDestination() Subject { - dest := DefaultDebitDest - if d.Destination != nil { - dest = *d.Destination - } - return dest -} - -func (d Debit) Validate() error { - if d.Destination != nil { - if err := d.Destination.Validate(); err != nil { - return err - } - } - if d.Amount.Amount.Cmp(big.NewInt(0)) < 0 { - return ErrNegativeAmount - } - if !assets.IsValid(d.Amount.Asset) { - return newErrInvalidAsset(d.Amount.Asset) - } - return nil -} diff --git a/ee/wallets/pkg/error.go b/ee/wallets/pkg/error.go deleted file mode 100644 index 8003578e8d..0000000000 --- a/ee/wallets/pkg/error.go +++ /dev/null @@ -1,66 +0,0 @@ -package wallet - -import ( - "errors" - "fmt" -) - -var ( - ErrAccountNotFound = errors.New("account not found") - ErrWalletNotFound = errors.New("wallet not found") - ErrHoldNotFound = errors.New("hold not found") - ErrInsufficientFundError = errors.New("insufficient fund") - ErrClosedHold = errors.New("closed hold") - ErrBalanceAlreadyExists = errors.New("balance already exists") - ErrInvalidBalanceName = errors.New("invalid balance name") - ErrReservedBalanceName = errors.New("reserved balance name") - ErrBalanceNotExists = errors.New("balance not exists") - ErrInvalidBalanceSpecified = errors.New("invalid balance specified") - ErrNegativeAmount = errors.New("negative amount provided") -) - -type GenericOpenAPIError interface { - Model() any -} - -type errInvalidAccountName string - -func (e errInvalidAccountName) Error() string { - return fmt.Sprintf("invalid format for account '%s'", string(e)) -} - -func (e errInvalidAccountName) Is(err error) bool { - _, ok := err.(errInvalidAccountName) - return ok -} - -func newErrInvalidAccountName(v string) errInvalidAccountName { - return errInvalidAccountName(v) -} - -var _ error = errInvalidAccountName("") - -func IsErrInvalidAccountName(err error) bool { - return errors.Is(err, errInvalidAccountName("")) -} - -type errInvalidAsset string - -func (e errInvalidAsset) Error() string { - return fmt.Sprintf("invalid format for account '%s'", string(e)) -} - -func (e errInvalidAsset) Is(err error) bool { - _, ok := err.(errInvalidAsset) - return ok -} - -func newErrInvalidAsset(v string) errInvalidAsset { - return errInvalidAsset(v) -} - -var _ error = errInvalidAsset("") - -func IsErrInvalidAsset(err error) bool { - return errors.Is(err, errInvalidAsset("")) -} diff --git a/ee/wallets/pkg/hold.go b/ee/wallets/pkg/hold.go deleted file mode 100644 index ae052579bf..0000000000 --- a/ee/wallets/pkg/hold.go +++ /dev/null @@ -1,122 +0,0 @@ -package wallet - -import ( - "math/big" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - - "github.com/formancehq/go-libs/metadata" - "github.com/google/uuid" -) - -type DebitHold struct { - ID string `json:"id"` - WalletID string `json:"walletID"` - Destination Subject `json:"destination"` - Asset string `json:"asset"` - Metadata metadata.Metadata `json:"metadata"` - Description string `json:"description"` -} - -func (h DebitHold) LedgerMetadata(chart *Chart) map[string]string { - - return metadata.Metadata{ - MetadataKeyWalletSpecType: HoldWallet, - MetadataKeyHoldWalletID: h.WalletID, - MetadataKeyHoldID: h.ID, - MetadataKeyHoldAsset: h.Asset, - MetadataKeyHoldVoidDestination: metadata.MarshalValue(map[string]any{ - "type": "account", - "value": chart.GetMainBalanceAccount(h.WalletID), - }), - MetadataKeyHoldDestination: metadata.MarshalValue(map[string]any{ - "type": "account", - "value": h.Destination.getAccount(chart), - }), - MetadataKeyWalletHoldDescription: h.Description, - MetadataKeyHoldSubject: metadata.MarshalValue(map[string]any{ - "type": h.Destination.Type, - "identifier": h.Destination.Identifier, - "balance": h.Destination.Balance, - }), - }.Merge(EncodeCustomMetadata(h.Metadata)) -} - -func NewDebitHold(walletID string, destination Subject, asset, description string, md metadata.Metadata) DebitHold { - return DebitHold{ - ID: uuid.NewString(), - WalletID: walletID, - Destination: destination, - Asset: asset, - Metadata: md, - Description: description, - } -} - -func DebitHoldFromLedgerAccount(account interface { - MetadataOwner - GetAddress() string - GetBalances() map[string]*big.Int -}) DebitHold { - destination := metadata.UnmarshalValue[metadata.Metadata](account.GetMetadata()[MetadataKeyHoldSubject]) - - hold := DebitHold{} - hold.ID = account.GetMetadata()[MetadataKeyHoldID] - hold.WalletID = account.GetMetadata()[MetadataKeyHoldWalletID] - hold.Destination = Subject{ - Type: destination["type"], - Identifier: destination["identifier"], - Balance: destination["balance"], - } - hold.Asset = account.GetMetadata()[MetadataKeyHoldAsset] - hold.Description = account.GetMetadata()[MetadataKeyWalletHoldDescription] - hold.Metadata = ExtractCustomMetadata(account) - - return hold -} - -type ExpandedDebitHold struct { - DebitHold - OriginalAmount *big.Int `json:"originalAmount"` - Remaining *big.Int `json:"remaining"` -} - -func (h ExpandedDebitHold) IsClosed() bool { - return h.Remaining.Uint64() == 0 -} - -func ExpandedDebitHoldFromLedgerAccount(account interface { - MetadataOwner - GetAddress() string - GetVolumes() map[string]shared.V2Volume - GetBalances() map[string]*big.Int -}) ExpandedDebitHold { - hold := ExpandedDebitHold{ - DebitHold: DebitHoldFromLedgerAccount(account), - } - hold.OriginalAmount = account.GetVolumes()[hold.Asset].Input - hold.Remaining = account.GetBalances()[hold.Asset] - return hold -} - -type ConfirmHold struct { - HoldID string `json:"holdID"` - Amount *big.Int - Reference string - Final bool -} - -func (c ConfirmHold) resolveAmount(hold ExpandedDebitHold) (uint64, error) { - amount := hold.Remaining.Uint64() - if c.Amount.Uint64() != 0 { - if c.Amount.Uint64() > amount { - return 0, ErrInsufficientFundError - } - amount = c.Amount.Uint64() - } - return amount, nil -} - -type VoidHold struct { - HoldID string `json:"holdID"` -} diff --git a/ee/wallets/pkg/ledger_interface.go b/ee/wallets/pkg/ledger_interface.go deleted file mode 100644 index 1f3e1cc817..0000000000 --- a/ee/wallets/pkg/ledger_interface.go +++ /dev/null @@ -1,324 +0,0 @@ -package wallet - -import ( - "context" - "encoding/json" - "fmt" - "math/big" - stdtime "time" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - "github.com/pkg/errors" - - "github.com/formancehq/go-libs/query" - - "github.com/formancehq/go-libs/time" - - sdk "github.com/formancehq/formance-sdk-go/v2" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "github.com/formancehq/go-libs/collectionutils" - "github.com/formancehq/go-libs/metadata" - "github.com/formancehq/go-libs/pointer" -) - -type ListAccountsQuery struct { - Cursor string - Limit int - Metadata metadata.Metadata - ExpandVolumes bool -} - -type ListTransactionsQuery struct { - Cursor string - Limit int - Metadata metadata.Metadata - Destination string - Source string - Account string -} - -type PostTransaction struct { - Metadata map[string]string `json:"metadata,omitempty"` - Postings []shared.V2Posting `json:"postings,omitempty"` - Reference *string `json:"reference,omitempty"` - Script *shared.V2PostTransactionScript `json:"script,omitempty"` - Timestamp *time.Time `json:"timestamp,omitempty"` -} - -type Account struct { - Address string `json:"address"` - Metadata map[string]string `json:"metadata,omitempty"` -} - -func (a Account) GetMetadata() map[string]string { - return a.Metadata -} - -func (a Account) GetAddress() string { - return a.Address -} - -type AccountWithVolumesAndBalances struct { - Account - Balances map[string]*big.Int `json:"balances,omitempty"` - Volumes map[string]shared.V2Volume `json:"volumes,omitempty"` -} - -func (a AccountWithVolumesAndBalances) GetBalances() map[string]*big.Int { - return a.Balances -} - -func (a AccountWithVolumesAndBalances) GetVolumes() map[string]shared.V2Volume { - return a.Volumes -} - -type AccountsCursorResponseCursor struct { - Data []AccountWithVolumesAndBalances `json:"data"` - HasMore bool `json:"hasMore"` - Next *string `json:"next,omitempty"` - PageSize int64 `json:"pageSize"` - Previous *string `json:"previous,omitempty"` -} - -func (c AccountsCursorResponseCursor) GetNext() *string { - return c.Next -} - -func (c AccountsCursorResponseCursor) GetPrevious() *string { - return c.Previous -} - -func (c AccountsCursorResponseCursor) GetData() []AccountWithVolumesAndBalances { - return c.Data -} - -func (c AccountsCursorResponseCursor) GetHasMore() bool { - return c.HasMore -} - -type Ledger interface { - EnsureLedgerExists(ctx context.Context, name string) error - AddMetadataToAccount(ctx context.Context, ledger, account, ik string, metadata map[string]string) error - GetAccount(ctx context.Context, ledger, account string) (*AccountWithVolumesAndBalances, error) - ListAccounts(ctx context.Context, ledger string, query ListAccountsQuery) (*AccountsCursorResponseCursor, error) - ListTransactions(ctx context.Context, ledger string, query ListTransactionsQuery) (*shared.V2TransactionsCursorResponseCursor, error) - CreateTransaction(ctx context.Context, ledger, ik string, postTransaction PostTransaction) (*shared.V2Transaction, error) -} - -type DefaultLedger struct { - client *sdk.Formance -} - -func (d DefaultLedger) EnsureLedgerExists(ctx context.Context, name string) error { - _, err := d.client.Ledger.V2.GetLedger(ctx, operations.V2GetLedgerRequest{ - Ledger: name, - }) - if err == nil { - return nil - } - - switch err := err.(type) { - case *sdkerrors.V2ErrorResponse: - if err.ErrorCode != shared.V2ErrorsEnumNotFound { - return err - } - default: - return err - } - - _, err = d.client.Ledger.V2.CreateLedger(ctx, operations.V2CreateLedgerRequest{ - V2CreateLedgerRequest: &shared.V2CreateLedgerRequest{ - Bucket: pointer.For(name), - }, - Ledger: name, - }) - return err -} - -func (d DefaultLedger) ListTransactions(ctx context.Context, ledger string, q ListTransactionsQuery) (*shared.V2TransactionsCursorResponseCursor, error) { - req := operations.V2ListTransactionsRequest{ - Ledger: ledger, - } - if q.Cursor == "" { - req.PageSize = pointer.For(int64(q.Limit)) - conditions := make([]query.Builder, 0) - if q.Destination != "" { - conditions = append(conditions, query.Match("destination", q.Destination)) - } - if q.Source != "" { - conditions = append(conditions, query.Match("source", q.Source)) - } - if q.Account != "" { - conditions = append(conditions, query.Match("account", q.Account)) - } - if q.Metadata != nil { - for k, v := range q.Metadata { - conditions = append(conditions, query.Match(fmt.Sprintf("metadata[%s]", k), v)) - } - } - if len(conditions) > 0 { - data, err := json.Marshal(query.And(conditions...)) - if err != nil { - panic(err) - } - body := make(map[string]any) - if err := json.Unmarshal(data, &body); err != nil { - panic(err) - } - req.RequestBody = body - } - } else { - req.Cursor = pointer.For(q.Cursor) - } - - rsp, err := d.client.Ledger.V2.ListTransactions(ctx, req) - if err != nil { - return nil, err - } - - return &rsp.V2TransactionsCursorResponse.Cursor, nil -} - -func (d DefaultLedger) CreateTransaction(ctx context.Context, ledger, ik string, transaction PostTransaction) (*shared.V2Transaction, error) { - ret, err := d.client.Ledger.V2.CreateTransaction(ctx, operations.V2CreateTransactionRequest{ - V2PostTransaction: shared.V2PostTransaction{ - Metadata: transaction.Metadata, - Postings: transaction.Postings, - Reference: transaction.Reference, - Script: transaction.Script, - Timestamp: func() *stdtime.Time { - if transaction.Timestamp == nil { - return nil - } - return &transaction.Timestamp.Time - }(), - }, - Ledger: ledger, - IdempotencyKey: pointer.For(ik), - }) - if err != nil { - return nil, err - } - - return &ret.V2CreateTransactionResponse.Data, nil -} - -func (d DefaultLedger) AddMetadataToAccount(ctx context.Context, ledger, account, ik string, metadata map[string]string) error { - - _, err := d.client.Ledger.V2.AddMetadataToAccount(ctx, operations.V2AddMetadataToAccountRequest{ - RequestBody: metadata, - Address: account, - Ledger: ledger, - IdempotencyKey: pointer.For(ik), - }) - if err != nil { - return err - } - return nil -} - -func (d DefaultLedger) GetAccount(ctx context.Context, ledger, account string) (*AccountWithVolumesAndBalances, error) { - ret, err := d.client.Ledger.V2.GetAccount(ctx, operations.V2GetAccountRequest{ - Address: account, - Ledger: ledger, - Expand: pointer.For("volumes"), - }) - if err != nil { - switch v := err.(type) { - case *sdkerrors.V2ErrorResponse: - if v.ErrorCode == shared.V2ErrorsEnumNotFound { - return nil, errors.Wrap(ErrAccountNotFound, err.Error()) - } else { - return nil, err - } - default: - return nil, err - } - } - - balances := make(map[string]*big.Int) - for asset, volumes := range ret.V2AccountResponse.Data.Volumes { - balances[asset] = big.NewInt(0).Sub(volumes.Input, volumes.Output) - } - - return &AccountWithVolumesAndBalances{ - Account: Account{ - Address: ret.V2AccountResponse.Data.Address, - Metadata: ret.V2AccountResponse.Data.Metadata, - }, - Balances: balances, - Volumes: ret.V2AccountResponse.Data.Volumes, - }, nil -} - -func (d DefaultLedger) ListAccounts(ctx context.Context, ledger string, q ListAccountsQuery) (*AccountsCursorResponseCursor, error) { - req := operations.V2ListAccountsRequest{ - Ledger: ledger, - } - if q.Cursor == "" { - req.PageSize = pointer.For(int64(q.Limit)) - if q.ExpandVolumes { - req.Expand = pointer.For("volumes") - } - - conditions := make([]query.Builder, 0) - if q.Metadata != nil { - for k, v := range q.Metadata { - conditions = append(conditions, query.Match(fmt.Sprintf("metadata[%s]", k), v)) - } - } - if len(conditions) > 0 { - data, err := json.Marshal(query.And(conditions...)) - if err != nil { - panic(err) - } - body := make(map[string]any) - if err := json.Unmarshal(data, &body); err != nil { - panic(err) - } - req.RequestBody = body - } - } else { - req.Cursor = pointer.For(q.Cursor) - } - - ret, err := d.client.Ledger.V2.ListAccounts(ctx, req) - if err != nil { - return nil, err - } - - return &AccountsCursorResponseCursor{ - Data: collectionutils.Map(ret.V2AccountsCursorResponse.Cursor.Data, func(from shared.V2Account) AccountWithVolumesAndBalances { - return AccountWithVolumesAndBalances{ - Account: Account{ - Address: from.Address, - Metadata: from.Metadata, - }, - Balances: func() map[string]*big.Int { - if from.Volumes == nil { - return nil - } - ret := make(map[string]*big.Int) - for asset, volumes := range from.Volumes { - ret[asset] = big.NewInt(0).Sub(volumes.Input, volumes.Output) - } - return ret - }(), - Volumes: from.Volumes, - } - }), - HasMore: ret.V2AccountsCursorResponse.Cursor.HasMore, - Next: ret.V2AccountsCursorResponse.Cursor.Next, - PageSize: ret.V2AccountsCursorResponse.Cursor.PageSize, - Previous: ret.V2AccountsCursorResponse.Cursor.Previous, - }, nil -} - -var _ Ledger = &DefaultLedger{} - -func NewDefaultLedger(client *sdk.Formance) *DefaultLedger { - return &DefaultLedger{ - client: client, - } -} diff --git a/ee/wallets/pkg/manager.go b/ee/wallets/pkg/manager.go deleted file mode 100644 index 8f669bfa06..0000000000 --- a/ee/wallets/pkg/manager.go +++ /dev/null @@ -1,680 +0,0 @@ -package wallet - -import ( - "context" - "math/big" - "sort" - - "github.com/formancehq/go-libs/time" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - "github.com/formancehq/go-libs/metadata" - "github.com/pkg/errors" -) - -type ListResponse[T any] struct { - Data []T - Next, Previous string - HasMore bool -} - -type Pagination struct { - Limit int - PaginationToken string -} - -type ListQuery[T any] struct { - Pagination - Payload T -} - -type mapper[SRC any, DST any] func(src SRC) DST - -func newListResponse[SRC any, DST any](cursor interface { - GetData() []SRC - GetNext() *string - GetPrevious() *string - GetHasMore() bool -}, mapper mapper[SRC, DST], -) *ListResponse[DST] { - ret := make([]DST, 0) - for _, item := range cursor.GetData() { - ret = append(ret, mapper(item)) - } - - next := "" - if n := cursor.GetNext(); n != nil { - next = *n - } - - previous := "" - if n := cursor.GetPrevious(); n != nil { - previous = *n - } - - return &ListResponse[DST]{ - Data: ret, - Next: next, - Previous: previous, - HasMore: cursor.GetHasMore(), - } -} - -type ListHolds struct { - WalletID string - Metadata metadata.Metadata -} - -type ListBalances struct { - WalletID string - Metadata metadata.Metadata -} - -type ListTransactions struct { - WalletID string -} - -func BalancesMetadataFilter(walletID string) metadata.Metadata { - return metadata.Metadata{ - MetadataKeyWalletBalance: TrueValue, - MetadataKeyWalletID: walletID, - } -} - -type Manager struct { - client Ledger - chart *Chart - ledgerName string -} - -func NewManager( - ledgerName string, - client Ledger, - chart *Chart, -) *Manager { - return &Manager{ - client: client, - chart: chart, - ledgerName: ledgerName, - } -} - -func (m *Manager) Init(ctx context.Context) error { - return m.client.EnsureLedgerExists(ctx, m.ledgerName) -} - -//nolint:cyclop -func (m *Manager) Debit(ctx context.Context, ik string, debit Debit) (*DebitHold, error) { - if err := debit.Validate(); err != nil { - return nil, err - } - - dest := debit.getDestination() - - var ( - hold *DebitHold - metadata map[string]map[string]string - ) - if debit.Pending { - if debit.Timestamp != nil { - return nil, errors.New("timestamp cannot be specified using pending debit") - } - - hold = Ptr(debit.newHold()) - holdAccount := m.chart.GetHoldAccount(hold.ID) - metadata = map[string]map[string]string{ - holdAccount: hold.LedgerMetadata(m.chart), - } - - dest = NewLedgerAccountSubject(holdAccount) - } - - sources := make([]string, 0) - switch { - case len(debit.Balances) == 0: - sources = append(sources, m.chart.GetMainBalanceAccount(debit.WalletID)) - case len(debit.Balances) == 1 && debit.Balances[0] == "*": - balancesRaw, err := fetchAndMapAllAccounts[Balance](ctx, m, BalancesMetadataFilter(debit.WalletID), BalanceFromAccount) - if err != nil { - return nil, err - } - balances := Balances(balancesRaw) - sort.Stable(balances) - - // Filter expired and generate sources - for _, balance := range balances { - if balance.ExpiresAt != nil && balance.ExpiresAt.Before(time.Now()) { - continue - } - sources = append(sources, m.chart.GetBalanceAccount(debit.WalletID, balance.Name)) - } - default: - for _, balance := range debit.Balances { - if balance == "*" { - return nil, ErrInvalidBalanceSpecified - } - sources = append(sources, m.chart.GetBalanceAccount(debit.WalletID, balance)) - } - } - - postTransaction := PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: BuildDebitWalletScript(metadata, sources...), - Vars: map[string]interface{}{ - "destination": dest.getAccount(m.chart), - "amount": map[string]any{ - // @todo: upgrade this to proper int after sdk is updated - "amount": debit.Amount.Amount.Uint64(), - "asset": debit.Amount.Asset, - }, - }, - }, - Timestamp: debit.Timestamp, - Metadata: TransactionMetadata(debit.Metadata), - //nolint:godox - // TODO: Add set account metadata for hold when released on ledger (v1.9) - } - - if debit.Reference != "" { - postTransaction.Reference = &debit.Reference - } - - if err := m.CreateTransaction(ctx, ik, postTransaction); err != nil { - return nil, err - } - - return hold, nil -} - -func (m *Manager) ConfirmHold(ctx context.Context, ik string, debit ConfirmHold) error { - account, err := m.client.GetAccount(ctx, m.ledgerName, m.chart.GetHoldAccount(debit.HoldID)) - if err != nil { - return errors.Wrap(err, "getting account") - } - if !IsHold(account) { - return ErrHoldNotFound - } - - hold := ExpandedDebitHoldFromLedgerAccount(account) - if hold.Remaining.Uint64() == 0 { - return ErrClosedHold - } - - amount, err := debit.resolveAmount(hold) - if err != nil { - return err - } - - vars := map[string]interface{}{ - "hold": m.chart.GetHoldAccount(debit.HoldID), - "amount": map[string]any{ - "amount": amount, - "asset": hold.Asset, - }, - "dest": hold.Destination.getAccount(m.chart), - } - if debit.Final { - vars["void_destination"] = m.chart.GetMainBalanceAccount(hold.WalletID) - } - - postTransaction := PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: BuildConfirmHoldScript(debit.Final, hold.Asset), - Vars: vars, - }, - Metadata: TransactionMetadata(metadata.Metadata{}), - } - - if err := m.CreateTransaction(ctx, ik, postTransaction); err != nil { - return err - } - - return nil -} - -func (m *Manager) VoidHold(ctx context.Context, ik string, void VoidHold) error { - account, err := m.client.GetAccount(ctx, m.ledgerName, m.chart.GetHoldAccount(void.HoldID)) - if err != nil { - return errors.Wrap(err, "getting account") - } - - hold := ExpandedDebitHoldFromLedgerAccount(account) - if hold.IsClosed() { - return ErrClosedHold - } - - postTransaction := PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: BuildCancelHoldScript(hold.Asset), - Vars: map[string]interface{}{ - "hold": m.chart.GetHoldAccount(void.HoldID), - "dest": m.chart.GetMainBalanceAccount(hold.WalletID), - }, - }, - Metadata: TransactionMetadata(metadata.Metadata{}), - } - - if err := m.CreateTransaction(ctx, ik, postTransaction); err != nil { - return err - } - - return nil -} - -func (m *Manager) Credit(ctx context.Context, ik string, credit Credit) error { - if err := credit.Validate(); err != nil { - return err - } - - if credit.Balance != "" { - if _, err := m.GetBalance(ctx, credit.WalletID, credit.Balance); err != nil { - return err - } - } - - postTransaction := PostTransaction{ - Script: &shared.V2PostTransactionScript{ - Plain: BuildCreditWalletScript(credit.Sources.ResolveAccounts(m.chart)...), - Vars: map[string]interface{}{ - "destination": credit.destinationAccount(m.chart), - "amount": map[string]any{ - // @todo: upgrade this to proper int after sdk is updated - "amount": credit.Amount.Amount.Uint64(), - "asset": credit.Amount.Asset, - }, - }, - }, - Timestamp: credit.Timestamp, - Metadata: TransactionMetadata(credit.Metadata), - } - if credit.Reference != "" { - postTransaction.Reference = &credit.Reference - } - - if err := m.CreateTransaction(ctx, ik, postTransaction); err != nil { - return err - } - - return nil -} - -func (m *Manager) CreateTransaction(ctx context.Context, ik string, postTransaction PostTransaction) error { - if _, err := m.client.CreateTransaction(ctx, m.ledgerName, ik, postTransaction); err != nil { - switch err := err.(type) { - case *sdkerrors.WalletsErrorResponse: - if err.ErrorCode == sdkerrors.SchemasWalletsErrorResponseErrorCodeInsufficientFund { - return ErrInsufficientFundError - } - } - - return errors.Wrap(err, "creating transaction") - } - - return nil -} - -func (m *Manager) ListWallets(ctx context.Context, query ListQuery[ListWallets]) (*ListResponse[Wallet], error) { - return mapAccountList(ctx, m, mapAccountListQuery{ - Pagination: query.Pagination, - Metadata: func() metadata.Metadata { - metadata := metadata.Metadata{ - MetadataKeyWalletSpecType: PrimaryWallet, - } - if query.Payload.Metadata != nil && len(query.Payload.Metadata) > 0 { - for k, v := range query.Payload.Metadata { - metadata[MetadataKeyWalletCustomDataPrefix+k] = v - } - } - if query.Payload.Name != "" { - metadata[MetadataKeyWalletName] = query.Payload.Name - } - return metadata - }, - ExpandVolumes: query.Payload.ExpandBalances, - }, func(account interface { - MetadataOwner - GetAddress() string - GetBalances() map[string]*big.Int - }) Wallet { - return WithBalancesFromAccount(m.ledgerName, account) - }) -} - -func (m *Manager) ListHolds(ctx context.Context, query ListQuery[ListHolds]) (*ListResponse[DebitHold], error) { - return mapAccountList(ctx, m, mapAccountListQuery{ - Pagination: query.Pagination, - Metadata: func() metadata.Metadata { - metadata := metadata.Metadata{ - MetadataKeyWalletSpecType: HoldWallet, - } - if query.Payload.WalletID != "" { - metadata[MetadataKeyHoldWalletID] = query.Payload.WalletID - } - if query.Payload.Metadata != nil && len(query.Payload.Metadata) > 0 { - for k, v := range query.Payload.Metadata { - metadata[MetadataKeyWalletCustomDataPrefix+k] = v - } - } - return metadata - }, - }, DebitHoldFromLedgerAccount) -} - -func (m *Manager) ListBalances(ctx context.Context, query ListQuery[ListBalances]) (*ListResponse[Balance], error) { - return mapAccountList(ctx, m, mapAccountListQuery{ - Metadata: func() metadata.Metadata { - metadata := BalancesMetadataFilter(query.Payload.WalletID) - if query.Payload.Metadata != nil && len(query.Payload.Metadata) > 0 { - for k, v := range query.Payload.Metadata { - metadata[MetadataKeyWalletCustomDataPrefix+k] = v - } - } - return metadata - }, - Pagination: query.Pagination, - }, BalanceFromAccount) -} - -func (m *Manager) ListTransactions(ctx context.Context, query ListQuery[ListTransactions]) (*ListResponse[Transaction], error) { - var ( - response *shared.V2TransactionsCursorResponseCursor - err error - ) - if query.PaginationToken == "" { - response, err = m.client.ListTransactions(ctx, m.ledgerName, ListTransactionsQuery{ - Limit: query.Limit, - Account: func() string { - if query.Payload.WalletID != "" { - return m.chart.GetMainBalanceAccount(query.Payload.WalletID) - } - return "" - }(), - Metadata: TransactionBaseMetadataFilter(), - }) - } else { - response, err = m.client.ListTransactions(ctx, m.ledgerName, ListTransactionsQuery{ - Cursor: query.PaginationToken, - }) - } - if err != nil { - return nil, errors.Wrap(err, "listing transactions") - } - - return newListResponse[shared.V2ExpandedTransaction, Transaction](response, func(tx shared.V2ExpandedTransaction) Transaction { - return Transaction{ - V2ExpandedTransaction: tx, - Ledger: m.ledgerName, - } - }), nil -} - -func (m *Manager) CreateWallet(ctx context.Context, data *CreateRequest) (*Wallet, error) { - wallet := NewWallet(data.Name, m.ledgerName, data.Metadata) - - if err := m.client.AddMetadataToAccount( - ctx, - m.ledgerName, - m.chart.GetMainBalanceAccount(wallet.ID), - "", - wallet.LedgerMetadata(), - ); err != nil { - return nil, errors.Wrap(err, "adding metadata to account") - } - - return &wallet, nil -} - -func (m *Manager) UpdateWallet(ctx context.Context, id, ik string, data *PatchRequest) error { - account, err := m.client.GetAccount(ctx, m.ledgerName, m.chart.GetMainBalanceAccount(id)) - if err != nil { - return ErrWalletNotFound - } - - if !IsPrimary(account) { - return ErrWalletNotFound - } - - newCustomMetadata := metadata.Metadata{} - newCustomMetadata = newCustomMetadata.Merge(ExtractCustomMetadata(account)) - newCustomMetadata = newCustomMetadata.Merge(data.Metadata) - - meta := metadata.Metadata(account.GetMetadata()) - meta = meta.Merge(EncodeCustomMetadata(newCustomMetadata)) - - if err := m.client.AddMetadataToAccount(ctx, m.ledgerName, m.chart.GetMainBalanceAccount(id), ik, meta); err != nil { - return errors.Wrap(err, "adding metadata to account") - } - - return nil -} - -func (m *Manager) GetWallet(ctx context.Context, id string) (*Wallet, error) { - account, err := m.client.GetAccount( - ctx, - m.ledgerName, - m.chart.GetMainBalanceAccount(id), - ) - if err != nil { - return nil, errors.Wrap(err, "getting account") - } - - if !IsPrimary(account) { - return nil, ErrWalletNotFound - } - - return Ptr(WithBalancesFromAccount(m.ledgerName, account)), nil -} - -type Summary struct { - Balances []ExpandedBalance `json:"balances"` - AvailableFunds map[string]*big.Int `json:"availableFunds"` - ExpiredFunds map[string]*big.Int `json:"expiredFunds"` - ExpirableFunds map[string]*big.Int `json:"expirableFunds"` - HoldFunds map[string]*big.Int `json:"holdFunds"` -} - -func (m *Manager) GetWalletSummary(ctx context.Context, id string) (*Summary, error) { - balances, err := fetchAndMapAllAccounts(ctx, m, metadata.Metadata{ - MetadataKeyWalletID: id, - }, func(src interface { - MetadataOwner - GetAddress() string - GetBalances() map[string]*big.Int - }) ExpandedBalance { - account, err := m.client.GetAccount(ctx, m.ledgerName, src.GetAddress()) - if err != nil { - // TODO: refine error handling - panic(errors.Wrap(err, "getting account")) - } - return ExpandedBalanceFromAccount(account) - }) - if err != nil { - return nil, err - } - - s := &Summary{ - Balances: balances, - AvailableFunds: map[string]*big.Int{}, - ExpiredFunds: map[string]*big.Int{}, - ExpirableFunds: map[string]*big.Int{}, - HoldFunds: map[string]*big.Int{}, - } - - for _, balance := range balances { - for asset, amount := range balance.Assets { - switch { - case balance.ExpiresAt != nil && balance.ExpiresAt.Before(time.Now()): - if s.ExpiredFunds[asset] == nil { - s.ExpiredFunds[asset] = new(big.Int) - } - s.ExpiredFunds[asset].Add(s.ExpiredFunds[asset], amount) - case balance.ExpiresAt != nil && !balance.ExpiresAt.Before(time.Now()): - if s.ExpirableFunds[asset] == nil { - s.ExpirableFunds[asset] = new(big.Int) - } - s.ExpirableFunds[asset].Add(s.ExpirableFunds[asset], amount) - if s.AvailableFunds[asset] == nil { - s.AvailableFunds[asset] = new(big.Int) - } - s.AvailableFunds[asset].Add(s.AvailableFunds[asset], amount) - case balance.ExpiresAt == nil: - if s.AvailableFunds[asset] == nil { - s.AvailableFunds[asset] = new(big.Int) - } - s.AvailableFunds[asset].Add(s.AvailableFunds[asset], amount) - } - } - } - - holds, err := fetchAndMapAllAccounts(ctx, m, metadata.Metadata{ - MetadataKeyHoldWalletID: id, - }, func(src interface { - MetadataOwner - GetAddress() string - GetBalances() map[string]*big.Int - }) ExpandedDebitHold { - account, err := m.client.GetAccount(ctx, m.ledgerName, src.GetAddress()) - if err != nil { - // TODO: refine error handling - panic(errors.Wrap(err, "getting account")) - } - - return ExpandedDebitHoldFromLedgerAccount(account) - }) - if err != nil { - return nil, err - } - - for _, hold := range holds { - if s.HoldFunds[hold.Asset] == nil { - s.HoldFunds[hold.Asset] = new(big.Int) - } - s.HoldFunds[hold.Asset].Add(s.HoldFunds[hold.Asset], hold.Remaining) - } - - return s, nil -} - -func (m *Manager) GetHold(ctx context.Context, id string) (*ExpandedDebitHold, error) { - account, err := m.client.GetAccount(ctx, m.ledgerName, m.chart.GetHoldAccount(id)) - if err != nil { - return nil, err - } - - return Ptr(ExpandedDebitHoldFromLedgerAccount(account)), nil -} - -func (m *Manager) CreateBalance(ctx context.Context, data *CreateBalance) (*Balance, error) { - if err := data.Validate(); err != nil { - return nil, err - } - ret, err := m.client.GetAccount(ctx, m.ledgerName, m.chart.GetBalanceAccount(data.WalletID, data.Name)) - switch { - case errors.Is(err, ErrAccountNotFound): - case err == nil: - if ret.Metadata != nil && - ret.Metadata[MetadataKeyWalletBalance] == TrueValue { - return nil, ErrBalanceAlreadyExists - } - default: - return nil, err - } - - balance := NewBalance(data.Name, data.ExpiresAt) - - if err := m.client.AddMetadataToAccount( - ctx, - m.ledgerName, - m.chart.GetBalanceAccount(data.WalletID, balance.Name), - "", - balance.LedgerMetadata(data.WalletID), - ); err != nil { - return nil, errors.Wrap(err, "adding metadata to account") - } - - return &balance, nil -} - -func (m *Manager) GetBalance(ctx context.Context, walletID string, balanceName string) (*ExpandedBalance, error) { - account, err := m.client.GetAccount(ctx, m.ledgerName, m.chart.GetBalanceAccount(walletID, balanceName)) - if err != nil { - return nil, err - } - - if account.Metadata[MetadataKeyWalletBalance] != TrueValue { - return nil, ErrBalanceNotExists - } - - return Ptr(ExpandedBalanceFromAccount(account)), nil -} - -type mapAccountListQuery struct { - Pagination - Metadata func() metadata.Metadata - ExpandVolumes bool -} - -func mapAccountList[TO any](ctx context.Context, r *Manager, query mapAccountListQuery, mapper mapper[interface { - MetadataOwner - GetAddress() string - GetBalances() map[string]*big.Int -}, TO]) (*ListResponse[TO], error) { - var ( - cursor *AccountsCursorResponseCursor - err error - ) - if query.PaginationToken == "" { - cursor, err = r.client.ListAccounts(ctx, r.ledgerName, ListAccountsQuery{ - Limit: query.Limit, - Metadata: query.Metadata(), - ExpandVolumes: query.ExpandVolumes, - }) - } else { - cursor, err = r.client.ListAccounts(ctx, r.ledgerName, ListAccountsQuery{ - Cursor: query.PaginationToken, - }) - } - if err != nil { - return nil, err - } - - return newListResponse[AccountWithVolumesAndBalances, TO](cursor, func(item AccountWithVolumesAndBalances) TO { - return mapper(&item) - }), nil -} - -const maxPageSize = 100 - -func fetchAndMapAllAccounts[TO any](ctx context.Context, r *Manager, md metadata.Metadata, mapper mapper[interface { - MetadataOwner - GetAddress() string - GetBalances() map[string]*big.Int -}, TO]) ([]TO, error) { - - ret := make([]TO, 0) - query := mapAccountListQuery{ - Metadata: func() metadata.Metadata { - return md - }, - Pagination: Pagination{ - Limit: maxPageSize, - }, - } - for { - listResponse, err := mapAccountList(ctx, r, query, mapper) - if err != nil { - return nil, err - } - ret = append(ret, listResponse.Data...) - if listResponse.Next == "" { - return ret, nil - } - query = mapAccountListQuery{ - Pagination: Pagination{ - PaginationToken: listResponse.Next, - }, - } - } -} diff --git a/ee/wallets/pkg/metadata.go b/ee/wallets/pkg/metadata.go deleted file mode 100644 index adcb38dcee..0000000000 --- a/ee/wallets/pkg/metadata.go +++ /dev/null @@ -1,96 +0,0 @@ -package wallet - -import ( - "strings" - - "github.com/formancehq/go-libs/metadata" -) - -const ( - MetadataKeyWalletTransaction = "wallets/transaction" - MetadataKeyWalletSpecType = "wallets/spec/type" - MetadataKeyWalletID = "wallets/id" - MetadataKeyWalletName = "wallets/name" - MetadataKeyHoldWalletID = "wallets/holds/wallet_id" - MetadataKeyHoldAsset = "wallets/holds/asset" - MetadataKeyHoldSubject = "wallets/holds/subject" - MetadataKeyHoldID = "wallets/holds/id" - MetadataKeyWalletHoldDescription = "wallets/holds/description" - MetadataKeyHoldVoidDestination = "void_destination" - MetadataKeyHoldDestination = "destination" - MetadataKeyBalanceName = "wallets/balances/name" - MetadataKeyBalanceExpiresAt = "wallets/balances/expiresAt" - MetadataKeyBalancePriority = "wallets/balances/priority" - MetadataKeyWalletBalance = "wallets/balances" - MetadataKeyCreatedAt = "wallets/createdAt" - - PrimaryWallet = "wallets.primary" - HoldWallet = "wallets.hold" - - TrueValue = "true" - - MetadataKeyWalletCustomDataPrefix = "wallets/custom_data_" -) - -func TransactionMetadata(customMetadata metadata.Metadata) map[string]string { - if customMetadata == nil { - customMetadata = metadata.Metadata{} - } - return metadata.Metadata{ - MetadataKeyWalletTransaction: "true", - }.Merge(EncodeCustomMetadata(customMetadata)) -} - -func TransactionBaseMetadataFilter() metadata.Metadata { - return metadata.Metadata{ - MetadataKeyWalletTransaction: "true", - } -} - -type MetadataOwner interface { - GetMetadata() map[string]string -} - -func IsPrimary(v MetadataOwner) bool { - return HasMetadata(v, MetadataKeyWalletSpecType, PrimaryWallet) -} - -func IsHold(v MetadataOwner) bool { - return HasMetadata(v, MetadataKeyWalletSpecType, HoldWallet) -} - -func GetMetadata(v MetadataOwner, key string) string { - return v.GetMetadata()[key] -} - -func HasMetadata(v MetadataOwner, key, value string) bool { - return GetMetadata(v, key) == value -} - -func LedgerMetadataToWalletMetadata(m map[string]any) metadata.Metadata { - ret := metadata.Metadata{} - for k, v := range m { - ret[k] = v.(string) - } - return ret -} - -func EncodeCustomMetadata(m metadata.Metadata) metadata.Metadata { - ret := metadata.Metadata{} - for key, value := range m { - ret[MetadataKeyWalletCustomDataPrefix+key] = value - } - return ret -} - -func ExtractCustomMetadata(account interface { - GetMetadata() map[string]string -}) metadata.Metadata { - ret := metadata.Metadata{} - for key, value := range account.GetMetadata() { - if strings.HasPrefix(key, MetadataKeyWalletCustomDataPrefix) { - ret[strings.TrimPrefix(key, MetadataKeyWalletCustomDataPrefix)] = value - } - } - return ret -} diff --git a/ee/wallets/pkg/module.go b/ee/wallets/pkg/module.go deleted file mode 100644 index 33c4015304..0000000000 --- a/ee/wallets/pkg/module.go +++ /dev/null @@ -1,33 +0,0 @@ -package wallet - -import ( - "net/http" - - sdk "github.com/formancehq/formance-sdk-go/v2" - - "go.uber.org/fx" -) - -func Module(ledgerURL string, ledgerName, chartPrefix string) fx.Option { - return fx.Module( - "wallet", - fx.Provide(fx.Annotate(func(httpClient *http.Client) *DefaultLedger { - sdk := sdk.New( - sdk.WithClient(httpClient), - sdk.WithServerURL(ledgerURL), - ) - return NewDefaultLedger(sdk) - }, fx.As(new(Ledger)))), - fx.Provide(func() *Chart { - return NewChart(chartPrefix) - }), - fx.Provide(func(ledger Ledger, chart *Chart) *Manager { - return NewManager(ledgerName, ledger, chart) - }), - fx.Invoke(func(manager *Manager, lc fx.Lifecycle) { - lc.Append(fx.Hook{ - OnStart: manager.Init, - }) - }), - ) -} diff --git a/ee/wallets/pkg/monetary.go b/ee/wallets/pkg/monetary.go deleted file mode 100644 index 37db44e5a4..0000000000 --- a/ee/wallets/pkg/monetary.go +++ /dev/null @@ -1,17 +0,0 @@ -package wallet - -import ( - "math/big" -) - -type Monetary struct { - Amount *big.Int `json:"amount"` - Asset string `json:"asset"` -} - -func NewMonetary(amount *big.Int, asset string) Monetary { - return Monetary{ - Amount: amount, - Asset: asset, - } -} diff --git a/ee/wallets/pkg/numscript/cancel-hold.num b/ee/wallets/pkg/numscript/cancel-hold.num deleted file mode 100644 index f2bff20e4f..0000000000 --- a/ee/wallets/pkg/numscript/cancel-hold.num +++ /dev/null @@ -1,9 +0,0 @@ -vars { - account $hold - account $dest -} - -send [{{ .Asset }} *] ( - source = $hold - destination = $dest -) diff --git a/ee/wallets/pkg/numscript/confirm-hold.num b/ee/wallets/pkg/numscript/confirm-hold.num deleted file mode 100644 index fe312ce674..0000000000 --- a/ee/wallets/pkg/numscript/confirm-hold.num +++ /dev/null @@ -1,20 +0,0 @@ -vars { - account $hold - account $dest - {{- if .Final }} - account $void_destination - {{- end }} - monetary $amount -} - -send $amount ( - source = $hold - destination = $dest -) - -{{- if .Final }} -send [{{.Asset}} *] ( - source = $hold - destination = $void_destination -) -{{- end }} diff --git a/ee/wallets/pkg/numscript/credit-wallet.num b/ee/wallets/pkg/numscript/credit-wallet.num deleted file mode 100644 index a17dfd8526..0000000000 --- a/ee/wallets/pkg/numscript/credit-wallet.num +++ /dev/null @@ -1,13 +0,0 @@ -vars { - monetary $amount - account $destination -} - -send $amount ( - source = { - {{- range $source := .Sources }} - @{{ $source }} - {{- end }} - } - destination = $destination -) diff --git a/ee/wallets/pkg/numscript/debit-wallet.num b/ee/wallets/pkg/numscript/debit-wallet.num deleted file mode 100644 index 04b438258f..0000000000 --- a/ee/wallets/pkg/numscript/debit-wallet.num +++ /dev/null @@ -1,21 +0,0 @@ -vars { - monetary $amount - account $destination -} - -send $amount ( - source = { - {{- range $source := .Sources }} - @{{ $source }} - {{- end }} - } - destination = $destination -) - -{{- if .Metadata }} -{{- range $account, $accountMetadata := .Metadata }} -{{- range $k, $v := $accountMetadata }} -set_account_meta(@{{ $account }}, "{{ $k }}", {{ $v | quote }}) -{{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/ee/wallets/pkg/scripts.go b/ee/wallets/pkg/scripts.go deleted file mode 100644 index 5adad99468..0000000000 --- a/ee/wallets/pkg/scripts.go +++ /dev/null @@ -1,57 +0,0 @@ -//nolint:golint -package wallet - -import ( - "bytes" - _ "embed" - "strconv" - "text/template" -) - -var ( - //go:embed numscript/confirm-hold.num - ConfirmHoldScript string - //go:embed numscript/cancel-hold.num - CancelHoldScript string - //go:embed numscript/credit-wallet.num - CreditWalletScript string - //go:embed numscript/debit-wallet.num - DebitWalletScript string -) - -func renderTemplate(tplStr string, data any) string { - buf := bytes.NewBufferString("") - tpl := template.Must(template.New("tpl").Funcs(template.FuncMap{ - "quote": strconv.Quote, - }).Parse(tplStr)) - if err := tpl.Execute(buf, data); err != nil { - panic(err) - } - return buf.String() -} - -func BuildConfirmHoldScript(final bool, asset string) string { - return renderTemplate(ConfirmHoldScript, map[string]any{ - "Final": final, - "Asset": asset, - }) -} - -func BuildCreditWalletScript(sources ...string) string { - return renderTemplate(CreditWalletScript, map[string]any{ - "Sources": sources, - }) -} - -func BuildDebitWalletScript(metadata map[string]map[string]string, sources ...string) string { - return renderTemplate(DebitWalletScript, map[string]any{ - "Sources": sources, - "Metadata": metadata, - }) -} - -func BuildCancelHoldScript(asset string) string { - return renderTemplate(CancelHoldScript, map[string]any{ - "Asset": asset, - }) -} diff --git a/ee/wallets/pkg/subject.go b/ee/wallets/pkg/subject.go deleted file mode 100644 index d4c3898e0e..0000000000 --- a/ee/wallets/pkg/subject.go +++ /dev/null @@ -1,81 +0,0 @@ -package wallet - -import ( - "fmt" - - "github.com/formancehq/ledger/pkg/core/accounts" -) - -const ( - SubjectTypeLedgerAccount string = "ACCOUNT" - SubjectTypeWallet string = "WALLET" -) - -type Subject struct { - Type string `json:"type"` - Identifier string `json:"identifier"` - Balance string `json:"balance,omitempty"` -} - -func (s Subject) getAccount(chart *Chart) string { - switch s.Type { - case SubjectTypeLedgerAccount: - return s.Identifier - case SubjectTypeWallet: - if s.Balance != "" { - return chart.GetBalanceAccount(s.Identifier, s.Balance) - } - return chart.GetMainBalanceAccount(s.Identifier) - } - panic("unknown type") -} - -func (s Subject) Validate() error { - if s.Type != SubjectTypeWallet && s.Type != SubjectTypeLedgerAccount { - return fmt.Errorf("unknown source type: %s", s.Type) - } - switch s.Type { - case SubjectTypeLedgerAccount: - if !accounts.ValidateAddress(s.Identifier) { - return newErrInvalidAccountName(s.Identifier) - } - } - return nil -} - -type Subjects []Subject - -func (subjects Subjects) ResolveAccounts(chart *Chart) []string { - if len(subjects) == 0 { - subjects = []Subject{DefaultCreditSource} - } - resolvedSources := make([]string, 0) - for _, source := range subjects { - resolvedSources = append(resolvedSources, source.getAccount(chart)) - } - return resolvedSources -} - -func (subjects Subjects) Validate() error { - for _, source := range subjects { - if err := source.Validate(); err != nil { - return err - } - } - return nil -} - -func NewWalletSubject(walletID, balance string) Subject { - return Subject{ - Type: SubjectTypeWallet, - Identifier: walletID, - Balance: balance, - } -} - -func NewLedgerAccountSubject(account string) Subject { - return Subject{ - Type: SubjectTypeLedgerAccount, - Identifier: account, - } -} diff --git a/ee/wallets/pkg/transaction.go b/ee/wallets/pkg/transaction.go deleted file mode 100644 index 1288203313..0000000000 --- a/ee/wallets/pkg/transaction.go +++ /dev/null @@ -1,25 +0,0 @@ -package wallet - -import ( - "encoding/json" - - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" -) - -type Transaction struct { - shared.V2ExpandedTransaction - Ledger string `json:"ledger"` -} - -func (t Transaction) MarshalJSON() ([]byte, error) { - asJSON, err := json.Marshal(t.V2ExpandedTransaction) - if err != nil { - return nil, err - } - asMap := make(map[string]any) - if err := json.Unmarshal(asJSON, &asMap); err != nil { - return nil, err - } - asMap["ledger"] = t.Ledger - return json.Marshal(asMap) -} diff --git a/ee/wallets/pkg/utils.go b/ee/wallets/pkg/utils.go deleted file mode 100644 index 6db8e0d38b..0000000000 --- a/ee/wallets/pkg/utils.go +++ /dev/null @@ -1,5 +0,0 @@ -package wallet - -func Ptr[T any](v T) *T { - return &v -} diff --git a/ee/wallets/pkg/wallet.go b/ee/wallets/pkg/wallet.go deleted file mode 100644 index 4771f00bf2..0000000000 --- a/ee/wallets/pkg/wallet.go +++ /dev/null @@ -1,146 +0,0 @@ -package wallet - -import ( - "encoding/json" - "math/big" - "net/http" - "time" - - "github.com/formancehq/go-libs/metadata" - "github.com/google/uuid" -) - -type ListWallets struct { - Metadata metadata.Metadata - Name string - ExpandBalances bool -} - -type PatchRequest struct { - Metadata metadata.Metadata `json:"metadata"` -} - -func (c *PatchRequest) Bind(r *http.Request) error { - return nil -} - -type CreateRequest struct { - PatchRequest - Name string `json:"name"` -} - -func (c *CreateRequest) Bind(r *http.Request) error { - return nil -} - -type Wallet struct { - ID string `json:"id"` - Name string `json:"name"` - Metadata metadata.Metadata `json:"metadata"` - CreatedAt time.Time `json:"createdAt"` - Ledger string `json:"ledger"` - Balances map[string]*big.Int `json:"balances,omitempty"` -} - -func (w *Wallet) UnmarshalJSON(data []byte) error { - type view struct { - ID string `json:"id"` - Name string `json:"name"` - Metadata metadata.Metadata `json:"metadata"` - CreatedAt time.Time `json:"createdAt"` - Ledger string `json:"ledger"` - Balances struct { - Main ExpandedBalance `json:"main"` - } `json:"balances"` - } - v := view{} - if err := json.Unmarshal(data, &v); err != nil { - return err - } - *w = Wallet{ - ID: v.ID, - Name: v.Name, - Metadata: v.Metadata, - CreatedAt: v.CreatedAt, - Ledger: v.Ledger, - Balances: v.Balances.Main.Assets, - } - return nil -} - -func (w Wallet) MarshalJSON() ([]byte, error) { - return json.Marshal(struct { - ID string `json:"id"` - Name string `json:"name"` - Metadata metadata.Metadata `json:"metadata"` - CreatedAt time.Time `json:"createdAt"` - Ledger string `json:"ledger"` - Balances struct { - Main ExpandedBalance `json:"main"` - } `json:"balances"` - }{ - ID: w.ID, - Name: w.Name, - Metadata: w.Metadata, - CreatedAt: w.CreatedAt, - Ledger: w.Ledger, - Balances: struct { - Main ExpandedBalance `json:"main"` - }{ - Main: ExpandedBalance{ - Assets: w.Balances, - }, - }, - }) -} - -func (w Wallet) LedgerMetadata() map[string]string { - return metadata.Metadata{ - MetadataKeyWalletSpecType: PrimaryWallet, - MetadataKeyWalletName: w.Name, - MetadataKeyWalletID: w.ID, - MetadataKeyWalletBalance: TrueValue, - MetadataKeyBalanceName: MainBalance, - MetadataKeyCreatedAt: w.CreatedAt.UTC().Format(time.RFC3339Nano), - }.Merge(EncodeCustomMetadata(w.Metadata)) -} - -func NewWallet(name, ledger string, m metadata.Metadata) Wallet { - if m == nil { - m = metadata.Metadata{} - } - return Wallet{ - ID: uuid.NewString(), - Metadata: m, - Name: name, - CreatedAt: time.Now().UTC().Round(time.Nanosecond), - Ledger: ledger, - Balances: map[string]*big.Int{}, - } -} - -func WithBalancesFromAccount(ledger string, account interface { - MetadataOwner - GetBalances() map[string]*big.Int -}) Wallet { - - createdAt, err := time.Parse(time.RFC3339Nano, GetMetadata(account, MetadataKeyCreatedAt)) - if err != nil { - panic(err) - } - - return Wallet{ - ID: GetMetadata(account, MetadataKeyWalletID), - Name: GetMetadata(account, MetadataKeyWalletName), - Metadata: ExtractCustomMetadata(account), - CreatedAt: createdAt, - Ledger: ledger, - Balances: func() map[string]*big.Int { - ret := account.GetBalances() - if ret == nil { - return map[string]*big.Int{} - } - return ret - }(), - } -} diff --git a/ee/wallets/scratch.Dockerfile b/ee/wallets/scratch.Dockerfile deleted file mode 100644 index 9bd0659e0e..0000000000 --- a/ee/wallets/scratch.Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM ghcr.io/formancehq/base:scratch -COPY wallets /usr/bin/wallets -ENV OTEL_SERVICE_NAME wallets -ENTRYPOINT ["/usr/bin/wallets"] -CMD ["server"] From 905cc57e116fb09cb5446d1514a166b0531fffee Mon Sep 17 00:00:00 2001 From: Maxence Maireaux Date: Thu, 26 Sep 2024 18:20:10 +0200 Subject: [PATCH 2/4] refactor: move all project to dedicated repo --- Earthfile | 11 ++++++----- helm/Earthfile | 3 --- helm/regions/Earthfile | 4 ++-- tests/integration/Earthfile | 7 ++++++- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Earthfile b/Earthfile index 949260a76e..c09c701e65 100644 --- a/Earthfile +++ b/Earthfile @@ -9,7 +9,9 @@ IMPORT github.com/formancehq/auth:main AS auth IMPORT github.com/formancehq/search:main AS search IMPORT github.com/formancehq/stargate:main AS stargate IMPORT github.com/formancehq/webhooks:main AS webhooks - +IMPORT github.com/formancehq/flows:main AS orchestration +IMPORT github.com/formancehq/reconciliation:main AS reconciliation +IMPORT github.com/formancehq/wallets:main AS wallets sources: FROM core+base-image @@ -36,10 +38,9 @@ build-final-spec: COPY (auth+openapi/openapi.yaml) /src/ee/auth/ COPY (search+openapi/openapi.yaml) /src/ee/search/ COPY (webhooks+openapi/openapi.yaml) /src/ee/webhooks/ - - FOR c IN wallets reconciliation orchestration - COPY (./ee/$c+openapi/openapi.yaml) /src/ee/$c/ - END + COPY (wallets+openapi/openapi.yaml) /src/ee/wallets/ + COPY (reconciliation+openapi/openapi.yaml) /src/ee/reconciliation/ + COPY (orchestration+openapi/openapi.yaml) /src/ee/orchestration/ RUN npm run build RUN jq -s '.[0] * .[1]' build/generate.json openapi-overlay.json > build/latest.json diff --git a/helm/Earthfile b/helm/Earthfile index 3c310388ab..30495bd1bd 100644 --- a/helm/Earthfile +++ b/helm/Earthfile @@ -1,8 +1,6 @@ VERSION 0.8 IMPORT github.com/formancehq/earthly:tags/v0.15.0 AS core -IMPORT .. AS stack -IMPORT ../components/operator AS operator sources: FROM core+base-image @@ -12,7 +10,6 @@ sources: helm-validate: FROM core+helm-base - WORKDIR /src/helm COPY . . FOR chart IN $(ls -d */) diff --git a/helm/regions/Earthfile b/helm/regions/Earthfile index 627bab7996..6ffe4c5706 100644 --- a/helm/regions/Earthfile +++ b/helm/regions/Earthfile @@ -2,8 +2,8 @@ VERSION 0.8 IMPORT github.com/formancehq/earthly:tags/v0.15.0 AS core IMPORT ../.. AS stack -IMPORT ../../components/operator AS operator -IMPORT ../../ee/agent AS agent +IMPORT github.com/formancehq/operator:main AS operator +IMPORT github.com/formancehq/agent:main AS agent sources: FROM core+base-image diff --git a/tests/integration/Earthfile b/tests/integration/Earthfile index 67c0263adb..d05e105117 100644 --- a/tests/integration/Earthfile +++ b/tests/integration/Earthfile @@ -8,6 +8,9 @@ IMPORT github.com/formancehq/auth:main AS auth IMPORT github.com/formancehq/search:main AS search IMPORT github.com/formancehq/stargate:main AS stargate IMPORT github.com/formancehq/webhooks:main AS webhooks +IMPORT github.com/formancehq/flows:main AS orchestration +IMPORT github.com/formancehq/reconciliation:main AS reconciliation +IMPORT github.com/formancehq/wallets:main AS wallets IMPORT ../.. AS stack IMPORT ../../releases AS releases @@ -38,11 +41,13 @@ tests: COPY --pass-args (stack+sources/out --LOCATION=libs) /src/libs COPY --pass-args (ledger+sources/src) /src/components/ledger COPY --pass-args (payments+sources/src) /src/components/payments - COPY --pass-args (stack+sources/out --LOCATION=ee) /src/ee COPY --pass-args (gateway+sources/src) /src/ee/gateway/ COPY --pass-args (auth+sources/src) /src/ee/auth/ COPY --pass-args (search+sources/src) /src/ee/search/ COPY --pass-args (webhooks+sources/src) /src/ee/webhooks/ + COPY --pass-args (orchestration+sources/src) /src/ee/orchestration/ + COPY --pass-args (reconciliation+sources/src) /src/ee/reconciliation/ + COPY --pass-args (wallets+sources/src) /src/ee/wallets/ COPY --pass-args (stack+build-final-spec/latest.json) /src/releases/build/latest.json COPY --pass-args (releases+sdk-generate/go) /src/releases/sdks/go COPY . /src/tests/integration From 91d7f42923fe93ec7e5b7b4732216fb3d256f8a1 Mon Sep 17 00:00:00 2001 From: Maxence Maireaux Date: Thu, 26 Sep 2024 18:22:42 +0200 Subject: [PATCH 3/4] refactor: Move operator to dedicated repository --- tests/integration/Earthfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/integration/Earthfile b/tests/integration/Earthfile index d05e105117..db829c12b5 100644 --- a/tests/integration/Earthfile +++ b/tests/integration/Earthfile @@ -82,11 +82,13 @@ sources: COPY --pass-args (releases+sdk-generate/go) /src/releases/sdks/go COPY --pass-args (ledger+sources/src) /src/components/ledger COPY --pass-args (payments+sources/src) /src/components/payments - COPY --pass-args (stack+sources/out --LOCATION=ee) /src/ee COPY --pass-args (gateway+sources/src) /src/ee/gateway/ COPY --pass-args (auth+sources/src) /src/ee/auth/ COPY --pass-args (search+sources/src) /src/ee/search/ COPY --pass-args (webhooks+sources/src) /src/ee/webhooks/ + COPY --pass-args (orchestration+sources/src) /src/ee/orchestration/ + COPY --pass-args (reconciliation+sources/src) /src/ee/reconciliation/ + COPY --pass-args (wallets+sources/src) /src/ee/wallets/ COPY --pass-args (stack+sources/out --LOCATION=go.mod) /src/go.mod COPY --pass-args (stack+sources/out --LOCATION=go.sum) /src/go.sum COPY . /src/tests/integration From c991a36fa98b65b7a56bb2cd2856c85bb66b413a Mon Sep 17 00:00:00 2001 From: Maxence Maireaux Date: Thu, 26 Sep 2024 20:33:12 +0200 Subject: [PATCH 4/4] fix: integration test --- tests/integration/go.mod | 26 ++++++----------- tests/integration/go.sum | 28 ++++++++++++------- tests/integration/internal/init.go | 2 +- .../suite/auth-client-credentials.go | 6 ++-- .../suite/ledger-aggregated-balances.go | 4 +-- tests/integration/suite/ledger-create-bulk.go | 4 +-- .../suite/ledger-create-transaction.go | 10 +++---- tests/integration/suite/ledger-create.go | 6 ++-- .../suite/ledger-delete-metadata.go | 4 +-- .../integration/suite/ledger-import-export.go | 4 +-- .../suite/ledger-list-count-accounts.go | 6 ++-- tests/integration/suite/ledger-list-logs.go | 4 +-- .../suite/ledger-list-transactions.go | 6 ++-- tests/integration/suite/ledger-list.go | 2 +- .../suite/ledger-revert-transaction.go | 6 ++-- .../suite/ledger-search-ingestion-v1.go | 2 +- .../suite/ledger-set-metadata-on-account.go | 4 +-- .../ledger-set-metadata-on-transaction.go | 6 ++-- .../suite/ledger-update-metadata.go | 2 +- .../suite/ledger-use-alternate-bucket.go | 4 +-- .../suite/ledger-v1-get-balances.go | 4 +-- .../integration/suite/ledger-volumes-list.go | 4 +-- .../suite/orchestration-triggers.go | 8 +++--- .../suite/orchestration-workflows-create.go | 2 +- ...hestration-workflows-execute-with-error.go | 4 +-- .../suite/orchestration-workflows-execute.go | 4 +-- .../suite/orchestration-workflows-list.go | 4 +-- .../orchestration-workflows-soft-delete.go | 6 ++-- .../suite/payments-connectors-dummy-pay.go | 4 +-- .../suite/payments-connectors-generic.go | 6 ++-- .../suite/payments-connectors-reset.go | 4 +-- .../suite/payments-connectors-stripe.go | 4 +-- .../reconciliation-policy-create-list.go | 4 +-- tests/integration/suite/wallets-create.go | 4 +-- tests/integration/suite/wallets-credit.go | 6 ++-- tests/integration/suite/wallets-debit.go | 6 ++-- .../suite/webhooks-configs-activation.go | 6 ++-- .../suite/webhooks-configs-delete.go | 6 ++-- .../integration/suite/webhooks-configs-get.go | 4 +-- .../suite/webhooks-configs-insert.go | 4 +-- .../suite/webhooks-configs-secret.go | 4 +-- .../suite/webhooks-configs-test.go | 6 ++-- .../webhooks-ledger-committed-transaction.go | 4 +-- tests/integration/suite/webhooks-retries.go | 4 +-- 44 files changed, 124 insertions(+), 124 deletions(-) diff --git a/tests/integration/go.mod b/tests/integration/go.mod index 64ceccd3d6..d23010b3b9 100644 --- a/tests/integration/go.mod +++ b/tests/integration/go.mod @@ -7,17 +7,17 @@ toolchain go1.22.7 require ( github.com/docker/docker v27.3.1+incompatible github.com/egymgmbh/go-prefix-writer v0.0.0-20180609083313-7326ea162eca - github.com/formancehq/auth v0.0.0-00010101000000-000000000000 - github.com/formancehq/formance-sdk-go/v2 v2.0.0-00010101000000-000000000000 + github.com/formancehq/auth v0.0.0-20240925213343-e5de0bb34c65 + github.com/formancehq/formance-sdk-go/v3 v3.0.0 github.com/formancehq/go-libs v1.7.1 - github.com/formancehq/ledger v0.0.0-00010101000000-000000000000 + github.com/formancehq/ledger v0.0.0-20240925213413-0ef9d8eb67e6 github.com/formancehq/orchestration v0.0.0-00010101000000-000000000000 - github.com/formancehq/payments v0.0.0-00010101000000-000000000000 - github.com/formancehq/reconciliation v0.0.0-00010101000000-000000000000 - github.com/formancehq/search v0.0.0-00010101000000-000000000000 + github.com/formancehq/payments v0.0.0-20240925213419-a849e779040f + github.com/formancehq/reconciliation v0.0.0-20240926152910-eda505f2fcd3 + github.com/formancehq/search v0.0.0-20240926085257-6b5288dc2576 github.com/formancehq/stack/libs/events v0.0.0-00010101000000-000000000000 - github.com/formancehq/wallets v0.0.0-00010101000000-000000000000 - github.com/formancehq/webhooks v0.0.0-00010101000000-000000000000 + github.com/formancehq/wallets v0.0.0-20240926151232-c6fc6e393af0 + github.com/formancehq/webhooks v0.0.0-20240926142120-a19c8730abaa github.com/golang-jwt/jwt v3.2.2+incompatible github.com/google/uuid v1.6.0 github.com/jackc/pgx/v5 v5.7.1 @@ -271,16 +271,8 @@ require ( ) replace ( - github.com/formancehq/auth => github.com/formancehq/auth v0.0.0-20240925174204-6f5cb5948775 - github.com/formancehq/formance-sdk-go/v2 => ../../releases/sdks/go - github.com/formancehq/ledger => github.com/formancehq/ledger v0.0.0-20240925161848-3cf78b93df02 - github.com/formancehq/orchestration => ../../ee/orchestration - github.com/formancehq/payments => github.com/formancehq/payments v0.0.0-20240925171236-82f077b2e178 + github.com/formancehq/orchestration => github.com/formancehq/flows v0.0.0-20240926150344-d8c14fc9e76c github.com/formancehq/payments/genericclient => github.com/formancehq/payments/cmd/connectors/internal/connectors/generic/client/generated v0.0.0-20240925171236-82f077b2e178 - github.com/formancehq/reconciliation => ../../ee/reconciliation - github.com/formancehq/search => github.com/formancehq/search v0.0.0-20240925174151-fe1cfd5a69cd github.com/formancehq/stack/libs/events => ../../libs/events - github.com/formancehq/wallets => ../../ee/wallets - github.com/formancehq/webhooks => github.com/formancehq/webhooks v0.0.0-20240925174047-7d4341ccfc5f github.com/zitadel/oidc => github.com/formancehq/oidc v0.0.0-20220923202448-e2960a99b71c ) diff --git a/tests/integration/go.sum b/tests/integration/go.sum index 226983708e..62a4b58952 100644 --- a/tests/integration/go.sum +++ b/tests/integration/go.sum @@ -788,20 +788,28 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/formancehq/auth v0.0.0-20240925174204-6f5cb5948775 h1:i4kSl3M+DSlIb2t/HEcnjT5cg3rJuk5XDSkB97kpQes= -github.com/formancehq/auth v0.0.0-20240925174204-6f5cb5948775/go.mod h1:sKfqRI3+6IZ0X+wrKRM0jLRRE2YyaMXGLm1iBBSlYn4= +github.com/formancehq/auth v0.0.0-20240925213343-e5de0bb34c65 h1:O7N8feKFJNSPkGpz0B52yS28mj1i8irCku9OMAtTnAo= +github.com/formancehq/auth v0.0.0-20240925213343-e5de0bb34c65/go.mod h1:sKfqRI3+6IZ0X+wrKRM0jLRRE2YyaMXGLm1iBBSlYn4= +github.com/formancehq/flows v0.0.0-20240926150344-d8c14fc9e76c h1:wSCzJfftp32Ifu5Ldy0DB2hRsrw6pGC544E5tmLYiBo= +github.com/formancehq/flows v0.0.0-20240926150344-d8c14fc9e76c/go.mod h1:BYDgQK6k1hxpD/ebqOmgWsTwDJL1uWt8asHXSwAy00k= +github.com/formancehq/formance-sdk-go/v3 v3.0.0 h1:UIzVMJSPUBUSm29Zg50tZjM0f101WeWHYlu0ClfUk2c= +github.com/formancehq/formance-sdk-go/v3 v3.0.0/go.mod h1:ZBBYCgtDgde68qMW5nZ9lfliM8W1D3ZI/BpZ+RdhD3c= github.com/formancehq/go-libs v1.7.1 h1:9D5cxKWFlVtdX5AYDXeUz1Nb9PdoEfQX0f/yeLsU324= github.com/formancehq/go-libs v1.7.1/go.mod h1:pWTScpoyieF7OoJ6WVmXNG9NhDjbZbAmFqd7UOw85iI= -github.com/formancehq/ledger v0.0.0-20240925161848-3cf78b93df02 h1:0jB2JrN653A25DxUh4THjujWFZseMQqg5VMwGQxv7gc= -github.com/formancehq/ledger v0.0.0-20240925161848-3cf78b93df02/go.mod h1:sGscj1S3S2ndAzOPVFQFBuC72YF8t+OAm/hcqDcxpxI= -github.com/formancehq/payments v0.0.0-20240925171236-82f077b2e178 h1:hDGGwY8D0/RvoxIxxdGrGP1b/J7DP7aoZlC+vV1/NPU= -github.com/formancehq/payments v0.0.0-20240925171236-82f077b2e178/go.mod h1:U4BNKrXyhCtk6pkZVNJjaLFkg5B9RQk3RiQq9gt18CY= +github.com/formancehq/ledger v0.0.0-20240925213413-0ef9d8eb67e6 h1:VjlFSyIPbX7T22+3q0pD7BhQjOYY1mNHubytWrwJLEE= +github.com/formancehq/ledger v0.0.0-20240925213413-0ef9d8eb67e6/go.mod h1:sGscj1S3S2ndAzOPVFQFBuC72YF8t+OAm/hcqDcxpxI= +github.com/formancehq/payments v0.0.0-20240925213419-a849e779040f h1:CY2/cYc3VWCjomlnSxfGNgfnAYnmVvx6hxxirq/6/RU= +github.com/formancehq/payments v0.0.0-20240925213419-a849e779040f/go.mod h1:U4BNKrXyhCtk6pkZVNJjaLFkg5B9RQk3RiQq9gt18CY= github.com/formancehq/payments/cmd/connectors/internal/connectors/generic/client/generated v0.0.0-20240925171236-82f077b2e178 h1:2bb1Zg4XtgrRDhqR0g/lSnnfyrgjh2FrqNh2UK4LpCs= github.com/formancehq/payments/cmd/connectors/internal/connectors/generic/client/generated v0.0.0-20240925171236-82f077b2e178/go.mod h1:Xsj5yVWO0e2XZx45RjL93JbPa+78CzNoSRlITuDA97c= -github.com/formancehq/search v0.0.0-20240925174151-fe1cfd5a69cd h1:zsv//syEUoJWo2VswR9vXvrbDAAoxm8rLXkCxYl114s= -github.com/formancehq/search v0.0.0-20240925174151-fe1cfd5a69cd/go.mod h1:vmUx4wanfOqGBZk0t2bhAXx+r+Pp9WaIA1UQQNc9Zds= -github.com/formancehq/webhooks v0.0.0-20240925174047-7d4341ccfc5f h1:hOm4zNG8Z/RH4TlISdGx3AzHvtFPtMuaV1tx4bvKIho= -github.com/formancehq/webhooks v0.0.0-20240925174047-7d4341ccfc5f/go.mod h1:ILmAle/plVuBCFjUKZtI3wrAFcyzbHbuKbXyrd/VtWA= +github.com/formancehq/reconciliation v0.0.0-20240926152910-eda505f2fcd3 h1:/7JCaSog8ln3QePn3JsknpR+M7YdiUWlhR3kTYhWkX8= +github.com/formancehq/reconciliation v0.0.0-20240926152910-eda505f2fcd3/go.mod h1:BQchlzhK8fdnPm8sfLSUWu2nslMRLEGsbHprjlw5O8c= +github.com/formancehq/search v0.0.0-20240926085257-6b5288dc2576 h1:2PuiQ5FPsyseXDs+8UoyvpS1Qgysh597ReyapnHB3Ig= +github.com/formancehq/search v0.0.0-20240926085257-6b5288dc2576/go.mod h1:vmUx4wanfOqGBZk0t2bhAXx+r+Pp9WaIA1UQQNc9Zds= +github.com/formancehq/wallets v0.0.0-20240926151232-c6fc6e393af0 h1:i9eaK3EUEeYwDvJyOiSgWtT9XLGEMzJQ9rgkIFZXIHE= +github.com/formancehq/wallets v0.0.0-20240926151232-c6fc6e393af0/go.mod h1:y8X2TaG5ar3gGQorP+fRxJ4wokpl9SbHW8vkyvDOYW4= +github.com/formancehq/webhooks v0.0.0-20240926142120-a19c8730abaa h1:6CWp15MLLH0ntpdWErj9+DXWHEGlCyocRW1YR/gw6+M= +github.com/formancehq/webhooks v0.0.0-20240926142120-a19c8730abaa/go.mod h1:ILmAle/plVuBCFjUKZtI3wrAFcyzbHbuKbXyrd/VtWA= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= diff --git a/tests/integration/internal/init.go b/tests/integration/internal/init.go index 0a39d63f52..af583df140 100644 --- a/tests/integration/internal/init.go +++ b/tests/integration/internal/init.go @@ -2,7 +2,7 @@ package internal import ( "context" - formance "github.com/formancehq/formance-sdk-go/v2" + formance "github.com/formancehq/formance-sdk-go/v3" "github.com/formancehq/go-libs/logging" "github.com/oauth2-proxy/mockoidc" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/auth-client-credentials.go b/tests/integration/suite/auth-client-credentials.go index 2123678442..bb04083340 100644 --- a/tests/integration/suite/auth-client-credentials.go +++ b/tests/integration/suite/auth-client-credentials.go @@ -2,9 +2,9 @@ package suite import ( "fmt" - formance "github.com/formancehq/formance-sdk-go/v2" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + formance "github.com/formancehq/formance-sdk-go/v3" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/collectionutils" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" diff --git a/tests/integration/suite/ledger-aggregated-balances.go b/tests/integration/suite/ledger-aggregated-balances.go index 7b242ecfa5..5d654228ef 100644 --- a/tests/integration/suite/ledger-aggregated-balances.go +++ b/tests/integration/suite/ledger-aggregated-balances.go @@ -6,8 +6,8 @@ import ( "net/http" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/ledger-create-bulk.go b/tests/integration/suite/ledger-create-bulk.go index 1c5fbf66e9..6537f7d301 100644 --- a/tests/integration/suite/ledger-create-bulk.go +++ b/tests/integration/suite/ledger-create-bulk.go @@ -5,8 +5,8 @@ import ( "net/http" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/metadata" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" diff --git a/tests/integration/suite/ledger-create-transaction.go b/tests/integration/suite/ledger-create-transaction.go index a0762b6915..ea84f20ba0 100644 --- a/tests/integration/suite/ledger-create-transaction.go +++ b/tests/integration/suite/ledger-create-transaction.go @@ -5,15 +5,15 @@ import ( "net/http" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" "github.com/formancehq/stack/tests/integration/internal/modules" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - ledgerevents "github.com/formancehq/ledger/pkg/events" - "github.com/formancehq/stack/libs/events" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/metadata" "github.com/formancehq/go-libs/pointer" + ledgerevents "github.com/formancehq/ledger/pkg/events" + "github.com/formancehq/stack/libs/events" . "github.com/formancehq/stack/tests/integration/internal" "github.com/nats-io/nats.go" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/ledger-create.go b/tests/integration/suite/ledger-create.go index bfdc60b52b..733724a6c2 100644 --- a/tests/integration/suite/ledger-create.go +++ b/tests/integration/suite/ledger-create.go @@ -4,9 +4,9 @@ import ( "net/http" "strings" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/pointer" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" diff --git a/tests/integration/suite/ledger-delete-metadata.go b/tests/integration/suite/ledger-delete-metadata.go index 8f037c86cd..c36e9b0cbb 100644 --- a/tests/integration/suite/ledger-delete-metadata.go +++ b/tests/integration/suite/ledger-delete-metadata.go @@ -1,8 +1,8 @@ package suite import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/ledger-import-export.go b/tests/integration/suite/ledger-import-export.go index 9582c02c8a..ceff94b92a 100644 --- a/tests/integration/suite/ledger-import-export.go +++ b/tests/integration/suite/ledger-import-export.go @@ -1,8 +1,8 @@ package suite import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/pointer" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" diff --git a/tests/integration/suite/ledger-list-count-accounts.go b/tests/integration/suite/ledger-list-count-accounts.go index 06e37b7d82..21bb7b4909 100644 --- a/tests/integration/suite/ledger-list-count-accounts.go +++ b/tests/integration/suite/ledger-list-count-accounts.go @@ -7,12 +7,12 @@ import ( "sort" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" "github.com/formancehq/go-libs/pointer" "github.com/formancehq/stack/tests/integration/internal/modules" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/metadata" . "github.com/formancehq/stack/tests/integration/internal" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/ledger-list-logs.go b/tests/integration/suite/ledger-list-logs.go index 4d78cc9ff4..3480346cb9 100644 --- a/tests/integration/suite/ledger-list-logs.go +++ b/tests/integration/suite/ledger-list-logs.go @@ -8,8 +8,8 @@ import ( "sort" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" diff --git a/tests/integration/suite/ledger-list-transactions.go b/tests/integration/suite/ledger-list-transactions.go index 1c2ab4a060..cd61043fdd 100644 --- a/tests/integration/suite/ledger-list-transactions.go +++ b/tests/integration/suite/ledger-list-transactions.go @@ -10,11 +10,11 @@ import ( "sort" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" "github.com/formancehq/stack/tests/integration/internal/modules" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/metadata" "github.com/formancehq/go-libs/pointer" . "github.com/formancehq/stack/tests/integration/internal" diff --git a/tests/integration/suite/ledger-list.go b/tests/integration/suite/ledger-list.go index da732d2522..94281860dd 100644 --- a/tests/integration/suite/ledger-list.go +++ b/tests/integration/suite/ledger-list.go @@ -2,7 +2,7 @@ package suite import ( "fmt" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/ledger-revert-transaction.go b/tests/integration/suite/ledger-revert-transaction.go index 1073d90a50..c5994aebb0 100644 --- a/tests/integration/suite/ledger-revert-transaction.go +++ b/tests/integration/suite/ledger-revert-transaction.go @@ -5,15 +5,15 @@ import ( "net/http" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" "github.com/formancehq/go-libs/pointer" "github.com/formancehq/stack/tests/integration/internal/modules" "github.com/nats-io/nats.go" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" ledgerevents "github.com/formancehq/ledger/pkg/events" "github.com/formancehq/stack/libs/events" . "github.com/formancehq/stack/tests/integration/internal" diff --git a/tests/integration/suite/ledger-search-ingestion-v1.go b/tests/integration/suite/ledger-search-ingestion-v1.go index 16bc62a76b..b5f3512217 100644 --- a/tests/integration/suite/ledger-search-ingestion-v1.go +++ b/tests/integration/suite/ledger-search-ingestion-v1.go @@ -1,7 +1,7 @@ package suite import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/publish" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" diff --git a/tests/integration/suite/ledger-set-metadata-on-account.go b/tests/integration/suite/ledger-set-metadata-on-account.go index 508af3176f..6050c8f5a1 100644 --- a/tests/integration/suite/ledger-set-metadata-on-account.go +++ b/tests/integration/suite/ledger-set-metadata-on-account.go @@ -7,8 +7,8 @@ import ( "reflect" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" ledgerevents "github.com/formancehq/ledger/pkg/events" "github.com/formancehq/stack/libs/events" . "github.com/formancehq/stack/tests/integration/internal" diff --git a/tests/integration/suite/ledger-set-metadata-on-transaction.go b/tests/integration/suite/ledger-set-metadata-on-transaction.go index 86c104911a..f9f9def7d9 100644 --- a/tests/integration/suite/ledger-set-metadata-on-transaction.go +++ b/tests/integration/suite/ledger-set-metadata-on-transaction.go @@ -5,11 +5,11 @@ import ( "net/http" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" "github.com/formancehq/stack/tests/integration/internal/modules" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" diff --git a/tests/integration/suite/ledger-update-metadata.go b/tests/integration/suite/ledger-update-metadata.go index 888b04f239..0f1e364269 100644 --- a/tests/integration/suite/ledger-update-metadata.go +++ b/tests/integration/suite/ledger-update-metadata.go @@ -1,7 +1,7 @@ package suite import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/ledger-use-alternate-bucket.go b/tests/integration/suite/ledger-use-alternate-bucket.go index 593f8cecbb..6c53cab5a8 100644 --- a/tests/integration/suite/ledger-use-alternate-bucket.go +++ b/tests/integration/suite/ledger-use-alternate-bucket.go @@ -1,8 +1,8 @@ package suite import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/pointer" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" diff --git a/tests/integration/suite/ledger-v1-get-balances.go b/tests/integration/suite/ledger-v1-get-balances.go index ef7d027871..dc929fc13c 100644 --- a/tests/integration/suite/ledger-v1-get-balances.go +++ b/tests/integration/suite/ledger-v1-get-balances.go @@ -9,8 +9,8 @@ import ( "github.com/formancehq/stack/tests/integration/internal/modules" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" diff --git a/tests/integration/suite/ledger-volumes-list.go b/tests/integration/suite/ledger-volumes-list.go index 1f78db696f..9c42527267 100644 --- a/tests/integration/suite/ledger-volumes-list.go +++ b/tests/integration/suite/ledger-volumes-list.go @@ -6,8 +6,8 @@ import ( "net/http" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/orchestration-triggers.go b/tests/integration/suite/orchestration-triggers.go index cbaf9abd73..30f0b10b61 100644 --- a/tests/integration/suite/orchestration-triggers.go +++ b/tests/integration/suite/orchestration-triggers.go @@ -6,12 +6,12 @@ import ( "net/http/httptest" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" - orchestrationevents "github.com/formancehq/orchestration/pkg/events" - paymentsevents "github.com/formancehq/payments/pkg/events" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/api" "github.com/formancehq/go-libs/publish" + orchestrationevents "github.com/formancehq/orchestration/pkg/events" + paymentsevents "github.com/formancehq/payments/pkg/events" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" "github.com/google/uuid" diff --git a/tests/integration/suite/orchestration-workflows-create.go b/tests/integration/suite/orchestration-workflows-create.go index 574cb27fc8..becb904601 100644 --- a/tests/integration/suite/orchestration-workflows-create.go +++ b/tests/integration/suite/orchestration-workflows-create.go @@ -1,7 +1,7 @@ package suite import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/orchestration-workflows-execute-with-error.go b/tests/integration/suite/orchestration-workflows-execute-with-error.go index 2134670128..e9e0da0502 100644 --- a/tests/integration/suite/orchestration-workflows-execute-with-error.go +++ b/tests/integration/suite/orchestration-workflows-execute-with-error.go @@ -9,8 +9,8 @@ import ( "net/http" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" diff --git a/tests/integration/suite/orchestration-workflows-execute.go b/tests/integration/suite/orchestration-workflows-execute.go index df15d5fafa..8a91f9cb2c 100644 --- a/tests/integration/suite/orchestration-workflows-execute.go +++ b/tests/integration/suite/orchestration-workflows-execute.go @@ -10,8 +10,8 @@ import ( "net/http" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/metadata" . "github.com/formancehq/stack/tests/integration/internal" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/orchestration-workflows-list.go b/tests/integration/suite/orchestration-workflows-list.go index 441f5a17a3..157b40719e 100644 --- a/tests/integration/suite/orchestration-workflows-list.go +++ b/tests/integration/suite/orchestration-workflows-list.go @@ -1,8 +1,8 @@ package suite import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/orchestration-workflows-soft-delete.go b/tests/integration/suite/orchestration-workflows-soft-delete.go index bf896c4c39..877f5b2f54 100644 --- a/tests/integration/suite/orchestration-workflows-soft-delete.go +++ b/tests/integration/suite/orchestration-workflows-soft-delete.go @@ -1,9 +1,9 @@ package suite import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/payments-connectors-dummy-pay.go b/tests/integration/suite/payments-connectors-dummy-pay.go index e83bdb2e70..e0ed881e7b 100644 --- a/tests/integration/suite/payments-connectors-dummy-pay.go +++ b/tests/integration/suite/payments-connectors-dummy-pay.go @@ -11,8 +11,8 @@ import ( "github.com/formancehq/stack/tests/integration/internal/modules" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" paymentEvents "github.com/formancehq/payments/pkg/events" "github.com/formancehq/stack/libs/events" . "github.com/formancehq/stack/tests/integration/internal" diff --git a/tests/integration/suite/payments-connectors-generic.go b/tests/integration/suite/payments-connectors-generic.go index 60f0c40d7f..85691cf96d 100644 --- a/tests/integration/suite/payments-connectors-generic.go +++ b/tests/integration/suite/payments-connectors-generic.go @@ -4,9 +4,9 @@ import ( "math/big" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/payments-connectors-reset.go b/tests/integration/suite/payments-connectors-reset.go index ea29a5ff5d..a4f233ec86 100644 --- a/tests/integration/suite/payments-connectors-reset.go +++ b/tests/integration/suite/payments-connectors-reset.go @@ -8,8 +8,8 @@ import ( "github.com/formancehq/stack/tests/integration/internal/modules" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" paymentEvents "github.com/formancehq/payments/pkg/events" "github.com/formancehq/stack/libs/events" . "github.com/formancehq/stack/tests/integration/internal" diff --git a/tests/integration/suite/payments-connectors-stripe.go b/tests/integration/suite/payments-connectors-stripe.go index 0aa259bb30..016df7ab48 100644 --- a/tests/integration/suite/payments-connectors-stripe.go +++ b/tests/integration/suite/payments-connectors-stripe.go @@ -6,8 +6,8 @@ import ( "github.com/formancehq/stack/tests/integration/internal/modules" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" paymentEvents "github.com/formancehq/payments/pkg/events" "github.com/formancehq/stack/libs/events" . "github.com/formancehq/stack/tests/integration/internal" diff --git a/tests/integration/suite/reconciliation-policy-create-list.go b/tests/integration/suite/reconciliation-policy-create-list.go index 53b54a0820..0cf153a7bf 100644 --- a/tests/integration/suite/reconciliation-policy-create-list.go +++ b/tests/integration/suite/reconciliation-policy-create-list.go @@ -1,8 +1,8 @@ package suite import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" "github.com/google/uuid" diff --git a/tests/integration/suite/wallets-create.go b/tests/integration/suite/wallets-create.go index c34efff9e4..2f698a7a59 100644 --- a/tests/integration/suite/wallets-create.go +++ b/tests/integration/suite/wallets-create.go @@ -5,8 +5,8 @@ import ( "github.com/formancehq/go-libs/pointer" "math/big" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" "github.com/google/uuid" diff --git a/tests/integration/suite/wallets-credit.go b/tests/integration/suite/wallets-credit.go index 9602e14d80..15ee8e7ca7 100644 --- a/tests/integration/suite/wallets-credit.go +++ b/tests/integration/suite/wallets-credit.go @@ -1,9 +1,9 @@ package suite import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/pointer" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" diff --git a/tests/integration/suite/wallets-debit.go b/tests/integration/suite/wallets-debit.go index 42605a9312..73dbb3e4b5 100644 --- a/tests/integration/suite/wallets-debit.go +++ b/tests/integration/suite/wallets-debit.go @@ -1,9 +1,9 @@ package suite import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" "github.com/formancehq/go-libs/pointer" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" diff --git a/tests/integration/suite/webhooks-configs-activation.go b/tests/integration/suite/webhooks-configs-activation.go index ff91a2b859..9e0f11a7ff 100644 --- a/tests/integration/suite/webhooks-configs-activation.go +++ b/tests/integration/suite/webhooks-configs-activation.go @@ -1,9 +1,9 @@ package suite import ( - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" "github.com/formancehq/stack/tests/integration/internal/modules" webhooks "github.com/formancehq/webhooks/pkg" diff --git a/tests/integration/suite/webhooks-configs-delete.go b/tests/integration/suite/webhooks-configs-delete.go index 2d51077c31..d7f7daef18 100644 --- a/tests/integration/suite/webhooks-configs-delete.go +++ b/tests/integration/suite/webhooks-configs-delete.go @@ -3,11 +3,11 @@ package suite import ( "net/http" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" "github.com/formancehq/stack/tests/integration/internal/modules" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" webhooks "github.com/formancehq/webhooks/pkg" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/webhooks-configs-get.go b/tests/integration/suite/webhooks-configs-get.go index 2610ebd2d9..d3215a3db3 100644 --- a/tests/integration/suite/webhooks-configs-get.go +++ b/tests/integration/suite/webhooks-configs-get.go @@ -4,8 +4,8 @@ import ( "github.com/formancehq/stack/tests/integration/internal/modules" "net/http" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" diff --git a/tests/integration/suite/webhooks-configs-insert.go b/tests/integration/suite/webhooks-configs-insert.go index 8b20d2860f..bd6d19a790 100644 --- a/tests/integration/suite/webhooks-configs-insert.go +++ b/tests/integration/suite/webhooks-configs-insert.go @@ -4,10 +4,10 @@ import ( "net/http" "time" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" "github.com/formancehq/stack/tests/integration/internal/modules" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" "github.com/google/uuid" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/webhooks-configs-secret.go b/tests/integration/suite/webhooks-configs-secret.go index f9b622f8b1..2496822123 100644 --- a/tests/integration/suite/webhooks-configs-secret.go +++ b/tests/integration/suite/webhooks-configs-secret.go @@ -4,8 +4,8 @@ import ( "github.com/formancehq/stack/tests/integration/internal/modules" "net/http" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" webhooks "github.com/formancehq/webhooks/pkg" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/webhooks-configs-test.go b/tests/integration/suite/webhooks-configs-test.go index 8243f5e423..a2a12ca2eb 100644 --- a/tests/integration/suite/webhooks-configs-test.go +++ b/tests/integration/suite/webhooks-configs-test.go @@ -6,11 +6,11 @@ import ( "net/http/httptest" "strconv" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/sdkerrors" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/sdkerrors" "github.com/formancehq/stack/tests/integration/internal/modules" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" webhooks "github.com/formancehq/webhooks/pkg" "github.com/formancehq/webhooks/pkg/security" diff --git a/tests/integration/suite/webhooks-ledger-committed-transaction.go b/tests/integration/suite/webhooks-ledger-committed-transaction.go index e987ddfbb8..4763bfcc80 100644 --- a/tests/integration/suite/webhooks-ledger-committed-transaction.go +++ b/tests/integration/suite/webhooks-ledger-committed-transaction.go @@ -6,8 +6,8 @@ import ( "net/http" "net/http/httptest" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" webhooks "github.com/formancehq/webhooks/pkg" . "github.com/onsi/ginkgo/v2" diff --git a/tests/integration/suite/webhooks-retries.go b/tests/integration/suite/webhooks-retries.go index 1a75d84119..c6efbe7470 100644 --- a/tests/integration/suite/webhooks-retries.go +++ b/tests/integration/suite/webhooks-retries.go @@ -9,8 +9,8 @@ import ( "github.com/formancehq/stack/tests/integration/internal/modules" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/operations" - "github.com/formancehq/formance-sdk-go/v2/pkg/models/shared" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/operations" + "github.com/formancehq/formance-sdk-go/v3/pkg/models/shared" . "github.com/formancehq/stack/tests/integration/internal" webhooks "github.com/formancehq/webhooks/pkg" . "github.com/onsi/ginkgo/v2"